diff --git a/ReadMe.md b/ReadMe.md index d316a92c7..354328f19 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -24,6 +24,30 @@ --- +## 📈 Performance + +TunGo includes in-memory full-cycle dataplane benchmarks for both UDP and TCP. These benchmarks measure userspace packet-processing throughput only: encryption, routing/lookup, validation, decryption, and handoff to an in-memory sink. + +Example single-run results for **1400-byte packets** on **Apple M4 Pro**: + +| Path | ns/op | Throughput | Allocs/op | +|---|---:|---:|---:| +| UDP client -> server | ~2.7 us | ~4.3 Gbit/s | 0 | +| UDP server -> client | ~2.6 us | ~4.3 Gbit/s | 0 | +| TCP client -> server | ~2.6 us | ~4.3 Gbit/s | 0 | +| TCP server -> client | ~2.6 us | ~4.3 Gbit/s | 0 | + +These numbers do **not** include TUN device, socket, kernel, firewall/NAT, or real network overhead. Treat them as dataplane-core benchmarks, not end-to-end VPN throughput claims. + +To reproduce: + +```bash +cd src +go test ./infrastructure/tunnel/dataplane/server/udp_chacha20 ./infrastructure/tunnel/dataplane/client/udp_chacha20 ./infrastructure/tunnel/dataplane/server/tcp_chacha20 ./infrastructure/tunnel/dataplane/client/tcp_chacha20 -run ^$ -bench FullCycle -benchmem +``` + +--- + ## 🚀 QuickStart Refer to: [QuickStart](https://tungo.ethacore.com/docs/QuickStart) diff --git a/docs/TunGo/docusaurus.config.js b/docs/TunGo/docusaurus.config.js index 50e4df0df..b33850aae 100644 --- a/docs/TunGo/docusaurus.config.js +++ b/docs/TunGo/docusaurus.config.js @@ -85,6 +85,11 @@ const config = { position: 'left', label: 'Tutorial', }, + { + to: '/benchmarks', + label: 'Benchmarks', + position: 'left', + }, { type: 'localeDropdown', position: 'right', diff --git a/docs/TunGo/i18n/ar/code.json b/docs/TunGo/i18n/ar/code.json index c219d0241..5d0c60577 100644 --- a/docs/TunGo/i18n/ar/code.json +++ b/docs/TunGo/i18n/ar/code.json @@ -9,39 +9,186 @@ "message": "أمّن اتصالك مع TunGo: VPN خفيف وسريع ومفتوح المصدر مبني بـ Go باستخدام تشفير حديث." }, "feature.cpuFast.title": { - "message": "سريع المعالجة" + "message": "سريع" }, "feature.cpuFast.description": { - "message": "بدون تخصيصات ذاكرة وقت التشغيل. استخدام CPU ضئيل تحت الحمل." + "message": "0 allocs/op على المسار السريع." }, "feature.ramEfficient.title": { - "message": "فعال الذاكرة" + "message": "الذاكرة" }, "feature.ramEfficient.description": { - "message": "≈5–15 ميجابايت RSS تحت الحمل، ≈5–8 ميجابايت في الخمول" + "message": "≈5–15 ميجابايت RSS تحت الحمل." }, "feature.secure.title": { - "message": "آمن" + "message": "التشفير" }, "feature.secure.description": { - "message": "مصافحة Noise IK، اتفاق مفاتيح X25519، تشفير AEAD ChaCha20-Poly1305" + "message": "Noise IK و X25519 و ChaCha20-Poly1305." }, "feature.multiTransport.title": { - "message": "دعم النقل المتعدد" + "message": "النواقل" }, "feature.multiTransport.description": { - "message": "UDP — أداء عالي، TCP — بديل موثوق، WebSocket/WSS — وضع التخفي" + "message": "UDP و TCP و WebSocket/WSS." }, "feature.platforms.title": { - "message": "المنصات المدعومة" + "message": "المنصات" }, "feature.platforms.description": { - "message": "Linux (عميل وخادم)، macOS (عميل)، Windows (عميل)" + "message": "Linux و macOS و Windows." }, "feature.openSource.title": { - "message": "مفتوح المصدر" + "message": "مفتوح" }, "feature.openSource.description": { - "message": "الرخصة: AGPLv3" + "message": "مرخّص تحت AGPLv3." + }, + "homepage.heroTitle.prefix": { + "message": "سريع وخفيف" + }, + "homepage.heroTitle.suffix": { + "message": "VPN يعمل في فضاء المستخدم" + }, + "homepage.benchmarksCta": { + "message": "عرض القياسات" + }, + "bench.hero.title": { + "message": "لقطة القياسات" + }, + "bench.section.fullCycle.title": { + "message": "دورة dataplane كاملة" + }, + "bench.section.fullCycle.text": { + "message": "تشفير، lookup، تحقق، فك تشفير، handoff. هذا حد أعلى لنواة dataplane وليس لسرعة VPN من الطرف إلى الطرف." + }, + "bench.section.scaling.title": { + "message": "توسّع UDP متعدد الـ peer" + }, + "bench.section.scaling.text": { + "message": "إنتاجية مجمعة مع توزيع العمل على عدد كبير من الـ peer، وليس عبر مسار إرسال واحد متسلسل." + }, + "bench.chart.aggregateThroughput": { + "message": "الإنتاجية المجمعة" + }, + "bench.section.lookup.title": { + "message": "Lookup والتسلسل" + }, + "bench.section.lookup.text": { + "message": "Lookup عبر Internal-IP و allowed-host و route-ID يبقى ثابتًا. أما misses والتسلسل لكل peer فهما نقاط الضغط الحقيقية." + }, + "bench.transport.udp": { + "message": "UDP" + }, + "bench.transport.tcp": { + "message": "TCP" + }, + "bench.direction.clientServer": { + "message": "العميل -> الخادم" + }, + "bench.direction.serverClient": { + "message": "الخادم -> العميل" + }, + "bench.parallel.clientServer": { + "message": "UDP العميل -> الخادم" + }, + "bench.parallel.serverClient": { + "message": "UDP الخادم -> العميل" + }, + "bench.lookup.exactInternal": { + "message": "Lookup داخلي دقيق" + }, + "bench.lookup.allowedHost": { + "message": "Lookup allowed host" + }, + "bench.lookup.routeId": { + "message": "Lookup Route ID" + }, + "bench.legend.peers": { + "message": "{count} peers" + }, + "bench.table.fullCycleAria": { + "message": "نتائج قياس دورة dataplane الكاملة" + }, + "bench.table.path": { + "message": "المسار" + }, + "bench.table.latency": { + "message": "الكمون" + }, + "bench.table.throughput": { + "message": "الإنتاجية" + }, + "bench.table.allocs": { + "message": "Allocs/op" + }, + "bench.lookup.missPath": { + "message": "Miss path" + }, + "bench.table.lookupAria": { + "message": "نتائج قياس repository lookup و miss path" + }, + "bench.table.lookup": { + "message": "Lookup" + }, + "bench.table.peerCount": { + "message": "{count} peers" + }, + "bench.page.title": { + "message": "القياسات" + }, + "bench.page.description": { + "message": "لوحة قياسات لـ dataplane في TunGo: الإنتاجية والكمون وكلفة lookup في repository والتزاحم في egress." + }, + "bench.hero.lead": { + "message": "لقطة يدوية جرى قياسها على {machine} باستخدام {goVersion}." + }, + "bench.metric.throughput": { + "message": "الإنتاجية" + }, + "bench.metric.throughputNote": { + "message": "أفضل مسار full-cycle" + }, + "bench.metric.latency": { + "message": "الكمون" + }, + "bench.metric.latencyNote": { + "message": "أقل مسار full-cycle" + }, + "bench.metric.lookup": { + "message": "Fast-path lookup" + }, + "bench.metric.lookupNote": { + "message": "ثابت حتى 10k peers" + }, + "bench.metric.allocs": { + "message": "Allocs/op" + }, + "bench.metric.allocsNote": { + "message": "Hot path" + }, + "bench.summary.egress": { + "message": "مسار egress" + }, + "bench.summary.egressNote": { + "message": "من إرسال دون تزاحم إلى إرسال مع تزاحم" + }, + "bench.summary.missPath": { + "message": "Miss path" + }, + "bench.summary.linear": { + "message": "خطي" + }, + "bench.summary.missPathNote": { + "message": "~35 ns عند 1 peer -> ~89.5 μs عند 10k peers" + }, + "footer.iconsBy": { + "message": "الأيقونات من" + }, + "footer.builtWith": { + "message": "مبني باستخدام" + }, + "footer.contributors": { + "message": "مساهمو TunGo" } } diff --git a/docs/TunGo/i18n/ar/docusaurus-theme-classic/navbar.json b/docs/TunGo/i18n/ar/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000..514f4226e --- /dev/null +++ b/docs/TunGo/i18n/ar/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "item.label.Tutorial": { + "message": "الدليل", + "description": "Navbar item with label Tutorial" + }, + "item.label.Benchmarks": { + "message": "القياسات", + "description": "Navbar item with label Benchmarks" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/docs/TunGo/i18n/de/code.json b/docs/TunGo/i18n/de/code.json index 01f6e953a..f15b5d908 100644 --- a/docs/TunGo/i18n/de/code.json +++ b/docs/TunGo/i18n/de/code.json @@ -6,42 +6,189 @@ "message": "Minimalistisches, schnelles & sicheres Open-Source-VPN" }, "homepage.description": { - "message": "Sichern Sie Ihre Verbindung mit TunGo: leichtgewichtiges, schnelles, Open-Source-VPN, gebaut in Go mit moderner Kryptographie." + "message": "Sichern Sie Ihre Verbindung mit TunGo: leichtgewichtiges, schnelles Open-Source-VPN, gebaut in Go mit moderner Kryptografie." }, "feature.cpuFast.title": { - "message": "CPU-Schnell" + "message": "Schnell" }, "feature.cpuFast.description": { - "message": "Keine Laufzeit-Allokationen. Vernachlässigbare CPU-Nutzung unter Last." + "message": "0 Allocs/op auf dem Hot Path." }, "feature.ramEfficient.title": { - "message": "RAM-Effizient" + "message": "Speicher" }, "feature.ramEfficient.description": { - "message": "≈5–15 MB RSS unter Last, ≈5–8 MB im Leerlauf" + "message": "≈5–15 MB RSS unter Last." }, "feature.secure.title": { - "message": "Sicher" + "message": "Krypto" }, "feature.secure.description": { - "message": "Noise IK-Handshake, X25519-Schlüsselaustausch, ChaCha20-Poly1305 AEAD" + "message": "Noise IK, X25519, ChaCha20-Poly1305." }, "feature.multiTransport.title": { - "message": "Multi-Transport-Unterstützung" + "message": "Transporte" }, "feature.multiTransport.description": { - "message": "UDP — hohe Leistung, TCP — zuverlässiger Fallback, WebSocket/WSS — Stealth-Modus" + "message": "UDP, TCP, WebSocket/WSS." }, "feature.platforms.title": { - "message": "Unterstützte Plattformen" + "message": "Plattformen" }, "feature.platforms.description": { - "message": "Linux (Client und Server), macOS (Client), Windows (Client)" + "message": "Linux, macOS, Windows." }, "feature.openSource.title": { - "message": "Open Source" + "message": "OSS" }, "feature.openSource.description": { - "message": "Lizenz: AGPLv3" + "message": "Unter AGPLv3 lizenziert." + }, + "homepage.heroTitle.prefix": { + "message": "Schnell und schlank" + }, + "homepage.heroTitle.suffix": { + "message": "Userspace-VPN" + }, + "homepage.benchmarksCta": { + "message": "Benchmarks ansehen" + }, + "bench.hero.title": { + "message": "Benchmark-Snapshot" + }, + "bench.section.fullCycle.title": { + "message": "Vollständiger Dataplane-Zyklus" + }, + "bench.section.fullCycle.text": { + "message": "Verschlüsseln, Lookup, Validierung, Entschlüsselung, Handoff. Obergrenze für den Dataplane-Kern, nicht für den End-to-End-VPN-Durchsatz." + }, + "bench.section.scaling.title": { + "message": "UDP-Skalierung über mehrere Peers" + }, + "bench.section.scaling.text": { + "message": "Aggregierter Durchsatz bei Verteilung der Arbeit über viele Peers, nicht über eine einzelne serialisierte Sendespur." + }, + "bench.chart.aggregateThroughput": { + "message": "Aggregierter Durchsatz" + }, + "bench.section.lookup.title": { + "message": "Lookup und Serialisierung" + }, + "bench.section.lookup.text": { + "message": "Internal-IP-, Allowed-Host- und Route-ID-Lookups bleiben flach. Misses und Serialisierung pro Peer sind die eigentlichen Druckpunkte." + }, + "bench.transport.udp": { + "message": "UDP" + }, + "bench.transport.tcp": { + "message": "TCP" + }, + "bench.direction.clientServer": { + "message": "Client -> Server" + }, + "bench.direction.serverClient": { + "message": "Server -> Client" + }, + "bench.parallel.clientServer": { + "message": "UDP Client -> Server" + }, + "bench.parallel.serverClient": { + "message": "UDP Server -> Client" + }, + "bench.lookup.exactInternal": { + "message": "Exakter Internal-Lookup" + }, + "bench.lookup.allowedHost": { + "message": "Allowed-Host-Lookup" + }, + "bench.lookup.routeId": { + "message": "Route-ID-Lookup" + }, + "bench.legend.peers": { + "message": "{count} Peers" + }, + "bench.table.fullCycleAria": { + "message": "Benchmark-Ergebnisse des vollständigen Dataplane-Zyklus" + }, + "bench.table.path": { + "message": "Pfad" + }, + "bench.table.latency": { + "message": "Latenz" + }, + "bench.table.throughput": { + "message": "Durchsatz" + }, + "bench.table.allocs": { + "message": "Allocs/op" + }, + "bench.lookup.missPath": { + "message": "Miss-Pfad" + }, + "bench.table.lookupAria": { + "message": "Benchmark-Ergebnisse für Repository-Lookup und Miss-Pfad" + }, + "bench.table.lookup": { + "message": "Lookup" + }, + "bench.table.peerCount": { + "message": "{count} Peers" + }, + "bench.page.title": { + "message": "Benchmarks" + }, + "bench.page.description": { + "message": "Benchmark-Dashboard für TunGo-Dataplane-Durchsatz, Latenz, Repository-Lookup-Kosten und Egress-Contention." + }, + "bench.hero.lead": { + "message": "Manueller Snapshot, gemessen auf {machine} mit {goVersion}." + }, + "bench.metric.throughput": { + "message": "Durchsatz" + }, + "bench.metric.throughputNote": { + "message": "Bester Full-Cycle-Pfad" + }, + "bench.metric.latency": { + "message": "Latenz" + }, + "bench.metric.latencyNote": { + "message": "Niedrigster Full-Cycle-Pfad" + }, + "bench.metric.lookup": { + "message": "Fast-Path-Lookup" + }, + "bench.metric.lookupNote": { + "message": "Flach bis 10k Peers" + }, + "bench.metric.allocs": { + "message": "Allocs/op" + }, + "bench.metric.allocsNote": { + "message": "Hot Path" + }, + "bench.summary.egress": { + "message": "Egress-Spur" + }, + "bench.summary.egressNote": { + "message": "Von uncontended zu contended Sends" + }, + "bench.summary.missPath": { + "message": "Miss-Pfad" + }, + "bench.summary.linear": { + "message": "Linear" + }, + "bench.summary.missPathNote": { + "message": "~35 ns bei 1 Peer -> ~89.5 μs bei 10k Peers" + }, + "footer.iconsBy": { + "message": "Symbole von" + }, + "footer.builtWith": { + "message": "Erstellt mit" + }, + "footer.contributors": { + "message": "TunGo-Mitwirkende" } } diff --git a/docs/TunGo/i18n/de/docusaurus-theme-classic/navbar.json b/docs/TunGo/i18n/de/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000..f858c10bf --- /dev/null +++ b/docs/TunGo/i18n/de/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "item.label.Tutorial": { + "message": "Anleitung", + "description": "Navbar item with label Tutorial" + }, + "item.label.Benchmarks": { + "message": "Benchmarks", + "description": "Navbar item with label Benchmarks" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/docs/TunGo/i18n/en/code.json b/docs/TunGo/i18n/en/code.json index b91291a6f..7bd24f90f 100644 --- a/docs/TunGo/i18n/en/code.json +++ b/docs/TunGo/i18n/en/code.json @@ -332,39 +332,186 @@ "description": "The title of the tag list page" }, "feature.cpuFast.title": { - "message": "CPU-Fast" + "message": "Fast" }, "feature.cpuFast.description": { - "message": "No runtime allocations. Negligible CPU usage under load." + "message": "0 allocs/op on the hot path." }, "feature.ramEfficient.title": { - "message": "RAM-Efficient" + "message": "Memory" }, "feature.ramEfficient.description": { - "message": "≈5–15 MB RSS under load, ≈5–8 MB idle" + "message": "≈5–15 MB RSS under load." }, "feature.secure.title": { - "message": "Secure" + "message": "Crypto" }, "feature.secure.description": { - "message": "Noise IK handshake, X25519 key agreement, ChaCha20-Poly1305 AEAD" + "message": "Noise IK, X25519, ChaCha20-Poly1305." }, "feature.multiTransport.title": { - "message": "Multi-Transport Support" + "message": "Transports" }, "feature.multiTransport.description": { - "message": "UDP — high performance, TCP — reliable fallback, WebSocket/WSS — stealth mode" + "message": "UDP, TCP, WebSocket/WSS." }, "feature.platforms.title": { - "message": "Supported Platforms" + "message": "Platforms" }, "feature.platforms.description": { - "message": "Linux (client and server), macOS (client), Windows (client)" + "message": "Linux, macOS, Windows." }, "feature.openSource.title": { - "message": "Open Source" + "message": "OSS" }, "feature.openSource.description": { - "message": "License: AGPLv3" + "message": "AGPLv3-licensed." + }, + "homepage.heroTitle.prefix": { + "message": "Fast, lightweight" + }, + "homepage.heroTitle.suffix": { + "message": "userspace VPN" + }, + "homepage.benchmarksCta": { + "message": "View benchmarks" + }, + "bench.hero.title": { + "message": "Benchmark snapshot" + }, + "bench.section.fullCycle.title": { + "message": "Full-cycle dataplane" + }, + "bench.section.fullCycle.text": { + "message": "Encrypt, lookup, validate, decrypt, handoff. Upper-bound for the dataplane core, not end-to-end VPN throughput." + }, + "bench.section.scaling.title": { + "message": "Multi-peer UDP scaling" + }, + "bench.section.scaling.text": { + "message": "Aggregate throughput with work spread across many peers, not one serialized send lane." + }, + "bench.chart.aggregateThroughput": { + "message": "Aggregate throughput" + }, + "bench.section.lookup.title": { + "message": "Lookup and serialization" + }, + "bench.section.lookup.text": { + "message": "Internal-IP, allowed-host, and route-ID lookups stay flat. Misses and per-peer serialization are the real pressure points." + }, + "bench.transport.udp": { + "message": "UDP" + }, + "bench.transport.tcp": { + "message": "TCP" + }, + "bench.direction.clientServer": { + "message": "Client -> Server" + }, + "bench.direction.serverClient": { + "message": "Server -> Client" + }, + "bench.parallel.clientServer": { + "message": "UDP Client -> Server" + }, + "bench.parallel.serverClient": { + "message": "UDP Server -> Client" + }, + "bench.lookup.exactInternal": { + "message": "Exact internal lookup" + }, + "bench.lookup.allowedHost": { + "message": "Allowed host lookup" + }, + "bench.lookup.routeId": { + "message": "Route ID lookup" + }, + "bench.legend.peers": { + "message": "{count} peers" + }, + "bench.table.fullCycleAria": { + "message": "Full-cycle dataplane benchmark results" + }, + "bench.table.path": { + "message": "Path" + }, + "bench.table.latency": { + "message": "Latency" + }, + "bench.table.throughput": { + "message": "Throughput" + }, + "bench.table.allocs": { + "message": "Allocs/op" + }, + "bench.lookup.missPath": { + "message": "Miss path" + }, + "bench.table.lookupAria": { + "message": "Repository lookup and miss-path benchmark results" + }, + "bench.table.lookup": { + "message": "Lookup" + }, + "bench.table.peerCount": { + "message": "{count} peers" + }, + "bench.page.title": { + "message": "Benchmarks" + }, + "bench.page.description": { + "message": "Benchmark dashboard for TunGo dataplane throughput, latency, repository lookup costs, and egress contention." + }, + "bench.hero.lead": { + "message": "Manual snapshot measured on {machine} with {goVersion}." + }, + "bench.metric.throughput": { + "message": "Throughput" + }, + "bench.metric.throughputNote": { + "message": "Best full-cycle path" + }, + "bench.metric.latency": { + "message": "Latency" + }, + "bench.metric.latencyNote": { + "message": "Lowest full-cycle path" + }, + "bench.metric.lookup": { + "message": "Fast-path lookup" + }, + "bench.metric.lookupNote": { + "message": "Flat through 10k peers" + }, + "bench.metric.allocs": { + "message": "Allocs/op" + }, + "bench.metric.allocsNote": { + "message": "Hot path" + }, + "bench.summary.egress": { + "message": "Egress lane" + }, + "bench.summary.egressNote": { + "message": "Uncontended to contended sends" + }, + "bench.summary.missPath": { + "message": "Miss path" + }, + "bench.summary.linear": { + "message": "Linear" + }, + "bench.summary.missPathNote": { + "message": "~35 ns at 1 peer -> ~89.5 μs at 10k peers" + }, + "footer.iconsBy": { + "message": "Icons by" + }, + "footer.builtWith": { + "message": "Built with" + }, + "footer.contributors": { + "message": "TunGo Contributors" } } diff --git a/docs/TunGo/i18n/en/docusaurus-theme-classic/navbar.json b/docs/TunGo/i18n/en/docusaurus-theme-classic/navbar.json index ef45984a4..fd59465e9 100644 --- a/docs/TunGo/i18n/en/docusaurus-theme-classic/navbar.json +++ b/docs/TunGo/i18n/en/docusaurus-theme-classic/navbar.json @@ -11,6 +11,10 @@ "message": "Tutorial", "description": "Navbar item with label Tutorial" }, + "item.label.Benchmarks": { + "message": "Benchmarks", + "description": "Navbar item with label Benchmarks" + }, "item.label.GitHub": { "message": "GitHub", "description": "Navbar item with label GitHub" diff --git a/docs/TunGo/i18n/es/code.json b/docs/TunGo/i18n/es/code.json index 186cc7d0b..b091bd6ad 100644 --- a/docs/TunGo/i18n/es/code.json +++ b/docs/TunGo/i18n/es/code.json @@ -9,39 +9,186 @@ "message": "Asegura tu conexión con TunGo: VPN ligera, rápida y de código abierto construida en Go con criptografía moderna." }, "feature.cpuFast.title": { - "message": "CPU-Rápido" + "message": "Rápido" }, "feature.cpuFast.description": { - "message": "Sin asignaciones en tiempo de ejecución. Uso de CPU insignificante bajo carga." + "message": "0 allocs/op en el hot path." }, "feature.ramEfficient.title": { - "message": "RAM-Eficiente" + "message": "Memoria" }, "feature.ramEfficient.description": { - "message": "≈5–15 MB RSS bajo carga, ≈5–8 MB en reposo" + "message": "≈5–15 MB RSS bajo carga." }, "feature.secure.title": { - "message": "Seguro" + "message": "Cripto" }, "feature.secure.description": { - "message": "Handshake Noise IK, acuerdo de claves X25519, AEAD ChaCha20-Poly1305" + "message": "Noise IK, X25519, ChaCha20-Poly1305." }, "feature.multiTransport.title": { - "message": "Soporte Multi-Transporte" + "message": "Transportes" }, "feature.multiTransport.description": { - "message": "UDP — alto rendimiento, TCP — respaldo confiable, WebSocket/WSS — modo sigiloso" + "message": "UDP, TCP, WebSocket/WSS." }, "feature.platforms.title": { - "message": "Plataformas Soportadas" + "message": "Plataformas" }, "feature.platforms.description": { - "message": "Linux (cliente y servidor), macOS (cliente), Windows (cliente)" + "message": "Linux, macOS, Windows." }, "feature.openSource.title": { - "message": "Código Abierto" + "message": "OSS" }, "feature.openSource.description": { - "message": "Licencia: AGPLv3" + "message": "Con licencia AGPLv3." + }, + "homepage.heroTitle.prefix": { + "message": "Rápido y ligero" + }, + "homepage.heroTitle.suffix": { + "message": "VPN en espacio de usuario" + }, + "homepage.benchmarksCta": { + "message": "Ver benchmarks" + }, + "bench.hero.title": { + "message": "Instantánea de benchmarks" + }, + "bench.section.fullCycle.title": { + "message": "Dataplane de ciclo completo" + }, + "bench.section.fullCycle.text": { + "message": "Cifrado, lookup, validación, descifrado, handoff. Límite superior del núcleo del dataplane, no del throughput VPN extremo a extremo." + }, + "bench.section.scaling.title": { + "message": "Escalado UDP multi-peer" + }, + "bench.section.scaling.text": { + "message": "Throughput agregado con el trabajo distribuido entre muchos peers, no en una sola línea de envío serializada." + }, + "bench.chart.aggregateThroughput": { + "message": "Throughput agregado" + }, + "bench.section.lookup.title": { + "message": "Lookup y serialización" + }, + "bench.section.lookup.text": { + "message": "Los lookups por IP interna, allowed-host y route-ID se mantienen planos. Los misses y la serialización por peer son los verdaderos puntos de presión." + }, + "bench.transport.udp": { + "message": "UDP" + }, + "bench.transport.tcp": { + "message": "TCP" + }, + "bench.direction.clientServer": { + "message": "Cliente -> Servidor" + }, + "bench.direction.serverClient": { + "message": "Servidor -> Cliente" + }, + "bench.parallel.clientServer": { + "message": "UDP Cliente -> Servidor" + }, + "bench.parallel.serverClient": { + "message": "UDP Servidor -> Cliente" + }, + "bench.lookup.exactInternal": { + "message": "Lookup interno exacto" + }, + "bench.lookup.allowedHost": { + "message": "Lookup de allowed host" + }, + "bench.lookup.routeId": { + "message": "Lookup de Route ID" + }, + "bench.legend.peers": { + "message": "{count} peers" + }, + "bench.table.fullCycleAria": { + "message": "Resultados del benchmark del dataplane de ciclo completo" + }, + "bench.table.path": { + "message": "Ruta" + }, + "bench.table.latency": { + "message": "Latencia" + }, + "bench.table.throughput": { + "message": "Throughput" + }, + "bench.table.allocs": { + "message": "Allocs/op" + }, + "bench.lookup.missPath": { + "message": "Miss path" + }, + "bench.table.lookupAria": { + "message": "Resultados del benchmark de lookup de repositorio y miss path" + }, + "bench.table.lookup": { + "message": "Lookup" + }, + "bench.table.peerCount": { + "message": "{count} peers" + }, + "bench.page.title": { + "message": "Benchmarks" + }, + "bench.page.description": { + "message": "Panel de benchmarks del dataplane de TunGo: throughput, latencia, coste de lookups del repositorio y contención en egress." + }, + "bench.hero.lead": { + "message": "Instantánea manual medida en {machine} con {goVersion}." + }, + "bench.metric.throughput": { + "message": "Throughput" + }, + "bench.metric.throughputNote": { + "message": "Mejor ruta full-cycle" + }, + "bench.metric.latency": { + "message": "Latencia" + }, + "bench.metric.latencyNote": { + "message": "Ruta full-cycle más baja" + }, + "bench.metric.lookup": { + "message": "Fast-path lookup" + }, + "bench.metric.lookupNote": { + "message": "Plano hasta 10k peers" + }, + "bench.metric.allocs": { + "message": "Allocs/op" + }, + "bench.metric.allocsNote": { + "message": "Hot path" + }, + "bench.summary.egress": { + "message": "Canal de egress" + }, + "bench.summary.egressNote": { + "message": "De envíos sin contención a contención" + }, + "bench.summary.missPath": { + "message": "Miss path" + }, + "bench.summary.linear": { + "message": "Lineal" + }, + "bench.summary.missPathNote": { + "message": "~35 ns con 1 peer -> ~89.5 μs con 10k peers" + }, + "footer.iconsBy": { + "message": "Iconos de" + }, + "footer.builtWith": { + "message": "Hecho con" + }, + "footer.contributors": { + "message": "Colaboradores de TunGo" } } diff --git a/docs/TunGo/i18n/es/docusaurus-theme-classic/navbar.json b/docs/TunGo/i18n/es/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000..4585da33a --- /dev/null +++ b/docs/TunGo/i18n/es/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "item.label.Tutorial": { + "message": "Tutorial", + "description": "Navbar item with label Tutorial" + }, + "item.label.Benchmarks": { + "message": "Benchmarks", + "description": "Navbar item with label Benchmarks" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/docs/TunGo/i18n/fr/code.json b/docs/TunGo/i18n/fr/code.json index 9b868c96c..0958acb18 100644 --- a/docs/TunGo/i18n/fr/code.json +++ b/docs/TunGo/i18n/fr/code.json @@ -9,39 +9,186 @@ "message": "Sécurisez votre connexion avec TunGo : VPN léger, rapide et open-source construit en Go avec une cryptographie moderne." }, "feature.cpuFast.title": { - "message": "CPU-Rapide" + "message": "Rapide" }, "feature.cpuFast.description": { - "message": "Aucune allocation à l'exécution. Utilisation CPU négligeable sous charge." + "message": "0 allocs/op sur le hot path." }, "feature.ramEfficient.title": { - "message": "RAM-Efficace" + "message": "Mémoire" }, "feature.ramEfficient.description": { - "message": "≈5–15 Mo RSS sous charge, ≈5–8 Mo au repos" + "message": "≈5–15 MB RSS sous charge." }, "feature.secure.title": { - "message": "Sécurisé" + "message": "Crypto" }, "feature.secure.description": { - "message": "Handshake Noise IK, échange de clés X25519, AEAD ChaCha20-Poly1305" + "message": "Noise IK, X25519, ChaCha20-Poly1305." }, "feature.multiTransport.title": { - "message": "Support Multi-Transport" + "message": "Transports" }, "feature.multiTransport.description": { - "message": "UDP — haute performance, TCP — solution de repli fiable, WebSocket/WSS — mode furtif" + "message": "UDP, TCP, WebSocket/WSS." }, "feature.platforms.title": { - "message": "Plateformes Supportées" + "message": "Plateformes" }, "feature.platforms.description": { - "message": "Linux (client et serveur), macOS (client), Windows (client)" + "message": "Linux, macOS, Windows." }, "feature.openSource.title": { - "message": "Open Source" + "message": "OSS" }, "feature.openSource.description": { - "message": "Licence : AGPLv3" + "message": "Sous licence AGPLv3." + }, + "homepage.heroTitle.prefix": { + "message": "Rapide et léger" + }, + "homepage.heroTitle.suffix": { + "message": "VPN en espace utilisateur" + }, + "homepage.benchmarksCta": { + "message": "Voir les benchmarks" + }, + "bench.hero.title": { + "message": "Instantané des benchmarks" + }, + "bench.section.fullCycle.title": { + "message": "Dataplane en cycle complet" + }, + "bench.section.fullCycle.text": { + "message": "Chiffrement, lookup, validation, déchiffrement, handoff. Limite supérieure pour le cœur du dataplane, pas pour le débit VPN de bout en bout." + }, + "bench.section.scaling.title": { + "message": "Mise à l’échelle UDP multi-peer" + }, + "bench.section.scaling.text": { + "message": "Débit agrégé avec le travail réparti sur de nombreux peers, et non sur une seule voie d’envoi sérialisée." + }, + "bench.chart.aggregateThroughput": { + "message": "Débit agrégé" + }, + "bench.section.lookup.title": { + "message": "Lookup et sérialisation" + }, + "bench.section.lookup.text": { + "message": "Les lookups par IP interne, allowed-host et route-ID restent plats. Les misses et la sérialisation par peer sont les vrais points de pression." + }, + "bench.transport.udp": { + "message": "UDP" + }, + "bench.transport.tcp": { + "message": "TCP" + }, + "bench.direction.clientServer": { + "message": "Client -> Serveur" + }, + "bench.direction.serverClient": { + "message": "Serveur -> Client" + }, + "bench.parallel.clientServer": { + "message": "UDP Client -> Serveur" + }, + "bench.parallel.serverClient": { + "message": "UDP Serveur -> Client" + }, + "bench.lookup.exactInternal": { + "message": "Lookup interne exact" + }, + "bench.lookup.allowedHost": { + "message": "Lookup allowed host" + }, + "bench.lookup.routeId": { + "message": "Lookup Route ID" + }, + "bench.legend.peers": { + "message": "{count} peers" + }, + "bench.table.fullCycleAria": { + "message": "Résultats du benchmark dataplane en cycle complet" + }, + "bench.table.path": { + "message": "Chemin" + }, + "bench.table.latency": { + "message": "Latence" + }, + "bench.table.throughput": { + "message": "Débit" + }, + "bench.table.allocs": { + "message": "Allocs/op" + }, + "bench.lookup.missPath": { + "message": "Miss path" + }, + "bench.table.lookupAria": { + "message": "Résultats du benchmark de lookup du dépôt et du miss path" + }, + "bench.table.lookup": { + "message": "Lookup" + }, + "bench.table.peerCount": { + "message": "{count} peers" + }, + "bench.page.title": { + "message": "Benchmarks" + }, + "bench.page.description": { + "message": "Tableau de benchmarks du dataplane TunGo : débit, latence, coût des lookups du dépôt et contention en egress." + }, + "bench.hero.lead": { + "message": "Instantané manuel mesuré sur {machine} avec {goVersion}." + }, + "bench.metric.throughput": { + "message": "Débit" + }, + "bench.metric.throughputNote": { + "message": "Meilleur chemin en cycle complet" + }, + "bench.metric.latency": { + "message": "Latence" + }, + "bench.metric.latencyNote": { + "message": "Chemin en cycle complet le plus bas" + }, + "bench.metric.lookup": { + "message": "Lookup fast-path" + }, + "bench.metric.lookupNote": { + "message": "Plat jusqu’à 10k peers" + }, + "bench.metric.allocs": { + "message": "Allocs/op" + }, + "bench.metric.allocsNote": { + "message": "Hot path" + }, + "bench.summary.egress": { + "message": "Voie egress" + }, + "bench.summary.egressNote": { + "message": "Envois sans contention à contention" + }, + "bench.summary.missPath": { + "message": "Miss path" + }, + "bench.summary.linear": { + "message": "Linéaire" + }, + "bench.summary.missPathNote": { + "message": "~35 ns à 1 peer -> ~89.5 μs à 10k peers" + }, + "footer.iconsBy": { + "message": "Icônes par" + }, + "footer.builtWith": { + "message": "Construit avec" + }, + "footer.contributors": { + "message": "Contributeurs TunGo" } } diff --git a/docs/TunGo/i18n/fr/docusaurus-theme-classic/navbar.json b/docs/TunGo/i18n/fr/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000..36c57af3c --- /dev/null +++ b/docs/TunGo/i18n/fr/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "item.label.Tutorial": { + "message": "Tutoriel", + "description": "Navbar item with label Tutorial" + }, + "item.label.Benchmarks": { + "message": "Benchmarks", + "description": "Navbar item with label Benchmarks" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/docs/TunGo/i18n/id/code.json b/docs/TunGo/i18n/id/code.json index 9ab6f559b..ccb3906c5 100644 --- a/docs/TunGo/i18n/id/code.json +++ b/docs/TunGo/i18n/id/code.json @@ -9,39 +9,186 @@ "message": "Amankan koneksi Anda dengan TunGo: VPN ringan, cepat, open-source yang dibangun dengan Go menggunakan kriptografi modern." }, "feature.cpuFast.title": { - "message": "CPU-Cepat" + "message": "Cepat" }, "feature.cpuFast.description": { - "message": "Tanpa alokasi runtime. Penggunaan CPU dapat diabaikan saat beban." + "message": "0 allocs/op pada hot path." }, "feature.ramEfficient.title": { - "message": "RAM-Efisien" + "message": "Memori" }, "feature.ramEfficient.description": { - "message": "≈5–15 MB RSS saat beban, ≈5–8 MB saat idle" + "message": "≈5–15 MB RSS saat beban." }, "feature.secure.title": { - "message": "Aman" + "message": "Kripto" }, "feature.secure.description": { - "message": "Handshake Noise IK, pertukaran kunci X25519, AEAD ChaCha20-Poly1305" + "message": "Noise IK, X25519, ChaCha20-Poly1305." }, "feature.multiTransport.title": { - "message": "Dukungan Multi-Transport" + "message": "Transport" }, "feature.multiTransport.description": { - "message": "UDP — performa tinggi, TCP — fallback andal, WebSocket/WSS — mode siluman" + "message": "UDP, TCP, WebSocket/WSS." }, "feature.platforms.title": { - "message": "Platform yang Didukung" + "message": "Platform" }, "feature.platforms.description": { - "message": "Linux (klien dan server), macOS (klien), Windows (klien)" + "message": "Linux, macOS, Windows." }, "feature.openSource.title": { - "message": "Open Source" + "message": "OSS" }, "feature.openSource.description": { - "message": "Lisensi: AGPLv3" + "message": "Berlisensi AGPLv3." + }, + "homepage.heroTitle.prefix": { + "message": "Cepat dan ringan" + }, + "homepage.heroTitle.suffix": { + "message": "VPN userspace" + }, + "homepage.benchmarksCta": { + "message": "Lihat benchmark" + }, + "bench.hero.title": { + "message": "Snapshot benchmark" + }, + "bench.section.fullCycle.title": { + "message": "Dataplane siklus penuh" + }, + "bench.section.fullCycle.text": { + "message": "Enkripsi, lookup, validasi, dekripsi, handoff. Batas atas untuk inti dataplane, bukan throughput VPN end-to-end." + }, + "bench.section.scaling.title": { + "message": "Penskalaan UDP multi-peer" + }, + "bench.section.scaling.text": { + "message": "Throughput agregat dengan pekerjaan yang tersebar di banyak peer, bukan satu jalur kirim terserialisasi." + }, + "bench.chart.aggregateThroughput": { + "message": "Throughput agregat" + }, + "bench.section.lookup.title": { + "message": "Lookup dan serialisasi" + }, + "bench.section.lookup.text": { + "message": "Lookup internal-IP, allowed-host, dan route-ID tetap datar. Misses dan serialisasi per peer adalah titik tekanan yang sebenarnya." + }, + "bench.transport.udp": { + "message": "UDP" + }, + "bench.transport.tcp": { + "message": "TCP" + }, + "bench.direction.clientServer": { + "message": "Klien -> Server" + }, + "bench.direction.serverClient": { + "message": "Server -> Klien" + }, + "bench.parallel.clientServer": { + "message": "UDP Klien -> Server" + }, + "bench.parallel.serverClient": { + "message": "UDP Server -> Klien" + }, + "bench.lookup.exactInternal": { + "message": "Lookup internal yang tepat" + }, + "bench.lookup.allowedHost": { + "message": "Lookup allowed host" + }, + "bench.lookup.routeId": { + "message": "Lookup Route ID" + }, + "bench.legend.peers": { + "message": "{count} peer" + }, + "bench.table.fullCycleAria": { + "message": "Hasil benchmark dataplane siklus penuh" + }, + "bench.table.path": { + "message": "Jalur" + }, + "bench.table.latency": { + "message": "Latensi" + }, + "bench.table.throughput": { + "message": "Throughput" + }, + "bench.table.allocs": { + "message": "Allocs/op" + }, + "bench.lookup.missPath": { + "message": "Miss path" + }, + "bench.table.lookupAria": { + "message": "Hasil benchmark lookup repositori dan miss path" + }, + "bench.table.lookup": { + "message": "Lookup" + }, + "bench.table.peerCount": { + "message": "{count} peer" + }, + "bench.page.title": { + "message": "Benchmark" + }, + "bench.page.description": { + "message": "Dashboard benchmark dataplane TunGo: throughput, latensi, biaya lookup repositori, dan contention pada egress." + }, + "bench.hero.lead": { + "message": "Snapshot manual yang diukur pada {machine} dengan {goVersion}." + }, + "bench.metric.throughput": { + "message": "Throughput" + }, + "bench.metric.throughputNote": { + "message": "Jalur full-cycle terbaik" + }, + "bench.metric.latency": { + "message": "Latensi" + }, + "bench.metric.latencyNote": { + "message": "Jalur full-cycle terendah" + }, + "bench.metric.lookup": { + "message": "Lookup fast-path" + }, + "bench.metric.lookupNote": { + "message": "Tetap datar hingga 10k peer" + }, + "bench.metric.allocs": { + "message": "Allocs/op" + }, + "bench.metric.allocsNote": { + "message": "Hot path" + }, + "bench.summary.egress": { + "message": "Jalur egress" + }, + "bench.summary.egressNote": { + "message": "Dari kirim tanpa contention ke contention" + }, + "bench.summary.missPath": { + "message": "Miss path" + }, + "bench.summary.linear": { + "message": "Linear" + }, + "bench.summary.missPathNote": { + "message": "~35 ns pada 1 peer -> ~89.5 μs pada 10k peer" + }, + "footer.iconsBy": { + "message": "Ikon oleh" + }, + "footer.builtWith": { + "message": "Dibangun dengan" + }, + "footer.contributors": { + "message": "Kontributor TunGo" } } diff --git a/docs/TunGo/i18n/id/docusaurus-theme-classic/navbar.json b/docs/TunGo/i18n/id/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000..cf5b10153 --- /dev/null +++ b/docs/TunGo/i18n/id/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "item.label.Tutorial": { + "message": "Tutorial", + "description": "Navbar item with label Tutorial" + }, + "item.label.Benchmarks": { + "message": "Benchmark", + "description": "Navbar item with label Benchmarks" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/docs/TunGo/i18n/ja/code.json b/docs/TunGo/i18n/ja/code.json index 967374ac0..9f19418be 100644 --- a/docs/TunGo/i18n/ja/code.json +++ b/docs/TunGo/i18n/ja/code.json @@ -9,39 +9,186 @@ "message": "TunGo で接続を保護:最新の暗号技術を使用し Go で構築された軽量、高速、オープンソース VPN。" }, "feature.cpuFast.title": { - "message": "CPU 高速" + "message": "高速" }, "feature.cpuFast.description": { - "message": "ランタイムアロケーションなし。負荷時の CPU 使用率はごくわずか。" + "message": "ホットパスで 0 allocs/op。" }, "feature.ramEfficient.title": { - "message": "RAM 効率的" + "message": "メモリ" }, "feature.ramEfficient.description": { - "message": "負荷時 ≈5–15 MB RSS、アイドル時 ≈5–8 MB" + "message": "高負荷時 ≈5–15 MB RSS。" }, "feature.secure.title": { - "message": "セキュア" + "message": "暗号" }, "feature.secure.description": { - "message": "Noise IK ハンドシェイク、X25519 鍵交換、ChaCha20-Poly1305 AEAD" + "message": "Noise IK、X25519、ChaCha20-Poly1305。" }, "feature.multiTransport.title": { - "message": "マルチトランスポート対応" + "message": "トランスポート" }, "feature.multiTransport.description": { - "message": "UDP — 高性能、TCP — 信頼性の高いフォールバック、WebSocket/WSS — ステルスモード" + "message": "UDP、TCP、WebSocket/WSS。" }, "feature.platforms.title": { - "message": "対応プラットフォーム" + "message": "プラットフォーム" }, "feature.platforms.description": { - "message": "Linux(クライアント&サーバー)、macOS(クライアント)、Windows(クライアント)" + "message": "Linux、macOS、Windows。" }, "feature.openSource.title": { - "message": "オープンソース" + "message": "OSS" }, "feature.openSource.description": { - "message": "ライセンス:AGPLv3" + "message": "AGPLv3 ライセンス。" + }, + "homepage.heroTitle.prefix": { + "message": "高速で軽量な" + }, + "homepage.heroTitle.suffix": { + "message": "ユーザースペース VPN" + }, + "homepage.benchmarksCta": { + "message": "ベンチマークを見る" + }, + "bench.hero.title": { + "message": "ベンチマークスナップショット" + }, + "bench.section.fullCycle.title": { + "message": "フルサイクル dataplane" + }, + "bench.section.fullCycle.text": { + "message": "暗号化、lookup、検証、復号、handoff。これは dataplane コアの上限であり、エンドツーエンド VPN スループットではありません。" + }, + "bench.section.scaling.title": { + "message": "マルチピア UDP スケーリング" + }, + "bench.section.scaling.text": { + "message": "単一の直列化された送信レーンではなく、多数のピアに作業を分散したときの集約スループット。" + }, + "bench.chart.aggregateThroughput": { + "message": "集約スループット" + }, + "bench.section.lookup.title": { + "message": "Lookup とシリアライズ" + }, + "bench.section.lookup.text": { + "message": "Internal-IP、allowed-host、route-ID の lookup は安定しています。ミスと peer ごとのシリアライズが本当の圧力点です。" + }, + "bench.transport.udp": { + "message": "UDP" + }, + "bench.transport.tcp": { + "message": "TCP" + }, + "bench.direction.clientServer": { + "message": "クライアント -> サーバー" + }, + "bench.direction.serverClient": { + "message": "サーバー -> クライアント" + }, + "bench.parallel.clientServer": { + "message": "UDP クライアント -> サーバー" + }, + "bench.parallel.serverClient": { + "message": "UDP サーバー -> クライアント" + }, + "bench.lookup.exactInternal": { + "message": "正確な internal lookup" + }, + "bench.lookup.allowedHost": { + "message": "allowed host lookup" + }, + "bench.lookup.routeId": { + "message": "Route ID lookup" + }, + "bench.legend.peers": { + "message": "{count} ピア" + }, + "bench.table.fullCycleAria": { + "message": "フルサイクル dataplane ベンチマーク結果" + }, + "bench.table.path": { + "message": "パス" + }, + "bench.table.latency": { + "message": "レイテンシ" + }, + "bench.table.throughput": { + "message": "スループット" + }, + "bench.table.allocs": { + "message": "Allocs/op" + }, + "bench.lookup.missPath": { + "message": "Miss path" + }, + "bench.table.lookupAria": { + "message": "リポジトリ lookup と miss path のベンチマーク結果" + }, + "bench.table.lookup": { + "message": "Lookup" + }, + "bench.table.peerCount": { + "message": "{count} ピア" + }, + "bench.page.title": { + "message": "ベンチマーク" + }, + "bench.page.description": { + "message": "TunGo dataplane のスループット、レイテンシ、リポジトリ lookup コスト、egress contention のベンチマークダッシュボード。" + }, + "bench.hero.lead": { + "message": "{machine} / {goVersion} で手動計測したスナップショット。" + }, + "bench.metric.throughput": { + "message": "スループット" + }, + "bench.metric.throughputNote": { + "message": "最良の full-cycle パス" + }, + "bench.metric.latency": { + "message": "レイテンシ" + }, + "bench.metric.latencyNote": { + "message": "最小の full-cycle パス" + }, + "bench.metric.lookup": { + "message": "Fast-path lookup" + }, + "bench.metric.lookupNote": { + "message": "10kピアまで横ばい" + }, + "bench.metric.allocs": { + "message": "Allocs/op" + }, + "bench.metric.allocsNote": { + "message": "Hot path" + }, + "bench.summary.egress": { + "message": "Egress レーン" + }, + "bench.summary.egressNote": { + "message": "競合なし送信から競合あり送信へ" + }, + "bench.summary.missPath": { + "message": "Miss path" + }, + "bench.summary.linear": { + "message": "線形" + }, + "bench.summary.missPathNote": { + "message": "1ピアで ~35 ns -> 10kピアで ~89.5 μs" + }, + "footer.iconsBy": { + "message": "アイコン提供" + }, + "footer.builtWith": { + "message": "使用技術" + }, + "footer.contributors": { + "message": "TunGo コントリビューター" } } diff --git a/docs/TunGo/i18n/ja/docusaurus-theme-classic/navbar.json b/docs/TunGo/i18n/ja/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000..ecf000beb --- /dev/null +++ b/docs/TunGo/i18n/ja/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "item.label.Tutorial": { + "message": "チュートリアル", + "description": "Navbar item with label Tutorial" + }, + "item.label.Benchmarks": { + "message": "ベンチマーク", + "description": "Navbar item with label Benchmarks" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/docs/TunGo/i18n/pt/code.json b/docs/TunGo/i18n/pt/code.json index 70e0e7a0f..cf6300907 100644 --- a/docs/TunGo/i18n/pt/code.json +++ b/docs/TunGo/i18n/pt/code.json @@ -9,39 +9,186 @@ "message": "Proteja sua conexão com TunGo: VPN leve, rápida e de código aberto construída em Go com criptografia moderna." }, "feature.cpuFast.title": { - "message": "CPU-Rápido" + "message": "Rápida" }, "feature.cpuFast.description": { - "message": "Sem alocações em tempo de execução. Uso de CPU desprezível sob carga." + "message": "0 allocs/op no hot path." }, "feature.ramEfficient.title": { - "message": "RAM-Eficiente" + "message": "Memória" }, "feature.ramEfficient.description": { - "message": "≈5–15 MB RSS sob carga, ≈5–8 MB em repouso" + "message": "≈5–15 MB RSS sob carga." }, "feature.secure.title": { - "message": "Seguro" + "message": "Cripto" }, "feature.secure.description": { - "message": "Handshake Noise IK, acordo de chaves X25519, AEAD ChaCha20-Poly1305" + "message": "Noise IK, X25519, ChaCha20-Poly1305." }, "feature.multiTransport.title": { - "message": "Suporte Multi-Transporte" + "message": "Transportes" }, "feature.multiTransport.description": { - "message": "UDP — alto desempenho, TCP — fallback confiável, WebSocket/WSS — modo furtivo" + "message": "UDP, TCP, WebSocket/WSS." }, "feature.platforms.title": { - "message": "Plataformas Suportadas" + "message": "Plataformas" }, "feature.platforms.description": { - "message": "Linux (cliente e servidor), macOS (cliente), Windows (cliente)" + "message": "Linux, macOS, Windows." }, "feature.openSource.title": { - "message": "Código Aberto" + "message": "OSS" }, "feature.openSource.description": { - "message": "Licença: AGPLv3" + "message": "Licenciada sob AGPLv3." + }, + "homepage.heroTitle.prefix": { + "message": "Rápida e leve" + }, + "homepage.heroTitle.suffix": { + "message": "VPN em espaço de usuário" + }, + "homepage.benchmarksCta": { + "message": "Ver benchmarks" + }, + "bench.hero.title": { + "message": "Snapshot de benchmarks" + }, + "bench.section.fullCycle.title": { + "message": "Dataplane de ciclo completo" + }, + "bench.section.fullCycle.text": { + "message": "Criptografar, lookup, validar, descriptografar, handoff. Limite superior para o núcleo do dataplane, não para o throughput VPN fim a fim." + }, + "bench.section.scaling.title": { + "message": "Escalonamento UDP multi-peer" + }, + "bench.section.scaling.text": { + "message": "Throughput agregado com o trabalho distribuído entre muitos peers, não em uma única trilha de envio serializada." + }, + "bench.chart.aggregateThroughput": { + "message": "Throughput agregado" + }, + "bench.section.lookup.title": { + "message": "Lookup e serialização" + }, + "bench.section.lookup.text": { + "message": "Lookups por IP interno, allowed-host e route-ID permanecem estáveis. Misses e serialização por peer são os verdadeiros pontos de pressão." + }, + "bench.transport.udp": { + "message": "UDP" + }, + "bench.transport.tcp": { + "message": "TCP" + }, + "bench.direction.clientServer": { + "message": "Cliente -> Servidor" + }, + "bench.direction.serverClient": { + "message": "Servidor -> Cliente" + }, + "bench.parallel.clientServer": { + "message": "UDP Cliente -> Servidor" + }, + "bench.parallel.serverClient": { + "message": "UDP Servidor -> Cliente" + }, + "bench.lookup.exactInternal": { + "message": "Lookup interno exato" + }, + "bench.lookup.allowedHost": { + "message": "Lookup de allowed host" + }, + "bench.lookup.routeId": { + "message": "Lookup de Route ID" + }, + "bench.legend.peers": { + "message": "{count} peers" + }, + "bench.table.fullCycleAria": { + "message": "Resultados do benchmark do dataplane de ciclo completo" + }, + "bench.table.path": { + "message": "Caminho" + }, + "bench.table.latency": { + "message": "Latência" + }, + "bench.table.throughput": { + "message": "Throughput" + }, + "bench.table.allocs": { + "message": "Allocs/op" + }, + "bench.lookup.missPath": { + "message": "Miss path" + }, + "bench.table.lookupAria": { + "message": "Resultados do benchmark de lookup de repositório e miss path" + }, + "bench.table.lookup": { + "message": "Lookup" + }, + "bench.table.peerCount": { + "message": "{count} peers" + }, + "bench.page.title": { + "message": "Benchmarks" + }, + "bench.page.description": { + "message": "Painel de benchmarks do dataplane TunGo: throughput, latência, custo de lookup no repositório e contenção no egress." + }, + "bench.hero.lead": { + "message": "Snapshot manual medido em {machine} com {goVersion}." + }, + "bench.metric.throughput": { + "message": "Throughput" + }, + "bench.metric.throughputNote": { + "message": "Melhor caminho full-cycle" + }, + "bench.metric.latency": { + "message": "Latência" + }, + "bench.metric.latencyNote": { + "message": "Menor caminho full-cycle" + }, + "bench.metric.lookup": { + "message": "Fast-path lookup" + }, + "bench.metric.lookupNote": { + "message": "Estável até 10k peers" + }, + "bench.metric.allocs": { + "message": "Allocs/op" + }, + "bench.metric.allocsNote": { + "message": "Hot path" + }, + "bench.summary.egress": { + "message": "Faixa de egress" + }, + "bench.summary.egressNote": { + "message": "De envios sem contenção a com contenção" + }, + "bench.summary.missPath": { + "message": "Miss path" + }, + "bench.summary.linear": { + "message": "Linear" + }, + "bench.summary.missPathNote": { + "message": "~35 ns em 1 peer -> ~89.5 μs em 10k peers" + }, + "footer.iconsBy": { + "message": "Ícones por" + }, + "footer.builtWith": { + "message": "Construído com" + }, + "footer.contributors": { + "message": "Contribuidores do TunGo" } } diff --git a/docs/TunGo/i18n/pt/docusaurus-theme-classic/navbar.json b/docs/TunGo/i18n/pt/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000..4585da33a --- /dev/null +++ b/docs/TunGo/i18n/pt/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "item.label.Tutorial": { + "message": "Tutorial", + "description": "Navbar item with label Tutorial" + }, + "item.label.Benchmarks": { + "message": "Benchmarks", + "description": "Navbar item with label Benchmarks" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/docs/TunGo/i18n/ru/code.json b/docs/TunGo/i18n/ru/code.json index 5fb999bed..cd9f73771 100644 --- a/docs/TunGo/i18n/ru/code.json +++ b/docs/TunGo/i18n/ru/code.json @@ -9,39 +9,186 @@ "message": "Защитите своё соединение с TunGo: лёгкий, быстрый VPN с открытым исходным кодом, написанный на Go с использованием современной криптографии." }, "feature.cpuFast.title": { - "message": "Быстрый CPU" + "message": "Быстрый" }, "feature.cpuFast.description": { - "message": "Нет аллокаций во время выполнения. Незначительное использование CPU под нагрузкой." + "message": "0 allocs/op на hot path." }, "feature.ramEfficient.title": { - "message": "Эффективная RAM" + "message": "Память" }, "feature.ramEfficient.description": { - "message": "≈5–15 МБ RSS под нагрузкой, ≈5–8 МБ в покое" + "message": "≈5–15 МБ RSS под нагрузкой." }, "feature.secure.title": { - "message": "Безопасный" + "message": "Криптография" }, "feature.secure.description": { - "message": "Хендшейк Noise IK, обмен ключами X25519, AEAD ChaCha20-Poly1305" + "message": "Noise IK, X25519, ChaCha20-Poly1305." }, "feature.multiTransport.title": { - "message": "Поддержка нескольких транспортов" + "message": "Транспорты" }, "feature.multiTransport.description": { - "message": "UDP — высокая производительность, TCP — надёжный резерв, WebSocket/WSS — режим скрытности" + "message": "UDP, TCP, WebSocket/WSS." }, "feature.platforms.title": { - "message": "Поддерживаемые платформы" + "message": "Платформы" }, "feature.platforms.description": { - "message": "Linux (клиент и сервер), macOS (клиент), Windows (клиент)" + "message": "Linux, macOS, Windows." }, "feature.openSource.title": { - "message": "Открытый исходный код" + "message": "Open source" }, "feature.openSource.description": { - "message": "Лицензия: AGPLv3" + "message": "Лицензия AGPLv3." + }, + "homepage.heroTitle.prefix": { + "message": "Быстрый и лёгкий" + }, + "homepage.heroTitle.suffix": { + "message": "userspace VPN" + }, + "homepage.benchmarksCta": { + "message": "Смотреть бенчмарки" + }, + "bench.hero.title": { + "message": "Снимок бенчмарков" + }, + "bench.section.fullCycle.title": { + "message": "Полный dataplane-цикл" + }, + "bench.section.fullCycle.text": { + "message": "Шифрование, lookup, валидация, дешифрование, handoff. Верхняя граница для ядра dataplane, а не сквозной пропускной способности VPN." + }, + "bench.section.scaling.title": { + "message": "Масштабирование UDP по peer" + }, + "bench.section.scaling.text": { + "message": "Агрегированная пропускная способность при распределении работы между множеством peer, а не по одной сериализованной send-линии." + }, + "bench.chart.aggregateThroughput": { + "message": "Агрегированная пропускная способность" + }, + "bench.section.lookup.title": { + "message": "Lookup и сериализация" + }, + "bench.section.lookup.text": { + "message": "Lookup по Internal IP, allowed-host и route-ID остаются плоскими. Misses и сериализация на peer — основные точки давления." + }, + "bench.transport.udp": { + "message": "UDP" + }, + "bench.transport.tcp": { + "message": "TCP" + }, + "bench.direction.clientServer": { + "message": "Клиент -> Сервер" + }, + "bench.direction.serverClient": { + "message": "Сервер -> Клиент" + }, + "bench.parallel.clientServer": { + "message": "UDP Клиент -> Сервер" + }, + "bench.parallel.serverClient": { + "message": "UDP Сервер -> Клиент" + }, + "bench.lookup.exactInternal": { + "message": "Точный lookup по internal IP" + }, + "bench.lookup.allowedHost": { + "message": "Lookup по allowed host" + }, + "bench.lookup.routeId": { + "message": "Lookup по Route ID" + }, + "bench.legend.peers": { + "message": "{count, plural, one {# пир} few {# пира} many {# пиров} other {# пира}}" + }, + "bench.table.fullCycleAria": { + "message": "Результаты бенчмарка полного dataplane-цикла" + }, + "bench.table.path": { + "message": "Путь" + }, + "bench.table.latency": { + "message": "Задержка" + }, + "bench.table.throughput": { + "message": "Пропускная способность" + }, + "bench.table.allocs": { + "message": "Allocs/op" + }, + "bench.lookup.missPath": { + "message": "Miss path" + }, + "bench.table.lookupAria": { + "message": "Результаты бенчмарка repository lookup и miss-path" + }, + "bench.table.lookup": { + "message": "Lookup" + }, + "bench.table.peerCount": { + "message": "{count, plural, one {# пир} few {# пира} many {# пиров} other {# пира}}" + }, + "bench.page.title": { + "message": "Бенчмарки" + }, + "bench.page.description": { + "message": "Панель бенчмарков dataplane TunGo: пропускная способность, задержка, стоимость repository lookup и contention на egress." + }, + "bench.hero.lead": { + "message": "Ручной снимок, замеренный на {machine} с {goVersion}." + }, + "bench.metric.throughput": { + "message": "Пропускная способность" + }, + "bench.metric.throughputNote": { + "message": "Лучший full-cycle path" + }, + "bench.metric.latency": { + "message": "Задержка" + }, + "bench.metric.latencyNote": { + "message": "Минимальный full-cycle path" + }, + "bench.metric.lookup": { + "message": "Fast-path lookup" + }, + "bench.metric.lookupNote": { + "message": "Плоско до 10k peer" + }, + "bench.metric.allocs": { + "message": "Allocs/op" + }, + "bench.metric.allocsNote": { + "message": "Hot path" + }, + "bench.summary.egress": { + "message": "Egress-линия" + }, + "bench.summary.egressNote": { + "message": "От uncontended до contended send" + }, + "bench.summary.missPath": { + "message": "Miss path" + }, + "bench.summary.linear": { + "message": "Линейно" + }, + "bench.summary.missPathNote": { + "message": "~35 нс на 1 peer -> ~89.5 μs на 10k peer" + }, + "footer.iconsBy": { + "message": "Иконки от" + }, + "footer.builtWith": { + "message": "Собрано на" + }, + "footer.contributors": { + "message": "Участники TunGo" } } diff --git a/docs/TunGo/i18n/ru/docusaurus-theme-classic/navbar.json b/docs/TunGo/i18n/ru/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000..818ec116f --- /dev/null +++ b/docs/TunGo/i18n/ru/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "item.label.Tutorial": { + "message": "Руководство", + "description": "Navbar item with label Tutorial" + }, + "item.label.Benchmarks": { + "message": "Бенчмарки", + "description": "Navbar item with label Benchmarks" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/docs/TunGo/i18n/zh-Hans/code.json b/docs/TunGo/i18n/zh-Hans/code.json index 0e13f3ee8..a887eae77 100644 --- a/docs/TunGo/i18n/zh-Hans/code.json +++ b/docs/TunGo/i18n/zh-Hans/code.json @@ -9,39 +9,186 @@ "message": "使用 TunGo 保护您的连接:基于现代加密技术用 Go 构建的轻量级、快速、开源 VPN。" }, "feature.cpuFast.title": { - "message": "CPU 高效" + "message": "快速" }, "feature.cpuFast.description": { - "message": "零运行时内存分配。负载下 CPU 使用率可忽略不计。" + "message": "热路径上 0 allocs/op。" }, "feature.ramEfficient.title": { - "message": "内存高效" + "message": "内存" }, "feature.ramEfficient.description": { - "message": "负载下约 5–15 MB RSS,空闲时约 5–8 MB" + "message": "负载下约 5–15 MB RSS。" }, "feature.secure.title": { - "message": "安全" + "message": "密码学" }, "feature.secure.description": { - "message": "Noise IK 握手、X25519 密钥协商、ChaCha20-Poly1305 AEAD" + "message": "Noise IK、X25519、ChaCha20-Poly1305。" }, "feature.multiTransport.title": { - "message": "多传输协议支持" + "message": "传输" }, "feature.multiTransport.description": { - "message": "UDP — 高性能,TCP — 可靠备选,WebSocket/WSS — 隐身模式" + "message": "UDP、TCP、WebSocket/WSS。" }, "feature.platforms.title": { - "message": "支持的平台" + "message": "平台" }, "feature.platforms.description": { - "message": "Linux(客户端和服务器),macOS(客户端),Windows(客户端)" + "message": "Linux、macOS、Windows。" }, "feature.openSource.title": { "message": "开源" }, "feature.openSource.description": { - "message": "许可证:AGPLv3" + "message": "采用 AGPLv3 许可。" + }, + "homepage.heroTitle.prefix": { + "message": "快速轻量" + }, + "homepage.heroTitle.suffix": { + "message": "用户态 VPN" + }, + "homepage.benchmarksCta": { + "message": "查看基准测试" + }, + "bench.hero.title": { + "message": "基准测试快照" + }, + "bench.section.fullCycle.title": { + "message": "完整 dataplane 周期" + }, + "bench.section.fullCycle.text": { + "message": "加密、lookup、校验、解密、handoff。这是 dataplane 核心的上限,不是端到端 VPN 吞吐量。" + }, + "bench.section.scaling.title": { + "message": "多 peer UDP 扩展" + }, + "bench.section.scaling.text": { + "message": "工作分摊到多个 peer 时的聚合吞吐量,而不是单条串行发送通道。" + }, + "bench.chart.aggregateThroughput": { + "message": "聚合吞吐量" + }, + "bench.section.lookup.title": { + "message": "Lookup 与串行化" + }, + "bench.section.lookup.text": { + "message": "Internal-IP、allowed-host 和 route-ID lookup 保持平稳。misses 和每个 peer 的串行化才是真正的压力点。" + }, + "bench.transport.udp": { + "message": "UDP" + }, + "bench.transport.tcp": { + "message": "TCP" + }, + "bench.direction.clientServer": { + "message": "客户端 -> 服务器" + }, + "bench.direction.serverClient": { + "message": "服务器 -> 客户端" + }, + "bench.parallel.clientServer": { + "message": "UDP 客户端 -> 服务器" + }, + "bench.parallel.serverClient": { + "message": "UDP 服务器 -> 客户端" + }, + "bench.lookup.exactInternal": { + "message": "精确 internal lookup" + }, + "bench.lookup.allowedHost": { + "message": "allowed host lookup" + }, + "bench.lookup.routeId": { + "message": "Route ID lookup" + }, + "bench.legend.peers": { + "message": "{count} peers" + }, + "bench.table.fullCycleAria": { + "message": "完整 dataplane 周期基准测试结果" + }, + "bench.table.path": { + "message": "路径" + }, + "bench.table.latency": { + "message": "延迟" + }, + "bench.table.throughput": { + "message": "吞吐量" + }, + "bench.table.allocs": { + "message": "Allocs/op" + }, + "bench.lookup.missPath": { + "message": "Miss path" + }, + "bench.table.lookupAria": { + "message": "仓库 lookup 与 miss path 基准测试结果" + }, + "bench.table.lookup": { + "message": "Lookup" + }, + "bench.table.peerCount": { + "message": "{count} peers" + }, + "bench.page.title": { + "message": "基准测试" + }, + "bench.page.description": { + "message": "TunGo dataplane 吞吐量、延迟、仓库 lookup 成本和 egress 争用的基准测试面板。" + }, + "bench.hero.lead": { + "message": "在 {machine} 上使用 {goVersion} 手动测得的快照。" + }, + "bench.metric.throughput": { + "message": "吞吐量" + }, + "bench.metric.throughputNote": { + "message": "最佳 full-cycle 路径" + }, + "bench.metric.latency": { + "message": "延迟" + }, + "bench.metric.latencyNote": { + "message": "最低 full-cycle 路径" + }, + "bench.metric.lookup": { + "message": "Fast-path lookup" + }, + "bench.metric.lookupNote": { + "message": "到 10k peers 仍保持平稳" + }, + "bench.metric.allocs": { + "message": "Allocs/op" + }, + "bench.metric.allocsNote": { + "message": "Hot path" + }, + "bench.summary.egress": { + "message": "Egress 通道" + }, + "bench.summary.egressNote": { + "message": "从无争用发送到有争用发送" + }, + "bench.summary.missPath": { + "message": "Miss path" + }, + "bench.summary.linear": { + "message": "线性" + }, + "bench.summary.missPathNote": { + "message": "1 peer 时约 35 ns -> 10k peers 时约 89.5 μs" + }, + "footer.iconsBy": { + "message": "图标来自" + }, + "footer.builtWith": { + "message": "基于" + }, + "footer.contributors": { + "message": "TunGo 贡献者" } } diff --git a/docs/TunGo/i18n/zh-Hans/docusaurus-theme-classic/navbar.json b/docs/TunGo/i18n/zh-Hans/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000..feb1ee49b --- /dev/null +++ b/docs/TunGo/i18n/zh-Hans/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "item.label.Tutorial": { + "message": "教程", + "description": "Navbar item with label Tutorial" + }, + "item.label.Benchmarks": { + "message": "基准测试", + "description": "Navbar item with label Benchmarks" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/docs/TunGo/src/components/features/index.js b/docs/TunGo/src/components/features/index.js index b62411e99..ef24121cb 100644 --- a/docs/TunGo/src/components/features/index.js +++ b/docs/TunGo/src/components/features/index.js @@ -1,18 +1,26 @@ import Clsx from 'clsx'; +import Link from '@docusaurus/Link'; import Heading from '@theme/Heading'; import Translate from '@docusaurus/Translate'; import Styles from './styles.module.css'; -function Feature({Svg, title, description}) { +function Feature({Svg, title, description, to, external = false}) { return ( -
-
- -
-
- {title} -
{description}
-
+
+ +
+
+ +
+
+ {title} +
{description}
+
+
+
); } @@ -21,36 +29,43 @@ export default function Features() { return (
-
+
CPU-Fast} - description={No runtime allocations. Negligible CPU usage under load.} + title={Fast} + description={0 allocs/op on the hot path.} + to="/benchmarks" /> RAM-Efficient} - description={≈5–15 MB RSS under load, ≈5–8 MB idle} + title={Memory} + description={≈5–15 MB RSS under load.} + to="/benchmarks" /> Secure} - description={Noise IK handshake, X25519 key agreement, ChaCha20-Poly1305 AEAD} + title={Crypto} + description={Noise IK, X25519, ChaCha20-Poly1305.} + to="/docs/QuickStart" /> Multi-Transport Support} - description={UDP — high performance, TCP — reliable fallback, WebSocket/WSS — stealth mode} + title={Transports} + description={UDP, TCP, WebSocket/WSS.} + to="/docs/QuickStart" /> Supported Platforms} - description={Linux (client and server), macOS (client), Windows (client)} + title={Platforms} + description={Linux, macOS, Windows.} + to="/docs/QuickStart" /> Open Source} - description={License: AGPLv3} + title={OSS} + description={AGPLv3-licensed.} + to="https://github.com/NLipatov/TunGo" + external />
diff --git a/docs/TunGo/src/components/features/styles.module.css b/docs/TunGo/src/components/features/styles.module.css index 211c1571c..d2bfe7577 100644 --- a/docs/TunGo/src/components/features/styles.module.css +++ b/docs/TunGo/src/components/features/styles.module.css @@ -1,19 +1,148 @@ .features { - display: grid; - padding: 2rem 0; - justify-items: center; + padding: 0.05rem 0 1.8rem; +} + +.features :global(.container) { + display: block; } .featureSvg { - height: 12rem; - width: 12rem; + height: 2.2rem; + width: 2.2rem; +} + +.featureColumn { + margin-bottom: 0.55rem; +} + +.featureCardLink { + display: block; + height: 100%; + color: inherit; + text-decoration: none; +} + +.featureCardLink:hover, +.featureCardLink:focus-visible, +.featureCardLink:hover .featureTitle, +.featureCardLink:hover .featureDescription, +.featureCardLink:focus-visible .featureTitle, +.featureCardLink:focus-visible .featureDescription { + text-decoration: none; +} + +.features :global(.row) { + align-items: stretch; } -.featureDescriptionList { +.featureCard { + display: grid; + grid-template-rows: auto 1fr; + height: 100%; + border-radius: 14px; + border: 1px solid var(--ifm-color-emphasis-200); + background: var(--ifm-background-surface-color); + box-shadow: none; + padding: 0.82rem 0.85rem 0.88rem; + transition: + transform 160ms ease, + border-color 160ms ease, + background-color 160ms ease; +} + +.featureVisual { display: flex; - flex-direction: column; + justify-content: flex-start; + align-items: center; + min-height: 0; + margin-bottom: 0.72rem; +} + +[data-theme='dark'] .featureVisual { + background: transparent; +} + +.featureVisual :global(svg) { + color: var(--ifm-color-primary); + opacity: 0.9; + transition: transform 180ms ease, opacity 180ms ease, color 180ms ease; +} + +.featureBody { + padding: 0; } -.jcCenter { - justify-content: center; -} \ No newline at end of file +.featureTitle { + margin-bottom: 0.12rem; + font-size: 0.92rem; + letter-spacing: -0.015em; +} + +.featureDescription { + color: var(--ifm-color-emphasis-700); + line-height: 1.28; + font-size: 0.8rem; +} + +.featureCardLink:hover .featureCard, +.featureCardLink:focus-visible .featureCard { + transform: translateY(-1px); + border-color: var(--ifm-color-primary); + box-shadow: none; + background: var(--ifm-background-surface-color); +} + +.featureCardLink:hover .featureVisual :global(svg), +.featureCardLink:focus-visible .featureVisual :global(svg) { + transform: scale(1.02); + opacity: 1; +} + +.featureCardLink:focus-visible { + outline: none; +} + +[data-theme='dark'] .featureCardLink:hover .featureCard, +[data-theme='dark'] .featureCardLink:focus-visible .featureCard { + box-shadow: none; +} + +@media screen and (max-width: 996px) { + .features { + padding: 0 0 1.55rem; + } + + .featureColumn { + margin-bottom: 0.42rem; + } + + .featureCard { + grid-template-columns: 2.2rem minmax(0, 1fr); + grid-template-rows: auto; + align-items: start; + gap: 0.72rem; + padding: 0.78rem 0.82rem; + border-radius: 13px; + } + + .featureVisual { + margin-bottom: 0; + justify-content: center; + padding-top: 0.1rem; + } + + .featureSvg { + height: 1.7rem; + width: 1.7rem; + } + + .featureTitle { + font-size: 0.9rem; + margin-bottom: 0.08rem; + } + + .featureDescription { + font-size: 0.78rem; + line-height: 1.28; + } +} diff --git a/docs/TunGo/src/components/footer/footer.js b/docs/TunGo/src/components/footer/footer.js index 97d2d7450..16b68cc18 100644 --- a/docs/TunGo/src/components/footer/footer.js +++ b/docs/TunGo/src/components/footer/footer.js @@ -1,25 +1,26 @@ import React from 'react'; import Link from '@docusaurus/Link'; +import Translate from '@docusaurus/Translate'; import Styles from './footer.module.css'; export default function Footer() { return (

- Icons by{' '} + Icons by{' '} OpenMoji {' '} (CC BY-SA 4.0)

- Built with{' '} + Built with{' '} Docusaurus

- ©{new Date().getFullYear()} TunGo Contributors + ©{new Date().getFullYear()} TunGo Contributors

); diff --git a/docs/TunGo/src/components/footer/footer.module.css b/docs/TunGo/src/components/footer/footer.module.css index c4df006c7..5a09859d8 100644 --- a/docs/TunGo/src/components/footer/footer.module.css +++ b/docs/TunGo/src/components/footer/footer.module.css @@ -3,5 +3,14 @@ flex-direction: column; justify-content: center; align-items: center; - padding: 1rem; + gap: 0.2rem; + margin: 0 auto; + padding: 0.75rem 1rem 1.5rem; +} + +.footer p { + margin: 0; + color: var(--ifm-color-emphasis-600); + text-align: center; + font-size: 0.92rem; } diff --git a/docs/TunGo/src/css/custom.css b/docs/TunGo/src/css/custom.css index 50c47631d..cdfee3f27 100644 --- a/docs/TunGo/src/css/custom.css +++ b/docs/TunGo/src/css/custom.css @@ -6,7 +6,7 @@ /* You can override the default Infima variables here. */ :root { - /* Primary color — cyan / Go-like, calm and technical */ + /* Primary color — restrained Go cyan */ --ifm-color-primary: #009fc9; --ifm-color-primary-dark: #008ab0; --ifm-color-primary-darker: #007a9d; @@ -19,6 +19,19 @@ /* Code highlight — tied to primary for harmony */ --docusaurus-highlighted-code-line-bg: rgba(0, 159, 201, 0.08); + + --site-hero-ink: #07131a; + --site-surface: rgba(255, 255, 255, 0.86); + --site-surface-strong: rgba(255, 255, 255, 0.94); + --site-surface-muted: rgba(6, 19, 26, 0.045); + --site-border: rgba(6, 19, 26, 0.08); + --site-shadow: 0 24px 60px rgba(6, 19, 26, 0.08); + --site-grid-line: rgba(0, 159, 201, 0.08); + --site-accent: #009fc9; + --site-gradient: + radial-gradient(circle at top left, rgba(0, 159, 201, 0.09), transparent 28%), + radial-gradient(circle at 85% 10%, rgba(0, 159, 201, 0.04), transparent 24%), + linear-gradient(180deg, #f7f7f5 0%, #ffffff 35%, #f6f6f4 100%); } /* Dark mode — same palette, softer contrast */ @@ -31,18 +44,51 @@ --ifm-color-primary-lightest: #c7f4fc; --docusaurus-highlighted-code-line-bg: rgba(0, 159, 201, 0.12); + + --site-hero-ink: #ecf7fb; + --site-surface: rgba(12, 23, 34, 0.82); + --site-surface-strong: rgba(13, 24, 35, 0.94); + --site-surface-muted: rgba(255, 255, 255, 0.05); + --site-border: rgba(255, 255, 255, 0.08); + --site-shadow: none; + --site-grid-line: rgba(79, 195, 227, 0.12); + --site-accent: #4fc3e3; + --site-gradient: + radial-gradient(circle at top left, rgba(79, 195, 227, 0.12), transparent 28%), + radial-gradient(circle at 85% 10%, rgba(79, 195, 227, 0.05), transparent 24%), + linear-gradient(180deg, #0b0b0c 0%, #101113 35%, #15171a 100%); } /* Footer — explicit, neutral background */ footer.footer { - background-color: #f7f9fb; + background-color: var(--ifm-background-color); +} + +/* Navbar spacing should read as one even rhythm. */ +.navbar__brand { + margin-right: 0.85rem; +} + +.navbar__items--left { + gap: 0.85rem; +} + +.navbar__items--left .navbar__item { + margin: 0; + padding: 0; } -[data-theme='dark'] footer.footer { - background-color: #0f172a; +.navbar__items--left .navbar__link { + padding-left: 0; + padding-right: 0; } /* Small UX polish (relative, typography-friendly) */ a:hover { text-decoration-thickness: 0.125em; } + +.theme-doc-markdown, +.container { + position: relative; +} diff --git a/docs/TunGo/src/data/benchmarks.js b/docs/TunGo/src/data/benchmarks.js new file mode 100644 index 000000000..b718fb757 --- /dev/null +++ b/docs/TunGo/src/data/benchmarks.js @@ -0,0 +1,75 @@ +export const benchmarkSnapshot = { + generatedAt: '2026-03-15', + machine: 'Apple M4 Pro', + goVersion: 'Go 1.26', + fullCycle1400: [ + {id: 'udp-c2s', transport: 'UDP', direction: 'Client -> Server', ns: 2658, throughput: 534.15, allocs: 0}, + {id: 'udp-s2c', transport: 'UDP', direction: 'Server -> Client', ns: 2649, throughput: 536.08, allocs: 0}, + {id: 'tcp-c2s', transport: 'TCP', direction: 'Client -> Server', ns: 2622, throughput: 541.49, allocs: 0}, + {id: 'tcp-s2c', transport: 'TCP', direction: 'Server -> Client', ns: 2633, throughput: 539.26, allocs: 0}, + ], + parallelPeers1400: [ + { + id: 'udp-c2s-parallel', + label: 'UDP Client -> Server', + series: [ + {peers: 1, ns: 3337, throughput: 425.57}, + {peers: 64, ns: 328.4, throughput: 4324.34}, + {peers: 1024, ns: 332.4, throughput: 4272.50}, + ], + }, + { + id: 'udp-s2c-parallel', + label: 'UDP Server -> Client', + series: [ + {peers: 1, ns: 3334, throughput: 425.89}, + {peers: 64, ns: 349.4, throughput: 4063.60}, + {peers: 1024, ns: 355.9, throughput: 3990.34}, + ], + }, + ], + repository: { + fastPath: [ + { + id: 'exact-internal', + label: 'Exact internal lookup', + series: [ + {peers: 1, ns: 8.677}, + {peers: 100, ns: 9.000}, + {peers: 1000, ns: 9.341}, + {peers: 10000, ns: 9.303}, + ], + }, + { + id: 'allowed-host', + label: 'Allowed host lookup', + series: [ + {peers: 1, ns: 13.49}, + {peers: 100, ns: 14.95}, + {peers: 1000, ns: 13.40}, + {peers: 10000, ns: 14.11}, + ], + }, + { + id: 'route-id', + label: 'Route ID lookup', + series: [ + {peers: 1, ns: 3.920}, + {peers: 100, ns: 6.378}, + {peers: 1000, ns: 6.032}, + {peers: 10000, ns: 6.604}, + ], + }, + ], + missPath: [ + {peers: 1, ns: 35.39}, + {peers: 100, ns: 699.2}, + {peers: 1000, ns: 9014}, + {peers: 10000, ns: 89484}, + ], + }, + egress: { + uncontendedNs: 4.706, + contendedNs: 80.15, + }, +}; diff --git a/docs/TunGo/src/pages/benchmarks.js b/docs/TunGo/src/pages/benchmarks.js new file mode 100644 index 000000000..79d400dd5 --- /dev/null +++ b/docs/TunGo/src/pages/benchmarks.js @@ -0,0 +1,425 @@ +import React from 'react'; +import Translate, {translate} from '@docusaurus/Translate'; +import Layout from '@theme/Layout'; +import Heading from '@theme/Heading'; +import Styles from './benchmarks.module.css'; +import {benchmarkSnapshot} from '@site/src/data/benchmarks'; + +function formatNs(ns) { + if (ns >= 1000) { + return `~${(ns / 1000).toFixed(1)} μs`; + } + if (ns >= 100) { + return `~${Math.round(ns)} ns`; + } + return `~${ns.toFixed(1)} ns`; +} + +function formatThroughput(value) { + const gbit = (value * 8) / 1000; + if (gbit >= 1) { + return `~${gbit.toFixed(1)} Gbit/s`; + } + return `~${Math.round(value * 8)} Mbit/s`; +} + +function translateTransport(id) { + const transportById = { + 'udp-c2s': translate({id: 'bench.transport.udp', message: 'UDP'}), + 'udp-s2c': translate({id: 'bench.transport.udp', message: 'UDP'}), + 'tcp-c2s': translate({id: 'bench.transport.tcp', message: 'TCP'}), + 'tcp-s2c': translate({id: 'bench.transport.tcp', message: 'TCP'}), + }; + + return transportById[id] || id.toUpperCase(); +} + +function translateDirection(id) { + const directionById = { + 'udp-c2s': translate({id: 'bench.direction.clientServer', message: 'Client -> Server'}), + 'tcp-c2s': translate({id: 'bench.direction.clientServer', message: 'Client -> Server'}), + 'udp-s2c': translate({id: 'bench.direction.serverClient', message: 'Server -> Client'}), + 'tcp-s2c': translate({id: 'bench.direction.serverClient', message: 'Server -> Client'}), + }; + + return directionById[id] || id; +} + +function translateParallelLabel(id) { + const labelById = { + 'udp-c2s-parallel': translate({ + id: 'bench.parallel.clientServer', + message: 'UDP Client -> Server', + }), + 'udp-s2c-parallel': translate({ + id: 'bench.parallel.serverClient', + message: 'UDP Server -> Client', + }), + }; + + return labelById[id] || id; +} + +function translateLookupLabel(id) { + const labelById = { + 'exact-internal': translate({ + id: 'bench.lookup.exactInternal', + message: 'Exact internal lookup', + }), + 'allowed-host': translate({ + id: 'bench.lookup.allowedHost', + message: 'Allowed host lookup', + }), + 'route-id': translate({ + id: 'bench.lookup.routeId', + message: 'Route ID lookup', + }), + }; + + return labelById[id] || id; +} + +function buildPolyline(series, valueKey, width, height, padding) { + const values = series.map((point) => point[valueKey]); + const peerLogs = series.map((point) => Math.log10(point.peers)); + const min = Math.min(...values); + const max = Math.max(...values); + const minPeerLog = Math.min(...peerLogs); + const maxPeerLog = Math.max(...peerLogs); + const innerWidth = width - padding * 2; + const innerHeight = height - padding * 2; + + return series + .map((point) => { + const peerLog = Math.log10(point.peers); + const x = + maxPeerLog === minPeerLog + ? padding + innerWidth / 2 + : padding + ((peerLog - minPeerLog) / (maxPeerLog - minPeerLog)) * innerWidth; + const y = + max === min + ? padding + innerHeight / 2 + : padding + innerHeight - ((point[valueKey] - min) / (max - min)) * innerHeight; + return `${x},${y}`; + }) + .join(' '); +} + +function buildDots(series, valueKey, width, height, padding) { + const values = series.map((point) => point[valueKey]); + const peerLogs = series.map((point) => Math.log10(point.peers)); + const min = Math.min(...values); + const max = Math.max(...values); + const minPeerLog = Math.min(...peerLogs); + const maxPeerLog = Math.max(...peerLogs); + const innerWidth = width - padding * 2; + const innerHeight = height - padding * 2; + + return series.map((point) => { + const peerLog = Math.log10(point.peers); + const x = + maxPeerLog === minPeerLog + ? padding + innerWidth / 2 + : padding + ((peerLog - minPeerLog) / (maxPeerLog - minPeerLog)) * innerWidth; + const y = + max === min + ? padding + innerHeight / 2 + : padding + innerHeight - ((point[valueKey] - min) / (max - min)) * innerHeight; + return {x, y, label: point.peers}; + }); +} + +function Sparkline({series, valueKey, color, formatter}) { + const width = 520; + const height = 180; + const padding = 18; + const polyline = buildPolyline(series, valueKey, width, height, padding); + const dots = buildDots(series, valueKey, width, height, padding); + + return ( +
+ +
+ {series.map((point) => ( +
+ + {translate( + { + id: 'bench.legend.peers', + message: '{count} peers', + }, + {count: point.peers}, + )} + + {formatter(point[valueKey])} +
+ ))} +
+
+ ); +} + +function MetricCard({label, value, note, className}) { + return ( +
+
{label}
+
{value}
+
{note}
+
+ ); +} + +function DataTable({colgroup, header, rows, ariaLabel, className, align = 'end'}) { + return ( +
+ + + {colgroup.map((width, index) => ( + + ))} + + + + {header.map((cell) => ( + + ))} + + + + {rows.map((row, rowIndex) => ( + + {row.map((cell, columnIndex) => ( + + ))} + + ))} + +
+ {cell} +
{cell}
+
+ ); +} + +function FullCycleTable() { + const rows = benchmarkSnapshot.fullCycle1400.map((entry) => [ + <> + {translateTransport(entry.id)} + {translateDirection(entry.id)} + , + formatNs(entry.ns), + formatThroughput(entry.throughput), + String(entry.allocs), + ]); + + return ( + + ); +} + +function FastPathTable() { + const peerCounts = benchmarkSnapshot.repository.fastPath[0].series.map((entry) => entry.peers); + const rows = [ + ...benchmarkSnapshot.repository.fastPath.map((row) => [ + translateLookupLabel(row.id), + ...row.series.map((point) => formatNs(point.ns)), + ]), + [ + translate({id: 'bench.lookup.missPath', message: 'Miss path'}), + ...benchmarkSnapshot.repository.missPath.map((point) => formatNs(point.ns)), + ], + ]; + + return ( + + translate( + { + id: 'bench.table.peerCount', + message: '{count} peers', + }, + {count}, + ), + ), + ]} + rows={rows} + /> + ); +} + +export default function BenchmarksPage() { + const bestFullCycle = [...benchmarkSnapshot.fullCycle1400].sort((a, b) => b.throughput - a.throughput)[0]; + const lowestLatency = [...benchmarkSnapshot.fullCycle1400].sort((a, b) => a.ns - b.ns)[0]; + + return ( + +
+
+
+ + Benchmark snapshot + +

+ {translate( + { + id: 'bench.hero.lead', + message: 'Manual snapshot measured on {machine} with {goVersion}.', + }, + {machine: benchmarkSnapshot.machine, goVersion: benchmarkSnapshot.goVersion}, + )} +

+
+
+ +
+ + + + +
+ +
+
+
+ + Full-cycle dataplane + +

+ + Encrypt, lookup, validate, decrypt, handoff. Upper-bound for the dataplane core, not end-to-end VPN throughput. + +

+
+
+ +
+
+
+ +
+
+ + Multi-peer UDP scaling + +

+ + Aggregate throughput with work spread across many peers, not one serialized send lane. + +

+
+ +
+ {benchmarkSnapshot.parallelPeers1400.map((entry) => ( +
+
+ + {translateParallelLabel(entry.id)} + + + Aggregate throughput + +
+ formatThroughput(value)} + /> +
+ ))} +
+
+ +
+
+
+ + Lookup and serialization + +

+ + Internal-IP, allowed-host, and route-ID lookups stay flat. Misses and per-peer serialization are the real pressure points. + +

+
+
+ +
+
+
+ ~${benchmarkSnapshot.egress.contendedNs.toFixed(0)} ns`} + note={translate({id: 'bench.summary.egressNote', message: 'Uncontended to contended sends'})} + /> + ~89.5 μs at 10k peers'})} + /> +
+
+
+
+ ); +} diff --git a/docs/TunGo/src/pages/benchmarks.module.css b/docs/TunGo/src/pages/benchmarks.module.css new file mode 100644 index 000000000..1b3779587 --- /dev/null +++ b/docs/TunGo/src/pages/benchmarks.module.css @@ -0,0 +1,407 @@ +.page { + background: var(--ifm-background-color); + min-height: 100vh; + color: var(--ifm-font-color-base); + padding: 1.7rem 0 2.5rem; +} + +.hero, +.section, +.metrics { + max-width: 1120px; + margin: 0 auto; + padding: 0 1rem; +} + +.hero { + margin-bottom: 1.55rem; +} + +.title { + font-size: clamp(2.2rem, 4.2vw, 4rem); + line-height: 0.94; + letter-spacing: -0.04em; + margin: 0 0 0.75rem; + max-width: 10ch; +} + +.lead { + font-size: 0.96rem; + line-height: 1.45; + max-width: 34rem; + margin: 0; + color: var(--ifm-color-emphasis-700); +} + +.metrics { + margin-bottom: 1.75rem; + display: grid; + grid-template-columns: minmax(0, 1.25fr) repeat(3, minmax(0, 1fr)); + gap: 0.7rem; +} + +.metricCard, +.chartCard { + border-radius: 14px; + border: 1px solid var(--ifm-color-emphasis-200); + background: var(--ifm-background-surface-color); + box-shadow: none; +} + +.metricCard { + padding: 0.8rem 0.9rem 0.85rem; +} + +.metricCardPrimary { + padding: 0.9rem 0.98rem 0.95rem; +} + +.metricCardPrimary .metricValue { + font-size: 1.78rem; +} + +.metricCardMuted .metricValue { + font-size: 1.18rem; +} + +.metricCardMuted .metricNote { + font-size: 0.82rem; +} + +.metricCardMuted { + border-color: var(--ifm-color-emphasis-200); + background: transparent; +} + +.metricLabel, +.chartMetric { + display: block; + font-size: 0.72rem; + text-transform: uppercase; + letter-spacing: 0.11em; + color: var(--ifm-color-emphasis-600); + margin-bottom: 0.22rem; +} + +.metricValue { + font-size: 1.46rem; + font-weight: 800; + line-height: 0.98; + margin-bottom: 0.2rem; +} + +.metricNote { + color: var(--ifm-color-emphasis-700); + line-height: 1.35; + font-size: 0.84rem; +} + +.section { + margin-bottom: 2.1rem; +} + +.section + .section { + border-top: 1px solid var(--ifm-color-emphasis-200); + padding-top: 1.65rem; +} + +.sectionHeader { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(280px, 0.92fr); + gap: 1rem; + align-items: start; + margin-bottom: 0.95rem; +} + +.sectionTitle { + margin: 0; + line-height: 1.02; + letter-spacing: -0.03em; +} + +.sectionText { + margin: 0; + color: var(--ifm-color-emphasis-700); + line-height: 1.42; + max-width: 28rem; +} + +.splitSection { + display: grid; + grid-template-columns: minmax(240px, 290px) minmax(620px, 720px); + justify-content: space-between; + gap: 1rem; + align-items: start; +} + +.splitCopy { + max-width: 16.75rem; + justify-self: start; +} + +.splitCopy .sectionTitle { + margin-bottom: 0.48rem; +} + +.splitTable { + min-width: 0; + display: flex; + justify-content: flex-end; + justify-self: end; +} + +.splitTable .tableWrap { + width: auto; + max-width: 100%; +} + +.tableWrap { + display: flex; + width: 100%; + max-width: 100%; + overflow: visible; + padding: 0; +} + +.tableWrapEnd { + justify-content: flex-end; + justify-self: end; +} + +.tableWrapCenter { + justify-content: center; + justify-self: center; +} + +.dataTable { + flex: none; + width: auto; + background: transparent; + border-collapse: collapse; + table-layout: fixed; +} + +.fullCycleTable { + min-width: 640px; +} + +.fastPathTable { + min-width: 760px; +} + +.dataTable th, +.dataTable td { + padding: 0.62rem 0.72rem; + border-right: 1px solid rgba(15, 23, 42, 0.08); + border-bottom: 1px solid rgba(15, 23, 42, 0.08); + border-top: 1px solid rgba(15, 23, 42, 0.08); + border-left: 1px solid rgba(15, 23, 42, 0.08); + text-align: left; + vertical-align: top; + font-size: 0.84rem; + line-height: 1.38; + min-width: 0; +} + +.dataTable th { + font-weight: 700; + font-size: 0.89rem; + line-height: 1.25; + background: rgba(15, 23, 42, 0.015); +} + +.dataTable th:not(:first-child), +.dataTable td:not(:first-child) { + text-align: right; +} + +[data-theme='dark'] .dataTable th, +[data-theme='dark'] .dataTable td { + border-bottom-color: rgba(255, 255, 255, 0.08); + border-right-color: rgba(255, 255, 255, 0.08); + border-top-color: rgba(255, 255, 255, 0.08); + border-left-color: rgba(255, 255, 255, 0.08); +} + +.tablePrimary { + display: block; + font-weight: 700; + line-height: 1.28; +} + +.tableSecondary { + display: block; + color: var(--ifm-color-emphasis-600); + font-size: 0.78rem; + line-height: 1.32; + margin-top: 0.14rem; + opacity: 0.86; +} + +.chartMetric { + color: var(--ifm-color-emphasis-500); + letter-spacing: 0.09em; +} + +.chartGrid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 0.75rem; +} + +.chartCard { + padding: 0.78rem; +} + +.chartHeader { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 0.8rem; + margin-bottom: 0.55rem; +} + +.chartTitle { + margin: 0; + font-size: 0.95rem; +} + +.sparklineShell { + display: grid; + gap: 0.48rem; +} + +.sparkline { + width: 100%; + height: auto; +} + +.chartFrame { + fill: transparent; + stroke: var(--ifm-color-emphasis-200); + stroke-width: 1; +} + +[data-theme='dark'] .chartFrame { + fill: transparent; + stroke: var(--ifm-color-emphasis-200); +} + +.chartLine { + fill: none; + stroke-width: 4; + stroke-linecap: round; + stroke-linejoin: round; +} + +.chartDot { + stroke: #fff; + stroke-width: 3; +} + +[data-theme='dark'] .chartDot { + stroke: #08131a; +} + +.chartLabel { + fill: var(--ifm-color-emphasis-600); + font-size: 11px; + font-weight: 700; +} + +.sparklineLegend { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 0.4rem; + padding-top: 0; +} + +.legendEntry { + padding: 0; + background: transparent; +} + +.legendPeers { + display: block; + font-size: 0.68rem; + text-transform: uppercase; + letter-spacing: 0.07em; + color: var(--ifm-color-emphasis-600); + margin-bottom: 0.1rem; +} + +.legendValue { + display: block; + font-weight: 700; + font-size: 0.92rem; +} + +.summaryRow { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 0.7rem; + margin-top: 0.9rem; +} + +@media screen and (max-width: 996px) { + .hero, + .sectionHeader, + .metrics, + .chartGrid, + .summaryRow, + .splitSection { + grid-template-columns: 1fr; + justify-content: initial; + } + + .title { + max-width: 8ch; + font-size: clamp(2rem, 10vw, 2.8rem); + } + + .page { + padding: 1.35rem 0 1.9rem; + } + + .metrics, + .section, + .hero { + margin-bottom: 1.35rem; + } + + .section + .section { + padding-top: 1.35rem; + } + + .sparklineLegend { + grid-template-columns: 1fr; + } + + .tableWrap { + justify-content: flex-start; + overflow-x: auto; + overflow-y: hidden; + -webkit-overflow-scrolling: touch; + } + + .tableWrapEnd, + .tableWrapCenter { + justify-content: flex-start; + } + + .dataTable, + .fullCycleTable, + .fastPathTable { + width: auto; + } + + .dataTable th, + .dataTable td { + padding: 0.6rem 0.64rem; + font-size: 0.8rem; + } + + .dataTable th { + font-size: 0.84rem; + } +} diff --git a/docs/TunGo/src/pages/index.js b/docs/TunGo/src/pages/index.js index d351fa47c..f6240435b 100644 --- a/docs/TunGo/src/pages/index.js +++ b/docs/TunGo/src/pages/index.js @@ -6,23 +6,25 @@ import Layout from '@theme/Layout'; import Features from '@site/src/components/features'; import Heading from '@theme/Heading'; import Styles from './index.module.css'; -import Footer from "../components/footer/footer"; +import Footer from '../components/footer/footer'; function HomepageHeader() { - const {siteConfig} = UseDocusaurusContext(); return ( -
-
- - {siteConfig.title} - -

{siteConfig.tagline}

-
- - Get started in minutes ⏱️ - +
+
+
+ + Fast, lightweight{' '} + userspace VPN + +
+ + Get started in minutes + + + View benchmarks + +
@@ -36,11 +38,13 @@ export default function Home() { - -
- -
-