ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Concours Masters CCA/GFCF/Finance/Fiscalité/Audit - Maroc
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
Base de données de sujets réels de concours d'accès aux Masters économie-gestion (Finance, Comptabilité & Audit, Management & RH, Marketing & Commerce, Économie Appliquée, Data & Économétrie) dans les universités marocaines (FSJES, ENCG, Facultés Polydisciplinaires...).檢視完整 README ↗
Base de données de sujets réels de concours d'accès aux Masters économie-gestion (Finance, Comptabilité & Audit, Management & RH, Marketing & Commerce, Économie Appliquée, Data & Économétrie) dans les universités marocaines (FSJES, ENCG, Facultés Polydisciplinaires...).
Application Next.js multi-pages :
/ — Accueil (présentation, accès aux sections)/bac/2bac — Cours du 2ème Bac SEG par matière et chapitre ; examens nationaux listés sur la page de chaque matière (la 1ère Bac est masquée tant qu'elle n'est pas rédigée)/cours — Cours de la Licence FSJES par module et chapitre/droit — Cours de la licence de Droit (FSJES) par semestre, tronc commun puis filières, en français et en arabe (public/data/droit.json), lancé le 2026-10-17/concours — Concours (filtres, recherche, rendu Markdown/LaTeX, galerie d'images, export PDF, corrigé quand disponible)/evaluation — QCM d'auto-évaluation par module ; caché depuis le 2026-10-28 (QCM_LANCE = false, lib/contenusPublies.mjs, recette E), /evaluation redirige en 302 vers /concours/blog — Articles de méthode et d'orientation/boutique — Cahiers de préparation commandés sur WhatsApp (le site présente ; paiement et envoi du PDF à la main sur WhatsApp, jamais de PDF sur le site) ; absente du menu tant qu'aucun cahier n'est publié/admin — Console d'administration v7 (voir « La console d'administration » plus bas), protégée par mot de passeLa section « Concours ouverts » (/news, copie automatique d'almaster-maroc.com) a été retirée du
site public le 24/09/2026 pour la demande AdSense ; public/data/news.json et le scraper restent.
lib/espaces.js) : un public = un espace (Bac, Licence FSJES — économie-gestion et
droit —, Licence d'excellence, Master). Un onglet peut dépendre d'un contenu (contenu) : il n'apparaît qu'une
fois ce contenu publié, calculé au build (lib/contenusPublies.mjs → SC_CONTENUS). Les espaces ENCG
et Taalim ont été supprimés le 2026-10-29 (anciennes adresses en 301). Le header,
la barre d'espace, le menu, la barre du bas, le pied de page et l'accueil se construisent depuis
ce registre. Ajouter une section : recette X1 de BANQUE_PROMPTS.md.app/globals.css (indigo de marque, rouge des
corrigés, une couleur de repère par espace via .esp-c-*, échelles de texte, d'espaces et de
largeurs). bac.css (contenu) et space.css (listes, fiches, accueil) n'utilisent que ces
jetons ; la console (app/admin/admin.css) aussi.app/_shared/adPlacements.js (rendus par AdSlot,
hauteur réservée, repli si vide), formulaire de la console généré depuis la même liste. Recette X3.lib/concoursNiveaux.js) : Master, Licence d'excellence, Master Droit.Le site a été refusé par AdSense pour « low value content » à cause de pages minces ou en
construction (pages d'examen réduites à un PDF, chapitres « en préparation », boutique vide,
news copiées). npm run check (et le CI) lance scripts/audit-contenu.mjs après le build : il
parcourt le site depuis l'accueil comme le relecteur et échoue sur toute page « Bientôt / en
préparation », de moins de 120 mots, ou sur un lien interne cassé. Un noindex ne protège pas :
une page liée est vue. Règles détaillées : BANQUE_PROMPTS.md, section 1.6.
GitHub est la base de données. public/data/concours.json, cours.json, quiz.json et news.json ne sont pas une simple seed : ce sont les fichiers que le site lit à chaque requête (via le contenu brut du dépôt) et dans lesquels /admin écrit directement à chaque ajout/modification/suppression (un commit Git par écriture, sur main). Il n'y a pas de base de données séparée qui pourrait diverger du dépôt — GitHub est la source unique, toujours à jour.
public/data/concours.json — un objet par concours, avec enonce_md (énoncé transcrit) et corrige_md (corrigé, optionnel)public/data/extraits/<id>.md et public/data/corriges/<id>.md — une copie lisible par concours de enonce_md/corrige_md, régénérée automatiquement à chaque écriture admin sur un concours, pour naviguer facilement dans le dépôt GitHub sans ouvrir le JSON — même logique que public/images/<ville>/<id>/. Ce sont des copies dérivées (lecture seule) : les éditer directement sur GitHub n'a pas d'effet sur le site, seul concours.json est réellement lu.public/data/cours.json, public/data/quiz.json — mêmes principes que concours.json, pour les fiches de cours et les QCM d'évaluation.public/data/news.json — mis à jour à la fois par scripts/fetch_almaster.py (scraping, lancé à la main depuis l'onglet Actions) et par /admin (ajout/suppression manuelle) : les deux écrivent dans le même fichier. N'est plus affiché sur le site public (voir plus haut).public/images/ — extraits réels scannés des sujets, organisés par ville puis par concoursCorrigés. Un corrigé, quand il existe, est rédigé par IA (relecture croisée entre le scan réel et une transcription texte de la source citée dans source, avec vérification par recoupement des chiffres donnés dans l'énoncé) — pas une correction officielle. Le site le présente comme « Corrigé proposé par SaadConcours, pas une correction officielle de la faculté » (bandeau en tête du corrigé) et ne mentionne jamais l'IA, nulle part sur les pages publiques (décision du 2026-10-10, voir BANQUE_PROMPTS.md §1.3). Chaque sujet de faculté porte la ligne « Sujet officiel du concours de la <établissement> », sauf les concours blancs et reconstitutions de SaadConcours. Toute donnée manquante ou illisible dans les sources disponibles est signalée explicitement dans le corrigé plutôt qu'inventée.
mobile/ contient l'application Flutter native (Android / iOS), détaillée dans
mobile/README.md. Elle lit public/app-data/v1/, généré à chaque build par
scripts/build-app-data.mjs (prebuild, ou npm run app:data) avec les mêmes
règles que le site public (pas de brouillon, pas de source, scans masqués si
réglé) et publié en assets statiques : l'appli ne passe jamais par le Worker.
npm install
npm run dev
Puis ouvrir http://localhost:3000. Sans GITHUB_TOKEN configuré, l'API lit les fichiers public/data/*.json du checkout local (lecture seule : les écritures admin restent en mémoire pour la durée du process, sans toucher au disque ni à GitHub).
Le site tourne sur le plan gratuit de Cloudflare Workers, qui accorde
10 ms de CPU par invocation. Démarrer un isolate froid en consomme à lui
seul ~33 ms (chiffre affiché par wrangler au déploiement : Worker Startup Time). Conséquence directe : toute requête servie par le Worker rend une
Error 1102 si elle tombe sur un isolate froid, avant d'exécuter la moindre
ligne de code applicatif. Ce n'est pas un bug à corriger dans le code, c'est le
plafond du plan.
La parade est structurelle : le site public ne passe pas par le Worker.
next build prérend les pages en .html, et
scripts/prerender-to-assets.mjs les publie dans les assets Cloudflare, servis
au bord du réseau sans démarrer d'isolate — gratuit, illimité, et incapable par
construction de rendre une 1102. Le sitemap y est publié aussi (le script refuse
un sitemap tronqué), et les redirections vivent dans public/_redirects, lu par
Cloudflare avant le Worker — jamais un redirect() Next sur une URL publique.
Le Worker ne garde que /admin, /api/*, les images de partage
(opengraph-image) et les 404. Les icônes et le manifeste sont des fichiers de
public/ (plus des routes Next) et les en-têtes de cache des assets vivent dans
public/_headers. Le même script réduit la copie déployée de public/data/ à ce
que le site lit : sans le champ source, sans brouillons ni sujets d'espaces
cachés, sans extraits/ ni news.json (le dépôt, lui, reste complet).
/api/* non plus depuis le navigateur.
Chaque appel est une invocation du Worker, décomptée du quota gratuit
(100 000 requêtes par jour) : réglages, corrigés et données se lisent dans la
page (inscrits au build) ou dans /data/*. Seul /api/track/batch
(statistiques) reste appelé par les visiteurs.En pratique, quand tu touches à une page publique :
Ne la rends pas dynamique. cookies(), headers(), searchParams,
export const dynamic = "force-dynamic" ou un revalidate non nul retirent
la page du prérendu : elle repasse par le Worker et se remet à tomber en
1102. Ce qui dépend du visiteur se fait côté client, après hydratation.
Vérifie d'un coup d'œil qu'une page est bien servie en statique :
curl -sI https://www.saadconcours.space/concours | grep -i x-opennext
Une ligne x-opennext: 1 signifie que le Worker a été invoqué, donc que la
page peut rendre une 1102. Aucune sortie = servie depuis les assets, tout va
bien.
Le CI le vérifie à chaque déploiement (étape Public pages must not
invoke the Worker) et refuse de laisser passer une régression. Le test
existe parce que la panne est invisible en local — le runtime de next dev
n'a aucune limite CPU — et ne frappe en production qu'une fraction des
requêtes.
Le diagnostic quand une 1102 apparaît quand même :
npx wrangler tail saad-concours --format json --status error
"outcome": "exceededCpu" avec "cpuTime": 10 confirme le plafond CPU. À ne
pas confondre avec la 1102 de l'espace admin causée par une KV_REST_API_URL
invalide, qui est systématique et non intermittente.
Le site a quitté Vercel pour Cloudflare Workers le 21/09/2026. Le déploiement est fait par
GitHub Actions (.github/workflows/deploy-cloudflare.yml) à chaque push sur main :
opennextjs-cloudflare build, publication des pages prérendues en assets
(scripts/prerender-to-assets.mjs), wrangler deploy, puis vérifications en production
(pages en 200, sitemap complet, aucune page publique servie par le Worker) et envoi IndexNow.
L'en-tête du workflow détaille chaque étape.
Jeton GitHub. Un Personal Access Token fine-grained (github.com/settings/personal-access-tokens) : Repository access → ce dépôt uniquement, Permissions → Contents: Read and write. Le même jeton est utilisé à deux endroits :
GH_CONTENT_TOKEN (le build lit settings.json avec) ;GITHUB_TOKEN (la console /admin écrit avec).Secrets.
| Où | Nom | Rôle |
|---|---|---|
| GitHub → Settings → Secrets → Actions | CLOUDFLARE_API_TOKEN | déploiement (modèle « Edit Cloudflare Workers ») |
| GitHub → Settings → Secrets → Actions | GH_CONTENT_TOKEN | jeton GitHub ci-dessus, pour le build |
Worker (npx wrangler secret put …) | GITHUB_TOKEN | écritures de /admin dans le dépôt |
| Worker | ADMIN_PASSWORD, ADMIN_SESSION_SECRET | connexion à /admin |
| Worker | KV_REST_API_URL, KV_REST_API_TOKEN | Redis Upstash (stats, abonnés, corbeille, sessions) |
En local, ces valeurs vont dans .dev.vars (ignoré par git). Sans GITHUB_TOKEN, l'API se
rabat sur les fichiers du build et /admin ne peut pas écrire.
public/data/*.json, écrites par /admin via des commits, voir ci-dessus). Chaque commit sur main, y compris ceux de la console, déclenche un déploiement.saad-concours, route www.saadconcours.space/* (wrangler.jsonc). Le domaine nu saadconcours.space répond par une redirection 301 vers www, servie par Cloudflare.ci.yml (lint, build, garde-fou AdSense sur chaque push), deploy-cloudflare.yml (ci-dessus) et update-news.yml (scraping almaster). Ce dernier n'a plus de cron depuis le 04/10/2026, puisque ses données ne sont plus affichées : il se lance à la main. L'envoi d'emails aux abonnés a été retiré du site (septembre 2026) : la liste s'exporte en CSV depuis la console vers une plateforme d'emailing externe./admin, v7)Refaite en septembre 2026, re-skinnée le 2026-10-10 sur les jetons du site public (plus de dégradés ni d'emoji). Écrans : tableau de bord, concours (liste, éditeur, couverture & qualité, import groupé), cours Licence, cours Bac, évaluations, blog, concours ouverts, boutique, studio social, studio PDF, abonnés, statistiques, monétisation, activité & corbeille, réglages. Recherche globale : Ctrl K.
Comment elle écrit dans le dépôt. Le Worker n'a que 10 ms de CPU : il ne parse plus jamais les gros fichiers. Le navigateur lit public/data/*.json sur le CDN de GitHub (adressé par hash de commit), applique la modification lui-même, envoie le résultat en blob, et /api/admin/repo/commit crée un seul commit pour tous les fichiers touchés (JSON + miroirs Markdown + images), refusé (409) si le fichier a changé entre-temps — la console recharge et réessaie. Voir lib/githubGit.js et app/admin/_lib/repo.js.
"statut": "brouillon" n'apparaît nulle part sur le site (getPublicConcours dans lib/store.js).deploy-cloudflare.yml : une modification est visible sur le site à la fin du déploiement (3 à 5 min)./api/admin/* exige une session (middleware), sauf login/logout.app/_shared/quranVerses.js) ; le navigateur le compose en Amiri Quran et l'insère en image dans le PDF, car jsPDF ne sait pas dessiner l'arabe (app/_shared/pdfVerse.js).Publicités vendues en direct à une école ou un centre, gérées dans Console › Monétisation › Bannières partenaires. Code : app/_shared/partnerAds.js (modèle, rendu, réservation d'espace), app/_shared/chrome.js (affichage), app/layout.js (configuration inscrite dans les pages).
contact ni note) est inscrite dans chaque page au build. Une modification est donc visible au prochain déploiement (3 à 5 min), comme ses images. Aucun appel au Worker n'est nécessaire pour afficher une bannière.getSettings), mais une image envoyée depuis la console n'existe pas sur le disque : elle est remplacée à l'affichage par la bannière suivante, comme en production avant la fin d'un déploiement.