feat(i18n): Simplified Chinese (zh-CN), search answers per locale, fr/de/es data fixes
CI / Lint e auditorias (push) Successful in 1m10s
CI / Trivy (dependências e segredos) (push) Successful in 12s
CI / Imagem Docker (linux/arm64) (push) Successful in 2m39s
Release / Plano (reaproveitar a imagem?) (push) Successful in 6s
Release / ci (push) Skipped
Release / Publica a imagem (linux/arm64) (push) Successful in 18s
Release / Cria a release no Gitea (push) Successful in 5s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Sonnet 5.5 committed 2026-11-01 23:28:39 -03:00
1 parent ae61416468
commit 5a9fe676fc
61 files changed
+2517 -920

No files matched your search

+25 -9
View File
@@ -6,15 +6,16 @@ export async function generateMetadata({ params }) {
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
const isZh = locale === "zh-CN";
return paginaMeta({
titulo: isEn ? "Compare ESP32 Series: Side-by-Side Table" : isEs ? "Comparar series ESP32: tabla comparativa" : isFr ? "Comparer les séries ESP32 : tableau comparatif" : isDe ? "ESP32-Serien vergleichen: Vergleichstabelle" : "Comparar séries ESP32",
titulo: isEn ? "Compare ESP32 Series: Side-by-Side Table" : isEs ? "Comparar series ESP32: tabla comparativa" : isFr ? "Comparer les séries ESP32 : tableau comparatif" : isZh ? "ESP32 系列对比" : isDe ? "ESP32-Serien vergleichen: Vergleichstabelle" : "Comparar séries ESP32",
descricao: isEn
? "Compare up to four ESP32 series side by side: processor, Wi-Fi, Bluetooth, memory, GPIO, peripherals, and hardware security, with official datasheet data."
: isEs
? "Compare hasta cuatro series de ESP32 frente a frente: procesador, Wi-Fi, Bluetooth, memoria, GPIO, periféricos y seguridad en hardware, con datos de hojas de datos oficiales."
: isFr
? "Comparez jusqu'à quatre séries d'ESP32 côte à côte : processeur, Wi-Fi, Bluetooth, mémoire, GPIO, périphériques et sécurité matérielle, avec les données des fiches techniques officielles."
: isDe
: isZh ? "最多并排对比四个 ESP32 系列:处理器、Wi-Fi、蓝牙、内存、GPIO、外设和硬件安全,数据来自官方数据手册。" : isDe
? "Vergleichen Sie bis zu vier ESP32-Serien nebeneinander: Prozessor, Wi-Fi, Bluetooth, Speicher, GPIO, Peripherie und Hardware-Sicherheit mit Daten aus offiziellen Datenblättern."
: "Compare até quatro séries de ESP32 lado a lado: processador, Wi-Fi, Bluetooth, memória, GPIO, periféricos e segurança em hardware, com os dados dos datasheets oficiais.",
caminho: "/comparacao",
@@ -25,7 +26,7 @@ export async function generateMetadata({ params }) {
? ["comparar ESP32", "ESP32 vs ESP32-S3", "tabla comparativa ESP32", "cuál ESP32 es mejor"]
: isFr
? ["comparer ESP32", "ESP32 vs ESP32-S3", "tableau comparatif ESP32", "quel ESP32 choisir"]
: isDe
: isZh ? ["ESP32 对比", "ESP32 vs ESP32-S3", "ESP32 对比表", "哪款 ESP32 最好"] : isDe
? ["ESP32 vergleichen", "ESP32 vs ESP32-S3", "ESP32 Vergleichstabelle", "welcher ESP32 ist der beste"]
: ["comparar ESP32", "ESP32 vs ESP32-S3", "tabela comparativa ESP32", "qual ESP32 é melhor"],
});
@@ -105,6 +106,20 @@ const faqsDe = [
resposta: "Der ESP32-C3 ist ein RISC-V-Mikrocontroller mit Wi-Fi 4 und Bluetooth 5 LE. Der ESP32-C6 erweitert dies um Wi-Fi 6 (802.11ax), Bluetooth 5.4 LE, ein IEEE-802.15.4-Funkmodul für Zigbee 3.0 und Thread 1.3 sowie einen extrem stromsparenden Coprozessor.",
},
];
const faqsZh = [
{
pergunta: "如何并排对比 ESP32 微控制器?",
resposta: "ESPDocs 对比工具可同时选择最多四个系列,对比架构、主频、SRAM/PSRAM 内存、无线标准(Wi-Fi 4/6、蓝牙 5/6、802.15.4)、外设接口以及硬件安全模块。",
},
{
pergunta: "经典 ESP32 与 ESP32-S3 有什么区别?",
resposta: "经典 ESP32 使用 Xtensa LX6 内核和传统蓝牙/BLE。ESP32-S3 采用带 AI(TinyML)向量指令的 Xtensa LX7 内核,提供原生 USB OTG、更多 GPIO(45 对 36)以及蓝牙 5.0 LE。",
},
{
pergunta: "ESP32-C3 与 ESP32-C6 有什么区别?",
resposta: "ESP32-C3 是支持 Wi-Fi 4 和蓝牙 5 LE 的 RISC-V 微控制器。ESP32-C6 升级为 Wi-Fi 6(802.11ax)、蓝牙 5.4 LE,并带有用于 Zigbee 3.0 和 Thread 1.3 的 IEEE 802.15.4 射频,以及一颗超低功耗协处理器。",
},
];
export default async function Layout({ children, params }) {
const { locale } = await params;
@@ -112,8 +127,9 @@ export default async function Layout({ children, params }) {
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
const faqs = isEn ? faqsEn : isEs ? faqsEs : isFr ? faqsFr : isDe ? faqsDe : faqsPt;
const canonPath = isEn ? "/en/compare" : isEs ? "/es/comparacion" : isFr ? "/fr/comparaison" : isDe ? "/de/vergleich" : "/comparacao";
const isZh = locale === "zh-CN";
const faqs = isEn ? faqsEn : isEs ? faqsEs : isFr ? faqsFr : isZh ? faqsZh : isDe ? faqsDe : faqsPt;
const canonPath = isEn ? "/en/compare" : isEs ? "/es/comparacion" : isFr ? "/fr/comparaison" : isZh ? "/zh-CN/compare" : isDe ? "/de/vergleich" : "/comparacao";
return (
<>
@@ -122,14 +138,14 @@ export default async function Layout({ children, params }) {
dangerouslySetInnerHTML={{
__html: JSON.stringify(
jsonLd.aplicacaoWeb({
nome: isEn ? "ESP32 Series Comparator" : isEs ? "Comparador de series ESP32" : isFr ? "Comparateur de séries ESP32" : isDe ? "ESP32-Serien-Vergleich" : "Comparador de Séries ESP32",
nome: isEn ? "ESP32 Series Comparator" : isEs ? "Comparador de series ESP32" : isFr ? "Comparateur de séries ESP32" : isZh ? "ESP32 系列对比工具" : isDe ? "ESP32-Serien-Vergleich" : "Comparador de Séries ESP32",
descricao: isEn
? "Technical comparison table to analyze specifications, pinouts, and features of multiple ESP32 series."
: isEs
? "Tabla comparativa técnica para analizar especificaciones, patillaje y características de múltiples series de ESP32."
: isFr
? "Tableau comparatif technique pour analyser les spécifications, le brochage et les fonctionnalités de plusieurs séries ESP32."
: isDe
: isZh ? "用于分析多个 ESP32 系列的规格、引脚和功能的技术对比表。" : isDe
? "Technische Vergleichstabelle zur Analyse von Spezifikationen, Pinbelegungen und Merkmalen mehrerer ESP32-Serien."
: "Tabela comparativa técnica para analisar especificações, pinagens e recursos de múltiplas séries de ESP32.",
caminho: canonPath,
@@ -143,8 +159,8 @@ export default async function Layout({ children, params }) {
dangerouslySetInnerHTML={{
__html: JSON.stringify(
jsonLd.trilha([
{ nome: isEn ? "Home" : isEs ? "Inicio" : isFr ? "Accueil" : isDe ? "Startseite" : "Início", caminho: isEn ? "/en" : isEs ? "/es" : isFr ? "/fr" : isDe ? "/de" : "/" },
{ nome: isEn ? "Compare Series" : isEs ? "Comparar series" : isFr ? "Comparer les séries" : isDe ? "Serien vergleichen" : "Comparar Séries", caminho: canonPath },
{ nome: isEn ? "Home" : isEs ? "Inicio" : isFr ? "Accueil" : isZh ? "首页" : isDe ? "Startseite" : "Início", caminho: isEn ? "/en" : isEs ? "/es" : isFr ? "/fr" : isZh ? "/zh-CN" : isDe ? "/de" : "/" },
{ nome: isEn ? "Compare Series" : isEs ? "Comparar series" : isFr ? "Comparer les séries" : isZh ? "系列对比" : isDe ? "Serien vergleichen" : "Comparar Séries", caminho: canonPath },
])
),
}}
+109 -27
View File
@@ -11,6 +11,7 @@ import seriesDataEn from "@/data/en/series.json";
import seriesDataEs from "@/data/es/series.json";
import seriesDataFr from "@/data/fr/series.json";
import seriesDataDe from "@/data/de/series.json";
import seriesDataZh from "@/data/zh-CN/series.json";
import { getLocalizedHref } from "@/i18n/links";
import { ArrowRight, ArrowUpRight, Check, ChevronDown, Scale } from "lucide-react";
@@ -416,6 +417,84 @@ const COMPARE_FIELDS_DE = [
{ key: "temperatura_armazenamento", label: "Lagertemp." },
]},
];
const COMPARE_FIELDS_ZH = [
{ category: "概览", fields: [
{ key: "nome_completo", label: "完整名称" },
{ key: "descricao", label: "描述" },
]},
{ category: "可用性与工具", fields: [
{ key: "esp_idf_minimo", label: "最低 ESP-IDF 版本" },
{ key: "arduino_core", label: "Arduino 核心" },
{ key: "depuracao", label: "调试 / JTAG" },
{ key: "encapsulamento", label: "封装" },
{ key: "modulos", label: "可用模组" },
]},
{ category: "处理器", fields: [
{ key: "arquitetura", label: "架构" },
{ key: "nucleos", label: "内核" },
{ key: "frequencia", label: "频率" },
{ key: "coprocessador_ulp", label: "ULP 协处理器" },
{ key: "aceleradores_ia", label: "AI 加速器" },
]},
{ category: "无线连接", fields: [
{ key: "wifi", label: "Wi-Fi" },
{ key: "bluetooth", label: "蓝牙" },
{ key: "zigbee_thread", label: "Zigbee/Thread" },
{ key: "matter", label: "Matter" },
{ key: "ethernet", label: "以太网" },
]},
{ category: "内存", fields: [
{ key: "memoria_sram", label: "SRAM" },
{ key: "memoria_sram_rtc", label: "RTC SRAM" },
{ key: "memoria_rom", label: "ROM" },
{ key: "flash_externa", label: "外部闪存" },
{ key: "psram_externa", label: "外部 PSRAM" },
]},
{ category: "数字外设", fields: [
{ key: "gpio", label: "GPIO" },
{ key: "uart", label: "UART" },
{ key: "spi", label: "SPI" },
{ key: "i2c", label: "I²C" },
{ key: "i2s", label: "I²S" },
{ key: "pwm", label: "PWM" },
{ key: "can", label: "CAN" },
{ key: "usb", label: "USB" },
{ key: "depuracao", label: "调试 / JTAG" },
{ key: "sdio", label: "SDIO" },
]},
{ category: "模拟外设", fields: [
{ key: "adc", label: "ADC" },
{ key: "dac", label: "DAC" },
{ key: "touch", label: "电容触摸" },
{ key: "sensor_hall", label: "霍尔传感器" },
{ key: "sensor_temperatura", label: "温度传感器" },
]},
{ category: "安全", fields: [
{ key: "seguranca.aes", label: "AES" },
{ key: "seguranca.sha", label: "SHA" },
{ key: "seguranca.rsa", label: "RSA / MPI" },
{ key: "seguranca.ecc", label: "ECC(椭圆曲线)" },
{ key: "seguranca.ecdsa", label: "硬件 ECDSA" },
{ key: "seguranca.hmac", label: "HMAC" },
{ key: "seguranca.assinatura_digital", label: "数字签名(DS)" },
{ key: "seguranca.key_manager", label: "密钥管理器" },
{ key: "seguranca.rng", label: "随机数发生器(TRNG)" },
{ key: "seguranca.criptografia_flash", label: "闪存加密" },
{ key: "seguranca.secure_boot", label: "安全启动" },
{ key: "seguranca.protecao_dpa", label: "DPA 防护" },
]},
{ category: "特殊接口", fields: [
{ key: "lcd", label: "LCD" },
{ key: "camera", label: "摄像头" },
{ key: "mipi_csi", label: "MIPI CSI" },
{ key: "mipi_dsi", label: "MIPI DSI" },
{ key: "ethernet_mac", label: "以太网 MAC" },
]},
{ category: "环境规格", fields: [
{ key: "temperatura_operacao", label: "工作温度" },
{ key: "temperatura_armazenamento", label: "存储温度" },
]},
];
export default function Comparacao() {
const pathname = usePathname();
@@ -423,15 +502,16 @@ export default function Comparacao() {
const isEs = pathname?.startsWith("/es");
const isFr = pathname?.startsWith("/fr");
const isDe = pathname?.startsWith("/de");
const currentLocale = isEs ? "es" : isEn ? "en" : isFr ? "fr" : isDe ? "de" : "pt";
const seriesData = isEs ? seriesDataEs : isEn ? seriesDataEn : isFr ? seriesDataFr : isDe ? seriesDataDe : seriesDataPt;
const compareFields = isEs ? COMPARE_FIELDS_ES : isEn ? COMPARE_FIELDS_EN : isFr ? COMPARE_FIELDS_FR : isDe ? COMPARE_FIELDS_DE : COMPARE_FIELDS_PT;
const isZh = pathname?.startsWith("/zh-CN");
const currentLocale = isEs ? "es" : isEn ? "en" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt";
const seriesData = isEs ? seriesDataEs : isEn ? seriesDataEn : isFr ? seriesDataFr : isZh ? seriesDataZh : isDe ? seriesDataDe : seriesDataPt;
const compareFields = isEs ? COMPARE_FIELDS_ES : isEn ? COMPARE_FIELDS_EN : isFr ? COMPARE_FIELDS_FR : isZh ? COMPARE_FIELDS_ZH : isDe ? COMPARE_FIELDS_DE : COMPARE_FIELDS_PT;
const [selectedSeries, setSelectedSeries] = useState(["ESP32", "ESP32-S3"]);
const [soDiferencas, setSoDiferencas] = useState(false);
const [collapsedCategories, setCollapsedCategories] = useState(() => ({
[isEs ? "Interfaces especiales" : isEn ? "Special Interfaces" : isFr ? "Interfaces spéciales" : isDe ? "Spezielle Schnittstellen" : "Interfaces Especiais"]: true,
[isEs ? "Especificaciones ambientales" : isEn ? "Environmental Specifications" : isFr ? "Spécifications environnementales" : isDe ? "Umgebungsbedingungen" : "Especificações Ambientais"]: true,
[isEs ? "Interfaces especiales" : isEn ? "Special Interfaces" : isFr ? "Interfaces spéciales" : isZh ? "特殊接口" : isDe ? "Spezielle Schnittstellen" : "Interfaces Especiais"]: true,
[isEs ? "Especificaciones ambientales" : isEn ? "Environmental Specifications" : isFr ? "Spécifications environnementales" : isZh ? "环境规格" : isDe ? "Umgebungsbedingungen" : "Especificações Ambientais"]: true,
}));
const series = Object.entries(seriesData);
@@ -457,19 +537,19 @@ export default function Comparacao() {
};
const renderValue = (value) => {
if (!value || value === "Não" || value === "No" || value === "Non" || value === "Nein") return <span className="text-muted">{isEs || isEn ? "No" : isFr ? "Non" : isDe ? "Nein" : "Não"}</span>;
if (value === "Sim" || value === "Yes" || value === "Sí" || value === "Oui" || value === "Ja") {
if (!value || value === "Não" || value === "No" || value === "Non" || (value === "Nein" || value === "否")) return <span className="text-muted">{isEs || isEn ? "No" : isFr ? "Non" : isZh ? "否" : isDe ? "Nein" : "Não"}</span>;
if (value === "Sim" || value === "Yes" || value === "Sí" || value === "Oui" || (value === "Ja" || value === "是")) {
return (
<span className="inline-flex items-center gap-1.5 font-medium text-ok">
<Check className="h-4 w-4" aria-hidden="true" />
{isEs ? "Sí" : isEn ? "Yes" : isFr ? "Oui" : isDe ? "Ja" : "Sim"}
{isEs ? "Sí" : isEn ? "Yes" : isFr ? "Oui" : isZh ? "是" : isDe ? "Ja" : "Sim"}
</span>
);
}
return <span className="font-medium text-ink">{value}</span>;
};
const valores = (key) => selectedSeries.map((k) => String(valorDe(seriesData[k], key) ?? (isEs || isEn ? "No" : isFr ? "Non" : isDe ? "Nein" : "Não")));
const valores = (key) => selectedSeries.map((k) => String(valorDe(seriesData[k], key) ?? (isEs || isEn ? "No" : isFr ? "Non" : isZh ? "否" : isDe ? "Nein" : "Não")));
const diferem = (key) => new Set(valores(key)).size > 1;
return (
@@ -481,11 +561,11 @@ export default function Comparacao() {
isEn={isEn}
isEs={isEs}
isFr={isFr}
isDe={isDe}
trail={[{ label: isEs ? "Comparador" : isEn ? "Comparator" : isFr ? "Comparateur" : isDe ? "Vergleich" : "Comparador" }]}
isDe={isDe} isZh={isZh}
trail={[{ label: isEs ? "Comparador" : isEn ? "Comparator" : isFr ? "Comparateur" : isZh ? "对比工具" : isDe ? "Vergleich" : "Comparador" }]}
icon={Scale}
label={isEs ? "Hasta cuatro series lado a lado" : isEn ? "Up to four series side by side" : isFr ? "Jusqu'à quatre séries côte à côte" : isDe ? "Bis zu vier Serien im Vergleich" : "Até quatro séries lado a lado"}
title={isEs ? "Comparador de series ESP32" : isEn ? "ESP32 Series Comparator" : isFr ? "Comparateur de séries ESP32" : isDe ? "ESP32-Serien-Vergleich" : "Comparador de séries"}
label={isEs ? "Hasta cuatro series lado a lado" : isEn ? "Up to four series side by side" : isFr ? "Jusqu'à quatre séries côte à côte" : isZh ? "最多四个系列并排对比" : isDe ? "Bis zu vier Serien im Vergleich" : "Até quatro séries lado a lado"}
title={isEs ? "Comparador de series ESP32" : isEn ? "ESP32 Series Comparator" : isFr ? "Comparateur de séries ESP32" : isZh ? "系列对比工具" : isDe ? "ESP32-Serien-Vergleich" : "Comparador de séries"}
lede={
isEs
? "Ponga núcleos, radio, memoria, periféricos y seguridad en la misma tabla y vea lo que realmente cambia de un chip a otro."
@@ -493,7 +573,7 @@ export default function Comparacao() {
? "Put cores, radio, memory, peripherals, and security in the same table and see what really changes from chip to chip."
: isFr
? "Placez les cœurs, la radio, la mémoire, les périphériques et la sécurité dans le même tableau et voyez ce qui change réellement d'une puce à l'autre."
: isDe
: isZh ? "把内核、无线、内存、外设和安全放进同一张表,看看芯片之间到底有什么不同。" : isDe
? "Stellen Sie Kerne, Funk, Speicher, Peripherie und Sicherheit in derselben Tabelle gegenüber und sehen Sie, was sich wirklich von Chip zu Chip ändert."
: "Coloque núcleos, rádio, memória, periféricos e segurança na mesma tabela e veja o que realmente muda de um chip para outro."
}
@@ -510,7 +590,7 @@ export default function Comparacao() {
<>Choose {MIN_SERIES} to {MAX_SERIES} series</>
) : isFr ? (
<>Choisissez de {MIN_SERIES} à {MAX_SERIES} séries</>
) : isDe ? (
) : isZh ? ( <>请选择 {MIN_SERIES} 到 {MAX_SERIES} 个系列</> ) : isDe ? (
<>Wählen Sie {MIN_SERIES} bis {MAX_SERIES} Serien</>
) : (
<>Escolha de {MIN_SERIES} a {MAX_SERIES} séries</>
@@ -532,7 +612,9 @@ export default function Comparacao() {
{selectedSeries.length} sur {MAX_SERIES} sélectionnées
{selectedSeries.length === MAX_SERIES && ". Supprimez-en une pour en changer."}
</>
) : isDe ? (
) : isZh ? ( <>
已选 {selectedSeries.length} / {MAX_SERIES} 个{selectedSeries.length === MAX_SERIES && "。请先移除一个再更换。"}
</> ) : isDe ? (
<>
{selectedSeries.length} von {MAX_SERIES} ausgewählt
{selectedSeries.length === MAX_SERIES && ". Entfernen Sie eine zum Wechseln."}
@@ -571,7 +653,7 @@ export default function Comparacao() {
<section className="shell mt-8" aria-labelledby="tabela-titulo">
<div className="flex flex-wrap items-center justify-between gap-3">
<h2 id="tabela-titulo" className="text-base font-semibold text-ink">
{isEs ? "Especificaciones" : isEn ? "Specifications" : isFr ? "Spécifications" : isDe ? "Spezifikationen" : "Especificações"}
{isEs ? "Especificaciones" : isEn ? "Specifications" : isFr ? "Spécifications" : isZh ? "规格" : isDe ? "Spezifikationen" : "Especificações"}
</h2>
<label className="flex min-h-11 cursor-pointer items-center gap-2.5 text-sm font-medium text-ink-soft">
<input
@@ -580,7 +662,7 @@ export default function Comparacao() {
onChange={(e) => setSoDiferencas(e.target.checked)}
className="h-5 w-5 cursor-pointer accent-[var(--accent)]"
/>
{isEs ? "Mostrar solo diferencias" : isEn ? "Show differences only" : isFr ? "Afficher uniquement les différences" : isDe ? "Nur Unterschiede anzeigen" : "Mostrar só as diferenças"}
{isEs ? "Mostrar solo diferencias" : isEn ? "Show differences only" : isFr ? "Afficher uniquement les différences" : isZh ? "仅显示差异" : isDe ? "Nur Unterschiede anzeigen" : "Mostrar só as diferenças"}
</label>
</div>
@@ -594,7 +676,7 @@ export default function Comparacao() {
<>Comparison of series {selectedSeries.join(", ")}</>
) : isFr ? (
<>Comparaison des séries {selectedSeries.join(", ")}</>
) : isDe ? (
) : isZh ? ( <>系列对比:{selectedSeries.join(", ")}</> ) : isDe ? (
<>Vergleich der Serien {selectedSeries.join(", ")}</>
) : (
<>Comparação das séries {selectedSeries.join(", ")}</>
@@ -603,7 +685,7 @@ export default function Comparacao() {
<thead>
<tr className="border-b border-line bg-surface-2">
<th scope="col" className="sticky left-0 z-20 w-28 bg-surface-2 px-4 py-4 text-left font-semibold text-muted sm:w-52 sm:px-6">
{isEs ? "Especificación" : isEn ? "Specification" : isFr ? "Spécification" : isDe ? "Spezifikation" : "Especificação"}
{isEs ? "Especificación" : isEn ? "Specification" : isFr ? "Spécification" : isZh ? "规格项" : isDe ? "Spezifikation" : "Especificação"}
</th>
{selectedSeries.map((seriesKey) => (
<th key={seriesKey} scope="col" className="min-w-40 px-4 py-4 text-left sm:px-6">
@@ -660,7 +742,7 @@ export default function Comparacao() {
<section className="shell section" aria-labelledby="docs-titulo">
<h2 id="docs-titulo" className="section-title">
{isEs ? "Documentación oficial" : isEn ? "Official documentation" : isFr ? "Documentation officielle" : isDe ? "Offizielle Dokumentation" : "Documentação oficial"}
{isEs ? "Documentación oficial" : isEn ? "Official documentation" : isFr ? "Documentation officielle" : isZh ? "官方文档" : isDe ? "Offizielle Dokumentation" : "Documentação oficial"}
</h2>
<div className="mt-6 grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
{selectedSeries.map((seriesKey) => {
@@ -672,13 +754,13 @@ export default function Comparacao() {
</Link>
{seriesItem.datasheet ? (
<a href={seriesItem.datasheet} target="_blank" rel="noopener noreferrer" className="btn btn-ghost btn-sm">
{isEs ? "Datasheet oficial" : isEn ? "Official datasheet" : isFr ? "Fiche technique officielle" : isDe ? "Offizielles Datenblatt" : "Datasheet oficial"}
{isEs ? "Datasheet oficial" : isEn ? "Official datasheet" : isFr ? "Fiche technique officielle" : isZh ? "官方数据手册" : isDe ? "Offizielles Datenblatt" : "Datasheet oficial"}
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
<span className="sr-only"> {isEs ? "(abre en una nueva pestaña)" : isEn ? "(opens in a new tab)" : isFr ? "(ouvre un nouvel onglet)" : isDe ? "(öffnet in neuem Tab)" : "(abre em nova aba)"}</span>
<span className="sr-only"> {isEs ? "(abre en una nueva pestaña)" : isEn ? "(opens in a new tab)" : isFr ? "(ouvre un nouvel onglet)" : isZh ? "(在新标签页打开)" : isDe ? "(öffnet in neuem Tab)" : "(abre em nova aba)"}</span>
</a>
) : (
<span className="text-sm text-muted">
{isEs ? "Datasheet aún no publicado" : isEn ? "Datasheet not yet published" : isFr ? "Fiche technique pas encore publiée" : isDe ? "Datenblatt noch nicht veröffentlicht" : "Datasheet ainda não publicado"}
{isEs ? "Datasheet aún no publicado" : isEn ? "Datasheet not yet published" : isFr ? "Fiche technique pas encore publiée" : isZh ? "数据手册尚未发布" : isDe ? "Datenblatt noch nicht veröffentlicht" : "Datasheet ainda não publicado"}
</span>
)}
</div>
@@ -689,7 +771,7 @@ export default function Comparacao() {
<div className="panel mt-10 flex flex-col items-start justify-between gap-6 p-7 sm:p-10 md:flex-row md:items-center">
<div className="max-w-2xl">
<h2 className="section-title">
{isEs ? "¿Desea probar en banco?" : isEn ? "Want to test on the bench?" : isFr ? "Envie de tester sur l'établi ?" : isDe ? "Möchten Sie es auf dem Prüfplatz testen ?" : "Quer testar na bancada?"}
{isEs ? "¿Desea probar en banco?" : isEn ? "Want to test on the bench?" : isFr ? "Envie de tester sur l'établi ?" : isZh ? "想在工作台上试试?" : isDe ? "Möchten Sie es auf dem Prüfplatz testen ?" : "Quer testar na bancada?"}
</h2>
<p className="mt-3 text-base text-muted">
{isEs
@@ -698,13 +780,13 @@ export default function Comparacao() {
? "Explore development boards with pinouts, peripherals, and official store links."
: isFr
? "Découvrez les cartes de développement avec brochage, périphériques et lien vers la boutique officielle."
: isDe
: isZh ? "查看带引脚、外设和商店链接的开发板。" : isDe
? "Entdecken Sie die Entwicklungsboards mit Pinbelegung, Peripherie und Link zum offiziellen Store."
: "Veja as placas de desenvolvimento com pinagem, periféricos e link para a loja."}
</p>
</div>
<Link href={getLocalizedHref("/catalogo", currentLocale)} className="btn btn-primary shrink-0">
{isEs ? "Ver catálogo de placas" : isEn ? "View boards catalog" : isFr ? "Voir le catalogue de cartes" : isDe ? "Board-Katalog ansehen" : "Ver catálogo de placas"}
{isEs ? "Ver catálogo de placas" : isEn ? "View boards catalog" : isFr ? "Voir le catalogue de cartes" : isZh ? "查看开发板目录" : isDe ? "Board-Katalog ansehen" : "Ver catálogo de placas"}
<ArrowRight className="h-4 w-4" aria-hidden="true" />
</Link>
</div>