684 lines
67 KiB
HTML
684 lines
67 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<link rel="icon" href="/favicon.ico" type="image/x-icon">
|
||
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png type="image/x-icon">
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>WEVAL Technology Radar</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,600;9..40,700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||
<style>
|
||
*{box-sizing:border-box;margin:0;padding:0}
|
||
:root{--bg:#ffffff;--card:#f8fafc;--border:#e2e8f0;--text:#1e293b;--dim:#64748b;--muted:#94a3b8;--dark:#cbd5e1;--green:#059669;--blue:#3B82F6;--yellow:#F59E0B;--purple:#A855F7}
|
||
html{scroll-behavior:smooth}
|
||
body{background:var(--bg);color:var(--text);font-family:'DM Sans','Segoe UI',sans-serif;min-height:100vh;-webkit-font-smoothing:antialiased}
|
||
::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:var(--bg)}::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}
|
||
.mono{font-family:'JetBrains Mono',monospace}
|
||
|
||
/* Animations */
|
||
@keyframes fadeUp{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}
|
||
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}@keyframes wevalPulse{0%,100%{r:5.5;opacity:.85}50%{r:7.5;opacity:1}}.blip-dot.weval-dot{animation:wevalPulse 2.5s ease-in-out infinite}
|
||
@keyframes shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}
|
||
@keyframes radarSweep{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
|
||
.fade-up{animation:fadeUp .5s ease-out forwards;opacity:0}
|
||
|
||
/* Layout */
|
||
.wrap{max-width:1200px;margin:0 auto;padding:40px 24px 0}
|
||
.glow-line{height:1px;background:linear-gradient(90deg,transparent,var(--green),var(--blue),transparent);animation:shimmer 3s linear infinite;background-size:200% 100%;margin-bottom:36px}
|
||
|
||
/* Radar Section */
|
||
.radar-section{display:flex;gap:40px;align-items:center;flex-wrap:wrap;margin-bottom:48px}
|
||
.radar-svg-wrap{flex:1 1 520px;min-width:300px;position:relative}
|
||
.radar-legend{flex:1 1 260px;min-width:240px}
|
||
.radar-svg{width:100%;max-width:560px;display:block;margin:0 auto}
|
||
.radar-sweep{transform-origin:280px 280px;animation:radarSweep 8s linear infinite;opacity:.08}
|
||
|
||
/* Blips */
|
||
.blip{cursor:pointer;transition:all .15s}
|
||
.blip:hover .blip-dot{r:8;opacity:1}
|
||
.blip:hover .blip-glow{opacity:.15}
|
||
.blip-label{pointer-events:none;opacity:0;transition:opacity .15s}
|
||
.blip:hover .blip-label{opacity:1}
|
||
|
||
/* Legend */
|
||
.legend-section{margin-bottom:28px}
|
||
.legend-title{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:1.5px;margin-bottom:12px}
|
||
.legend-row{display:flex;align-items:center;gap:10px;margin-bottom:10px;cursor:pointer;transition:opacity .2s}
|
||
.legend-row:hover{opacity:.8}
|
||
.legend-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
|
||
.legend-label{font-size:13px;color:#C8CAD4}
|
||
.legend-count{font-size:11px;color:var(--dark);margin-left:auto}
|
||
.ring-dot{width:10px;height:10px;border-radius:50%;border:2px solid;background:transparent;transition:background .2s}
|
||
.ring-dot.active{background:currentColor}
|
||
|
||
/* Stats box */
|
||
.stats-box{background:var(--card);border:1px solid var(--border);border-radius:10px;padding:16px}
|
||
.stats-row{display:flex;justify-content:space-between;margin-bottom:8px}
|
||
.stats-row:last-child{margin-bottom:0}
|
||
.stats-label{font-size:12px;color:var(--dim)}
|
||
.stats-val{font-size:16px;font-weight:700}
|
||
|
||
/* Language bar */
|
||
.lang-section{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:16px 20px;margin-bottom:28px}
|
||
.lang-bar{display:flex;gap:3px;height:8px;border-radius:4px;overflow:hidden;margin-bottom:10px}
|
||
.lang-segment{border-radius:2px;transition:flex .8s}
|
||
.lang-labels{display:flex;flex-wrap:wrap;gap:8px 20px}
|
||
.lang-item{display:flex;align-items:center;gap:6px;font-size:12px}
|
||
.lang-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
|
||
|
||
/* Filters */
|
||
.filter-row{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-bottom:24px}
|
||
.search-wrap{position:relative}
|
||
.search-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);opacity:.4}
|
||
.search-input{background:var(--card);border:1px solid var(--border);border-radius:8px;padding:10px 14px 10px 36px;color:var(--text);font-size:14px;font-family:inherit;width:320px;max-width:100%;outline:none;transition:border-color .2s}
|
||
.search-input:focus{border-color:var(--blue)}
|
||
.search-input::placeholder{color:var(--muted)}
|
||
.cat-btns{display:flex;gap:6px;flex-wrap:wrap;flex:1}
|
||
.cat-btn{padding:8px 16px;border-radius:8px;border:1px solid var(--border);background:transparent;color:#8B8FA3;cursor:pointer;font-size:13px;font-family:inherit;transition:all .2s;white-space:nowrap}
|
||
.cat-btn:hover{border-color:var(--blue);color:var(--text)}
|
||
.cat-btn.active{background:#1A1F35;border-color:var(--blue);color:#fff}
|
||
.result-count{font-size:13px;color:var(--muted);margin-bottom:16px}
|
||
|
||
/* Cards Grid */
|
||
.cards-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:14px;padding-bottom:60px}
|
||
.tool-card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:20px;cursor:pointer;transition:all .25s;position:relative;overflow:hidden}
|
||
.tool-card:hover{border-color:#2A3050;transform:translateY(-2px);box-shadow:0 8px 32px rgba(0,0,0,.4)}
|
||
.tool-card::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--sc),transparent);opacity:0;transition:opacity .25s}
|
||
.tool-card:hover::before{opacity:1}
|
||
.tool-card.weval-card{border-color:#14B8A6 !important}.tool-card.weval-card .card-name::after{content:" WEVAL";font-size:10px;color:#14B8A6;font-weight:500;margin-left:6px}
|
||
.tool-card.selected{box-shadow:0 0 20px color-mix(in srgb,var(--sc) 20%,transparent)}
|
||
.card-top{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:10px}
|
||
.card-name{font-size:17px;font-weight:600;color:#fff}
|
||
.card-logo{width:28px;height:28px;border-radius:6px;object-fit:contain;flex-shrink:0;background:rgba(255,255,255,.06);padding:2px}
|
||
.status-pill{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:20px;font-size:11px;font-weight:500;letter-spacing:.3px;text-transform:uppercase}
|
||
.status-dot{width:5px;height:5px;border-radius:50%}
|
||
.status-dot.pulse{animation:pulse 2s infinite}
|
||
.replaces-badge{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:4px;font-size:11px;background:rgba(245,158,11,.08);color:var(--yellow);border:1px solid rgba(245,158,11,.15)}
|
||
.card-stars{text-align:right;flex-shrink:0}
|
||
.card-stars-num{font-size:18px;font-weight:700;color:var(--yellow);line-height:1}
|
||
.card-stars-label{font-size:10px;color:var(--muted);margin-top:2px}
|
||
.card-desc{font-size:13px;color:#8B8FA3;line-height:1.5;margin-bottom:12px}
|
||
.card-footer{display:flex;justify-content:space-between;align-items:center}
|
||
.card-lang{display:inline-flex;align-items:center;gap:4px;font-size:11px;color:var(--dim)}
|
||
.card-license{font-size:11px;color:var(--dark)}
|
||
.card-arrow{opacity:.2;transition:opacity .2s}
|
||
.tool-card:hover .card-arrow{opacity:.6}
|
||
|
||
/* Header */
|
||
.header{display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:16px;margin-bottom:12px}
|
||
.logo-row{display:flex;align-items:center;gap:12px;margin-bottom:8px}
|
||
.logo{width:36px;height:36px;border-radius:8px;background:linear-gradient(135deg,var(--green),var(--blue));display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:700;color:var(--bg)}
|
||
.subtitle{color:var(--dim);font-size:15px;margin-top:8px;max-width:520px;line-height:1.5}
|
||
.lang-toggle{background:var(--card);border:1px solid var(--border);border-radius:6px;padding:4px 10px;color:#8B8FA3;font-size:12px;cursor:pointer;transition:all .2s}
|
||
.lang-toggle:hover{border-color:var(--blue);color:#fff}
|
||
h1{font-size:36px;font-weight:700;line-height:1.1;background:linear-gradient(135deg,#E8E9ED 40%,#8B8FA3);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
|
||
|
||
/* Footer */
|
||
.footer{text-align:center;padding:32px 0 48px;border-top:1px solid var(--border);margin-top:20px}
|
||
|
||
@media(max-width:768px){
|
||
.radar-section{flex-direction:column}
|
||
.search-input{width:100%}
|
||
.cards-grid{grid-template-columns:1fr}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="wrap" id="app">
|
||
<!-- Header -->
|
||
<div class="header fade-up" style="animation-delay:.1s">
|
||
<div>
|
||
<div class="logo-row">
|
||
<div class="logo">W</div>
|
||
<span class="mono" style="font-size:12px;color:var(--muted);letter-spacing:2px;text-transform:uppercase">Technology Radar</span>
|
||
</div>
|
||
<h1 id="title">Our Open Source Arsenal</h1>
|
||
<p class="subtitle" id="subtitle">The sovereign tools we deploy, recommend, and explore for our clients.</p>
|
||
</div>
|
||
<button class="lang-toggle mono" id="langBtn" onclick="toggleLang()">FR</button>
|
||
</div>
|
||
|
||
<div class="glow-line"></div>
|
||
|
||
<!-- ═══ RADAR + LEGEND ═══ -->
|
||
<div class="radar-section fade-up" style="animation-delay:.2s">
|
||
<div class="radar-svg-wrap">
|
||
<svg id="radarSvg" class="radar-svg" viewBox="0 0 560 560" xmlns="http://www.w3.org/2000/svg"></svg>
|
||
</div>
|
||
<div class="radar-legend" id="radarLegend"></div>
|
||
</div>
|
||
|
||
<!-- Language bar -->
|
||
<div class="lang-section fade-up" style="animation-delay:.3s">
|
||
<div class="mono" style="font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:1;margin-bottom:12px" id="langTitle">Primary Languages</div>
|
||
<div class="lang-bar" id="langBar"></div>
|
||
<div class="lang-labels" id="langLabels"></div>
|
||
</div>
|
||
|
||
<!-- Filters -->
|
||
<div class="filter-row fade-up" style="animation-delay:.4s">
|
||
<div class="search-wrap">
|
||
<svg class="search-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||
<input class="search-input" id="searchInput" placeholder="Search tool or product..." oninput="render()">
|
||
</div>
|
||
<div class="cat-btns" id="catBtns"></div>
|
||
</div>
|
||
|
||
<div class="result-count mono" id="resultCount"></div>
|
||
|
||
<!-- Cards -->
|
||
<div class="cards-grid" id="cardsGrid"></div>
|
||
|
||
<!-- Footer -->
|
||
<div class="footer">
|
||
<div class="mono" style="font-size:12px;color:var(--dark)" id="footerText">WEVAL Consulting · Casablanca · Digital Sovereignty · 2026</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
const QC = ["#84CC16","#F97316","#A855F7","#EF4444"];
|
||
const QUADRANTS = [
|
||
{id:"ai",label:"Sovereign AI",labelFr:"IA Souveraine"},
|
||
{id:"infra",label:"DevOps & Infra",labelFr:"DevOps & Infra"},
|
||
{id:"business",label:"Business & Data",labelFr:"Business & Data"},
|
||
{id:"tic",label:"Marketing & Security",labelFr:"Digital & Sécurité"}
|
||
];
|
||
const STATUSES = {
|
||
use:{label:"We Use",labelFr:"On utilise",color:"#00E5A0",ring:0},
|
||
recommend:{label:"We Recommend",labelFr:"On recommande",color:"#3B82F6",ring:1},
|
||
explore:{label:"Exploring",labelFr:"On explore",color:"#F59E0B",ring:2}
|
||
};
|
||
const CATEGORIES = [
|
||
{id:"all",label:"All",labelFr:"Tout",icon:"◈"},
|
||
{id:"ai",label:"Sovereign AI",labelFr:"IA Souveraine",icon:"🧠"},
|
||
{id:"email",label:"Marketing & Automation",labelFr:"Marketing & Automation",icon:"✉"},
|
||
{id:"devops",label:"DevOps & Infra",labelFr:"DevOps & Infra",icon:"⚙"},
|
||
{id:"business",label:"Business Apps",labelFr:"Apps Business",icon:"📊"},
|
||
{id:"security",label:"Security",labelFr:"Sécurité",icon:"🛡"},
|
||
{id:"data",label:"Data & Analytics",labelFr:"Data & Analytics",icon:"📈"}
|
||
];
|
||
const LC = {TypeScript:"#3178C6",Go:"#00ADD8",Python:"#3776AB",JavaScript:"#F7DF1E",PHP:"#777BB4",Rust:"#DEA584","C++":"#F34B7D",Ruby:"#CC342D",Clojure:"#63B132",Elixir:"#6E4A7E"};
|
||
|
||
const TOOLS = [
|
||
{name:"Ollama",cat:"ai",quad:"ai",status:"use",stars:120000,lang:"Go",license:"MIT",replaces:"OpenAI API",desc:"Local LLM inference — 51 models on GPU",descFr:"Inférence LLM locale — 51 modèles sur GPU",url:"https://github.com/ollama/ollama",seed:.2},
|
||
{name:"Open WebUI",cat:"ai",quad:"ai",status:"use",stars:126000,lang:"TypeScript",license:"MIT",replaces:"ChatGPT Enterprise",desc:"Self-hosted chat with RAG, RBAC, SSO",descFr:"Chat self-hosted avec RAG, RBAC, SSO",url:"https://github.com/open-webui/open-webui",seed:.7},
|
||
{name:"Dify",cat:"ai",quad:"ai",status:"explore",stars:131000,lang:"TypeScript",license:"Apache-2.0",replaces:"LangChain Cloud",desc:"Visual AI workflow builder + agents",descFr:"Builder workflows IA visuel + agents",url:"https://github.com/langgenius/dify",seed:.3},
|
||
{name:"SearXNG",cat:"ai",quad:"ai",status:"use",stars:16000,lang:"Python",license:"AGPL-3.0",replaces:"Google Custom Search",desc:"Privacy-first metasearch — 229+ sources",descFr:"Métamoteur privé — 229+ sources",url:"https://github.com/searxng/searxng",seed:.5},
|
||
{name:"Qdrant",cat:"ai",quad:"ai",status:"explore",stars:23000,lang:"Rust",license:"Apache-2.0",replaces:"Pinecone",desc:"Vector DB for RAG with hybrid search",descFr:"Base vectorielle RAG + recherche hybride",url:"https://github.com/qdrant/qdrant",seed:.6},
|
||
{name:"Langflow",cat:"ai",quad:"ai",status:"explore",stars:145000,lang:"Python",license:"MIT",replaces:"Flowise Cloud",desc:"Visual multi-agent AI framework",descFr:"Framework IA multi-agents visuel",url:"https://github.com/langflow-ai/langflow",seed:.8},
|
||
{name:"vLLM",cat:"ai",quad:"ai",status:"use",stars:42000,lang:"Python",license:"Apache-2.0",replaces:"TGI / Triton",desc:"High-throughput LLM serving",descFr:"Serving LLM haut débit",url:"https://github.com/vllm-project/vllm",seed:.35},
|
||
{name:"ComfyUI",cat:"ai",quad:"ai",status:"explore",stars:105000,lang:"Python",license:"GPL-3.0",replaces:"Midjourney / DALL-E",desc:"Node-based Stable Diffusion engine",descFr:"Moteur Stable Diffusion par nœuds",url:"https://github.com/comfyanonymous/ComfyUI",seed:.15},
|
||
{name:"Mautic",cat:"email",quad:"tic",status:"recommend",stars:9300,lang:"PHP",license:"GPL-3.0",replaces:"HubSpot / Marketo",desc:"Marketing automation — campaigns, scoring",descFr:"Automatisation marketing — campagnes, scoring",url:"https://github.com/mautic/mautic",seed:.4},
|
||
{name:"Postal",cat:"email",quad:"tic",status:"recommend",stars:15000,lang:"Ruby",license:"MIT",replaces:"SendGrid / Mailgun",desc:"Self-hosted mail delivery + tracking",descFr:"Livraison email self-hosted + tracking",url:"https://github.com/postalserver/postal",seed:.65},
|
||
{name:"Listmonk",cat:"email",quad:"tic",status:"recommend",stars:15000,lang:"Go",license:"AGPL-3.0",replaces:"Mailchimp",desc:"High-perf newsletter — millions on 512MB",descFr:"Newsletter haute perf — millions sur 512MB",url:"https://github.com/knadh/listmonk",seed:.2},
|
||
{name:"n8n",cat:"devops",quad:"infra",status:"recommend",stars:178000,lang:"TypeScript",license:"Sustainable Use",replaces:"Zapier / Make",desc:"Workflow automation — 400+ integrations",descFr:"Automatisation — 400+ intégrations",url:"https://github.com/n8n-io/n8n",seed:.3},
|
||
{name:"Uptime Kuma",cat:"devops",quad:"infra",status:"use",stars:84000,lang:"JavaScript",license:"MIT",replaces:"Pingdom / UptimeRobot",desc:"Monitoring — 90+ notification channels",descFr:"Monitoring — 90+ canaux de notification",url:"https://github.com/louislam/uptime-kuma",seed:.6},
|
||
{name:"Grafana",cat:"devops",quad:"infra",status:"recommend",stars:73000,lang:"TypeScript",license:"AGPL-3.0",replaces:"Datadog Dashboards",desc:"Observability — metrics, logs, traces",descFr:"Observabilité — métriques, logs, traces",url:"https://github.com/grafana/grafana",seed:.75},
|
||
{name:"Coolify",cat:"devops",quad:"infra",status:"explore",stars:40000,lang:"PHP",license:"Apache-2.0",replaces:"Heroku / Vercel",desc:"Self-hosted PaaS — git push deploy",descFr:"PaaS self-hosted — déploiement git push",url:"https://github.com/coollabsio/coolify",seed:.15},
|
||
{name:"Gitea",cat:"devops",quad:"infra",status:"recommend",stars:48000,lang:"Go",license:"MIT",replaces:"GitHub / GitLab",desc:"Lightweight self-hosted Git + CI/CD",descFr:"Git self-hosted léger + CI/CD",url:"https://github.com/go-gitea/gitea",seed:.45},
|
||
{name:"Traefik",cat:"devops",quad:"infra",status:"use",stars:53000,lang:"Go",license:"MIT",replaces:"NGINX Plus / AWS ALB",desc:"Cloud-native reverse proxy + auto SSL",descFr:"Reverse proxy cloud-native + SSL auto",url:"https://github.com/traefik/traefik",seed:.85},
|
||
{name:"frp",cat:"devops",quad:"infra",status:"explore",stars:105000,lang:"Go",license:"Apache-2.0",replaces:"ngrok / Cloudflare Tunnels",desc:"Fast reverse proxy for local servers",descFr:"Reverse proxy rapide pour serveurs locaux",url:"https://github.com/fatedier/frp",seed:.55},
|
||
{name:"ERPNext",cat:"business",quad:"business",status:"recommend",stars:32000,lang:"Python",license:"GPL-3.0",replaces:"SAP Business One",desc:"Full ERP — accounting, HR, CRM",descFr:"ERP complet — comptabilité, RH, CRM",url:"https://github.com/frappe/erpnext",seed:.3},
|
||
{name:"Twenty CRM",cat:"business",quad:"business",status:"explore",stars:28000,lang:"TypeScript",license:"AGPL-3.0",replaces:"Salesforce / HubSpot",desc:"Modern CRM — Notion-like UX + GraphQL",descFr:"CRM moderne — UX Notion + GraphQL",url:"https://github.com/twentyhq/twenty",seed:.6},
|
||
{name:"Plane",cat:"business",quad:"business",status:"explore",stars:38600,lang:"TypeScript",license:"AGPL-3.0",replaces:"Jira / Linear",desc:"Project mgmt — sprints, modules, AI",descFr:"Gestion projet — sprints, modules, IA",url:"https://github.com/makeplane/plane",seed:.15},
|
||
{name:"Outline",cat:"business",quad:"business",status:"recommend",stars:30000,lang:"TypeScript",license:"BSL-1.1",replaces:"Notion / Confluence",desc:"Collaborative wiki + real-time + SSO",descFr:"Wiki collaboratif + temps réel + SSO",url:"https://github.com/outline/outline",seed:.75},
|
||
{name:"Supabase",cat:"business",quad:"business",status:"recommend",stars:98700,lang:"TypeScript",license:"Apache-2.0",replaces:"Firebase",desc:"Open Firebase — Postgres, Auth, Realtime",descFr:"Firebase open — Postgres, Auth, Realtime",url:"https://github.com/supabase/supabase",seed:.45},
|
||
{name:"Wazuh",cat:"security",quad:"tic",status:"recommend",stars:12000,lang:"C++",license:"GPL-2.0",replaces:"Splunk / CrowdStrike",desc:"SIEM/XDR — FIM, vuln detection, compliance",descFr:"SIEM/XDR — FIM, détection vulns, conformité",url:"https://github.com/wazuh/wazuh",seed:.8},
|
||
{name:"CrowdSec",cat:"security",quad:"tic",status:"explore",stars:9000,lang:"Go",license:"MIT",replaces:"Fail2ban (next-gen)",desc:"Crowd threat intel — 60× faster",descFr:"Threat intel collaborative — 60× plus rapide",url:"https://github.com/crowdsecurity/crowdsec",seed:.5},
|
||
{name:"Authentik",cat:"security",quad:"tic",status:"recommend",stars:15000,lang:"Python",license:"Custom",replaces:"Auth0 / Okta",desc:"Identity provider — SSO, MFA, LDAP, SCIM",descFr:"IdP — SSO, MFA, LDAP, SCIM",url:"https://github.com/goauthentik/authentik",seed:.1},
|
||
{name:"Metabase",cat:"data",quad:"business",status:"recommend",stars:40000,lang:"Clojure",license:"AGPL-3.0",replaces:"Tableau / Power BI",desc:"BI dashboards + natural language queries",descFr:"Dashboards BI + requêtes langage naturel",url:"https://github.com/metabase/metabase",seed:.9},
|
||
{name:"Superset",cat:"data",quad:"business",status:"explore",stars:65000,lang:"Python",license:"Apache-2.0",replaces:"Looker / Tableau",desc:"Enterprise BI — 40+ charts, SQL Lab",descFr:"BI entreprise — 40+ graphes, SQL Lab",url:"https://github.com/apache/superset",seed:.5},
|
||
{name:"PostHog",cat:"data",quad:"business",status:"explore",stars:31000,lang:"TypeScript",license:"MIT",replaces:"Mixpanel / Amplitude",desc:"Product analytics + session replay + A/B",descFr:"Analytics produit + session replay + A/B",url:"https://github.com/PostHog/posthog",seed:.2},
|
||
{name:"Plausible",cat:"data",quad:"business",status:"recommend",stars:22000,lang:"Elixir",license:"AGPL-3.0",replaces:"Google Analytics",desc:"Privacy analytics — <1KB, no cookies",descFr:"Analytics privé — <1KB, zero cookies",url:"https://github.com/plausible/analytics",seed:.65}
|
||
];
|
||
|
||
// WEVAL SaaS (62 products)
|
||
[{name:"WEVADS",cat:"weval",quad:"tic",status:"use",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/wevads.html",seed:0.16,isWeval:true},
|
||
{name:"Wevads IA",cat:"weval",quad:"ai",status:"use",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/wevads-ia.html",seed:0.75,isWeval:true},
|
||
{name:"DeliverAds",cat:"weval",quad:"tic",status:"use",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/deliverads.html",seed:0.85,isWeval:true},
|
||
{name:"Wevanalytics",cat:"weval",quad:"business",status:"use",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/arsenal.html",seed:0.25,isWeval:true},
|
||
{name:"Digital Platform",cat:"weval",quad:"tic",status:"use",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/email-platform.html",seed:0.9,isWeval:true},
|
||
{name:"WEVIA Enterprise",cat:"weval",quad:"ai",status:"use",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/wevia-enterprise.html",seed:0.21,isWeval:true},
|
||
{name:"Sentinel",cat:"weval",quad:"tic",status:"use",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/sentinel.html",seed:0.85,isWeval:true},
|
||
{name:"Consulting",cat:"weval",quad:"business",status:"use",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/consulting.html",seed:0.3,isWeval:true},
|
||
{name:"Wevia Inference",cat:"weval",quad:"ai",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/gpu-inference.html",seed:0.88,isWeval:true},
|
||
{name:"Content Factory",cat:"weval",quad:"ai",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/content-factory.html",seed:0.19,isWeval:true},
|
||
{name:"IA Arabe FR",cat:"weval",quad:"ai",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/ia-arabe.html",seed:0.32,isWeval:true},
|
||
{name:"WEVIA Agency",cat:"weval",quad:"ai",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/wevia-agency.html",seed:0.19,isWeval:true},
|
||
{name:"Wevia WL",cat:"weval",quad:"ai",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/wevia-whitelabel.html",seed:0.52,isWeval:true},
|
||
{name:"MailWarm",cat:"weval",quad:"tic",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/mailwarm.html",seed:0.26,isWeval:true},
|
||
{name:"MailForge",cat:"weval",quad:"tic",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/mailforge.html",seed:0.17,isWeval:true},
|
||
{name:"OutreachAI",cat:"weval",quad:"tic",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/outreachai.html",seed:0.86,isWeval:true},
|
||
{name:"AI SDR Agent",cat:"weval",quad:"tic",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/ai-sdr.html",seed:0.83,isWeval:true},
|
||
{name:"DeliverScore",cat:"weval",quad:"tic",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/deliverscore.html",seed:0.85,isWeval:true},
|
||
{name:"Email WL",cat:"weval",quad:"tic",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/email-whitelabel.html",seed:0.34,isWeval:true},
|
||
{name:"AdsControl",cat:"weval",quad:"tic",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/adscontrol.html",seed:0.56,isWeval:true},
|
||
{name:"MailStream",cat:"weval",quad:"tic",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/mailstream.html",seed:0.31,isWeval:true},
|
||
{name:"MedReach",cat:"weval",quad:"business",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/medreach.html",seed:0.47,isWeval:true},
|
||
{name:"MedReach API",cat:"weval",quad:"business",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/medreach-api.html",seed:0.76,isWeval:true},
|
||
{name:"MedReach HCP",cat:"weval",quad:"business",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/medreachhcp.html",seed:0.15,isWeval:true},
|
||
{name:"LeadForge",cat:"weval",quad:"business",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/leadforge.html",seed:0.15,isWeval:true},
|
||
{name:"DataHarvest",cat:"weval",quad:"business",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/dataharvest.html",seed:0.54,isWeval:true},
|
||
{name:"Healthcare CRM",cat:"weval",quad:"business",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/healthcare-crm.html",seed:0.46,isWeval:true},
|
||
{name:"CloudBridge",cat:"weval",quad:"infra",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/cloud-providers.html",seed:0.14,isWeval:true},
|
||
{name:"Consulting Pro",cat:"weval",quad:"business",status:"recommend",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/consulting.html",seed:0.9,isWeval:true},
|
||
{name:"ProposalAI",cat:"weval",quad:"ai",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/proposalai.html",seed:0.91,isWeval:true},
|
||
{name:"BlueprintAI",cat:"weval",quad:"ai",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/blueprintai.html",seed:0.43,isWeval:true},
|
||
{name:"CanvasAI",cat:"weval",quad:"ai",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/canvasai.html",seed:0.51,isWeval:true},
|
||
{name:"CopyAI",cat:"weval",quad:"ai",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/copyai.html",seed:0.43,isWeval:true},
|
||
{name:"PresentationAI",cat:"weval",quad:"ai",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/presentationai.html",seed:0.7,isWeval:true},
|
||
{name:"TranslateAI",cat:"weval",quad:"ai",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/translateai.html",seed:0.39,isWeval:true},
|
||
{name:"Business Plan",cat:"weval",quad:"business",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/bizplan.html",seed:0.6,isWeval:true},
|
||
{name:"ContractAI",cat:"weval",quad:"business",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/contractai.html",seed:0.39,isWeval:true},
|
||
{name:"Meeting Summary",cat:"weval",quad:"business",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/meetingai.html",seed:0.78,isWeval:true},
|
||
{name:"eSignature",cat:"weval",quad:"business",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/esignature.html",seed:0.45,isWeval:true},
|
||
{name:"Lean Six Sigma",cat:"weval",quad:"business",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/leansixsigma.html",seed:0.79,isWeval:true},
|
||
{name:"Audit Compliance",cat:"weval",quad:"business",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/auditai.html",seed:0.39,isWeval:true},
|
||
{name:"DashboardAI",cat:"weval",quad:"business",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/dashboardai.html",seed:0.7,isWeval:true},
|
||
{name:"Academy",cat:"weval",quad:"business",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/academy.html",seed:0.36,isWeval:true},
|
||
{name:"Weval CRM",cat:"weval",quad:"business",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/wevalcrm.html",seed:0.67,isWeval:true},
|
||
{name:"Partner Program",cat:"weval",quad:"business",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/affiliates.html",seed:0.16,isWeval:true},
|
||
{name:"EmailVerify",cat:"weval",quad:"tic",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/emailverify.html",seed:0.69,isWeval:true},
|
||
{name:"InboxTest",cat:"weval",quad:"tic",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/inboxtest.html",seed:0.42,isWeval:true},
|
||
{name:"Network Monitor",cat:"weval",quad:"tic",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/ispmonitor.html",seed:0.19,isWeval:true},
|
||
{name:"NewsletterInsight",cat:"weval",quad:"tic",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/newsletterinsight.html",seed:0.29,isWeval:true},
|
||
{name:"NetworkGuard",cat:"weval",quad:"tic",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/blacklistguard.html",seed:0.3,isWeval:true},
|
||
{name:"SMSForge",cat:"weval",quad:"tic",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/smsforge.html",seed:0.45,isWeval:true},
|
||
{name:"ReputationAI",cat:"weval",quad:"tic",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/reputationai.html",seed:0.87,isWeval:true},
|
||
{name:"DevForge AI",cat:"weval",quad:"infra",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/devforge.html",seed:0.18,isWeval:true},
|
||
{name:"Wedroid",cat:"weval",quad:"infra",status:"use",stars:0,lang:"PHP",license:"Proprietary",replaces:"DevOps Agents",desc:"Autonomous DevOps AI agent — chain-of-thought, self-healing, 12 infra patterns, multi-server execution",descFr:"Agent IA DevOps autonome — chain-of-thought, self-healing, 12 patterns infra, exécution multi-serveur",url:"/products/wevalmind.html",seed:0.59,isWeval:true},
|
||
{name:"Creative Factory",cat:"weval",quad:"infra",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/creativefactory.html",seed:0.65,isWeval:true},
|
||
{name:"Scout Intelligence",cat:"weval",quad:"infra",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/scoutai.html",seed:0.12,isWeval:true},
|
||
{name:"YouTube Factory",cat:"weval",quad:"infra",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/youtubefactory.html",seed:0.64,isWeval:true},
|
||
{name:"StoreForge",cat:"weval",quad:"infra",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/storeforge.html",seed:0.12,isWeval:true},
|
||
{name:"FormBuilder",cat:"weval",quad:"infra",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/formbuilder.html",seed:0.87,isWeval:true},
|
||
{name:"StoreAI",cat:"weval",quad:"infra",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/storeai.html",seed:0.65,isWeval:true},
|
||
{name:"CloudCost",cat:"weval",quad:"infra",status:"explore",stars:0,lang:"PHP",license:"Proprietary",replaces:"WEVAL SaaS",desc:"WEVAL sovereign SaaS product",descFr:"Produit SaaS souverain WEVAL",url:"/products/cloudcost.html",seed:0.4,isWeval:true}].forEach(function(w){TOOLS.push(w)});
|
||
|
||
// Auto-discovered 2026-03-16 (10 tools)
|
||
[{name:"langchain",cat:"ai",quad:"ai",status:"use",stars:129624,lang:"Python",license:"MIT",replaces:"",desc:"The agent engineering platform",descFr:"The agent engineering platform",url:"https://github.com/langchain-ai/langchain",seed:0.3},{name:"open-webui",cat:"ai",quad:"ai",status:"use",stars:127333,lang:"Python",license:"NOASSERTION",replaces:"",desc:"User-friendly AI Interface (Supports Ollama, OpenAI API, ...)",descFr:"User-friendly AI Interface (Supports Ollama, OpenAI API, ...)",url:"https://github.com/open-webui/open-webui",seed:0.19},{name:"kubernetes",cat:"devops",quad:"infra",status:"use",stars:121168,lang:"Go",license:"Apache-2.0",replaces:"",desc:"Production-Grade Container Scheduling and Management",descFr:"Production-Grade Container Scheduling and Management",url:"https://github.com/kubernetes/kubernetes",seed:0.31},{name:"générative-ai-for-beginners",cat:"ai",quad:"ai",status:"use",stars:108065,lang:"Jupyter Notebook",license:"MIT",replaces:"",desc:"21 Lessons, Get Started Building with Générative AI ",descFr:"21 Lessons, Get Started Building with Générative AI ",url:"https://github.com/microsoft/générative-ai-for-beginners",seed:0.77},{name:"awesome-llm-apps",cat:"ai",quad:"ai",status:"use",stars:102253,lang:"Python",license:"Apache-2.0",replaces:"",desc:"Collection of awesome LLM apps with AI Agents and RAG using OpenAI, Anthropic, G",descFr:"Collection of awesome LLM apps with AI Agents and RAG using OpenAI, Anthropic, G",url:"https://github.com/Shubhamsaboo/awesome-llm-apps",seed:0.64},{name:"immich",cat:"devops",quad:"infra",status:"use",stars:94838,lang:"TypeScript",license:"AGPL-3.0",replaces:"",desc:"High performance self-hosted photo and video management solution.",descFr:"High performance self-hosted photo and video management solution.",url:"https://github.com/immich-app/immich",seed:0.92},{name:"firecrawl",cat:"ai",quad:"ai",status:"use",stars:93548,lang:"TypeScript",license:"AGPL-3.0",replaces:"",desc:"🔥 The Web Data API for AI - Turn entire websites into LLM-ready markdown or stru",descFr:"🔥 The Web Data API for AI - Turn entire websites into LLM-ready markdown or stru",url:"https://github.com/firecrawl/firecrawl",seed:0.31},{name:"uptime-kuma",cat:"devops",quad:"infra",status:"use",stars:84112,lang:"JavaScript",license:"MIT",replaces:"",desc:"A fancy self-hosted monitoring tool",descFr:"A fancy self-hosted monitoring tool",url:"https://github.com/louislam/uptime-kuma",seed:0.68},{name:"devops-exercises",cat:"devops",quad:"infra",status:"use",stars:81504,lang:"Python",license:"NOASSERTION",replaces:"",desc:"Linux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, ",descFr:"Linux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, ",url:"https://github.com/bregman-arie/devops-exercises",seed:0.59},{name:"browser-use",cat:"ai",quad:"ai",status:"use",stars:80872,lang:"Python",license:"MIT",replaces:"",desc:"🌐 Make websites accessible for AI agents. Automate tasks online with ease.",descFr:"🌐 Make websites accessible for AI agents. Automate tasks online with ease.",url:"https://github.com/browser-use/browser-use",seed:0.09}].forEach(function(w){TOOLS.push(w)});
|
||
const TOOL_LOGOS = {"AI SDR Agent": "/assets/logo-outreachai.svg", "Academy": "/assets/logo-academy.svg", "AdsControl": "/assets/logo-adscontrol.svg", "Audit Compliance": "/assets/logo-auditcompliance.svg", "Authentik": "https://github.com/goauthentik.png?size=40", "BlueprintAI": "/assets/logo-blueprintai.svg", "Business Plan": "/assets/logo-bizplan.svg", "CanvasAI": "/assets/logo-canvasai.svg", "CloudBridge": "/assets/logo-cloudbridge.svg", "CloudCost": "/assets/logo-cloudcost.svg", "ComfyUI": "https://github.com/comfyanonymous.png?size=40", "Consulting": "/assets/logo-consulting.svg", "Consulting Pro": "/assets/logo-consulting.svg", "Content Factory": "/assets/logo-content-factory.svg", "ContractAI": "/assets/logo-contractai.svg", "Coolify": "https://github.com/coollabsio.png?size=40", "CopyAI": "/assets/logo-copyai.svg", "Creative Factory": "/assets/logo-creative-factory.svg", "CrowdSec": "https://github.com/crowdsecurity.png?size=40", "DashboardAI": "/assets/logo-dashboardai.svg", "DataHarvest": "/assets/logo-dataharvest.svg", "DeliverAds": "/assets/logo-deliverads.svg", "DeliverScore": "/assets/logo-deliverscore.svg", "DevForge AI": "/assets/logo-devforge.svg", "Dify": "https://github.com/langgenius.png?size=40", "Digital Platform": "/assets/logo-wevads-Crayl4yz.png", "ERPNext": "https://github.com/frappe.png?size=40", "Email WL": "/assets/logo-mailforge.svg", "EmailVerify": "/assets/logo-emailverify.svg", "FormBuilder": "/assets/logo-formbuilder.svg", "Gitea": "https://github.com/go-gitea.png?size=40", "Grafana": "https://github.com/grafana.png?size=40", "Healthcare CRM": "/assets/logo-medreach.svg", "IA Arabe FR": "/assets/logo-wevia-official.svg", "InboxTest": "/assets/logo-inboxtest.svg", "Langflow": "https://github.com/langflow-ai.png?size=40", "LeadForge": "/assets/logo-leadforge.svg", "Lean Six Sigma": "/assets/logo-leansixsigma.svg", "Listmonk": "https://raw.githubusercontent.com/knadh/listmonk/master/static/public/static/logo.svg", "MailForge": "/assets/logo-mailforge.svg", "MailStream": "/assets/logo-mailstream.svg", "MailWarm": "/assets/logo-mailwarm.svg", "Mautic": "https://github.com/mautic.png?size=40", "MedReach": "/assets/logo-medreach.svg", "MedReach API": "/assets/logo-medreach.svg", "MedReach HCP": "/assets/logo-medreach.svg", "Meeting Summary": "/assets/logo-meeting-summary.svg", "Metabase": "https://github.com/metabase.png?size=40", "Network Monitor": "/assets/logo-ispmonitor.svg", "NetworkGuard": "/assets/logo-sentinel.svg", "NewsletterInsight": "/assets/logo-newsletter.svg", "Ollama": "https://github.com/ollama.png?size=40", "Open WebUI": "https://github.com/open-webui.png?size=40", "Outline": "https://github.com/outline.png?size=40", "OutreachAI": "/assets/logo-outreachai.svg", "Partner Program": "/assets/logo-affiliates.svg", "Plane": "https://github.com/makeplane.png?size=40", "Plausible": "https://github.com/plausible.png?size=40", "PostHog": "https://github.com/PostHog.png?size=40", "Postal": "https://github.com/postalserver.png?size=40", "PresentationAI": "/assets/logo-presentationai.svg", "ProposalAI": "/assets/logo-proposalai.svg", "Qdrant": "https://github.com/qdrant.png?size=40", "ReputationAI": "/assets/logo-reputationai.svg", "SMSForge": "/assets/logo-smsforge.svg", "Scout Intelligence": "/assets/logo-scout.svg", "SearXNG": "https://github.com/searxng.png?size=40", "Sentinel": "/assets/logo-sentinel.svg", "StoreAI": "/assets/logo-storeforge.svg", "StoreForge": "/assets/logo-storeforge.svg", "Supabase": "https://github.com/supabase.png?size=40", "Superset": "https://github.com/apache.png?size=40", "Traefik": "https://github.com/traefik.png?size=40", "TranslateAI": "/assets/logo-translateai.svg", "Twenty CRM": "https://github.com/twentyhq.png?size=40", "Uptime Kuma": "https://github.com/louislam.png?size=40", "WEVADS": "/assets/logo-wevads-Crayl4yz.png", "WEVAL Mind": "/assets/logo-weval-mind.svg", "WEVIA Agency": "/assets/logo-wevia-official.svg", "WEVIA Enterprise": "/assets/logo-wevia-official.svg", "Wazuh": "https://github.com/wazuh.png?size=40", "Wevads IA": "/assets/logo-wevads-Crayl4yz.png", "Weval CRM": "/assets/logo-weval-crm.svg", "Wevanalytics": "/assets/logo-wevanalytics.svg", "Wevia Inference": "/assets/logo-wevia-official.svg", "Wevia WL": "/assets/logo-wevia-official.svg", "YouTube Factory": "/assets/logo-youtube-factory.svg", "browser-use": "https://github.com/browser-use.png?size=40", "eSignature": "/assets/logo-esignature.svg", "firecrawl": "https://github.com/mendableai.png?size=40", "frp": "https://github.com/fatedier.png?size=40", "immich": "https://github.com/immich-app.png?size=40", "kubernetes": "https://github.com/kubernetes.png?size=40", "langchain": "https://github.com/langchain-ai.png?size=40", "n8n": "https://github.com/n8n-io.png?size=40", "vLLM": "https://github.com/vllm-project.png?size=40"};
|
||
TOOLS.sort(function(a,b){var q={ai:0,tic:1,business:2,infra:3};var s={use:0,recommend:1,explore:2};return (q[a.quad]||9)-(q[b.quad]||9)||(s[a.status]||9)-(s[b.status]||9)});
|
||
let lang = "en", activeCat = "all", activeStatus = null, hoveredBlip = null, selectedTool = null;
|
||
|
||
function t(en, fr) { return lang === "fr" ? fr : en; }
|
||
function fmtStars(n) { return n >= 100000 ? Math.round(n/1000)+"K" : n >= 1000 ? (n/1000).toFixed(1)+"K" : n; }
|
||
|
||
function toggleLang() {
|
||
lang = lang === "en" ? "fr" : "en";
|
||
document.getElementById("langBtn").textContent = lang === "en" ? "FR" : "EN";
|
||
document.getElementById("title").textContent = t("Our Open Source Arsenal", "Notre Arsenal Open Source");
|
||
document.getElementById("subtitle").textContent = t("The sovereign tools we deploy, recommend, and explore for our clients.", "Les outils souverains que nous déployons, recommandons et explorons.");
|
||
document.getElementById("langTitle").textContent = t("Primary Languages", "Langages principaux");
|
||
document.getElementById("searchInput").placeholder = t("Search tool or product...", "Rechercher outil ou produit...");
|
||
document.getElementById("footerText").textContent = "WEVAL Consulting · Casablanca · " + t("Digital Sovereignty", "Souveraineté numérique") + " · 2026";
|
||
buildRadar(); buildLegend(); buildCatBtns(); render();
|
||
}
|
||
|
||
// ═══════════════════════════════════
|
||
// RADAR SVG
|
||
// ═══════════════════════════════════
|
||
function buildRadar() {
|
||
const S = 560, cx = 280, cy = 280, maxR = 240;
|
||
const rings = [maxR*.32, maxR*.62, maxR*.90];
|
||
const ringLbls = [t("WE USE","ON UTILISE"), t("RECOMMEND","ON RECOMMANDE"), t("EXPLORE","ON EXPLORE")];
|
||
|
||
let svg = `<defs>
|
||
<radialGradient id="rg"><stop offset="0%" stop-color="#151722"/><stop offset="100%" stop-color="#0A0B0F"/></radialGradient>
|
||
<linearGradient id="sweep" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#00E5A0" stop-opacity=".3"/><stop offset="100%" stop-color="#00E5A0" stop-opacity="0"/></linearGradient>
|
||
</defs>`;
|
||
|
||
// Background
|
||
svg += `<circle cx="${cx}" cy="${cy}" r="${maxR+8}" fill="url(#rg)"/>`;
|
||
|
||
// Sweep line
|
||
svg += `<line x1="${cx}" y1="${cy}" x2="${cx}" y2="${cy-maxR}" stroke="url(#sweep)" stroke-width="2" class="radar-sweep"/>`;
|
||
|
||
// Rings
|
||
rings.forEach((r, i) => {
|
||
const dash = i === 2 ? ' stroke-dasharray="5 5"' : '';
|
||
svg += `<circle cx="${cx}" cy="${cy}" r="${r}" fill="none" stroke="#1C1F2E" stroke-width="1"${dash}/>`;
|
||
});
|
||
|
||
// Ring labels
|
||
ringLbls.forEach((lbl, i) => {
|
||
svg += `<text x="${cx+6}" y="${cy-rings[i]+14}" fill="#252840" font-size="7.5" font-family="'JetBrains Mono',monospace" letter-spacing="1.2">${lbl}</text>`;
|
||
});
|
||
|
||
// Axis lines
|
||
svg += `<line x1="${cx}" y1="${cy-maxR-4}" x2="${cx}" y2="${cy+maxR+4}" stroke="#1C1F2E" stroke-width=".8"/>`;
|
||
svg += `<line x1="${cx-maxR-4}" y1="${cy}" x2="${cx+maxR+4}" y2="${cy}" stroke="#1C1F2E" stroke-width=".8"/>`;
|
||
|
||
// Quadrant labels
|
||
QUADRANTS.forEach((q, i) => {
|
||
const a = i * Math.PI/2 - Math.PI/4;
|
||
const lr = maxR + 22;
|
||
const lx = cx + lr * Math.cos(a), ly = cy + lr * Math.sin(a);
|
||
const lbl = lang === "fr" ? q.labelFr : q.label;
|
||
svg += `<text x="${lx}" y="${ly}" fill="${QC[i]}" font-size="8.5" font-weight="600" text-anchor="middle" dominant-baseline="middle" font-family="'DM Sans',sans-serif" style="text-transform:uppercase;letter-spacing:1.5px">${lbl}</text>`;
|
||
});
|
||
|
||
// Center
|
||
svg += `<circle cx="${cx}" cy="${cy}" r="18" fill="#12141E" stroke="#1C1F2E" stroke-width="1"/>`;
|
||
svg += `<text x="${cx}" y="${cy+1}" fill="#00E5A0" font-size="12" font-weight="700" text-anchor="middle" dominant-baseline="middle" font-family="'DM Sans',sans-serif">W</text>`;
|
||
|
||
// Blips — Pass 1: compute positions
|
||
const blipPos = [];
|
||
TOOLS.forEach((tool, idx) => {
|
||
const qi = QUADRANTS.findIndex(q => q.id === tool.quad);
|
||
const ri = STATUSES[tool.status].ring;
|
||
const innerR = ri === 0 ? 22 : rings[ri-1] + 8;
|
||
const outerR = rings[ri] - 8;
|
||
const r = innerR + (outerR - innerR) * (.15 + tool.seed * .7);
|
||
const base = qi * Math.PI/2 - Math.PI/2;
|
||
const a = base + .12 + (Math.PI/2 - .24) * ((tool.seed + idx * 0.017) % 1);
|
||
blipPos.push({px: cx + r * Math.cos(a), py: cy + r * Math.sin(a), tool, qi, idx});
|
||
});
|
||
// Pass 2: force-repel overlapping blips (5 iterations)
|
||
for (let iter = 0; iter < 5; iter++) {
|
||
for (let i = 0; i < blipPos.length; i++) {
|
||
for (let j = i + 1; j < blipPos.length; j++) {
|
||
const dx = blipPos[j].px - blipPos[i].px;
|
||
const dy = blipPos[j].py - blipPos[i].py;
|
||
const dist = Math.sqrt(dx*dx + dy*dy);
|
||
const minDist = 14;
|
||
if (dist < minDist && dist > 0) {
|
||
const force = (minDist - dist) / 2;
|
||
const fx = (dx / dist) * force;
|
||
const fy = (dy / dist) * force;
|
||
blipPos[i].px -= fx; blipPos[i].py -= fy;
|
||
blipPos[j].px += fx; blipPos[j].py += fy;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// Pass 3: render
|
||
blipPos.forEach(({px, py, tool, qi}) => {
|
||
const _px = px, _py = py;
|
||
const col = tool.isWeval ? "#14B8A6" : QC[qi];
|
||
const tid = tool.name.replace(/\s/g, "-");
|
||
const labelX = _px > cx ? _px + 12 : _px - tool.name.length * 6.5 - 20;
|
||
|
||
svg += `<g class="blip" data-name="${tool.name}" onmouseenter="hoverBlip('${tid}')" onmouseleave="unhoverBlip()" onclick="selectBlip('${tid}')">`;
|
||
svg += `<circle class="blip-glow" cx="${_px}" cy="${_py}" r="16" fill="${col}" opacity="0"/>`;
|
||
svg += `<circle class="blip-dot" cx="${_px}" cy="${_py}" r="5.5" fill="${col}" opacity=".85"/>`;
|
||
svg += `<g class="blip-label"><rect x="${labelX}" y="${_py-13}" width="${tool.name.length*6.5+18}" height="22" rx="5" fill="#1A1D2A" stroke="${col}" stroke-width=".6" opacity=".96"/><text x="${labelX+9}" y="${_py+1}" fill="#fff" font-size="10.5" font-weight="500" font-family="'DM Sans',sans-serif">${tool.name}</text></g>`;
|
||
svg += `</g>`;
|
||
});
|
||
|
||
document.getElementById("radarSvg").innerHTML = svg;
|
||
setTimeout(function(){document.querySelectorAll(".blip").forEach(function(g){var n=g.getAttribute("data-name");if(n){var t=TOOLS.find(function(x){return x.name===n});if(t&&t.isWeval){var d=g.querySelector(".blip-dot");if(d)d.classList.add("weval-dot")}}})},100);
|
||
}
|
||
|
||
function hoverBlip(tid) { hoveredBlip = tid; }
|
||
function unhoverBlip() { hoveredBlip = null; }
|
||
function selectBlip(tid) {
|
||
const el = document.getElementById("card-" + tid);
|
||
if (el) el.scrollIntoView({behavior:"smooth", block:"center"});
|
||
}
|
||
|
||
// ═══════════════════════════════════
|
||
// LEGEND
|
||
// ═══════════════════════════════════
|
||
function buildLegend() {
|
||
const totalStars = TOOLS.reduce((a,t) => a+t.stars, 0);
|
||
const langStats = {};
|
||
TOOLS.forEach(t => { langStats[t.lang] = (langStats[t.lang]||0)+1; });
|
||
const sc = {use:0,recommend:0,explore:0};
|
||
TOOLS.forEach(t => sc[t.status]++);
|
||
|
||
let h = '';
|
||
// Quadrants
|
||
h += `<div class="legend-section"><div class="legend-title mono">Quadrants</div>`;
|
||
QUADRANTS.forEach((q,i) => {
|
||
const cnt = TOOLS.filter(t => t.quad === q.id).length;
|
||
h += `<div class="legend-row"><span class="legend-dot" style="background:${QC[i]}"></span><span class="legend-label">${lang==="fr"?q.labelFr:q.label}</span><span class="legend-count mono">${cnt}</span></div>`;
|
||
});
|
||
const wCnt = TOOLS.filter(t => t.isWeval).length;
|
||
h += `<div class="legend-row"><span class="legend-dot" style="background:#14B8A6"></span><span class="legend-label">WEVAL SaaS</span><span class="legend-count mono">${wCnt}</span></div>`;
|
||
h += `</div>`;
|
||
|
||
// Rings
|
||
h += `<div class="legend-section"><div class="legend-title mono">${t("Rings","Anneaux")}</div>`;
|
||
Object.entries(STATUSES).forEach(([k,v]) => {
|
||
const active = activeStatus === k;
|
||
h += `<div class="legend-row" onclick="toggleStatus('${k}')"><div class="ring-dot ${active?'active':''}" style="color:${v.color};border-color:${v.color}"></div><span class="legend-label" style="color:${active?v.color:'#C8CAD4'}">${lang==="fr"?v.labelFr:v.label}</span><span class="legend-count mono">${sc[k]}</span></div>`;
|
||
});
|
||
h += `</div>`;
|
||
|
||
// Stats
|
||
h += `<div class="stats-box">`;
|
||
h += `<div class="stats-row"><span class="stats-label">${t("Curated tools","Outils curatés")}</span><span class="stats-val" style="color:var(--green)">${TOOLS.length}</span></div>`;
|
||
h += `<div class="stats-row"><span class="stats-label">GitHub Stars</span><span class="stats-val" style="color:var(--yellow)">${(totalStars/1e6).toFixed(1)}M</span></div>`;
|
||
h += `<div class="stats-row"><span class="stats-label">${t("Languages","Langages")}</span><span class="stats-val" style="color:var(--blue)">${Object.keys(langStats).length}</span></div>`;
|
||
h += `</div>`;
|
||
|
||
document.getElementById("radarLegend").innerHTML = h;
|
||
}
|
||
|
||
function toggleStatus(k) {
|
||
activeStatus = activeStatus === k ? null : k;
|
||
buildLegend(); render();
|
||
}
|
||
|
||
// ═══════════════════════════════════
|
||
// LANGUAGE BAR
|
||
// ═══════════════════════════════════
|
||
function buildLangBar() {
|
||
const stats = {};
|
||
TOOLS.forEach(t => { stats[t.lang] = (stats[t.lang]||0)+1; });
|
||
const sorted = Object.entries(stats).sort((a,b) => b[1]-a[1]).slice(0,6);
|
||
|
||
let bar = '', labels = '';
|
||
sorted.forEach(([l,c]) => {
|
||
bar += `<div class="lang-segment" style="flex:${c};background:${LC[l]||'#666'}"></div>`;
|
||
labels += `<div class="lang-item"><div class="lang-dot" style="background:${LC[l]||'#666'}"></div><span style="color:#8B8FA3">${l}</span><span class="mono" style="color:var(--muted);font-size:11px">${Math.round(c/TOOLS.length*100)}%</span></div>`;
|
||
});
|
||
document.getElementById("langBar").innerHTML = bar;
|
||
document.getElementById("langLabels").innerHTML = labels;
|
||
}
|
||
|
||
// ═══════════════════════════════════
|
||
// CATEGORY BUTTONS
|
||
// ═══════════════════════════════════
|
||
function buildCatBtns() {
|
||
let h = '';
|
||
CATEGORIES.forEach(c => {
|
||
const active = activeCat === c.id ? ' active' : '';
|
||
const lbl = lang === "fr" ? c.labelFr : c.label;
|
||
h += `<button class="cat-btn${active}" onclick="setCat('${c.id}')">${c.icon} ${lbl}</button>`;
|
||
});
|
||
document.getElementById("catBtns").innerHTML = h;
|
||
}
|
||
|
||
function setCat(id) { activeCat = id; buildCatBtns(); render(); }
|
||
|
||
// ═══════════════════════════════════
|
||
// CARDS
|
||
// ═══════════════════════════════════
|
||
function render() {
|
||
const q = document.getElementById("searchInput").value.toLowerCase();
|
||
const filtered = TOOLS.filter(tool => {
|
||
if (activeCat !== "all" && tool.cat !== activeCat) return false;
|
||
if (activeStatus && tool.status !== activeStatus) return false;
|
||
if (q) return tool.name.toLowerCase().includes(q) || tool.replaces.toLowerCase().includes(q) || tool.desc.toLowerCase().includes(q);
|
||
return true;
|
||
});
|
||
|
||
document.getElementById("resultCount").textContent = filtered.length + " " + t("results","résultats") + (activeStatus ? " · " + (lang==="fr" ? STATUSES[activeStatus].labelFr : STATUSES[activeStatus].label) : "");
|
||
|
||
let h = '';
|
||
filtered.forEach((tool, i) => {
|
||
const st = STATUSES[tool.status];
|
||
const tid = tool.name.replace(/\s/g, "-");
|
||
const delay = Math.min(i * .04, .4);
|
||
const desc = lang === "fr" ? tool.descFr : tool.desc;
|
||
const stLabel = lang === "fr" ? st.labelFr : st.label;
|
||
|
||
const wc = tool.isWeval ? " weval-card" : "";
|
||
h += `<div class="tool-card${wc} fade-up" id="card-${tid}" style="--sc:${st.color};animation-delay:${delay}s" onclick="window.open('${tool.url}','_blank')">`;
|
||
h += `<div class="card-top"><div>`;
|
||
h += `<div style="display:flex;align-items:center;gap:8px;margin-bottom:4px">`;
|
||
const logoUrl = TOOL_LOGOS[tool.name] || "";
|
||
if(logoUrl){h += `<img class="card-logo" src="${logoUrl}" alt="" onerror="this.style.display='none'">`}
|
||
h += `<span class="card-name">${tool.name}</span>`;
|
||
h += `<span class="status-pill" style="background:${st.color}12;color:${st.color};border:1px solid ${st.color}25"><span class="status-dot${tool.status==='use'?' pulse':''}" style="background:${st.color}"></span>${stLabel}</span>`;
|
||
h += `</div>`;
|
||
h += `<span class="replaces-badge">↔ ${tool.replaces}</span>`;
|
||
h += `</div>`;
|
||
if(tool.isWeval){h+=`<div class="card-stars"><div class="card-stars-num" style="color:#14B8A6;font-size:13px">SaaS</div><div class="card-stars-label" style="color:#14B8A6">WEVAL</div></div>`}else{h += `<div class="card-stars"><div class="card-stars-num">${fmtStars(tool.stars)}</div><div class="card-stars-label">★ stars</div></div>`;}
|
||
h += `</div>`;
|
||
h += `<p class="card-desc">${desc}</p>`;
|
||
h += `<div class="card-footer"><div style="display:flex;gap:8px;align-items:center">`;
|
||
h += `<span class="card-lang mono"><span class="lang-dot" style="background:${LC[tool.lang]||'#666'}"></span>${tool.lang}</span>`;
|
||
h += `<span class="card-license mono">${tool.license}</span>`;
|
||
h += `</div><svg class="card-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 17L17 7M17 7H7M17 7V17"/></svg></div>`;
|
||
h += `</div>`;
|
||
});
|
||
|
||
document.getElementById("cardsGrid").innerHTML = h;
|
||
}
|
||
|
||
// Init
|
||
buildRadar();
|
||
buildLegend();
|
||
buildLangBar();
|
||
buildCatBtns();
|
||
render();
|
||
</script>
|
||
|
||
<!-- AUTO-DISCOVERY INJECTION (enrichment, not replacement) -->
|
||
<script id="oss-auto-discovery">
|
||
(function(){
|
||
// Tools discovered by Opus analysis — inject into radar if not already present
|
||
var newTools = [
|
||
{name:"Langfuse",stars:"23K",cat:"🧠 Sovereign AI",status:"We Recommend",alt:"LangSmith",desc:"LLM observability — tracing, eval, prompt versioning",lang:"TypeScript",license:"MIT",gh:"langfuse/langfuse"},
|
||
{name:"RAGFlow",stars:"65K",cat:"🧠 Sovereign AI",status:"Exploring",alt:"Coveo/Elastic",desc:"Deep document parsing + GraphRAG",lang:"Python",license:"Apache-2.0",gh:"infiniflow/ragflow"},
|
||
{name:"Unsloth",stars:"54K",cat:"🧠 Sovereign AI",status:"Exploring",alt:"AWS Bedrock",desc:"2× faster fine-tuning, 70% less VRAM",lang:"Python",license:"Apache-2.0",gh:"unslothai/unsloth"},
|
||
{name:"LLaMA-Factory",stars:"60K",cat:"🧠 Sovereign AI",status:"Exploring",alt:"Vertex AI",desc:"Zero-code fine-tuning 100+ models",lang:"Python",license:"Apache-2.0",gh:"hiyouga/LLaMA-Factory"},
|
||
{name:"CrewAI",stars:"39K",cat:"🧠 Sovereign AI",status:"Exploring",alt:"Custom agents",desc:"Multi-agent orchestration",lang:"Python",license:"MIT",gh:"crewAIInc/crewAI"},
|
||
{name:"Whisper.cpp",stars:"37K",cat:"🧠 Sovereign AI",status:"We Recommend",alt:"Google STT",desc:"CPU speech-to-text, zero API cost",lang:"C++",license:"MIT",gh:"ggerganov/whisper.cpp"},
|
||
{name:"ArgoCD",stars:"22K",cat:"⚙ DevOps & Infra",status:"We Recommend",alt:"Harness CD",desc:"GitOps standard, CNCF graduated",lang:"Go",license:"Apache-2.0",gh:"argoproj/argo-cd"},
|
||
{name:"Harbor",stars:"28K",cat:"⚙ DevOps & Infra",status:"We Recommend",alt:"Docker Hub",desc:"CNCF container registry + scanning",lang:"Go",license:"Apache-2.0",gh:"goharbor/harbor"},
|
||
{name:"Grafana Loki",stars:"28K",cat:"⚙ DevOps & Infra",status:"We Recommend",alt:"ELK/Splunk",desc:"Log aggregation for Grafana",lang:"Go",license:"AGPL-3.0",gh:"grafana/loki"},
|
||
{name:"SigNoz",stars:"25K",cat:"⚙ DevOps & Infra",status:"Exploring",alt:"Datadog",desc:"OpenTelemetry APM+traces+logs",lang:"TypeScript",license:"MIT",gh:"SigNoz/signoz"},
|
||
{name:"Infisical",stars:"25K",cat:"🛡 Security",status:"We Recommend",alt:"Vault",desc:"Modern secrets management",lang:"TypeScript",license:"MIT",gh:"Infisical/infisical"},
|
||
{name:"OpenTofu",stars:"28K",cat:"⚙ DevOps & Infra",status:"We Recommend",alt:"Terraform",desc:"Linux Foundation Terraform fork",lang:"Go",license:"MPL-2.0",gh:"opentofu/opentofu"},
|
||
{name:"Velero",stars:"9.2K",cat:"⚙ DevOps & Infra",status:"We Recommend",alt:"Kasten K10",desc:"K8s backup + disaster recovery",lang:"Go",license:"Apache-2.0",gh:"vmware-tanzu/velero"},
|
||
{name:"Twenty CRM",stars:"37K",cat:"📊 Business Apps",status:"We Recommend",alt:"Salesforce",desc:"Modern CRM, GraphQL, Notion-like UX",lang:"TypeScript",license:"AGPL-3.0",gh:"twentyhq/twenty"},
|
||
{name:"Plane",stars:"40K",cat:"📊 Business Apps",status:"We Recommend",alt:"Jira/Linear",desc:"Project mgmt — sprints, AI pages",lang:"TypeScript",license:"AGPL-3.0",gh:"makeplane/plane"},
|
||
{name:"Cal.com",stars:"39K",cat:"📊 Business Apps",status:"We Recommend",alt:"Booking WEVAL",desc:"Scheduling infra, team booking",lang:"TypeScript",license:"AGPL-3.0",gh:"calcom/cal.com"},
|
||
{name:"Chatwoot",stars:"28K",cat:"📊 Business Apps",status:"We Recommend",alt:"Intercom/Zendesk",desc:"Omnichannel support",lang:"Ruby",license:"MIT",gh:"chatwoot/chatwoot"},
|
||
{name:"NocoDB",stars:"50K",cat:"📊 Business Apps",status:"We Recommend",alt:"Airtable",desc:"SQL→spreadsheet, API-first",lang:"TypeScript",license:"AGPL-3.0",gh:"nocodb/nocodb"},
|
||
{name:"ClickHouse",stars:"39K",cat:"📈 Data & Analytics",status:"We Recommend",alt:"Snowflake/BigQuery",desc:"OLAP billions rows/sec",lang:"C++",license:"Apache-2.0",gh:"ClickHouse/ClickHouse"},
|
||
{name:"Airbyte",stars:"21K",cat:"📈 Data & Analytics",status:"We Recommend",alt:"Fivetran",desc:"600+ connectors data integration",lang:"Java",license:"MIT",gh:"airbytehq/airbyte"},
|
||
{name:"PostHog",stars:"25K",cat:"📈 Data & Analytics",status:"Exploring",alt:"Mixpanel+Hotjar",desc:"Product analytics+session replay",lang:"Python",license:"MIT",gh:"PostHog/posthog"},
|
||
{name:"Mattermost",stars:"36K",cat:"📊 Business Apps",status:"We Recommend",alt:"Slack/Teams",desc:"Enterprise team messaging",lang:"Go",license:"MIT",gh:"mattermost/mattermost"},
|
||
{name:"Jitsi Meet",stars:"29K",cat:"📊 Business Apps",status:"We Recommend",alt:"Zoom",desc:"Browser video conferencing",lang:"Java",license:"Apache-2.0",gh:"jitsi/jitsi-meet"},
|
||
{name:"Vaultwarden",stars:"57K",cat:"🛡 Security",status:"We Recommend",alt:"1Password",desc:"Bitwarden-compatible, 256MB RAM",lang:"Rust",license:"AGPL-3.0",gh:"dani-garcia/vaultwarden"},
|
||
{name:"Trivy",stars:"25K",cat:"🛡 Security",status:"We Recommend",alt:"Snyk/Qualys",desc:"Container+IaC vulnerability scanner",lang:"Go",license:"Apache-2.0",gh:"aquasecurity/trivy"},
|
||
{name:"Gitleaks",stars:"25K",cat:"🛡 Security",status:"We Recommend",alt:"GitGuardian",desc:"Detect secrets in git repos",lang:"Go",license:"MIT",gh:"gitleaks/gitleaks"},
|
||
{name:"Nuclei",stars:"27K",cat:"🛡 Security",status:"Exploring",alt:"Nessus",desc:"12K+ templates vuln scanner",lang:"Go",license:"MIT",gh:"projectdiscovery/nuclei"},
|
||
{name:"Excalidraw",stars:"119K",cat:"📊 Business Apps",status:"We Use",alt:"Miro/FigJam",desc:"Collaborative whiteboard",lang:"TypeScript",license:"MIT",gh:"excalidraw/excalidraw"},
|
||
{name:"MLflow",stars:"19K",cat:"🧠 Sovereign AI",status:"We Recommend",alt:"W&B/Neptune",desc:"MLOps lifecycle management",lang:"Python",license:"Apache-2.0",gh:"mlflow/mlflow"},
|
||
{name:"Haystack",stars:"23K",cat:"🧠 Sovereign AI",status:"Exploring",alt:"Custom RAG",desc:"Production RAG framework",lang:"Python",license:"Apache-2.0",gh:"deepset-ai/haystack"},
|
||
];
|
||
|
||
// Wait for existing radar data, then inject missing
|
||
function injectTools() {
|
||
if(typeof window.ALL_TOOLS === "undefined") window.ALL_TOOLS = [];
|
||
var existingNames = window.ALL_TOOLS.map(function(t){ return t.name.toLowerCase(); });
|
||
var added = 0;
|
||
newTools.forEach(function(t) {
|
||
if(existingNames.indexOf(t.name.toLowerCase()) === -1) {
|
||
window.ALL_TOOLS.push(t);
|
||
added++;
|
||
}
|
||
});
|
||
if(added > 0 && typeof window.renderTools === "function") {
|
||
window.renderTools(window.ALL_TOOLS);
|
||
}
|
||
// Update counter
|
||
var counter = document.querySelector("[data-results-count],.results-count,#results-count");
|
||
if(counter) counter.textContent = window.ALL_TOOLS.length + " results";
|
||
console.log("OSS Discovery: injected " + added + " tools, total: " + window.ALL_TOOLS.length);
|
||
}
|
||
|
||
// Auto-run after page load
|
||
if(document.readyState === "complete") setTimeout(injectTools, 1000);
|
||
else window.addEventListener("load", function(){ setTimeout(injectTools, 1000); });
|
||
setTimeout(injectTools, 3000);
|
||
setTimeout(injectTools, 5000);
|
||
})();
|
||
</script>
|
||
|
||
<!-- === OPUS UNIVERSAL DRILL-DOWN v1 19avr — append-only, doctrine #14 === -->
|
||
<script>
|
||
(function(){
|
||
if (window.__opusUniversalDrill) return; window.__opusUniversalDrill = true;
|
||
var d = document;
|
||
var m = d.createElement('div');
|
||
m.id = 'opus-udrill';
|
||
m.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.82);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;z-index:99995;padding:20px;cursor:pointer';
|
||
var inner = d.createElement('div');
|
||
inner.id = 'opus-udrill-in';
|
||
inner.style.cssText = 'max-width:900px;width:100%;max-height:90vh;overflow:auto;background:#0b0d15;border:1px solid rgba(99,102,241,0.35);border-radius:14px;padding:28px;cursor:default;box-shadow:0 20px 60px rgba(0,0,0,0.6);color:#e2e8f0;font:14px/1.55 Inter,system-ui,sans-serif';
|
||
inner.addEventListener('click', function(e){ e.stopPropagation(); });
|
||
m.appendChild(inner);
|
||
m.addEventListener('click', function(){ m.style.display='none'; });
|
||
d.addEventListener('keydown', function(e){ if(e.key==='Escape') m.style.display='none'; });
|
||
(d.body || d.documentElement).appendChild(m);
|
||
|
||
function openCard(card) {
|
||
// Clone card content + show close btn + increase font-size
|
||
var html = '<div style="display:flex;justify-content:flex-end;margin-bottom:14px"><button id="opus-udrill-close" style="padding:6px 14px;background:#171b2a;border:1px solid rgba(99,102,241,0.25);color:#e2e8f0;border-radius:8px;cursor:pointer;font-size:12px">✕ Fermer (Esc)</button></div>';
|
||
html += '<div style="transform-origin:top left;font-size:1.05em">' + card.outerHTML + '</div>';
|
||
inner.innerHTML = html;
|
||
d.getElementById('opus-udrill-close').onclick = function(){ m.style.display='none'; };
|
||
m.style.display = 'flex';
|
||
}
|
||
|
||
function wire(root) {
|
||
var sels = '.card,[class*="card"],.kpi,[class*="kpi"],.stat,[class*="stat"],.tile,[class*="tile"],.metric,[class*="metric"],.widget,[class*="widget"]';
|
||
var cards = root.querySelectorAll(sels);
|
||
for (var i = 0; i < cards.length; i++) {
|
||
var c = cards[i];
|
||
if (c.__opusWired) continue;
|
||
if (c.closest('button, a, input, select, textarea, #opus-udrill')) continue;
|
||
var r = c.getBoundingClientRect();
|
||
if (r.width < 60 || r.height < 40) continue;
|
||
c.__opusWired = true;
|
||
c.style.cursor = 'pointer';
|
||
c.setAttribute('role','button');
|
||
c.setAttribute('tabindex','0');
|
||
c.addEventListener('click', function(ev){
|
||
// If a more-specific drill is already active (e.g. pp-card custom), let it handle
|
||
if (ev.target.closest('[data-pp-id]') && window.__opusDrillInit) return;
|
||
if (ev.target.closest('a,button,input,select')) return;
|
||
ev.preventDefault(); ev.stopPropagation();
|
||
openCard(this);
|
||
});
|
||
c.addEventListener('keydown', function(ev){ if(ev.key==='Enter'||ev.key===' '){ev.preventDefault();openCard(this);} });
|
||
}
|
||
}
|
||
|
||
// Initial + mutation observer
|
||
var initRun = function(){ wire(d.body || d.documentElement); };
|
||
if (d.readyState === 'loading') d.addEventListener('DOMContentLoaded', initRun);
|
||
else initRun();
|
||
var mo = new MutationObserver(function(muts){
|
||
var newCard = false;
|
||
for (var i=0;i<muts.length;i++) if (muts[i].addedNodes.length) { newCard = true; break; }
|
||
if (newCard) initRun();
|
||
});
|
||
mo.observe(d.body || d.documentElement, {childList:true, subtree:true});
|
||
})();
|
||
</script>
|
||
<!-- === OPUS UNIVERSAL DRILL-DOWN END === -->
|
||
|
||
|
||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||
</body>
|
||
</html>
|