Skip to content

UI

Three files under static/:

File Content
socrates.html HTML shell
static/socrates.css All styles
static/socrates.js All JavaScript

socrates.html loads the CSS and JS via <link> and <script src> tags. D3 and d3-sankey are vendored in static/ for offline use.

UI States

Welcome Screen (no analysis loaded)
  ├── URL input + file upload
  └── Previous analyses list

Analysis View (analysis loaded)
  ├── Header (back button, name, path, date range)
  ├── Visualizations bar (Diagram toggle, Aggregation toggle)
  ├── Filter Bar (active search and filters as removable chips)
  ├── Stats Grid (clickable event-type cards, shows filtered/total counts when active)
  ├── Sankey Diagram (diagram mode — Source IP → Dest IP → Dest Port, reflects current filters)
  ├── Aggregations (frequency counts per column)
  └── Data Sections (tabbed tables)

JavaScript Architecture

Global state:

let allEvents = [];          // Loaded for "All Events" tab
let eventTypes = [];         // available types for current analysis
let currentMd5 = '';         // current analysis MD5
let currentFileName = '';    // display name
let currentFilters = {};     // {columnName: value} — global, flat
let currentSearch = [];      // server-side full-text search terms (array)
let baseEventStats = {};     // unfiltered totals for stats card denominator
let advancedMode = false;    // advanced toggle state
let tabDataCache = {};       // cached event data per type

Key function groups:

Group Functions Purpose
Navigation showWelcome(), loadAnalysis(), showTab(), showWelcomeUI(), showAnalysisUI() Screen/tab switching
Data Loading loadTabData(), loadFromUrl(), uploadPcap(), checkStatus() Fetch data from API
Rendering buildStats(), buildSections(), buildSection(), buildAllEvents(), buildRowForEvent(), updateSankeyDiagram() Build HTML
Aggregation buildAggregationTablesCore(), buildAggregationTables(), buildAggregationTablesAll(), buildAggregationsSection(), buildAggregationsSectionAll() Frequency grids
Search performSearch(), clearSearchTerm(), refreshAnalysisData() Full-text search via server
Filtering applyFilter(), applyFilters(), clearFilter(), clearAllFilters(), getFilteredEvents(), getSankeyEvents(), refreshCurrentView() Column filter management
Streams downloadPcap(), loadAsciiTranscript(), loadHexdumpData(), switchStreamView(), togglePacket(), toggleRow() Stream analysis
Utilities escapeHtml(), formatEvent(), extractValue(), extractAllValue(), getColumnsForType(), clearAnalysisContainers() Helpers

Column System

Each event type has its own column set. The "All Events" view uses a unified column set.

Shared columns (all types): Time, Protocol, Source IP, Source Port, Dest IP, Dest Port

Per-type columns: e.g. Alert/Category/Severity (alerts), Query/Type (DNS), Method/Host/URL/Status (HTTP). Every event type on the Event Types page has its own set — 30+ types by now — defined in getColumnsForType() (static/socrates.js), which is the source of truth; this doc intentionally doesn't enumerate all of them; a full list here would just drift out of sync with every new protocol added (the same problem already found and fixed once in filtering.md's old "Column Overlap" table).

All-events columns: Type (event type), Detail (type-specific summary)

Filtering Design

Filters are globalcurrentFilters is a flat {columnName: value} object. When switching tabs, filters for columns that don't exist in the new view are silently skipped (the column lookup returns -1 and the filter is ignored).

See filtering.md for full details.