diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..df3a62c73b6d39779bb30a191ee2bd54bffd1f84 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# --- SENSITIVE KEYS (Never Push) --- +.env +backend/.env +frontend/.env +*.env + +# --- HEAVY FOLDERS (Never Push) --- +node_modules/ +frontend/node_modules/ +backend/env/ +env/ +__pycache__/ +backend/__pycache__/ +dist/ +build/ + +# --- ML MODELS (Ignore entire folder over 100MB) --- +backend/ml_models/ \ No newline at end of file diff --git a/backend/app.py b/backend/app.py new file mode 100644 index 0000000000000000000000000000000000000000..1cbaac2f078efe6484918a5b450efaf1568778b2 --- /dev/null +++ b/backend/app.py @@ -0,0 +1,106 @@ +# ============================================================= +# FILE: app.py +# Optimized Flask + SocketIO entry (threading mode, no debug) +# ============================================================= +import logging +from flask import Flask, jsonify +from flask_cors import CORS +from flask_socketio import SocketIO + + +# lightweight logging +logging.getLogger('werkzeug').setLevel(logging.ERROR) +logging.getLogger('socketio').setLevel(logging.ERROR) + + +app = Flask(__name__) +CORS(app, resources={r"/api/*": {"origins": "*"}}) + + +# Use threading mode to avoid eventlet monkey-patch issues with Scapy/IO +socketio = SocketIO(app, cors_allowed_origins="*", async_mode="threading") + + +# Mail initialization is left as-is but keep credentials out of source in production +try: + from extensions import mail + app.config.update( + MAIL_SERVER="smtp.gmail.com", + MAIL_PORT=587, + MAIL_USE_TLS=True, + MAIL_USERNAME="yishu2005.ju@gmail.com", + MAIL_PASSWORD="prko cejt awef zmmi", + MAIL_DEFAULT_SENDER=("Adaptive AI NIDS", "yishu2005.ju@gmail.com") + ) + mail.init_app(app) + +except Exception: +# If mail is not available in dev/test, continue gracefully + pass + + +# lazy import of sniffer so import side-effects are minimal +sniffer = None + + +def _get_sniffer(): + global sniffer + if sniffer is None: + from capture.live_manager import sniffer as _s + sniffer = _s + return sniffer + + +# Register blueprints lazily to avoid heavy imports at startup +def register_blueprints(app): + from importlib import import_module + + + routes = [ + ("routes.live_route", "live_bp", "/api/live"), + ("routes.logs_route", "logs_bp", "/api/logs"), + ("routes.predict_route", "predict_bp", "/api/predict"), + ("routes.reports_route", "reports_bp", "/api/reports"), + ("routes.ip_lookup_route", "ip_lookup_bp", "/api/ip"), + ("routes.geo_route", "geo_bp", "/api/geo"), + ("routes.alerts_route", "alerts_bp", "/api"), + ("routes.system_info", "system_bp", "/api"), + ("routes.ml_route", "ml_bp", "/api"), + ("routes.traffic_routes", "traffic_bp", "/api"), + ("routes.ml_switch_route","ml_switch","/api/model"), + ("routes.manual_predict_route","manual_predict","/api"), + ("routes.ai_route","ai_bp","/api/ai"), + ("routes.chat_route","chat_bp","/api"), + ("routes.offline_detection","offline_bp","/api/offline") + ] + + for module_name, varname, prefix in routes: + try: + mod = import_module(module_name) + bp = getattr(mod, varname) + app.register_blueprint(bp, url_prefix=prefix) + print(f"✅ Registered route: {module_name} -> {prefix}") + + except Exception as e: + print(f"⚠️ Skipping {module_name}: {e}") + +register_blueprints(app) + + +@app.route("/") +def home(): + s = _get_sniffer() + return jsonify({ + "status": "✅ Backend Active", + "capture_running": s.is_running() if s else False, + "tip": "Use /api/live/start and /api/live/stop to control capture" + }) + + +if __name__ == "__main__": + print("🚀 Starting Adaptive AI NIDS Backend (threading mode)...") + # Run without debug — debug spawns extra processes and uses more CPU + socketio.run(app, host="0.0.0.0", port=5000, debug=False) + + + diff --git a/backend/capture/__init__.py b/backend/capture/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/backend/capture/live_capture.py b/backend/capture/live_capture.py new file mode 100644 index 0000000000000000000000000000000000000000..c3d6b21ab888c463519efb2392850e78922cef13 --- /dev/null +++ b/backend/capture/live_capture.py @@ -0,0 +1,620 @@ +# backend/capture/live_capture.py +# Flow-aware live capture supporting both BCC (per-packet) and CICIDS (flow-aggregated) +import os +import time +import threading +import queue +from datetime import datetime +from collections import defaultdict, deque +import numpy as np +from scapy.all import sniff, IP, TCP, UDP # keep scapy usage +import joblib + +from utils.logger import push_event +from socket_manager import emit_new_event +from utils.model_selector import get_active_model, load_model + +# ------------------------- +# Tunables +# ------------------------- +CAPTURE_QUEUE_MAX = 5000 +PROCESS_BATCH_SIZE = 40 +EMIT_INTERVAL = 0.5 +BPF_FILTER = "tcp or udp" +SAMPLE_RATE = 0.45 +THROTTLE_PER_PACKET = 0.02 + +# Flow builder tunables +FLOW_IDLE_TIMEOUT = 1.5 # seconds of inactivity -> expire flow +FLOW_PACKET_THRESHOLD = 50 # force flush if many packets +FLOW_MAX_TRACKED = 20000 # limit number of active flows tracked to avoid memory explosion + +# ------------------------- +# Internal state +# ------------------------- +_packet_queue = queue.Queue(maxsize=CAPTURE_QUEUE_MAX) +_running = threading.Event() +_last_emit = 0.0 + +# Flow table and lock +_flows = dict() # flow_key -> Flow object +_flows_lock = threading.Lock() + +# background threads +_processor_thr = None +_capture_thr = None +_expiry_thr = None + +# ------------------------- +# Flow data container +# ------------------------- +class Flow: + def __init__(self, first_pkt, ts): + # 5-tuple key derived externally + self.first_seen = ts + self.last_seen = ts + self.packets_total = 0 + self.packets_fwd = 0 + self.packets_bwd = 0 + self.bytes_fwd = 0 + self.bytes_bwd = 0 + self.fwd_lens = [] # for mean + self.bwd_lens = [] + self.inter_arrivals = [] # global IATs across flow + self.last_pkt_ts = ts + self.fwd_psh = 0 + self.fwd_urg = 0 + self.protocol = 6 if first_pkt.haslayer(TCP) else (17 if first_pkt.haslayer(UDP) else 0) + # store client/server ip+port orientation based on first packet's src/dst + self.client_ip = first_pkt[IP].src + self.server_ip = first_pkt[IP].dst + self.client_port = first_pkt.sport if hasattr(first_pkt, 'sport') else 0 + self.server_port = first_pkt.dport if hasattr(first_pkt, 'dport') else 0 + + def update(self, pkt, ts): + self.packets_total += 1 + # Determine direction relative to initial client/server + try: + src = pkt[IP].src + sport = pkt.sport if hasattr(pkt, 'sport') else 0 + payload = bytes(pkt.payload) if pkt.payload else b"" + plen = len(payload) + except Exception: + src = None; sport = 0; plen = 0 + + # if src equals initial client, it's forward + if src == self.client_ip and sport == self.client_port: + dir_fwd = True + else: + dir_fwd = False + + if dir_fwd: + self.packets_fwd += 1 + self.bytes_fwd += plen + self.fwd_lens.append(plen) + # flags + if pkt.haslayer(TCP): + flags = pkt[TCP].flags + if flags & 0x08: # PSH + self.fwd_psh += 1 + if flags & 0x20: # URG + self.fwd_urg += 1 + else: + self.packets_bwd += 1 + self.bytes_bwd += plen + self.bwd_lens.append(plen) + + # inter-arrival + iat = ts - (self.last_pkt_ts or ts) + if iat > 0: + self.inter_arrivals.append(iat) + self.last_pkt_ts = ts + self.last_seen = ts + + def is_idle(self, now, idle_timeout): + return (now - self.last_seen) >= idle_timeout + + def build_cicids_features(self, dst_port_override=None): + """ + Build feature vector matching: + ['Protocol', 'Dst Port', 'Flow Duration', 'Tot Fwd Pkts', 'Tot Bwd Pkts', + 'TotLen Fwd Pkts', 'TotLen Bwd Pkts', 'Fwd Pkt Len Mean', 'Bwd Pkt Len Mean', + 'Flow IAT Mean', 'Fwd PSH Flags', 'Fwd URG Flags', 'Fwd IAT Mean'] + -> returns list of floats/ints + """ + duration = max(self.last_seen - self.first_seen, 0.000001) + tot_fwd = self.packets_fwd + tot_bwd = self.packets_bwd + totlen_fwd = float(self.bytes_fwd) + totlen_bwd = float(self.bytes_bwd) + fwd_mean = float(np.mean(self.fwd_lens)) if self.fwd_lens else 0.0 + bwd_mean = float(np.mean(self.bwd_lens)) if self.bwd_lens else 0.0 + flow_iat_mean = float(np.mean(self.inter_arrivals)) if self.inter_arrivals else 0.0 + fwd_iat_mean = self._fwd_iat_mean() + proto = int(self.protocol) + # FIXED: respect explicit override even if zero + dst_port = self.server_port if dst_port_override is None else int(dst_port_override or 0) + + return [ + proto, + dst_port, + duration, + tot_fwd, + tot_bwd, + totlen_fwd, + totlen_bwd, + fwd_mean, + bwd_mean, + flow_iat_mean, + self.fwd_psh, + self.fwd_urg, + fwd_iat_mean + ] + + def _fwd_iat_mean(self): + # approximate forward-only IATs by splitting inter_arrivals roughly (coarse) + # If we had per-direction timestamps we would measure precisely; + # here we approximate as global mean when forward packets exist. + if self.inter_arrivals and self.packets_fwd > 0: + return float(np.mean(self.inter_arrivals)) + return 0.0 + +# ------------------------- +# helpers: flow key +# ------------------------- +def make_flow_key(pkt): + try: + ip = pkt[IP] + proto = 6 if pkt.haslayer(TCP) else (17 if pkt.haslayer(UDP) else 0) + sport = pkt.sport if hasattr(pkt, 'sport') else 0 + dport = pkt.dport if hasattr(pkt, 'dport') else 0 + # canonicalize tuple order to consider direction + return (ip.src, ip.dst, sport, dport, proto) + except Exception: + return None + +# ------------------------- +# queueing / sniff simple wrappers +# ------------------------- +def _enqueue(pkt): + try: + _packet_queue.put_nowait((pkt, time.time())) + except queue.Full: + return + +def _packet_capture_worker(iface=None): + sniff(iface=iface, prn=_enqueue, store=False, filter=BPF_FILTER) + +# ------------------------- +# Expiry thread: periodically expire idle flows +# ------------------------- +def _expiry_worker(): + while _running.is_set(): + time.sleep(0.5) + now = time.time() + to_flush = [] + with _flows_lock: + keys = list(_flows.keys()) + for k in keys: + f = _flows.get(k) + if f is None: + continue + if f.is_idle(now, FLOW_IDLE_TIMEOUT) or f.packets_total >= FLOW_PACKET_THRESHOLD: + to_flush.append(k) + + if to_flush: + _process_and_emit_flows(to_flush) + +# ------------------------- +# core: process queue, update flows, flush when needed +# ------------------------- +def _processor_worker(): + global _last_emit + # lazy load initial model bundle + active = get_active_model() + model_bundle = load_model(active) + processor_model = model_bundle.get("model") + processor_scaler = model_bundle.get("scaler") or (model_bundle.get("artifacts") and model_bundle["artifacts"].get("scaler")) + processor_encoder = model_bundle.get("encoder") or (model_bundle.get("artifacts") and model_bundle["artifacts"].get("label_encoder")) + + batch = [] + while _running.is_set(): + # refresh model if switched + new_active = get_active_model() + if new_active != active: + active = new_active + model_bundle = load_model(active) + processor_model = model_bundle.get("model") + processor_scaler = model_bundle.get("scaler") or (model_bundle.get("artifacts") and model_bundle["artifacts"].get("scaler")) + processor_encoder = model_bundle.get("encoder") or (model_bundle.get("artifacts") and model_bundle["artifacts"].get("label_encoder")) + print(f"[live_capture] switched active model to {active}") + + try: + pkt, ts = _packet_queue.get(timeout=0.5) + except queue.Empty: + # flush small batches if exist (not required) + continue + + # sampling, ignore some traffic + if np.random.rand() > SAMPLE_RATE: + continue + if not pkt.haslayer(IP): + continue + + # BCC path: still do per-packet predictions if active 'bcc' + if active == "bcc": + batch.append((pkt, ts)) + if len(batch) >= PROCESS_BATCH_SIZE or _packet_queue.empty(): + _process_bcc_batch(batch, processor_model, processor_scaler, processor_encoder) + batch.clear() + continue + + # CICIDS path: update flow table + key = make_flow_key(pkt) + if key is None: + continue + + # Prevent runaway flows table + with _flows_lock: + if len(_flows) > FLOW_MAX_TRACKED: + # flush oldest flows (heuristic) to free space + # choose keys ordered by last_seen + items = list(_flows.items()) + items.sort(key=lambda kv: kv[1].last_seen) + n_to_remove = int(len(items) * 0.1) or 100 + keys_to_flush = [k for k, _ in items[:n_to_remove]] + # flush asynchronously + threading.Thread(target=_process_and_emit_flows, args=(keys_to_flush,), daemon=True).start() + + flow = _flows.get(key) + if flow is None: + # new flow + flow = Flow(pkt, ts) + _flows[key] = flow + + # update outside big lock (Flow.update is mostly per-flow) + flow.update(pkt, ts) + + # flush immediately if surpass threshold + if flow.packets_total >= FLOW_PACKET_THRESHOLD: + _process_and_emit_flows([key]) + + # when stopped, flush all + with _flows_lock: + keys = list(_flows.keys()) + if keys: + _process_and_emit_flows(keys) + + +# ------------------------- +# Process BCC batch (existing behavior) +# ------------------------- +def _process_bcc_batch(batch, model, scaler, encoder): + events = [] + features_list = [] + for pkt, ts in batch: + # reuse earlier extraction (simple) + features = _extract_bcc_vector(pkt) + features_list.append(features) + + X = np.asarray(features_list, dtype=float) + if scaler is not None: + try: + Xs = scaler.transform(X) + except Exception: + Xs = X + else: + Xs = X + + if model is not None: + try: + preds = model.predict(Xs) + probs = model.predict_proba(Xs) if hasattr(model, "predict_proba") else None + except Exception as e: + preds = [None] * len(Xs) + probs = None + print("[live_capture] BCC model predict failed:", e) + else: + preds = [None] * len(Xs) + probs = None + + for i, (pkt, ts) in enumerate(batch): + pred = preds[i] + conf = float(np.max(probs[i])) if (probs is not None and len(probs) > i) else None + try: + decoded = encoder.inverse_transform([int(pred)])[0] if encoder else str(pred) + except Exception: + decoded = str(pred) + + evt = { + "time": datetime.now().strftime("%H:%M:%S"), + "src_ip": pkt[IP].src, + "dst_ip": pkt[IP].dst, + "sport": (pkt.sport if (pkt.haslayer(TCP) or pkt.haslayer(UDP)) else 0), + "dport": (pkt.dport if (pkt.haslayer(TCP) or pkt.haslayer(UDP)) else 0), + "proto": "TCP" if pkt.haslayer(TCP) else ("UDP" if pkt.haslayer(UDP) else "OTHER"), + "prediction": decoded, + "confidence": conf if conf is None or isinstance(conf, float) else float(conf), + "packet_meta": extract_packet_metadata(pkt) # <-- NEW +} + + try: + push_event(evt) + except Exception: + pass + events.append(evt) + + # emit once per batch + if events: + try: + emit_new_event({"items": events, "count": len(events)}) + except Exception: + pass + + +def _extract_bcc_vector(pkt): + # this matches your old extract_bcc_features but kept minimal and robust + try: + proto = 6 if pkt.haslayer(TCP) else (17 if pkt.haslayer(UDP) else 1) + src_port = pkt.sport if pkt.haslayer(TCP) or pkt.haslayer(UDP) else 0 + dst_port = pkt.dport if pkt.haslayer(TCP) or pkt.haslayer(UDP) else 0 + + payload = bytes(pkt.payload) if pkt.payload else b"" + plen = len(payload) + header = max(len(pkt) - plen, 0) + + syn = 1 if pkt.haslayer(TCP) and pkt[TCP].flags & 0x02 else 0 + ack = 1 if pkt.haslayer(TCP) and pkt[TCP].flags & 0x10 else 0 + rst = 1 if pkt.haslayer(TCP) and pkt[TCP].flags & 0x04 else 0 + fin = 1 if pkt.haslayer(TCP) and pkt[TCP].flags & 0x01 else 0 + + return [ + proto, + src_port, + dst_port, + 0.001, + 1, + 1, + 0, + plen, + header, + plen / 0.002 if 0.002 else plen, + 1 / 0.002 if 0.002 else 1, + syn, + ack, + rst, + fin + ] + except Exception: + return [0] * 15 + + +# ------------------------- +# Packet-level metadata extractor +# ------------------------- +def extract_packet_metadata(pkt): + """Extract detailed packet-level metadata for frontend display.""" + meta = {} + + # IP-level metadata + try: + meta["ttl"] = pkt[IP].ttl if pkt.haslayer(IP) else None + meta["pkt_len"] = len(pkt) + except: + meta["ttl"] = None + meta["pkt_len"] = None + + # TCP metadata + if pkt.haslayer(TCP): + tcp = pkt[TCP] + try: + meta["seq"] = int(tcp.seq) + meta["ack"] = int(tcp.ack) + meta["window"] = int(tcp.window) + meta["flags"] = str(tcp.flags) + meta["header_len"] = tcp.dataofs * 4 # Data offset (words) + except: + meta["seq"] = None + meta["ack"] = None + meta["window"] = None + meta["flags"] = None + meta["header_len"] = None + else: + meta["seq"] = None + meta["ack"] = None + meta["window"] = None + meta["flags"] = None + meta["header_len"] = None + + # Payload length + try: + payload = bytes(pkt.payload) + meta["payload_len"] = len(payload) + except: + meta["payload_len"] = None + + return meta + +# ------------------------- +# flush flows and emit/predict +# ------------------------- +def _process_and_emit_flows(keys): + # keys: list of flow_keys to flush; safe to call from any thread + # collect features for predict, delete flows + to_predict = [] + mapping = [] # keep (flow_key, flow_obj) for events + with _flows_lock: + for k in keys: + f = _flows.pop(k, None) + if f: + mapping.append((k, f)) + + if not mapping: + return + + # create features list + for k, f in mapping: + feat = f.build_cicids_features() + to_predict.append((k, f, feat)) + + X = np.array([t[2] for t in to_predict], dtype=float) + # lazy load latest model bundle (in case switching) + active = get_active_model() + bundle = load_model(active) + model = bundle.get("model") + scaler = None + artifacts = bundle.get("artifacts") + + # try to get scaler from bundle/artifacts + if bundle.get("scaler") is not None: + scaler = bundle.get("scaler") + elif artifacts and artifacts.get("scaler") is not None: + scaler = artifacts.get("scaler") + + if scaler is not None: + try: + # If scaler expects dataframe shape, it should still accept ndarray + Xs = scaler.transform(X) + except Exception as e: + print("[live_capture] cicids scaler transform failed:", e) + Xs = X + else: + Xs = X + + preds = [] + probs = None + if model is not None: + try: + preds = model.predict(Xs) + if hasattr(model, "predict_proba"): + try: + probs = model.predict_proba(Xs) + except Exception: + probs = None + except Exception as e: + print("[live_capture] cicids model predict failed:", e) + preds = [None] * len(Xs) + probs = None + else: + preds = [None] * len(Xs) + + # build events and emit/push + events = [] + for i, (k, f, feat) in enumerate(to_predict): + pred = preds[i] + conf = float(np.max(probs[i])) if (probs is not None and len(probs) > i) else None + + # ------------------------- + # SIMPLIFIED LABEL DECODING + # ------------------------- + # Your RF pipeline outputs string labels directly (e.g. 'DoS attacks-Hulk', 'BENIGN'). + # So keep it simple and safe: + try: + label = str(pred) + except Exception: + label = repr(pred) + + evt = { + "time": datetime.now().strftime("%H:%M:%S"), + "src_ip": f.client_ip, + "dst_ip": f.server_ip, + "sport": f.client_port, + "dport": f.server_port, + "proto": "TCP" if f.protocol == 6 else ("UDP" if f.protocol == 17 else "OTHER"), + "prediction": label, + "confidence": conf if conf is None or isinstance(conf, float) else float(conf), + "features": feat, + "flow_summary": { + "packets_fwd": f.packets_fwd, + "packets_bwd": f.packets_bwd, + "bytes_fwd": f.bytes_fwd, + "bytes_bwd": f.bytes_bwd, + "duration": f.last_seen - f.first_seen, + "fwd_mean_len": float(np.mean(f.fwd_lens)) if f.fwd_lens else 0.0 + } +} + + try: + push_event(evt) + except Exception: + pass + events.append(evt) + + if events: + try: + emit_new_event({"items": events, "count": len(events)}) + except Exception: + pass + +# ------------------------- +# start/stop API (keeps your old signatures) +# ------------------------- +def start_live_capture_packet_mode(iface=None): + """Start packet capture + processor + expiry threads.""" + global _processor_thr, _capture_thr, _expiry_thr + if _running.is_set(): + print("Already running") + return + _running.set() + _processor_thr = threading.Thread(target=_processor_worker, daemon=True) + _capture_thr = threading.Thread(target=_packet_capture_worker, kwargs={"iface": iface}, daemon=True) + _expiry_thr = threading.Thread(target=_expiry_worker, daemon=True) + _processor_thr.start() + _capture_thr.start() + _expiry_thr.start() + print("Live capture started (flow-aware)") + +def stop_live_capture(): + _running.clear() + time.sleep(0.2) + # flush all flows and stop + with _flows_lock: + keys = list(_flows.keys()) + if keys: + _process_and_emit_flows(keys) + print("Stopping capture...") + +def is_running(): + return _running.is_set() + +# ------------------------- +# Small test helpers (simulate simple flow packets) +# ------------------------- +def _make_fake_pkt(src, dst, sport, dport, proto='TCP', payload_len=100, flags=0x18): + """Return a tiny object resembling scapy packet for testing without scapy.""" + # If scapy present prefer to build actual IP/TCP + try: + if proto.upper() == 'TCP': + from scapy.all import IP, TCP + pkt = IP(src=src, dst=dst)/TCP(sport=sport, dport=dport, flags=flags)/("X"*payload_len) + return pkt + elif proto.upper() == 'UDP': + from scapy.all import IP, UDP + pkt = IP(src=src, dst=dst)/UDP(sport=sport, dport=dport)/("X"*payload_len) + return pkt + except Exception: + # fallback plain namespace + class SimplePkt: + def __init__(self): + self.payload = b"X"*payload_len + self.len = payload_len + 40 + def haslayer(self, cls): + return False + return SimplePkt() + +def simulate_flow(src="10.0.0.1", dst="10.0.0.2", sport=1234, dport=80, count=6, interval=0.1): + """Quick local simulator: pushes `count` fake packets for a flow into the queue.""" + for i in range(count): + pkt = _make_fake_pkt(src, dst, sport, dport, proto='TCP', payload_len=100, flags=0x18) + _enqueue((pkt, time.time())) if False else _packet_queue.put_nowait((pkt, time.time())) + time.sleep(interval) + +# ---------------------------------------------------------------------------- +# If you want to test this module interactively: +# 1) from backend.capture import live_capture +# 2) live_capture.start_live_capture_packet_mode() +# 3) call live_capture.simulate_flow(...) or send real packets +# 4) view server logs, or GET /api/live/recent to see events (existing route) +# ---------------------------------------------------------------------------- + + diff --git a/backend/capture/live_manager.py b/backend/capture/live_manager.py new file mode 100644 index 0000000000000000000000000000000000000000..28e52e4a21dff42fe38409e52e2c7379c498308b --- /dev/null +++ b/backend/capture/live_manager.py @@ -0,0 +1,57 @@ +# live_manager.py (Optimized) +# ------------------------------------------------------------- +import threading +import time +from typing import Optional +from .live_capture import start_live_capture_packet_mode, stop_live_capture, is_running +from utils.logger import get_recent_events, get_model_stats, get_active_model + + +class LiveSniffer: + def __init__(self): + self._thr: Optional[threading.Thread] = None + self._lock = threading.Lock() + self._iface = None + self._last_start_time = None + + def start(self, iface=None, packet_limit=0): + with self._lock: + if is_running(): + print("Already running.") + return + self._iface = iface + self._last_start_time = time.strftime("%H:%M:%S") + + def _worker(): + print(f"LiveSniffer started on interface={iface or 'default'}") + try: + # FIX: start_live_capture_packet_mode signature accepts iface only + start_live_capture_packet_mode(iface=self._iface) + except Exception as e: + print("Sniffer error:", e) + print("LiveSniffer thread exit.") + + self._thr = threading.Thread(target=_worker, daemon=True) + self._thr.start() + + def stop(self): + with self._lock: + if not is_running(): + print("Already stopped.") + return + stop_live_capture() + + if self._thr and self._thr.is_alive(): + self._thr.join(timeout=3) + print("Sniffer fully stopped.") + + def is_running(self) -> bool: + return is_running() + + + def recent(self, n=200): + return get_recent_events(get_active_model(), n) + def stats(self): + return get_model_stats(get_active_model()) + +sniffer = LiveSniffer() diff --git a/backend/extensions.py b/backend/extensions.py new file mode 100644 index 0000000000000000000000000000000000000000..2a66feb79daededb865f1497a2862bc268a7360e --- /dev/null +++ b/backend/extensions.py @@ -0,0 +1,4 @@ +# backend/extensions.py +from flask_mail import Mail + +mail = Mail() diff --git a/backend/flow_builder.py b/backend/flow_builder.py new file mode 100644 index 0000000000000000000000000000000000000000..ebd73f4d218e42a4e8ecec5746504420b1850947 --- /dev/null +++ b/backend/flow_builder.py @@ -0,0 +1,35 @@ +# flow_builder.py +from collections import defaultdict + +def build_flows(events): + flows = defaultdict(lambda: { + "src_ip": "", + "dst_ip": "", + "sport": "", + "dport": "", + "proto": "", + "packets": 0, + "bytes": 0, + "first_seen": "", + "last_seen": "", + }) + + for e in events: + key = (e["src_ip"], e["dst_ip"], e["sport"], e["dport"], e["proto"]) + f = flows[key] + + f["src_ip"] = e["src_ip"] + f["dst_ip"] = e["dst_ip"] + f["sport"] = e["sport"] + f["dport"] = e["dport"] + f["proto"] = e["proto"] + + f["packets"] += 1 + f["bytes"] += 1500 # approximation (or use real payload length if available) + + # Update timestamps + if not f["first_seen"]: + f["first_seen"] = e.get("time") + f["last_seen"] = e.get("time") + + return list(flows.values()) diff --git a/backend/generated_reports/traffic_logs.csv b/backend/generated_reports/traffic_logs.csv new file mode 100644 index 0000000000000000000000000000000000000000..6dbc0ec2d0069da2af5d1e2b36f87b9c73a234cb --- /dev/null +++ b/backend/generated_reports/traffic_logs.csv @@ -0,0 +1,8 @@ +date,VPN,TOR,I2P,DDoS +2025-11-06,3,1,0,5 +2025-11-07,4,3,1,7 +2025-11-08,7,2,0,6 +2025-11-09,5,4,2,8 +2025-11-10,2,3,1,4 +2025-11-11,6,2,1,6 +2025-11-12,3,1,0,5 diff --git a/backend/list_groq_models.py b/backend/list_groq_models.py new file mode 100644 index 0000000000000000000000000000000000000000..d3c711efba44e7ccfd01881a29f46ec4da6836ee --- /dev/null +++ b/backend/list_groq_models.py @@ -0,0 +1,13 @@ +import os +import requests + +API_KEY = os.getenv("GROQ_API_KEY") +if not API_KEY: + raise RuntimeError("Set env GROQ_API_KEY") + +resp = requests.get( + "https://api.groq.com/v1/models", + headers={"Authorization": f"Bearer {API_KEY}"} +) +print("Status:", resp.status_code) +print("Response:", resp.text) diff --git a/backend/logs/bcc_logs.csv b/backend/logs/bcc_logs.csv new file mode 100644 index 0000000000000000000000000000000000000000..67c898beaac08a5a973ab7c66724f52a04787ed4 --- /dev/null +++ b/backend/logs/bcc_logs.csv @@ -0,0 +1,3348 @@ +time,src_ip,sport,dst_ip,dport,proto,prediction,risk_level,risk_score,src_country,src_city,src_lat,src_lon,dst_country,dst_city,dst_lat,dst_lon +23:33:23,192.168.0.102,62365,142.250.67.196,443,UDP,BENIGN,Low,0,,,,,,,, +23:33:28,142.250.192.106,443,192.168.0.102,55445,UDP,Infilteration,Low,0,,,,,,,, +23:33:33,192.168.0.1,53,192.168.0.102,50570,UDP,BENIGN,Low,0,,,,,,,, +23:33:33,192.168.0.102,56399,23.64.59.50,443,TCP,BENIGN,Low,0,,,,,,,, +23:33:33,23.64.59.50,443,192.168.0.102,56399,TCP,Infilteration,Low,0,,,,,,,, +23:33:37,192.168.0.102,56300,104.18.36.252,443,TCP,BENIGN,Low,0,,,,,,,, +23:33:37,104.18.36.252,443,192.168.0.102,56300,TCP,Infilteration,Low,0,,,,,,,, +23:33:43,192.168.0.102,55445,142.250.192.106,443,UDP,BENIGN,Low,0,,,,,,,, +23:33:43,142.250.192.106,443,192.168.0.102,55445,UDP,Infilteration,Low,0,,,,,,,, +23:50:51,192.168.0.102,56300,104.18.36.252,443,TCP,BENIGN,Low,0,,,,,,,, +23:50:51,104.18.36.252,443,192.168.0.102,56300,TCP,Infilteration,Low,0,,,,,,,, +23:50:52,192.168.0.102,55445,142.250.192.106,443,UDP,BENIGN,Low,0,,,,,,,, +23:51:06,192.168.0.102,56300,104.18.36.252,443,TCP,BENIGN,Low,0,,,,,,,, +23:51:13,192.168.0.102,57058,142.250.77.99,443,TCP,BENIGN,Low,0,,,,,,,, +23:51:13,142.250.77.99,443,192.168.0.102,57058,TCP,Infilteration,Low,0,,,,,,,, +23:51:21,192.168.0.102,56300,104.18.36.252,443,TCP,BENIGN,Low,0,,,,,,,, +23:51:21,104.18.36.252,443,192.168.0.102,56300,TCP,Infilteration,Low,0,,,,,,,, +23:51:22,142.250.192.106,443,192.168.0.102,55445,UDP,Infilteration,Low,0,,,,,,,, +23:51:22,192.168.0.102,55445,142.250.192.106,443,UDP,BENIGN,Low,0,,,,,,,, +23:51:30,142.250.67.196,443,192.168.0.102,52350,UDP,Infilteration,Low,0,,,,,,,, +23:51:31,192.168.0.102,57058,142.250.77.99,443,TCP,BENIGN,Low,0,,,,,,,, +23:51:31,192.168.0.102,58911,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +23:51:31,192.168.0.1,53,192.168.0.102,50593,UDP,BENIGN,Low,0,,,,,,,, +23:51:31,192.168.0.102,61123,142.250.77.99,443,UDP,BENIGN,Low,0,,,,,,,, +23:51:31,192.168.0.102,53948,4.213.25.241,443,TCP,BENIGN,Low,0,,,,,,,, +23:51:31,142.250.77.99,443,192.168.0.102,57058,TCP,Infilteration,Low,0,,,,,,,, +23:51:31,142.250.77.99,443,192.168.0.102,61123,UDP,Infilteration,Low,0,,,,,,,, +23:51:31,4.213.25.241,443,192.168.0.102,53948,TCP,Infilteration,Low,0,,,,,,,, +23:51:36,104.18.36.252,443,192.168.0.102,56300,TCP,Infilteration,Low,0,,,,,,,, +23:51:37,192.168.0.102,55445,142.250.192.106,443,UDP,BENIGN,Low,0,,,,,,,, +23:51:38,192.168.0.102,57089,13.52.88.154,443,TCP,BENIGN,Low,0,,,,,,,, +23:51:38,13.52.88.154,443,192.168.0.102,57089,TCP,Infilteration,Low,0,,,,,,,, +23:51:40,57.144.169.33,80,192.168.0.102,55149,TCP,Infilteration,Low,0,,,,,,,, +23:51:40,192.168.0.102,55149,57.144.169.33,80,TCP,BENIGN,Low,0,,,,,,,, +00:07:30,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:30,192.168.0.102,53851,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:30,192.168.0.1,53,192.168.0.102,53851,UDP,VPN,Low,0,,,,,,,, +00:07:30,192.168.0.102,59195,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.1,53,192.168.0.102,59416,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,59195,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,59195,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,59195,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,59195,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,59195,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,57102,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,59195,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,59195,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,59195,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,57102,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,59195,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,59195,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,59195,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,59195,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,53898,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:30,104.18.1.22,443,192.168.0.102,61306,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,61306,104.18.1.22,443,UDP,VPN,Low,0,,,,,,,, +00:07:30,104.18.1.22,443,192.168.0.102,61306,UDP,TOR,Low,0,,,,,,,, +00:07:30,104.18.1.22,443,192.168.0.102,61306,UDP,TOR,Low,0,,,,,,,, +00:07:30,104.18.1.22,443,192.168.0.102,61306,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,61306,104.18.1.22,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,52350,142.250.67.196,443,UDP,FREENET,Low,0,,,,,,,, +00:07:30,104.18.1.22,443,192.168.0.102,61306,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.250.67.196,443,192.168.0.102,52350,UDP,VPN,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,60258,142.251.220.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,60258,142.251.220.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,60258,142.251.220.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,60258,142.251.220.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,60258,142.251.220.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,57109,142.251.220.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,57109,142.251.220.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,57109,TCP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,57109,TCP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,57109,142.251.220.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,60258,142.251.220.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.1,53,192.168.0.102,58723,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,57109,TCP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,58938,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,58938,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,58938,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,58938,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,58938,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,57109,142.251.220.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,58938,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:30,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,192.168.0.102,53571,64.233.170.188,5228,TCP,TOR,Low,0,,,,,,,, +00:07:30,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:30,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:30,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:30,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:30,142.251.222.74,443,192.168.0.102,58938,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,55961,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:30,192.168.0.1,53,192.168.0.102,55961,UDP,VPN,Low,0,,,,,,,, +00:07:30,192.168.0.102,51026,142.250.207.142,443,UDP,I2P,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,51026,142.250.207.142,443,UDP,I2P,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,51026,142.250.207.142,443,UDP,I2P,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,51026,142.250.207.142,443,UDP,I2P,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,51026,142.250.207.142,443,UDP,I2P,Low,0,,,,,,,, +00:07:30,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:30,142.250.67.196,443,192.168.0.102,52350,UDP,VPN,Low,0,,,,,,,, +00:07:30,192.168.0.102,61079,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,64699,34.8.7.18,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,64699,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,64699,34.8.7.18,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,192.168.0.102,57127,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,57127,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,57127,TCP,TOR,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,64699,UDP,TOR,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,64699,UDP,TOR,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,64699,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,64699,34.8.7.18,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,192.168.0.102,64699,34.8.7.18,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,64699,UDP,TOR,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,64699,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,64699,34.8.7.18,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,64699,UDP,TOR,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,57127,TCP,TOR,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,57127,TCP,TOR,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,57127,TCP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,57127,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,57127,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,57127,TCP,TOR,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,64699,UDP,TOR,Low,0,,,,,,,, +00:07:30,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,64699,34.8.7.18,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:30,34.8.7.18,443,192.168.0.102,64699,UDP,TOR,Low,0,,,,,,,, +00:07:30,192.168.0.102,59195,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,59195,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,53073,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:31,192.168.0.102,53396,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:31,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.1,53,192.168.0.102,53073,UDP,VPN,Low,0,,,,,,,, +00:07:31,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:31,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:31,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60258,142.251.220.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60258,142.251.220.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,58938,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,58938,142.251.222.74,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.74,443,192.168.0.102,58938,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60258,142.251.220.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.74,443,192.168.0.102,58938,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.251.220.42,443,192.168.0.102,60258,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:31,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:31,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:31,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:31,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:31,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:31,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:31,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,55445,142.250.192.106,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:31,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,51026,142.250.207.142,443,UDP,I2P,Low,0,,,,,,,, +00:07:31,142.250.207.142,443,192.168.0.102,51026,UDP,TOR,Low,0,,,,,,,, +00:07:31,34.8.7.18,443,192.168.0.102,64699,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.1,53,192.168.0.102,53078,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,58122,172.217.174.67,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,58122,UDP,TOR,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,58122,UDP,TOR,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,58122,UDP,TOR,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,58122,UDP,TOR,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,58122,UDP,TOR,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,58122,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,64699,34.8.7.18,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,58122,UDP,TOR,Low,0,,,,,,,, +00:07:31,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57150,140.82.114.22,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,140.82.114.22,443,192.168.0.102,57150,TCP,TOR,Low,0,,,,,,,, +00:07:31,140.82.114.22,443,192.168.0.102,57150,TCP,TOR,Low,0,,,,,,,, +00:07:31,140.82.114.22,443,192.168.0.102,57150,TCP,TOR,Low,0,,,,,,,, +00:07:31,140.82.114.22,443,192.168.0.102,57150,TCP,VPN,Low,0,,,,,,,, +00:07:31,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,57152,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,20.44.229.112,443,192.168.0.102,57152,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57152,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57152,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,20.44.229.112,443,192.168.0.102,57152,TCP,TOR,Low,0,,,,,,,, +00:07:31,20.44.229.112,443,192.168.0.102,57152,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57152,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57152,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,20.44.229.112,443,192.168.0.102,57152,TCP,TOR,Low,0,,,,,,,, +00:07:31,20.44.229.112,443,192.168.0.102,57152,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57152,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57152,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57152,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,20.44.229.112,443,192.168.0.102,57152,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57152,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.1,53,192.168.0.102,54729,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57126,142.250.207.142,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57126,142.250.207.142,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.207.142,443,192.168.0.102,57126,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.207.142,443,192.168.0.102,57126,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.207.142,443,192.168.0.102,57126,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57126,142.250.207.142,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57126,142.250.207.142,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.207.142,443,192.168.0.102,57126,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57126,142.250.207.142,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.207.142,443,192.168.0.102,57126,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57126,142.250.207.142,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.207.142,443,192.168.0.102,57126,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.207.142,443,192.168.0.102,57126,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.207.142,443,192.168.0.102,57126,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57126,142.250.207.142,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57126,142.250.207.142,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60880,142.250.77.99,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60880,142.250.77.99,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60880,142.250.77.99,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.77.99,443,192.168.0.102,60880,UDP,TOR,Low,0,,,,,,,, +00:07:31,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,52350,142.250.67.196,443,UDP,FREENET,Low,0,,,,,,,, +00:07:31,192.168.0.102,57160,142.251.222.106,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,52515,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:31,192.168.0.102,52515,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,57160,TCP,TOR,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,52515,UDP,VPN,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,52515,UDP,FREENET,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,52515,UDP,VPN,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,52515,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,52515,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:31,192.168.0.102,52515,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,52515,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,52515,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,52515,UDP,VPN,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,56343,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,56343,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56343,142.251.222.106,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57160,142.251.222.106,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,56343,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56343,142.251.222.106,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56343,142.251.222.106,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56343,142.251.222.106,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57160,142.251.222.106,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,56343,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,56343,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56343,142.251.222.106,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56343,142.251.222.106,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,56343,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,57160,TCP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,57160,TCP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,57160,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57160,142.251.222.106,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,57160,TCP,TOR,Low,0,,,,,,,, +00:07:31,142.251.222.106,443,192.168.0.102,56343,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56343,142.251.222.106,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.1,53,192.168.0.102,63243,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60051,142.250.192.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60051,142.250.192.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60051,142.250.192.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60051,142.250.192.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,60051,142.250.192.42,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.42,443,192.168.0.102,60051,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57102,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,52350,142.250.67.196,443,UDP,FREENET,Low,0,,,,,,,, +00:07:31,192.168.0.102,52350,142.250.67.196,443,UDP,FREENET,Low,0,,,,,,,, +00:07:31,192.168.0.1,36845,239.255.255.250,1900,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.1,36845,239.255.255.250,1900,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.1,36845,239.255.255.250,1900,UDP,VPN,Low,0,,,,,,,, +00:07:31,142.250.67.196,443,192.168.0.102,52350,UDP,VPN,Low,0,,,,,,,, +00:07:31,142.250.192.106,443,192.168.0.102,55445,UDP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,53571,64.233.170.188,5228,TCP,TOR,Low,0,,,,,,,, +00:07:31,172.217.174.67,443,192.168.0.102,58122,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,58122,172.217.174.67,443,UDP,TOR,Low,0,,,,,,,, +00:07:31,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:31,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:31,142.251.222.74,443,192.168.0.102,57102,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:31,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57212,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57212,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57212,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57212,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57212,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57212,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57212,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,142.250.192.74,443,192.168.0.102,57212,TCP,VPN,Low,0,,,,,,,, +00:07:31,192.168.0.102,53571,64.233.170.188,5228,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,59849,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.1,53,192.168.0.102,59849,UDP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57219,23.64.59.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:31,23.64.59.42,443,192.168.0.102,57219,TCP,TOR,Low,0,,,,,,,, +00:07:31,192.168.0.102,57219,23.64.59.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,23.64.59.42,443,192.168.0.102,57219,TCP,TOR,Low,0,,,,,,,, +00:07:32,23.64.59.42,443,192.168.0.102,57219,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57219,23.64.59.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,23.64.59.42,443,192.168.0.102,57219,TCP,TOR,Low,0,,,,,,,, +00:07:32,23.64.59.42,443,192.168.0.102,57219,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57219,23.64.59.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,23.64.59.42,443,192.168.0.102,57219,TCP,TOR,Low,0,,,,,,,, +00:07:32,23.64.59.42,443,192.168.0.102,57219,TCP,TOR,Low,0,,,,,,,, +00:07:32,23.64.59.42,443,192.168.0.102,57219,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57219,23.64.59.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57219,23.64.59.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57219,23.64.59.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,59388,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.1,53,192.168.0.102,59388,UDP,TOR,Low,0,,,,,,,, +00:07:32,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,51808,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:32,192.168.0.1,53,192.168.0.102,51808,UDP,VPN,Low,0,,,,,,,, +00:07:32,192.168.0.102,57226,20.189.173.26,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.189.173.26,443,192.168.0.102,57226,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57226,20.189.173.26,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,34.8.7.18,443,192.168.0.102,57127,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.189.173.26,443,192.168.0.102,57226,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.189.173.26,443,192.168.0.102,57226,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57226,20.189.173.26,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57226,20.189.173.26,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57226,20.189.173.26,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57226,20.189.173.26,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57226,20.189.173.26,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57226,20.189.173.26,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.189.173.26,443,192.168.0.102,57226,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.189.173.26,443,192.168.0.102,57226,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.189.173.26,443,192.168.0.102,57226,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.189.173.26,443,192.168.0.102,57226,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57226,20.189.173.26,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:32,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,52350,142.250.67.196,443,UDP,FREENET,Low,0,,,,,,,, +00:07:32,142.250.67.196,443,192.168.0.102,52350,UDP,VPN,Low,0,,,,,,,, +00:07:32,192.168.0.102,62109,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:32,192.168.0.102,57240,64.233.170.95,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57240,64.233.170.95,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57240,64.233.170.95,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57240,64.233.170.95,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,64.233.170.95,443,192.168.0.102,57240,TCP,TOR,Low,0,,,,,,,, +00:07:32,64.233.170.95,443,192.168.0.102,57240,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57240,64.233.170.95,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,64.233.170.95,443,192.168.0.102,57240,TCP,TOR,Low,0,,,,,,,, +00:07:32,64.233.170.95,443,192.168.0.102,57240,TCP,TOR,Low,0,,,,,,,, +00:07:32,64.233.170.95,443,192.168.0.102,57240,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57240,64.233.170.95,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,64.233.170.95,443,192.168.0.102,57240,TCP,TOR,Low,0,,,,,,,, +00:07:32,64.233.170.95,443,192.168.0.102,57240,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:32,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.1,53,192.168.0.102,59220,UDP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57259,20.50.73.11,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.50.73.11,443,192.168.0.102,57259,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57259,20.50.73.11,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57259,20.50.73.11,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.50.73.11,443,192.168.0.102,57259,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57259,20.50.73.11,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.50.73.11,443,192.168.0.102,57259,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.50.73.11,443,192.168.0.102,57259,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.50.73.11,443,192.168.0.102,57259,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57259,20.50.73.11,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57259,20.50.73.11,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.50.73.11,443,192.168.0.102,57259,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.50.73.11,443,192.168.0.102,57259,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.50.73.11,443,192.168.0.102,57259,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.50.73.11,443,192.168.0.102,57259,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57259,20.50.73.11,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57259,20.50.73.11,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.50.73.11,443,192.168.0.102,57259,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57061,20.42.65.84,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,20.42.65.84,443,192.168.0.102,57061,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.106,443,192.168.0.102,57160,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.74,443,192.168.0.102,57102,TCP,TOR,Low,0,,,,,,,, +00:07:32,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,52350,142.250.67.196,443,UDP,FREENET,Low,0,,,,,,,, +00:07:32,142.251.220.42,443,192.168.0.102,57109,TCP,TOR,Low,0,,,,,,,, +00:07:32,64.233.170.188,5228,192.168.0.102,53571,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57240,64.233.170.95,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,64.233.170.95,443,192.168.0.102,57240,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,63991,192.168.0.1,53,UDP,ZERONET,Low,0,,,,,,,, +00:07:32,192.168.0.102,57102,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57127,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.1,53,192.168.0.102,64581,UDP,TOR,Low,0,,,,,,,, +00:07:32,104.18.0.22,443,192.168.0.102,53847,UDP,TOR,Low,0,,,,,,,, +00:07:32,142.251.220.42,443,192.168.0.102,57109,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57109,142.251.220.42,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,34.8.7.18,443,192.168.0.102,57127,TCP,TOR,Low,0,,,,,,,, +00:07:32,142.251.222.106,443,192.168.0.102,57160,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57127,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,53847,104.18.0.22,443,UDP,FREENET,Low,0,,,,,,,, +00:07:32,104.18.0.22,443,192.168.0.102,53847,UDP,TOR,Low,0,,,,,,,, +00:07:32,104.18.0.22,443,192.168.0.102,53847,UDP,TOR,Low,0,,,,,,,, +00:07:32,104.18.0.22,443,192.168.0.102,53847,UDP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.1,53,192.168.0.102,53433,UDP,VPN,Low,0,,,,,,,, +00:07:32,192.168.0.1,53,192.168.0.102,64065,UDP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,51915,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:32,192.168.0.102,56078,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:32,192.168.0.1,53,192.168.0.102,51915,UDP,VPN,Low,0,,,,,,,, +00:07:32,192.168.0.1,53,192.168.0.102,56078,UDP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,53721,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:07:32,142.250.77.99,443,192.168.0.102,53721,UDP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,53721,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:07:32,192.168.0.102,53721,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:07:32,192.168.0.102,53721,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:07:32,192.168.0.102,53721,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:07:32,142.250.77.99,443,192.168.0.102,53721,UDP,TOR,Low,0,,,,,,,, +00:07:32,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.1,53,192.168.0.102,63562,UDP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:32,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:32,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57287,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.217.174.234,443,192.168.0.102,57287,TCP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57402,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,51400,142.250.207.142,443,UDP,I2P,Low,0,,,,,,,, +00:07:33,192.168.0.102,51400,142.250.207.142,443,UDP,I2P,Low,0,,,,,,,, +00:07:33,142.250.207.142,443,192.168.0.102,51400,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,51400,142.250.207.142,443,UDP,I2P,Low,0,,,,,,,, +00:07:33,142.250.207.142,443,192.168.0.102,51400,UDP,VPN,Low,0,,,,,,,, +00:07:33,142.250.207.142,443,192.168.0.102,51400,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,51400,142.250.207.142,443,UDP,I2P,Low,0,,,,,,,, +00:07:33,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:33,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.1,36845,239.255.255.250,1900,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.1,36845,239.255.255.250,1900,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,57298,72.145.35.118,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57298,72.145.35.118,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,72.145.35.118,443,192.168.0.102,57298,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57298,72.145.35.118,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57298,72.145.35.118,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57298,72.145.35.118,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57298,72.145.35.118,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57298,72.145.35.118,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,72.145.35.118,443,192.168.0.102,57298,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57298,72.145.35.118,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,72.145.35.118,443,192.168.0.102,57298,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,53631,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.1,53,192.168.0.102,53631,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,57299,23.62.40.63,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,23.62.40.63,443,192.168.0.102,57299,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57299,23.62.40.63,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57298,72.145.35.118,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,23.62.40.63,443,192.168.0.102,57299,TCP,TOR,Low,0,,,,,,,, +00:07:33,23.62.40.63,443,192.168.0.102,57299,TCP,TOR,Low,0,,,,,,,, +00:07:33,23.62.40.63,443,192.168.0.102,57299,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57299,23.62.40.63,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,23.62.40.63,443,192.168.0.102,57299,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57299,23.62.40.63,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57240,64.233.170.95,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,64.233.170.95,443,192.168.0.102,57240,TCP,TOR,Low,0,,,,,,,, +00:07:33,142.250.67.196,443,192.168.0.102,52350,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:33,142.250.67.196,443,192.168.0.102,57981,UDP,TOR,Low,0,,,,,,,, +00:07:33,142.250.67.196,443,192.168.0.102,57981,UDP,TOR,Low,0,,,,,,,, +00:07:33,142.250.67.196,443,192.168.0.102,57981,UDP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:33,142.250.67.196,443,192.168.0.102,57981,UDP,TOR,Low,0,,,,,,,, +00:07:33,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:33,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:33,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:33,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:33,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:33,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:33,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,57240,64.233.170.95,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,64.233.170.95,443,192.168.0.102,57240,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57240,64.233.170.95,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57241,142.251.222.74,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,142.251.222.74,443,192.168.0.102,57241,TCP,TOR,Low,0,,,,,,,, +00:07:33,142.250.67.196,443,192.168.0.102,57981,UDP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,65000,192.168.0.1,53,UDP,I2P,Low,0,,,,,,,, +00:07:33,192.168.0.1,53,192.168.0.102,52082,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.1,53,192.168.0.102,65000,UDP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,58606,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,FREENET,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,FREENET,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,57328,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,57328,172.67.73.182,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,57328,172.67.73.182,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,192.168.0.102,57328,172.67.73.182,443,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,57328,TCP,TOR,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:33,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,57328,TCP,TOR,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,57328,TCP,TOR,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,172.67.73.182,443,192.168.0.102,52296,UDP,VPN,Low,0,,,,,,,, +00:07:34,192.168.0.102,57328,172.67.73.182,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,52296,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57801,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57801,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,34.8.7.18,443,192.168.0.102,57801,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57801,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:34,34.8.7.18,443,192.168.0.102,57330,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57330,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,34.8.7.18,443,192.168.0.102,57801,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57801,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57801,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:34,34.8.7.18,443,192.168.0.102,57801,UDP,TOR,Low,0,,,,,,,, +00:07:34,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,52435,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,55315,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.1,53,192.168.0.102,55315,UDP,VPN,Low,0,,,,,,,, +00:07:34,192.168.0.102,57331,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57331,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57331,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,172.64.155.209,443,192.168.0.102,57331,TCP,TOR,Low,0,,,,,,,, +00:07:34,172.64.155.209,443,192.168.0.102,57331,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57331,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,34.8.7.18,443,192.168.0.102,57330,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57331,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57330,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57331,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57331,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,34.8.7.18,443,192.168.0.102,57330,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57801,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57331,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57801,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:34,34.8.7.18,443,192.168.0.102,57801,UDP,TOR,Low,0,,,,,,,, +00:07:34,4.213.25.241,443,192.168.0.102,53948,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:34,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.1,53,192.168.0.102,57466,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57338,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,20.44.229.112,443,192.168.0.102,57338,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57338,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57338,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57338,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,20.44.229.112,443,192.168.0.102,57338,TCP,TOR,Low,0,,,,,,,, +00:07:34,20.44.229.112,443,192.168.0.102,57338,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57338,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.1,53,192.168.0.102,56915,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,53569,142.251.220.10,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,53569,142.251.220.10,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,53569,142.251.220.10,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,57346,142.251.220.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,142.251.220.10,443,192.168.0.102,53569,UDP,VPN,Low,0,,,,,,,, +00:07:34,192.168.0.102,57346,142.251.220.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,53569,142.251.220.10,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,53569,142.251.220.10,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,142.251.220.10,443,192.168.0.102,57346,TCP,TOR,Low,0,,,,,,,, +00:07:34,142.251.220.10,443,192.168.0.102,57346,TCP,TOR,Low,0,,,,,,,, +00:07:34,142.251.220.10,443,192.168.0.102,57346,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57346,142.251.220.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,142.251.220.10,443,192.168.0.102,53569,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,53569,142.251.220.10,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,53569,142.251.220.10,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,142.251.220.10,443,192.168.0.102,53569,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,53569,142.251.220.10,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,64.233.170.188,5228,192.168.0.102,53571,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,53569,142.251.220.10,443,UDP,FREENET,Low,0,,,,,,,, +00:07:34,192.168.0.102,57346,142.251.220.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,60805,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.1,53,192.168.0.102,60805,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.1,53,192.168.0.102,52686,UDP,VPN,Low,0,,,,,,,, +00:07:34,192.168.0.102,64093,142.250.207.142,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:34,142.250.207.142,443,192.168.0.102,64093,UDP,TOR,Low,0,,,,,,,, +00:07:34,142.250.207.142,443,192.168.0.102,64093,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,64093,142.250.207.142,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:34,192.168.0.102,64093,142.250.207.142,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:34,142.250.207.142,443,192.168.0.102,64093,UDP,TOR,Low,0,,,,,,,, +00:07:34,142.250.207.142,443,192.168.0.102,64093,UDP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,142.250.207.142,443,192.168.0.102,64093,UDP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,64093,142.250.207.142,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:34,142.250.207.142,443,192.168.0.102,64093,UDP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,172.64.155.209,443,192.168.0.102,57331,TCP,TOR,Low,0,,,,,,,, +00:07:34,172.64.155.209,443,192.168.0.102,57331,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57331,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:34,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,150.171.27.12,443,192.168.0.102,57352,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:35,23.218.158.211,443,192.168.0.102,58329,UDP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57331,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,104.18.32.47,443,192.168.0.102,57323,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57323,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57330,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57355,50.112.39.233,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.1,53,192.168.0.102,57148,UDP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,50957,35.244.251.182,443,UDP,I2P,Low,0,,,,,,,, +00:07:35,35.244.251.182,443,192.168.0.102,50957,UDP,TOR,Low,0,,,,,,,, +00:07:35,35.244.251.182,443,192.168.0.102,50957,UDP,TOR,Low,0,,,,,,,, +00:07:35,35.244.251.182,443,192.168.0.102,50957,UDP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,50957,35.244.251.182,443,UDP,I2P,Low,0,,,,,,,, +00:07:35,192.168.0.102,50957,35.244.251.182,443,UDP,I2P,Low,0,,,,,,,, +00:07:35,192.168.0.102,50957,35.244.251.182,443,UDP,I2P,Low,0,,,,,,,, +00:07:35,192.168.0.102,50957,35.244.251.182,443,UDP,I2P,Low,0,,,,,,,, +00:07:35,35.244.251.182,443,192.168.0.102,50957,UDP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,50957,35.244.251.182,443,UDP,I2P,Low,0,,,,,,,, +00:07:35,50.112.39.233,443,192.168.0.102,57355,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57355,50.112.39.233,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,61157,192.168.0.1,53,UDP,VPN,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,35.244.251.182,443,192.168.0.102,50957,UDP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,50.112.39.233,443,192.168.0.102,57355,TCP,TOR,Low,0,,,,,,,, +00:07:35,50.112.39.233,443,192.168.0.102,57355,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57355,50.112.39.233,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,35.244.251.182,443,192.168.0.102,50957,UDP,TOR,Low,0,,,,,,,, +00:07:35,13.107.213.58,443,192.168.0.102,57356,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,56708,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:35,50.112.39.233,443,192.168.0.102,57355,TCP,TOR,Low,0,,,,,,,, +00:07:35,50.112.39.233,443,192.168.0.102,57355,TCP,TOR,Low,0,,,,,,,, +00:07:35,50.112.39.233,443,192.168.0.102,57355,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57355,50.112.39.233,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57357,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57359,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,23.212.254.115,443,192.168.0.102,57359,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57359,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57357,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57357,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57357,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:35,192.168.0.102,57359,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57355,50.112.39.233,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,52224,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,55236,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:36,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:36,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:36,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:36,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:36,3.233.158.25,443,192.168.0.102,57375,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57375,3.233.158.25,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,3.233.158.25,443,192.168.0.102,57375,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57375,3.233.158.25,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57375,3.233.158.25,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57375,3.233.158.25,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,3.233.158.25,443,192.168.0.102,57375,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57375,3.233.158.25,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,142.250.67.196,443,192.168.0.102,57981,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,53571,64.233.170.188,5228,TCP,TOR,Low,0,,,,,,,, +00:07:36,64.233.170.188,5228,192.168.0.102,53571,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.62.40.63,443,192.168.0.102,57299,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57298,72.145.35.118,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,72.145.35.118,443,192.168.0.102,57298,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,56572,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,52753,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:36,192.168.0.1,53,192.168.0.102,52753,UDP,VPN,Low,0,,,,,,,, +00:07:36,192.168.0.102,58201,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,58201,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57392,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57392,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,34.8.7.18,443,192.168.0.102,58201,UDP,TOR,Low,0,,,,,,,, +00:07:36,34.8.7.18,443,192.168.0.102,57392,TCP,TOR,Low,0,,,,,,,, +00:07:36,34.8.7.18,443,192.168.0.102,58201,UDP,TOR,Low,0,,,,,,,, +00:07:36,34.8.7.18,443,192.168.0.102,58201,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,58201,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,58201,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,58201,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,34.8.7.18,443,192.168.0.102,57392,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57392,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:36,172.64.155.209,443,192.168.0.102,57362,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57362,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57362,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57362,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,172.64.155.209,443,192.168.0.102,57362,TCP,TOR,Low,0,,,,,,,, +00:07:36,172.64.155.209,443,192.168.0.102,57362,TCP,TOR,Low,0,,,,,,,, +00:07:36,172.64.155.209,443,192.168.0.102,57362,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57362,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57362,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,172.64.155.209,443,192.168.0.102,57362,TCP,TOR,Low,0,,,,,,,, +00:07:36,172.64.155.209,443,192.168.0.102,57362,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57362,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,56648,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57363,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,52.168.117.174,443,192.168.0.102,57363,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57363,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57363,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57363,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57363,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,52.168.117.174,443,192.168.0.102,57363,TCP,TOR,Low,0,,,,,,,, +00:07:36,52.168.117.174,443,192.168.0.102,57363,TCP,TOR,Low,0,,,,,,,, +00:07:36,52.168.117.174,443,192.168.0.102,57363,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57356,13.107.213.58,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57355,50.112.39.233,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57362,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,172.64.155.209,443,192.168.0.102,57362,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57362,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,50.112.39.233,443,192.168.0.102,57355,TCP,TOR,Low,0,,,,,,,, +00:07:36,50.112.39.233,443,192.168.0.102,57355,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,142.250.67.196,443,192.168.0.102,57981,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,34.8.7.18,443,192.168.0.102,57392,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:36,142.250.207.142,443,192.168.0.102,52178,UDP,TOR,Low,0,,,,,,,, +00:07:36,142.250.207.142,443,192.168.0.102,52178,UDP,TOR,Low,0,,,,,,,, +00:07:36,142.250.207.142,443,192.168.0.102,52178,UDP,TOR,Low,0,,,,,,,, +00:07:36,142.250.207.142,443,192.168.0.102,52178,UDP,TOR,Low,0,,,,,,,, +00:07:36,142.250.207.142,443,192.168.0.102,52178,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:36,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:36,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:36,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:36,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:36,142.250.207.142,443,192.168.0.102,52178,UDP,VPN,Low,0,,,,,,,, +00:07:36,192.168.0.102,57338,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,20.44.229.112,443,192.168.0.102,57396,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,20.44.229.112,443,192.168.0.102,57396,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,142.250.207.142,443,192.168.0.102,52178,UDP,VPN,Low,0,,,,,,,, +00:07:36,142.250.207.142,443,192.168.0.102,52178,UDP,VPN,Low,0,,,,,,,, +00:07:36,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:36,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,20.44.229.112,443,192.168.0.102,57396,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,20.44.229.112,443,192.168.0.102,57396,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.1,53,192.168.0.102,54416,UDP,VPN,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57352,150.171.27.12,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,54587,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:36,192.168.0.102,51552,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.1,53,192.168.0.102,51552,UDP,VPN,Low,0,,,,,,,, +00:07:36,192.168.0.102,54803,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:36,172.217.174.67,443,192.168.0.102,54803,UDP,VPN,Low,0,,,,,,,, +00:07:36,172.217.174.67,443,192.168.0.102,54803,UDP,TOR,Low,0,,,,,,,, +00:07:36,172.217.174.67,443,192.168.0.102,54803,UDP,TOR,Low,0,,,,,,,, +00:07:36,172.217.174.67,443,192.168.0.102,54803,UDP,TOR,Low,0,,,,,,,, +00:07:36,172.217.174.67,443,192.168.0.102,54803,UDP,TOR,Low,0,,,,,,,, +00:07:36,172.217.174.67,443,192.168.0.102,54803,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,54803,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:36,172.217.174.67,443,192.168.0.102,54803,UDP,VPN,Low,0,,,,,,,, +00:07:36,172.217.174.67,443,192.168.0.102,54803,UDP,VPN,Low,0,,,,,,,, +00:07:36,192.168.0.102,54803,172.217.174.67,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,172.217.174.67,443,192.168.0.102,54803,UDP,FREENET,Low,0,,,,,,,, +00:07:36,192.168.0.102,54803,172.217.174.67,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,58201,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,34.8.7.18,443,192.168.0.102,58201,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,58201,34.8.7.18,443,UDP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:36,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:36,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:37,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:37,172.64.155.209,443,192.168.0.102,57416,TCP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:37,172.64.155.209,443,192.168.0.102,57416,TCP,TOR,Low,0,,,,,,,, +00:07:37,172.64.155.209,443,192.168.0.102,57416,TCP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:37,172.64.155.209,443,192.168.0.102,57416,TCP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:37,172.64.155.209,443,192.168.0.102,57416,TCP,TOR,Low,0,,,,,,,, +00:07:37,172.64.155.209,443,192.168.0.102,57416,TCP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:37,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,142.250.207.142,443,192.168.0.102,52178,UDP,VPN,Low,0,,,,,,,, +00:07:38,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,142.250.207.142,443,192.168.0.102,52178,UDP,VPN,Low,0,,,,,,,, +00:07:38,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,52178,142.250.207.142,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,54091,172.67.73.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,172.67.73.182,443,192.168.0.102,54091,UDP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,3.233.158.25,443,192.168.0.102,57375,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,172.64.155.209,443,192.168.0.102,57416,TCP,TOR,Low,0,,,,,,,, +00:07:38,172.64.155.209,443,192.168.0.102,57416,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.1,53,192.168.0.102,54924,UDP,VPN,Low,0,,,,,,,, +00:07:38,192.168.0.102,52176,35.244.251.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,52176,35.244.251.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,35.244.251.182,443,192.168.0.102,52176,UDP,VPN,Low,0,,,,,,,, +00:07:38,35.244.251.182,443,192.168.0.102,52176,UDP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,52176,35.244.251.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,52176,35.244.251.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,35.244.251.182,443,192.168.0.102,52176,UDP,TOR,Low,0,,,,,,,, +00:07:38,35.244.251.182,443,192.168.0.102,52176,UDP,VPN,Low,0,,,,,,,, +00:07:38,35.244.251.182,443,192.168.0.102,52176,UDP,VPN,Low,0,,,,,,,, +00:07:38,192.168.0.102,52176,35.244.251.182,443,UDP,FREENET,Low,0,,,,,,,, +00:07:38,192.168.0.102,57424,35.162.37.145,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,35.244.251.182,443,192.168.0.102,52176,UDP,VPN,Low,0,,,,,,,, +00:07:38,35.162.37.145,443,192.168.0.102,57424,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57424,35.162.37.145,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57424,35.162.37.145,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57424,35.162.37.145,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,35.162.37.145,443,192.168.0.102,57424,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:38,142.250.67.196,443,192.168.0.102,57981,UDP,TOR,Low,0,,,,,,,, +00:07:38,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.64.155.209,443,192.168.0.102,57416,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.64.155.209,443,192.168.0.102,57416,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.217.174.67,443,192.168.0.102,54803,UDP,VPN,Low,0,,,,,,,, +00:07:39,192.168.0.102,54803,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:39,172.217.174.67,443,192.168.0.102,54803,UDP,VPN,Low,0,,,,,,,, +00:07:39,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:39,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:39,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:39,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57367,104.18.32.47,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.44.229.112,443,192.168.0.102,57396,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.44.229.112,443,192.168.0.102,57396,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.44.229.112,443,192.168.0.102,57396,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57396,20.44.229.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.44.229.112,443,192.168.0.102,57396,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.44.229.112,443,192.168.0.102,57396,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,63930,192.168.0.1,53,UDP,ZERONET,Low,0,,,,,,,, +00:07:39,192.168.0.102,60424,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.1,53,192.168.0.102,63930,UDP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.1,53,192.168.0.102,60424,UDP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57430,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57430,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57430,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.64.151.4,443,192.168.0.102,57430,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57430,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57430,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57430,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57430,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.64.151.4,443,192.168.0.102,57430,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.64.151.4,443,192.168.0.102,57430,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57430,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.64.151.4,443,192.168.0.102,57430,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.64.151.4,443,192.168.0.102,57430,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57430,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.64.151.4,443,192.168.0.102,57430,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.64.151.4,443,192.168.0.102,57430,TCP,TOR,Low,0,,,,,,,, +00:07:39,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57392,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,34.8.7.18,443,192.168.0.102,57392,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57434,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.217.174.234,443,192.168.0.102,57434,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57434,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57434,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.217.174.234,443,192.168.0.102,57434,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.217.174.234,443,192.168.0.102,57434,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.217.174.234,443,192.168.0.102,57434,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57434,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57434,172.217.174.234,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,172.217.174.234,443,192.168.0.102,57434,TCP,VPN,Low,0,,,,,,,, +00:07:39,192.168.0.102,57375,3.233.158.25,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57360,23.218.158.211,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57358,23.212.254.115,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,58748,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57440,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57440,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57440,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57440,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57440,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57440,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57440,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57440,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57440,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,60655,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57440,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,62147,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:07:39,192.168.0.102,57375,3.233.158.25,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57375,3.233.158.25,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.1,53,192.168.0.102,62147,UDP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,3.233.158.112,443,192.168.0.102,57443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57443,3.233.158.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,3.233.158.112,443,192.168.0.102,57443,TCP,TOR,Low,0,,,,,,,, +00:07:39,3.233.158.112,443,192.168.0.102,57443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57443,3.233.158.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,3.233.158.112,443,192.168.0.102,57443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57443,3.233.158.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,3.233.158.112,443,192.168.0.102,57443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.1,53,192.168.0.102,64342,UDP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.1,53,192.168.0.102,54895,UDP,VPN,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57443,3.233.158.112,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57451,4.225.11.192,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57451,4.225.11.192,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57451,4.225.11.192,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57451,4.225.11.192,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57451,4.225.11.192,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57451,4.225.11.192,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57451,4.225.11.192,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57451,4.225.11.192,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57451,4.225.11.192,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,4.225.11.192,443,192.168.0.102,57451,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57451,4.225.11.192,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:39,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:39,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57442,142.250.67.170,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.170,443,192.168.0.102,57442,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57981,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:39,142.250.67.196,443,192.168.0.102,57981,UDP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57444,20.189.173.10,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,20.189.173.10,443,192.168.0.102,57444,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,55344,172.217.174.67,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:39,192.168.0.102,55344,172.217.174.67,443,UDP,ZERONET,Low,0,,,,,,,, +00:07:39,192.168.0.102,55344,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:39,172.217.174.67,443,192.168.0.102,55344,UDP,VPN,Low,0,,,,,,,, +00:07:39,172.217.174.67,443,192.168.0.102,55344,UDP,TOR,Low,0,,,,,,,, +00:07:39,172.217.174.67,443,192.168.0.102,55344,UDP,TOR,Low,0,,,,,,,, +00:07:39,172.217.174.67,443,192.168.0.102,55344,UDP,VPN,Low,0,,,,,,,, +00:07:39,192.168.0.102,55344,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:39,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:39,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:39,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:39,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:39,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,56300,104.18.36.252,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,104.18.36.252,443,192.168.0.102,56300,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,64290,192.168.0.1,53,UDP,ZERONET,Low,0,,,,,,,, +00:07:39,192.168.0.1,53,192.168.0.102,64290,UDP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:39,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:39,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,23.218.158.211,443,192.168.0.102,57360,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:40,23.212.254.115,443,192.168.0.102,57358,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,140.82.114.21,443,192.168.0.102,57461,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57461,140.82.114.21,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,35.162.37.145,443,192.168.0.102,57424,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57416,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,104.18.32.47,443,192.168.0.102,57367,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57430,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:40,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:40,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:40,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:40,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57810,13.107.5.93,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,13.107.5.93,443,192.168.0.102,57810,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:07:40,172.64.151.4,443,192.168.0.102,57715,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57715,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,172.64.151.4,443,192.168.0.102,57715,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57715,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,172.64.151.4,443,192.168.0.102,57715,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57715,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:40,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:41,192.168.0.102,53571,64.233.170.188,5228,TCP,TOR,Low,0,,,,,,,, +00:07:41,192.168.0.102,53571,64.233.170.188,5228,TCP,TOR,Low,0,,,,,,,, +00:07:41,64.233.170.188,5228,192.168.0.102,53571,TCP,TOR,Low,0,,,,,,,, +00:07:41,64.233.170.188,5228,192.168.0.102,53571,TCP,TOR,Low,0,,,,,,,, +00:07:42,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:42,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:42,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:42,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:42,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:45,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:45,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:45,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:45,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.102,57633,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.102,50496,192.168.0.1,53,UDP,I2P,Low,0,,,,,,,, +00:07:45,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.102,57633,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.102,50496,192.168.0.1,53,UDP,I2P,Low,0,,,,,,,, +00:07:45,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.1,53,192.168.0.102,57633,UDP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.1,53,192.168.0.102,50496,UDP,VPN,Low,0,,,,,,,, +00:07:45,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:45,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:45,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:45,192.168.0.102,52626,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:45,192.168.0.102,52626,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,TOR,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,VPN,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,TOR,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,VPN,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,VPN,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,VPN,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,VPN,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,TOR,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,VPN,Low,0,,,,,,,, +00:07:45,192.168.0.102,52626,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,VPN,Low,0,,,,,,,, +00:07:45,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,VPN,Low,0,,,,,,,, +00:07:45,192.168.0.102,52626,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,VPN,Low,0,,,,,,,, +00:07:45,172.217.174.67,443,192.168.0.102,52626,UDP,VPN,Low,0,,,,,,,, +00:07:46,44.246.53.134,443,192.168.0.102,57774,TCP,TOR,Low,0,,,,,,,, +00:07:46,44.246.53.134,443,192.168.0.102,57774,TCP,TOR,Low,0,,,,,,,, +00:07:46,192.168.0.102,57774,44.246.53.134,443,TCP,TOR,Low,0,,,,,,,, +00:07:46,192.168.0.102,57774,44.246.53.134,443,TCP,TOR,Low,0,,,,,,,, +00:07:47,44.246.53.134,443,192.168.0.102,57774,TCP,TOR,Low,0,,,,,,,, +00:07:49,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:49,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:49,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:49,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:49,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:49,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:49,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:49,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:49,192.168.0.102,60980,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:49,192.168.0.102,60980,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:49,192.168.0.102,60980,142.250.67.196,443,UDP,TOR,Low,0,,,,,,,, +00:07:49,142.250.67.196,443,192.168.0.102,60980,UDP,TOR,Low,0,,,,,,,, +00:07:49,142.250.67.196,443,192.168.0.102,60980,UDP,TOR,Low,0,,,,,,,, +00:07:50,192.168.0.102,53948,4.213.25.241,443,TCP,FREENET,Low,0,,,,,,,, +00:07:50,4.213.25.241,443,192.168.0.102,53948,TCP,TOR,Low,0,,,,,,,, +00:07:52,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:52,192.168.0.102,55149,57.144.169.33,80,TCP,FREENET,Low,0,,,,,,,, +00:07:52,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:52,57.144.169.33,80,192.168.0.102,55149,TCP,VPN,Low,0,,,,,,,, +00:07:53,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:53,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:53,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:53,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:53,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:53,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:53,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:53,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:54,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:54,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:07:54,172.64.151.4,443,192.168.0.102,57715,TCP,TOR,Low,0,,,,,,,, +00:07:55,192.168.0.102,57715,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:55,192.168.0.102,57715,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:07:55,172.64.151.4,443,192.168.0.102,57715,TCP,TOR,Low,0,,,,,,,, +00:07:55,172.64.151.4,443,192.168.0.102,57715,TCP,TOR,Low,0,,,,,,,, +00:07:55,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:55,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:55,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:55,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:55,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:55,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:55,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:55,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:55,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:59,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:59,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:59,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:07:59,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:59,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:07:59,192.168.0.102,57713,172.64.155.209,443,TCP,TOR,Low,0,,,,,,,, +00:08:03,172.64.155.209,443,192.168.0.102,57713,TCP,TOR,Low,0,,,,,,,, +00:08:03,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:03,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:03,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:03,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:03,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:03,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:07,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:07,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:07,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:07,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:07,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:07,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:07,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:08,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:09,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:09,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:09,172.64.151.4,443,192.168.0.102,57715,TCP,TOR,Low,0,,,,,,,, +00:08:09,192.168.0.102,57715,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:08:09,192.168.0.102,57715,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:08:09,172.64.151.4,443,192.168.0.102,57715,TCP,TOR,Low,0,,,,,,,, +00:08:09,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:09,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:09,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:09,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:09,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:10,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:10,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:10,192.168.0.102,57844,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:08:11,192.168.0.102,57844,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +00:08:11,34.8.7.18,443,192.168.0.102,57844,TCP,TOR,Low,0,,,,,,,, +00:08:11,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:11,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:11,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:11,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:11,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,65185,104.18.1.22,443,UDP,I2P,Low,0,,,,,,,, +00:08:15,192.168.0.102,65185,104.18.1.22,443,UDP,I2P,Low,0,,,,,,,, +00:08:15,192.168.0.102,65185,104.18.1.22,443,UDP,I2P,Low,0,,,,,,,, +00:08:15,104.18.1.22,443,192.168.0.102,65185,UDP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,65185,104.18.1.22,443,UDP,I2P,Low,0,,,,,,,, +00:08:15,192.168.0.102,65185,104.18.1.22,443,UDP,I2P,Low,0,,,,,,,, +00:08:15,104.18.1.22,443,192.168.0.102,65185,UDP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,65185,104.18.1.22,443,UDP,I2P,Low,0,,,,,,,, +00:08:15,104.18.1.22,443,192.168.0.102,65185,UDP,TOR,Low,0,,,,,,,, +00:08:15,104.18.1.22,443,192.168.0.102,65185,UDP,TOR,Low,0,,,,,,,, +00:08:15,104.18.1.22,443,192.168.0.102,65185,UDP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,65185,104.18.1.22,443,UDP,I2P,Low,0,,,,,,,, +00:08:15,104.18.1.22,443,192.168.0.102,65185,UDP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,65185,104.18.1.22,443,UDP,I2P,Low,0,,,,,,,, +00:08:15,192.168.0.102,65185,104.18.1.22,443,UDP,I2P,Low,0,,,,,,,, +00:08:15,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:15,104.18.1.22,443,192.168.0.102,65185,UDP,TOR,Low,0,,,,,,,, +00:08:15,192.168.0.102,65185,104.18.1.22,443,UDP,I2P,Low,0,,,,,,,, +00:08:15,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:15,142.250.67.196,443,192.168.0.102,60980,UDP,TOR,Low,0,,,,,,,, +00:08:16,142.250.67.196,443,192.168.0.102,60980,UDP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,49975,192.168.0.1,53,UDP,I2P,Low,0,,,,,,,, +00:08:16,192.168.0.1,53,192.168.0.102,49975,UDP,VPN,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:16,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:16,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:16,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:16,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:16,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:16,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,51540,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,51540,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.1,53,192.168.0.102,51540,UDP,VPN,Low,0,,,,,,,, +00:08:17,192.168.0.102,58018,192.168.0.1,53,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.1,53,192.168.0.102,51540,UDP,VPN,Low,0,,,,,,,, +00:08:17,192.168.0.1,53,192.168.0.102,58018,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,52882,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:08:17,192.168.0.102,52882,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:08:17,192.168.0.102,52882,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:08:17,192.168.0.102,52882,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:08:17,192.168.0.102,52882,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,VPN,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,TOR,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,VPN,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,TOR,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,VPN,Low,0,,,,,,,, +00:08:17,192.168.0.102,52882,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:08:17,192.168.0.102,52882,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,TOR,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,VPN,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,VPN,Low,0,,,,,,,, +00:08:17,192.168.0.102,52882,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,TOR,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,VPN,Low,0,,,,,,,, +00:08:17,192.168.0.102,52882,142.250.77.99,443,UDP,FREENET,Low,0,,,,,,,, +00:08:17,142.250.77.99,443,192.168.0.102,52882,UDP,VPN,Low,0,,,,,,,, +00:08:17,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:17,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:17,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:17,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:17,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:17,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:17,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:17,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:18,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:18,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:18,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:18,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57866,142.250.70.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:18,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:18,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,142.250.70.74,443,192.168.0.102,57866,TCP,TOR,Low,0,,,,,,,, +00:08:18,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57781,172.217.174.234,443,UDP,TOR,Low,0,,,,,,,, +00:08:18,172.217.174.234,443,192.168.0.102,57781,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:18,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:18,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:18,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:18,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:18,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:18,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.192.106,443,192.168.0.102,63360,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,63360,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.76.170,443,192.168.0.102,57839,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.76.170,443,192.168.0.102,57839,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.76.170,443,192.168.0.102,57839,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.76.170,443,192.168.0.102,57839,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.76.170,443,192.168.0.102,57839,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.76.170,443,192.168.0.102,57839,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.76.170,443,192.168.0.102,57839,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,142.250.76.170,443,192.168.0.102,57839,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:19,142.250.76.170,443,192.168.0.102,57839,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,192.168.0.102,57839,142.250.76.170,443,UDP,TOR,Low,0,,,,,,,, +00:08:19,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:19,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:20,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:20,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,61412,192.168.0.1,53,UDP,I2P,Low,0,,,,,,,, +00:08:23,192.168.0.1,53,192.168.0.102,61412,UDP,TOR,Low,0,,,,,,,, +00:08:23,172.217.174.74,443,192.168.0.102,57884,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,57884,172.217.174.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,172.217.174.74,443,192.168.0.102,57884,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,57884,172.217.174.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,57884,172.217.174.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,57884,172.217.174.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,57884,172.217.174.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,172.217.174.74,443,192.168.0.102,57884,TCP,TOR,Low,0,,,,,,,, +00:08:23,172.217.174.74,443,192.168.0.102,57884,TCP,TOR,Low,0,,,,,,,, +00:08:23,172.217.174.74,443,192.168.0.102,57884,TCP,TOR,Low,0,,,,,,,, +00:08:23,172.217.174.74,443,192.168.0.102,57884,TCP,TOR,Low,0,,,,,,,, +00:08:23,172.217.174.74,443,192.168.0.102,57884,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,57884,172.217.174.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,57884,172.217.174.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,57884,172.217.174.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,57884,172.217.174.74,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,172.217.174.74,443,192.168.0.102,57884,TCP,VPN,Low,0,,,,,,,, +00:08:23,172.217.174.74,443,192.168.0.102,57884,TCP,VPN,Low,0,,,,,,,, +00:08:23,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:23,13.107.5.93,443,192.168.0.102,57810,TCP,TOR,Low,0,,,,,,,, +00:08:23,13.107.5.93,443,192.168.0.102,57810,TCP,TOR,Low,0,,,,,,,, +00:08:23,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:23,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:23,192.168.0.102,57697,20.189.173.28,443,TCP,TOR,Low,0,,,,,,,, +00:08:24,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:24,20.189.173.28,443,192.168.0.102,57697,TCP,TOR,Low,0,,,,,,,, +00:08:24,192.168.0.102,57715,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:08:24,192.168.0.102,57715,172.64.151.4,443,TCP,TOR,Low,0,,,,,,,, +00:08:24,172.64.151.4,443,192.168.0.102,57715,TCP,TOR,Low,0,,,,,,,, +00:08:24,172.64.151.4,443,192.168.0.102,57715,TCP,TOR,Low,0,,,,,,,, +18:30:50,192.168.0.102,64961,142.250.192.106,443,UDP,I2P,Low,0,,,,,,,, +18:31:03,104.18.39.21,443,192.168.0.102,52306,TCP,FREENET,Low,0,,,,,,,, +18:31:03,192.168.0.102,52306,104.18.39.21,443,TCP,FREENET,Low,0,,,,,,,, +18:31:03,104.18.39.21,443,192.168.0.102,52306,TCP,FREENET,Low,0,,,,,,,, +18:31:05,192.168.0.102,64961,142.250.192.106,443,UDP,I2P,Low,0,,,,,,,, +18:31:19,192.168.0.1,53,192.168.0.102,52688,UDP,VPN,Low,0,,,,,,,, +18:31:20,192.168.0.102,57233,142.250.207.170,443,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.207.170,443,192.168.0.102,57233,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.207.170,443,192.168.0.102,57233,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.207.170,443,192.168.0.102,57233,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.207.170,443,192.168.0.102,57233,UDP,TOR,Low,0,,,,,,,, +18:31:20,192.168.0.102,57233,142.250.207.170,443,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.207.170,443,192.168.0.102,57233,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.207.170,443,192.168.0.102,57233,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.207.170,443,192.168.0.102,57233,UDP,TOR,Low,0,,,,,,,, +18:31:20,192.168.0.102,57233,142.250.207.170,443,UDP,TOR,Low,0,,,,,,,, +18:31:20,192.168.0.102,53694,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +18:31:20,192.168.0.1,53,192.168.0.102,53694,UDP,VPN,Low,0,,,,,,,, +18:31:20,192.168.0.102,57233,142.250.207.170,443,UDP,TOR,Low,0,,,,,,,, +18:31:20,192.168.0.1,53,192.168.0.102,53101,UDP,VPN,Low,0,,,,,,,, +18:31:20,142.250.207.170,443,192.168.0.102,57233,UDP,TOR,Low,0,,,,,,,, +18:31:20,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:20,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,52406,TCP,FREENET,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,52406,TCP,FREENET,Low,0,,,,,,,, +18:31:20,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,52406,TCP,FREENET,Low,0,,,,,,,, +18:31:20,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:20,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:20,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,52406,TCP,FREENET,Low,0,,,,,,,, +18:31:20,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,52406,TCP,FREENET,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,52406,TCP,FREENET,Low,0,,,,,,,, +18:31:20,192.168.0.102,56070,142.250.67.202,443,UDP,FREENET,Low,0,,,,,,,, +18:31:20,192.168.0.102,56070,142.250.67.202,443,UDP,FREENET,Low,0,,,,,,,, +18:31:20,192.168.0.102,64961,142.250.192.106,443,UDP,I2P,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,56070,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,56070,UDP,TOR,Low,0,,,,,,,, +18:31:20,192.168.0.102,56070,142.250.67.202,443,UDP,FREENET,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,56070,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,56070,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,56070,UDP,TOR,Low,0,,,,,,,, +18:31:20,192.168.0.102,56070,142.250.67.202,443,UDP,FREENET,Low,0,,,,,,,, +18:31:20,142.250.192.106,443,192.168.0.102,64961,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.192.106,443,192.168.0.102,64961,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.192.106,443,192.168.0.102,64961,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,56070,UDP,TOR,Low,0,,,,,,,, +18:31:20,192.168.0.102,56070,142.250.67.202,443,UDP,FREENET,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,56070,UDP,TOR,Low,0,,,,,,,, +18:31:20,192.168.0.102,56070,142.250.67.202,443,UDP,FREENET,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,56070,UDP,TOR,Low,0,,,,,,,, +18:31:20,142.250.67.202,443,192.168.0.102,56070,UDP,TOR,Low,0,,,,,,,, +18:31:21,142.250.67.202,443,192.168.0.102,52406,TCP,FREENET,Low,0,,,,,,,, +18:31:21,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:21,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:21,142.250.192.106,443,192.168.0.102,64961,UDP,TOR,Low,0,,,,,,,, +18:31:25,192.168.0.102,64961,142.250.192.106,443,UDP,I2P,Low,0,,,,,,,, +18:31:25,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:25,142.250.67.202,443,192.168.0.102,52406,TCP,FREENET,Low,0,,,,,,,, +18:31:25,192.168.0.102,52406,142.250.67.202,443,TCP,FREENET,Low,0,,,,,,,, +18:31:27,192.168.0.102,51099,64.233.170.188,5228,TCP,I2P,Low,0,,,,,,,, +18:31:35,142.250.192.106,443,192.168.0.102,64961,UDP,TOR,Low,0,,,,,,,, +18:31:35,142.250.192.106,443,192.168.0.102,64961,UDP,TOR,Low,0,,,,,,,, +23:12:08,192.168.0.102,57163,15.197.213.252,443,TCP,TOR,Low,0,,,,,,,, +23:12:08,15.197.213.252,443,192.168.0.102,57163,TCP,TOR,Low,0,,,,,,,, +23:12:09,192.168.0.102,62369,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +23:12:09,192.168.0.102,62369,142.250.192.106,443,UDP,FREENET,Low,0,,,,,,,, +23:12:09,192.168.0.102,55304,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +23:12:09,192.168.0.102,49606,192.168.0.1,53,UDP,I2P,Low,0,,,,,,,, +23:12:09,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:09,192.168.0.1,53,192.168.0.102,49606,UDP,VPN,Low,0,,,,,,,, +23:12:09,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:09,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:09,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:13,192.168.0.1,53,192.168.0.102,57995,UDP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:13,192.168.0.102,59245,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +23:12:13,192.168.0.102,59245,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +23:12:13,192.168.0.102,59245,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +23:12:13,192.168.0.102,59245,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +23:12:13,192.168.0.102,59245,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +23:12:13,192.168.0.102,58128,74.125.200.188,5228,TCP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:13,192.168.0.102,59245,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +23:12:13,192.168.0.102,59245,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +23:12:13,192.168.0.102,59245,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:13,74.125.200.188,5228,192.168.0.102,58128,TCP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:13,142.250.192.74,443,192.168.0.102,59245,TCP,TOR,Low,0,,,,,,,, +23:12:15,192.168.0.102,59245,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +23:12:15,192.168.0.102,59245,142.250.192.74,443,TCP,TOR,Low,0,,,,,,,, +23:12:15,142.250.192.74,443,192.168.0.102,59245,TCP,VPN,Low,0,,,,,,,, +23:12:15,192.168.0.102,52835,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +23:12:15,172.217.174.67,443,192.168.0.102,52835,UDP,VPN,Low,0,,,,,,,, +23:12:15,172.217.174.67,443,192.168.0.102,52835,UDP,VPN,Low,0,,,,,,,, +23:12:15,192.168.0.102,52835,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +23:12:15,192.168.0.102,52835,172.217.174.67,443,UDP,FREENET,Low,0,,,,,,,, +23:12:16,192.168.0.102,59166,142.250.207.138,443,TCP,TOR,Low,0,,,,,,,, +23:12:16,104.18.37.186,443,192.168.0.102,58180,TCP,TOR,Low,0,,,,,,,, +23:12:17,192.168.0.102,59166,142.250.207.138,443,TCP,TOR,Low,0,,,,,,,, +23:12:17,142.250.207.138,443,192.168.0.102,59166,TCP,TOR,Low,0,,,,,,,, +23:12:17,192.168.0.102,59166,142.250.207.138,443,TCP,TOR,Low,0,,,,,,,, +23:12:20,192.168.0.1,53,192.168.0.102,56826,UDP,TOR,Low,0,,,,,,,, +23:12:20,192.168.0.102,57897,142.250.77.99,443,UDP,TOR,Low,0,,,,,,,, +23:12:20,142.250.77.99,443,192.168.0.102,57897,UDP,TOR,Low,0,,,,,,,, +23:12:20,142.250.77.99,443,192.168.0.102,57897,UDP,TOR,Low,0,,,,,,,, +23:12:20,192.168.0.102,57897,142.250.77.99,443,UDP,TOR,Low,0,,,,,,,, +23:12:20,192.168.0.102,57897,142.250.77.99,443,UDP,TOR,Low,0,,,,,,,, +23:12:20,142.250.77.99,443,192.168.0.102,57897,UDP,TOR,Low,0,,,,,,,, +23:12:20,142.250.77.99,443,192.168.0.102,57897,UDP,TOR,Low,0,,,,,,,, +23:12:20,142.250.77.99,443,192.168.0.102,57897,UDP,TOR,Low,0,,,,,,,, +23:12:20,142.250.77.99,443,192.168.0.102,57897,UDP,TOR,Low,0,,,,,,,, +23:12:21,100.21.51.158,443,192.168.0.102,57994,TCP,TOR,Low,0,,,,,,,, +23:12:22,192.168.0.102,57994,100.21.51.158,443,TCP,TOR,Low,0,,,,,,,, +23:12:22,192.168.0.102,59251,140.82.112.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:22,192.168.0.102,59251,140.82.112.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:23,192.168.0.102,59251,140.82.112.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:23,192.168.0.102,59251,140.82.112.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:23,140.82.112.21,443,192.168.0.102,59251,TCP,TOR,Low,0,,,,,,,, +23:12:23,192.168.0.102,59251,140.82.112.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:23,140.82.112.21,443,192.168.0.102,59251,TCP,TOR,Low,0,,,,,,,, +23:12:23,140.82.112.21,443,192.168.0.102,59251,TCP,TOR,Low,0,,,,,,,, +23:12:23,192.168.0.102,59251,140.82.112.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:24,192.168.0.102,59251,140.82.112.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:24,192.168.0.102,59251,140.82.112.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:24,192.168.0.102,62369,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +23:12:24,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:24,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:24,192.168.0.102,62369,142.250.192.106,443,UDP,FREENET,Low,0,,,,,,,, +23:12:24,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:24,192.168.0.102,62369,142.250.192.106,443,UDP,FREENET,Low,0,,,,,,,, +23:12:25,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:25,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:25,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:25,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:25,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:25,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:25,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:25,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:25,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:25,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:25,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:25,192.168.0.102,59203,104.120.94.248,80,TCP,I2P,Low,0,,,,,,,, +23:12:25,104.120.94.248,80,192.168.0.102,59203,TCP,TOR,Low,0,,,,,,,, +23:12:25,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:25,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:25,192.168.0.102,57746,3.33.221.48,80,TCP,TOR,Low,0,,,,,,,, +23:12:25,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:25,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:25,192.168.0.102,57746,3.33.221.48,80,TCP,TOR,Low,0,,,,,,,, +23:12:26,192.168.0.102,57746,3.33.221.48,80,TCP,TOR,Low,0,,,,,,,, +23:12:29,34.8.7.18,443,192.168.0.102,59228,TCP,TOR,Low,0,,,,,,,, +23:12:29,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:29,192.168.0.102,57746,3.33.221.48,80,TCP,TOR,Low,0,,,,,,,, +23:12:29,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:29,192.168.0.102,57746,3.33.221.48,80,TCP,TOR,Low,0,,,,,,,, +23:12:29,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:29,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:29,192.168.0.102,57746,3.33.221.48,80,TCP,TOR,Low,0,,,,,,,, +23:12:29,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:34,192.168.0.102,53543,142.250.67.196,443,UDP,FREENET,Low,0,,,,,,,, +23:12:34,142.250.67.196,443,192.168.0.102,53543,UDP,TOR,Low,0,,,,,,,, +23:12:38,192.168.0.102,61117,192.168.0.1,53,UDP,VPN,Low,0,,,,,,,, +23:12:38,192.168.0.102,59258,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:38,192.168.0.102,59258,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:38,140.82.113.21,443,192.168.0.102,59258,TCP,TOR,Low,0,,,,,,,, +23:12:38,140.82.113.21,443,192.168.0.102,59258,TCP,TOR,Low,0,,,,,,,, +23:12:38,192.168.0.102,59258,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:38,192.168.0.102,59258,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:38,192.168.0.102,59258,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:39,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:39,140.82.113.21,443,192.168.0.102,59258,TCP,TOR,Low,0,,,,,,,, +23:12:39,192.168.0.102,59258,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:39,192.168.0.102,57746,3.33.221.48,80,TCP,TOR,Low,0,,,,,,,, +23:12:39,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:39,192.168.0.102,62369,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +23:12:39,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:39,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:39,3.33.221.48,80,192.168.0.102,57746,TCP,TOR,Low,0,,,,,,,, +23:12:39,192.168.0.102,57746,3.33.221.48,80,TCP,TOR,Low,0,,,,,,,, +23:12:40,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:41,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:41,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:41,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:41,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:41,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:44,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:44,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:44,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:44,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:45,192.168.0.102,49950,172.217.174.67,443,UDP,I2P,Low,0,,,,,,,, +23:12:45,172.217.174.67,443,192.168.0.102,49950,UDP,TOR,Low,0,,,,,,,, +23:12:45,172.217.174.67,443,192.168.0.102,49950,UDP,TOR,Low,0,,,,,,,, +23:12:45,172.217.174.67,443,192.168.0.102,49950,UDP,TOR,Low,0,,,,,,,, +23:12:45,172.217.174.67,443,192.168.0.102,49950,UDP,TOR,Low,0,,,,,,,, +23:12:45,172.217.174.67,443,192.168.0.102,49950,UDP,TOR,Low,0,,,,,,,, +23:12:45,172.217.174.67,443,192.168.0.102,49950,UDP,TOR,Low,0,,,,,,,, +23:12:45,172.217.174.67,443,192.168.0.102,49950,UDP,TOR,Low,0,,,,,,,, +23:12:51,192.168.0.102,59228,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +23:12:51,192.168.0.102,59228,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +23:12:51,104.18.37.186,443,192.168.0.102,58180,TCP,TOR,Low,0,,,,,,,, +23:12:52,192.168.0.102,55810,142.250.67.196,443,UDP,ZERONET,Low,0,,,,,,,, +23:12:52,192.168.0.102,55810,142.250.67.196,443,UDP,FREENET,Low,0,,,,,,,, +23:12:52,142.250.67.196,443,192.168.0.102,55810,UDP,TOR,Low,0,,,,,,,, +23:12:52,142.250.67.196,443,192.168.0.102,55810,UDP,VPN,Low,0,,,,,,,, +23:12:52,142.250.67.196,443,192.168.0.102,55810,UDP,TOR,Low,0,,,,,,,, +23:12:52,192.168.0.102,55810,142.250.67.196,443,UDP,FREENET,Low,0,,,,,,,, +23:12:52,192.168.0.102,55810,142.250.67.196,443,UDP,FREENET,Low,0,,,,,,,, +23:12:52,142.250.67.196,443,192.168.0.102,55810,UDP,VPN,Low,0,,,,,,,, +23:12:52,15.197.213.252,443,192.168.0.102,57163,TCP,TOR,Low,0,,,,,,,, +23:12:53,192.168.0.102,57163,15.197.213.252,443,TCP,TOR,Low,0,,,,,,,, +23:12:53,192.168.0.102,57163,15.197.213.252,443,TCP,TOR,Low,0,,,,,,,, +23:12:53,15.197.213.252,443,192.168.0.102,57163,TCP,TOR,Low,0,,,,,,,, +23:12:53,192.168.0.102,50567,142.250.207.138,443,UDP,I2P,Low,0,,,,,,,, +23:12:53,192.168.0.102,49797,192.168.0.1,53,UDP,I2P,Low,0,,,,,,,, +23:12:53,192.168.0.102,56892,142.250.183.42,443,UDP,TOR,Low,0,,,,,,,, +23:12:53,142.250.207.138,443,192.168.0.102,50567,UDP,TOR,Low,0,,,,,,,, +23:12:53,142.250.207.138,443,192.168.0.102,50567,UDP,TOR,Low,0,,,,,,,, +23:12:53,142.250.207.138,443,192.168.0.102,50567,UDP,TOR,Low,0,,,,,,,, +23:12:53,142.250.207.138,443,192.168.0.102,50567,UDP,TOR,Low,0,,,,,,,, +23:12:53,142.250.207.138,443,192.168.0.102,50567,UDP,TOR,Low,0,,,,,,,, +23:12:53,192.168.0.102,50567,142.250.207.138,443,UDP,I2P,Low,0,,,,,,,, +23:12:53,192.168.0.102,50567,142.250.207.138,443,UDP,I2P,Low,0,,,,,,,, +23:12:53,192.168.0.102,50567,142.250.207.138,443,UDP,I2P,Low,0,,,,,,,, +23:12:53,142.250.183.42,443,192.168.0.102,56892,UDP,TOR,Low,0,,,,,,,, +23:12:53,142.250.183.42,443,192.168.0.102,56892,UDP,TOR,Low,0,,,,,,,, +23:12:53,142.250.183.42,443,192.168.0.102,56892,UDP,TOR,Low,0,,,,,,,, +23:12:53,192.168.0.102,56892,142.250.183.42,443,UDP,TOR,Low,0,,,,,,,, +23:12:53,192.168.0.102,56892,142.250.183.42,443,UDP,TOR,Low,0,,,,,,,, +23:12:53,142.250.183.42,443,192.168.0.102,56892,UDP,TOR,Low,0,,,,,,,, +23:12:53,142.250.183.42,443,192.168.0.102,56892,UDP,TOR,Low,0,,,,,,,, +23:12:53,142.250.183.42,443,192.168.0.102,56892,UDP,TOR,Low,0,,,,,,,, +23:12:53,192.168.0.102,50567,142.250.207.138,443,UDP,I2P,Low,0,,,,,,,, +23:12:53,192.168.0.102,56892,142.250.183.42,443,UDP,TOR,Low,0,,,,,,,, +23:12:54,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:54,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:54,192.168.0.102,62369,142.250.192.106,443,UDP,FREENET,Low,0,,,,,,,, +23:12:54,192.168.0.102,62369,142.250.192.106,443,UDP,TOR,Low,0,,,,,,,, +23:12:54,142.250.207.138,443,192.168.0.102,50567,UDP,TOR,Low,0,,,,,,,, +23:12:54,192.168.0.102,50567,142.250.207.138,443,UDP,I2P,Low,0,,,,,,,, +23:12:54,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:54,192.168.0.102,62369,142.250.192.106,443,UDP,FREENET,Low,0,,,,,,,, +23:12:54,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:54,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:54,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:57,142.250.192.106,443,192.168.0.102,62369,UDP,TOR,Low,0,,,,,,,, +23:12:57,52.168.117.174,443,192.168.0.102,59227,TCP,TOR,Low,0,,,,,,,, +23:12:57,192.168.0.102,59227,52.168.117.174,443,TCP,TOR,Low,0,,,,,,,, +23:12:57,192.168.0.102,59288,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:57,140.82.113.21,443,192.168.0.102,59288,TCP,TOR,Low,0,,,,,,,, +23:12:57,192.168.0.102,59288,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:57,192.168.0.102,59288,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:57,192.168.0.102,59288,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:57,192.168.0.102,59288,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:58,140.82.113.21,443,192.168.0.102,59288,TCP,TOR,Low,0,,,,,,,, +23:12:58,140.82.113.21,443,192.168.0.102,59288,TCP,TOR,Low,0,,,,,,,, +23:12:58,140.82.113.21,443,192.168.0.102,59288,TCP,TOR,Low,0,,,,,,,, +23:12:58,140.82.113.21,443,192.168.0.102,59288,TCP,TOR,Low,0,,,,,,,, +23:12:58,192.168.0.102,59288,140.82.113.21,443,TCP,TOR,Low,0,,,,,,,, +23:12:58,74.125.200.188,5228,192.168.0.102,58128,TCP,TOR,Low,0,,,,,,,, +23:12:59,192.168.0.102,51874,192.168.0.1,53,UDP,FREENET,Low,0,,,,,,,, +00:06:41,142.250.67.196,443,192.168.0.102,61641,UDP,Infilteration,Low,0,,,,,,,, +00:06:41,192.168.0.102,63468,142.250.67.196,443,UDP,BENIGN,Low,0,,,,,,,, +00:06:41,142.250.67.196,443,192.168.0.102,63468,UDP,Infilteration,Low,0,,,,,,,, +00:06:41,192.168.0.102,57746,3.33.221.48,80,TCP,BENIGN,Low,0,,,,,,,, +00:06:41,3.33.221.48,80,192.168.0.102,57746,TCP,Infilteration,Low,0,,,,,,,, +00:06:41,104.18.36.252,443,192.168.0.102,60109,TCP,Infilteration,Low,0,,,,,,,, +00:06:47,172.64.150.70,443,192.168.0.102,59359,TCP,Infilteration,Low,0,,,,,,,, +00:06:52,192.168.0.102,50691,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +00:06:52,192.168.0.102,53137,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +00:06:52,192.168.0.102,58782,172.217.174.67,443,UDP,BENIGN,Low,0,,,,,,,, +00:06:52,172.217.174.67,443,192.168.0.102,58782,UDP,Infilteration,Low,0,,,,,,,, +00:06:53,104.18.39.21,443,192.168.0.102,60023,TCP,Infilteration,Low,0,,,,,,,, +00:06:53,192.168.0.102,60023,104.18.39.21,443,TCP,BENIGN,Low,0,,,,,,,, +00:06:53,192.168.0.102,51054,142.251.220.10,443,UDP,BENIGN,Low,0,,,,,,,, +00:06:53,142.251.220.10,443,192.168.0.102,51054,UDP,BENIGN,Low,0,,,,,,,, +00:06:54,192.168.0.102,57746,3.33.221.48,80,TCP,DoS attacks-Slowloris,Low,0,,,,,,,, +00:06:54,3.33.221.48,80,192.168.0.102,57746,TCP,Infilteration,Low,0,,,,,,,, +00:06:54,16.146.176.229,443,192.168.0.102,59930,TCP,Infilteration,Low,0,,,,,,,, +00:06:54,15.197.213.252,443,192.168.0.102,57163,TCP,Infilteration,Low,0,,,,,,,, +00:06:54,192.168.0.102,57163,15.197.213.252,443,TCP,BENIGN,Low,0,,,,,,,, +00:06:54,192.168.0.102,60468,162.247.241.14,443,TCP,BENIGN,Low,0,,,,,,,, +00:06:54,192.168.0.102,60469,162.247.241.14,443,TCP,BENIGN,Low,0,,,,,,,, +00:06:55,162.247.241.14,443,192.168.0.102,60468,TCP,Infilteration,Low,0,,,,,,,, +00:06:55,162.247.241.14,443,192.168.0.102,60469,TCP,Infilteration,Low,0,,,,,,,, +00:06:55,192.168.0.102,60470,52.71.237.94,443,TCP,BENIGN,Low,0,,,,,,,, +00:06:55,192.168.0.102,54168,142.250.192.106,443,UDP,BENIGN,Low,0,,,,,,,, +00:06:55,142.250.192.106,443,192.168.0.102,54168,UDP,Infilteration,Low,0,,,,,,,, +00:06:55,52.71.237.94,443,192.168.0.102,60470,TCP,Infilteration,Low,0,,,,,,,, +00:06:56,192.168.0.102,60109,104.18.36.252,443,TCP,BENIGN,Low,0,,,,,,,, +00:06:56,104.18.36.252,443,192.168.0.102,60109,TCP,Infilteration,Low,0,,,,,,,, +20:35:00,192.168.0.102,57544,142.250.67.174,443,UDP,TOR,Low,0,,,,,,,, +20:35:00,192.168.0.102,57544,142.250.67.174,443,UDP,TOR,Low,0,,,,,,,, +20:35:00,142.250.67.174,443,192.168.0.102,57544,UDP,TOR,Low,0,,,,,,,, +20:35:00,142.250.67.174,443,192.168.0.102,57544,UDP,TOR,Low,0,,,,,,,, +20:35:03,142.250.67.174,443,192.168.0.102,57544,UDP,TOR,Low,0,,,,,,,, +20:35:03,192.168.0.102,57544,142.250.67.174,443,UDP,TOR,Low,0,,,,,,,, +20:35:03,142.250.67.174,443,192.168.0.102,57544,UDP,TOR,Low,0,,,,,,,, +20:35:03,142.250.67.174,443,192.168.0.102,57544,UDP,TOR,Low,0,,,,,,,, +20:35:03,142.250.67.174,443,192.168.0.102,57544,UDP,TOR,Low,0,,,,,,,, +20:35:03,57.144.169.33,443,192.168.0.102,64969,TCP,TOR,Low,0,,,,,,,, +20:35:03,192.168.0.102,64969,57.144.169.33,443,TCP,I2P,Low,0,,,,,,,, +20:35:03,192.168.0.102,64969,57.144.169.33,443,TCP,I2P,Low,0,,,,,,,, +20:35:03,57.144.169.33,443,192.168.0.102,64969,TCP,TOR,Low,0,,,,,,,, +20:35:03,57.144.169.33,443,192.168.0.102,64969,TCP,TOR,Low,0,,,,,,,, +20:35:03,192.168.0.102,64969,57.144.169.33,443,TCP,I2P,Low,0,,,,,,,, +20:35:04,57.144.169.33,443,192.168.0.102,64969,TCP,TOR,Low,0,,,,,,,, +20:35:05,192.168.0.102,64969,57.144.169.33,443,TCP,I2P,Low,0,,,,,,,, +20:35:05,57.144.169.33,443,192.168.0.102,64969,TCP,TOR,Low,0,,,,,,,, +20:35:05,192.168.0.102,64969,57.144.169.33,443,TCP,ZERONET,Low,0,,,,,,,, +20:35:05,57.144.169.33,443,192.168.0.102,64969,TCP,TOR,Low,0,,,,,,,, +20:35:05,192.168.0.102,64969,57.144.169.33,443,TCP,I2P,Low,0,,,,,,,, +20:35:05,104.18.36.252,443,192.168.0.102,50949,TCP,TOR,Low,0,,,,,,,, +20:35:05,192.168.0.102,50949,104.18.36.252,443,TCP,I2P,Low,0,,,,,,,, +20:35:05,192.168.0.102,50949,104.18.36.252,443,TCP,I2P,Low,0,,,,,,,, +20:35:05,57.144.169.33,443,192.168.0.102,64969,TCP,TOR,Low,0,,,,,,,, +20:35:06,57.144.169.33,443,192.168.0.102,64969,TCP,TOR,Low,0,,,,,,,, +20:35:06,192.168.0.102,64969,57.144.169.33,443,TCP,I2P,Low,0,,,,,,,, +20:35:06,104.18.39.21,443,192.168.0.102,50482,TCP,TOR,Low,0,,,,,,,, +20:35:06,104.18.39.21,443,192.168.0.102,50482,TCP,TOR,Low,0,,,,,,,, +20:35:07,142.250.67.196,443,192.168.0.102,58049,UDP,TOR,Low,0,,,,,,,, +20:35:11,142.250.192.106,443,192.168.0.102,53388,UDP,TOR,Low,0,,,,,,,, +20:35:15,52.98.87.242,443,192.168.0.102,49276,TCP,TOR,Low,0,,,,,,,, +20:35:15,192.168.0.102,49276,52.98.87.242,443,TCP,VPN,Low,0,,,,,,,, +20:35:15,192.168.0.102,49276,52.98.87.242,443,TCP,VPN,Low,0,,,,,,,, +20:35:15,52.98.87.242,443,192.168.0.102,49276,TCP,TOR,Low,0,,,,,,,, +20:35:15,52.98.87.242,443,192.168.0.102,49276,TCP,TOR,Low,0,,,,,,,, +20:35:16,52.12.242.17,443,192.168.0.102,51029,TCP,TOR,Low,0,,,,,,,, +20:35:17,52.98.87.242,443,192.168.0.102,49276,TCP,TOR,Low,0,,,,,,,, +20:35:17,192.168.0.102,49276,52.98.87.242,443,TCP,VPN,Low,0,,,,,,,, +20:35:17,52.98.87.242,443,192.168.0.102,49276,TCP,TOR,Low,0,,,,,,,, +20:35:17,192.168.0.102,64969,57.144.169.33,443,TCP,I2P,Low,0,,,,,,,, +20:35:20,104.18.36.252,443,192.168.0.102,50949,TCP,TOR,Low,0,,,,,,,, +20:35:20,192.168.0.102,50949,104.18.36.252,443,TCP,I2P,Low,0,,,,,,,, +20:35:20,192.168.0.102,50949,104.18.36.252,443,TCP,I2P,Low,0,,,,,,,, +20:35:20,192.168.0.102,50949,104.18.36.252,443,TCP,I2P,Low,0,,,,,,,, +20:39:52,23.212.254.42,443,192.168.0.102,51147,UDP,BENIGN,Low,0,,,,,,,, +20:39:52,40.104.122.242,443,192.168.0.102,63875,UDP,Infilteration,Low,0,,,,,,,, +20:39:52,192.168.0.102,63875,40.104.122.242,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,57.144.53.32,443,192.168.0.102,51153,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,104.18.36.252,443,192.168.0.102,50949,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,60807,142.250.77.99,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,142.250.77.99,443,192.168.0.102,60807,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,185.199.110.133,443,192.168.0.102,50897,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,53388,142.250.192.106,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,142.250.192.106,443,192.168.0.102,53388,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,192.168.0.102,63339,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,54224,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.1,53,192.168.0.102,63339,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,192.168.0.1,53,192.168.0.102,54224,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,192.168.0.102,62528,104.18.1.22,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,104.18.1.22,443,192.168.0.102,62528,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,104.18.39.21,443,192.168.0.102,50482,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,58049,142.250.67.196,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,50002,142.250.70.74,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,142.250.70.74,443,192.168.0.102,50002,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,59134,142.250.67.202,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,142.250.67.202,443,192.168.0.102,59134,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,57.144.169.33,443,192.168.0.102,64969,TCP,Infilteration,Low,0,,,,,,,, +20:39:53,192.168.0.102,64969,57.144.169.33,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,49276,52.98.87.242,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,52.98.87.242,443,192.168.0.102,49276,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,50949,104.18.36.252,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,59165,34.8.7.18,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,51033,34.8.7.18,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,34.8.7.18,443,192.168.0.102,59165,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,34.8.7.18,443,192.168.0.102,51033,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,56303,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,51119,150.171.28.12,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,150.171.28.12,443,192.168.0.102,51119,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,56828,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.1,53,192.168.0.102,56828,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,192.168.0.102,54726,142.250.207.142,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,142.250.207.142,443,192.168.0.102,54726,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,192.168.0.102,51321,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,51147,23.212.254.42,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,57901,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.1,53,192.168.0.102,56527,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,192.168.0.1,53,192.168.0.102,57901,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,23.210.245.120,443,192.168.0.102,49935,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,49935,23.210.245.120,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,65209,23.210.245.120,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,23.210.245.120,443,192.168.0.102,65209,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,23.212.254.42,443,192.168.0.102,51147,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,52.12.242.17,443,192.168.0.102,51029,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,50482,104.18.39.21,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,104.18.32.47,443,192.168.0.102,51021,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,51020,104.18.32.47,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,50897,185.199.110.133,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,64968,74.125.200.188,5228,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,55208,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,65375,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.1,53,192.168.0.102,65375,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,192.168.0.102,65027,4.213.25.242,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,40.104.122.242,443,192.168.0.102,63875,UDP,Infilteration,Low,0,,,,,,,, +20:39:53,57.144.169.32,443,192.168.0.102,51149,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,192.168.0.102,51153,57.144.53.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:53,57.144.53.32,443,192.168.0.102,51153,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,40.104.122.242,443,192.168.0.102,63875,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,53388,142.250.192.106,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.192.106,443,192.168.0.102,53388,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,57.144.169.33,443,192.168.0.102,64969,TCP,Infilteration,Low,0,,,,,,,, +20:39:54,52.98.87.242,443,192.168.0.102,49276,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,50949,104.18.36.252,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,104.18.36.252,443,192.168.0.102,50949,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,49276,52.98.87.242,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51119,150.171.28.12,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,50571,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,13.89.178.26,443,192.168.0.102,51127,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51127,13.89.178.26,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51128,13.89.178.26,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,13.89.178.26,443,192.168.0.102,51128,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,104.18.39.21,443,192.168.0.102,50482,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,50482,104.18.39.21,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,64969,57.144.169.33,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,53877,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,60020,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,61464,142.250.77.35,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.77.35,443,192.168.0.102,61464,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,57134,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,61488,142.250.77.99,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.77.99,443,192.168.0.102,61488,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,50100,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,60560,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,60560,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,51135,13.107.213.58,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,13.107.213.58,443,192.168.0.102,51135,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,55290,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,55290,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,20.189.172.33,443,192.168.0.102,51136,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51136,20.189.172.33,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,63875,40.104.122.242,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,63682,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,51137,140.82.114.22,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,140.82.114.22,443,192.168.0.102,51137,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,61501,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,23.64.59.64,443,192.168.0.102,51139,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51139,23.64.59.64,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,58849,142.250.192.106,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.192.106,443,192.168.0.102,58849,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,74.125.200.188,5228,192.168.0.102,64968,TCP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,64283,142.250.77.35,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.77.35,443,192.168.0.102,64283,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,64101,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,64101,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,61502,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,56933,142.250.67.174,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.67.174,443,192.168.0.102,56933,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,57631,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,53677,142.250.77.99,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.77.99,443,192.168.0.102,53677,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,65027,4.213.25.242,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51843,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,51843,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,51147,23.212.254.106,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,23.212.254.106,443,192.168.0.102,51147,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51151,57.144.125.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51152,57.144.43.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51154,157.240.16.52,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51155,57.144.169.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51149,57.144.169.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.169.32,443,192.168.0.102,51155,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.177.32,443,192.168.0.102,51148,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51148,57.144.177.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.125.32,443,192.168.0.102,51151,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.243.32,443,192.168.0.102,51150,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51150,57.144.243.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.43.32,443,192.168.0.102,51152,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,157.240.16.52,443,192.168.0.102,51154,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.169.32,443,192.168.0.102,51149,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,64968,74.125.200.188,5228,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,60941,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,60941,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,52.123.129.14,443,192.168.0.102,51156,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51156,52.123.129.14,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51570,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,55015,142.250.77.99,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.77.99,443,192.168.0.102,55015,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.1,36845,239.255.255.250,1900,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,56157,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,62631,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,50107,40.104.135.130,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,40.104.135.130,443,192.168.0.102,50107,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,62619,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51782,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51158,172.64.155.209,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,172.64.155.209,443,192.168.0.102,51158,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,58313,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,64322,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,58990,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,64481,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,50826,142.250.77.99,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51160,104.18.39.21,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,104.18.39.21,443,192.168.0.102,51160,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.77.99,443,192.168.0.102,50826,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51153,57.144.53.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.53.32,443,192.168.0.102,51153,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51153,57.144.53.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,49276,52.98.87.242,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,52.98.87.242,443,192.168.0.102,49276,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51147,23.212.254.106,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,104.18.36.252,443,192.168.0.102,50949,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51162,142.250.70.67,80,TCP,DoS attacks-Slowloris,Low,0,,,,,,,, +20:39:54,142.250.70.67,80,192.168.0.102,51162,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.169.33,443,192.168.0.102,64969,TCP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,64969,57.144.169.33,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51155,57.144.169.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.43.32,443,192.168.0.102,51152,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51148,57.144.177.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.243.32,443,192.168.0.102,51150,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,157.240.16.52,443,192.168.0.102,51154,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51154,157.240.16.52,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51149,57.144.169.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,49807,192.168.0.1,53,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,49807,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,23.38.59.250,80,192.168.0.102,51163,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51164,142.250.70.67,80,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.70.67,80,192.168.0.102,51164,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51160,104.18.39.21,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,104.18.39.21,443,192.168.0.102,51160,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,142.250.192.106,443,192.168.0.102,58849,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,57.144.169.32,443,192.168.0.102,51155,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.177.32,443,192.168.0.102,51148,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51150,57.144.243.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51151,57.144.125.32,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,57.144.169.32,443,192.168.0.102,51149,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,50949,104.18.36.252,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.1,53,192.168.0.102,55252,UDP,Infilteration,Low,0,,,,,,,, +20:39:54,192.168.0.102,51169,40.119.249.228,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,40.119.249.228,443,192.168.0.102,51169,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,52.123.129.14,443,192.168.0.102,51156,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,52.123.129.14,443,192.168.0.102,51170,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51170,52.123.129.14,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,58849,142.250.192.106,443,UDP,BENIGN,Low,0,,,,,,,, +20:39:54,192.168.0.102,51158,172.64.155.209,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:54,172.64.155.209,443,192.168.0.102,51158,TCP,BENIGN,Low,0,,,,,,,, +20:39:56,52.98.87.242,443,192.168.0.102,49276,TCP,BENIGN,Low,0,,,,,,,, +20:39:56,192.168.0.102,49276,52.98.87.242,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:57,57.144.169.33,443,192.168.0.102,64969,TCP,Infilteration,Low,0,,,,,,,, +20:39:57,74.125.200.188,5228,192.168.0.102,64968,TCP,Infilteration,Low,0,,,,,,,, +20:39:58,192.168.0.102,64969,57.144.169.33,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:58,192.168.0.1,53,192.168.0.102,57098,UDP,Infilteration,Low,0,,,,,,,, +20:39:58,23.64.59.88,443,192.168.0.102,51179,TCP,BENIGN,Low,0,,,,,,,, +20:39:58,192.168.0.102,51179,23.64.59.88,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:59,192.168.0.102,49276,52.98.87.242,443,TCP,BENIGN,Low,0,,,,,,,, +20:39:59,52.98.87.242,443,192.168.0.102,49276,TCP,BENIGN,Low,0,,,,,,,, +20:40:00,57.144.169.33,443,192.168.0.102,64969,TCP,Infilteration,Low,0,,,,,,,, +20:40:00,192.168.0.102,64969,57.144.169.33,443,TCP,BENIGN,Low,0,,,,,,,, +20:40:01,142.250.192.106,443,192.168.0.102,58849,UDP,Infilteration,Low,0,,,,,,,, +20:40:03,52.98.87.242,443,192.168.0.102,49276,TCP,BENIGN,Low,0,,,,,,,, +20:40:03,192.168.0.102,49276,52.98.87.242,443,TCP,BENIGN,Low,0,,,,,,,, +20:40:07,192.168.0.102,50949,104.18.36.252,443,TCP,BENIGN,Low,0,,,,,,,, +20:40:07,104.18.36.252,443,192.168.0.102,50949,TCP,BENIGN,Low,0,,,,,,,, +20:40:08,192.168.0.102,64969,57.144.169.33,443,TCP,BENIGN,Low,0,,,,,,,, +20:40:08,57.144.169.33,443,192.168.0.102,64969,TCP,Infilteration,Low,0,,,,,,,, +20:40:10,104.18.39.21,443,192.168.0.102,51160,TCP,BENIGN,Low,0,,,,,,,, +20:40:10,192.168.0.102,64969,57.144.169.33,443,TCP,BENIGN,Low,0,,,,,,,, +20:40:13,57.144.169.33,443,192.168.0.102,64969,TCP,Infilteration,Low,0,,,,,,,, +20:40:13,192.168.0.102,64969,57.144.169.33,443,TCP,BENIGN,Low,0,,,,,,,, +20:40:16,192.168.0.102,58849,142.250.192.106,443,UDP,BENIGN,Low,0,,,,,,,, +20:40:16,142.250.192.106,443,192.168.0.102,58849,UDP,Infilteration,Low,0,,,,,,,, +20:40:17,52.98.87.242,443,192.168.0.102,49276,TCP,BENIGN,Low,0,,,,,,,, +20:40:17,192.168.0.102,49276,52.98.87.242,443,TCP,BENIGN,Low,0,,,,,,,, +10:34:08,57.144.169.32,443,192.168.160.32,56929,TCP,TOR,Low,0,,,,,,,, +10:34:08,192.168.160.32,56929,57.144.169.32,443,TCP,TOR,Low,0,,,,,,,, +10:34:08,192.168.160.32,56929,57.144.169.32,443,TCP,TOR,Low,0,,,,,,,, +10:34:08,192.168.160.32,56929,57.144.169.32,443,TCP,TOR,Low,0,,,,,,,, +10:34:09,192.168.160.32,56929,57.144.169.32,443,TCP,TOR,Low,0,,,,,,,, +10:34:09,192.168.160.32,56929,57.144.169.32,443,TCP,TOR,Low,0,,,,,,,, +10:34:09,192.168.160.32,56929,57.144.169.32,443,TCP,TOR,Low,0,,,,,,,, +10:34:09,192.168.160.32,56929,57.144.169.32,443,TCP,TOR,Low,0,,,,,,,, +10:34:10,57.144.169.32,443,192.168.160.32,56929,TCP,TOR,Low,0,,,,,,,, +10:34:30,142.250.67.74,443,192.168.160.32,56773,TCP,TOR,Low,0,,,,,,,, +10:34:36,192.168.160.32,56773,142.250.67.74,443,TCP,TOR,Low,0,,,,,,,, +10:34:36,192.168.160.229,53,192.168.160.32,63207,UDP,TOR,Low,0,,,,,,,, +10:35:20,192.168.160.32,52035,192.168.160.229,53,UDP,BENIGN,Low,0,,,,,,,, +10:35:20,192.168.160.229,53,192.168.160.32,61891,UDP,Infilteration,Low,0,,,,,,,, +10:35:20,192.168.160.229,53,192.168.160.32,52035,UDP,Infilteration,Low,0,,,,,,,, +10:35:20,192.168.160.229,53,192.168.160.32,51468,UDP,BENIGN,Low,0,,,,,,,, +10:35:20,192.168.160.229,53,192.168.160.32,63635,UDP,Infilteration,Low,0,,,,,,,, +10:35:20,192.168.160.229,53,192.168.160.32,57219,UDP,Infilteration,Low,0,,,,,,,, +10:35:20,192.168.160.32,56125,192.168.160.229,53,UDP,BENIGN,Low,0,,,,,,,, +10:35:20,192.168.160.32,53619,192.168.160.229,53,UDP,BENIGN,Low,0,,,,,,,, +10:35:20,192.168.160.229,53,192.168.160.32,53619,UDP,Infilteration,Low,0,,,,,,,, +10:35:20,192.168.160.32,51911,192.168.160.229,53,UDP,BENIGN,Low,0,,,,,,,, +10:35:20,192.168.160.32,53927,192.168.160.229,53,UDP,BENIGN,Low,0,,,,,,,, +10:35:20,192.168.160.229,53,192.168.160.32,60636,UDP,Infilteration,Low,0,,,,,,,, +10:35:20,192.168.160.229,53,192.168.160.32,53927,UDP,Infilteration,Low,0,,,,,,,, +10:35:20,192.168.160.32,56823,57.155.141.119,443,TCP,BENIGN,Low,0,,,,,,,, +10:35:21,57.144.169.32,443,192.168.160.32,56929,TCP,Infilteration,Low,0,,,,,,,, +10:35:21,192.168.160.32,56929,57.144.169.32,443,TCP,BENIGN,Low,0,,,,,,,, +10:35:29,192.168.160.32,56823,57.155.141.119,443,TCP,BENIGN,Low,0,,,,,,,, +10:35:53,192.168.160.32,50297,192.168.160.229,53,UDP,BENIGN,Low,0,,,,,,,, +10:38:27,192.168.160.32,57072,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +10:38:27,34.8.7.18,443,192.168.160.32,57072,TCP,TOR,Low,0,,,,,,,, +10:38:52,192.168.160.32,57079,142.250.182.35,443,TCP,TOR,Low,0,,,,,,,, +10:38:52,142.250.182.35,443,192.168.160.32,57079,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57076,142.250.182.35,443,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57089,142.250.76.67,443,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57089,142.250.76.67,443,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57079,142.250.182.35,443,TCP,TOR,Low,0,,,,,,,, +10:39:45,142.250.182.35,443,192.168.160.32,57076,TCP,TOR,Low,0,,,,,,,, +10:39:45,142.250.76.67,443,192.168.160.32,57089,TCP,TOR,Low,0,,,,,,,, +10:39:45,142.250.76.67,443,192.168.160.32,57089,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57089,142.250.76.67,443,TCP,TOR,Low,0,,,,,,,, +10:39:45,142.250.76.67,443,192.168.160.32,57089,TCP,TOR,Low,0,,,,,,,, +10:39:45,142.250.76.67,443,192.168.160.32,57089,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57089,142.250.76.67,443,TCP,TOR,Low,0,,,,,,,, +10:39:45,142.250.76.67,443,192.168.160.32,57089,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57089,142.250.76.67,443,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57089,142.250.76.67,443,TCP,TOR,Low,0,,,,,,,, +10:39:45,142.250.76.67,443,192.168.160.32,57089,TCP,TOR,Low,0,,,,,,,, +10:39:45,142.250.76.67,443,192.168.160.32,57089,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,59050,192.168.160.229,53,UDP,I2P,Low,0,,,,,,,, +10:39:45,192.168.160.229,53,192.168.160.32,63433,UDP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.229,53,192.168.160.32,63190,UDP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,62092,192.168.160.229,53,UDP,FREENET,Low,0,,,,,,,, +10:39:45,192.168.160.229,53,192.168.160.32,59491,UDP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.229,53,192.168.160.32,50547,UDP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57072,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +10:39:45,34.8.7.18,443,192.168.160.32,57072,TCP,TOR,Low,0,,,,,,,, +10:39:45,34.8.7.18,443,192.168.160.32,57072,TCP,TOR,Low,0,,,,,,,, +10:39:45,34.8.7.18,443,192.168.160.32,57072,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57076,142.250.182.35,443,TCP,TOR,Low,0,,,,,,,, +10:39:45,142.250.182.35,443,192.168.160.32,57076,TCP,TOR,Low,0,,,,,,,, +10:39:45,192.168.160.32,57089,142.250.76.67,443,TCP,TOR,Low,0,,,,,,,, +10:40:16,142.250.76.67,443,192.168.160.32,57089,TCP,TOR,Low,0,,,,,,,, +10:40:16,192.168.160.32,57072,34.8.7.18,443,TCP,TOR,Low,0,,,,,,,, +10:40:18,34.8.7.18,443,192.168.160.32,57072,TCP,TOR,Low,0,,,,,,,, +10:40:30,192.168.160.32,57076,142.250.182.35,443,TCP,TOR,Low,0,,,,,,,, +10:40:30,142.250.182.35,443,192.168.160.32,57076,TCP,TOR,Low,0,,,,,,,, +10:40:30,142.250.182.35,443,192.168.160.32,57076,TCP,TOR,Low,0,,,,,,,, +10:40:30,192.168.160.32,57076,142.250.182.35,443,TCP,TOR,Low,0,,,,,,,, +10:40:30,142.250.182.35,443,192.168.160.32,57076,TCP,TOR,Low,0,,,,,,,, +10:40:30,192.168.160.32,57076,142.250.182.35,443,TCP,TOR,Low,0,,,,,,,, +10:40:30,192.168.160.32,57089,142.250.76.67,443,TCP,TOR,Low,0,,,,,,,, +10:40:48,192.168.160.32,57089,142.250.76.67,443,TCP,TOR,Low,0,,,,,,,, +10:40:48,142.250.76.67,443,192.168.160.32,57089,TCP,TOR,Low,0,,,,,,,, +10:40:48,192.168.160.32,56579,192.168.160.229,53,UDP,TOR,Low,0,,,,,,,, +10:40:48,192.168.160.229,53,192.168.160.32,56579,UDP,TOR,Low,0,,,,,,,, +10:40:48,192.168.160.32,65320,192.168.160.229,53,UDP,I2P,Low,0,,,,,,,, diff --git a/backend/logs/cicids_logs.csv b/backend/logs/cicids_logs.csv new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/backend/reporting/pdf_report.py b/backend/reporting/pdf_report.py new file mode 100644 index 0000000000000000000000000000000000000000..c86a4a81fa81d0692a5c6bd8806aa14044e9cd3b --- /dev/null +++ b/backend/reporting/pdf_report.py @@ -0,0 +1,58 @@ +from fpdf import FPDF +import pandas as pd, os +from utils.logger import log_path + +class NIDSReportPDF(FPDF): + def header(self): + self.set_font("Helvetica", "B", 18) + self.cell(0, 10, "NIDS - Network Intrusion Detection Report", ln=True, align="C") + self.ln(5) + + def footer(self): + self.set_y(-15) + self.set_font("Helvetica", "I", 9) + self.cell(0, 10, f"Page {self.page_no()}/{{nb}}", align="C") + +def generate_pdf_bytes(n=300): + """Generate PDF summary of recent events.""" + df = pd.read_csv(log_path) if os.path.exists(log_path) else pd.DataFrame() + + pdf = NIDSReportPDF() + pdf.alias_nb_pages() + pdf.add_page() + pdf.set_font("Helvetica", "", 12) + + pdf.cell(0, 10, f"Last {n} Events Summary", ln=True) + pdf.ln(5) + + if len(df) == 0: + pdf.cell(0, 10, "No data available.", ln=True) + else: + df = df.tail(n) + counts = df["prediction"].value_counts().to_dict() if "prediction" in df.columns else {} + + pdf.cell(0, 10, "Prediction Distribution:", ln=True) + pdf.ln(4) + for label, count in counts.items(): + pdf.cell(0, 10, f"{label}: {count}", ln=True) + + pdf.ln(8) + pdf.cell(0, 10, "Sample Events:", ln=True) + pdf.ln(4) + + # limit to 10 sample rows + cols = ["time", "src", "dst", "proto", "prediction"] + cols = [c for c in cols if c in df.columns] + for _, row in df.tail(10).iterrows(): + line = " | ".join(str(row[c]) for c in cols) + if len(line) > 150: + line = line[:147] + "..." + pdf.multi_cell(0, 8, line) + + # return as bytes + output = pdf.output(dest="S") + if isinstance(output, (bytes, bytearray)): + return bytes(output) + else: + return bytes(output.encode("latin1", "ignore")) + diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..da4eb335eda4bc312118f8a454d907d7f4043b06 --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,34 @@ +appdirs==1.4.4 +blinker==1.9.0 +click==8.3.0 +colorama==0.4.6 +contourpy==1.3.3 +cycler==0.12.1 +Flask==3.1.2 +flask-cors==6.0.1 +fonttools==4.60.1 +itsdangerous==2.2.0 +Jinja2==3.1.6 +joblib==1.5.2 +kiwisolver==1.4.9 +lightgbm==4.6.0 +lxml==6.0.2 +MarkupSafe==3.0.3 +matplotlib==3.10.7 +numpy==2.3.4 +packaging==25.0 +pandas==2.3.3 +pillow==12.0.0 +pyparsing==3.2.5 +pyshark==0.6 +python-dateutil==2.9.0.post0 +pytz==2025.2 +scapy==2.6.1 +scikit-learn==1.7.2 +scipy==1.16.3 +seaborn==0.13.2 +six==1.17.0 +termcolor==3.2.0 +threadpoolctl==3.6.0 +tzdata==2025.2 +Werkzeug==3.1.3 diff --git a/backend/retrain_requests.jsonl b/backend/retrain_requests.jsonl new file mode 100644 index 0000000000000000000000000000000000000000..473e62655eb3186d77d8d6686ed1d5de211bdd2c --- /dev/null +++ b/backend/retrain_requests.jsonl @@ -0,0 +1 @@ +{"model": "cicids", "expected": "Brute Force -XSS", "predicted": "DoS attacks-Slowloris", "values": [6, 80, 5000000, 2, 2, 120, 120, 60, 60, 2000000, 0, 0, 2000000], "note": "Model is wrong"} diff --git a/backend/routes/__init__.py b/backend/routes/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/backend/routes/ai_route.py b/backend/routes/ai_route.py new file mode 100644 index 0000000000000000000000000000000000000000..87a75d729696a5644348e4a99a277bfc2a869265 --- /dev/null +++ b/backend/routes/ai_route.py @@ -0,0 +1,40 @@ +# routes/ai_route.py +# -------------------------------------- +from flask import Blueprint, request, jsonify +from utils.ai_engine import explain_threat, summarize_events +from utils.logger import get_recent_events, get_active_model + +ai_bp = Blueprint("ai_bp", __name__) + + +@ai_bp.route("/explain", methods=["POST"]) +def ai_explain(): + """ + Body: JSON event (one row from table) + Returns: {"explanation": "..."} + """ + data = request.get_json() or {} + try: + text = explain_threat(data) + return jsonify({"ok": True, "explanation": text}) + except Exception as e: + print("AI explain error:", e) + return jsonify({"ok": False, "error": str(e)}), 500 + + +@ai_bp.route("/summary", methods=["GET"]) +def ai_summary(): + """ + Query: ?model=bcc&n=200 + Returns: {"ok": True, "summary": "..."} + """ + model = request.args.get("model", get_active_model()) + n = int(request.args.get("n", 200)) + + try: + events = get_recent_events(model, n) + text = summarize_events(events, model=model) + return jsonify({"ok": True, "summary": text, "count": len(events), "model": model}) + except Exception as e: + print("AI summary error:", e) + return jsonify({"ok": False, "error": str(e)}), 500 diff --git a/backend/routes/alerts_route.py b/backend/routes/alerts_route.py new file mode 100644 index 0000000000000000000000000000000000000000..ce8e5367b1c055d4265a95c19ca12844840af51b --- /dev/null +++ b/backend/routes/alerts_route.py @@ -0,0 +1,82 @@ +from flask import Blueprint, jsonify +from flask_cors import cross_origin +from utils.logger import get_recent_events +from utils.risk_engine import compute_risk_score +from datetime import datetime + +alerts_bp = Blueprint("alerts", __name__) + +# --------------------------------------------------------- +# Deduce risk based on prediction (simple + stable) +# --------------------------------------------------------- +def classify_risk(prediction): + if prediction in ["TOR", "I2P", "ZERONET", "FREENET"]: + return "High" + if prediction in ["VPN"]: + return "Medium" + return "Low" + + +@alerts_bp.route("/alerts", methods=["GET"]) +@cross_origin() +def get_alerts(): + """ + Returns ONLY real alerts (Medium + High) + with stable risk scoring and time sorting. + Fully compatible with optimized logger. + """ + try: + raw_events = get_recent_events() + alerts = [] + + for e in raw_events: + pred = e.get("prediction", "Unknown") + + # ------------------------------- + # Recompute Risk + # ------------------------------- + risk = classify_risk(pred) + + if risk == "Low": + continue # do NOT include normal traffic + + # ------------------------------- + # Stable risk score (0-100) + # ------------------------------- + try: + risk_score = compute_risk_score(e) + except: + # fallback scoring + risk_score = 90 if risk == "High" else 60 + + # ------------------------------- + # Build alert payload + # ------------------------------- + alerts.append({ + "timestamp": datetime.now().strftime("%H:%M:%S"), + "time": e.get("time"), + "src_ip": e.get("src_ip"), + "dst_ip": e.get("dst_ip"), + "sport": e.get("sport", "—"), + "dport": e.get("dport", "—"), + "proto": e.get("proto", "-"), + "prediction": pred, + "risk_level": risk, + "risk_score": risk_score, + }) + + # ------------------------------------------------ + # Sort newest first (based on event time) + # ------------------------------------------------ + alerts = sorted(alerts, key=lambda x: x["time"], reverse=True) + + return jsonify({ + "count": len(alerts), + "alerts": alerts[:150], # limit for UI performance + "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S") + }) + + except Exception as err: + print("❌ Alerts API error:", err) + return jsonify({"error": str(err)}), 500 + diff --git a/backend/routes/chat_route.py b/backend/routes/chat_route.py new file mode 100644 index 0000000000000000000000000000000000000000..4421fed5f7332a5222c21a616b1904e6117ceb54 --- /dev/null +++ b/backend/routes/chat_route.py @@ -0,0 +1,26 @@ +from flask import Blueprint, request, jsonify +from groq import Groq +import os + +chat_bp = Blueprint("chat_bp", __name__) +client = Groq(api_key=os.getenv("GROQ_API_KEY")) + +@chat_bp.route("/chat", methods=["POST"]) +def chat(): + try: + data = request.get_json() + msg = data.get("message", "") + + result = client.chat.completions.create( + model="llama-3.1-8b-instant", + messages=[{"role": "user", "content": msg}] + ) + + reply = result.choices[0].message.content + + return jsonify({"reply": reply}) + + except Exception as e: + print("Chat error:", e) + return jsonify({"error": str(e)}), 500 + diff --git a/backend/routes/geo_route.py b/backend/routes/geo_route.py new file mode 100644 index 0000000000000000000000000000000000000000..066c7e92b016855c6d5c42e918d0fb53dfacf5ff --- /dev/null +++ b/backend/routes/geo_route.py @@ -0,0 +1,33 @@ +# ========================================== +# 🌍 GEO ROUTE — Adaptive AI NIDS +# ------------------------------------------ +# ✅ /api/geo/resolve?ip= +# ✅ /api/geo/recent +# ========================================== + +from flask import Blueprint, jsonify, request +from utils.geo_lookup import get_geo_info, enrich_event_with_geo +from utils.logger import get_recent_events + +geo_bp = Blueprint("geo", __name__) + +# 🔹 Resolve a single IP (for IPInfoModal) +@geo_bp.route("/resolve") +def resolve_ip(): + ip = request.args.get("ip") + if not ip: + return jsonify({"error": "Missing IP parameter"}), 400 + info = get_geo_info(ip) + return jsonify(info), 200 + + +# 🔹 Return recent events enriched with geo (for map) +@geo_bp.route("/recent") +def geo_recent(): + try: + events = get_recent_events() + geo_events = [enrich_event_with_geo(e) for e in events[-200:]] + return jsonify(geo_events), 200 + except Exception as e: + print("⚠️ Geo recent error:", e) + return jsonify({"error": str(e)}), 500 diff --git a/backend/routes/ip_lookup_route.py b/backend/routes/ip_lookup_route.py new file mode 100644 index 0000000000000000000000000000000000000000..658400fa8fba112633eee70169cc19ee0af31c49 --- /dev/null +++ b/backend/routes/ip_lookup_route.py @@ -0,0 +1,148 @@ +import requests +import ipaddress +from flask import Blueprint, jsonify, request +from flask_cors import cross_origin +from datetime import datetime + +ip_lookup_bp = Blueprint("ip_lookup", __name__) + +# 🔹 Cache lookups to reduce API load +_ip_cache = {} + +# ====================================== +# 🚨 RISK CLASSIFIER +# ====================================== +def _guess_risk(org_name: str): + org = (org_name or "").lower() + if any(k in org for k in ["tor", "anonym", "i2p"]): + return {"level": "High", "score": 95, "reason": "Anonymizing service (TOR/I2P detected)"} + if any(k in org for k in ["vpn", "proxy", "tunnel"]): + return {"level": "Medium", "score": 80, "reason": "VPN or proxy-based routing"} + if any(k in org for k in ["aws", "gcp", "digitalocean", "azure", "oracle"]): + return {"level": "Medium", "score": 70, "reason": "Cloud-hosted server (possible C2 or proxy)"} + return {"level": "Low", "score": 40, "reason": "Likely clean residential or enterprise IP"} + + +# ====================================== +# ⚙️ IP DATA NORMALIZATION +# ====================================== +def _normalize_data(ip, d: dict, api_source: str): + """Unify structure across ipapi.co and ipwho.is""" + if not d: + return {"error": "No data"} + + try: + if api_source == "ipapi": + org = d.get("org", "") + return { + "ip": ip, + "city": d.get("city"), + "region": d.get("region"), + "country_name": d.get("country_name"), + "continent_code": d.get("continent_code"), + "org": org, + "asn": d.get("asn"), + "version": d.get("version", "IPv4"), + "latitude": float(d.get("latitude", 0)), + "longitude": float(d.get("longitude", 0)), + "timezone": d.get("timezone"), + "risk": _guess_risk(org), + "flag": f"https://flagsapi.com/{d.get('country_code','US')}/flat/32.png" + } + elif api_source == "ipwhois": + org = d.get("connection", {}).get("isp", "") + return { + "ip": ip, + "city": d.get("city"), + "region": d.get("region"), + "country_name": d.get("country"), + "continent_code": d.get("continent"), + "org": org, + "asn": d.get("connection", {}).get("asn"), + "version": d.get("type", "IPv4"), + "latitude": float(d.get("latitude", 0)), + "longitude": float(d.get("longitude", 0)), + "timezone": d.get("timezone"), + "risk": _guess_risk(org), + "flag": f"https://flagsapi.com/{d.get('country_code','US')}/flat/32.png" + } + except Exception: + pass + + return {"error": "Normalization failed"} + + +# ====================================== +# 🔍 LOOKUP (PRIVATE or PUBLIC) +# ====================================== +def lookup_ip_data(ip: str): + """Internal helper for backend components (non-JSON).""" + try: + if not ip: + return {"error": "Empty IP"} + + # Check cache first + if ip in _ip_cache: + return _ip_cache[ip] + + # Handle local/private IPs + if ipaddress.ip_address(ip).is_private: + info = { + "ip": ip, + "city": "Bengaluru", + "region": "Private Range", + "country_name": "India", + "org": "Local Device", + "asn": "LAN", + "version": "IPv4", + "latitude": 12.9716, + "longitude": 77.5946, + "risk": {"level": "Low", "score": 20, "reason": "Private/local IP"}, + "flag": "https://flagsapi.com/IN/flat/32.png" + } + _ip_cache[ip] = info + return info + + # === Try ipapi.co === + try: + r = requests.get(f"https://ipapi.co/{ip}/json/", timeout=4) + if r.ok: + d = r.json() + if not d.get("error"): + info = _normalize_data(ip, d, "ipapi") + _ip_cache[ip] = info + return info + except Exception: + pass + + # === Fallback: ipwho.is === + try: + r = requests.get(f"https://ipwho.is/{ip}", timeout=4) + d = r.json() + if d.get("success"): + info = _normalize_data(ip, d, "ipwhois") + _ip_cache[ip] = info + return info + except Exception: + pass + + except Exception as e: + return {"error": str(e)} + + return {"error": "Could not fetch IP info"} + + +# ====================================== +# 🌍 EXTERNAL API ENDPOINT +# ====================================== +@ip_lookup_bp.route("/lookup/", methods=["GET"]) +@cross_origin() +def lookup_ip(ip): + """Public API: Look up an IP's geolocation + threat risk.""" + data = lookup_ip_data(ip) + if "error" in data: + return jsonify(data), 404 + + data["lookup_time"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + return jsonify(data) + diff --git a/backend/routes/live_route.py b/backend/routes/live_route.py new file mode 100644 index 0000000000000000000000000000000000000000..a77b288d9cca6fd58750bdef1423925a1f683f83 --- /dev/null +++ b/backend/routes/live_route.py @@ -0,0 +1,53 @@ +# ============================================================== +# live_route.py — Flask routes for controlling live capture +# ============================================================== + +from flask import Blueprint, jsonify, request +from capture.live_manager import sniffer +import numpy as np +import math + + +live_bp = Blueprint("live_bp", __name__) + +@live_bp.route("/start") +def start_live(): + iface = request.args.get("iface") + sniffer.start(iface=iface) + return jsonify({"status": "started", "running": sniffer.is_running()}) + +@live_bp.route("/stop") +def stop_live(): + sniffer.stop() + return jsonify({"status": "stopped", "running": sniffer.is_running()}) + +@live_bp.route("/status") +def status(): + return jsonify({"running": sniffer.is_running()}) + +@live_bp.route("/recent") +def recent(): + events = sniffer.recent() + + safe_events = [] + for e in events: + safe = {} + for k, v in e.items(): + + # convert numpy ints/floats to python native + if isinstance(v, (np.generic,)): + v = v.item() + + # replace None / NaN with string + if v is None or (isinstance(v, float) and math.isnan(v)): + v = "Unknown" + + safe[str(k)] = v + + safe_events.append(safe) + + return jsonify({"events": safe_events}), 200 + +@live_bp.route("/stats") +def stats(): + return jsonify(sniffer.stats()) diff --git a/backend/routes/logs_route.py b/backend/routes/logs_route.py new file mode 100644 index 0000000000000000000000000000000000000000..492d5217e923fbc98391dabd043fd408aabc4f94 --- /dev/null +++ b/backend/routes/logs_route.py @@ -0,0 +1,137 @@ +from flask import Blueprint, send_file, jsonify, request +import os +from utils.logger import ( + BCC_LOG_FILE, + CICIDS_LOG_FILE, + LOG_FILE, + get_recent_events, + get_model_stats, + clear_last_events, + delete_by_prediction, + delete_by_index, + get_active_model +) + +logs_bp = Blueprint("logs", __name__) + + +# ------------------------------- +# DOWNLOAD CSV LOG FILE (global) +# ------------------------------- +@logs_bp.route("/download", methods=["GET"]) +def download_logs(): + model = request.args.get("model") + + # MODEL-SPECIFIC CSVs + if model == "bcc": + path = BCC_LOG_FILE + elif model == "cicids": + path = CICIDS_LOG_FILE + else: + # fallback — global CSV + path = LOG_FILE + + if not os.path.exists(path): + return jsonify({"error": "Log file not found"}), 404 + + return send_file( + path, + as_attachment=True, + download_name=f"{model}_logs.csv" if model else "traffic_logs.csv", + mimetype="text/csv", + ) + + + +# ------------------------------- +# DOWNLOAD MODEL-SPECIFIC JSON +# ------------------------------- +@logs_bp.route("/download/json", methods=["GET"]) +def download_json_logs(): + try: + model = request.args.get("model", get_active_model()) + events = get_recent_events(model) + return jsonify({"model": model, "count": len(events), "events": events}) + except Exception as e: + print("❌ JSON log fetch error:", e) + return jsonify({"error": "Failed to fetch logs"}), 500 + + +# ------------------------------- +# CLEAR MODEL-WISE LAST N EVENTS +# ------------------------------- +@logs_bp.route("/clear", methods=["POST"]) +def clear_logs(): + try: + model = request.args.get("model", get_active_model()) + n = int(request.args.get("n", 50)) + + clear_last_events(model, n) + + print(f"🧹 Cleared last {n} events for model={model}") + return jsonify({"status": "ok", "deleted": n, "model": model}) + except Exception as e: + print("❌ Clear logs error:", e) + return jsonify({"error": str(e)}), 500 + + +# ------------------------------- +# CLEAR MODEL-WISE BY PREDICTION +# ------------------------------- +@logs_bp.route("/clear_pred", methods=["POST"]) +def clear_pred(): + pred = request.args.get("pred") + model = request.args.get("model", get_active_model()) + + if not pred: + return jsonify({"error": "Missing 'pred' parameter"}), 400 + + try: + delete_by_prediction(model, pred) + print(f"🧹 Deleted all events for prediction={pred} in model={model}") + return jsonify({"status": "ok", "deleted_pred": pred, "model": model}) + except Exception as e: + print("❌ Clear prediction error:", e) + return jsonify({"error": str(e)}), 500 + + +# ------------------------------- +# DELETE ONE ROW MODEL-WISE +# ------------------------------- +@logs_bp.route("/delete_one", methods=["POST"]) +def delete_one(): + try: + model = request.args.get("model", get_active_model()) + idx = int(request.args.get("index", -1)) + + ok = delete_by_index(model, idx) + + if ok: + print(f"🗑️ Deleted row index={idx} from model={model}") + return jsonify({"status": "ok", "index": idx, "model": model}) + else: + return jsonify({"status": "invalid index", "index": idx}), 400 + except Exception as e: + print("❌ Delete row error:", e) + return jsonify({"error": str(e)}), 500 + + +# ------------------------------- +# MODEL-WISE LOG STATUS +# ------------------------------- +@logs_bp.route("/status", methods=["GET"]) +def log_status(): + try: + model = request.args.get("model", get_active_model()) + counts = get_model_stats(model) + total = sum(counts.values()) + + return jsonify({ + "model": model, + "total_events": total, + "by_class": counts + }) + except Exception as e: + print("❌ Log status error:", e) + return jsonify({"error": str(e)}), 500 + diff --git a/backend/routes/manual_predict_route.py b/backend/routes/manual_predict_route.py new file mode 100644 index 0000000000000000000000000000000000000000..5efac9add1e2ae7a742bbfc5f3d7bf2442c99beb --- /dev/null +++ b/backend/routes/manual_predict_route.py @@ -0,0 +1,384 @@ +from flask import Blueprint, request, jsonify +from utils.model_selector import get_active_model, load_model +import numpy as np +import traceback +import math +import json + +manual_predict = Blueprint("manual_predict", __name__) + + +def _reliability_score_from_count(count): + # simple monotonic score: log-scale so diminishing returns for many samples + # returns 0-100 + if count is None: + return None + try: + c = float(count) + score = 20 + min(75, math.log10(c + 1) * 18) # tuned curve + return round(min(100, score), 1) + except Exception: + return None + + +@manual_predict.route("/predict_manual", methods=["POST"]) +def predict_manual(): + data = request.get_json(force=True, silent=True) or {} + + model_name = data.get("model") + values = data.get("values") # expecting a LIST (array) + if not model_name or not isinstance(values, list): + return jsonify({ + "error": "Expect JSON: { model: 'cicids'|'bcc', values: [v1, v2, ...] }" + }), 400 + + bundle = load_model(model_name) + model = bundle.get("model") + artifacts = bundle.get("artifacts") or {} + + if model is None: + return jsonify({"error": "Model not loaded"}), 500 + + try: + # Common metadata + model_info = { + "model_name": model_name, + "features": artifacts.get("features") or artifacts.get("feature_list") or bundle.get("features") or None, + "classes": None, + "train_counts": artifacts.get("train_counts") or artifacts.get("class_counts") or None, + "scaler_present": bool(artifacts.get("scaler")) or bool(bundle.get("scaler")), + } + + # helper to decode label_map / encoder (checks artifacts first, then bundle) + def decode_label(raw): + try: + # artifacts label_map (mapping value->name) + if artifacts.get("label_map"): + inv = {v: k for k, v in artifacts["label_map"].items()} + return inv.get(int(raw), str(raw)) + + # artifacts label_encoder + if artifacts.get("label_encoder"): + return artifacts["label_encoder"].inverse_transform([int(raw)])[0] + + # bundle-level encoder (e.g. realtime_encoder.pkl loaded in bundle) + if bundle.get("encoder"): + return bundle["encoder"].inverse_transform([int(raw)])[0] + except Exception as e: + # decoding failed; log and fallback to str + print("[decode_label] ERROR:", e) + # fallback: if raw already a string return it, else stringified raw + return str(raw) + + # CICIDS (13 features expected) + if model_name == "cicids": + feature_list = model_info["features"] + if not feature_list: + return jsonify({"error": "CICIDS artifacts missing 'features' list"}), 500 + + if len(values) != len(feature_list): + return jsonify({ + "error": f"CICIDS needs {len(feature_list)} features, received {len(values)}" + }), 400 + + X = np.array([[float(x) for x in values]], dtype=float) + + # apply scaler if present in artifacts or bundle + scaler = artifacts.get("scaler") or bundle.get("scaler") + scaled_row = None + try: + if scaler is not None: + scaled = scaler.transform(X) + scaled_row = np.array(scaled).tolist() + Xs = scaled + else: + Xs = X + except Exception as e: + # fallback to raw X if scaler fails + print("[predict_manual][CICIDS] scaler error:", e) + Xs = X + + # predict + pred_raw = model.predict(Xs)[0] + pred_label = decode_label(pred_raw) + + # probabilities + proba_max = None + probs = None + try: + if hasattr(model, "predict_proba"): + p = model.predict_proba(Xs)[0] + probs = [float(x) for x in p] + proba_max = float(max(p)) + except Exception: + pass + + # fill model_info.classes if possible (prefer encoder classes) + try: + if artifacts.get("label_encoder"): + model_info["classes"] = list(artifacts["label_encoder"].classes_) + elif bundle.get("encoder"): + model_info["classes"] = list(bundle["encoder"].classes_) + elif hasattr(model, "classes_"): + model_info["classes"] = [str(c) for c in model.classes_] + except Exception: + pass + + # compute reliability + train_counts = model_info.get("train_counts") + reliability = None + if train_counts and isinstance(train_counts, dict): + # try to get count for the predicted label (string keys) + reliability = _reliability_score_from_count( + train_counts.get(str(pred_label)) or train_counts.get(pred_raw) + ) + elif train_counts and isinstance(train_counts, list): + reliability = _reliability_score_from_count(sum(train_counts) / len(train_counts)) + else: + reliability = None + + resp = { + "prediction": pred_label, + "pred_raw": str(pred_raw), + "confidence": proba_max, + "proba_max": proba_max, + "probs": probs, + "raw_row": X.tolist()[0], + "scaled_row": scaled_row, + "model_info": model_info, + "reliability": reliability + } + return jsonify(resp) + + # BCC (15 features expected) + elif model_name == "bcc": + EXPECTED = 15 + if len(values) != EXPECTED: + return jsonify({ + "error": f"BCC needs {EXPECTED} features, received {len(values)}" + }), 400 + + X = np.array([[float(x) for x in values]], dtype=float) + + scaler = bundle.get("scaler") or artifacts.get("scaler") + scaled_row = None + try: + if scaler is not None: + scaled = scaler.transform(X) + scaled_row = np.array(scaled).tolist() + Xs = scaled + else: + Xs = X + except Exception as e: + print("[predict_manual][BCC] scaler error:", e) + Xs = X + + pred_raw = model.predict(Xs)[0] + pred_label = decode_label(pred_raw) + + proba_max = None + probs = None + try: + if hasattr(model, "predict_proba"): + p = model.predict_proba(Xs)[0] + probs = [float(x) for x in p] + proba_max = float(max(p)) + except Exception: + pass + + # model_info classes: prefer encoder classes if present + try: + encoder = bundle.get("encoder") or artifacts.get("label_encoder") + if encoder is not None: + model_info["classes"] = list(encoder.classes_) + elif hasattr(model, "classes_"): + # fallback - often these are numeric indices + model_info["classes"] = [str(c) for c in model.classes_] + except Exception: + pass + + train_counts = model_info.get("train_counts") + reliability = None + if train_counts and isinstance(train_counts, dict): + reliability = _reliability_score_from_count( + train_counts.get(str(pred_label)) or train_counts.get(pred_raw) + ) + elif train_counts: + reliability = _reliability_score_from_count(sum(train_counts) / len(train_counts)) + + resp = { + "prediction": pred_label, + "pred_raw": str(pred_raw), + "confidence": proba_max, + "proba_max": proba_max, + "probs": probs, + "raw_row": X.tolist()[0], + "scaled_row": scaled_row, + "model_info": model_info, + "reliability": reliability + } + return jsonify(resp) + + else: + return jsonify({"error": "unsupported model"}), 400 + + except Exception as e: + print("[predict_manual] Exception:", e) + return jsonify({"error": str(e)}), 500 + + +@manual_predict.route("/predict_debug", methods=["POST"]) +def predict_debug(): + """ + Debug endpoint: returns raw ordered vector, scaled vector (if scaler), + model classes, prediction, predict_proba (if available), and artifacts info. + Use this to compare what you *intend* to send vs what model receives. + """ + try: + data = request.get_json(force=True, silent=True) or {} + model_name = data.get("model") + feats = data.get("features") + if not model_name or not isinstance(feats, dict): + return jsonify({"error": "Provide JSON {model: 'cicids'|'bcc', features: {...}}"}), 400 + + bundle = load_model(model_name) + model = bundle.get("model") + artifacts = bundle.get("artifacts") or {} + + if model is None: + return jsonify({"error": "Model not loaded"}), 500 + + debug = {"model_name": model_name} + + if model_name == "cicids": + feature_list = artifacts.get("features") + debug["artifact_features"] = feature_list + # Build ordered row (float) + row = [float(feats.get(f, 0.0)) for f in (feature_list or [])] + debug["raw_row"] = row + + X = np.array([row], dtype=float) + + scaler = artifacts.get("scaler") or bundle.get("scaler") + if scaler is not None: + try: + Xs = scaler.transform(X) + debug["scaled_row"] = np.array(Xs).tolist() + except Exception as e: + debug["scaler_error"] = str(e) + Xs = X + else: + Xs = X + debug["scaled_row"] = None + + # predict + try: + pred_raw = model.predict(Xs)[0] + debug["pred_raw"] = repr(pred_raw) + # classes + try: + debug["model_classes"] = [str(c) for c in getattr(model, "classes_", [])] + except Exception: + debug["model_classes"] = None + # proba + if hasattr(model, "predict_proba"): + try: + probs = model.predict_proba(Xs)[0].tolist() + debug["probs"] = probs + debug["proba_max"] = max(probs) + except Exception as e: + debug["proba_error"] = str(e) + # decode label + label = str(pred_raw) + try: + if artifacts.get("label_map"): + inv = {v: k for k, v in artifacts["label_map"].items()} + label = inv.get(int(pred_raw), str(pred_raw)) + elif artifacts.get("label_encoder"): + label = artifacts["label_encoder"].inverse_transform([int(pred_raw)])[0] + elif bundle.get("encoder"): + label = bundle["encoder"].inverse_transform([int(pred_raw)])[0] + except Exception as e: + debug["label_decode_error"] = str(e) + + debug["label"] = label + except Exception as e: + debug["predict_error"] = str(e) + debug["predict_tb"] = traceback.format_exc() + + return jsonify(debug) + + elif model_name == "bcc": + # BCC: we will attempt to build 15-element row from expected keys or values + BCC_FEATURES = [ + "proto", "src_port", "dst_port", "flow_duration", "total_fwd_pkts", + "total_bwd_pkts", "flags_numeric", "payload_len", "header_len", + "rate", "iat", "syn", "ack", "rst", "fin" + ] + debug["expected_bcc_features"] = BCC_FEATURES + if all(k in feats for k in BCC_FEATURES): + row = [float(feats.get(k, 0.0)) for k in BCC_FEATURES] + else: + vals = list(feats.values()) + vals = [float(v) if (v is not None and str(v).strip() != "") else 0.0 for v in vals] + if len(vals) < 15: + vals = vals + [0.0] * (15 - len(vals)) + row = vals[:15] + debug["raw_row"] = row + X = np.array([row], dtype=float) + + # try scaler from bundle or artifacts + scaler = bundle.get("scaler") or artifacts.get("scaler") + if scaler is not None: + try: + Xs = scaler.transform(X) + debug["scaled_row"] = np.array(Xs).tolist() + except Exception as e: + debug["scaler_error"] = str(e) + Xs = X + else: + Xs = X + debug["scaled_row"] = None + + try: + pred_raw = model.predict(Xs)[0] + debug["pred_raw"] = repr(pred_raw) + # model raw classes (may be numeric) + debug["model_classes"] = [str(c) for c in getattr(model, "classes_", [])] + if hasattr(model, "predict_proba"): + try: + probs = model.predict_proba(Xs)[0].tolist() + debug["probs"] = probs + debug["proba_max"] = max(probs) + except Exception as e: + debug["proba_error"] = str(e) + # decode using encoder if present (bundle or artifacts) + label = str(pred_raw) + try: + encoder = bundle.get("encoder") or artifacts.get("label_encoder") + if encoder: + label = encoder.inverse_transform([int(pred_raw)])[0] + except Exception as e: + debug["label_decode_error"] = str(e) + debug["label"] = label + except Exception as e: + debug["predict_error"] = str(e) + debug["predict_tb"] = traceback.format_exc() + + return jsonify(debug) + + else: + return jsonify({"error": "unsupported model"}), 400 + + except Exception as e: + return jsonify({"error": str(e), "tb": traceback.format_exc()}), 500 + + +@manual_predict.route("/retrain_request", methods=["POST"]) +def retrain_request(): + data = request.get_json() or {} + # Save retrain request to a file for later processing + with open("retrain_requests.jsonl", "a") as f: + f.write(json.dumps(data) + "\n") + + return jsonify({"status": "saved", "msg": "Retrain request recorded"}) diff --git a/backend/routes/ml_route.py b/backend/routes/ml_route.py new file mode 100644 index 0000000000000000000000000000000000000000..622f25ab07da72c325e1cd6cda04cb0c672a094e --- /dev/null +++ b/backend/routes/ml_route.py @@ -0,0 +1,297 @@ +# ========================================================== +# backend/routes/ml_route.py +# Adaptive AI Framework - ML Route for NIDS Intelligence +# ========================================================== + +from flask import Blueprint, request, jsonify +import threading +import time +import os +import joblib +import random +from datetime import datetime +from flask_cors import cross_origin +import numpy as np + +ml_bp = Blueprint("ml_bp", __name__) + +ML_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "ml_models")) + +# In-memory global stores +MODELS = {} +RETRAIN_STATUS = {"running": False, "progress": 0, "message": "", "last_result": None} +METRICS_CACHE = {} + +# Your NIDS feature list (15) +FEATURE_NAMES = [ + "protocol", "src_port", "dst_port", "duration", "packets_count", + "fwd_packets_count", "bwd_packets_count", "total_payload_bytes", + "total_header_bytes", "bytes_rate", "packets_rate", + "syn_flag_counts", "ack_flag_counts", "rst_flag_counts", "fin_flag_counts" +] + +# ========================================================== +# 🧠 Model Management +# ========================================================== + +def try_load_models(): + """Load models from disk (if available).""" + global MODELS + MODELS = {} + try: + files = os.listdir(ML_DIR) + except Exception: + files = [] + + for fname in files: + if fname.endswith(".pkl"): + name = os.path.splitext(fname)[0] + try: + m = joblib.load(os.path.join(ML_DIR, fname)) + MODELS[name] = {"obj": m, "name": name, "path": os.path.join(ML_DIR, fname)} + except Exception as e: + MODELS[name] = {"obj": None, "name": name, "path": os.path.join(ML_DIR, fname), "load_error": str(e)} + +try_load_models() + +def model_summary(name, entry): + obj = entry.get("obj") + info = { + "id": name, + "name": name, + "type": type(obj).__name__ if obj is not None else "Unknown", + "accuracy": None, + "f1_score": None, + "dataset": "unknown", + "status": "Active" if obj is not None else "Unavailable", + "last_trained": None, + } + meta = getattr(obj, "metadata", None) + if isinstance(meta, dict): + info.update({ + "accuracy": meta.get("accuracy"), + "f1_score": meta.get("f1_score"), + "dataset": meta.get("dataset"), + "last_trained": meta.get("last_trained"), + }) + return info + +# ========================================================== +# 📦 ROUTES +# ========================================================== + +@ml_bp.route("/ml/models", methods=["GET"]) +def list_models(): + """Return all available models.""" + try_load_models() + out = [model_summary(name, entry) for name, entry in MODELS.items()] + + if not out: + out = [{ + "id": "placeholder_model", + "name": "Placeholder Detector", + "type": "Simulated", + "accuracy": 92.1, + "f1_score": 0.90, + "dataset": "Simulated-NIDS", + "status": "Active", + "last_trained": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + }] + return jsonify(out) + + +@ml_bp.route("/ml/metrics", methods=["GET"]) +def get_metrics(): + """Return metrics like accuracy history & class distribution.""" + if METRICS_CACHE: + return jsonify(METRICS_CACHE) + + accuracy_history = [ + {"epoch": i + 1, "accuracy": round(0.8 + i * 0.04 + random.random() * 0.01, 3)} + for i in range(10) + ] + class_distribution = { + "Normal": 1500, + "DDoS": 420, + "PortScan": 260, + "Botnet": 140, + "VPN": 120, + "TOR": 90 + } + METRICS_CACHE.update({ + "accuracy_history": accuracy_history, + "class_distribution": class_distribution + }) + return jsonify(METRICS_CACHE) + +# ========================================================== +# 🔮 PREDICTION ENDPOINT +# ========================================================== + +def safe_predict_with_model(model_entry, features): + """Try to predict with a loaded model.""" + obj = model_entry.get("obj") + if obj is None: + return None + try: + if isinstance(features, dict): + features_list = [features.get(k, 0) for k in FEATURE_NAMES] + else: + features_list = features + X = [features_list] + + if hasattr(obj, "predict_proba"): + probs = obj.predict_proba(X)[0] + pred_idx = int(np.argmax(probs)) + pred_label = obj.classes_[pred_idx] if hasattr(obj, "classes_") else str(pred_idx) + return {"prediction": str(pred_label), "confidence": float(round(probs[pred_idx], 4))} + else: + pred = obj.predict(X)[0] + return {"prediction": str(pred), "confidence": 1.0} + except Exception: + return None + + +@ml_bp.route("/ml/predict-test", methods=["POST"]) +def predict_test(): + """Accept feature dict and return prediction result.""" + data = request.get_json() or {} + features = data.get("features") or data.get("sample") + model_name = data.get("model") + + try: + if not features: + return jsonify({"error": "No features provided"}), 400 + + try_load_models() + chosen = None + if model_name and model_name in MODELS: + chosen = MODELS[model_name] + else: + for k, e in MODELS.items(): + if e.get("obj") is not None: + chosen = e + break + + if chosen: + res = safe_predict_with_model(chosen, features) + if res: + res.update({"model_used": chosen.get("name")}) + return jsonify(res) + + # Fallback simulated prediction + classes = ["Normal", "DDoS", "PortScan", "Botnet", "VPN", "TOR"] + pred = random.choice(classes) + confidence = round(random.uniform(0.7, 0.99), 3) + return jsonify({ + "prediction": pred, + "confidence": confidence, + "model_used": "SimulatedDetector", + "used_features": FEATURE_NAMES + }) + + except Exception as e: + return jsonify({"error": str(e)}), 500 + +# ========================================================== +# ⚙️ RETRAIN SIMULATION +# ========================================================== + +def _retrain_job(model_id=None, epochs=6): + RETRAIN_STATUS["running"] = True + RETRAIN_STATUS["progress"] = 0 + RETRAIN_STATUS["message"] = "Starting retrain..." + best_acc = 0.0 + try: + for e in range(1, epochs + 1): + RETRAIN_STATUS["message"] = f"Epoch {e}/{epochs}..." + for p in range(5): + time.sleep(0.45) + RETRAIN_STATUS["progress"] = int(((e - 1) * 100 / epochs) + (p + 1) * (100 / (epochs * 5))) + best_acc = round(0.85 + (e * 0.02) + random.random() * 0.01, 4) + RETRAIN_STATUS["message"] = f"Epoch {e} finished. acc: {best_acc}" + RETRAIN_STATUS["message"] = "Finalizing..." + time.sleep(0.6) + RETRAIN_STATUS["last_result"] = { + "accuracy": best_acc, + "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S") + } + METRICS_CACHE.setdefault("accuracy_history", []).append({ + "epoch": len(METRICS_CACHE.get("accuracy_history", [])) + 1, + "accuracy": best_acc + }) + except Exception as e: + RETRAIN_STATUS["message"] = f"Error: {e}" + finally: + RETRAIN_STATUS["running"] = False + RETRAIN_STATUS["progress"] = 100 + + +@ml_bp.route("/ml/retrain", methods=["POST"]) +def retrain(): + """Start retraining in background thread.""" + if RETRAIN_STATUS.get("running"): + return jsonify({"error": "Retrain already in progress"}), 409 + payload = request.get_json() or {} + model_id = payload.get("model") + epochs = int(payload.get("epochs", 6)) + t = threading.Thread(target=_retrain_job, args=(model_id, epochs), daemon=True) + t.start() + return jsonify({"message": "Retrain started", "epochs": epochs}) + + +@ml_bp.route("/ml/retrain/status", methods=["GET"]) +def retrain_status(): + """Get retrain progress.""" + return jsonify(RETRAIN_STATUS) + +# ========================================================== +# 🧩 FEATURE IMPORTANCE +# ========================================================== + +@ml_bp.route("/feature-importance/", methods=["GET"]) +@cross_origin() +def feature_importance(model_id): + """Return actual or simulated feature importances.""" + try: + try_load_models() + entry = MODELS.get(model_id) + mdl = entry.get("obj") if entry else None + + fi = [] + if mdl is not None and hasattr(mdl, "feature_importances_"): + arr = np.array(getattr(mdl, "feature_importances_")).flatten() + arr = arr[:len(FEATURE_NAMES)] + for i, v in enumerate(arr): + fi.append({"feature": FEATURE_NAMES[i], "importance": float(v)}) + elif mdl is not None and hasattr(mdl, "coef_"): + arr = np.abs(np.array(getattr(mdl, "coef_")).flatten()) + arr = arr[:len(FEATURE_NAMES)] + total = float(np.sum(arr)) or 1.0 + for i, v in enumerate(arr): + fi.append({"feature": FEATURE_NAMES[i], "importance": float(v / total * 100.0)}) + else: + simulated = { + "protocol": 8.2, + "src_port": 7.1, + "dst_port": 6.4, + "duration": 10.5, + "packets_count": 7.8, + "fwd_packets_count": 6.9, + "bwd_packets_count": 6.5, + "total_payload_bytes": 9.8, + "total_header_bytes": 8.6, + "bytes_rate": 9.9, + "packets_rate": 9.1, + "syn_flag_counts": 5.3, + "ack_flag_counts": 4.9, + "rst_flag_counts": 3.8, + "fin_flag_counts": 3.2 + } + fi = [{"feature": f, "importance": float(v)} for f, v in simulated.items()] + + return jsonify({"model_id": model_id, "feature_importance": fi}) + + except Exception as e: + return jsonify({"error": str(e)}), 500 + diff --git a/backend/routes/ml_switch_route.py b/backend/routes/ml_switch_route.py new file mode 100644 index 0000000000000000000000000000000000000000..cd494efc26bd5d025c901ef429024b1abe188147 --- /dev/null +++ b/backend/routes/ml_switch_route.py @@ -0,0 +1,105 @@ +# backend/routes/ml_switch_route.py +from flask import Blueprint, request, jsonify +from utils.model_selector import set_active_model, get_active_model, load_model + +ml_switch = Blueprint("ml_switch", __name__) + +@ml_switch.route("/active", methods=["GET"]) +def active(): + return jsonify({"active_model": get_active_model()}) + +@ml_switch.route("/select", methods=["POST"]) +def select(): + data = request.get_json(force=True, silent=True) or {} + model = data.get("model") + if model not in ("bcc", "cicids"): + return jsonify({"error": "model must be 'bcc' or 'cicids'"}), 400 + try: + set_active_model(model) + # attempt load to give quick feedback + info = load_model(model) + return jsonify({"message": f"Active model set to {model}", "loaded": bool(info)}) + + except Exception as e: + return jsonify({"error": str(e)}), 500 + + +@ml_switch.route("/health", methods=["GET"]) +def health(): + import numpy as np + import pandas as pd + + active = get_active_model() + bundle = load_model(active) + + model = bundle.get("model") + artifacts = bundle.get("artifacts") + + # Default responses + artifact_keys = list(artifacts.keys()) if artifacts else [] + features = None + feature_count = 0 + test_prediction = "N/A" + + # ------------------------------------------ + # CICIDS HEALTH CHECK + # ------------------------------------------ + if active == "cicids": + if artifacts and "features" in artifacts: + features = artifacts["features"] + feature_count = len(features) + + try: + # generate a zero vector + X = np.zeros((1, feature_count)) + scaler = artifacts.get("scaler") + if scaler: + X = scaler.transform(X) + + pred = model.predict(X)[0] + test_prediction = str(pred) + + except Exception as e: + test_prediction = f"Error: {str(e)}" + + # ------------------------------------------ + # BCC HEALTH CHECK + # ------------------------------------------ + elif active == "bcc": + try: + # Create minimal fake BCC packet feature vector: 15 values + X = np.zeros((1, 15)) + + scaler = bundle.get("scaler") + encoder = bundle.get("encoder") + + if scaler: + Xs = scaler.transform(X) + else: + Xs = X + + pred_raw = model.predict(Xs)[0] + + if encoder: + pred = encoder.inverse_transform([int(pred_raw)])[0] + else: + pred = str(pred_raw) + + test_prediction = f"OK: {pred}" + + except Exception as e: + test_prediction = f"Error: {str(e)}" + + # ------------------------------------------ + # Build response + # ------------------------------------------ + return { + "active_model": active, + "model_loaded": model is not None, + "artifact_keys": artifact_keys, + "feature_count": feature_count, + "features": features, + "test_prediction": test_prediction + } + + diff --git a/backend/routes/offline_detection.py b/backend/routes/offline_detection.py new file mode 100644 index 0000000000000000000000000000000000000000..9e7b66a8643ba4063357c95c424d5a1aa9ea210b --- /dev/null +++ b/backend/routes/offline_detection.py @@ -0,0 +1,139 @@ +import os +import pandas as pd +from flask import Blueprint, request, jsonify, send_file +from werkzeug.utils import secure_filename +from datetime import datetime +import joblib +from fpdf import FPDF +from utils.pcap_to_csv import convert_pcap_to_csv + +offline_bp = Blueprint("offline_bp", __name__) + +UPLOAD_DIR = "uploads" +SAMPLE_DIR = "sample" +os.makedirs(UPLOAD_DIR, exist_ok=True) +os.makedirs(SAMPLE_DIR, exist_ok=True) + +ALLOWED_EXT = {"csv", "pcap"} + +# Features +BCC_FEATURES = [ + "proto","src_port","dst_port","flow_duration","total_fwd_pkts","total_bwd_pkts", + "flags_numeric","payload_len","header_len","rate","iat","syn","ack","rst","fin" +] + +CICIDS_FEATURES = [ + "Protocol","Dst Port","Flow Duration","Tot Fwd Pkts","Tot Bwd Pkts", + "TotLen Fwd Pkts","TotLen Bwd Pkts","Fwd Pkt Len Mean","Bwd Pkt Len Mean", + "Flow IAT Mean","Fwd PSH Flags","Fwd URG Flags","Fwd IAT Mean" +] + +# Models +bcc_model = joblib.load("ml_models/realtime_model.pkl") +bcc_encoder = joblib.load("ml_models/realtime_encoder.pkl") +bcc_scaler = joblib.load("ml_models/realtime_scaler.pkl") + +cicids_model = joblib.load("ml_models/rf_pipeline.joblib") + + +def allowed(filename): + return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXT + + +# 📌 Sample CSV Download +@offline_bp.route("/sample/", methods=["GET"]) +def download_sample(model): + file_path = None + if model == "bcc": + file_path = os.path.join(SAMPLE_DIR, "bcc_sample.csv") + elif model == "cicids": + file_path = os.path.join(SAMPLE_DIR, "cicids_sample.csv") + else: + return jsonify(success=False, message="Invalid model"), 400 + + if not os.path.exists(file_path): + return jsonify(success=False, message="Sample file missing"), 404 + + return send_file(file_path, as_attachment=True) + + +# 📌 Prediction API +@offline_bp.route("/predict", methods=["POST"]) +def offline_predict(): + if "file" not in request.files: + return jsonify(success=False, message="No file uploaded"), 400 + + file = request.files["file"] + model_type = request.form.get("model", "bcc") + + if not allowed(file.filename): + return jsonify(success=False, message="Unsupported file type"), 400 + + filename = secure_filename(file.filename) + saved_path = os.path.join(UPLOAD_DIR, filename) + file.save(saved_path) + + # PCAP Conversion + if filename.lower().endswith(".pcap"): + saved_path = convert_pcap_to_csv(saved_path) + + + df = pd.read_csv(saved_path) + # Prevent empty CSV prediction + if df.shape[0] == 0: + return jsonify(success=False, message="CSV has no data rows to analyze!"), 400 + + expected = BCC_FEATURES if model_type == "bcc" else CICIDS_FEATURES + + missing = [c for c in expected if c not in df.columns] + if missing: + return jsonify(success=False, message=f"Missing features: {missing}") + + df = df[expected] + + if model_type == "bcc": + scaled = bcc_scaler.transform(df) + preds = bcc_model.predict(scaled) + labels = bcc_encoder.inverse_transform(preds) + else: + labels = cicids_model.predict(df) + + df["prediction"] = labels + class_counts = df["prediction"].value_counts().to_dict() + + results = [{"index": i, "class": lbl} for i, lbl in enumerate(labels)] + + result_file = os.path.join(UPLOAD_DIR, "last_results.csv") + df.to_csv(result_file, index=False) + + return jsonify(success=True, classCounts=class_counts, results=results) + + +# 📌 PDF Report Generation +@offline_bp.route("/report", methods=["GET"]) +def offline_report(): + result_file = os.path.join(UPLOAD_DIR, "last_results.csv") + if not os.path.exists(result_file): + return jsonify(success=False, message="Run prediction first"), 400 + + df = pd.read_csv(result_file) + class_counts = df["prediction"].value_counts().to_dict() + + pdf_path = os.path.join(UPLOAD_DIR, "offline_report.pdf") + + pdf = FPDF() + pdf.add_page() + pdf.set_font("Arial", "B", 16) + pdf.cell(0, 10, "AI-NIDS Offline Threat Analysis Report", ln=True) + + pdf.set_font("Arial", size=12) + pdf.cell(0, 10, f"Generated: {datetime.now()}", ln=True) + pdf.ln(5) + + for c, v in class_counts.items(): + pdf.cell(0, 8, f"{c}: {v}", ln=True) + + pdf.output(pdf_path) + return send_file(pdf_path, as_attachment=True) + + diff --git a/backend/routes/predict_route.py b/backend/routes/predict_route.py new file mode 100644 index 0000000000000000000000000000000000000000..529b7c73fdd9f71142b6b5b91664c65195be066a --- /dev/null +++ b/backend/routes/predict_route.py @@ -0,0 +1,132 @@ +# backend/routes/predict_route.py +from flask import Blueprint, request, jsonify +import time +import numpy as np +import pandas as pd +from utils.model_selector import load_model, get_active_model +from utils.logger import classify_risk + +predict_bp = Blueprint("predict", __name__) + +@predict_bp.route("/", methods=["GET"]) +def info(): + active = get_active_model() + return jsonify({ + "message": "POST JSON to /api/predict/ to get model prediction.", + "active_model": active, + "note": "For 'bcc' model send ordered features or dict; for 'cicids' send named features matching artifacts['features']." + }) + +@predict_bp.route("/", methods=["POST"]) +def predict(): + active = get_active_model() + mdl = load_model(active) + + if active == "bcc": + model = mdl.get("model") + scaler = mdl.get("scaler") + encoder = mdl.get("encoder") + + if model is None or scaler is None or encoder is None: + return jsonify({"error": "BCC model/scaler/encoder not loaded on server."}), 500 + + data = request.get_json(force=True, silent=True) + if data is None: + return jsonify({"error": "No JSON body provided"}), 400 + + # Accept either list/array or dict of features + # You must keep the same feature order as used in training (15 values) + if isinstance(data, dict): + # if the client provides named keys, try to coerce to ordered list + # fallback: take values in insertion order + vals = list(data.values()) + else: + vals = list(data) + + try: + X = np.array([float(v) for v in vals], dtype=float).reshape(1, -1) + except Exception as e: + return jsonify({"error": f"Failed to coerce input to numeric vector: {e}"}), 400 + + try: + Xs = scaler.transform(X) + except Exception: + # fallback: try prediction without scaler + Xs = X + + try: + pred_idx = model.predict(Xs)[0] + conf = None + if hasattr(model, "predict_proba"): + conf = float(np.max(model.predict_proba(Xs))) * 100.0 + label = encoder.inverse_transform([int(pred_idx)])[0] + risk = classify_risk(label) + return jsonify({ + "prediction": str(label), + "confidence": round(conf, 2) if conf is not None else None, + "risk_level": risk + }) + except Exception as e: + return jsonify({"error": f"Model predict failed: {str(e)}"}), 500 + + elif active == "cicids": + obj = mdl.get("artifacts", None) + model = mdl.get("model", None) + if model is None or obj is None: + return jsonify({"error": "CICIDS model or artifacts not available on server."}), 500 + + # artifacts expected to have 'features' and 'scaler' + features = obj.get("features") or obj.get("features_used") or obj.get("feature_list") + scaler = obj.get("scaler") or obj.get("scaler_object") + + if not features or scaler is None: + return jsonify({"error": "CICIDS artifacts missing features or scaler."}), 500 + + data = request.get_json(force=True, silent=True) + if data is None: + return jsonify({"error": "No JSON body provided"}), 400 + + # Accept dict of named features or list + if isinstance(data, dict): + # build row using artifacts feature order (missing -> 0) + row = [float(data.get(f, 0)) for f in features] + else: + # list or array + try: + row = [float(x) for x in data] + except Exception as e: + return jsonify({"error": "Provided input must be array or dict of numbers."}), 400 + + if len(row) != len(features): + return jsonify({"error": f"Expecting {len(features)} features for cicids: {features}"}), 400 + + X_df = pd.DataFrame([row], columns=features) + try: + Xs = scaler.transform(X_df) + except Exception: + Xs = X_df.values + + try: + pred = model.predict(Xs)[0] + conf = None + if hasattr(model, "predict_proba"): + conf = float(np.max(model.predict_proba(Xs))) * 100.0 + # label may already be string; try safe conversion + try: + label = str(pred) + except Exception: + label = repr(pred) + + risk = classify_risk(label) + return jsonify({ + "prediction": label, + "confidence": round(conf, 2) if conf else None, + "risk_level": risk + }) + except Exception as e: + return jsonify({"error": f"CICIDS predict failed: {str(e)}"}), 500 + + else: + return jsonify({"error": "Unknown active model"}), 500 + + diff --git a/backend/routes/reports_route.py b/backend/routes/reports_route.py new file mode 100644 index 0000000000000000000000000000000000000000..45b57bcccc281a3fdbffc8d31c1d276e2aee7447 --- /dev/null +++ b/backend/routes/reports_route.py @@ -0,0 +1,172 @@ +# backend/routes/reports_route.py +from flask import Blueprint, jsonify, request, send_file +from fpdf import FPDF +from io import BytesIO +from datetime import datetime, timedelta +from flask_mail import Message +from extensions import mail +import random + +reports_bp = Blueprint("reports_bp", __name__) + +# Fake (but structured) historical attack data +CLASSES = ["DDoS", "VPN", "TOR", "I2P", "SQL Injection", "Malware"] + +def generate_fake_data(days=7): + today = datetime.now() + data = [] + for i in range(days): + date = (today - timedelta(days=i)).strftime("%Y-%m-%d") + day_data = {cls: random.randint(20, 200) for cls in CLASSES} + day_data["date"] = date + data.append(day_data) + return list(reversed(data)) + +ATTACK_DATA = generate_fake_data(14) + +# -------------------------------------------------------- +@reports_bp.route("/", methods=["GET"]) +def reports_overview(): + total_attacks = sum(sum(v for k, v in day.items() if k != "date") for day in ATTACK_DATA) + recent = ATTACK_DATA[-1] + return jsonify({ + "total_attacks": total_attacks, + "last_day": recent["date"], + "last_day_total": sum(v for k, v in recent.items() if k != "date"), + }) + +# -------------------------------------------------------- +@reports_bp.route("/trend", methods=["GET"]) +def attack_trend(): + trend = [{"date": d["date"], "attacks": sum(v for k, v in d.items() if k != "date")} for d in ATTACK_DATA] + return jsonify(trend) + +# -------------------------------------------------------- +@reports_bp.route("/distribution", methods=["GET"]) +def attack_distribution(): + total = {cls: sum(day.get(cls, 0) for day in ATTACK_DATA) for cls in CLASSES} + return jsonify(total) + +# -------------------------------------------------------- +@reports_bp.route("/generate", methods=["GET"]) +def generate_report_pdf(): + pdf = FPDF() + pdf.add_page() + pdf.set_font("Helvetica", "B", 16) + pdf.cell(0, 10, "Adaptive AI NIDS - Attack Report", ln=True, align="C") + + pdf.set_font("Helvetica", "", 12) + pdf.ln(8) + pdf.cell(0, 10, f"Generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True) + pdf.ln(6) + + pdf.set_font("Helvetica", "B", 13) + pdf.cell(0, 10, "Summary:", ln=True) + pdf.set_font("Helvetica", "", 11) + total = {cls: sum(day.get(cls, 0) for day in ATTACK_DATA) for cls in CLASSES} + for cls, val in total.items(): + pdf.cell(0, 8, f" • {cls}: {val} attacks", ln=True) + + pdf.ln(8) + pdf.set_font("Helvetica", "I", 10) + pdf.multi_cell(0, 8, + "This report summarizes attack activity captured by the Adaptive AI NIDS system. " + "It includes class-wise distribution and historical trend for the past two weeks.") + + # Output to memory + buffer = BytesIO() + pdf.output(buffer) + buffer.seek(0) + filename = f"NIDS_Report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf" + return send_file(buffer, as_attachment=True, download_name=filename, mimetype="application/pdf") + +# -------------------------------------------------------- +@reports_bp.route("/email", methods=["POST"]) +def send_report_email(): + data = request.get_json() + recipient = data.get("email") + if not recipient: + return jsonify({"error": "No recipient email provided"}), 400 + + # Generate detailed PDF + pdf_buffer = BytesIO() + pdf = FPDF() + pdf.add_page() + pdf.set_font("Helvetica", "B", 16) + pdf.cell(0, 10, "Adaptive AI NIDS - Full System Report", ln=True, align="C") + pdf.ln(8) + pdf.set_font("Helvetica", "", 12) + pdf.cell(0, 10, "Summary of recent network activity:", ln=True) + pdf.ln(5) + + pdf.set_font("Helvetica", "B", 12) + pdf.cell(0, 8, "Attack Distribution:", ln=True) + total = {cls: sum(day.get(cls, 0) for day in ATTACK_DATA) for cls in CLASSES} + pdf.set_font("Helvetica", "", 11) + for cls, val in total.items(): + pdf.cell(0, 8, f" - {cls}: {val} attacks", ln=True) + + pdf.ln(6) + pdf.set_font("Helvetica", "B", 12) + pdf.cell(0, 8, "Recent Trend (last 7 days):", ln=True) + pdf.set_font("Helvetica", "", 11) + for d in ATTACK_DATA[-7:]: + pdf.cell(0, 8, f"{d['date']}: {sum(v for k, v in d.items() if k != 'date')} total", ln=True) + + pdf.ln(10) + pdf.set_font("Helvetica", "I", 10) + pdf.multi_cell(0, 8, "This automated report is generated by Adaptive AI NIDS. " + "It summarizes live detections, system diagnostics, and " + "AI-identified attack classes.") + + pdf.output(pdf_buffer) + pdf_buffer.seek(0) + + try: + msg = Message( + subject="Adaptive AI NIDS - Full Report", + recipients=[recipient], + body="Attached is your Adaptive AI NIDS summary report with recent attack data.", + ) + msg.attach("Adaptive_NIDS_Report.pdf", "application/pdf", pdf_buffer.read()) + mail.send(msg) + return jsonify({"success": True, "message": f"Email sent to {recipient}"}) + except Exception as e: + return jsonify({"error": str(e)}), 500 + + + +@reports_bp.route("/list", methods=["GET"]) +def list_reports(): + reports = [ + { + "id": 1, + "name": "System Health Summary", + "type": "System Health", + "size": "420 KB", + "date": datetime.now().strftime("%Y-%m-%d %H:%M"), + "endpoint": "/api/reports/generate" + }, + { + "id": 2, + "name": "Network Attack Analysis", + "type": "Network Analysis", + "size": "1.2 MB", + "date": datetime.now().strftime("%Y-%m-%d %H:%M"), + "endpoint": "/api/reports/generate" + }, + { + "id": 3, + "name": "Threat Intelligence Summary", + "type": "Threat Intelligence", + "size": "620 KB", + "date": datetime.now().strftime("%Y-%m-%d %H:%M"), + "endpoint": "/api/reports/generate" + }, + ] + return jsonify(reports) + + + + + diff --git a/backend/routes/system_info.py b/backend/routes/system_info.py new file mode 100644 index 0000000000000000000000000000000000000000..b4dea609c31da93470d715e199c0b3a83a420427 --- /dev/null +++ b/backend/routes/system_info.py @@ -0,0 +1,211 @@ +from flask import Blueprint, jsonify +import psutil +import platform +import socket +from datetime import datetime +import random +import time +import random +import io +from fpdf import FPDF +from flask import send_file + + + + +system_bp = Blueprint("system", __name__) + +@system_bp.route("/system/status", methods=["GET"]) +def system_status(): + try: + hostname = socket.gethostname() + ip_address = socket.gethostbyname(hostname) + os_info = platform.platform() + cpu_name = platform.processor() + + # --- Metrics --- + cpu_percent = psutil.cpu_percent(interval=0.5) + ram = psutil.virtual_memory() + disk = psutil.disk_usage('/') + net_io = psutil.net_io_counters() + + # --- Temperature --- + try: + temps = psutil.sensors_temperatures() + cpu_temp = ( + temps.get("coretemp")[0].current + if "coretemp" in temps + else random.uniform(45.0, 75.0) # fallback + ) + except Exception: + cpu_temp = random.uniform(45.0, 75.0) + + # --- AI Health Score --- + # Weighted average (higher = better) + usage = (cpu_percent * 0.4 + ram.percent * 0.3 + disk.percent * 0.3) + health_score = max(0, 100 - usage) + + data = { + "hostname": hostname, + "ip_address": ip_address, + "os": os_info, + "cpu_name": cpu_name, + "cpu_usage": round(cpu_percent, 2), + "ram_usage": round(ram.percent, 2), + "disk_usage": round(disk.percent, 2), + "ram_total": round(ram.total / (1024 ** 3), 2), + "disk_total": round(disk.total / (1024 ** 3), 2), + "network_sent": round(net_io.bytes_sent / (1024 ** 2), 2), + "network_recv": round(net_io.bytes_recv / (1024 ** 2), 2), + "cpu_temp": round(cpu_temp, 2), + "health_score": round(health_score, 2), + "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + } + return jsonify(data) + except Exception as e: + return jsonify({"error": str(e)}), 500 + +@system_bp.route("/system/diagnostic", methods=["GET"]) +def run_diagnostic(): + """Simulate a full AI-powered system stability diagnostic.""" + try: + # Simulated stress test (CPU, memory response) + cpu_load = random.uniform(60, 98) + ram_stress = random.uniform(50, 95) + disk_io = random.uniform(40, 90) + latency = random.uniform(15, 100) + + # AI stability score (100 = perfect) + stability = 100 - ((cpu_load * 0.3) + (ram_stress * 0.3) + (disk_io * 0.2) + (latency * 0.2)) / 2 + stability = round(max(0, min(100, stability)), 2) + + # Fake attack summary data + attacks = { + "total_attacks": random.randint(1200, 4200), + "blocked": random.randint(1100, 4000), + "missed": random.randint(5, 20), + "recent_threats": [ + {"type": "DDoS Flood", "risk": "High", "ip": "45.77.23.9"}, + {"type": "SQL Injection", "risk": "Medium", "ip": "103.54.66.120"}, + {"type": "VPN Evasion", "risk": "Low", "ip": "198.168.12.45"}, + ], + } + + diagnostic = { + "cpu_load": round(cpu_load, 2), + "ram_stress": round(ram_stress, 2), + "disk_io": round(disk_io, 2), + "latency": round(latency, 2), + "stability_score": stability, + "attacks": attacks, + "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"), + } + return jsonify(diagnostic) + except Exception as e: + return jsonify({"error": str(e)}), 500 + + + +@system_bp.route("/system/report", methods=["GET"]) +def generate_system_report(): + """Generate a downloadable PDF system report.""" + try: + # --- Simulated data or pull from live sources --- + system_status = { + "OS": "Windows 10 Pro", + "CPU": "Intel i5-12700H", + "Memory": "16 GB", + "Disk": "512 GB SSD", + "IP": "127.0.0.1", + "Health Score": "89%", + "Last Diagnostic": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + } + + # --- Create PDF report --- + pdf = FPDF() + pdf.add_page() + pdf.set_auto_page_break(auto=True, margin=15) + + # Title + pdf.set_font("Helvetica", "B", 18) + pdf.cell(0, 10, "Adaptive AI NIDS - System Report", ln=True, align="C") + pdf.ln(10) + + # Subtitle + pdf.set_font("Helvetica", "", 12) + pdf.cell(0, 10, f"Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True) + pdf.ln(8) + + # Section: System Status + pdf.set_font("Helvetica", "B", 14) + pdf.cell(0, 10, "System Information", ln=True) + pdf.set_font("Helvetica", "", 12) + pdf.ln(5) + + for key, value in system_status.items(): + pdf.cell(0, 8, f"{key}: {value}", ln=True) + + pdf.ln(10) + pdf.set_font("Helvetica", "B", 14) + pdf.cell(0, 10, "Attack Summary (Last 24h)", ln=True) + pdf.set_font("Helvetica", "", 12) + pdf.ln(5) + + pdf.cell(0, 8, "Total Attacks Detected: 3471", ln=True) + pdf.cell(0, 8, "High Risk: 512", ln=True) + pdf.cell(0, 8, "Medium Risk: 948", ln=True) + pdf.cell(0, 8, "Low Risk: 2011", ln=True) + + pdf.ln(10) + pdf.set_font("Helvetica", "I", 10) + pdf.cell(0, 8, "This report is automatically generated by Adaptive AI NIDS.", ln=True, align="C") + + # Save to memory + buffer = io.BytesIO() + pdf.output(buffer) + buffer.seek(0) + + filename = f"System_Report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf" + return send_file(buffer, as_attachment=True, download_name=filename, mimetype="application/pdf") + + except Exception as e: + return jsonify({"error": str(e)}), 500 + + +@system_bp.route("/system/processes") +def system_processes(): + try: + processes = [] + for proc in psutil.process_iter(['name', 'cpu_percent', 'memory_percent', 'status']): + info = proc.info + processes.append({ + "name": info.get("name", "Unknown"), + "cpu": round(info.get("cpu_percent", 0), 2), + "mem": round(info.get("memory_percent", 0), 2), + "status": info.get("status", "N/A"), + }) + # ✅ Sort by CPU usage and keep top 6 + top_processes = sorted(processes, key=lambda p: p["cpu"], reverse=True)[:6] + return jsonify(top_processes) + except Exception as e: + return jsonify({"error": str(e)}), 500 + + + +@system_bp.route("/system/connections") +def system_connections(): + try: + conns = [] + for c in psutil.net_connections(kind='inet'): + if c.laddr: + conns.append({ + "ip": c.laddr.ip, + "port": c.laddr.port, + "proto": "TCP" if c.type == socket.SOCK_STREAM else "UDP", + "state": c.status, + }) + # ✅ Only top 6 most recent/active connections + top_conns = conns[:6] + return jsonify(top_conns) + except Exception as e: + return jsonify({"error": str(e)}), 500 diff --git a/backend/routes/traffic_routes.py b/backend/routes/traffic_routes.py new file mode 100644 index 0000000000000000000000000000000000000000..e8424b56506988a213a2287cf8e9a8cb2db3e750 --- /dev/null +++ b/backend/routes/traffic_routes.py @@ -0,0 +1,49 @@ +# traffic_routes.py +from flask import Blueprint, jsonify +from utils.logger import get_recent_events, summarize_counts +from flow_builder import build_flows + +traffic_bp = Blueprint("traffic_bp", __name__) + +@traffic_bp.route("traffic/flows") +def flows(): + """Return aggregated flows from recent network events.""" + events = get_recent_events(2000) + flows = build_flows(events) + return jsonify({"flows": flows}) + + +@traffic_bp.route("traffic/protocols") +def protocols(): + """Return protocol distribution.""" + events = get_recent_events(2000) + counts = {"TCP": 0, "UDP": 0, "Other": 0} + + for e in events: + proto = e.get("proto", "").upper() + if proto == "TCP": + counts["TCP"] += 1 + elif proto == "UDP": + counts["UDP"] += 1 + else: + counts["Other"] += 1 + + return jsonify(counts) + + +@traffic_bp.route("traffic/bandwidth") +def bandwidth(): + """ + Returns packet count per second for the last ~30 records. + Used for bandwidth line chart. + """ + events = get_recent_events(200) + timeline = {} + + for e in events: + t = e.get("time") + timeline[t] = timeline.get(t, 0) + 1 + + graph = [{"time": k, "value": v} for k, v in timeline.items()] + + return jsonify(graph) diff --git a/backend/sample/bcc_sample.csv b/backend/sample/bcc_sample.csv new file mode 100644 index 0000000000000000000000000000000000000000..ecc0757ad6d31ec53b3f39013f93185f53a22e61 --- /dev/null +++ b/backend/sample/bcc_sample.csv @@ -0,0 +1,2 @@ +proto,src_port,dst_port,flow_duration,total_fwd_pkts,total_bwd_pkts,flags_numeric,payload_len,header_len,rate,iat,syn,ack,rst,fin +6,12345,443,100000,20,5,2,5000,800,50,20000,1,1,0,0 \ No newline at end of file diff --git a/backend/sample/cicids_sample.csv b/backend/sample/cicids_sample.csv new file mode 100644 index 0000000000000000000000000000000000000000..920f3162f9fa28be00bf30cae4da06d7ef17f09e --- /dev/null +++ b/backend/sample/cicids_sample.csv @@ -0,0 +1,2 @@ +Protocol,Dst Port,Flow Duration,Tot Fwd Pkts,Tot Bwd Pkts,TotLen Fwd Pkts,TotLen Bwd Pkts,Fwd Pkt Len Mean,Bwd Pkt Len Mean,Flow IAT Mean,Fwd PSH Flags,Fwd URG Flags,Fwd IAT Mean +6,443,120000,12,2,4000,1500,350,700,60000,1,0,30000 diff --git a/backend/socket_manager.py b/backend/socket_manager.py new file mode 100644 index 0000000000000000000000000000000000000000..8e92a2b90755d1bb5c5a75d6b315e5a75816cc1b --- /dev/null +++ b/backend/socket_manager.py @@ -0,0 +1,80 @@ +# socket_manager.py (Optimized) +# - Non-blocking emit queue with background worker +# - Rate-limited batching for frequent events +# - Backwards-compatible init_socketio & emit_new_event API + +import threading +import time +import queue + +_emit_q = queue.Queue(maxsize=2000) +_socketio = None +_emit_lock = threading.Lock() +_worker_thr = None +_stop_worker = threading.Event() + +# batch/rate config +_BATCH_INTERVAL = 0.5 # seconds between worker sends +_BATCH_MAX = 10 # max events to bundle per emit + + +def init_socketio(socketio): + """Initialize global socketio and start background emit worker.""" + global _socketio, _worker_thr + _socketio = socketio + print("✅ SocketIO initialized (thread-safe)") + if _worker_thr is None or not _worker_thr.is_alive(): + _worker_thr = threading.Thread(target=_emit_worker, daemon=True) + _worker_thr.start() + + +def _emit_worker(): + """Background worker: drains _emit_q and emits aggregated payloads at intervals.""" + last_send = 0.0 + buffer = [] + while not _stop_worker.is_set(): + try: + evt = _emit_q.get(timeout=_BATCH_INTERVAL) + buffer.append(evt) + except Exception: + # timeout, flush if buffer exists + pass + + now = time.time() + if buffer and (now - last_send >= _BATCH_INTERVAL or len(buffer) >= _BATCH_MAX): + payload = {"count": len(buffer), "items": buffer[:_BATCH_MAX]} + try: + if _socketio: + # emit in background so worker isn't blocked on network + _socketio.start_background_task(lambda: _socketio.emit("new_event", payload, namespace="/")) + except Exception as e: + print("⚠️ emit worker error:", e) + buffer.clear() + last_send = now + + # final flush on shutdown + if buffer and _socketio: + try: + _socketio.start_background_task(lambda: _socketio.emit("new_event", {"count": len(buffer), "items": buffer}, namespace="/")) + except Exception: + pass + + +def emit_new_event(evt): + """Enqueue event for background emit. Non-blocking. + + Compatible with previous API: callers can pass full event dicts. + """ + try: + _emit_q.put_nowait(evt) + except queue.Full: + # drop silently (prefer availability over backlog) + return + + +def shutdown_socket_manager(timeout=2): + """Stop background worker gracefully.""" + _stop_worker.set() + if _worker_thr and _worker_thr.is_alive(): + _worker_thr.join(timeout=timeout) + diff --git a/backend/uploads/bcc_sample.csv b/backend/uploads/bcc_sample.csv new file mode 100644 index 0000000000000000000000000000000000000000..ecc0757ad6d31ec53b3f39013f93185f53a22e61 --- /dev/null +++ b/backend/uploads/bcc_sample.csv @@ -0,0 +1,2 @@ +proto,src_port,dst_port,flow_duration,total_fwd_pkts,total_bwd_pkts,flags_numeric,payload_len,header_len,rate,iat,syn,ack,rst,fin +6,12345,443,100000,20,5,2,5000,800,50,20000,1,1,0,0 \ No newline at end of file diff --git a/backend/uploads/cicids_sample.csv b/backend/uploads/cicids_sample.csv new file mode 100644 index 0000000000000000000000000000000000000000..1b3f5a53e98c4141597dd570ab7a6d9eca4e5a77 --- /dev/null +++ b/backend/uploads/cicids_sample.csv @@ -0,0 +1,2 @@ +Protocol,Dst Port,Flow Duration,Tot Fwd Pkts,Tot Bwd Pkts,TotLen Fwd Pkts,TotLen Bwd Pkts,Fwd Pkt Len Mean,Bwd Pkt Len Mean,Flow IAT Mean,Fwd PSH Flags,Fwd URG Flags,Fwd IAT Mean + diff --git a/backend/uploads/cicids_sample_1.csv b/backend/uploads/cicids_sample_1.csv new file mode 100644 index 0000000000000000000000000000000000000000..920f3162f9fa28be00bf30cae4da06d7ef17f09e --- /dev/null +++ b/backend/uploads/cicids_sample_1.csv @@ -0,0 +1,2 @@ +Protocol,Dst Port,Flow Duration,Tot Fwd Pkts,Tot Bwd Pkts,TotLen Fwd Pkts,TotLen Bwd Pkts,Fwd Pkt Len Mean,Bwd Pkt Len Mean,Flow IAT Mean,Fwd PSH Flags,Fwd URG Flags,Fwd IAT Mean +6,443,120000,12,2,4000,1500,350,700,60000,1,0,30000 diff --git a/backend/uploads/iris.csv b/backend/uploads/iris.csv new file mode 100644 index 0000000000000000000000000000000000000000..b7f746072794309a9a971949562a050e7366ceb1 --- /dev/null +++ b/backend/uploads/iris.csv @@ -0,0 +1,151 @@ +150,4,setosa,versicolor,virginica +5.1,3.5,1.4,0.2,0 +4.9,3.0,1.4,0.2,0 +4.7,3.2,1.3,0.2,0 +4.6,3.1,1.5,0.2,0 +5.0,3.6,1.4,0.2,0 +5.4,3.9,1.7,0.4,0 +4.6,3.4,1.4,0.3,0 +5.0,3.4,1.5,0.2,0 +4.4,2.9,1.4,0.2,0 +4.9,3.1,1.5,0.1,0 +5.4,3.7,1.5,0.2,0 +4.8,3.4,1.6,0.2,0 +4.8,3.0,1.4,0.1,0 +4.3,3.0,1.1,0.1,0 +5.8,4.0,1.2,0.2,0 +5.7,4.4,1.5,0.4,0 +5.4,3.9,1.3,0.4,0 +5.1,3.5,1.4,0.3,0 +5.7,3.8,1.7,0.3,0 +5.1,3.8,1.5,0.3,0 +5.4,3.4,1.7,0.2,0 +5.1,3.7,1.5,0.4,0 +4.6,3.6,1.0,0.2,0 +5.1,3.3,1.7,0.5,0 +4.8,3.4,1.9,0.2,0 +5.0,3.0,1.6,0.2,0 +5.0,3.4,1.6,0.4,0 +5.2,3.5,1.5,0.2,0 +5.2,3.4,1.4,0.2,0 +4.7,3.2,1.6,0.2,0 +4.8,3.1,1.6,0.2,0 +5.4,3.4,1.5,0.4,0 +5.2,4.1,1.5,0.1,0 +5.5,4.2,1.4,0.2,0 +4.9,3.1,1.5,0.2,0 +5.0,3.2,1.2,0.2,0 +5.5,3.5,1.3,0.2,0 +4.9,3.6,1.4,0.1,0 +4.4,3.0,1.3,0.2,0 +5.1,3.4,1.5,0.2,0 +5.0,3.5,1.3,0.3,0 +4.5,2.3,1.3,0.3,0 +4.4,3.2,1.3,0.2,0 +5.0,3.5,1.6,0.6,0 +5.1,3.8,1.9,0.4,0 +4.8,3.0,1.4,0.3,0 +5.1,3.8,1.6,0.2,0 +4.6,3.2,1.4,0.2,0 +5.3,3.7,1.5,0.2,0 +5.0,3.3,1.4,0.2,0 +7.0,3.2,4.7,1.4,1 +6.4,3.2,4.5,1.5,1 +6.9,3.1,4.9,1.5,1 +5.5,2.3,4.0,1.3,1 +6.5,2.8,4.6,1.5,1 +5.7,2.8,4.5,1.3,1 +6.3,3.3,4.7,1.6,1 +4.9,2.4,3.3,1.0,1 +6.6,2.9,4.6,1.3,1 +5.2,2.7,3.9,1.4,1 +5.0,2.0,3.5,1.0,1 +5.9,3.0,4.2,1.5,1 +6.0,2.2,4.0,1.0,1 +6.1,2.9,4.7,1.4,1 +5.6,2.9,3.6,1.3,1 +6.7,3.1,4.4,1.4,1 +5.6,3.0,4.5,1.5,1 +5.8,2.7,4.1,1.0,1 +6.2,2.2,4.5,1.5,1 +5.6,2.5,3.9,1.1,1 +5.9,3.2,4.8,1.8,1 +6.1,2.8,4.0,1.3,1 +6.3,2.5,4.9,1.5,1 +6.1,2.8,4.7,1.2,1 +6.4,2.9,4.3,1.3,1 +6.6,3.0,4.4,1.4,1 +6.8,2.8,4.8,1.4,1 +6.7,3.0,5.0,1.7,1 +6.0,2.9,4.5,1.5,1 +5.7,2.6,3.5,1.0,1 +5.5,2.4,3.8,1.1,1 +5.5,2.4,3.7,1.0,1 +5.8,2.7,3.9,1.2,1 +6.0,2.7,5.1,1.6,1 +5.4,3.0,4.5,1.5,1 +6.0,3.4,4.5,1.6,1 +6.7,3.1,4.7,1.5,1 +6.3,2.3,4.4,1.3,1 +5.6,3.0,4.1,1.3,1 +5.5,2.5,4.0,1.3,1 +5.5,2.6,4.4,1.2,1 +6.1,3.0,4.6,1.4,1 +5.8,2.6,4.0,1.2,1 +5.0,2.3,3.3,1.0,1 +5.6,2.7,4.2,1.3,1 +5.7,3.0,4.2,1.2,1 +5.7,2.9,4.2,1.3,1 +6.2,2.9,4.3,1.3,1 +5.1,2.5,3.0,1.1,1 +5.7,2.8,4.1,1.3,1 +6.3,3.3,6.0,2.5,2 +5.8,2.7,5.1,1.9,2 +7.1,3.0,5.9,2.1,2 +6.3,2.9,5.6,1.8,2 +6.5,3.0,5.8,2.2,2 +7.6,3.0,6.6,2.1,2 +4.9,2.5,4.5,1.7,2 +7.3,2.9,6.3,1.8,2 +6.7,2.5,5.8,1.8,2 +7.2,3.6,6.1,2.5,2 +6.5,3.2,5.1,2.0,2 +6.4,2.7,5.3,1.9,2 +6.8,3.0,5.5,2.1,2 +5.7,2.5,5.0,2.0,2 +5.8,2.8,5.1,2.4,2 +6.4,3.2,5.3,2.3,2 +6.5,3.0,5.5,1.8,2 +7.7,3.8,6.7,2.2,2 +7.7,2.6,6.9,2.3,2 +6.0,2.2,5.0,1.5,2 +6.9,3.2,5.7,2.3,2 +5.6,2.8,4.9,2.0,2 +7.7,2.8,6.7,2.0,2 +6.3,2.7,4.9,1.8,2 +6.7,3.3,5.7,2.1,2 +7.2,3.2,6.0,1.8,2 +6.2,2.8,4.8,1.8,2 +6.1,3.0,4.9,1.8,2 +6.4,2.8,5.6,2.1,2 +7.2,3.0,5.8,1.6,2 +7.4,2.8,6.1,1.9,2 +7.9,3.8,6.4,2.0,2 +6.4,2.8,5.6,2.2,2 +6.3,2.8,5.1,1.5,2 +6.1,2.6,5.6,1.4,2 +7.7,3.0,6.1,2.3,2 +6.3,3.4,5.6,2.4,2 +6.4,3.1,5.5,1.8,2 +6.0,3.0,4.8,1.8,2 +6.9,3.1,5.4,2.1,2 +6.7,3.1,5.6,2.4,2 +6.9,3.1,5.1,2.3,2 +5.8,2.7,5.1,1.9,2 +6.8,3.2,5.9,2.3,2 +6.7,3.3,5.7,2.5,2 +6.7,3.0,5.2,2.3,2 +6.3,2.5,5.0,1.9,2 +6.5,3.0,5.2,2.0,2 +6.2,3.4,5.4,2.3,2 +5.9,3.0,5.1,1.8,2 diff --git a/backend/utils/ai_engine.py b/backend/utils/ai_engine.py new file mode 100644 index 0000000000000000000000000000000000000000..43f77d82c5712477ffa73aa8458a8f55ea63690f --- /dev/null +++ b/backend/utils/ai_engine.py @@ -0,0 +1,164 @@ +# utils/ai_engine.py +# ----------------------------------------- +# Lightweight "AI" engine using rules + templates +# No heavy ML model – safe for your laptop 🙂 + +from collections import Counter +from datetime import datetime + + +def _normalize_label(label: str) -> str: + return str(label or "Unknown").strip().upper() + + +# 1️⃣ Explain a single threat/event +def explain_threat(event: dict) -> str: + """ + Takes a single event dict (from logger / recent()) + and returns a human-readable explanation. + """ + + label = _normalize_label(event.get("prediction")) + risk_level = str(event.get("risk_level", "Low")).title() + src_ip = event.get("src_ip") or event.get("src") or "Unknown source" + dst_ip = event.get("dst_ip") or event.get("dst") or "Unknown destination" + proto = event.get("proto", "Unknown") + sport = event.get("sport") or event.get("src_port") or "?" + dport = event.get("dport") or event.get("dst_port") or "?" + + # Simple knowledge base + explanations = { + "VPN": ( + "Traffic from {src} to {dst} over {proto} looks like VPN usage. " + "VPN tunnels encrypt traffic and can hide the real origin of an attacker. " + "Review if this VPN endpoint is expected for this host." + ), + "TOR": ( + "Traffic appears to be routed through the Tor anonymity network. " + "Tor is commonly used to hide attacker identity. " + "Investigate the host at {src} and check if Tor usage is allowed." + ), + "I2P": ( + "Detected I2P (Invisible Internet Project) style traffic. " + "I2P is an anonymity network similar to Tor and can be abused for C2 channels." + ), + "FREENET": ( + "Traffic resembles Freenet P2P anonymity network. " + "Such networks can be used to exchange illegal or malicious content." + ), + "ZERONET": ( + "ZeroNet-like traffic detected. ZeroNet hosts sites over a P2P network. " + "This may bypass normal web filtering and logging." + ), + # CICIDS-style examples – extend as you like + "DOS HULK": ( + "High-rate HTTP traffic typical of DoS-Hulk attack was detected. " + "This can exhaust web server resources and cause service disruption." + ), + "DOS SLOWLORIS": ( + "Slowloris-style DoS traffic detected. It keeps many HTTP connections open " + "to slowly exhaust server connection limits." + ), + "BOT": ( + "Behavior suggests the host may be part of a botnet. " + "Correlate with outbound connections and run malware scans on {src}." + ), + "BENIGN": ( + "This flow is classified as BENIGN. No immediate malicious pattern detected, " + "but you should still monitor for anomalies over time." + ), + } + + # Pick best match (exact or substring) + text = None + if label in explanations: + text = explanations[label] + else: + for k, v in explanations.items(): + if k in label: + text = v + break + + if text is None: + text = ( + "The traffic is classified as '{label}' with a risk level of {risk}. " + "Review source {src} → destination {dst}, protocol {proto}, " + "and ports {sport} → {dport} for suspicious patterns." + ) + + return text.format( + label=label, + risk=risk_level, + src=src_ip, + dst=dst_ip, + proto=proto, + sport=sport, + dport=dport, + ) + + +# 2️⃣ Summarize multiple events (for report) +def summarize_events(events, model: str = "bcc") -> str: + """ + Takes a list of events and returns a high-level English summary. + """ + + if not events: + return "No recent events available for summary." + + labels = [_normalize_label(e.get("prediction")) for e in events] + counts = Counter(labels) + total = len(events) + + high_risk_keywords = [ + "DDOS", "DOS", "BRUTE", "SQL", "BOT", "INFILTRATION", "HULK", + "SLOWLORIS", "SLOWHTTPTEST" + ] + high_risk = sum( + c for lbl, c in counts.items() + if any(k in lbl for k in high_risk_keywords) + ) + + tor_like = sum( + counts.get(lbl, 0) for lbl in ["TOR", "I2P", "ZERONET", "FREENET", "VPN"] + ) + + ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + # Build readable summary + parts = [ + f"AI Summary generated at {ts} for model '{model.upper()}'.", + f"Total analysed events: {total}.", + ] + + if high_risk: + parts.append( + f"High-risk attacks detected: {high_risk} events " + f"({', '.join(k for k in counts.keys() if any(x in k for x in high_risk_keywords))})." + ) + else: + parts.append("No high-risk attack pattern strongly detected in this window.") + + if tor_like: + parts.append( + f"Anonymity or tunneling traffic (VPN/TOR/I2P/etc.) observed in {tor_like} events. " + "Verify if this usage is expected and authorized." + ) + + # top 3 labels + top3 = counts.most_common(3) + label_str = ", ".join(f"{lbl}: {cnt}" for lbl, cnt in top3) + parts.append(f"Top traffic classes: {label_str}.") + + if model == "bcc": + parts.append( + "BCC model focuses on live packet patterns; consider correlating with host logs " + "for deeper forensic analysis." + ) + else: + parts.append( + "CICIDS model analyses flow-level statistics; consider exporting flows for " + "offline investigation if anomalies increase." + ) + + return " ".join(parts) diff --git a/backend/utils/geo_lookup.py b/backend/utils/geo_lookup.py new file mode 100644 index 0000000000000000000000000000000000000000..ccd4d34252ac3fe2d775eb6828da157153c934bd --- /dev/null +++ b/backend/utils/geo_lookup.py @@ -0,0 +1,133 @@ +# utils/geo_lookup.py +# ========================================== +# 🌍 GEO LOOKUP UTILITY — Robust version +# - Uses ipwho.is +# - Validates inputs +# - Caches results +# - Graceful fallback for bad/ private IPs +# ========================================== + +import requests +from functools import lru_cache +import re +import time + +# Public API (no API key) +GEO_API = "https://ipwho.is/{ip}" + +# Regex for private/reserved IPv4 blocks + simple IPv4/IPv6 check +_IPV4_RE = re.compile(r"^(?:\d{1,3}\.){3}\d{1,3}$") +_IPV6_RE = re.compile(r"^[0-9a-fA-F:]+$") + +PRIVATE_IP_RANGES = [ + re.compile(r"^127\."), # localhost + re.compile(r"^10\."), # private + re.compile(r"^192\.168\."), # private + re.compile(r"^172\.(1[6-9]|2[0-9]|3[0-1])\."), # private block + re.compile(r"^0\."), # invalid + re.compile(r"^255\."), # broadcast/reserved +] + +# Cache size tuned to common usage (increase if you have many distinct IPs) +@lru_cache(maxsize=2000) +def get_geo_info(ip: str) -> dict: + """Return geolocation info for an IP address (string-safe, cached, fallback).""" + # Normalize + try: + ip_raw = ip + if ip is None: + return _default_geo(ip, "Empty IP") + ip = str(ip).strip() + except Exception: + return _default_geo(ip, "Invalid IP") + + # Quick checks + if ip == "" or ip.lower() in ("unknown", "n/a", "na", "local", "localhost"): + return _default_geo(ip, "Unknown") + + # If it's clearly not an IPv4/IPv6 string, avoid calling external API + if not (_IPV4_RE.match(ip) or _IPV6_RE.match(ip)): + return _default_geo(ip, "Not an IP") + + # Private/reserved check + if any(r.match(ip) for r in PRIVATE_IP_RANGES): + return { + "ip": ip, + "country": "Local", + "city": "Private Network", + "lat": 0.0, + "lon": 0.0, + } + + # Query remote API (with timeout + basic retry) + try: + # simple single attempt with timeout; if you need reliability add a tiny backoff/retry + res = requests.get(GEO_API.format(ip=ip), timeout=4) + if res.status_code == 200: + data = res.json() + # ipwho.is returns {"success": false, "message": "..."} for invalid + if data.get("success", True) is False: + return _default_geo(ip, data.get("message", "Invalid IP")) + return { + "ip": ip, + "country": data.get("country", "Unknown"), + "city": data.get("city", "Unknown"), + "lat": float(data.get("latitude") or 0.0), + "lon": float(data.get("longitude") or 0.0), + } + # non-200 -> fallback + print(f"⚠️ Geo lookup failed for {ip} (status {res.status_code})") + except Exception as e: + # network errors, DNS issues, etc. + print(f"⚠️ Geo lookup error for {ip}: {e}") + + return _default_geo(ip, "Unknown") + + +def _default_geo(ip: str, reason="Unknown"): + """Return default location info when lookup fails.""" + return { + "ip": ip, + "country": reason, + "city": "Unknown", + "lat": 0.0, + "lon": 0.0, + } + + +def enrich_event_with_geo(evt: dict) -> dict: + """ + Given an event dict that contains 'src_ip' and 'dst_ip' (or similar keys), + attach src/dst city, country, lat, lon fields. + This function is safe to call synchronously, but consider async enrichment + when running on a hot packet-processing loop (see optional snippet below). + """ + try: + # Accept multiple possible keys (compatibility) + src_ip = evt.get("src_ip") or evt.get("src") or evt.get("srcIP") or "" + dst_ip = evt.get("dst_ip") or evt.get("dst") or evt.get("dstIP") or "" + + # Normalize to string before calling get_geo_info + src_ip = str(src_ip).strip() if src_ip is not None else "" + dst_ip = str(dst_ip).strip() if dst_ip is not None else "" + + # Get geo info (cached) + src_info = get_geo_info(src_ip) + dst_info = get_geo_info(dst_ip) + + evt.update({ + "src_country": src_info["country"], + "dst_country": dst_info["country"], + "src_city": src_info["city"], + "dst_city": dst_info["city"], + "src_lat": src_info["lat"], + "src_lon": src_info["lon"], + "dst_lat": dst_info["lat"], + "dst_lon": dst_info["lon"], + }) + except Exception as e: + # Keep it quiet but informative + print(f"⚠️ Geo enrichment failed for event: {e}") + + return evt + diff --git a/backend/utils/logger.py b/backend/utils/logger.py new file mode 100644 index 0000000000000000000000000000000000000000..b726866ee90cd9bcaecc05a5847cef48db11f617 --- /dev/null +++ b/backend/utils/logger.py @@ -0,0 +1,273 @@ +# logger.py (Model-separated, non-blocking logger, per-model CSVs) +# ------------------------------------------------------------- +import os +import csv +import threading +import time +from datetime import datetime +import numpy as np + +LOG_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "logs")) +os.makedirs(LOG_DIR, exist_ok=True) + +BCC_LOG_FILE = os.path.join(LOG_DIR, "bcc_logs.csv") +CICIDS_LOG_FILE = os.path.join(LOG_DIR, "cicids_logs.csv") + +_MAX_RECENT = 500 +_FLUSH_INTERVAL = 2.0 +_FLUSH_BATCH = 50 + +_headers = [ + "time", "src_ip", "sport", "dst_ip", "dport", "proto", + "prediction", "risk_level", "risk_score", + "src_country", "src_city", "src_lat", "src_lon", + "dst_country", "dst_city", "dst_lat", "dst_lon" +] + +# In-memory per-model buffers & stats +_model_events = { + "bcc": [], # list of dicts + "cicids": [] +} + +_model_stats = { + "bcc": {}, + "cicids": {} +} + +# active model (default) +_active_model_lock = threading.Lock() +_active_model = "bcc" + +# writer buffers and locks +_write_buffer = [] # list of dicts, each item must include "model" key +_buffer_lock = threading.Lock() +_events_lock = threading.Lock() + +_stop_writer = threading.Event() + +# ------------------------- +# Helpers: file name for model +# ------------------------- +def _file_for_model(model): + if model == "cicids": + return CICIDS_LOG_FILE + return BCC_LOG_FILE + +# ------------------------- +# Full overwrite for a model CSV +# ------------------------- +def _flush_full_overwrite_model(model): + """Rewrite the entire CSV for a specific model from its in-memory buffer.""" + fname = _file_for_model(model) + try: + with _events_lock: + rows = list(_model_events.get(model, [])) + with open(fname, "w", newline="", encoding="utf-8") as f: + writer = csv.DictWriter(f, fieldnames=_headers) + writer.writeheader() + for row in rows: + writer.writerow({k: row.get(k, "") for k in _headers}) + # optional debug print + # print(f"[logger] {model} CSV fully rewritten: {len(rows)} rows -> {fname}") + except Exception as e: + print("[logger] Full overwrite failed:", e) + +# ------------------------- +# Flush small batches to disk (append) +# ------------------------- +def _flush_to_disk(): + global _write_buffer + with _buffer_lock: + if not _write_buffer: + return + batch = _write_buffer[:_FLUSH_BATCH] + _write_buffer = _write_buffer[len(batch):] + + # group by model for efficient writes + groups = {} + for row in batch: + m = row.get("model", "bcc") + groups.setdefault(m, []).append(row) + + for model, rows in groups.items(): + fname = _file_for_model(model) + try: + file_empty = not os.path.exists(fname) or os.stat(fname).st_size == 0 + with open(fname, "a", newline="", encoding="utf-8") as f: + writer = csv.DictWriter(f, fieldnames=_headers) + if file_empty: + writer.writeheader() + for r in rows: + # write only header keys (ignore extra) + writer.writerow({k: r.get(k, "") for k in _headers}) + except Exception as e: + print("[logger] Append write error for", model, ":", e) + +# ------------------------- +# Background writer thread +# ------------------------- +def _writer_thread(): + while not _stop_writer.is_set(): + time.sleep(_FLUSH_INTERVAL) + _flush_to_disk() + # flush remaining on shutdown + _flush_to_disk() + +_writer_thr = threading.Thread(target=_writer_thread, daemon=True) +_writer_thr.start() + +# ------------------------- +# Load existing CSVs into _model_events on startup (keep last _MAX_RECENT) +# ------------------------- +def _load_recent_model(model): + fname = _file_for_model(model) + if not os.path.exists(fname): + return [] + try: + with open(fname, "r", encoding="utf-8") as f: + reader = list(csv.DictReader(f)) + return reader[-_MAX_RECENT:] + except Exception: + return [] + +def _load_all_recent(): + global _model_events + with _events_lock: + _model_events["bcc"] = _load_recent_model("bcc") + _model_events["cicids"] = _load_recent_model("cicids") + +_load_all_recent() + +# =============================== +# Public API: push_event +# =============================== +def push_event(evt): + """ + evt: dict containing event fields expected (prediction, src_ip, dst_ip, etc.) + Uses current active model to store event. + Also enqueues to write buffer for background flush. + """ + global _write_buffer + + # attach model at time of push + with _active_model_lock: + model = _active_model + + e = dict(evt) + e.setdefault("time", datetime.now().strftime("%H:%M:%S")) + e.setdefault("risk_level", "Low") + e.setdefault("risk_score", 0) + + # add to in-memory buffer for model + with _events_lock: + _model_events.setdefault(model, []) + _model_events[model].append(e) + if len(_model_events[model]) > _MAX_RECENT: + _model_events[model] = _model_events[model][-_MAX_RECENT:] + + # update stats + pred = str(e.get("prediction", "Unknown")) + _model_stats.setdefault(model, {}) + _model_stats[model][pred] = _model_stats[model].get(pred, 0) + 1 + + # add to write buffer with model tag for background writer + item = dict(e) + item["model"] = model + with _buffer_lock: + _write_buffer.append(item) + # if buffer grows big, flush asynchronously + if len(_write_buffer) > (_FLUSH_BATCH * 4): + threading.Thread(target=_flush_to_disk, daemon=True).start() + +# =============================== +# Public API: get recent & stats +# =============================== +def get_recent_events(model="bcc", n=None): + with _events_lock: + data = list(_model_events.get(model, [])) + if n: + return data[-n:] + return data + +def get_model_stats(model="bcc"): + with _events_lock: + # return a shallow copy to avoid external mutation + return dict(_model_stats.get(model, {})) + +# ------------------------- +# Convenience: summary across active model (legacy) +# ------------------------- +def summarize_counts(): + with _active_model_lock: + model = _active_model + return get_model_stats(model) + +# =============================== +# Model selection API +# =============================== +def set_active_model(model): + if model not in ("bcc", "cicids"): + raise ValueError("invalid model") + with _active_model_lock: + global _active_model + _active_model = model + # no immediate clearing — in-memory buffers persist per model + return _active_model + +def get_active_model(): + with _active_model_lock: + return _active_model + +# =============================== +# CLEAR / DELETE (model-wise) +# =============================== +def clear_last_events(model="bcc", n=99999): + with _events_lock: + ev = _model_events.get(model, []) + if n >= len(ev): + _model_events[model] = [] + else: + _model_events[model] = ev[:-n] + # reset stats for this model + _model_stats[model] = {} + # rewrite model CSV fully + _flush_full_overwrite_model(model) + return True + +def delete_by_index(model="bcc", idx=0): + with _events_lock: + ev = _model_events.get(model, []) + if 0 <= idx < len(ev): + ev.pop(idx) + _model_events[model] = ev + # recompute stats (simple recompute) + _model_stats[model] = {} + for e in ev: + pred = str(e.get("prediction", "Unknown")) + _model_stats[model][pred] = _model_stats[model].get(pred, 0) + 1 + _flush_full_overwrite_model(model) + return True + return False + +def delete_by_prediction(model="bcc", pred=None): + if pred is None: + return False + with _events_lock: + ev = _model_events.get(model, []) + _model_events[model] = [e for e in ev if e.get("prediction") != pred] + # recompute stats + _model_stats[model] = {} + for e in _model_events[model]: + p = str(e.get("prediction", "Unknown")) + _model_stats[model][p] = _model_stats[model].get(p, 0) + 1 + _flush_full_overwrite_model(model) + return True + +# =============================== +# Shutdown +# =============================== +def shutdown_logger(): + _stop_writer.set() + _writer_thr.join(timeout=3) + diff --git a/backend/utils/model_selector.py b/backend/utils/model_selector.py new file mode 100644 index 0000000000000000000000000000000000000000..b402b34614423c082748175e978ffe430e50c0c8 --- /dev/null +++ b/backend/utils/model_selector.py @@ -0,0 +1,116 @@ +import os +import joblib +import threading +import traceback + +# Global active model (default = bcc so your current flow remains unchanged) +ACTIVE_MODEL = "bcc" +_ACTIVE_LOCK = threading.Lock() + +# Cache loaded models to avoid repeated disk loads +_MODEL_CACHE = {} +ML_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "ml_models")) +print("[model_selector] ML_DIR =", ML_DIR) +try: + print("[model_selector] ML_DIR files:", os.listdir(ML_DIR)) +except Exception as e: + print("[model_selector] Could not list ML_DIR:", e) + + +def _try_load(path): + """Try to joblib.load(path). On failure return None but print full traceback.""" + if not os.path.exists(path): + print(f"[model_selector] SKIP (not found): {path}") + return None + try: + print(f"[model_selector] Attempting to load: {path}") + obj = joblib.load(path) + print(f"[model_selector] Successfully loaded: {os.path.basename(path)}") + return obj + except Exception as e: + print(f"[model_selector] FAILED to load {path}: {e}") + traceback.print_exc() + return None + +def load_model(model_key): + """Return a dict with keys depending on model. Caches result.""" + if model_key in _MODEL_CACHE: + return _MODEL_CACHE[model_key] + + if model_key == "bcc": + # original BCC artifact names (your working files) + model_path = os.path.join(ML_DIR, "realtime_model.pkl") + scaler_path = os.path.join(ML_DIR, "realtime_scaler.pkl") + encoder_path = os.path.join(ML_DIR, "realtime_encoder.pkl") + + model = _try_load(model_path) + scaler = _try_load(scaler_path) + encoder = _try_load(encoder_path) + + if model is None: + print(f"[model_selector] WARNING: bcc model not found at {model_path}") + _MODEL_CACHE["bcc"] = {"model": model, "scaler": scaler, "encoder": encoder} + return _MODEL_CACHE["bcc"] + + if model_key == "cicids": + # Prefer the RF pipeline you requested; try common names in preferred order + candidate_models = [ + "rf_pipeline.joblib", # preferred - your RF pipeline + "cicids_rf.joblib", + "rf_pipeline.pkl", + "cicids_model.joblib", + "lgb_pipeline.joblib", + "cicids_rf.pkl", + ] + # prefer 'training_artifacts' or 'cicids_artifacts' + candidate_artifacts = [ + "training_artifacts.joblib", + "training_artifacts.pkl", + "cicids_artifacts.joblib", + "cicids_artifacts.pkl", + "artifacts.joblib", + "artifacts.pkl" + ] + + model = None + artifacts = None + for fn in candidate_models: + p = os.path.join(ML_DIR, fn) + model = _try_load(p) + if model is not None: + print(f"[model_selector] Loaded cicids model from {p}") + break + + for fn in candidate_artifacts: + p = os.path.join(ML_DIR, fn) + artifacts = _try_load(p) + if artifacts is not None: + print(f"[model_selector] Loaded cicids artifacts from {p}") + break + + if model is None: + print("[model_selector] WARNING: No cicids model found in ml_models.") + if artifacts is None: + print("[model_selector] WARNING: No cicids artifacts found in ml_models.") + + # artifacts expected to include: 'scaler' and 'features' at minimum + _MODEL_CACHE["cicids"] = { + "model": model, + "artifacts": artifacts + } + return _MODEL_CACHE["cicids"] + + raise ValueError("Unknown model_key") + +def set_active_model(key: str): + global ACTIVE_MODEL + if key not in ("bcc", "cicids"): + raise ValueError("Active model must be 'bcc' or 'cicids'") + with _ACTIVE_LOCK: + ACTIVE_MODEL = key + print(f"[model_selector] ACTIVE_MODEL set to: {ACTIVE_MODEL}") + +def get_active_model(): + return ACTIVE_MODEL + + diff --git a/backend/utils/pcap_to_csv.py b/backend/utils/pcap_to_csv.py new file mode 100644 index 0000000000000000000000000000000000000000..b42021ad15c39e154cc1c0a880a24785a124246f --- /dev/null +++ b/backend/utils/pcap_to_csv.py @@ -0,0 +1,23 @@ +import pandas as pd +from scapy.all import rdpcap + +def convert_pcap_to_csv(input_pcap): + packets = rdpcap(input_pcap) + data = [] + + for pkt in packets: + try: + row = { + "src_port": pkt.sport if hasattr(pkt, "sport") else 0, + "dst_port": pkt.dport if hasattr(pkt, "dport") else 0, + "proto": pkt.proto if hasattr(pkt, "proto") else 0, + "payload_len": len(pkt.payload) + } + data.append(row) + except: + pass + + df = pd.DataFrame(data) + out_csv = input_pcap + ".csv" + df.to_csv(out_csv, index=False) + return out_csv diff --git a/backend/utils/risk_engine.py b/backend/utils/risk_engine.py new file mode 100644 index 0000000000000000000000000000000000000000..633322e2f5629ac6e45288a8850b8275db5fe2d8 --- /dev/null +++ b/backend/utils/risk_engine.py @@ -0,0 +1,77 @@ +# risk_engine.py (Optimized) +# - Accepts optional `recent_events` to avoid repeated disk/IO calls +# - Uses light-weight counters and caching for frequency checks +# - Returns (level, score) as before + +import random +import time +from utils.logger import get_recent_events + +# small in-memory cache for source counts to avoid repeated scans +_SRC_CACHE = { + "ts": 0, + "counts": {}, + "ttl": 2.0 # seconds +} + + +def _build_source_cache(recent_events): + counts = {} + for e in recent_events: + s = e.get("src_ip") + if s: + counts[s] = counts.get(s, 0) + 1 + return counts + + +def compute_risk_score(evt, recent_events=None): + """Compute adaptive risk score (0–100). + + If `recent_events` is provided, it is used directly. Otherwise `get_recent_events()` + is called once (limited inside the function). + """ + label = (evt.get("prediction") or "").upper() + src_ip = evt.get("src_ip") or "" + + base_map = { + "TOR": 90, + "I2P": 85, + "ZERONET": 70, + "VPN": 55, + "FREENET": 60, + "HTTP": 30, + "DNS": 25, + } + base = base_map.get(label, 35) + + # get recent events once if not provided + if recent_events is None: + recent_events = get_recent_events() + + # try cached counts for short TTL + now = time.time() + if now - _SRC_CACHE.get("ts", 0) > _SRC_CACHE.get("ttl", 2.0) or not _SRC_CACHE.get("counts"): + _SRC_CACHE["counts"] = _build_source_cache(recent_events) + _SRC_CACHE["ts"] = now + + freq = _SRC_CACHE["counts"].get(src_ip, 0) + + freq_boost = 0 + if freq >= 3: + freq_boost = 5 + if freq >= 6: + freq_boost = 15 + + noise = random.randint(-3, 3) + + score = min(100, max(0, base + freq_boost + noise)) + + if score >= 80: + level = "High" + elif score >= 50: + level = "Medium" + else: + level = "Low" + + return level, score + diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a547bf36d8d11a4f89c59c144f24795749086dd1 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000000000000000000000000000000000000..18bc70ebe277fbfe6e55e6f9a0ae7e2c3e4bdd83 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,16 @@ +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. diff --git a/frontend/components.json b/frontend/components.json new file mode 100644 index 0000000000000000000000000000000000000000..2d14f31ca9f026e568ff1c9e76abeef4a9251d3c --- /dev/null +++ b/frontend/components.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": false, + "tsx": false, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/index.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "registries": {} +} diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js new file mode 100644 index 0000000000000000000000000000000000000000..cee1e2c788d908e4a8ff796eb6edbe73ee73fffd --- /dev/null +++ b/frontend/eslint.config.js @@ -0,0 +1,29 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{js,jsx}'], + extends: [ + js.configs.recommended, + reactHooks.configs['recommended-latest'], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + parserOptions: { + ecmaVersion: 'latest', + ecmaFeatures: { jsx: true }, + sourceType: 'module', + }, + }, + rules: { + 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], + }, + }, +]) diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000000000000000000000000000000000000..a05cd5a5b0c8260b24934b37dc9f55b422a5f6e0 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,17 @@ + + + + + + + +NIDS Cyber Security + + +
+ + + \ No newline at end of file diff --git a/frontend/jsconfig.json b/frontend/jsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..cd326945a5dcc179c970154b1c6a28e13ea75a2b --- /dev/null +++ b/frontend/jsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": "./src", + "paths": { + "@/*": ["*"] + } + } +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..d1a33b800dd6acaf643b842cd18d84912b8ea969 --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,8099 @@ +{ + "name": "frontend", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.0.0", + "dependencies": { + "@radix-ui/react-accordion": "^1.2.12", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-separator": "^1.1.8", + "@radix-ui/react-slot": "^1.2.4", + "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", + "@react-three/drei": "^10.7.6", + "@react-three/fiber": "^9.4.0", + "axios": "^1.13.1", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "firebase": "^12.5.0", + "framer-motion": "^12.23.24", + "html2canvas": "^1.4.1", + "jspdf": "^3.0.3", + "leaflet": "^1.9.4", + "lodash": "^4.17.21", + "lucide-react": "^0.552.0", + "prop-types": "^15.8.1", + "react": "^19.1.1", + "react-circular-progressbar": "^2.2.0", + "react-dom": "^19.1.1", + "react-draggable": "^4.5.0", + "react-gauge-chart": "^0.5.1", + "react-hot-toast": "^2.6.0", + "react-is": "^19.2.0", + "react-leaflet": "^5.0.0", + "react-parallax-tilt": "^1.7.313", + "react-router-dom": "^7.9.5", + "react-simple-maps": "^3.0.0", + "recharts": "^3.3.0", + "tailwind-merge": "^3.4.0", + "tailwindcss-animate": "^1.0.7", + "three": "^0.181.1", + "xlsx": "^0.18.5" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/react": "^19.1.16", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.4", + "autoprefixer": "^10.4.21", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.22", + "globals": "^16.4.0", + "postcss": "^8.5.6", + "tailwindcss": "^3.4.18", + "vite": "^7.1.7" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@dimforge/rapier3d-compat": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz", + "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==", + "license": "Apache-2.0" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", + "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", + "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", + "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", + "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", + "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", + "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", + "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", + "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", + "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", + "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", + "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", + "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", + "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", + "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", + "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", + "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", + "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", + "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", + "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", + "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", + "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", + "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", + "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", + "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", + "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", + "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.0.tgz", + "integrity": "sha512-BIhe0sW91JGPiaF1mOuPy5v8NflqfjIcDNpC+LbW9f609WVRX1rArrhi6Z2ymvrAry9jw+5POTj4t2t62o8Bmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@firebase/ai": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-2.5.0.tgz", + "integrity": "sha512-OXv/jZLRjV9jTejWA4KOvW8gM1hNsLvQSCPwKhi2CEfe0Nap3rM6z+Ial0PGqXga0WgzhpypEvJOFvaAUFX3kg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/analytics": { + "version": "0.10.19", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.19.tgz", + "integrity": "sha512-3wU676fh60gaiVYQEEXsbGS4HbF2XsiBphyvvqDbtC1U4/dO4coshbYktcCHq+HFaGIK07iHOh4pME0hEq1fcg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.25.tgz", + "integrity": "sha512-fdzoaG0BEKbqksRDhmf4JoyZf16Wosrl0Y7tbZtJyVDOOwziE0vrFjmZuTdviL0yhak+Nco6rMsUUbkbD+qb6Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/analytics": "0.10.19", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.5.tgz", + "integrity": "sha512-zyNY77xJOGwcuB+xCxF8z8lSiHvD4ox7BCsqLEHEvgqQoRjxFZ0fkROR6NV5QyXmCqRLodMM8J5d2EStOocWIw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.11.0.tgz", + "integrity": "sha512-XAvALQayUMBJo58U/rxW02IhsesaxxfWVmVkauZvGEz3vOAjMEQnzFlyblqkc2iAaO82uJ2ZVyZv9XzPfxjJ6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.4.0.tgz", + "integrity": "sha512-UfK2Q8RJNjYM/8MFORltZRG9lJj11k0nW84rrffiKvcJxLf1jf6IEjCIkCamykHE73C6BwqhVfhIBs69GXQV0g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check": "0.11.0", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-compat": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.5.5.tgz", + "integrity": "sha512-lVG/nRnXaot0rQSZazmTNqy83ti9O3+kdwoaE0d5wahRIWNoDirbIMcGVjDDgdmf4IE6FYreWOMh0L3DV1475w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app": "0.14.5", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.11.1.tgz", + "integrity": "sha512-Mea0G/BwC1D0voSG+60Ylu3KZchXAFilXQ/hJXWCw3gebAu+RDINZA0dJMNeym7HFxBaBaByX8jSa7ys5+F2VA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.6.1.tgz", + "integrity": "sha512-I0o2ZiZMnMTOQfqT22ur+zcGDVSAfdNZBHo26/Tfi8EllfR1BO7aTVo2rt/ts8o/FWsK8pOALLeVBGhZt8w/vg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth": "1.11.1", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-types": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.0.tgz", + "integrity": "sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/data-connect": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.11.tgz", + "integrity": "sha512-G258eLzAD6im9Bsw+Qm1Z+P4x0PGNQ45yeUuuqe5M9B1rn0RJvvsQCRHXgE52Z+n9+WX1OJd/crcuunvOGc7Vw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/database": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.0.tgz", + "integrity": "sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.0.tgz", + "integrity": "sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/database": "1.1.0", + "@firebase/database-types": "1.0.16", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.16.tgz", + "integrity": "sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.13.0" + } + }, + "node_modules/@firebase/firestore": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.9.2.tgz", + "integrity": "sha512-iuA5+nVr/IV/Thm0Luoqf2mERUvK9g791FZpUJV1ZGXO6RL2/i/WFJUj5ZTVXy5pRjpWYO+ZzPcReNrlilmztA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "@firebase/webchannel-wrapper": "1.0.5", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.4.2.tgz", + "integrity": "sha512-cy7ov6SpFBx+PHwFdOOjbI7kH00uNKmIFurAn560WiPCZXy9EMnil1SOG7VF4hHZKdenC+AHtL4r3fNpirpm0w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/firestore": "4.9.2", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.13.1.tgz", + "integrity": "sha512-sUeWSb0rw5T+6wuV2o9XNmh9yHxjFI9zVGFnjFi+n7drTEWpl7ZTz1nROgGrSu472r+LAaj+2YaSicD4R8wfbw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.4.1.tgz", + "integrity": "sha512-AxxUBXKuPrWaVNQ8o1cG1GaCAtXT8a0eaTDfqgS5VsRYLAR0ALcfqDLwo/QyijZj1w8Qf8n3Qrfy/+Im245hOQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/functions": "0.13.1", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/installations": { + "version": "0.6.19", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.19.tgz", + "integrity": "sha512-nGDmiwKLI1lerhwfwSHvMR9RZuIH5/8E3kgUWnVRqqL7kGVSktjLTWEMva7oh5yxQ3zXfIlIwJwMcaM5bK5j8Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.19.tgz", + "integrity": "sha512-khfzIY3EI5LePePo7vT19/VEIH1E3iYsHknI/6ek9T8QCozAZshWT9CjlwOzZrKvTHMeNcbpo/VSOSIWDSjWdQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/logger": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.5.0.tgz", + "integrity": "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.12.23", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.23.tgz", + "integrity": "sha512-cfuzv47XxqW4HH/OcR5rM+AlQd1xL/VhuaeW/wzMW1LFrsFcTn0GND/hak1vkQc2th8UisBcrkVcQAnOnKwYxg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.23.tgz", + "integrity": "sha512-SN857v/kBUvlQ9X/UjAqBoQ2FEaL1ZozpnmL1ByTe57iXkmnVVFm9KqAsTfmf+OEwWI4kJJe9NObtN/w22lUgg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/messaging": "0.12.23", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/performance": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.9.tgz", + "integrity": "sha512-UzybENl1EdM2I1sjYm74xGt/0JzRnU/0VmfMAKo2LSpHJzaj77FCLZXmYQ4oOuE+Pxtt8Wy2BVJEENiZkaZAzQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.22.tgz", + "integrity": "sha512-xLKxaSAl/FVi10wDX/CHIYEUP13jXUjinL+UaNXT9ByIvxII5Ne5150mx6IgM8G6Q3V+sPiw9C8/kygkyHUVxg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/performance": "0.7.9", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/remote-config": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.7.0.tgz", + "integrity": "sha512-dX95X6WlW7QlgNd7aaGdjAIZUiQkgWgNS+aKNu4Wv92H1T8Ue/NDUjZHd9xb8fHxLXIHNZeco9/qbZzr500MjQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.20", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.20.tgz", + "integrity": "sha512-P/ULS9vU35EL9maG7xp66uljkZgcPMQOxLj3Zx2F289baTKSInE6+YIkgHEi1TwHoddC/AFePXPpshPlEFkbgg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/remote-config": "0.7.0", + "@firebase/remote-config-types": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.5.0.tgz", + "integrity": "sha512-vI3bqLoF14L/GchtgayMiFpZJF+Ao3uR8WCde0XpYNkSokDpAKca2DxvcfeZv7lZUqkUwQPL2wD83d3vQ4vvrg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/storage": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.14.0.tgz", + "integrity": "sha512-xWWbb15o6/pWEw8H01UQ1dC5U3rf8QTAzOChYyCpafV6Xki7KVp3Yaw2nSklUwHEziSWE9KoZJS7iYeyqWnYFA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.4.0.tgz", + "integrity": "sha512-vDzhgGczr1OfcOy285YAPur5pWDEvD67w4thyeCUh6Ys0izN9fNYtA1MJERmNBfqjqu0lg0FM5GLbw0Il21M+g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/storage": "0.14.0", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", + "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.5.tgz", + "integrity": "sha512-+uGNN7rkfn41HLO0vekTFhTxk61eKa8mTpRGLO0QSqlQdKvIoGAvLp3ppdVIWbTGYJWM6Kp0iN+PjMIOcnVqTw==", + "license": "Apache-2.0" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mediapipe/tasks-vision": { + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz", + "integrity": "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==", + "license": "Apache-2.0" + }, + "node_modules/@monogrid/gainmap-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.1.0.tgz", + "integrity": "sha512-Obb0/gEd/HReTlg8ttaYk+0m62gQJmCblMOjHSMHRrBP2zdfKMHLCRbh/6ex9fSUJMKdjjIEiohwkbGD3wj2Nw==", + "license": "MIT", + "dependencies": { + "promise-worker-transferable": "^1.0.4" + }, + "peerDependencies": { + "three": ">= 0.159.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", + "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.8.tgz", + "integrity": "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", + "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", + "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@react-leaflet/core": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz", + "integrity": "sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ==", + "license": "Hippocratic-2.1", + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, + "node_modules/@react-three/drei": { + "version": "10.7.6", + "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-10.7.6.tgz", + "integrity": "sha512-ZSFwRlRaa4zjtB7yHO6Q9xQGuyDCzE7whXBhum92JslcMRC3aouivp0rAzszcVymIoJx6PXmibyP+xr+zKdwLg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mediapipe/tasks-vision": "0.10.17", + "@monogrid/gainmap-js": "^3.0.6", + "@use-gesture/react": "^10.3.1", + "camera-controls": "^3.1.0", + "cross-env": "^7.0.3", + "detect-gpu": "^5.0.56", + "glsl-noise": "^0.0.0", + "hls.js": "^1.5.17", + "maath": "^0.10.8", + "meshline": "^3.3.1", + "stats-gl": "^2.2.8", + "stats.js": "^0.17.0", + "suspend-react": "^0.1.3", + "three-mesh-bvh": "^0.8.3", + "three-stdlib": "^2.35.6", + "troika-three-text": "^0.52.4", + "tunnel-rat": "^0.1.2", + "use-sync-external-store": "^1.4.0", + "utility-types": "^3.11.0", + "zustand": "^5.0.1" + }, + "peerDependencies": { + "@react-three/fiber": "^9.0.0", + "react": "^19", + "react-dom": "^19", + "three": ">=0.159" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/@react-three/fiber": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.4.0.tgz", + "integrity": "sha512-k4iu1R6e5D54918V4sqmISUkI5OgTw3v7/sDRKEC632Wd5g2WBtUS5gyG63X0GJO/HZUj1tsjSXfyzwrUHZl1g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.17.8", + "@types/react-reconciler": "^0.32.0", + "@types/webxr": "*", + "base64-js": "^1.5.1", + "buffer": "^6.0.3", + "its-fine": "^2.0.0", + "react-reconciler": "^0.31.0", + "react-use-measure": "^2.1.7", + "scheduler": "^0.25.0", + "suspend-react": "^0.1.3", + "use-sync-external-store": "^1.4.0", + "zustand": "^5.0.3" + }, + "peerDependencies": { + "expo": ">=43.0", + "expo-asset": ">=8.4", + "expo-file-system": ">=11.0", + "expo-gl": ">=11.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-native": ">=0.78", + "three": ">=0.156" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + }, + "expo-asset": { + "optional": true + }, + "expo-file-system": { + "optional": true + }, + "expo-gl": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@react-three/fiber/node_modules/scheduler": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "license": "MIT" + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.9.2.tgz", + "integrity": "sha512-ZAYu/NXkl/OhqTz7rfPaAhY0+e8Fr15jqNxte/2exKUxvHyQ/hcqmdekiN1f+Lcw3pE+34FCgX+26zcUE3duCg==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.43", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.43.tgz", + "integrity": "sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", + "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", + "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", + "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", + "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", + "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", + "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, + "node_modules/@tweenjs/tween.js": { + "version": "23.1.3", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", + "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/draco3d": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz", + "integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==", + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/offscreencanvas": { + "version": "2019.7.3", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz", + "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==", + "license": "MIT" + }, + "node_modules/@types/pako": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/pako/-/pako-2.0.4.tgz", + "integrity": "sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==", + "license": "MIT" + }, + "node_modules/@types/raf": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz", + "integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/react": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", + "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/react-reconciler": { + "version": "0.32.3", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.32.3.tgz", + "integrity": "sha512-cMi5ZrLG7UtbL7LTK6hq9w/EZIRk4Mf1Z5qHoI+qBh7/WkYkFXQ7gOto2yfUvPzF5ERMAhaXS5eTQ2SAnHjLzA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/stats.js": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz", + "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==", + "license": "MIT" + }, + "node_modules/@types/three": { + "version": "0.181.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.181.0.tgz", + "integrity": "sha512-MLF1ks8yRM2k71D7RprFpDb9DOX0p22DbdPqT/uAkc6AtQXjxWCVDjCy23G9t1o8HcQPk7woD2NIyiaWcWPYmA==", + "license": "MIT", + "dependencies": { + "@dimforge/rapier3d-compat": "~0.12.0", + "@tweenjs/tween.js": "~23.1.3", + "@types/stats.js": "*", + "@types/webxr": "*", + "@webgpu/types": "*", + "fflate": "~0.8.2", + "meshoptimizer": "~0.22.0" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, + "node_modules/@types/webxr": { + "version": "0.5.24", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz", + "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==", + "license": "MIT" + }, + "node_modules/@use-gesture/core": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz", + "integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==", + "license": "MIT" + }, + "node_modules/@use-gesture/react": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz", + "integrity": "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==", + "license": "MIT", + "dependencies": { + "@use-gesture/core": "10.3.1" + }, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.0.tgz", + "integrity": "sha512-4LuWrg7EKWgQaMJfnN+wcmbAW+VSsCmqGohftWjuct47bv8uE4n/nPpq4XjJPsxgq00GGG5J8dvBczp8uxScew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.4", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.43", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@webgpu/types": { + "version": "0.1.66", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.66.tgz", + "integrity": "sha512-YA2hLrwLpDsRueNDXIMqN9NTzD6bCDkuXbOSe0heS+f8YE8usA6Gbv1prj81pzVHrbaAma7zObnIC+I6/sXJgA==", + "license": "BSD-3-Clause" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/adler-32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", + "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.1.tgz", + "integrity": "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.23", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.23.tgz", + "integrity": "sha512-616V5YX4bepJFzNyOfce5Fa8fDJMfoxzOIzDCZwaGL8MKVpFrXqfNUoIpRn9YMI5pXf/VKgzjB4htFMsFKKdiQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/camera-controls": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-3.1.0.tgz", + "integrity": "sha512-w5oULNpijgTRH0ARFJJ0R5ct1nUM3R3WP7/b8A6j9uTGpRfnsypc/RBMPQV8JQDPayUe37p/TZZY1PcUr4czOQ==", + "license": "MIT", + "engines": { + "node": ">=20.11.0", + "npm": ">=10.8.2" + }, + "peerDependencies": { + "three": ">=0.126.1" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001752", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001752.tgz", + "integrity": "sha512-vKUk7beoukxE47P5gcVNKkDRzXdVofotshHwfR9vmpeFKxmI5PBpgOMC18LUJUA/DvJ70Y7RveasIBraqsyO/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/canvg": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.11.tgz", + "integrity": "sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@types/raf": "^3.4.0", + "core-js": "^3.8.3", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.7", + "rgbcolor": "^1.0.1", + "stackblur-canvas": "^2.0.0", + "svg-pathdata": "^6.0.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/cfb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", + "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "license": "Apache-2.0", + "dependencies": { + "adler-32": "~1.3.0", + "crc-32": "~1.2.0" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/codepage": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", + "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/core-js": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.46.0.tgz", + "integrity": "sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush/node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush/node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz", + "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-drag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz", + "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-dispatch": "1 - 2", + "d3-selection": "2" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-2.0.2.tgz", + "integrity": "sha512-8pM1WGMLGFuhq9S+FpPURxic+gKzjluCD/CHTuUF3mXMeiCo0i6R0tO1s4+GArRFde96SLcW/kOFRjoAosPsFA==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "^2.5.0" + } + }, + "node_modules/d3-geo/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-geo/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC" + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz", + "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz", + "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-color": "1 - 2", + "d3-dispatch": "1 - 2", + "d3-ease": "1 - 2", + "d3-interpolate": "1 - 2", + "d3-timer": "1 - 2" + }, + "peerDependencies": { + "d3-selection": "2" + } + }, + "node_modules/d3-transition/node_modules/d3-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", + "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-transition/node_modules/d3-ease": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz", + "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-transition/node_modules/d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-color": "1 - 2" + } + }, + "node_modules/d3-transition/node_modules/d3-timer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz", + "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-zoom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz", + "integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-dispatch": "1 - 2", + "d3-drag": "2", + "d3-interpolate": "1 - 2", + "d3-selection": "2", + "d3-transition": "2" + } + }, + "node_modules/d3-zoom/node_modules/d3-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", + "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-zoom/node_modules/d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-color": "1 - 2" + } + }, + "node_modules/d3/node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3/node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-gpu": { + "version": "5.0.70", + "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.70.tgz", + "integrity": "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==", + "license": "MIT", + "dependencies": { + "webgl-constants": "^1.1.1" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dompurify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz", + "integrity": "sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optional": true, + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/draco3d": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz", + "integrity": "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==", + "license": "Apache-2.0" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.244", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.244.tgz", + "integrity": "sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-toolkit": { + "version": "1.41.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.41.0.tgz", + "integrity": "sha512-bDd3oRmbVgqZCJS6WmeQieOrzpl3URcWBUVDXxOELlUW2FuW+0glPOz1n0KnRie+PdyvUZcXz2sOn00c6pPRIA==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, + "node_modules/esbuild": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", + "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.11", + "@esbuild/android-arm": "0.25.11", + "@esbuild/android-arm64": "0.25.11", + "@esbuild/android-x64": "0.25.11", + "@esbuild/darwin-arm64": "0.25.11", + "@esbuild/darwin-x64": "0.25.11", + "@esbuild/freebsd-arm64": "0.25.11", + "@esbuild/freebsd-x64": "0.25.11", + "@esbuild/linux-arm": "0.25.11", + "@esbuild/linux-arm64": "0.25.11", + "@esbuild/linux-ia32": "0.25.11", + "@esbuild/linux-loong64": "0.25.11", + "@esbuild/linux-mips64el": "0.25.11", + "@esbuild/linux-ppc64": "0.25.11", + "@esbuild/linux-riscv64": "0.25.11", + "@esbuild/linux-s390x": "0.25.11", + "@esbuild/linux-x64": "0.25.11", + "@esbuild/netbsd-arm64": "0.25.11", + "@esbuild/netbsd-x64": "0.25.11", + "@esbuild/openbsd-arm64": "0.25.11", + "@esbuild/openbsd-x64": "0.25.11", + "@esbuild/openharmony-arm64": "0.25.11", + "@esbuild/sunos-x64": "0.25.11", + "@esbuild/win32-arm64": "0.25.11", + "@esbuild/win32-ia32": "0.25.11", + "@esbuild/win32-x64": "0.25.11" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.0.tgz", + "integrity": "sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.0", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.24.tgz", + "integrity": "sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-png": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/fast-png/-/fast-png-6.4.0.tgz", + "integrity": "sha512-kAqZq1TlgBjZcLr5mcN6NP5Rv4V2f22z00c3g8vRrwkcqjerx7BEhPbOnWCPqaHUl2XWQBJQvOT/FQhdMT7X/Q==", + "license": "MIT", + "dependencies": { + "@types/pako": "^2.0.3", + "iobuffer": "^5.3.2", + "pako": "^2.1.0" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/firebase": { + "version": "12.5.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-12.5.0.tgz", + "integrity": "sha512-Ak8JcpH7FL6kiv0STwkv5+3CYEROO9iFWSx7OCZVvc4kIIABAIyAGs1mPGaHRxGUIApFZdMCXA7baq17uS6Mow==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/ai": "2.5.0", + "@firebase/analytics": "0.10.19", + "@firebase/analytics-compat": "0.2.25", + "@firebase/app": "0.14.5", + "@firebase/app-check": "0.11.0", + "@firebase/app-check-compat": "0.4.0", + "@firebase/app-compat": "0.5.5", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.11.1", + "@firebase/auth-compat": "0.6.1", + "@firebase/data-connect": "0.3.11", + "@firebase/database": "1.1.0", + "@firebase/database-compat": "2.1.0", + "@firebase/firestore": "4.9.2", + "@firebase/firestore-compat": "0.4.2", + "@firebase/functions": "0.13.1", + "@firebase/functions-compat": "0.4.1", + "@firebase/installations": "0.6.19", + "@firebase/installations-compat": "0.2.19", + "@firebase/messaging": "0.12.23", + "@firebase/messaging-compat": "0.2.23", + "@firebase/performance": "0.7.9", + "@firebase/performance-compat": "0.2.22", + "@firebase/remote-config": "0.7.0", + "@firebase/remote-config-compat": "0.2.20", + "@firebase/storage": "0.14.0", + "@firebase/storage-compat": "0.4.0", + "@firebase/util": "1.13.0" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/frac": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", + "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/framer-motion": { + "version": "12.23.24", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.24.tgz", + "integrity": "sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.23.23", + "motion-utils": "^12.23.6", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glsl-noise": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz", + "integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==", + "license": "MIT" + }, + "node_modules/goober": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.18.tgz", + "integrity": "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==", + "license": "MIT", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hls.js": { + "version": "1.6.14", + "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.14.tgz", + "integrity": "sha512-CSpT2aXsv71HST8C5ETeVo+6YybqCpHBiYrCRQSn3U5QUZuLTSsvtq/bj+zuvjLVADeKxoebzo16OkH8m1+65Q==", + "license": "Apache-2.0" + }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "license": "MIT", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/immer": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz", + "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/iobuffer": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-5.4.0.tgz", + "integrity": "sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/its-fine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-2.0.0.tgz", + "integrity": "sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==", + "license": "MIT", + "dependencies": { + "@types/react-reconciler": "^0.28.9" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, + "node_modules/its-fine/node_modules/@types/react-reconciler": { + "version": "0.28.9", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz", + "integrity": "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jspdf": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-3.0.3.tgz", + "integrity": "sha512-eURjAyz5iX1H8BOYAfzvdPfIKK53V7mCpBTe7Kb16PaM8JSXEcUQNBQaiWMI8wY5RvNOPj4GccMjTlfwRBd+oQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.9", + "fast-png": "^6.2.0", + "fflate": "^0.8.1" + }, + "optionalDependencies": { + "canvg": "^3.0.11", + "core-js": "^3.6.0", + "dompurify": "^3.2.4", + "html2canvas": "^1.0.0-rc.5" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "license": "BSD-2-Clause" + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.552.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.552.0.tgz", + "integrity": "sha512-g9WCjmfwqbexSnZE+2cl21PCfXOcqnGeWeMTNAOGEfpPbm/ZF4YIq77Z8qWrxbu660EKuLB4nSLggoKnCb+isw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/maath": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz", + "integrity": "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==", + "license": "MIT", + "peerDependencies": { + "@types/three": ">=0.134.0", + "three": ">=0.134.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/meshline": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/meshline/-/meshline-3.3.1.tgz", + "integrity": "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==", + "license": "MIT", + "peerDependencies": { + "three": ">=0.137" + } + }, + "node_modules/meshoptimizer": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.22.0.tgz", + "integrity": "sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==", + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/motion-dom": { + "version": "12.23.23", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.23.tgz", + "integrity": "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.23.6" + } + }, + "node_modules/motion-utils": { + "version": "12.23.6", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz", + "integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "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/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT", + "optional": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/potpack": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", + "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==", + "license": "ISC" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/promise-worker-transferable": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz", + "integrity": "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==", + "license": "Apache-2.0", + "dependencies": { + "is-promise": "^2.1.0", + "lie": "^3.0.2" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "license": "MIT", + "optional": true, + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/react": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", + "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-circular-progressbar": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-circular-progressbar/-/react-circular-progressbar-2.2.0.tgz", + "integrity": "sha512-cgyqEHOzB0nWMZjKfWN3MfSa1LV3OatcDjPz68lchXQUEiBD5O1WsAtoVK4/DSL0B4USR//cTdok4zCBkq8X5g==", + "license": "MIT", + "peerDependencies": { + "react": ">=0.14.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", + "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, + "node_modules/react-draggable": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.5.0.tgz", + "integrity": "sha512-VC+HBLEZ0XJxnOxVAZsdRi8rD04Iz3SiiKOoYzamjylUcju/hP9np/aZdLHf/7WOD268WMoNJMvYfB5yAK45cw==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": ">= 16.3.0", + "react-dom": ">= 16.3.0" + } + }, + "node_modules/react-gauge-chart": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/react-gauge-chart/-/react-gauge-chart-0.5.1.tgz", + "integrity": "sha512-Kd0pLIfHWOVEWJCz+xAxFfrKzCdOkLHNKR13V+O3h06ocyGT7fWjz2oevMXsPt3bVn1Du2od7gPrjUhqXKdASg==", + "license": "MIT", + "dependencies": { + "d3": "^7.6.1" + }, + "peerDependencies": { + "react": "^16.8.2 || ^17.0 || ^18.x", + "react-dom": "^16.8.2 || ^17.0 || ^18.x" + } + }, + "node_modules/react-hot-toast": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.6.0.tgz", + "integrity": "sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg==", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.3", + "goober": "^2.1.16" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/react-is": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz", + "integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==", + "license": "MIT" + }, + "node_modules/react-leaflet": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz", + "integrity": "sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw==", + "license": "Hippocratic-2.1", + "dependencies": { + "@react-leaflet/core": "^3.0.0" + }, + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, + "node_modules/react-parallax-tilt": { + "version": "1.7.313", + "resolved": "https://registry.npmjs.org/react-parallax-tilt/-/react-parallax-tilt-1.7.313.tgz", + "integrity": "sha512-SjIic2FehsB4v/zDEmcf7MInCd6vy/tjj5Vn+Cwl9ksEgNxsDIuLZEhEy7w7rR+svj8NPGUpvTpy93D8e3q9hA==", + "license": "MIT", + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-reconciler": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.31.0.tgz", + "integrity": "sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.25.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, + "node_modules/react-reconciler/node_modules/scheduler": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "license": "MIT" + }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.5.tgz", + "integrity": "sha512-JmxqrnBZ6E9hWmf02jzNn9Jm3UqyeimyiwzD69NjxGySG6lIz/1LVPsoTCwN7NBX2XjCEa1LIX5EMz1j2b6u6A==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.5.tgz", + "integrity": "sha512-mkEmq/K8tKN63Ae2M7Xgz3c9l9YNbY+NHH6NNeUmLA3kDkhKXRsNb/ZpxaEunvGo2/3YXdk5EJU3Hxp3ocaBPw==", + "license": "MIT", + "dependencies": { + "react-router": "7.9.5" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-simple-maps": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-simple-maps/-/react-simple-maps-3.0.0.tgz", + "integrity": "sha512-vKNFrvpPG8Vyfdjnz5Ne1N56rZlDfHXv5THNXOVZMqbX1rWZA48zQuYT03mx6PAKanqarJu/PDLgshIZAfHHqw==", + "license": "MIT", + "dependencies": { + "d3-geo": "^2.0.2", + "d3-selection": "^2.0.0", + "d3-zoom": "^2.0.0", + "topojson-client": "^3.1.0" + }, + "peerDependencies": { + "prop-types": "^15.7.2", + "react": "^16.8.0 || 17.x || 18.x", + "react-dom": "^16.8.0 || 17.x || 18.x" + } + }, + "node_modules/react-use-measure": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz", + "integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.13", + "react-dom": ">=16.13" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/recharts": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.3.0.tgz", + "integrity": "sha512-Vi0qmTB0iz1+/Cz9o5B7irVyUjX2ynvEgImbgMt/3sKRREcUM07QiYjS1QpAVrkmVlXqy5gykq4nGWMz9AS4Rg==", + "license": "MIT", + "dependencies": { + "@reduxjs/toolkit": "1.x.x || 2.x.x", + "clsx": "^2.1.1", + "decimal.js-light": "^2.5.1", + "es-toolkit": "^1.39.3", + "eventemitter3": "^5.0.1", + "immer": "^10.1.1", + "react-redux": "8.x.x || 9.x.x", + "reselect": "5.1.1", + "tiny-invariant": "^1.3.3", + "use-sync-external-store": "^1.2.2", + "victory-vendor": "^37.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT", + "optional": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rgbcolor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", + "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==", + "license": "MIT OR SEE LICENSE IN FEEL-FREE.md", + "optional": true, + "engines": { + "node": ">= 0.8.15" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense" + }, + "node_modules/rollup": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssf": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", + "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", + "license": "Apache-2.0", + "dependencies": { + "frac": "~1.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/stackblur-canvas": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz", + "integrity": "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.14" + } + }, + "node_modules/stats-gl": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.4.2.tgz", + "integrity": "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==", + "license": "MIT", + "dependencies": { + "@types/three": "*", + "three": "^0.170.0" + }, + "peerDependencies": { + "@types/three": "*", + "three": "*" + } + }, + "node_modules/stats-gl/node_modules/three": { + "version": "0.170.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.170.0.tgz", + "integrity": "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ==", + "license": "MIT" + }, + "node_modules/stats.js": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", + "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/suspend-react": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz", + "integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==", + "license": "MIT", + "peerDependencies": { + "react": ">=17.0" + } + }, + "node_modules/svg-pathdata": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", + "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tailwind-merge": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", + "integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.18", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.18.tgz", + "integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "license": "MIT", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/three": { + "version": "0.181.1", + "resolved": "https://registry.npmjs.org/three/-/three-0.181.1.tgz", + "integrity": "sha512-bz9xZUQMw3pJbjKy7roiwXWgAp+oVUa+4k5o0oBAQ+IFJuru1xzvtk63h6k72XZanXS/SgoEhV6927Vgazyq2w==", + "license": "MIT" + }, + "node_modules/three-mesh-bvh": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.8.3.tgz", + "integrity": "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==", + "license": "MIT", + "peerDependencies": { + "three": ">= 0.159.0" + } + }, + "node_modules/three-stdlib": { + "version": "2.36.1", + "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.36.1.tgz", + "integrity": "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg==", + "license": "MIT", + "dependencies": { + "@types/draco3d": "^1.4.0", + "@types/offscreencanvas": "^2019.6.4", + "@types/webxr": "^0.5.2", + "draco3d": "^1.4.1", + "fflate": "^0.6.9", + "potpack": "^1.0.1" + }, + "peerDependencies": { + "three": ">=0.128.0" + } + }, + "node_modules/three-stdlib/node_modules/fflate": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", + "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==", + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "license": "ISC", + "dependencies": { + "commander": "2" + }, + "bin": { + "topo2geo": "bin/topo2geo", + "topomerge": "bin/topomerge", + "topoquantize": "bin/topoquantize" + } + }, + "node_modules/topojson-client/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/troika-three-text": { + "version": "0.52.4", + "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.52.4.tgz", + "integrity": "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==", + "license": "MIT", + "dependencies": { + "bidi-js": "^1.0.2", + "troika-three-utils": "^0.52.4", + "troika-worker-utils": "^0.52.0", + "webgl-sdf-generator": "1.1.1" + }, + "peerDependencies": { + "three": ">=0.125.0" + } + }, + "node_modules/troika-three-utils": { + "version": "0.52.4", + "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.52.4.tgz", + "integrity": "sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==", + "license": "MIT", + "peerDependencies": { + "three": ">=0.125.0" + } + }, + "node_modules/troika-worker-utils": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.52.0.tgz", + "integrity": "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==", + "license": "MIT" + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tunnel-rat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz", + "integrity": "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==", + "license": "MIT", + "dependencies": { + "zustand": "^4.3.2" + } + }, + "node_modules/tunnel-rat/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, + "node_modules/victory-vendor": { + "version": "37.3.6", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz", + "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/vite": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz", + "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, + "node_modules/webgl-constants": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz", + "integrity": "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==" + }, + "node_modules/webgl-sdf-generator": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz", + "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==", + "license": "MIT" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wmf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", + "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/word": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", + "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/xlsx": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", + "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", + "license": "Apache-2.0", + "dependencies": { + "adler-32": "~1.3.0", + "cfb": "~1.2.1", + "codepage": "~1.15.0", + "crc-32": "~1.2.1", + "ssf": "~0.11.2", + "wmf": "~1.0.1", + "word": "~0.3.0" + }, + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zustand": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz", + "integrity": "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000000000000000000000000000000000000..9cc6b8f583debe3f1ae4a3312c8c978eb31201ea --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,64 @@ +{ + "name": "frontend", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview", + "tailwind-init": "tailwindcss init -p" + }, + "dependencies": { + "@radix-ui/react-accordion": "^1.2.12", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-separator": "^1.1.8", + "@radix-ui/react-slot": "^1.2.4", + "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", + "@react-three/drei": "^10.7.6", + "@react-three/fiber": "^9.4.0", + "axios": "^1.13.1", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "firebase": "^12.5.0", + "framer-motion": "^12.23.24", + "html2canvas": "^1.4.1", + "jspdf": "^3.0.3", + "leaflet": "^1.9.4", + "lodash": "^4.17.21", + "lucide-react": "^0.552.0", + "prop-types": "^15.8.1", + "react": "^19.1.1", + "react-circular-progressbar": "^2.2.0", + "react-dom": "^19.1.1", + "react-draggable": "^4.5.0", + "react-gauge-chart": "^0.5.1", + "react-hot-toast": "^2.6.0", + "react-is": "^19.2.0", + "react-leaflet": "^5.0.0", + "react-parallax-tilt": "^1.7.313", + "react-router-dom": "^7.9.5", + "react-simple-maps": "^3.0.0", + "recharts": "^3.3.0", + "tailwind-merge": "^3.4.0", + "tailwindcss-animate": "^1.0.7", + "three": "^0.181.1", + "xlsx": "^0.18.5" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/react": "^19.1.16", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.4", + "autoprefixer": "^10.4.21", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.22", + "globals": "^16.4.0", + "postcss": "^8.5.6", + "tailwindcss": "^3.4.18", + "vite": "^7.1.7" + } +} diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js new file mode 100644 index 0000000000000000000000000000000000000000..e735cfc417522abfb47d80ef294bd72ae9418eca --- /dev/null +++ b/frontend/postcss.config.js @@ -0,0 +1,6 @@ +export default { +plugins: { +tailwindcss: {}, +autoprefixer: {}, +}, +}; \ No newline at end of file diff --git a/frontend/public/images.ico b/frontend/public/images.ico new file mode 100644 index 0000000000000000000000000000000000000000..e8a09a7cab7ed3ec71ceee48cc3756ee00951d78 Binary files /dev/null and b/frontend/public/images.ico differ diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg new file mode 100644 index 0000000000000000000000000000000000000000..e7b8dfb1b2a60bd50538bec9f876511b9cac21e3 --- /dev/null +++ b/frontend/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx new file mode 100644 index 0000000000000000000000000000000000000000..eca0b1573a2d33dba38a7066f8a443df2749d10c --- /dev/null +++ b/frontend/src/App.jsx @@ -0,0 +1,80 @@ +import { BrowserRouter as Router, Routes, Route, useLocation } from "react-router-dom"; +import { LiveDataProvider } from "./context/DataContext"; +import { AuthProvider } from "./context/AuthContext"; +import ProtectedRoute from "./components/ProtectedRoute"; +import Sidebar from "./components/Sidebar"; +import { useState } from "react"; + +import AuthPage from "./pages/Login"; +import Dashboard from "./pages/Dashboard"; +import LiveTraffic from "./components/dashboard/LiveDashboard"; +import FlowPage from "./pages/FlowPage"; +import SettingsPage from "./pages/SettingsPage"; +import InfoPage from "./pages/InfoPage"; +import ThreatIntel from "./pages/ThreatIntel"; +import Reports from "./pages/ReportsPage"; +import TrafficPage from "./pages/TrafficPage"; +import IncidentsPage from "./pages/IncidentsPage"; +import SystemPage from "./pages/SystemPage"; +import ResponsePage from "./pages/ResponsePage"; +import MlmodelPage from "./pages/MLModelsPage"; +import ConstellationBackground from "./components/ConstellationBackground"; +import SamplePred from "./pages/MLAttackSamplesPage"; +import Aichat from "./pages/ChatAssistant"; +import MainLayout from "./components/MainLayout"; + + +// Layout wrapper +function AppLayout() { + const location = useLocation(); + const hideSidebar = location.pathname === "/login"; + + const [collapsed, setCollapsed] = useState(false); + + return ( +
+ + + {!hideSidebar && ( + + )} + +
+ + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + +
+
+ ); +} + +export default function App() { + return ( + + + + + + + + ); +} + diff --git a/frontend/src/api.js b/frontend/src/api.js new file mode 100644 index 0000000000000000000000000000000000000000..aab5c5f9f38542c11cbc61c42518c939237b0779 --- /dev/null +++ b/frontend/src/api.js @@ -0,0 +1,182 @@ +// =============================================== +// 🔐 API Layer for Adaptive AI NIDS Frontend +// =============================================== + +const BASE_URL = + import.meta.env.VITE_API_URL || "http://127.0.0.1:5000"; + +// Safe fetch wrapper +async function safeFetch(url, options = {}, timeout = 10000, retries = 1) { + const controller = new AbortController(); + const id = setTimeout(() => controller.abort(), timeout); + + try { + const res = await fetch(url, { ...options, signal: controller.signal }); + + if (!res.ok) { + const errText = await res.text(); + throw new Error(`HTTP ${res.status}: ${errText}`); + } + return await res.json(); + } catch (err) { + console.error(`❌ API Error [${url}]:`, err.message); + + if (retries > 0 && url.includes("/geo/")) { + await new Promise((r) => setTimeout(r, 1500)); + return safeFetch(url, options, timeout * 1.5, retries - 1); + } + + return { error: err.message }; + } finally { + clearTimeout(id); + } +} + +// ------------------------------------------------------------- +// 🚀 LIVE CAPTURE +// ------------------------------------------------------------- +export async function startSniffer(iface = null) { + const q = iface ? `?iface=${iface}` : ""; + return safeFetch(`${BASE_URL}/api/live/start${q}`); +} + +export async function stopSniffer() { + return safeFetch(`${BASE_URL}/api/live/stop`); +} + +export async function getStatus() { + return safeFetch(`${BASE_URL}/api/live/status`); +} + +// MODEL-AWARE 🎯 +export async function getRecent(model, limit = 300) { + const res = await safeFetch(`${BASE_URL}/api/live/recent?model=${model}`); + + if (res?.events && Array.isArray(res.events)) { + res.events = res.events.slice(-limit); + } + return res; +} + +// MODEL-AWARE 🎯 +export async function getStats(model) { + return safeFetch(`${BASE_URL}/api/live/stats?model=${model}`); +} + +// ------------------------------------------------------------- +// 🧾 LOGS (MODEL-AWARE) +// ------------------------------------------------------------- +export function download_logs(model) { + window.location.href = `${BASE_URL}/api/logs/download?model=${model}`; +} + +export async function clearLogs(model, n = 50) { + return safeFetch( + `${BASE_URL}/api/logs/clear?model=${model}&n=${n}`, + { method: "POST" } + ); +} + +export async function clearByPrediction(model, pred) { + return safeFetch( + `${BASE_URL}/api/logs/clear_pred?model=${model}&pred=${pred}`, + { method: "POST" } + ); +} + +export async function deleteOne(model, index) { + return safeFetch( + `${BASE_URL}/api/logs/delete_one?model=${model}&index=${index}`, + { method: "POST" } + ); +} + +// ------------------------------------------------------------- +// 🌍 GEO + ALERTS +// ------------------------------------------------------------- +export async function getGeoData() { + return safeFetch(`${BASE_URL}/api/geo/recent`, {}, 20000, 2); +} + +export async function getAlerts() { + return safeFetch(`${BASE_URL}/api/alerts`); +} + +// ------------------------------------------------------------- +// 🧩 MODEL CONTROL +// ------------------------------------------------------------- +export async function getActiveModel() { + return safeFetch(`${BASE_URL}/api/model/active`); +} + +export async function switchModel(model) { + return safeFetch(`${BASE_URL}/api/model/select`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ model }), + }); +} + +export async function getModelHealth() { + return safeFetch(`${BASE_URL}/api/model/health`); +} + + +// ------------------------------------------------------------- +// 🤖 AI HELPERS +// ------------------------------------------------------------- +export async function explainThreat(event) { + return safeFetch(`${BASE_URL}/api/ai/explain`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(event), + }); +} + +export async function getAISummary(model, n = 200) { + return safeFetch( + `${BASE_URL}/api/ai/summary?model=${encodeURIComponent(model)}&n=${n}` + ); +} + + +export async function sendMessageToAI(message) { + try { + const res = await fetch(`${BASE_URL}/api/chat`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ message }) + }); + + if (!res.ok) throw new Error("Chat API failed"); + return res.json(); + } catch (err) { + console.error("Chat error:", err); + return { reply: "⚠ AI Assistant not responding." }; + } +} + +// ➤ Offline CSV/PCAP prediction +export const offlinePredictAPI = async (file, model) => { + const formData = new FormData(); + formData.append("file", file); + formData.append("model", model); + + const res = await fetch("http://127.0.0.1:5000/api/offline/predict", { + method: "POST", + body: formData, + }); + + return res.json(); +}; + +// ➤ Get PDF forensic report download link +export const downloadOfflineReport = () => { + window.open("http://127.0.0.1:5000/api/offline/report", "_blank"); +}; + + +// ------------------------------------------------------------- +export { BASE_URL }; + + diff --git a/frontend/src/assests/Dos-HTTPtest.jpg b/frontend/src/assests/Dos-HTTPtest.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d0ee11971cd2f071f4fb4d65dde7034359dc3ee2 Binary files /dev/null and b/frontend/src/assests/Dos-HTTPtest.jpg differ diff --git a/frontend/src/assests/Dos_Attacks-hulk.jpeg b/frontend/src/assests/Dos_Attacks-hulk.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..7a7d44c8d1a48d6348eff643a9c2db801a1387ef Binary files /dev/null and b/frontend/src/assests/Dos_Attacks-hulk.jpeg differ diff --git a/frontend/src/assests/HOIC.jpeg b/frontend/src/assests/HOIC.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..eaba03516551e68cc99795a2a398f5f95609c081 Binary files /dev/null and b/frontend/src/assests/HOIC.jpeg differ diff --git a/frontend/src/assests/LOic.jpeg b/frontend/src/assests/LOic.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..fcbcb8c390ad51d908664e3b3ef1261b3a3573d4 Binary files /dev/null and b/frontend/src/assests/LOic.jpeg differ diff --git a/frontend/src/assests/heroBlocks.svg b/frontend/src/assests/heroBlocks.svg new file mode 100644 index 0000000000000000000000000000000000000000..ba0c5004a6fb40218a499f24444f7a409629d17c --- /dev/null +++ b/frontend/src/assests/heroBlocks.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/assests/sql.jpeg b/frontend/src/assests/sql.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..5601028bf89da07e2ef36973dad98f0d959e3fdd Binary files /dev/null and b/frontend/src/assests/sql.jpeg differ diff --git a/frontend/src/assests/vpn.jpg b/frontend/src/assests/vpn.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e3cd42beffbd56ecb57427d7054ec990f8ca6869 Binary files /dev/null and b/frontend/src/assests/vpn.jpg differ diff --git a/frontend/src/assests/web.jpeg b/frontend/src/assests/web.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..e6de3cc124ae020f609e62bcdc039720ba56949e Binary files /dev/null and b/frontend/src/assests/web.jpeg differ diff --git a/frontend/src/components/Alerts.jsx b/frontend/src/components/Alerts.jsx new file mode 100644 index 0000000000000000000000000000000000000000..ade84bbaaf4222a43b8d98c2ba84b6945167e9f7 --- /dev/null +++ b/frontend/src/components/Alerts.jsx @@ -0,0 +1,36 @@ +import React, { useContext } from "react"; +import { AlertTriangle, ShieldAlert, Info } from "lucide-react"; +import { AlertContext } from "../context/AlertContext.jsx"; + +export default function Alerts() { + const { alerts, removeAlert } = useContext(AlertContext); + + const COLORS = { + info: "border-blue-400/40 bg-blue-500/10 text-blue-300", + warn: "border-yellow-400/40 bg-yellow-500/10 text-yellow-300", + danger: "border-red-400/40 bg-red-500/10 text-red-300", + }; + + const ICONS = { + info: , + warn: , + danger: , + }; + + return ( +
+ {alerts.map(a => ( +
removeAlert(a.id)} + > + {ICONS[a.type]} + {a.msg} +
+ ))} +
+ ); +} diff --git a/frontend/src/components/ConstellationBackground.jsx b/frontend/src/components/ConstellationBackground.jsx new file mode 100644 index 0000000000000000000000000000000000000000..5bb21252c1990f50a0e39ee343f3fe0f90d36b48 --- /dev/null +++ b/frontend/src/components/ConstellationBackground.jsx @@ -0,0 +1,85 @@ +import { useEffect, useRef } from "react"; + +export default function ConstellationBackground() { + const canvasRef = useRef(null); + + useEffect(() => { + const canvas = canvasRef.current; + const ctx = canvas.getContext("2d"); + + let particles = []; + const count = 140; // number of stars + + // resize canvas + function resize() { + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + } + resize(); + window.addEventListener("resize", resize); + + // create particles + for (let i = 0; i < count; i++) { + particles.push({ + x: Math.random() * canvas.width, + y: Math.random() * canvas.height, + vx: (Math.random() - 0.5) * 0.3, + vy: (Math.random() - 0.5) * 0.3, + size: Math.random() * 2 + 1, + }); + } + + // animation loop + function animate() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + + // draw particles + particles.forEach((p) => { + p.x += p.vx; + p.y += p.vy; + + // soft bounce + if (p.x < 0 || p.x > canvas.width) p.vx *= -1; + if (p.y < 0 || p.y > canvas.height) p.vy *= -1; + + ctx.beginPath(); + ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); + ctx.fillStyle = "rgba(0, 220, 255, 0.9)"; + ctx.shadowBlur = 10; + ctx.shadowColor = "#66e0ff"; + ctx.fill(); + }); + + // draw connecting lines + for (let i = 0; i < count; i++) { + for (let j = i + 1; j < count; j++) { + const a = particles[i]; + const b = particles[j]; + const dist = Math.hypot(a.x - b.x, a.y - b.y); + + if (dist < 140) { + ctx.strokeStyle = `rgba(120, 255, 255, ${1 - dist / 140})`; + ctx.lineWidth = 0.7; + ctx.beginPath(); + ctx.moveTo(a.x, a.y); + ctx.lineTo(b.x, b.y); + ctx.stroke(); + } + } + } + + requestAnimationFrame(animate); + } + + animate(); + + return () => window.removeEventListener("resize", resize); + }, []); + + return ( + + ); +} diff --git a/frontend/src/components/Header.jsx b/frontend/src/components/Header.jsx new file mode 100644 index 0000000000000000000000000000000000000000..8378b063e8499f9b5910040856d0ba4d18197251 --- /dev/null +++ b/frontend/src/components/Header.jsx @@ -0,0 +1,16 @@ +// src/components/Header.jsx +import React from "react"; +import { useAuth } from "../context/AuthContext"; + +export default function Header() { + const { user, logout } = useAuth(); + return ( +
+
NIDS Cyber Defense
+
+
{user?.email}
+ +
+
+ ); +} diff --git a/frontend/src/components/IPInfoModal.jsx b/frontend/src/components/IPInfoModal.jsx new file mode 100644 index 0000000000000000000000000000000000000000..014eb49da4c1d8662afcaa22c39b7bb4fe89ff0e --- /dev/null +++ b/frontend/src/components/IPInfoModal.jsx @@ -0,0 +1,182 @@ +import React, { useEffect, useState } from "react"; + +export default function IPInfoModal({ ip, onClose }) { + const [info, setInfo] = useState(null); + const [loading, setLoading] = useState(true); + const [risk, setRisk] = useState({ + level: "Unknown", + score: 0, + reason: "Unverified", + }); + + useEffect(() => { + if (!ip) return; + + // Reset state for new IP + setInfo(null); + setRisk({ level: "Unknown", score: 0, reason: "Unverified" }); + setLoading(true); + + // ✅ Private / Local IP detection + const privateRanges = [ + /^127\./, + /^10\./, + /^192\.168\./, + /^172\.(1[6-9]|2[0-9]|3[0-1])\./, + /^239\./, // multicast + ]; + + if (privateRanges.some((r) => r.test(ip))) { + setInfo({ + city: "Local Network", + region: "Private or Multicast Range", + country_name: "N/A", + org: "Local Device", + asn: "LAN", + version: "IPv4", + latitude: "-", + longitude: "-", + }); + setRisk({ + level: "Low", + score: 5, + reason: "Private / local or multicast IP", + }); + setLoading(false); + return; + } + + // ✅ Backend lookup (new route) +fetch(`http://127.0.0.1:5000/api/geo/resolve?ip=${ip}`) + .then(async (res) => { + if (!res.ok) { + const errData = await res.json().catch(() => ({})); + throw new Error(errData.error || "Lookup failed"); + } + return res.json(); + }) + .then((data) => { + setInfo(data); + setRisk({ + level: + data.country === "Local" + ? "Low" + : data.country === "Unknown" + ? "Medium" + : "Low", + score: data.country === "Unknown" ? 40 : 15, + reason: `Detected in ${data.country || "Unknown"}`, + }); + }) + .catch((err) => { + console.warn("⚠️ Geo lookup failed:", err.message); + setInfo({ + city: "Unknown", + country_name: "Unknown", + org: "No data", + latitude: "-", + longitude: "-", + }); + setRisk({ + level: "Low", + score: 10, + reason: "No threat detected / lookup failed", + }); + }) + .finally(() => setLoading(false)); + }, [ip]); + + if (!ip) return null; + + // ✅ Helper for dynamic color + const riskColor = + risk.level === "High" + ? "text-red-400" + : risk.level === "Medium" + ? "text-yellow-400" + : "text-green-400"; + + const riskBarColor = + risk.level === "High" + ? "bg-red-500" + : risk.level === "Medium" + ? "bg-yellow-400" + : "bg-green-400"; + + return ( +
+
+

+ 🌐 IP Info — {ip} +

+ + {loading ? ( +

+ Fetching IP intelligence... +

+ ) : info ? ( +
+

+ City: {info.city || "Unknown"} +

+

+ Region: {info.region || "Unknown"} +

+

+ Country: {info.country_name || "Unknown"} +

+

+ ISP: {info.org || "Unknown"} +

+

+ ASN: {info.asn || "N/A"} +

+

+ IP Type: {info.version} +

+

+ Coordinates: {info.latitude}, {info.longitude} +

+
+ ) : ( +

+ Could not fetch IP intelligence data. +

+ )} + + {/* Risk / Threat assessment */} + {!loading && ( +
+

Threat Assessment

+
+ + {risk.level} Risk ({risk.score}%) + + + {risk.reason} + +
+ + {/* Risk Progress Bar */} +
+
+
+
+ )} + + {/* Close button */} + +
+
+ ); +} + + diff --git a/frontend/src/components/LoadingOverlay.jsx b/frontend/src/components/LoadingOverlay.jsx new file mode 100644 index 0000000000000000000000000000000000000000..5005452cd1ee0e85f6154e595f9846d91fc135eb --- /dev/null +++ b/frontend/src/components/LoadingOverlay.jsx @@ -0,0 +1,12 @@ +// src/components/LoadingOverlay.jsx +export default function LoadingOverlay({ show, message = "Processing..." }) { + if (!show) return null; + return ( +
+
+
+

{message}

+
+
+ ); +} diff --git a/frontend/src/components/MainLayout.jsx b/frontend/src/components/MainLayout.jsx new file mode 100644 index 0000000000000000000000000000000000000000..79f618f1eee1e4fa7a794710560cdca7c0fba926 --- /dev/null +++ b/frontend/src/components/MainLayout.jsx @@ -0,0 +1,13 @@ +import React from "react"; +import Navbar from "./Navbar"; +import ChatAssistant from "../pages/ChatAssistant"; + +export default function MainLayout({ children }) { + return ( +
+ + {children} + +
+ ); +} diff --git a/frontend/src/components/Navbar.jsx b/frontend/src/components/Navbar.jsx new file mode 100644 index 0000000000000000000000000000000000000000..f70700ecc928333ce869cfa85d90b86311633635 --- /dev/null +++ b/frontend/src/components/Navbar.jsx @@ -0,0 +1,128 @@ +import React, { useState } from "react"; +import { Shield, Search, User, ChevronDown, RefreshCcw, LogOut, CurrencyIcon } from "lucide-react"; +import { useAuth } from "../context/AuthContext"; +import { useLocation, useNavigate } from "react-router-dom"; + +export default function Navbar({ onRefresh }) { + const { user, logout } = useAuth(); + const navigate = useNavigate(); + const location = useLocation(); + + const [searchQuery, setSearchQuery] = useState(""); + const [profileOpen, setProfileOpen] = useState(false); + + return ( + + ); +} diff --git a/frontend/src/components/NeonShield.jsx b/frontend/src/components/NeonShield.jsx new file mode 100644 index 0000000000000000000000000000000000000000..9ca4820ba3084c0688dda5ea62f53c39cd06ab6c --- /dev/null +++ b/frontend/src/components/NeonShield.jsx @@ -0,0 +1,87 @@ +import { Canvas, useFrame } from "@react-three/fiber"; +import * as THREE from "three"; +import { useRef } from "react"; + +/* ------------- Rotating Packet Ring ------------- */ +function PacketRing() { + const ring = useRef(); + const pulse = useRef(); + + useFrame(({ clock }) => { + const t = clock.getElapsedTime(); + + ring.current.rotation.y = t * 0.6; + + const r = 1.5; + pulse.current.position.x = r * Math.cos(t * 1.5); + pulse.current.position.y = r * Math.sin(t * 1.5); + }); + + return ( + + + + + + + + + + + + ); +} + +/* ------------- Floating Network Nodes ------------- */ +function NetworkNodes() { + const group = useRef(); + + useFrame(({ clock }) => { + group.current.rotation.y = clock.getElapsedTime() * 0.3; + }); + + const nodes = Array.from({ length: 12 }).map(() => [ + (Math.random() - 0.5) * 2, + (Math.random() - 0.5) * 1.5, + (Math.random() - 0.5) * 1.2, + ]); + + return ( + + {nodes.map((pos, i) => ( + + + + + ))} + + ); +} + +/* ------------- Main Scene ------------- */ +export default function NIDS3D() { + return ( + + + + + + + + + + ); +} + + diff --git a/frontend/src/components/ProtectedRoute.jsx b/frontend/src/components/ProtectedRoute.jsx new file mode 100644 index 0000000000000000000000000000000000000000..f83c96446e12d3217180f0afb3089923a7bb94d0 --- /dev/null +++ b/frontend/src/components/ProtectedRoute.jsx @@ -0,0 +1,10 @@ +// src/components/ProtectedRoute.jsx +import React from "react"; +import { Navigate } from "react-router-dom"; +import { useAuth } from "../context/AuthContext"; + +export default function ProtectedRoute({ children }) { + const { user, authLoading } = useAuth(); + if (authLoading) return null; // or a spinner + return user ? children : ; +} diff --git a/frontend/src/components/Sidebar.jsx b/frontend/src/components/Sidebar.jsx new file mode 100644 index 0000000000000000000000000000000000000000..5212e8af6f8ecfcb3dfb8d1fe69413d0302fef15 --- /dev/null +++ b/frontend/src/components/Sidebar.jsx @@ -0,0 +1,324 @@ +// src/components/Sidebar.jsx +import React, { useEffect, useRef, useState } from "react"; +import { NavLink } from "react-router-dom"; +import { + Activity, + AlertTriangle, + FileText, + Info, + Settings, + TrafficCone, + MonitorCog, + GitBranchMinus, + BrickWallShield, + ChevronLeft, + ChevronRight, + MoonStar, + LayoutDashboard, +} from "lucide-react"; + +/** + * Sidebar with mini-constellation canvas (B3) + * + * Props: + * - collapsed: boolean + * - setCollapsed: function + */ +export default function Sidebar({ collapsed, setCollapsed }) { + const sidebarRef = useRef(null); + const canvasRef = useRef(null); + const [time, setTime] = useState(""); + + // clock tick + useEffect(() => { + const tick = () => { + const now = new Date(); + setTime( + now.toLocaleTimeString("en-IN", { + hour12: true, + hour: "2-digit", + minute: "2-digit", + second: "2-digit", + }) + ); + }; + tick(); + const id = setInterval(tick, 1000); + return () => clearInterval(id); + }, []); + + // mini-constellation canvas (node+line) - optimized for sidebar + useEffect(() => { + const canvas = canvasRef.current; + const sidebar = sidebarRef.current; + if (!canvas || !sidebar) return; + + const ctx = canvas.getContext("2d", { alpha: true }); + let width = sidebar.clientWidth; + let height = sidebar.clientHeight; + let rafId = null; + let particles = []; + const COUNT = Math.max(18, Math.floor((width * height) / 10000)); // scale nodes by size + + // Resize handler + function resize() { + width = sidebar.clientWidth; + height = sidebar.clientHeight; + const dpr = Math.max(1, window.devicePixelRatio || 1); + canvas.width = Math.floor(width * dpr); + canvas.height = Math.floor(height * dpr); + canvas.style.width = `${width}px`; + canvas.style.height = `${height}px`; + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + // recreate particles to adapt density + initParticles(); + } + + function rand(min, max) { + return Math.random() * (max - min) + min; + } + + function initParticles() { + particles = []; + const n = COUNT; + for (let i = 0; i < n; i++) { + particles.push({ + x: rand(10, width - 10), + y: rand(10, height - 10), + vx: rand(-0.15, 0.15), + vy: rand(-0.15, 0.15), + size: rand(0.8, 2.2), + hue: rand(170, 200), // cyan-ish + }); + } + } + + function step() { + ctx.clearRect(0, 0, width, height); + + // draw lines between close particles + for (let i = 0; i < particles.length; i++) { + const a = particles[i]; + for (let j = i + 1; j < particles.length; j++) { + const b = particles[j]; + const dx = a.x - b.x; + const dy = a.y - b.y; + const dist = Math.sqrt(dx * dx + dy * dy); + const MAX = Math.min(120, Math.max(70, (width + height) / 15)); + if (dist < MAX) { + const alpha = 0.12 * (1 - dist / MAX); + ctx.beginPath(); + ctx.moveTo(a.x, a.y); + ctx.lineTo(b.x, b.y); + ctx.strokeStyle = `rgba(40,220,210, ${alpha.toFixed(3)})`; + ctx.lineWidth = 0.6; + ctx.stroke(); + } + } + } + + // draw nodes + for (let p of particles) { + // move + p.x += p.vx; + p.y += p.vy; + + // gentle wrap/bounce + if (p.x < -6) p.x = width + 6; + if (p.x > width + 6) p.x = -6; + if (p.y < -6) p.y = height + 6; + if (p.y > height + 6) p.y = -6; + + // glow circle + ctx.beginPath(); + const grad = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, p.size * 6); + grad.addColorStop(0, `rgba(0,230,255,0.95)`); + grad.addColorStop(0.2, `rgba(0,230,255,0.55)`); + grad.addColorStop(1, `rgba(0,230,255,0.02)`); + ctx.fillStyle = grad; + ctx.arc(p.x, p.y, p.size * 3.2, 0, Math.PI * 2); + ctx.fill(); + + // center bright dot + ctx.beginPath(); + ctx.fillStyle = `rgba(220,255,255,0.95)`; + ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); + ctx.fill(); + } + + rafId = requestAnimationFrame(step); + } + + // ResizeObserver to respond to sidebar size changes (collapse/expand) + const ro = new ResizeObserver(resize); + ro.observe(sidebar); + + resize(); + step(); // start animation + + return () => { + if (rafId) cancelAnimationFrame(rafId); + ro.disconnect(); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [sidebarRef, canvasRef, collapsed]); + + // navigation items + const navItems = [ + { to: "/", label: "Dashboard", icon: }, + { to: "/livetraffic", label: "Live Traffic", icon: }, + { to: "/threats", label: "Threat Intelligence", icon: }, + { to: "/alerts", label: "Alerts", icon: }, + { to: "/incidents", label: "Offline Detection", icon: }, + { to: "/traffic", label: "Traffic Analysis", icon: }, + { to: "/response", label: "Response System", icon: }, + { to: "/mlmodels", label: "ML Model", icon: }, + { to: "/reports", label: "Reports", icon: }, + { to: "/system", label: "System Info", icon: }, + { to: "/settings", label: "Settings", icon: }, + ]; + + return ( + + ); +} + diff --git a/frontend/src/components/TopStatusBar.jsx b/frontend/src/components/TopStatusBar.jsx new file mode 100644 index 0000000000000000000000000000000000000000..45d42462649ff768bb2795f49878b9a52fe1942e --- /dev/null +++ b/frontend/src/components/TopStatusBar.jsx @@ -0,0 +1,13 @@ +// src/components/TopStatusBar.jsx +export default function TopStatusBar({ running, packetCount, iface, lastUpdate }) { + return ( +
+ + {running ? "🟢 Capturing Packets" : "🔴 Capture Stopped"} + + + Packets: {packetCount} | Interface: {iface || "auto"} | Updated: {lastUpdate || "—"} + +
+ ); +} diff --git a/frontend/src/components/dashboard/Controls.jsx b/frontend/src/components/dashboard/Controls.jsx new file mode 100644 index 0000000000000000000000000000000000000000..ef74ec023a81f0320545f7c050da1f39cd625e38 --- /dev/null +++ b/frontend/src/components/dashboard/Controls.jsx @@ -0,0 +1,55 @@ +import React, { useContext, useState, useEffect } from "react"; +import { LiveDataContext } from "../../context/DataContext"; +import { startSniffer, stopSniffer, getStatus } from "../../api"; + +export default function Controls() { + const { running, setRunning } = useContext(LiveDataContext); + const [loading, setLoading] = useState(false); + + useEffect(() => { + (async () => { + const res = await getStatus(); + setRunning(res?.running || false); + })(); + }, []); + + const handleStart = async () => { + setLoading(true); + // 🔥 RESET BUFFER on START + window.__EVENT_BUFFER_RESET = true; + + await startSniffer(); + setRunning(true); + setLoading(false); + }; + + const handleStop = async () => { + setLoading(true); + await stopSniffer(); + setRunning(false); + setLoading(false); + }; + + return ( +
+ + +
+ ); +} diff --git a/frontend/src/components/dashboard/LiveDashboard.jsx b/frontend/src/components/dashboard/LiveDashboard.jsx new file mode 100644 index 0000000000000000000000000000000000000000..7e80917f35292ca4af8989d65e4f55df991bd23c --- /dev/null +++ b/frontend/src/components/dashboard/LiveDashboard.jsx @@ -0,0 +1,254 @@ +import React, { useEffect, useState, useContext, useRef } from "react"; +import Controls from "./Controls.jsx"; +import LiveTable from "./LiveTable.jsx"; +import ChatAssistant from "../../pages/ChatAssistant.jsx"; +import StatsPanel from "./StatsPanel.jsx"; +import { Download, Loader2, MessageSquare } from "lucide-react"; +import { socket } from "../../socket.js"; +import { + getRecent, + getStats, + download_logs, + switchModel, + getActiveModel, + getStatus +} from "../../api.js"; +import { AlertContext } from "../../context/AlertContext.jsx"; +import ThreatFeed from "./ThreatFeed"; +import ThreatTimeline from "./ThreatTimeline"; +import TopIPs from "./TopIPs"; +import TopCountries from "./TopCountries"; +import Sparkline from "./Sparkline"; + +export default function LiveDashboard() { + const [rows, setRows] = useState([]); + const [stats, setStats] = useState({}); + const [connected, setConnected] = useState(false); + const [lastUpdate, setLastUpdate] = useState(null); + const [threatCount, setThreatCount] = useState(0); + const { pushAlert } = useContext(AlertContext); + + const [model, setModel] = useState("bcc"); + const [snifferRunning, setSnifferRunning] = useState(false); + const [switching, setSwitching] = useState(false); + const [modelReady, setModelReady] = useState(false); + + const [tableKey, setTableKey] = useState(0); + const eventBufferRef = useRef([]); + + // ============================================================ + // INIT LOAD: Active model + sniffer status + // ============================================================ + useEffect(() => { + (async () => { + const res = await getActiveModel(); + if (res?.model) setModel(res.model); + + const st = await getStatus(); + setSnifferRunning(st?.running === true); + })(); + }, []); + + // ============================================================ + // MODEL SWITCH (backend + UI reset) + // ============================================================ + useEffect(() => { + const doSwitch = async () => { + setSwitching(true); + setModelReady(false); + + setRows([]); + setStats({}); + setThreatCount(0); + eventBufferRef.current = []; + setTableKey((k) => k + 1); + + const res = await switchModel(model); + + if (!res?.error) { + pushAlert(`${model.toUpperCase()} model activated`, "info"); + setModelReady(true); + } else { + pushAlert("Model switch failed!", "danger"); + } + + setSwitching(false); + }; + + doSwitch(); + }, [model]); + + // ============================================================ + // INITIAL FETCH (after model switch) + // ============================================================ + useEffect(() => { + if (!modelReady) return; + (async () => { + const [r1, r2] = await Promise.all([ + getRecent(model), + getStats(model) + ]); + + setRows(Array.isArray(r1?.events) ? r1.events : []); + setStats(r2 || {}); + })(); + }, [model, modelReady]); + + // ============================================================ + // SOCKET LIVE EVENTS + // ============================================================ + useEffect(() => { + socket.on("connect", () => setConnected(true)); + socket.on("disconnect", () => setConnected(false)); + + socket.on("new_event", (payload) => { + if (!modelReady || switching) return; + const events = payload?.items ?? []; + if (events.length) eventBufferRef.current.push(...events); + }); + + return () => { + socket.off("connect"); + socket.off("disconnect"); + socket.off("new_event"); + }; + }, [modelReady, switching]); + + // ============================================================ + // BUFFER TO UI processing + // ============================================================ + useEffect(() => { + const interval = setInterval(() => { + if (!modelReady) return; + if (!eventBufferRef.current.length) return; + + const batch = eventBufferRef.current.splice(0, 50); + + setRows((prev) => [...batch, ...prev].slice(0, 180)); + + setStats((prev) => { + const next = { ...prev }; + batch.forEach((evt) => { + const label = (evt.prediction || "UNKNOWN").toUpperCase(); + next[label] = (next[label] || 0) + 1; + }); + return next; + }); + + batch.forEach((evt) => { + const label = (evt.prediction || "").toUpperCase(); + const isThreat = (model === "bcc" && ["TOR","I2P","ZERONET"].includes(label)) || + (model === "cicids" && label !== "BENIGN"); + if (isThreat) setThreatCount((c) => c + 1); + }); + + setLastUpdate(new Date().toLocaleTimeString()); + }, 1200); + + return () => clearInterval(interval); + }, [model, modelReady]); + + // ============================================================ + // AI Assistant Handler (local popup) + // ============================================================ + const askAISummary = async () => { + const dangerous = rows.filter(evt => { + const label = (evt.prediction || "").toUpperCase(); + return (model === "bcc" && ["TOR","I2P","ZERONET"].includes(label)) || + (model === "cicids" && label !== "BENIGN"); + }); + + alert(`AI Summary: +Danger Events: ${dangerous.length} +Recent Threat Types: ${dangerous.slice(0, 5).map(e => e.prediction).join(", ")}`); + }; + + // ============================================================ + // RENDER UI + // ============================================================ + return ( +
+

+ Live Capture +

+ +
+ Active Model: {model.toUpperCase()} +
+ + {/* Model Toggle */} +
+ + + + + {/* 🧠 AI Button */} + +
+ + + + {/* Status + Logs */} +
+

+ {model === "bcc" ? "Realtime BCC Monitor" : "Realtime CICIDS Monitor"} +

+ + +
+ + + + + + + + + {/* VISUAL ANALYTICS BACK ADDED */} +
+ + + + + +
+ +

+ Last packet: {lastUpdate || "Waiting…"} +

+
+ ); +} + + diff --git a/frontend/src/components/dashboard/LiveTable.jsx b/frontend/src/components/dashboard/LiveTable.jsx new file mode 100644 index 0000000000000000000000000000000000000000..ca914b00e01b55985c7ef1a1b0110b4800c4686a --- /dev/null +++ b/frontend/src/components/dashboard/LiveTable.jsx @@ -0,0 +1,168 @@ +import React, { useState } from "react"; +import Badge from "../../ui/Badge"; +import { clearLogs, clearByPrediction, deleteOne } from "../../api"; +import { Trash } from "lucide-react"; +import IPInfoModal from "../IPInfoModal"; + +export default function LiveTable({ rows, refresh }) { + const [clearing, setClearing] = useState(false); + const [deleteCount, setDeleteCount] = useState(50); + const [selectedIP, setSelectedIP] = useState(null); + + + + // ✅ Safely clear last N rows + const handleClear = async (n) => { + try { + setClearing(true); + // 🔥 RESET BUFFER on CLEAR + window.__EVENT_BUFFER_RESET = true; + await clearLogs(n); + if (typeof refresh === "function") await refresh(); + } catch (err) { + console.error("Clear logs failed:", err); + } finally { + setTimeout(() => setClearing(false), 500); + } + }; + + // ✅ Clear logs by prediction type + const handleClearPrediction = async (pred) => { + if (!pred) return; + try { + await clearByPrediction(pred); + if (typeof refresh === "function") await refresh(); + } catch (err) { + console.error("Clear by prediction failed:", err); + } + }; + + // ✅ Delete a single row safely + const deleteSingleRow = async (index) => { + try { + await deleteOne(index); + if (typeof refresh === "function") await refresh(); + } catch (err) { + console.error("Delete single row failed:", err); + } + }; + + return ( +
+ {/* HEADER + ACTIONS */} +
+
+

Live Events

+ + Showing last {rows.length} packets + +
+ + {/* DELETE CONTROLS */} +
+ {/* DELETE BY PREDICTION */} + + + {/* CLEAR LAST N */} + + + {/* CLEAR ALL */} + +
+
+ + {/* TABLE */} +
+ + + + + + + + + + + + + {rows + .slice() + .reverse() + .map((r, idx) => ( + + + + + + + + ))} + +
TimeSrc → DstPortsProtoPrediction
{r.time} + setSelectedIP(r.src_ip || r.src)} + > + {r.src_ip || r.src} + {" "} + → + setSelectedIP(r.dst_ip || r.dst)} + > + {r.dst_ip || r.dst} + + + {r.sport} → {r.dport} + {r.proto} + + + deleteSingleRow(rows.length - 1 - idx) + } + /> +
+
+ + {/* ✅ IP Lookup Modal */} + {selectedIP && ( + setSelectedIP(null)} + /> + )} +
+ ); +} diff --git a/frontend/src/components/dashboard/Sparkline.jsx b/frontend/src/components/dashboard/Sparkline.jsx new file mode 100644 index 0000000000000000000000000000000000000000..83cc0fcaff1e1b08f68b2976ff252e079cba1720 --- /dev/null +++ b/frontend/src/components/dashboard/Sparkline.jsx @@ -0,0 +1,28 @@ +import { LineChart, Line, ResponsiveContainer } from "recharts"; + +export default function Sparkline({ events }) { + const data = events.slice(-40).map((e, i) => ({ + index: i, + value: (e.prediction || "").toUpperCase() !== "UNKNOWN" ? 1 : 0, + })); + + return ( +
+

Threat Activity Trend

+ +
+ + + + + +
+
+ ); +} diff --git a/frontend/src/components/dashboard/StatsPanel.jsx b/frontend/src/components/dashboard/StatsPanel.jsx new file mode 100644 index 0000000000000000000000000000000000000000..7e131237d4377224da92742da8f32bb0774ebb4e --- /dev/null +++ b/frontend/src/components/dashboard/StatsPanel.jsx @@ -0,0 +1,104 @@ +import React, { useMemo } from "react"; +import { + PieChart, + Pie, + Cell, + Tooltip, + ResponsiveContainer, + BarChart, + Bar, + XAxis, + YAxis, + CartesianGrid, +} from "recharts"; + +// 🎨 Neon cyber color palette +const COLORS = ["#00e5ff", "#ff0059", "#a78bfa", "#fbbf24", "#10b981"]; + +export default function StatsPanel({ stats }) { + // ✅ Memoized data transformation for performance + const data = useMemo(() => { + if (!stats || typeof stats !== "object") return []; + return Object.entries(stats) + .map(([name, value]) => ({ + name: String(name).toUpperCase(), + value: Number(value) || 0, + })) + .filter((d) => d.value > 0); + }, [stats]); + + const total = data.reduce((sum, d) => sum + d.value, 0); + + return ( +
+ {/* ==== PIE CHART ==== */} +
+

+ Class Distribution (Pie) +

+ +
+ {data.length > 0 ? ( + + + `${name}: ${value}`} + > + {data.map((entry, index) => ( + + ))} + + + + + ) : ( +
+ No Data Yet +
+ )} +
+ + {/* Total Packets Indicator */} +

+ Total Packets:{" "} + {total} +

+
+ + {/* ==== BAR CHART ==== */} +
+

+ Class Counts (Bar) +

+ +
+ {data.length > 0 ? ( + + + + + + + + + + ) : ( +
+ Awaiting Data... +
+ )} +
+
+
+ ); +} + diff --git a/frontend/src/components/dashboard/ThreatFeed.jsx b/frontend/src/components/dashboard/ThreatFeed.jsx new file mode 100644 index 0000000000000000000000000000000000000000..7e7c23d80b8b4494d9c943798d55830e3e7f0a36 --- /dev/null +++ b/frontend/src/components/dashboard/ThreatFeed.jsx @@ -0,0 +1,39 @@ +import { AlertTriangle } from "lucide-react"; + +export default function ThreatFeed({ events }) { + const highRisk = events + .filter((e) => + ["TOR", "I2P", "ZERONET"].includes((e.prediction || "").toUpperCase()) + ) + .slice(-20) + .reverse(); + + return ( +
+

+ High-Risk Events +

+ + {/* Scrollable list */} +
+ {highRisk.length === 0 ? ( +

No critical activity detected

+ ) : ( + highRisk.map((e, i) => ( +
+ {e.prediction} + from + {e.src_ip} +
+ )) + )} +
+
+ ); +} + diff --git a/frontend/src/components/dashboard/ThreatTimeline.jsx b/frontend/src/components/dashboard/ThreatTimeline.jsx new file mode 100644 index 0000000000000000000000000000000000000000..e182c3d16d6f9845e351f727e6e176c5863c3585 --- /dev/null +++ b/frontend/src/components/dashboard/ThreatTimeline.jsx @@ -0,0 +1,27 @@ +export default function ThreatTimeline({ events }) { + const last20 = [...events].slice(-20).reverse(); + + return ( +
+

Event Timeline

+ + {/* Scrollable container */} +
+ {last20.map((e, i) => ( +
+
+
+

+ {e.prediction}{" "} + detected from {e.src_ip} +

+

+ {new Date().toLocaleTimeString()} +

+
+
+ ))} +
+
+ ); +} diff --git a/frontend/src/components/dashboard/TopCountries.jsx b/frontend/src/components/dashboard/TopCountries.jsx new file mode 100644 index 0000000000000000000000000000000000000000..2546920996d9e808a1362b7084324420e2d66d08 --- /dev/null +++ b/frontend/src/components/dashboard/TopCountries.jsx @@ -0,0 +1,26 @@ +export default function TopCountries({ events }) { + const map = {}; + + events.forEach((e) => { + const c = e.src_country || "Unknown"; + map[c] = (map[c] || 0) + 1; + }); + + const sorted = Object.entries(map) + .sort((a, b) => b[1] - a[1]) + .slice(0, 6); + + return ( +
+

Top Source Countries

+
    + {sorted.map(([country, count], i) => ( +
  • + {country} + {count} +
  • + ))} +
+
+ ); +} diff --git a/frontend/src/components/dashboard/TopIPs.jsx b/frontend/src/components/dashboard/TopIPs.jsx new file mode 100644 index 0000000000000000000000000000000000000000..6b8a11d24d83120a1c4b32ebfb281c1314d3b4dd --- /dev/null +++ b/frontend/src/components/dashboard/TopIPs.jsx @@ -0,0 +1,26 @@ +export default function TopIPs({ events }) { + const map = {}; + + events.forEach((e) => { + const ip = e.src_ip || "Unknown"; + map[ip] = (map[ip] || 0) + 1; + }); + + const sorted = Object.entries(map) + .sort((a, b) => b[1] - a[1]) + .slice(0, 6); + + return ( +
+

Top Source IPs

+
    + {sorted.map(([ip, count], i) => ( +
  • + {ip} + {count} +
  • + ))} +
+
+ ); +} diff --git a/frontend/src/components/ui/accordion.jsx b/frontend/src/components/ui/accordion.jsx new file mode 100644 index 0000000000000000000000000000000000000000..a6bf4f3f8df50625e42cb7b132e06dd6504b7727 --- /dev/null +++ b/frontend/src/components/ui/accordion.jsx @@ -0,0 +1,43 @@ +"use client" + +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDown } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Accordion = AccordionPrimitive.Root + +const AccordionItem = React.forwardRef(({ className, ...props }, ref) => ( + +)) +AccordionItem.displayName = "AccordionItem" + +const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className + )} + {...props}> + {children} + + + +)) +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName + +const AccordionContent = React.forwardRef(({ className, children, ...props }, ref) => ( + +
{children}
+
+)) + +AccordionContent.displayName = AccordionPrimitive.Content.displayName + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/frontend/src/components/ui/badge.jsx b/frontend/src/components/ui/badge.jsx new file mode 100644 index 0000000000000000000000000000000000000000..deae51c4a2f714ccbc27a14d6c8b2f510f59bb15 --- /dev/null +++ b/frontend/src/components/ui/badge.jsx @@ -0,0 +1,34 @@ +import * as React from "react" +import { cva } from "class-variance-authority"; + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function Badge({ + className, + variant, + ...props +}) { + return (
); +} + +export { Badge, badgeVariants } diff --git a/frontend/src/components/ui/button.jsx b/frontend/src/components/ui/button.jsx new file mode 100644 index 0000000000000000000000000000000000000000..ce4184bf8f1367d9aca4c07d9e638043ee50ce0a --- /dev/null +++ b/frontend/src/components/ui/button.jsx @@ -0,0 +1,47 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva } from "class-variance-authority"; + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ); +}) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/frontend/src/components/ui/card.jsx b/frontend/src/components/ui/card.jsx new file mode 100644 index 0000000000000000000000000000000000000000..c0ede2efd087447ac0604cf82ba061f46e69012a --- /dev/null +++ b/frontend/src/components/ui/card.jsx @@ -0,0 +1,50 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Card = React.forwardRef(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef(({ className, ...props }, ref) => ( +
+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef(({ className, ...props }, ref) => ( +
+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef(({ className, ...props }, ref) => ( +
+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/frontend/src/components/ui/input.jsx b/frontend/src/components/ui/input.jsx new file mode 100644 index 0000000000000000000000000000000000000000..879e612dc6be68af99d5d17c0faf77d4e00918d6 --- /dev/null +++ b/frontend/src/components/ui/input.jsx @@ -0,0 +1,19 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Input = React.forwardRef(({ className, type, ...props }, ref) => { + return ( + + ); +}) +Input.displayName = "Input" + +export { Input } diff --git a/frontend/src/components/ui/scroll-area.jsx b/frontend/src/components/ui/scroll-area.jsx new file mode 100644 index 0000000000000000000000000000000000000000..dc3d3840ca9a57627ec2edcc938111a877c67761 --- /dev/null +++ b/frontend/src/components/ui/scroll-area.jsx @@ -0,0 +1,38 @@ +import * as React from "react" +import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area" + +import { cn } from "@/lib/utils" + +const ScrollArea = React.forwardRef(({ className, children, ...props }, ref) => ( + + + {children} + + + + +)) +ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName + +const ScrollBar = React.forwardRef(({ className, orientation = "vertical", ...props }, ref) => ( + + + +)) +ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName + +export { ScrollArea, ScrollBar } diff --git a/frontend/src/components/ui/separator.jsx b/frontend/src/components/ui/separator.jsx new file mode 100644 index 0000000000000000000000000000000000000000..c40b88839ea28b3755355e6a9841301315abf908 --- /dev/null +++ b/frontend/src/components/ui/separator.jsx @@ -0,0 +1,23 @@ +import * as React from "react" +import * as SeparatorPrimitive from "@radix-ui/react-separator" + +import { cn } from "@/lib/utils" + +const Separator = React.forwardRef(( + { className, orientation = "horizontal", decorative = true, ...props }, + ref +) => ( + +)) +Separator.displayName = SeparatorPrimitive.Root.displayName + +export { Separator } diff --git a/frontend/src/components/ui/switch.jsx b/frontend/src/components/ui/switch.jsx new file mode 100644 index 0000000000000000000000000000000000000000..e0b4e8e65d55179868f9e0265590b27dc680ba79 --- /dev/null +++ b/frontend/src/components/ui/switch.jsx @@ -0,0 +1,24 @@ +"use client" + +import * as React from "react" +import * as SwitchPrimitives from "@radix-ui/react-switch" + +import { cn } from "@/lib/utils" + +const Switch = React.forwardRef(({ className, ...props }, ref) => ( + + + +)) +Switch.displayName = SwitchPrimitives.Root.displayName + +export { Switch } diff --git a/frontend/src/components/ui/table.jsx b/frontend/src/components/ui/table.jsx new file mode 100644 index 0000000000000000000000000000000000000000..31b58edcad1e1684e5feff2089c5ff3ffc6f2f6b --- /dev/null +++ b/frontend/src/components/ui/table.jsx @@ -0,0 +1,83 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Table = React.forwardRef(({ className, ...props }, ref) => ( +
+ + +)) +Table.displayName = "Table" + +const TableHeader = React.forwardRef(({ className, ...props }, ref) => ( + +)) +TableHeader.displayName = "TableHeader" + +const TableBody = React.forwardRef(({ className, ...props }, ref) => ( + +)) +TableBody.displayName = "TableBody" + +const TableFooter = React.forwardRef(({ className, ...props }, ref) => ( + tr]:last:border-b-0", className)} + {...props} /> +)) +TableFooter.displayName = "TableFooter" + +const TableRow = React.forwardRef(({ className, ...props }, ref) => ( + +)) +TableRow.displayName = "TableRow" + +const TableHead = React.forwardRef(({ className, ...props }, ref) => ( +
+)) +TableHead.displayName = "TableHead" + +const TableCell = React.forwardRef(({ className, ...props }, ref) => ( + +)) +TableCell.displayName = "TableCell" + +const TableCaption = React.forwardRef(({ className, ...props }, ref) => ( +
+)) +TableCaption.displayName = "TableCaption" + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +} diff --git a/frontend/src/components/ui/tabs.jsx b/frontend/src/components/ui/tabs.jsx new file mode 100644 index 0000000000000000000000000000000000000000..baa34224cd6439ab57721f3184a48decd972f1bb --- /dev/null +++ b/frontend/src/components/ui/tabs.jsx @@ -0,0 +1,41 @@ +import * as React from "react" +import * as TabsPrimitive from "@radix-ui/react-tabs" + +import { cn } from "@/lib/utils" + +const Tabs = TabsPrimitive.Root + +const TabsList = React.forwardRef(({ className, ...props }, ref) => ( + +)) +TabsList.displayName = TabsPrimitive.List.displayName + +const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => ( + +)) +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName + +const TabsContent = React.forwardRef(({ className, ...props }, ref) => ( + +)) +TabsContent.displayName = TabsPrimitive.Content.displayName + +export { Tabs, TabsList, TabsTrigger, TabsContent } diff --git a/frontend/src/context/AlertContext.jsx b/frontend/src/context/AlertContext.jsx new file mode 100644 index 0000000000000000000000000000000000000000..4ebda8617c69b40efb1712edf1d2feed7a865fef --- /dev/null +++ b/frontend/src/context/AlertContext.jsx @@ -0,0 +1,36 @@ +import { createContext, useState, useRef } from "react"; + +export const AlertContext = createContext(); + +export function AlertProvider({ children }) { + const [alerts, setAlerts] = useState([]); + const lastAlertTime = useRef({}); // per-class cooldown + + const COOLDOWN = 8000; // 8 seconds per class + + const pushAlert = (msg, type = "info", key = "general") => { + const now = Date.now(); + + if (lastAlertTime.current[key] && now - lastAlertTime.current[key] < COOLDOWN) + return; // skip spam alerts + + lastAlertTime.current[key] = now; + + const id = now; + setAlerts(prev => [...prev, { id, msg, type }]); + + setTimeout(() => { + setAlerts(prev => prev.filter(a => a.id !== id)); + }, 5000); + }; + + const removeAlert = (id) => { + setAlerts(prev => prev.filter(a => a.id !== id)); + }; + + return ( + + {children} + + ); +} diff --git a/frontend/src/context/AuthContext.jsx b/frontend/src/context/AuthContext.jsx new file mode 100644 index 0000000000000000000000000000000000000000..dd1dbd46e6e7d6fdcedd3a0f7d71e5f8b02f4e99 --- /dev/null +++ b/frontend/src/context/AuthContext.jsx @@ -0,0 +1,158 @@ +// src/context/AuthContext.jsx +import React, { createContext, useContext, useEffect, useState } from "react"; +import { auth, db } from "../firebaseConfig"; +import { + createUserWithEmailAndPassword, + signInWithEmailAndPassword, + signOut, + onAuthStateChanged, + sendEmailVerification, + updateProfile, +} from "firebase/auth"; +import { + doc, + getDoc, + setDoc, + onSnapshot, + serverTimestamp, +} from "firebase/firestore"; +import toast from "react-hot-toast"; + +const AuthContext = createContext(); + +export function useAuth() { + return useContext(AuthContext); +} + +const defaultSettings = { + theme: "Cyber Blue", + autoRefresh: true, + soundAlerts: true, + aiSensitivity: 70, + responseMode: "Semi-Auto", + ipConfig: "127.0.0.1", + portConfig: "5000", +}; + +export function AuthProvider({ children }) { + const [user, setUser] = useState(null); + const [authLoading, setAuthLoading] = useState(true); + const [settings, setSettings] = useState(defaultSettings); + const [settingsUnsub, setSettingsUnsub] = useState(null); + + useEffect(() => { + const unsub = onAuthStateChanged(auth, async (u) => { + setAuthLoading(true); + if (u) { + setUser(u); + // load settings from Firestore + const docRef = doc(db, "users", u.uid); + const docSnap = await getDoc(docRef); + if (!docSnap.exists()) { + // create default settings for new user + await setDoc(docRef, { + settings: defaultSettings, + createdAt: serverTimestamp(), + }); + setSettings(defaultSettings); + } else { + const d = docSnap.data(); + setSettings(d.settings || defaultSettings); + } + // real-time listener — updates settings in UI when changed elsewhere + const unsubSettings = onSnapshot(docRef, (snap) => { + if (snap.exists()) { + const data = snap.data(); + if (data.settings) setSettings(data.settings); + } + }); + setSettingsUnsub(() => unsubSettings); + } else { + // user logged out + setUser(null); + setSettings(defaultSettings); + if (settingsUnsub) settingsUnsub(); + } + setAuthLoading(false); + }); + return () => unsub(); + // eslint-disable-next-line + }, []); + + // register + async function register(email, password, displayName) { + const creds = await createUserWithEmailAndPassword(auth, email, password); + // optional: set displayName + if (displayName) { + try { + await updateProfile(creds.user, { displayName }); + } catch (e) { + console.warn("Update profile failed:", e); + } + } + // send verification (optional) + try { + await sendEmailVerification(creds.user); + toast.success("Verification email sent (check inbox)."); + } catch {} + return creds.user; + } + + // login + async function login(email, password) { + const creds = await signInWithEmailAndPassword(auth, email, password); + return creds.user; + } + + // logout + async function logout() { + if (settingsUnsub) settingsUnsub(); + await signOut(auth); + } + + // Save settings to Firestore for current user + async function saveSettings(newSettings) { + if (!user) return; + const docRef = doc(db, "users", user.uid); + await setDoc(docRef, { settings: newSettings }, { merge: true }); + setSettings(newSettings); + toast.success("Settings synced to cloud"); + } + + const value = { + user, + authLoading, + settings, + setSettings, + saveSettings, + register, + login, + logout, + }; + + + // 🟢 Apply theme globally whenever settings.theme changes +useEffect(() => { + if (!settings?.theme) return; + + const body = document.body; + body.classList.remove("theme-cyber", "theme-crimson", "theme-emerald", "theme-default"); + + switch (settings.theme) { + case "Cyber Blue": + body.classList.add("theme-cyber"); + break; + case "Crimson Dark": + body.classList.add("theme-crimson"); + break; + case "Emerald Matrix": + body.classList.add("theme-emerald"); + break; + default: + body.classList.add("theme-default"); + } +}, [settings.theme]); + + + return {children}; +} diff --git a/frontend/src/context/DataContext.jsx b/frontend/src/context/DataContext.jsx new file mode 100644 index 0000000000000000000000000000000000000000..8f2422a9be1e81a54ec17b8d5b8fb27371cf40f6 --- /dev/null +++ b/frontend/src/context/DataContext.jsx @@ -0,0 +1,65 @@ +import React, { createContext, useState, useEffect } from "react"; +import { getRecent, getStats } from "../api"; +import { socket } from "../socket"; + +export const LiveDataContext = createContext(); + +export function LiveDataProvider({ children }) { + const [rows, setRows] = useState([]); + const [stats, setStats] = useState({}); + const [threatCount, setThreatCount] = useState(0); + const [running, setRunning] = useState(false); + + // Load saved data + useEffect(() => { + const r = JSON.parse(localStorage.getItem("live_rows") || "[]"); + const s = JSON.parse(localStorage.getItem("live_stats") || "{}"); + if (r.length) setRows(r); + if (Object.keys(s).length) setStats(s); + }, []); + + // Fetch from backend on mount + useEffect(() => { + (async () => { + const [r1, r2] = await Promise.all([getRecent(), getStats()]); + setRows(r1?.events || []); + setStats(r2 || {}); + })(); + }, []); + + // Socket listener + useEffect(() => { + socket.on("new_event", (evt) => { + setRows((prev) => { + const updated = [...prev, evt]; + if (updated.length > 300) updated.shift(); + localStorage.setItem("live_rows", JSON.stringify(updated)); + return updated; + }); + setStats((prev) => { + const updated = { ...prev }; + const label = (evt.prediction || "UNKNOWN").toUpperCase(); + if (label !== "UNKNOWN") updated[label] = (updated[label] || 0) + 1; + localStorage.setItem("live_stats", JSON.stringify(updated)); + return updated; + }); + if (["TOR", "I2P", "ZERONET"].includes(evt.prediction?.toUpperCase())) + setThreatCount((c) => c + 1); + }); + return () => socket.off("new_event"); + }, []); + + return ( + + {children} + + ); +} diff --git a/frontend/src/data/attackSamples.js b/frontend/src/data/attackSamples.js new file mode 100644 index 0000000000000000000000000000000000000000..b39abdbfebaf376ac1530920a19c39fe88859dc3 --- /dev/null +++ b/frontend/src/data/attackSamples.js @@ -0,0 +1,56 @@ +// src/data/attackSamples.js +// Option A: arrays-only. Feature order MUST match CICIDS_FEATURES below. + +export const CICIDS_SAMPLES = { + "BENIGN": [ + 6, 80, 200000, 10, 8, 640, 512, 64, 64, 50000, 0, 0, 50000 + ], + "DoS attacks-Hulk": [ + 6, 80, 20000, 1500, 50, 900000, 2400, 600, 48, 100, 500, 0, 100 + ], + "DoS attacks-SlowHTTPTest": [ + 6, 80, 10000000, 5, 5, 200, 200, 40, 40, 1000000, 0, 0, 1000000 + ], + "DoS attacks-Slowloris": [ + 6, 80, 12000000, 3, 3, 150, 150, 50, 50, 2000000, 0, 0, 2000000 + ], + "DoS attacks-GoldenEye": [ + 6, 80, 500000, 400, 40, 24000, 3200, 60, 80, 10000, 100, 0, 10000 + ], + "Bot": [ + 6, 8080, 5000000, 20, 20, 1024, 1024, 51, 51, 200000, 1, 0, 200000 + ], + "Infilteration": [ + 6, 445, 20000000, 3, 1, 120, 40, 40, 40, 3000000, 0, 0, 3000000 + ], + "FTP-BruteForce": [ + 6, 21, 1000000, 6, 6, 300, 300, 50, 50, 100000, 0, 0, 100000 + ], + "SSH-Bruteforce": [ + 6, 22, 2000000, 8, 8, 560, 560, 70, 70, 300000, 0, 0, 300000 + ], + "DDOS attack-HOIC": [ + 6, 80, 20000, 500, 10, 300000, 600, 600, 60, 200, 200, 0, 200 + ], + "DDOS attack-LOIC-UDP": [ + 17, 80, 10000, 200, 0, 14000, 0, 70, 0, 500, 0, 0, 500 + ], + "Brute Force -Web": [ + 6, 80, 8000000, 2, 2, 150, 150, 75, 75, 1000000, 0, 0, 1000000 + ], + "Brute Force -XSS": [ + 6, 80, 5000000, 2, 2, 120, 120, 60, 60, 2000000, 0, 0, 2000000 + ], + "SQL Injection": [ + 6, 80, 15000000, 3, 3, 200, 200, 66, 66, 3000000, 0, 0, 3000000 + ] +}; + +export const BCC_SAMPLES = { + "BENIGN": [6, 52344, 443, 0.18, 8, 6, 24, 1200, 60, 1200/0.18, 0.02, 0, 1, 0, 1], + "VPN": [17, 52100, 1194, 30, 400, 380, 0, 1400, 28, (1400*400)/30, 0.075, 0, 0, 0, 0], + "TOR": [6, 52321, 9001, 12, 200, 195, 24, 512, 40, (512*200)/12, 0.06, 0, 1, 0, 0], + "I2P": [6, 40000, 7656, 40, 500, 500, 24, 256, 40, (256*500)/40, 0.04, 0, 1, 0, 0], + "FREENET": [6, 52000, 8888, 8, 60, 58, 24, 400, 40, (400*60)/8, 0.12, 0, 1, 0, 1], + "ZERONET": [6, 51000, 8888, 3, 10, 9, 24, 300, 40, (300*10)/3, 0.3, 0, 1, 0, 1] +}; \ No newline at end of file diff --git a/frontend/src/data/featureInfo.js b/frontend/src/data/featureInfo.js new file mode 100644 index 0000000000000000000000000000000000000000..79a95785e936399306324c7524d37c8c12735db0 --- /dev/null +++ b/frontend/src/data/featureInfo.js @@ -0,0 +1,35 @@ +// src/data/featureInfo.js + +export const FEATURE_INFO = { + // CICIDS features + "Protocol": "Transport layer protocol. 6 = TCP, 17 = UDP.", + "Dst Port": "Destination port number of the network flow.", + "Flow Duration": "Total duration of the flow in seconds.", + "Tot Fwd Pkts": "Total number of packets sent forward.", + "Tot Bwd Pkts": "Total number of packets sent backward.", + "TotLen Fwd Pkts": "Total bytes sent forward.", + "TotLen Bwd Pkts": "Total bytes sent backward.", + "Fwd Pkt Len Mean": "Mean length of forward packets.", + "Bwd Pkt Len Mean": "Mean length of backward packets.", + "Flow IAT Mean": "Mean inter-arrival time between packets.", + "Fwd PSH Flags": "Number of TCP PUSH flags (PSH).", + "Fwd URG Flags": "Number of TCP URG flags (urgent).", + "Fwd IAT Mean": "Mean inter-arrival time of forward packets.", + + // BCC features + "proto": "Network protocol. 6 = TCP, 17 = UDP.", + "src_port": "Source port of the traffic flow.", + "dst_port": "Destination port of the traffic flow.", + "flow_duration": "Duration of the observed flow.", + "total_fwd_pkts": "Packets flowed forward.", + "total_bwd_pkts": "Packets flowed backward.", + "flags_numeric": "TCP flag combination encoded numerically.", + "payload_len": "Payload bytes in flow.", + "header_len": "Header bytes in flow.", + "rate": "Data throughput rate (bytes/sec).", + "iat": "Inter-arrival time between packets.", + "syn": "Count of SYN flags.", + "ack": "Count of ACK flags.", + "rst": "Count of RST flags.", + "fin": "Count of FIN flags." +}; diff --git a/frontend/src/firebaseConfig.js b/frontend/src/firebaseConfig.js new file mode 100644 index 0000000000000000000000000000000000000000..7d16f5da51816a8cb14a5f0588416a66248322e7 --- /dev/null +++ b/frontend/src/firebaseConfig.js @@ -0,0 +1,34 @@ +// ✅ src/firebaseConfig.js + +// Import the Firebase SDK modules you need +import { initializeApp } from "firebase/app"; +import { + getAuth, + setPersistence, + browserLocalPersistence +} from "firebase/auth"; +import { getFirestore } from "firebase/firestore"; + +// ✅ Replace these values with your Firebase project config +const firebaseConfig = { + apiKey: "AIzaSyB5koj8scMrv1v_hyl3wPLKouuZI3dWA6g", + authDomain: "network-intrusion-detect-ce914.firebaseapp.com", + projectId: "network-intrusion-detect-ce914", + storageBucket: "network-intrusion-detect-ce914.firebasestorage.app", + messagingSenderId: "1078562682443", + appId: "1:1078562682443:web:80869f04cbdce16616bfce", +}; + +// ✅ Initialize the Firebase app +const app = initializeApp(firebaseConfig); + +// ✅ Initialize Auth & Firestore +const auth = getAuth(app); +setPersistence(auth, browserLocalPersistence); // keeps login after refresh + +const db = getFirestore(app); + +// ✅ Export them +export { app, auth, db }; + + diff --git a/frontend/src/index.css b/frontend/src/index.css new file mode 100644 index 0000000000000000000000000000000000000000..e41ac38ca22ab0e8c75686d4ba5f3422eff726cc --- /dev/null +++ b/frontend/src/index.css @@ -0,0 +1,499 @@ +/* ------------------------- + LIGHT THEME VARIABLES +------------------------- */ +:root { + --bg: #f8fafc; + --text: #0f172a; + --card: #ffffff; + --accent: #2563eb; +} + +/* ------------------------- + DARK THEME VARIABLES +------------------------- */ +.dark { + --bg: #0a0f1c; + --text: #e2e8f0; + --card: #0f172a; + --accent: #00e5ff; +} + +/* Smooth transitions */ +body { + transition: background-color 0.3s ease, color 0.3s ease; +} + +@tailwind base; +@tailwind components; +@tailwind utilities; + + +:root { + color-scheme: light; +} +.dark { + color-scheme: dark; +} + + + +body { + background-color: var(--bg); + color: var(--text); + min-height: 100vh; + background-image: radial-gradient(ellipse at top left, rgba(0,229,255,.05), transparent 40%), + radial-gradient(ellipse at bottom right, rgba(167,139,250,.05), transparent 40%); + transition: background-color 0.3s ease, color 0.3s ease; +} + + + +.cyber-card { + background-color: var(--card); + @apply backdrop-blur rounded-2xl p-4 shadow-neon border border-cyan-400/10; +} + + +.neon-text { text-shadow: 0 0 8px rgba(0,229,255,.55); } + +.tooltip { + backdrop-filter: blur(6px); + background: rgba(15, 23, 42, 0.6); + color: white; + box-shadow: 0 0 10px rgba(0, 229, 255, 0.3); + border: 1px solid rgba(0, 229, 255, 0.3); + border-radius: 10px; + padding: 10px 14px; + font-size: 0.9rem; + z-index: 50; +} + + +@keyframes glowPulse { + 0%, 100% { + box-shadow: 0 0 8px rgba(0, 229, 255, 0.3); + } + 50% { + box-shadow: 0 0 16px rgba(0, 229, 255, 0.6); + } +} + +.animate-glowPulse { + animation: glowPulse 3s infinite ease-in-out; +} + +.flow-wrap svg { background: linear-gradient(180deg, rgba(2,6,23,0.3), rgba(2,6,23,0.15)); border-radius: 6px; } +.flow-wrap rect { filter: drop-shadow(0 3px 12px rgba(0,0,0,0.6)); } + + +@keyframes gridMove { + 0% { background-position: 0 0, 0 0; } + 100% { background-position: 22px 22px, 22px 22px; } +} +.animate-grid { + animation: gridMove 8s linear infinite; +} +@keyframes fadeIn { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} +.animate-fadeIn { + animation: fadeIn 0.3s ease-out; +} + +@keyframes pulse-slow { + 0%, 100% { opacity: 0.6; } + 50% { opacity: 1; } +} +.animate-pulse-slow { + animation: pulse-slow 8s ease-in-out infinite; +} + +/* In index.css */ +canvas { + filter: drop-shadow(0 0 25px rgba(0, 229, 255, 0.3)); + position: fixed; /* Do NOT override Tailwind */ + inset: 0; + z-index: -1; + pointer-events: none; +} + + +/* 🌈 THEME VARIANTS */ +.theme-cyber { + --bg: #010b14; + --text: #aeeaff; + --card: rgba(0, 15, 30, 0.7); + --accent: #00e5ff; +} + +.theme-crimson { + --bg: #100006; + --text: #ffccd5; + --card: rgba(20, 0, 10, 0.7); + --accent: #ff0044; +} + +.theme-emerald { + --bg: #00150c; + --text: #b0ffd6; + --card: rgba(0, 30, 15, 0.7); + --accent: #00ff99; +} + +.theme-default { + --bg: #0a0a0a; + --text: #dddddd; + --card: rgba(25, 25, 25, 0.6); + --accent: #8888ff; +} + +/* 🎨 Base Styles Using Variables */ +body { + background-color: var(--bg); + color: var(--text); + transition: background-color 0.4s ease, color 0.4s ease; +} + +.card-glow { + background-color: var(--card); + border: 1px solid var(--accent); + box-shadow: 0 0 20px color-mix(in srgb, var(--accent) 25%, transparent); + transition: all 0.3s ease; +} + +.text-accent { + color: var(--accent); +} + +.border-accent { + border-color: var(--accent); +} + +.bg-accent { + background-color: color-mix(in srgb, var(--accent) 15%, transparent); +} + +/* ---------- HERO + GLASS LAYER STYLES ---------- */ +.hero-wrapper { + position: relative; + overflow: visible; +} + +.hero-bg-layer { + position: absolute; + inset: 0; + height: 360px; + pointer-events: none; + z-index: 0; + background: radial-gradient(800px 200px at 10% 10%, rgba(0,229,255,0.06), transparent), + radial-gradient(600px 200px at 90% 30%, rgba(167,139,250,0.05), transparent), + linear-gradient(180deg, rgba(2,6,23,0.8), transparent 60%); + filter: blur(40px); +} + +/* hero inner panel / right artwork */ +.hero-panel { + background: linear-gradient(180deg, rgba(5,10,18,0.65), rgba(6,8,20,0.35)); + border-radius: 1rem; + box-shadow: 0 10px 40px rgba(2,6,23,0.6), inset 0 1px 0 rgba(255,255,255,0.02); + border: 1px solid rgba(0,229,255,0.12); +} + +/* 3D floating cubes */ +.cube-1, .cube-2, .cube-3 { + border-radius: 10%; + background: linear-gradient(135deg, rgba(139,92,246,0.25), rgba(0,229,255,0.12)); + box-shadow: 0 16px 48px rgba(2,6,23,0.8), 0 2px 8px rgba(0,229,255,0.06); + transform: rotateY(12deg) rotateX(8deg); +} + +/* simple block 3d elements used inside hero-panel */ +.block-3d { + background: linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.01)); + border-radius: 0.6rem; + border: 1px solid rgba(0,229,255,0.12); + box-shadow: 0 10px 30px rgba(2,6,23,0.65), 0 0 30px rgba(0,229,255,0.06); + backdrop-filter: blur(6px); +} + +/* glass shell that holds the dashboard section under the hero */ +.glass-shell { + background: linear-gradient(180deg, rgba(2,6,23,0.6), rgba(2,6,23,0.35)); + border-radius: 1.2rem; + box-shadow: 0 30px 60px rgba(2,6,23,0.6), 0 4px 18px rgba(0,229,255,0.03); + border: 1px solid rgba(0,229,255,0.06); + backdrop-filter: blur(8px); +} + +/* neon text and small tweaks */ +.hero-text .neon-text { + text-shadow: 0 0 12px rgba(0,229,255,0.6); +} + +.hero-inner .hero-art { min-height: 320px; } + +/* responsive spacing */ +@media (max-width: 768px) { + .hero-inner { padding-top: 6rem; padding-bottom: 3rem; } + .hero-panel { height: 240px; } +} + +/* a little floating animation for cubes */ +.cube-1 { animation: floaty 7s ease-in-out infinite; opacity: 0.9; } +.cube-2 { animation: floaty 8s ease-in-out infinite; opacity: 0.85; } +.cube-3 { animation: floaty 6s ease-in-out infinite; opacity: 0.8; } + +@keyframes floaty { + 0% { transform: translateY(0) rotate(6deg); } + 50% { transform: translateY(-8px) rotate(4deg); } + 100% { transform: translateY(0) rotate(6deg); } +} + +/* ensure hero sits above background glow */ +.hero-wrapper { z-index: 10; } + + +/* Hologram floating blocks */ +.block-holo { + background: linear-gradient( + 135deg, + rgba(139, 92, 246, 0.28), + rgba(0, 229, 255, 0.22) + ); + box-shadow: + 0 18px 50px rgba(2, 6, 23, 0.8), + 0 0 40px rgba(0, 229, 255, 0.18), + inset 0 0 20px rgba(255, 255, 255, 0.08); + animation: holoFloat 6s ease-in-out infinite; + filter: saturate(140%); +} + +@keyframes holoFloat { + 0% { transform: translateY(0px) rotate(6deg); } + 50% { transform: translateY(-10px) rotate(3deg); } + 100% { transform: translateY(0px) rotate(6deg); } +} + +/* Stacked 3D tiles */ +.tile-3d { + background: linear-gradient( + 160deg, + rgba(255, 255, 255, 0.04), + rgba(0, 229, 255, 0.05) + ); + border: 1px solid rgba(0, 229, 255, 0.2); + backdrop-filter: blur(8px); + border-radius: 0.85rem; + box-shadow: + 0 14px 35px rgba(2, 6, 23, 0.5), + 0 0 25px rgba(0,229,255,0.09); + transform: perspective(800px) rotateX(25deg); +} + + +.hero-panel { + backdrop-filter: blur(12px); + border-radius: 24px; +} + + +.topbar-button { + backdrop-filter: blur(6px); + box-shadow: 0 0 20px rgba(0,229,255,0.15); + transition: all 0.2s ease; +} + +.topbar-button:hover { + box-shadow: 0 0 25px rgba(0,229,255,0.3); + transform: translateY(-2px); +} + + +@keyframes waveMove { + 0% { transform: translateX(0); } + 100% { transform: translateX(-50%); } +} + +.neon-wave { + width: 200%; + height: 60px; + background: repeating-linear-gradient( + 90deg, + rgba(0,229,255,0.8) 0px, + rgba(0,229,255,0.8) 2px, + transparent 2px, + transparent 6px + ); + mask-image: url("data:image/svg+xml;utf8,"); + mask-size: 200% 100%; + mask-repeat: repeat-x; + animation: waveMove 4s linear infinite; + opacity: 0.7; +} + + +@keyframes spin-slow { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.animate-spin-slow { + animation: spin-slow 18s linear infinite; +} + +@keyframes float-slow { + 0% { transform: translateY(0px) rotate(0deg); } + 50% { transform: translateY(-15px) rotate(3deg); } + 100% { transform: translateY(0px) rotate(0deg); } +} + +.animate-float-slow { + animation: float-slow 6s ease-in-out infinite; +} + + +@keyframes drift { + 0% { + transform: translate(0px, 0px); + } + 50% { + transform: translate(15px, -10px); + } + 100% { + transform: translate(0px, 0px); + } +} + +.drift-slow { + animation: drift 10s ease-in-out infinite; +} + + +/* Neon Scrollbar */ +.custom-scroll::-webkit-scrollbar { + width: 6px; +} + +.custom-scroll::-webkit-scrollbar-track { + background: rgba(0, 229, 255, 0.05); + border-radius: 10px; +} + +.custom-scroll::-webkit-scrollbar-thumb { + background: rgba(0, 229, 255, 0.4); + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 229, 255, 0.6); +} + +.custom-scroll::-webkit-scrollbar-thumb:hover { + background: rgba(0, 229, 255, 0.7); +} + +/* Show thinner scrollbar in Firefox and set thumb color */ +.custom-scroll { + scrollbar-width: thin; + scrollbar-color: rgba(0,229,255,0.4) rgba(0,229,255,0.05); + -ms-overflow-style: auto; +} + +/* Scroll fade overlays to hint at scrollable content */ +.scroll-fade-top { + background: linear-gradient(180deg, rgba(2,6,23,0.85), transparent 60%); +} +.scroll-fade-bottom { + background: linear-gradient(0deg, rgba(2,6,23,0.85), transparent 60%); +} + +/* Floating buttons styling */ +.floating-controls { + box-shadow: 0 10px 30px rgba(0, 229, 255, 0.08), 0 6px 12px rgba(2,6,23,0.6); + border: 1px solid rgba(0,229,255,0.08); +} + +/* Larger neon action buttons */ +.neon-btn { + background: linear-gradient(90deg, rgba(0,229,255,0.06), rgba(139,92,246,0.04)); + border: 1px solid rgba(0,229,255,0.18); + box-shadow: 0 8px 30px rgba(0,229,255,0.08), inset 0 1px 0 rgba(255,255,255,0.02); +} +.neon-btn:hover { + box-shadow: 0 12px 40px rgba(0,229,255,0.14), inset 0 1px 0 rgba(255,255,255,0.02); +} + +.danger-btn { + background: linear-gradient(90deg, rgba(255,80,80,0.12), rgba(255,80,80,0.06)); + border: 1px solid rgba(255,80,80,0.18); + box-shadow: 0 8px 30px rgba(255,80,80,0.06); +} +.danger-btn:hover { box-shadow: 0 12px 40px rgba(255,80,80,0.12); } + +/* Tab accent glow for active state */ +.tab-active-glow { + box-shadow: 0 6px 22px rgba(0,229,255,0.12); +} + +/* Slightly glow scrollbar thumb for non-webkit fallbacks using scrollbar-color */ +html { scrollbar-color: rgba(0,229,255,0.45) rgba(0,0,0,0.15); } + + + +@layer base { + .shadcn{ + + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + --radius: 0.5rem; + } + shadcn.dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 212.7 26.8% 83.9%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } +} + + + diff --git a/frontend/src/layouts/MainLayout.jsx b/frontend/src/layouts/MainLayout.jsx new file mode 100644 index 0000000000000000000000000000000000000000..b2b6e7fe65b7042511f9e5151da58f52f61d45bf --- /dev/null +++ b/frontend/src/layouts/MainLayout.jsx @@ -0,0 +1,23 @@ +// src/layouts/MainLayout.jsx +import Sidebar from "../components/Sidebar"; + +export default function MainLayout({ children }) { + return ( +
+ + {/* Sidebar (glass) */} + + + {/* Main content should NOT override background */} +
+ {children} +
+ + {/* Transparent background carrier */} +
+
+ ); +} diff --git a/frontend/src/lib/utils.js b/frontend/src/lib/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..b20bf017182a344cc7cd55ce40eb2e19752a42df --- /dev/null +++ b/frontend/src/lib/utils.js @@ -0,0 +1,6 @@ +import { clsx } from "clsx"; +import { twMerge } from "tailwind-merge" + +export function cn(...inputs) { + return twMerge(clsx(inputs)); +} diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx new file mode 100644 index 0000000000000000000000000000000000000000..9c47f2d99065bf66eb96428f3bbdd181a97fa20d --- /dev/null +++ b/frontend/src/main.jsx @@ -0,0 +1,20 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.jsx"; +import "./index.css"; +import { ThemeProvider } from "./theme.jsx"; // ✅ ADD THIS +import { AlertProvider } from "./context/AlertContext.jsx"; +import { applySavedTheme } from "./themeManager"; + +applySavedTheme(); + + +ReactDOM.createRoot(document.getElementById("root")).render( + + {/* ✅ WRAP APP */} + {/* ✅ WRAP APP */} + + + + +); diff --git a/frontend/src/pages/ChatAssistant.jsx b/frontend/src/pages/ChatAssistant.jsx new file mode 100644 index 0000000000000000000000000000000000000000..3883808b8bcf363f60a59abab6d4c0d3a7ac80dd --- /dev/null +++ b/frontend/src/pages/ChatAssistant.jsx @@ -0,0 +1,265 @@ +import React, { useState, useEffect, useRef } from "react"; +import { MessageCircle, X, Sparkles } from "lucide-react"; +import { BASE_URL } from "../api.js"; + +// Display name for the model (shown in header) +const CHAT_MODEL_LABEL = "Llama-3.1-8B-Instant (Groq)"; + +export default function ChatAssistant() { + const [isOpen, setIsOpen] = useState(false); + const [messages, setMessages] = useState([ + { + role: "assistant", + content: + "Hello, I’m your NIDS assistant. Ask me about threats, logs, models, or anything security-related! ⚡", + }, + ]); + const [input, setInput] = useState(""); + const [loading, setLoading] = useState(false); + const [errorText, setErrorText] = useState(""); + + const messagesEndRef = useRef(null); + const bootAudioRef = useRef(null); + + // -------- Boot sound when opening ---------- + useEffect(() => { + if (isOpen) { + // lazy init audio + if (!bootAudioRef.current) { + bootAudioRef.current = new Audio("../../ai_bootup.mp3"); + } + try { + bootAudioRef.current.currentTime = 0; + bootAudioRef.current.play(); + } catch (e) { + // ignore autoplay errors + console.warn("Boot sound blocked by browser:", e); + } + } + }, [isOpen]); + + // -------- Auto-scroll to latest message ---------- + useEffect(() => { + if (messagesEndRef.current) { + messagesEndRef.current.scrollIntoView({ behavior: "smooth" }); + } + }, [messages, loading]); + + // -------- Send message to backend ---------- + const handleSend = async () => { + const trimmed = input.trim(); + if (!trimmed || loading) return; + + setErrorText(""); + setLoading(true); + + const userMessage = { role: "user", content: trimmed }; + setMessages((prev) => [...prev, userMessage]); + setInput(""); + + try { + const res = await fetch(`${BASE_URL}/api/chat`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ message: trimmed }), + }); + + if (!res.ok) { + const txt = await res.text(); + throw new Error(`HTTP ${res.status}: ${txt}`); + } + + const data = await res.json(); + const replyText = + typeof data.reply === "string" + ? data.reply + : "I received your message, but the reply format was unexpected."; + + setMessages((prev) => [ + ...prev, + { role: "assistant", content: replyText }, + ]); + } catch (err) { + console.error("Chat error:", err); + setErrorText("AI is unreachable right now. Please try again in a bit."); + setMessages((prev) => [ + ...prev, + { + role: "assistant", + content: + "Sorry, I couldn't reach the AI backend. Check your internet / API key and try again.", + }, + ]); + } finally { + setLoading(false); + } + }; + + const handleKeyDown = (e) => { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + handleSend(); + } + }; + + // -------- Small helper for message bubble style ---------- + const bubbleClass = (role) => + role === "user" + ? "bg-cyan-500/20 border border-cyan-400/40 self-end" + : "bg-slate-800/80 border border-slate-600/60 self-start"; + + const textClass = (role) => + role === "user" ? "text-cyan-100" : "text-slate-100"; + + return ( + <> + {/* Floating Jarvis orb button */} + + + {/* Overlay */} + {isOpen && ( +
+ {/* Chat panel */} +
+ {/* Header */} +
+
+ {/* Jarvis orb avatar */} +
+
+ +
+
+
+
+ + NIDS AI Assistant + + + Model:{" "} + {CHAT_MODEL_LABEL} + +
+
+ + +
+ + {/* Messages area */} +
+ {/* Bootup caption */} +

+ System online · You can ask things like{" "} + + “Explain this alert” or “Summarize current threats” + +

+ + {messages.map((m, idx) => ( +
+
+

{m.content}

+
+
+ ))} + + {/* Typing indicator */} + {loading && ( +
+
+ + + +
+
+ )} + +
+
+ + {/* Error text */} + {errorText && ( +
+ {errorText} +
+ )} + + {/* Input area */} +
+
{ + e.preventDefault(); + handleSend(); + }} + > +