Add persistent onion key backup and restore, improve startup resilience, and flesh out the major site verticals with richer navigation, search coverage, and operator documentation. Made-with: Cursor
92 lines
2.3 KiB
TypeScript
92 lines
2.3 KiB
TypeScript
/** “Subreddits” for Void Aggregate — onion-style board names (rings). */
|
|
|
|
export type ForumRing = {
|
|
slug: string;
|
|
shortName: string;
|
|
title: string;
|
|
about: string;
|
|
/** Cosmetic — static for immersion */
|
|
members: number;
|
|
activeNow: number;
|
|
};
|
|
|
|
export const FORUM_RINGS: ForumRing[] = [
|
|
{
|
|
slug: "opsec",
|
|
shortName: "opsec",
|
|
title: "OPSEC & tradecraft",
|
|
about: "Burners, compartmentalization, Tor hardening, countersurveillance.",
|
|
members: 128_400,
|
|
activeNow: 2_847,
|
|
},
|
|
{
|
|
slug: "markets",
|
|
shortName: "markets",
|
|
title: "Markets & clearing",
|
|
about: "Venue stability, escrow policy, downtime watches, fee gossip.",
|
|
members: 96_200,
|
|
activeNow: 4_102,
|
|
},
|
|
{
|
|
slug: "crypto",
|
|
shortName: "chains",
|
|
title: "Settlement & chains",
|
|
about: "BTC / XMR coin control, feerates, mixers, address hygiene.",
|
|
members: 74_800,
|
|
activeNow: 1_903,
|
|
},
|
|
{
|
|
slug: "tech",
|
|
shortName: "exploit",
|
|
title: "Exploit & tooling",
|
|
about: "Research PoCs, lab setups — keep it legal in your jurisdiction.",
|
|
members: 52_100,
|
|
activeNow: 891,
|
|
},
|
|
{
|
|
slug: "reputation",
|
|
shortName: "vouch",
|
|
title: "Vouch & mirrors",
|
|
about: "PGP proofs, phishing reports, signed mirror threads.",
|
|
members: 61_300,
|
|
activeNow: 2_210,
|
|
},
|
|
{
|
|
slug: "lounge",
|
|
shortName: "lounge",
|
|
title: "Dead-drop lounge",
|
|
about: "Meta, moderation, chaos — off-topic.",
|
|
members: 204_000,
|
|
activeNow: 8_440,
|
|
},
|
|
];
|
|
|
|
const SLUG_SET = new Set(FORUM_RINGS.map((r) => r.slug));
|
|
|
|
export function getRing(slug: string): ForumRing | undefined {
|
|
return FORUM_RINGS.find((r) => r.slug === slug);
|
|
}
|
|
|
|
/** Legacy `category` strings from older saves → ring slug */
|
|
export function categoryToSlug(category: string | undefined): string {
|
|
const c = (category ?? "").trim();
|
|
const map: Record<string, string> = {
|
|
Security: "opsec",
|
|
Market: "markets",
|
|
Tech: "tech",
|
|
Crypto: "crypto",
|
|
"Off-topic": "lounge",
|
|
Reputation: "reputation",
|
|
All: "lounge",
|
|
};
|
|
const hit = map[c];
|
|
if (hit && SLUG_SET.has(hit)) return hit;
|
|
if (c && SLUG_SET.has(c.toLowerCase())) return c.toLowerCase();
|
|
return "lounge";
|
|
}
|
|
|
|
export function formatRingLabel(slug: string): string {
|
|
const r = getRing(slug);
|
|
return r ? `r/${r.shortName}` : `r/${slug}`;
|
|
}
|