{ "port": 3000, "apiKey": "your-secret-api-key-here", "retention": { "nodeDays": 7, "_comment": "Nodes not seen in this many days are moved to inactive_nodes table. Default 7." }, "https": { "cert": "/path/to/cert.pem", "key": "/path/to/key.pem" }, "branding": { "siteName": "MeshCore Analyzer", "tagline": "Real-time MeshCore LoRa mesh network analyzer", "logoUrl": null, "faviconUrl": null }, "theme": { "accent": "#4a9eff", "accentHover": "#6db3ff", "navBg": "#0f0f23", "navBg2": "#1a1a2e", "statusGreen": "#45644c", "statusYellow": "#b08b2d", "statusRed": "#b54a4a" }, "nodeColors": { "repeater": "#dc2626", "companion": "#2563eb", "room": "#16a34a", "sensor": "#d97706", "observer": "#8b5cf6" }, "home": { "heroTitle": "MeshCore Analyzer", "heroSubtitle": "Find your nodes to start monitoring them.", "steps": [ { "emoji": "πŸ“‘", "title": "Connect", "description": "Link your node to the mesh" }, { "emoji": "πŸ”", "title": "Monitor", "description": "Watch packets flow in real-time" }, { "emoji": "πŸ“Š", "title": "Analyze", "description": "Understand your network's health" } ], "checklist": [ { "question": "How do I add my node?", "answer": "Search for your node name or paste your public key." }, { "question": "What regions are covered?", "answer": "Check the map page to see active observers and nodes." } ], "footerLinks": [ { "label": "πŸ“¦ Packets", "url": "#/packets" }, { "label": "πŸ—ΊοΈ Network Map", "url": "#/map" }, { "label": "πŸ”΄ Live", "url": "#/live" }, { "label": "πŸ“‘ All Nodes", "url": "#/nodes" }, { "label": "πŸ’¬ Channels", "url": "#/channels" } ] }, "mqtt": { "broker": "mqtt://localhost:1883", "topic": "meshcore/+/+/packets" }, "mqttSources": [ { "name": "local", "broker": "mqtt://localhost:1883", "topics": [ "meshcore/+/+/packets", "meshcore/#" ] }, { "name": "lincomatic", "broker": "mqtts://mqtt.lincomatic.com:8883", "username": "your-username", "password": "your-password", "rejectUnauthorized": false, "topics": [ "meshcore/SJC/#", "meshcore/SFO/#", "meshcore/OAK/#", "meshcore/MRY/#" ], "iataFilter": [ "SJC", "SFO", "OAK", "MRY" ] } ], "channelKeys": { "public": "8b3387e9c5cdea6ac9e5edbaa115cd72" }, "hashChannels": [ "#LongFast", "#test", "#sf", "#wardrive", "#yo", "#bot", "#queer", "#bookclub", "#shtf" ], "defaultRegion": "SJC", "mapDefaults": { "center": [ 37.45, -122.0 ], "zoom": 9 }, "regions": { "SJC": "San Jose, US", "SFO": "San Francisco, US", "OAK": "Oakland, US", "MRY": "Monterey, US" }, "cacheTTL": { "stats": 10, "nodeDetail": 300, "nodeHealth": 300, "nodeList": 90, "bulkHealth": 600, "networkStatus": 600, "observers": 300, "channels": 15, "channelMessages": 10, "analyticsRF": 1800, "analyticsTopology": 1800, "analyticsChannels": 1800, "analyticsHashSizes": 3600, "analyticsSubpaths": 3600, "analyticsSubpathDetail": 3600, "nodeAnalytics": 60, "nodeSearch": 10, "invalidationDebounce": 30, "_comment": "All values in seconds. Server uses these directly. Client fetches via /api/config/cache." }, "liveMap": { "propagationBufferMs": 5000, "_comment": "How long (ms) to buffer incoming observations of the same packet before animating. Mesh packets propagate through multiple paths and arrive at different observers over several seconds. This window collects all observations of a single transmission so the live map can animate them simultaneously as one realistic propagation event. Set higher for wide meshes with many observers, lower for snappier animations. 5000ms captures ~95% of observations for a typical mesh." }, "packetStore": { "maxMemoryMB": 1024, "estimatedPacketBytes": 450, "_comment": "In-memory packet store. maxMemoryMB caps RAM usage. All packets loaded on startup, served from RAM." } }