"description":"AS adjacency graph derived from consecutive AS pairs in observed AS_PATHs. Reads the mv_as_adjacency materialized view (full RIB, refreshed hourly by pg_cron) so panels load instantly. Edge label = how many times that adjacency appears. Raise 'Min occurrences' to thin the graph; set 'Focus AS' for a 1-hop view around one AS.",
"description":"Each node is an AS (enriched from info_asn whois data); each edge is an adjacency seen in the AS_PATH data. Edge label is the occurrence count.",
"rawSql":"WITH edges AS (\n SELECT asn_a, asn_b, occ FROM mv_as_adjacency\n WHERE occ >= $min_occ\n AND ('$focus_as' = '' OR asn_a::text = '$focus_as' OR asn_b::text = '$focus_as')\n ORDER BY occ DESC LIMIT 300\n),\nnlist AS (SELECT asn_a AS asn FROM edges UNION SELECT asn_b FROM edges),\ndeg AS (SELECT asn, COUNT(*) AS d FROM (SELECT asn_a AS asn FROM edges UNION ALL SELECT asn_b FROM edges) z GROUP BY asn)\nSELECT n.asn::text AS id,\n COALESCE(NULLIF(ia.as_name,''),'AS'||n.asn) AS title,\n 'AS ' || n.asn AS mainstat,\n COALESCE(NULLIF(ia.country,''),'?') || ' · ' || dg.d::text || ' links' AS secondarystat,\n COALESCE(NULLIF(ia.org_name,''),'—') AS detail__org,\n COALESCE(NULLIF(ia.country,''),'—') AS detail__country,\n dg.d::text AS detail__degree\nFROM nlist n\nLEFT JOIN info_asn ia ON ia.asn = n.asn\nLEFT JOIN deg dg ON dg.asn = n.asn\nORDER BY dg.d DESC",
"rawSql":"SELECT asn_a::text || '-' || asn_b::text AS id,\n asn_a::text AS source, asn_b::text AS target,\n occ AS mainstat,\n occ::text || ' paths' AS detail__occurrences\nFROM mv_as_adjacency\nWHERE occ >= $min_occ\n AND ('$focus_as' = '' OR asn_a::text = '$focus_as' OR asn_b::text = '$focus_as')\nORDER BY occ DESC LIMIT 300",
"rawSql":"SELECT e.asn_a AS \"AS A\",\n COALESCE(NULLIF(ax.as_name,''),'—') AS \"Name A\",\n e.asn_b AS \"AS B\",\n COALESCE(NULLIF(ay.as_name,''),'—') AS \"Name B\",\n e.occ AS \"Occurrences\"\nFROM (\n SELECT asn_a, asn_b, occ FROM mv_as_adjacency\n WHERE occ >= $min_occ\n AND ('$focus_as' = '' OR asn_a::text = '$focus_as' OR asn_b::text = '$focus_as')\n ORDER BY occ DESC LIMIT 300\n) e\nLEFT JOIN info_asn ax ON ax.asn = e.asn_a\nLEFT JOIN info_asn ay ON ay.asn = e.asn_b\nORDER BY e.occ DESC",
{"name":"min_occ","type":"custom","label":"Min occurrences","description":"Only draw adjacencies seen at least this many times across the RIB. Raise it to thin a cluttered graph.","query":"2000,5000,10000,50000","current":{"text":"2000","value":"2000"},"options":[{"text":"2000","value":"2000","selected":true},{"text":"5000","value":"5000","selected":false},{"text":"10000","value":"10000","selected":false},{"text":"50000","value":"50000","selected":false}],"hide":0},
{"name":"focus_as","type":"textbox","label":"Focus AS","description":"Optional. Enter an ASN to show only adjacencies touching that AS (1-hop view). Leave blank for the full graph.","query":"","current":{"text":"","value":""},"options":[{"text":"","value":"","selected":true}],"hide":0}