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>
1097 lines
51 KiB
React
1097 lines
51 KiB
React
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||
import Link from "next/link";
|
||
import Image from "next/image";
|
||
import Header from "@/components/Header";
|
||
import Footer from "@/components/Footer";
|
||
import PageHero from "@/components/PageHero";
|
||
import { notFound } from "next/navigation";
|
||
import seriesDataPt from "@/public/series.json";
|
||
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 ConnectionsDiagram from "@/components/ConnectionsDiagram";
|
||
import SeriesTabMenu from "@/components/SeriesTabMenu";
|
||
import PinRestrictions from "@/components/PinRestrictions";
|
||
import { getLocalizedHref } from "@/i18n/links";
|
||
import {
|
||
AlertTriangle,
|
||
ArrowLeft,
|
||
ArrowRight,
|
||
ArrowUpRight,
|
||
Battery,
|
||
BookOpen,
|
||
Code,
|
||
Cpu,
|
||
Database,
|
||
ExternalLink,
|
||
FileText,
|
||
Lightbulb,
|
||
Package,
|
||
Scale,
|
||
ShieldCheck,
|
||
Sliders,
|
||
Thermometer,
|
||
Wifi,
|
||
} from "lucide-react";
|
||
|
||
export default async function SerieDetail({ params }) {
|
||
const { locale, key } = await params;
|
||
const isEn = locale === "en";
|
||
const isEs = locale === "es";
|
||
const isFr = locale === "fr";
|
||
const isDe = locale === "de";
|
||
const isZh = locale === "zh-CN";
|
||
const currentLocale = isZh ? "zh-CN" : isDe ? "de" : isFr ? "fr" : isEs ? "es" : isEn ? "en" : "pt";
|
||
const seriesData = isZh ? seriesDataZh : isDe ? seriesDataDe : isFr ? seriesDataFr : isEs ? seriesDataEs : isEn ? seriesDataEn : seriesDataPt;
|
||
const serie = seriesData[key];
|
||
|
||
if (!serie) {
|
||
notFound();
|
||
}
|
||
|
||
let conexoes = [];
|
||
try {
|
||
conexoes = isZh ? require(`@/data/zh-CN/conexoes/${key}.json`) : isDe
|
||
? require(`@/data/de/conexoes/${key}.json`)
|
||
: isFr
|
||
? require(`@/data/fr/conexoes/${key}.json`)
|
||
: isEs
|
||
? require(`@/data/es/conexoes/${key}.json`)
|
||
: isEn
|
||
? require(`@/data/en/conexoes/${key}.json`)
|
||
: require(`@/public/conexoes/${key}.json`);
|
||
} catch (error) {
|
||
console.log(`Arquivo de conexões não encontrado para ${key}`);
|
||
}
|
||
|
||
const seriesKeys = Object.keys(seriesData);
|
||
const currentIndex = seriesKeys.indexOf(key);
|
||
const previousKey = currentIndex > 0 ? seriesKeys[currentIndex - 1] : null;
|
||
const nextKey = currentIndex < seriesKeys.length - 1 ? seriesKeys[currentIndex + 1] : null;
|
||
|
||
const nao = isZh ? "否" : isDe ? "Nein" : isFr ? "Non" : isEs || isEn ? "No" : "Não";
|
||
const naoInformado = isZh ? "未提供" : isDe ? "Nicht angegeben" : isFr ? "Non communiqué" : isEs ? "No informado" : isEn ? "Not informed" : "Não informado";
|
||
|
||
const processadorSpecs = isZh ? [
|
||
{ label: "架构", value: serie.arquitetura },
|
||
{ label: "内核", value: serie.nucleos },
|
||
{ label: "频率", value: serie.frequencia },
|
||
{ label: "ULP 协处理器", value: serie.coprocessador_ulp || nao },
|
||
{ label: "AI 加速器", value: serie.aceleradores_ia || nao },
|
||
] : isDe
|
||
? [
|
||
{ label: "Architektur", value: serie.arquitetura },
|
||
{ label: "Kerne", value: serie.nucleos },
|
||
{ label: "Taktfrequenz", value: serie.frequencia },
|
||
{ label: "ULP-Coprozessor", value: serie.coprocessador_ulp || nao },
|
||
{ label: "KI-Beschleuniger", value: serie.aceleradores_ia || nao },
|
||
]
|
||
: isFr
|
||
? [
|
||
{ label: "Architecture", value: serie.arquitetura },
|
||
{ label: "Cœurs", value: serie.nucleos },
|
||
{ label: "Fréquence", value: serie.frequencia },
|
||
{ label: "Coprocesseur ULP", value: serie.coprocessador_ulp || nao },
|
||
{ label: "Accélérateurs IA", value: serie.aceleradores_ia || nao },
|
||
]
|
||
: isEs
|
||
? [
|
||
{ label: "Arquitectura", value: serie.arquitetura },
|
||
{ label: "Núcleos", value: serie.nucleos },
|
||
{ label: "Frecuencia", value: serie.frequencia },
|
||
{ label: "Coprocesador ULP", value: serie.coprocessador_ulp || nao },
|
||
{ label: "Aceleradores de IA", value: serie.aceleradores_ia || nao },
|
||
]
|
||
: isEn
|
||
? [
|
||
{ label: "Architecture", value: serie.arquitetura },
|
||
{ label: "Cores", value: serie.nucleos },
|
||
{ label: "Frequency", value: serie.frequencia },
|
||
{ label: "ULP Coprocessor", value: serie.coprocessador_ulp || nao },
|
||
{ label: "AI Accelerators", value: serie.aceleradores_ia || nao },
|
||
]
|
||
: [
|
||
{ label: "Arquitetura", value: serie.arquitetura },
|
||
{ label: "Núcleos", value: serie.nucleos },
|
||
{ label: "Frequência", value: serie.frequencia },
|
||
{ label: "Coprocessador ULP", value: serie.coprocessador_ulp || "Não" },
|
||
{ label: "Aceleradores IA", value: serie.aceleradores_ia || "Não" },
|
||
];
|
||
|
||
const seg = serie.seguranca || {};
|
||
const segurancaSpecs = isZh ? [
|
||
{ label: "AES", value: seg.aes || nao },
|
||
{ label: "SHA", value: seg.sha || nao },
|
||
{ label: "RSA / MPI", value: seg.rsa || nao },
|
||
{ label: "ECC(椭圆曲线)", value: seg.ecc || nao },
|
||
{ label: "硬件 ECDSA", value: seg.ecdsa || nao },
|
||
{ label: "HMAC", value: seg.hmac || nao },
|
||
{ label: "数字签名(DS)", value: seg.assinatura_digital || nao },
|
||
{ label: "密钥管理器", value: seg.key_manager || nao },
|
||
{ label: "随机数发生器(TRNG)", value: seg.rng || nao },
|
||
{ label: "闪存加密", value: seg.criptografia_flash || nao },
|
||
{ label: "安全启动", value: seg.secure_boot || nao },
|
||
{ label: "DPA 防护", value: seg.protecao_dpa || nao },
|
||
] : isDe
|
||
? [
|
||
{ label: "AES", value: seg.aes || nao },
|
||
{ label: "SHA", value: seg.sha || nao },
|
||
{ label: "RSA / MPI", value: seg.rsa || nao },
|
||
{ label: "ECC (elliptische Kurven)", value: seg.ecc || nao },
|
||
{ label: "Hardware-ECDSA", value: seg.ecdsa || nao },
|
||
{ label: "HMAC", value: seg.hmac || nao },
|
||
{ label: "Digitale Signatur (DS)", value: seg.assinatura_digital || nao },
|
||
{ label: "Key Manager", value: seg.key_manager || nao },
|
||
{ label: "Zufallszahlengenerator (TRNG)", value: seg.rng || nao },
|
||
{ label: "Flash-Verschlüsselung", value: seg.criptografia_flash || nao },
|
||
{ label: "Secure Boot", value: seg.secure_boot || nao },
|
||
{ label: "DPA-Schutz", value: seg.protecao_dpa || nao },
|
||
]
|
||
: isFr
|
||
? [
|
||
{ label: "AES", value: seg.aes || nao },
|
||
{ label: "SHA", value: seg.sha || nao },
|
||
{ label: "RSA / MPI", value: seg.rsa || nao },
|
||
{ label: "ECC (courbes elliptiques)", value: seg.ecc || nao },
|
||
{ label: "ECDSA matériel", value: seg.ecdsa || nao },
|
||
{ label: "HMAC", value: seg.hmac || nao },
|
||
{ label: "Signature numérique (DS)", value: seg.assinatura_digital || nao },
|
||
{ label: "Key Manager", value: seg.key_manager || nao },
|
||
{ label: "Générateur aléatoire (TRNG)", value: seg.rng || nao },
|
||
{ label: "Chiffrement Flash", value: seg.criptografia_flash || nao },
|
||
{ label: "Secure Boot", value: seg.secure_boot || nao },
|
||
{ label: "Protection DPA", value: seg.protecao_dpa || nao },
|
||
]
|
||
: isEs
|
||
? [
|
||
{ label: "AES", value: seg.aes || nao },
|
||
{ label: "SHA", value: seg.sha || nao },
|
||
{ label: "RSA / MPI", value: seg.rsa || nao },
|
||
{ label: "ECC (curvas elípticas)", value: seg.ecc || nao },
|
||
{ label: "ECDSA en hardware", value: seg.ecdsa || nao },
|
||
{ label: "HMAC", value: seg.hmac || nao },
|
||
{ label: "Firma digital (DS)", value: seg.assinatura_digital || nao },
|
||
{ label: "Key Manager", value: seg.key_manager || nao },
|
||
{ label: "Generador aleatorio (TRNG)", value: seg.rng || nao },
|
||
{ label: "Cifrado de flash", value: seg.criptografia_flash || nao },
|
||
{ label: "Secure Boot", value: seg.secure_boot || nao },
|
||
{ label: "Protección contra DPA", value: seg.protecao_dpa || nao },
|
||
]
|
||
: isEn
|
||
? [
|
||
{ label: "AES", value: seg.aes || nao },
|
||
{ label: "SHA", value: seg.sha || nao },
|
||
{ label: "RSA / MPI", value: seg.rsa || nao },
|
||
{ label: "ECC (elliptic curves)", value: seg.ecc || nao },
|
||
{ label: "Hardware ECDSA", value: seg.ecdsa || nao },
|
||
{ label: "HMAC", value: seg.hmac || nao },
|
||
{ label: "Digital Signature (DS)", value: seg.assinatura_digital || nao },
|
||
{ label: "Key Manager", value: seg.key_manager || nao },
|
||
{ label: "Random Generator (TRNG)", value: seg.rng || nao },
|
||
{ label: "Flash Encryption", value: seg.criptografia_flash || nao },
|
||
{ label: "Secure Boot", value: seg.secure_boot || nao },
|
||
{ label: "DPA Protection", value: seg.protecao_dpa || nao },
|
||
]
|
||
: [
|
||
{ label: "AES", value: seg.aes || "Não" },
|
||
{ label: "SHA", value: seg.sha || "Não" },
|
||
{ label: "RSA / MPI", value: seg.rsa || "Não" },
|
||
{ label: "ECC (curvas elípticas)", value: seg.ecc || "Não" },
|
||
{ label: "ECDSA em hardware", value: seg.ecdsa || "Não" },
|
||
{ label: "HMAC", value: seg.hmac || "Não" },
|
||
{ label: "Assinatura Digital (DS)", value: seg.assinatura_digital || "Não" },
|
||
{ label: "Key Manager", value: seg.key_manager || "Não" },
|
||
{ label: "Gerador aleatório (RNG)", value: seg.rng || "Não" },
|
||
{ label: "Criptografia de flash", value: seg.criptografia_flash || "Não" },
|
||
{ label: "Secure Boot", value: seg.secure_boot || "Não" },
|
||
{ label: "Proteção contra DPA", value: seg.protecao_dpa || "Não" },
|
||
];
|
||
|
||
const ferramentasSpecs = isZh ? [
|
||
{ label: "最低 ESP-IDF 版本", value: serie.esp_idf_minimo || naoInformado },
|
||
{ label: "Arduino 核心", value: serie.arduino_core || naoInformado },
|
||
{ label: "调试", value: serie.depuracao || naoInformado },
|
||
{ label: "封装", value: serie.encapsulamento || naoInformado },
|
||
{ label: "可用模组", value: serie.modulos || naoInformado },
|
||
] : isDe
|
||
? [
|
||
{ label: "Minimales ESP-IDF", value: serie.esp_idf_minimo || naoInformado },
|
||
{ label: "Arduino-Core", value: serie.arduino_core || naoInformado },
|
||
{ label: "Debugging", value: serie.depuracao || naoInformado },
|
||
{ label: "Gehäuse", value: serie.encapsulamento || naoInformado },
|
||
{ label: "Verfügbare Module", value: serie.modulos || naoInformado },
|
||
]
|
||
: isFr
|
||
? [
|
||
{ label: "ESP-IDF minimal", value: serie.esp_idf_minimo || naoInformado },
|
||
{ label: "Core Arduino", value: serie.arduino_core || naoInformado },
|
||
{ label: "Débogage", value: serie.depuracao || naoInformado },
|
||
{ label: "Boîtier", value: serie.encapsulamento || naoInformado },
|
||
{ label: "Modules disponibles", value: serie.modulos || naoInformado },
|
||
]
|
||
: isEs
|
||
? [
|
||
{ label: "ESP-IDF mínimo", value: serie.esp_idf_minimo || naoInformado },
|
||
{ label: "Core Arduino", value: serie.arduino_core || naoInformado },
|
||
{ label: "Depuración", value: serie.depuracao || naoInformado },
|
||
{ label: "Encapsulado", value: serie.encapsulamento || naoInformado },
|
||
{ label: "Módulos disponibles", value: serie.modulos || naoInformado },
|
||
]
|
||
: isEn
|
||
? [
|
||
{ label: "Minimum ESP-IDF", value: serie.esp_idf_minimo || naoInformado },
|
||
{ label: "Arduino Core", value: serie.arduino_core || naoInformado },
|
||
{ label: "Debugging", value: serie.depuracao || naoInformado },
|
||
{ label: "Package", value: serie.encapsulamento || naoInformado },
|
||
{ label: "Available Modules", value: serie.modulos || naoInformado },
|
||
]
|
||
: [
|
||
{ label: "ESP-IDF mínimo", value: serie.esp_idf_minimo || "Não informado" },
|
||
{ label: "Core Arduino", value: serie.arduino_core || "Não informado" },
|
||
{ label: "Depuração", value: serie.depuracao || "Não informado" },
|
||
{ label: "Encapsulamento", value: serie.encapsulamento || "Não informado" },
|
||
{ label: "Módulos disponíveis", value: serie.modulos || "Não informado" },
|
||
];
|
||
|
||
const conectividadeSpecs = isZh ? [
|
||
{ label: "Wi-Fi", value: serie.wifi || nao },
|
||
{ label: "蓝牙", value: serie.bluetooth || nao },
|
||
{ label: "Zigbee/Thread", value: serie.zigbee_thread || nao },
|
||
{ label: "Matter", value: serie.matter || nao },
|
||
{ label: "以太网", value: serie.ethernet || serie.ethernet_mac || nao },
|
||
{ label: "CAN", value: serie.can || nao },
|
||
] : isDe
|
||
? [
|
||
{ label: "Wi-Fi", value: serie.wifi || nao },
|
||
{ label: "Bluetooth", value: serie.bluetooth || nao },
|
||
{ label: "Zigbee/Thread", value: serie.zigbee_thread || nao },
|
||
{ label: "Matter", value: serie.matter || nao },
|
||
{ label: "Ethernet", value: serie.ethernet || serie.ethernet_mac || nao },
|
||
{ label: "CAN", value: serie.can || nao },
|
||
]
|
||
: isFr
|
||
? [
|
||
{ label: "Wi-Fi", value: serie.wifi || nao },
|
||
{ label: "Bluetooth", value: serie.bluetooth || nao },
|
||
{ label: "Zigbee/Thread", value: serie.zigbee_thread || nao },
|
||
{ label: "Matter", value: serie.matter || nao },
|
||
{ label: "Ethernet", value: serie.ethernet || serie.ethernet_mac || nao },
|
||
{ label: "CAN", value: serie.can || nao },
|
||
]
|
||
: isEs
|
||
? [
|
||
{ label: "Wi-Fi", value: serie.wifi || nao },
|
||
{ label: "Bluetooth", value: serie.bluetooth || nao },
|
||
{ label: "Zigbee/Thread", value: serie.zigbee_thread || nao },
|
||
{ label: "Matter", value: serie.matter || nao },
|
||
{ label: "Ethernet", value: serie.ethernet || serie.ethernet_mac || nao },
|
||
{ label: "CAN", value: serie.can || nao },
|
||
]
|
||
: isEn
|
||
? [
|
||
{ label: "Wi-Fi", value: serie.wifi || nao },
|
||
{ label: "Bluetooth", value: serie.bluetooth || nao },
|
||
{ label: "Zigbee/Thread", value: serie.zigbee_thread || nao },
|
||
{ label: "Matter", value: serie.matter || nao },
|
||
{ label: "Ethernet", value: serie.ethernet || serie.ethernet_mac || nao },
|
||
{ label: "CAN", value: serie.can || nao },
|
||
]
|
||
: [
|
||
{ label: "Wi-Fi", value: serie.wifi || "Não" },
|
||
{ label: "Bluetooth", value: serie.bluetooth || "Não" },
|
||
{ label: "Zigbee/Thread", value: serie.zigbee_thread || "Não" },
|
||
{ label: "Matter", value: serie.matter || "Não" },
|
||
{ label: "Ethernet", value: serie.ethernet || serie.ethernet_mac || "Não" },
|
||
{ label: "CAN", value: serie.can || "Não" },
|
||
];
|
||
|
||
const memoriaSpecs = isZh ? [
|
||
{ label: "SRAM", value: serie.memoria_sram },
|
||
{ label: "RTC SRAM", value: serie.memoria_sram_rtc },
|
||
{ label: "ROM", value: serie.memoria_rom },
|
||
{ label: "外部闪存", value: serie.flash_externa },
|
||
{ label: "外部 PSRAM", value: serie.psram_externa || nao },
|
||
] : isDe
|
||
? [
|
||
{ label: "SRAM", value: serie.memoria_sram },
|
||
{ label: "RTC-SRAM", value: serie.memoria_sram_rtc },
|
||
{ label: "ROM", value: serie.memoria_rom },
|
||
{ label: "Externer Flash", value: serie.flash_externa },
|
||
{ label: "Externer PSRAM", value: serie.psram_externa || nao },
|
||
]
|
||
: isFr
|
||
? [
|
||
{ label: "SRAM", value: serie.memoria_sram },
|
||
{ label: "SRAM RTC", value: serie.memoria_sram_rtc },
|
||
{ label: "ROM", value: serie.memoria_rom },
|
||
{ label: "Flash externe", value: serie.flash_externa },
|
||
{ label: "PSRAM externe", value: serie.psram_externa || nao },
|
||
]
|
||
: isEs
|
||
? [
|
||
{ label: "SRAM", value: serie.memoria_sram },
|
||
{ label: "SRAM RTC", value: serie.memoria_sram_rtc },
|
||
{ label: "ROM", value: serie.memoria_rom },
|
||
{ label: "Flash externa", value: serie.flash_externa },
|
||
{ label: "PSRAM externa", value: serie.psram_externa || nao },
|
||
]
|
||
: isEn
|
||
? [
|
||
{ label: "SRAM", value: serie.memoria_sram },
|
||
{ label: "RTC SRAM", value: serie.memoria_sram_rtc },
|
||
{ label: "ROM", value: serie.memoria_rom },
|
||
{ label: "External Flash", value: serie.flash_externa },
|
||
{ label: "External PSRAM", value: serie.psram_externa || nao },
|
||
]
|
||
: [
|
||
{ label: "SRAM", value: serie.memoria_sram },
|
||
{ label: "SRAM RTC", value: serie.memoria_sram_rtc },
|
||
{ label: "ROM", value: serie.memoria_rom },
|
||
{ label: "Flash Externa", value: serie.flash_externa },
|
||
{ label: "PSRAM Externa", value: serie.psram_externa || "Não" },
|
||
];
|
||
|
||
const perifericos = isZh ? [
|
||
{ label: "GPIO", value: serie.gpio },
|
||
{ label: "ADC", value: serie.adc },
|
||
{ label: "DAC", value: serie.dac || nao },
|
||
{ label: "触摸", value: serie.touch || nao },
|
||
{ label: "UART", value: serie.uart },
|
||
{ label: "SPI", value: serie.spi },
|
||
{ label: "I2C", value: serie.i2c },
|
||
{ label: "I2S", value: serie.i2s },
|
||
{ label: "PWM", value: serie.pwm },
|
||
{ label: "USB", value: serie.usb || nao },
|
||
] : isDe
|
||
? [
|
||
{ label: "GPIO", value: serie.gpio },
|
||
{ label: "ADC", value: serie.adc },
|
||
{ label: "DAC", value: serie.dac || nao },
|
||
{ label: "Touch", value: serie.touch || nao },
|
||
{ label: "UART", value: serie.uart },
|
||
{ label: "SPI", value: serie.spi },
|
||
{ label: "I2C", value: serie.i2c },
|
||
{ label: "I2S", value: serie.i2s },
|
||
{ label: "PWM", value: serie.pwm },
|
||
{ label: "USB", value: serie.usb || nao },
|
||
]
|
||
: isFr
|
||
? [
|
||
{ label: "GPIO", value: serie.gpio },
|
||
{ label: "ADC", value: serie.adc },
|
||
{ label: "DAC", value: serie.dac || nao },
|
||
{ label: "Touch", value: serie.touch || nao },
|
||
{ label: "UART", value: serie.uart },
|
||
{ label: "SPI", value: serie.spi },
|
||
{ label: "I2C", value: serie.i2c },
|
||
{ label: "I2S", value: serie.i2s },
|
||
{ label: "PWM", value: serie.pwm },
|
||
{ label: "USB", value: serie.usb || nao },
|
||
]
|
||
: isEs
|
||
? [
|
||
{ label: "GPIO", value: serie.gpio },
|
||
{ label: "ADC", value: serie.adc },
|
||
{ label: "DAC", value: serie.dac || nao },
|
||
{ label: "Touch", value: serie.touch || nao },
|
||
{ label: "UART", value: serie.uart },
|
||
{ label: "SPI", value: serie.spi },
|
||
{ label: "I2C", value: serie.i2c },
|
||
{ label: "I2S", value: serie.i2s },
|
||
{ label: "PWM", value: serie.pwm },
|
||
{ label: "USB", value: serie.usb || nao },
|
||
]
|
||
: isEn
|
||
? [
|
||
{ label: "GPIO", value: serie.gpio },
|
||
{ label: "ADC", value: serie.adc },
|
||
{ label: "DAC", value: serie.dac || nao },
|
||
{ label: "Touch", value: serie.touch || nao },
|
||
{ label: "UART", value: serie.uart },
|
||
{ label: "SPI", value: serie.spi },
|
||
{ label: "I2C", value: serie.i2c },
|
||
{ label: "I2S", value: serie.i2s },
|
||
{ label: "PWM", value: serie.pwm },
|
||
{ label: "USB", value: serie.usb || nao },
|
||
]
|
||
: [
|
||
{ label: "GPIO", value: serie.gpio },
|
||
{ label: "ADC", value: serie.adc },
|
||
{ label: "DAC", value: serie.dac || "Não" },
|
||
{ label: "Touch", value: serie.touch || "Não" },
|
||
{ label: "UART", value: serie.uart },
|
||
{ label: "SPI", value: serie.spi },
|
||
{ label: "I2C", value: serie.i2c },
|
||
{ label: "I2S", value: serie.i2s },
|
||
{ label: "PWM", value: serie.pwm },
|
||
{ label: "USB", value: serie.usb || "Não" },
|
||
];
|
||
|
||
const interfacesEspeciais = [];
|
||
if (serie.lcd) interfacesEspeciais.push({ label: "LCD", value: serie.lcd });
|
||
if (serie.camera) interfacesEspeciais.push({ label: isZh ? "摄像头" : isDe ? "Kamera" : isFr ? "Caméra" : isEs ? "Cámara" : isEn ? "Camera" : "Câmera", value: serie.camera });
|
||
if (serie.mipi_csi) interfacesEspeciais.push({ label: "MIPI CSI", value: serie.mipi_csi });
|
||
if (serie.mipi_dsi) interfacesEspeciais.push({ label: "MIPI DSI", value: serie.mipi_dsi });
|
||
if (serie.sdio) interfacesEspeciais.push({ label: "SDIO", value: serie.sdio });
|
||
if (serie.sensor_hall) interfacesEspeciais.push({ label: isZh ? "霍尔传感器" : isDe ? "Hall-Sensor" : isFr ? "Capteur Hall" : isEs ? "Sensor Hall" : isEn ? "Hall Sensor" : "Sensor Hall", value: serie.sensor_hall });
|
||
if (serie.sensor_temperatura) interfacesEspeciais.push({ label: isZh ? "温度传感器" : isDe ? "Temperatursensor" : isFr ? "Capteur de température" : isEs ? "Sensor de temperatura" : isEn ? "Temperature Sensor" : "Sensor Temperatura", value: serie.sensor_temperatura });
|
||
|
||
// Consumo de Energia
|
||
const consumoEnergia = [];
|
||
if (serie.consumo_energia) {
|
||
const modoLabelsPt = {
|
||
'active': 'Modo Ativo',
|
||
'active_cpu_240mhz': 'Ativo (CPU 240MHz)',
|
||
'active_cpu_160mhz': 'Ativo (CPU 160MHz)',
|
||
'active_wifi_tx': 'Ativo (Wi-Fi TX)',
|
||
'active_wifi_tx_peak': 'Ativo (Wi-Fi TX Pico)',
|
||
'active_wifi': 'Ativo (Wi-Fi)',
|
||
'active_wifi6': 'Ativo (Wi-Fi 6)',
|
||
'modem_sleep': 'Modem Sleep',
|
||
'modem_sleep_cpu_160mhz': 'Modem Sleep (CPU 160MHz)',
|
||
'light_sleep': 'Light Sleep',
|
||
'deep_sleep': 'Deep Sleep',
|
||
'hibernation': 'Hibernação'
|
||
};
|
||
const modoLabelsEn = {
|
||
'active': 'Active Mode',
|
||
'active_cpu_240mhz': 'Active (CPU 240MHz)',
|
||
'active_cpu_160mhz': 'Active (CPU 160MHz)',
|
||
'active_wifi_tx': 'Active (Wi-Fi TX)',
|
||
'active_wifi_tx_peak': 'Active (Wi-Fi TX Peak)',
|
||
'active_wifi': 'Active (Wi-Fi)',
|
||
'active_wifi6': 'Active (Wi-Fi 6)',
|
||
'modem_sleep': 'Modem Sleep',
|
||
'modem_sleep_cpu_160mhz': 'Modem Sleep (CPU 160MHz)',
|
||
'light_sleep': 'Light Sleep',
|
||
'deep_sleep': 'Deep Sleep',
|
||
'hibernation': 'Hibernation'
|
||
};
|
||
const modoLabelsEs = {
|
||
'active': 'Modo activo',
|
||
'active_cpu_240mhz': 'Activo (CPU 240MHz)',
|
||
'active_cpu_160mhz': 'Activo (CPU 160MHz)',
|
||
'active_wifi_tx': 'Activo (Wi-Fi TX)',
|
||
'active_wifi_tx_peak': 'Activo (Wi-Fi TX Pico)',
|
||
'active_wifi': 'Activo (Wi-Fi)',
|
||
'active_wifi6': 'Activo (Wi-Fi 6)',
|
||
'modem_sleep': 'Modem Sleep',
|
||
'modem_sleep_cpu_160mhz': 'Modem Sleep (CPU 160MHz)',
|
||
'light_sleep': 'Light Sleep',
|
||
'deep_sleep': 'Deep Sleep',
|
||
'hibernation': 'Hibernación'
|
||
};
|
||
const modoLabelsFr = {
|
||
'active': 'Mode actif',
|
||
'active_cpu_240mhz': 'Actif (CPU 240MHz)',
|
||
'active_cpu_160mhz': 'Actif (CPU 160MHz)',
|
||
'active_wifi_tx': 'Actif (Wi-Fi TX)',
|
||
'active_wifi_tx_peak': 'Actif (Wi-Fi TX Pic)',
|
||
'active_wifi': 'Actif (Wi-Fi)',
|
||
'active_wifi6': 'Actif (Wi-Fi 6)',
|
||
'modem_sleep': 'Modem Sleep',
|
||
'modem_sleep_cpu_160mhz': 'Modem Sleep (CPU 160MHz)',
|
||
'light_sleep': 'Light Sleep',
|
||
'deep_sleep': 'Deep Sleep',
|
||
'hibernation': 'Hibernation'
|
||
};
|
||
const modoLabelsDe = {
|
||
'active': 'Aktivmodus',
|
||
'active_cpu_240mhz': 'Aktiv (CPU 240MHz)',
|
||
'active_cpu_160mhz': 'Aktiv (CPU 160MHz)',
|
||
'active_wifi_tx': 'Aktiv (Wi-Fi TX)',
|
||
'active_wifi_tx_peak': 'Aktiv (Wi-Fi TX Spitze)',
|
||
'active_wifi': 'Aktiv (Wi-Fi)',
|
||
'active_wifi6': 'Aktiv (Wi-Fi 6)',
|
||
'modem_sleep': 'Modem Sleep',
|
||
'modem_sleep_cpu_160mhz': 'Modem Sleep (CPU 160MHz)',
|
||
'light_sleep': 'Light Sleep',
|
||
'deep_sleep': 'Deep Sleep',
|
||
'hibernation': 'Ruhezustand'
|
||
};
|
||
const modoLabelsZh = {
|
||
'active': '工作模式',
|
||
'active_cpu_240mhz': '工作(CPU 240MHz)',
|
||
'active_cpu_160mhz': '工作(CPU 160MHz)',
|
||
'active_wifi_tx': '工作(Wi-Fi 发射)',
|
||
'active_wifi_tx_peak': '工作(Wi-Fi 发射峰值)',
|
||
'active_wifi': '工作(Wi-Fi)',
|
||
'active_wifi6': '工作(Wi-Fi 6)',
|
||
'modem_sleep': 'Modem Sleep',
|
||
'modem_sleep_cpu_160mhz': 'Modem Sleep(CPU 160MHz)',
|
||
'light_sleep': 'Light Sleep',
|
||
'deep_sleep': 'Deep Sleep',
|
||
'hibernation': 'Hibernation'
|
||
};
|
||
const modoLabels = isZh ? modoLabelsZh : isDe ? modoLabelsDe : isFr ? modoLabelsFr : isEs ? modoLabelsEs : isEn ? modoLabelsEn : modoLabelsPt;
|
||
|
||
Object.entries(serie.consumo_energia).forEach(([modo, consumo]) => {
|
||
consumoEnergia.push({
|
||
label: modoLabels[modo] || modo.replace(/_/g, ' ').replace(/\b\w/g, (l) => l.toUpperCase()),
|
||
value: consumo
|
||
});
|
||
});
|
||
}
|
||
|
||
const tabs = [
|
||
{
|
||
id: "devboard",
|
||
label: isZh ? "开发板" : isDe ? "Entwicklungsboard" : isFr ? "Carte de développement" : isEs ? "Placa de desarrollo" : isEn ? "Development board" : "Placa de desenvolvimento",
|
||
available: serie.placa,
|
||
content: (
|
||
<div className="card p-5 sm:p-7">
|
||
<h2 className="text-lg font-semibold text-ink">
|
||
{isZh ? "官方开发套件" : isDe ? "Offizielles Development Kit" : isFr ? "Kit de développement officiel" : isEs ? "Kit de desarrollo oficial" : isEn ? "Official development kit" : "Kit de desenvolvimento oficial"}
|
||
</h2>
|
||
{/* As fotos oficiais foram feitas para fundo claro: o quadro fica branco nos dois temas. */}
|
||
<div className="mt-5 overflow-hidden rounded-xl border border-line bg-white p-4">
|
||
<Image
|
||
src={serie.placa}
|
||
alt={isZh ? `开发板 ${key}` : isDe ? `Entwicklungsboard ${key}` : isFr ? `Carte de développement ${key}` : isEs ? `Placa de desarrollo ${key}` : isEn ? `Development board ${key}` : `Placa de desenvolvimento ${key}`}
|
||
width={1200}
|
||
height={800}
|
||
className="mx-auto h-auto max-h-[28rem] w-full rounded-lg object-contain"
|
||
priority
|
||
/>
|
||
</div>
|
||
<p className="mt-3 text-sm text-muted">
|
||
{isZh ? ( <>乐鑫面向 {key} 系列的官方开发板。</> ) : isDe ? (
|
||
<>Offizielles Espressif-Board für die Serie {key}.</>
|
||
) : isFr ? (
|
||
<>Carte officielle d'Espressif pour la série {key}.</>
|
||
) : isEs ? (
|
||
<>Placa estándar de Espressif para la serie {key}.</>
|
||
) : isEn ? (
|
||
<>Official Espressif board for the {key} series.</>
|
||
) : (
|
||
<>Placa padrão da Espressif para a série {key}.</>
|
||
)}
|
||
</p>
|
||
</div>
|
||
),
|
||
},
|
||
{
|
||
id: "connections",
|
||
label: isZh ? "引脚图" : isDe ? "Pinbelegungsdiagramm" : isFr ? "Diagramme de brochage" : isEs ? "Diagrama de patillaje" : isEn ? "Pinout diagram" : "Diagrama de conexões",
|
||
available: conexoes.length > 0,
|
||
content: (
|
||
<div className="card p-5 sm:p-7">
|
||
<div className="callout callout-warn flex items-start gap-3">
|
||
<AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-gold" aria-hidden="true" />
|
||
<div>
|
||
<p className="font-semibold text-ink">
|
||
{isZh ? "这是芯片图,不是开发板" : isDe ? "Dies ist das Diagramm des Chips, nicht des Entwicklungsboards" : isFr ? "Ceci est le schéma de la puce, pas de la carte de développement" : isEs ? "Este es el diagrama del chip, no de la placa" : isEn ? "This is the chip diagram, not the development board" : "Este é o diagrama do chip, não da placa"}
|
||
</p>
|
||
<p className="mt-1">
|
||
{isZh ? ( `该图展示了 ${key} 的芯片内部连接。每块开发板只会引出其中一部分,或做不同的走线。` ) : isDe ? (
|
||
`Das Diagramm zeigt die Silizium-Anschlüsse des ${key}. Jedes Entwicklungsboard führt nur einen Teil heraus oder leitet sie anders weiter.`
|
||
) : isFr ? (
|
||
`Le schéma montre les connexions du silicium du ${key}. Chaque carte de développement n'en expose qu'une partie ou les route différemment.`
|
||
) : isEs ? (
|
||
`El mapa muestra las conexiones del silicio del ${key}. Cada placa de desarrollo expone solo parte de ellas o las enruta de otra forma.`
|
||
) : isEn ? (
|
||
`The map shows the silicon connections for the ${key}. Each development board exposes only a subset or routes them differently.`
|
||
) : (
|
||
<>
|
||
O mapa mostra as conexões do silício do <strong>{key}</strong>. Cada placa de desenvolvimento
|
||
expõe só parte delas, ou as roteia de outra forma.
|
||
</>
|
||
)}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="mt-6">
|
||
<ConnectionsDiagram connections={conexoes} serie={serie} />
|
||
</div>
|
||
|
||
<div className="callout mt-8">
|
||
<p className="flex items-center gap-2 font-semibold text-ink">
|
||
<Lightbulb className="h-4 w-4 text-accent" aria-hidden="true" />
|
||
{isZh ? "几乎每个引脚都可重新配置" : isDe ? "Nahezu jeder Pin ist rekonfigurierbar" : isFr ? "La quasi-totalité des broches est reconfigurable" : isEs ? "Casi todos los pines son reconfigurables" : isEn ? "Almost every pin is reconfigurable" : "Quase todo pino é reconfigurável"}
|
||
</p>
|
||
<p className="mt-1">
|
||
{isZh ? (
|
||
<>
|
||
{key} 的 IO 矩阵可以把 SPI、I2C、UART、PWM 以及摄像头/显示总线移到大多数数字引脚上。关于启动配置引脚的限制和模拟引脚,请查阅{" "}
|
||
<a
|
||
href={`https://docs.espressif.com/projects/esp-idf/en/latest/${String(key).toLowerCase().replace("-", "")}/api-reference/peripherals/gpio.html`}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="inline-flex items-center gap-1 font-medium text-accent underline decoration-accent/30 underline-offset-2 hover:decoration-accent"
|
||
>
|
||
官方 GPIO 指南
|
||
<ExternalLink className="h-3.5 w-3.5" aria-hidden="true" />
|
||
</a>
|
||
。
|
||
</>
|
||
) : isDe ? (
|
||
<>
|
||
Die IO-Matrix des {key} ermöglicht das Zuweisen von SPI, I2C, UART, PWM und Kamera-/Displaybussen
|
||
zu den meisten digitalen Pins. Für Strapping-Einschränkungen und analoge Pins konsultieren Sie den{" "}
|
||
<a
|
||
href={`https://docs.espressif.com/projects/esp-idf/en/latest/${String(key).toLowerCase().replace("-", "")}/api-reference/peripherals/gpio.html`}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="inline-flex items-center gap-1 font-medium text-accent underline decoration-accent/30 underline-offset-2 hover:decoration-accent"
|
||
>
|
||
offiziellen GPIO-Leitfaden
|
||
<ExternalLink className="h-3.5 w-3.5" aria-hidden="true" />
|
||
</a>
|
||
.
|
||
</>
|
||
) : isFr ? (
|
||
<>
|
||
La matrice d'E/S du {key} permet d'assigner SPI, I2C, UART, PWM et bus caméra/écran
|
||
à la majorité des broches numériques. Pour les restrictions de strapping et broches analogiques,
|
||
consultez le{" "}
|
||
<a
|
||
href={`https://docs.espressif.com/projects/esp-idf/en/latest/${String(key).toLowerCase().replace("-", "")}/api-reference/peripherals/gpio.html`}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="inline-flex items-center gap-1 font-medium text-accent underline decoration-accent/30 underline-offset-2 hover:decoration-accent"
|
||
>
|
||
guide officiel GPIO
|
||
<ExternalLink className="h-3.5 w-3.5" aria-hidden="true" />
|
||
</a>
|
||
.
|
||
</>
|
||
) : isEs ? (
|
||
<>
|
||
La matriz de E/S del {key} permite mover buses SPI, I2C, UART, PWM y cámara/pantalla
|
||
a la mayoría de los pines digitales. Para las restricciones de strapping y pines analógicos,
|
||
consulte la{" "}
|
||
<a
|
||
href={`https://docs.espressif.com/projects/esp-idf/en/latest/${String(key).toLowerCase().replace("-", "")}/api-reference/peripherals/gpio.html`}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="inline-flex items-center gap-1 font-medium text-accent underline decoration-accent/30 underline-offset-2 hover:decoration-accent"
|
||
>
|
||
guía oficial de GPIO
|
||
<ExternalLink className="h-3.5 w-3.5" aria-hidden="true" />
|
||
</a>
|
||
.
|
||
</>
|
||
) : isEn ? (
|
||
<>
|
||
The {key} IO matrix allows moving SPI, I2C, UART, PWM, and camera/display buses
|
||
to most digital pins. For strapping restrictions and analog pins, consult the{" "}
|
||
<a
|
||
href={`https://docs.espressif.com/projects/esp-idf/en/latest/${String(key).toLowerCase().replace("-", "")}/api-reference/peripherals/gpio.html`}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="inline-flex items-center gap-1 font-medium text-accent underline decoration-accent/30 underline-offset-2 hover:decoration-accent"
|
||
>
|
||
official GPIO guide
|
||
<ExternalLink className="h-3.5 w-3.5" aria-hidden="true" />
|
||
</a>
|
||
.
|
||
</>
|
||
) : (
|
||
<>
|
||
A matriz de IO do {key} permite mover SPI, I2C, UART, PWM e barramentos de câmera ou display
|
||
para a maioria dos pinos digitais. Para as restrições de strapping e dos pinos analógicos,
|
||
consulte o{" "}
|
||
<a
|
||
href={`https://docs.espressif.com/projects/esp-idf/en/latest/${String(key).toLowerCase().replace("-", "")}/api-reference/peripherals/gpio.html`}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="inline-flex items-center gap-1 font-medium text-accent underline decoration-accent/30 underline-offset-2 hover:decoration-accent"
|
||
>
|
||
guia oficial de GPIO
|
||
<ExternalLink className="h-3.5 w-3.5" aria-hidden="true" />
|
||
</a>
|
||
.
|
||
</>
|
||
)}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
),
|
||
},
|
||
];
|
||
|
||
const secoes = [
|
||
{ id: "processador", titulo: isZh ? "处理器" : isDe ? "Prozessor" : isFr ? "Processeur" : isEs ? "Procesador" : isEn ? "Processor" : "Processador", icon: Cpu, specs: processadorSpecs },
|
||
{ id: "conectividade", titulo: isZh ? "无线连接" : isDe ? "Konnektivität" : isFr ? "Connectivité" : isEs ? "Conectividad" : isEn ? "Connectivity" : "Conectividade", icon: Wifi, specs: conectividadeSpecs },
|
||
{ id: "ferramentas", titulo: isZh ? "工具与可用性" : isDe ? "Werkzeuge und Verfügbarkeit" : isFr ? "Outils et disponibilité" : isEs ? "Herramientas y disponibilidad" : isEn ? "Tools and availability" : "Ferramentas e disponibilidade", icon: Package, specs: ferramentasSpecs },
|
||
{ id: "seguranca", titulo: isZh ? "安全" : isDe ? "Sicherheit" : isFr ? "Sécurité" : isEs ? "Seguridad" : isEn ? "Security" : "Segurança", icon: ShieldCheck, specs: segurancaSpecs },
|
||
{ id: "memoria", titulo: isZh ? "内存" : isDe ? "Speicher" : isFr ? "Mémoire" : isEs ? "Memoria" : isEn ? "Memory" : "Memória", icon: Database, specs: memoriaSpecs },
|
||
...(consumoEnergia.length > 0
|
||
? [{
|
||
id: "energia",
|
||
titulo: isZh ? "功耗" : isDe ? "Stromverbrauch" : isFr ? "Consommation d'énergie" : isEs ? "Consumo de energía" : isEn ? "Power consumption" : "Consumo de energia",
|
||
icon: Battery,
|
||
specs: consumoEnergia,
|
||
nota: isZh ? "典型值,条件为 3.3 V、25 °C。实际功耗取决于射频占空比和所配置的时钟频率。" : isDe
|
||
? "Typische Werte bei 3,3 V und 25 °C. Der tatsächliche Stromverbrauch hängt vom Funk-Tastgrad und der konfigurierten Taktfrequenz ab."
|
||
: isFr
|
||
? "Valeurs typiques à 3,3 V et 25 °C. La consommation réelle dépend du cycle de travail de la radio et de la fréquence d'horloge configurée."
|
||
: isEs
|
||
? "Valores típicos a 3,3 V y 25 °C. El consumo real depende del ciclo de trabajo de la radio y de la frecuencia de reloj configurada."
|
||
: isEn
|
||
? "Typical values at 3.3 V and 25 °C. Actual power consumption depends on radio duty cycle and configured clock frequency."
|
||
: "Valores típicos a 3,3 V e 25 °C. O consumo real depende do ciclo de trabalho do rádio e da frequência de clock configurada.",
|
||
}]
|
||
: []),
|
||
{ id: "perifericos", titulo: isZh ? "外设" : isDe ? "Peripherie" : isFr ? "Périphériques" : isEs ? "Periféricos" : isEn ? "Peripherals" : "Periféricos", icon: Sliders, specs: perifericos },
|
||
...(interfacesEspeciais.length > 0
|
||
? [{ id: "interfaces", titulo: isZh ? "特殊接口" : isDe ? "Spezielle Schnittstellen" : isFr ? "Interfaces spéciales" : isEs ? "Interfaces especiales" : isEn ? "Special interfaces" : "Interfaces especiais", icon: Sliders, specs: interfacesEspeciais }]
|
||
: []),
|
||
{
|
||
id: "temperatura",
|
||
titulo: isZh ? "温度范围" : isDe ? "Temperaturgrenzwerte" : isFr ? "Limites de température" : isEs ? "Límites de temperatura" : isEn ? "Temperature limits" : "Limites de temperatura",
|
||
icon: Thermometer,
|
||
specs: [
|
||
{ label: isZh ? "工作" : isDe ? "Betrieb" : isFr ? "Fonctionnement" : isEs ? "Operación" : isEn ? "Operating" : "Operação", value: serie.temperatura_operacao },
|
||
{ label: isZh ? "存储" : isDe ? "Lagerung" : isFr ? "Stockage" : isEs ? "Almacenamiento" : isEn ? "Storage" : "Armazenamento", value: serie.temperatura_armazenamento },
|
||
],
|
||
},
|
||
];
|
||
|
||
const fatos = [
|
||
{ label: isZh ? "处理器" : isDe ? "Prozessor" : isFr ? "Processeur" : isEs ? "Procesador" : isEn ? "Processor" : "Processador", value: String(serie.nucleos).includes("2") ? "Dual-core" : "Single-core", detail: serie.frequencia },
|
||
{ label: "SRAM", value: serie.memoria_sram, detail: isZh ? `+ ${serie.memoria_sram_rtc} RTC SRAM` : isDe ? `+ ${serie.memoria_sram_rtc} RTC-SRAM` : isFr ? `+ ${serie.memoria_sram_rtc} de SRAM RTC` : isEs ? `+ ${serie.memoria_sram_rtc} de SRAM RTC` : isEn ? `+ ${serie.memoria_sram_rtc} RTC SRAM` : `+ ${serie.memoria_sram_rtc} de SRAM RTC` },
|
||
{ label: "GPIO", value: serie.gpio, detail: isZh ? "个可编程引脚" : isDe ? "programmierbare Pins" : isFr ? "broches programmables" : isEs ? "pines programables" : isEn ? "programmable pins" : "pinos programáveis" },
|
||
{ label: isZh ? "架构" : isDe ? "Architektur" : isFr ? "Architecture" : isEs ? "Arquitectura" : isEn ? "Architecture" : "Arquitetura", value: String(serie.arquitetura).includes("RISC-V") ? "RISC-V" : "Xtensa", detail: serie.arquitetura },
|
||
];
|
||
|
||
return (
|
||
<div className="site-canvas min-h-screen">
|
||
<script
|
||
type="application/ld+json"
|
||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.serie(key, serie, currentLocale)) }}
|
||
/>
|
||
<script
|
||
type="application/ld+json"
|
||
dangerouslySetInnerHTML={{
|
||
__html: JSON.stringify(jsonLd.trilha([
|
||
{ nome: isZh ? "首页" : isDe ? "Startseite" : isFr ? "Accueil" : isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isZh ? "/zh-CN" : isDe ? "/de" : isFr ? "/fr" : isEn ? "/en" : isEs ? "/es" : "/" },
|
||
{ nome: isZh ? "ESP32 系列" : isDe ? "ESP32-Serien" : isFr ? "Séries ESP32" : isEs ? "Series ESP32" : isEn ? "ESP32 Series" : "Séries ESP32", caminho: getLocalizedHref("/series", currentLocale) },
|
||
{ nome: serie.nome_completo, caminho: getLocalizedHref(`/series/${key}`, currentLocale) },
|
||
])),
|
||
}}
|
||
/>
|
||
|
||
<Header />
|
||
|
||
<main id="conteudo">
|
||
<PageHero
|
||
isEn={isEn}
|
||
isEs={isEs}
|
||
isFr={isFr}
|
||
isDe={isDe} isZh={isZh}
|
||
trail={[{ label: isZh ? "系列" : isDe ? "Serien" : isFr ? "Séries" : isEs ? "Series" : isEn ? "Series" : "Séries", href: getLocalizedHref("/series", currentLocale) }, { label: key }]}
|
||
icon={Cpu}
|
||
label={serie.arquitetura}
|
||
title={key}
|
||
lede={serie.descricao}
|
||
>
|
||
{serie.datasheet ? (
|
||
<a href={serie.datasheet} target="_blank" rel="noopener noreferrer" className="btn btn-primary">
|
||
<FileText className="h-4 w-4" aria-hidden="true" />
|
||
{isZh ? "官方数据手册" : isDe ? "Offizielles Datenblatt" : isFr ? "Datasheet officiel" : isEs ? "Datasheet oficial" : isEn ? "Official datasheet" : "Datasheet oficial"}
|
||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||
</a>
|
||
) : (
|
||
<span className="btn btn-ghost cursor-not-allowed opacity-70" aria-disabled="true">
|
||
<FileText className="h-4 w-4" aria-hidden="true" />
|
||
{isZh ? "数据手册尚未发布" : isDe ? "Datenblatt noch nicht veröffentlicht" : isFr ? "Datasheet pas encore publié" : isEs ? "Datasheet aún no publicado" : isEn ? "Datasheet not yet published" : "Datasheet ainda não publicado"}
|
||
</span>
|
||
)}
|
||
{serie.guia_de_programacao && (
|
||
<a href={serie.guia_de_programacao} target="_blank" rel="noopener noreferrer" className="btn btn-ghost">
|
||
<Code className="h-4 w-4" aria-hidden="true" />
|
||
{isZh ? "编程指南" : isDe ? "Programmierleitfaden" : isFr ? "Guide de programmation" : isEs ? "Guía de programación" : isEn ? "Programming guide" : "Guia de programação"}
|
||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||
</a>
|
||
)}
|
||
{serie.manual_tecnico && (
|
||
<a href={serie.manual_tecnico} target="_blank" rel="noopener noreferrer" className="btn btn-ghost">
|
||
<BookOpen className="h-4 w-4" aria-hidden="true" />
|
||
{isZh ? "技术参考手册" : isDe ? "Technisches Referenzhandbuch" : isFr ? "Manuel technique de référence" : isEs ? "Manual de referencia técnica" : isEn ? "Technical reference manual" : "Manual técnico"}
|
||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||
</a>
|
||
)}
|
||
</PageHero>
|
||
|
||
<section className="shell mt-10" aria-label={isZh ? "概要" : isDe ? "Zusammenfassung" : isFr ? "Résumé" : isEs ? "Resumen" : isEn ? "Summary" : "Resumo"}>
|
||
<dl className="grid grid-cols-2 gap-3 lg:grid-cols-4">
|
||
{fatos.map((fato) => (
|
||
<div key={fato.label} className="tile">
|
||
<dt className="text-xs font-medium text-muted">{fato.label}</dt>
|
||
<dd className="mt-1 font-display text-2xl font-semibold tracking-[-0.03em] text-ink">{fato.value}</dd>
|
||
<dd className="mt-0.5 text-xs text-muted">{fato.detail}</dd>
|
||
</div>
|
||
))}
|
||
</dl>
|
||
|
||
{serie.status_documentacao && (
|
||
<div className="callout callout-warn mt-4 flex items-start gap-3">
|
||
<AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-gold" aria-hidden="true" />
|
||
<div>
|
||
<p className="font-semibold text-ink">
|
||
{isZh ? "初步文档" : isDe ? "Vorläufige Dokumentation" : isFr ? "Documentation préliminaire" : isEs ? "Documentación preliminar" : isEn ? "Preliminary documentation" : "Documentação preliminar"}
|
||
</p>
|
||
<p className="mt-1">{serie.status_documentacao}</p>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</section>
|
||
|
||
<div className="shell mt-10">
|
||
<SeriesTabMenu tabs={tabs} isEn={isEn} isEs={isEs} isFr={isFr} isDe={isDe} isZh={isZh} />
|
||
<PinRestrictions conexoes={conexoes} serieKey={key} isEn={isEn} isEs={isEs} isFr={isFr} isDe={isDe} isZh={isZh} />
|
||
</div>
|
||
|
||
<div className="shell mt-12">
|
||
<nav
|
||
aria-label={isZh ? "数据手册章节" : isDe ? "Abschnitte des Datenblatts" : isFr ? "Sections de la fiche" : isEs ? "Secciones de la ficha" : isEn ? "Datasheet sections" : "Seções da ficha"}
|
||
className="nav-pill no-scrollbar sticky top-20 z-30 flex gap-1 overflow-x-auto rounded-full p-1.5"
|
||
>
|
||
{secoes.map((secao) => (
|
||
<a key={secao.id} href={`#${secao.id}`} className="nav-link shrink-0">
|
||
{secao.titulo}
|
||
</a>
|
||
))}
|
||
</nav>
|
||
|
||
<div className="mt-8 space-y-5">
|
||
{secoes.map((secao) => (
|
||
<SpecSection key={secao.id} {...secao} />
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<section className="shell section">
|
||
<div className="panel 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">
|
||
{isZh ? ( <>准备好用 {key} 做原型了吗?</> ) : isDe ? (
|
||
<>Bereit zum Prototyping mit {key}?</>
|
||
) : isFr ? (
|
||
<>Prêt à prototyper avec {key} ?</>
|
||
) : isEs ? (
|
||
<>¿Listo para prototipar con {key}?</>
|
||
) : isEn ? (
|
||
<>Ready to prototype with {key}?</>
|
||
) : (
|
||
<>Pronto para prototipar o {key}?</>
|
||
)}
|
||
</h2>
|
||
<p className="mt-3 text-base text-muted">
|
||
{isZh ? "查看这个系列可用的开发板,含 USB、板载传感器和官方商店链接。" : isDe
|
||
? "Entdecken Sie die für diese Serie verfügbaren Entwicklungsboards mit USB, integrierten Sensoren und Links zum offiziellen Shop."
|
||
: isFr
|
||
? "Explorez les cartes de développement disponibles pour cette série, avec USB, capteurs intégrés et liens vers la boutique officielle."
|
||
: isEs
|
||
? "Explore las placas de desarrollo disponibles para esta serie, con USB, sensores integrados y enlaces a la tienda oficial."
|
||
: isEn
|
||
? "Explore development boards available for this series, with USB, onboard sensors, and official store links."
|
||
: "Veja as placas de desenvolvimento disponíveis para a série, com USB, sensores integrados e link para a loja oficial."}
|
||
</p>
|
||
</div>
|
||
<Link href={getLocalizedHref("/catalogo", currentLocale)} className="btn btn-primary shrink-0">
|
||
{isZh ? "查看开发板" : isDe ? "Boards ansehen" : isFr ? "Voir les cartes" : isEs ? "Ver placas" : isEn ? "View boards" : "Ver placas"}
|
||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||
</Link>
|
||
</div>
|
||
|
||
<nav aria-label={isZh ? "其他系列" : isDe ? "Andere Serien" : isFr ? "Autres séries" : isEs ? "Otras series" : isEn ? "Other series" : "Outras séries"} className="mt-6 grid gap-3 sm:grid-cols-[1fr_auto_1fr] sm:items-center">
|
||
{previousKey ? (
|
||
<Link href={getLocalizedHref(`/series/${previousKey}`, currentLocale)} className="card card-interactive group flex items-center gap-3 px-5 py-4">
|
||
<ArrowLeft className="h-4 w-4 text-muted transition-transform group-hover:-translate-x-1" aria-hidden="true" />
|
||
<span>
|
||
<span className="block text-xs text-muted">{isZh ? "上一个系列" : isDe ? "Vorherige Serie" : isFr ? "Série précédente" : isEs ? "Serie anterior" : isEn ? "Previous series" : "Série anterior"}</span>
|
||
<span className="block font-display text-lg font-semibold text-ink">{previousKey}</span>
|
||
</span>
|
||
</Link>
|
||
) : (
|
||
<span className="hidden sm:block" />
|
||
)}
|
||
<Link href={getLocalizedHref("/comparacao", currentLocale)} className="btn btn-ghost justify-self-center">
|
||
<Scale className="h-4 w-4" aria-hidden="true" />
|
||
{isZh ? "对比系列" : isDe ? "Serien vergleichen" : isFr ? "Comparer les séries" : isEs ? "Comparar series" : isEn ? "Compare series" : "Comparar séries"}
|
||
</Link>
|
||
{nextKey ? (
|
||
<Link href={getLocalizedHref(`/series/${nextKey}`, currentLocale)} className="card card-interactive group flex items-center justify-end gap-3 px-5 py-4 text-right">
|
||
<span>
|
||
<span className="block text-xs text-muted">{isZh ? "下一个系列" : isDe ? "Nächste Serie" : isFr ? "Série suivante" : isEs ? "Siguiente serie" : isEn ? "Next series" : "Próxima série"}</span>
|
||
<span className="block font-display text-lg font-semibold text-ink">{nextKey}</span>
|
||
</span>
|
||
<ArrowRight className="h-4 w-4 text-muted transition-transform group-hover:translate-x-1" aria-hidden="true" />
|
||
</Link>
|
||
) : (
|
||
<span className="hidden sm:block" />
|
||
)}
|
||
</nav>
|
||
</section>
|
||
</main>
|
||
|
||
<Footer />
|
||
</div>
|
||
);
|
||
}
|
||
|
||
function SpecSection({ id, titulo, icon: Icon, specs, nota }) {
|
||
return (
|
||
<section id={id} aria-labelledby={`${id}-titulo`} className="card scroll-mt-36 p-5 sm:p-7">
|
||
<h2 id={`${id}-titulo`} className="flex items-center gap-3 font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||
<span className="grid h-9 w-9 place-items-center rounded-full bg-accent-soft text-accent">
|
||
<Icon className="h-4 w-4" aria-hidden="true" />
|
||
</span>
|
||
{titulo}
|
||
</h2>
|
||
{nota && <p className="mt-3 text-sm text-muted">{nota}</p>}
|
||
<dl className="mt-5 grid grid-cols-2 gap-3 lg:grid-cols-3">
|
||
{specs.map((spec) => {
|
||
const negativo = /^n[ãa]o\b|^no\b/i.test(String(spec.value));
|
||
return (
|
||
<div key={spec.label} className="tile">
|
||
<dt className="text-xs font-medium text-muted">{spec.label}</dt>
|
||
<dd className={`mt-1 text-sm font-semibold leading-snug ${negativo ? "text-muted" : "text-ink"}`}>{spec.value}</dd>
|
||
</div>
|
||
);
|
||
})}
|
||
</dl>
|
||
</section>
|
||
);
|
||
}
|
||
|
||
export async function generateMetadata({ params }) {
|
||
const { locale, key } = await params;
|
||
const isEn = locale === "en";
|
||
const isEs = locale === "es";
|
||
const isFr = locale === "fr";
|
||
const isDe = locale === "de";
|
||
const isZh = locale === "zh-CN";
|
||
const currentLocale = isZh ? "zh-CN" : isDe ? "de" : isFr ? "fr" : isEs ? "es" : isEn ? "en" : "pt";
|
||
const seriesData = isZh ? seriesDataZh : isDe ? seriesDataDe : isFr ? seriesDataFr : isEs ? seriesDataEs : isEn ? seriesDataEn : seriesDataPt;
|
||
const serie = seriesData[key];
|
||
|
||
if (!serie) {
|
||
return {
|
||
title: isZh ? "未找到该系列" : isDe
|
||
? "Serie nicht gefunden"
|
||
: isFr
|
||
? "Série non trouvée"
|
||
: isEs
|
||
? "Serie no encontrada"
|
||
: isEn
|
||
? "Series not found"
|
||
: "Série não encontrada",
|
||
robots: { index: false, follow: false },
|
||
};
|
||
}
|
||
|
||
const radio = [
|
||
String(serie.wifi).startsWith("Não") || String(serie.wifi).startsWith("No") ? null : serie.wifi.split(" (")[0],
|
||
String(serie.bluetooth).startsWith("Não") || String(serie.bluetooth).startsWith("No") ? null : serie.bluetooth.split(" (")[0],
|
||
serie.zigbee_thread && !String(serie.zigbee_thread).startsWith("Não") && !String(serie.zigbee_thread).startsWith("No") ? "802.15.4" : null,
|
||
].filter(Boolean).join(", ");
|
||
|
||
const descricao = isZh ? `${serie.nome_completo}:${serie.arquitetura},${serie.frequencia},` +
|
||
`${serie.memoria_sram} SRAM,${serie.gpio} 个 GPIO` +
|
||
(radio ? `。无线:${radio}` : "") +
|
||
`。含完整引脚图、外设、硬件安全与受限引脚的简体中文说明。` : isDe
|
||
? `${serie.nome_completo}: ${serie.arquitetura}, ${serie.frequencia}, ` +
|
||
`${serie.memoria_sram} SRAM und ${serie.gpio} GPIOs` +
|
||
(radio ? `. Funk: ${radio}` : "") +
|
||
`. Vollständige Pinbelegung, Peripherie, Hardwaresicherheit und eingeschränkte Pins auf Deutsch.`
|
||
: isFr
|
||
? `${serie.nome_completo} : ${serie.arquitetura}, ${serie.frequencia}, ` +
|
||
`${serie.memoria_sram} de SRAM et ${serie.gpio} GPIO` +
|
||
(radio ? `. Radio : ${radio}` : "") +
|
||
`. Brochage complet, périphériques, sécurité matérielle et broches avec restrictions, en français.`
|
||
: isEs
|
||
? `${serie.nome_completo}: ${serie.arquitetura}, ${serie.frequencia}, ` +
|
||
`${serie.memoria_sram} de SRAM y ${serie.gpio} GPIO` +
|
||
(radio ? `. Radio: ${radio}` : "") +
|
||
`. Patillaje completo, periféricos, seguridad por hardware y pines restringidos, en español.`
|
||
: isEn
|
||
? `${serie.nome_completo}: ${serie.arquitetura}, ${serie.frequencia}, ` +
|
||
`${serie.memoria_sram} SRAM, and ${serie.gpio} GPIOs` +
|
||
(radio ? `. Radio: ${radio}` : "") +
|
||
`. Complete pinout, peripherals, hardware security, and restricted pins in English.`
|
||
: `${serie.nome_completo}: ${serie.arquitetura}, ${serie.frequencia.replace("Até ", "até ")}, ` +
|
||
`${serie.memoria_sram} de SRAM e ${serie.gpio} GPIOs` +
|
||
(radio ? `. Rádio: ${radio}` : "") +
|
||
`. Pinagem completa, periféricos, segurança em hardware e pinos com restrição, em português.`;
|
||
|
||
const imagem = serie.placa
|
||
? [{ url: serie.placa, width: 1600, height: 1091, alt: isZh ? `${serie.nome_completo} 的引脚图` : isDe ? `Pinbelegung von ${serie.nome_completo}` : isFr ? `Brochage de ${serie.nome_completo}` : isEs ? `Patillaje de ${serie.nome_completo}` : isEn ? `Pinout of ${serie.nome_completo}` : `Pinagem do ${serie.nome_completo}` }]
|
||
: [{ url: "/opengraph-image.png", width: 1200, height: 630, alt: "ESPDocs" }];
|
||
|
||
const keywords = isZh ? [ serie.nome_completo, `${serie.nome_completo} 引脚图`, `${serie.nome_completo} 数据手册`, `${serie.nome_completo} 规格`, "ESP32", "乐鑫", "微控制器", ] : isDe
|
||
? [
|
||
serie.nome_completo, `${serie.nome_completo} pinout`, `${serie.nome_completo} Pinbelegung`,
|
||
`${serie.nome_completo} datasheet`, `${serie.nome_completo} Spezifikationen`,
|
||
`${serie.nome_completo} deutsch`, "ESP32", "Espressif", "Mikrocontroller",
|
||
]
|
||
: isFr
|
||
? [
|
||
serie.nome_completo, `${serie.nome_completo} pinout`, `${serie.nome_completo} brochage`,
|
||
`${serie.nome_completo} datasheet`, `${serie.nome_completo} spécifications`,
|
||
`${serie.nome_completo} français`, "ESP32", "Espressif", "microcontrôleur",
|
||
]
|
||
: isEs
|
||
? [
|
||
serie.nome_completo, `${serie.nome_completo} pinout`, `${serie.nome_completo} patillaje`,
|
||
`${serie.nome_completo} datasheet`, `${serie.nome_completo} especificaciones`,
|
||
`${serie.nome_completo} español`, "ESP32", "Espressif", "microcontrolador",
|
||
]
|
||
: isEn
|
||
? [
|
||
serie.nome_completo, `${serie.nome_completo} pinout`,
|
||
`${serie.nome_completo} datasheet`, `${serie.nome_completo} specifications`,
|
||
"ESP32", "Espressif", "microcontroller",
|
||
]
|
||
: [
|
||
serie.nome_completo, `${serie.nome_completo} pinout`,
|
||
`${serie.nome_completo} datasheet`, `${serie.nome_completo} especificações`,
|
||
`${serie.nome_completo} português`, "ESP32", "Espressif", "microcontrolador",
|
||
];
|
||
|
||
const meta = {
|
||
...paginaMeta({
|
||
titulo: isZh ? `${serie.nome_completo}:规格与引脚图` : isDe
|
||
? `${serie.nome_completo}: Spezifikationen und Pinbelegung`
|
||
: isFr
|
||
? `${serie.nome_completo} : spécifications et brochage`
|
||
: isEs
|
||
? `${serie.nome_completo}: especificaciones y patillaje`
|
||
: isEn
|
||
? `${serie.nome_completo}: specifications and pinout`
|
||
: `${serie.nome_completo}: especificações e pinagem`,
|
||
descricao,
|
||
caminho: `/series/${key}`,
|
||
tipo: "article",
|
||
locale: currentLocale,
|
||
keywords,
|
||
}),
|
||
other: {
|
||
"article:section": isZh ? "ESP32 系列" : isDe
|
||
? "ESP32-Serien"
|
||
: isFr
|
||
? "Séries ESP32"
|
||
: isEs
|
||
? "Series ESP32"
|
||
: isEn
|
||
? "ESP32 Series"
|
||
: "Séries ESP32",
|
||
},
|
||
};
|
||
|
||
meta.openGraph = { ...meta.openGraph, images: imagem };
|
||
meta.twitter = { ...meta.twitter, images: imagem };
|
||
|
||
return meta;
|
||
}
|
||
|
||
export async function generateStaticParams() {
|
||
return Object.keys(seriesDataPt).map((key) => ({
|
||
key: key,
|
||
}));
|
||
} |