/* ============================================================ FLOWSHIELD — Wiki de herramientas Índice navegable de las fichas "¿Qué hace?" (data.js → eng.help), agrupadas por categoría de REDTEAM_TABS/DEVSECOPS_TABS. Reutiliza ToolCard (ui.jsx) y HelpDrawer (redteam.jsx) tal cual: sin duplicar render. ============================================================ */ const WIKI_CATEGORY_TABS = ['recon', 'vuln', 'exploit', 'utils', 'ad']; const WIKI_DEVSECOPS_TABS = ['code', 'deps', 'iac', 'containers', 'cloud']; function wikiToolList() { const seen = {}; const list = []; const addFromTabs = (tabs, ids) => { ids.forEach(tabId => { const tab = (tabs || []).find(t => t.id === tabId); if (!tab) return; (tab.sections || []).forEach(sec => (sec.tools || []).forEach(t => { if (seen[t.id]) return; const eng = window.redteamEngine(t.id); if (!eng.help) return; seen[t.id] = true; list.push(Object.assign({}, t, { category: tab.label, help: eng.help })); })); }); }; addFromTabs(window.REDTEAM_TABS, WIKI_CATEGORY_TABS); addFromTabs(window.DEVSECOPS_TABS, WIKI_DEVSECOPS_TABS); return list; } function Wiki() { const [q, setQ] = useStateL(''); const [cat, setCat] = useStateL('all'); const [active, setActive] = useStateL(null); const tools = wikiToolList(); const categories = []; tools.forEach(t => { if (categories.indexOf(t.category) === -1) categories.push(t.category); }); const ql = q.trim().toLowerCase(); const filtered = tools.filter(t => (cat === 'all' || t.category === cat) && (!ql || (t.name + ' ' + (t.help.what || '')).toLowerCase().includes(ql)) ); return (