// Generates PS_Launcher-Guide-Utilisateur.pptx const pptxgen = require("pptxgenjs"); const COL = { bg: "000000", card: "161B23", elev: "1E2632", border: "2A2F3A", text: "F2F2F2", muted: "A0A0A8", accent: "3B82F6", accentDk: "1F3A66", green: "16A34A", greenDk: "0E2A1B", amber: "F59E0B", amberDk: "3A2A0E", red: "EF4444", redDk: "2A1414", codeBg: "0A0E14", }; const F_TITLE = "Calibri"; const F_BODY = "Calibri"; const F_CODE = "Consolas"; const pres = new pptxgen(); pres.layout = "LAYOUT_16x9"; pres.author = "ASTERION VR"; pres.title = "PROSERVE Launcher — Guide Utilisateur"; pres.company = "ASTERION VR"; const W = 10, H = 5.625; // ---- helpers (same as internal but kept local to avoid module fuss) ---- function fillBg(slide) { slide.background = { color: COL.bg }; } function addHeader(slide, title, kicker) { slide.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: W, h: 0.06, fill: { color: COL.green }, line: { type: "none" } }); if (kicker) { slide.addText(kicker.toUpperCase(), { x: 0.5, y: 0.25, w: W - 1, h: 0.3, fontFace: F_BODY, fontSize: 11, bold: true, color: COL.green, charSpacing: 4, margin: 0 }); } slide.addText(title, { x: 0.5, y: kicker ? 0.55 : 0.35, w: W - 1, h: 0.7, fontFace: F_TITLE, fontSize: 32, bold: true, color: COL.text, margin: 0 }); slide.addShape(pres.shapes.LINE, { x: 0.5, y: kicker ? 1.3 : 1.15, w: 1.2, h: 0, line: { color: COL.green, width: 2 } }); } function addFooter(slide, page) { slide.addText("PROSERVE Launcher • Guide Utilisateur • ASTERION VR", { x: 0.5, y: H - 0.35, w: W - 2, h: 0.25, fontFace: F_BODY, fontSize: 9, color: COL.muted, margin: 0 }); if (page) { slide.addText(String(page), { x: W - 1, y: H - 0.35, w: 0.5, h: 0.25, fontFace: F_BODY, fontSize: 9, color: COL.muted, align: "right", margin: 0 }); } } function addCard(slide, x, y, w, h, options = {}) { slide.addShape(pres.shapes.RECTANGLE, { x, y, w, h, fill: { color: options.fill || COL.card }, line: { color: options.border || COL.border, width: 1 }, }); } function addAccentCard(slide, x, y, w, h, accentColor) { addCard(slide, x, y, w, h); slide.addShape(pres.shapes.RECTANGLE, { x, y, w: 0.08, h, fill: { color: accentColor }, line: { type: "none" } }); } function addCodeBlock(slide, x, y, w, h, lines) { slide.addShape(pres.shapes.RECTANGLE, { x, y, w, h, fill: { color: COL.codeBg }, line: { color: COL.border, width: 1 } }); const text = (Array.isArray(lines) ? lines : [lines]).map((line, i, arr) => ({ text: line, options: { breakLine: i < arr.length - 1 } })); slide.addText(text, { x: x + 0.15, y: y + 0.1, w: w - 0.3, h: h - 0.2, fontFace: F_CODE, fontSize: 11, color: COL.text, margin: 0, valign: "top" }); } function addBullets(slide, x, y, w, h, items, opts = {}) { const fontSize = opts.fontSize || 14; const color = opts.color || COL.text; const arr = items.map((it, i) => ({ text: it, options: { bullet: { code: "25A0" }, breakLine: i < items.length - 1, color } })); slide.addText(arr, { x, y, w, h, fontFace: F_BODY, fontSize, color, margin: 0, paraSpaceAfter: 6 }); } // ===================== SLIDE 1: COVER ===================== { const s = pres.addSlide(); fillBg(s); // Big band on left s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 3.5, h: H, fill: { color: COL.greenDk }, line: { type: "none" } }); s.addShape(pres.shapes.RECTANGLE, { x: 3.45, y: 0, w: 0.05, h: H, fill: { color: COL.green }, line: { type: "none" } }); // Brand s.addText("ASTERION VR", { x: 0.4, y: 0.5, w: 3, h: 0.4, fontFace: F_BODY, fontSize: 13, bold: true, color: COL.green, charSpacing: 8, margin: 0 }); // Big right title s.addText("PROSERVE", { x: 3.9, y: 1.3, w: 6, h: 1, fontFace: F_TITLE, fontSize: 60, bold: true, color: COL.text, margin: 0 }); s.addText("Launcher", { x: 3.9, y: 2.1, w: 6, h: 0.7, fontFace: F_TITLE, fontSize: 40, bold: true, color: COL.muted, margin: 0 }); s.addText("Guide utilisateur", { x: 3.9, y: 3.0, w: 6, h: 0.5, fontFace: F_TITLE, fontSize: 22, color: COL.green, margin: 0 }); s.addText("Installation, activation et utilisation", { x: 3.9, y: 3.5, w: 6, h: 0.4, fontFace: F_BODY, fontSize: 14, italic: true, color: COL.muted, margin: 0 }); // Left band content s.addText("v0.8", { x: 0.4, y: 2, w: 3, h: 1, fontFace: F_TITLE, fontSize: 56, bold: true, color: COL.text, align: "center", margin: 0 }); s.addText("Mai 2026", { x: 0.4, y: 2.95, w: 3, h: 0.3, fontFace: F_BODY, fontSize: 13, color: COL.muted, align: "center", margin: 0 }); // Bottom strip s.addShape(pres.shapes.RECTANGLE, { x: 0, y: H - 0.5, w: W, h: 0.5, fill: { color: COL.card }, line: { type: "none" } }); s.addText("© 2026 ASTERION VR — Tous droits réservés", { x: 0.5, y: H - 0.45, w: W - 1, h: 0.4, fontFace: F_BODY, fontSize: 11, color: COL.muted, margin: 0 }); } // ===================== SLIDE 2: WHAT IS IT ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "Qu'est-ce que PROSERVE Launcher ?", "introduction"); addFooter(s, 2); s.addText("Une application Windows qui te permet de :", { x: 0.5, y: 1.4, w: W - 1, h: 0.4, fontFace: F_BODY, fontSize: 16, color: COL.text, margin: 0 }); const features = [ ["📦", "Installer", "Télécharge et déploie chaque nouvelle version de Proserve sur ta machine en quelques clics."], ["▶", "Lancer", "Démarre la version de ton choix. Plusieurs versions peuvent cohabiter sur le même PC."], ["🔄", "Mettre à jour", "Détecte automatiquement les nouvelles versions disponibles côté serveur ASTERION et propose la mise à jour."], ["🔑", "License", "Vérifie ta license en ligne (ou via cache local 7 jours en cas de coupure réseau)."], ]; let y = 2.0; features.forEach(([icon, title, desc]) => { addCard(s, 0.5, y, W - 1, 0.7); s.addText(icon, { x: 0.7, y: y + 0.13, w: 0.6, h: 0.45, fontFace: F_TITLE, fontSize: 20, color: COL.green, align: "center", margin: 0 }); s.addText(title, { x: 1.4, y: y + 0.07, w: 2, h: 0.3, fontFace: F_TITLE, fontSize: 14, bold: true, color: COL.text, margin: 0 }); s.addText(desc, { x: 1.4, y: y + 0.34, w: W - 1.9, h: 0.35, fontFace: F_BODY, fontSize: 11, color: COL.muted, margin: 0 }); y += 0.78; }); } // ===================== SLIDE 3: PREREQUISITES ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "Pré-requis", "avant de commencer"); addFooter(s, 3); const prereqs = [ ["💻", "Windows 10 ou 11", "Édition 64-bit. Pas de version macOS / Linux pour l'instant."], ["🌐", "Connexion internet", "Requise pour activer la license et télécharger les versions. Le launcher fonctionne hors-ligne pendant 7 jours après la dernière validation."], ["💾", "Espace disque", "Prévoir ~14 Go par version installée + ~14 Go de cache temporaire pendant le téléchargement."], ["🔑", "Une clé license", "Format PRSRV-XXXX-XXXX-XXXX-XXXX, fournie par ASTERION VR."], ]; let y = 1.5; prereqs.forEach(([icon, title, desc]) => { addAccentCard(s, 0.5, y, W - 1, 0.85, COL.green); s.addText(icon, { x: 0.75, y: y + 0.18, w: 0.7, h: 0.5, fontFace: F_TITLE, fontSize: 22, color: COL.green, align: "center", margin: 0 }); s.addText(title, { x: 1.5, y: y + 0.12, w: 6, h: 0.3, fontFace: F_TITLE, fontSize: 14, bold: true, color: COL.text, margin: 0 }); s.addText(desc, { x: 1.5, y: y + 0.42, w: W - 2, h: 0.4, fontFace: F_BODY, fontSize: 11, color: COL.muted, margin: 0 }); y += 0.95; }); } // ===================== SLIDE 4: INSTALLATION ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "Installation", "première fois"); addFooter(s, 4); const steps = [ ["1", "Télécharge le setup", "Tu reçois un fichier nommé PSLauncher-Setup-X.Y.Z.exe (~80 Mo) — par email, lien WeTransfer, ou via le site ASTERION."], ["2", "Double-clique pour lancer", "Windows peut afficher un avertissement SmartScreen « Éditeur inconnu ».\nClique « Informations complémentaires » → « Exécuter quand même »."], ["3", "Suis l'assistant", "Choisis la langue, valide les chemins par défaut. Le launcher s'installe dans ton profil utilisateur — pas besoin de droits administrateur."], ["4", "Lance PROSERVE Launcher", "Un raccourci apparaît sur le bureau et dans le menu Démarrer."], ]; let y = 1.5; steps.forEach(([num, title, desc]) => { addCard(s, 0.5, y, W - 1, 0.85); s.addShape(pres.shapes.OVAL, { x: 0.7, y: y + 0.2, w: 0.45, h: 0.45, fill: { color: COL.green }, line: { type: "none" } }); s.addText(num, { x: 0.7, y: y + 0.2, w: 0.45, h: 0.45, fontFace: F_TITLE, fontSize: 16, bold: true, color: "FFFFFF", align: "center", valign: "middle", margin: 0 }); s.addText(title, { x: 1.4, y: y + 0.1, w: W - 2, h: 0.3, fontFace: F_TITLE, fontSize: 14, bold: true, color: COL.text, margin: 0 }); s.addText(desc, { x: 1.4, y: y + 0.4, w: W - 2, h: 0.4, fontFace: F_BODY, fontSize: 11, color: COL.muted, margin: 0 }); y += 0.95; }); } // ===================== SLIDE 5: ACTIVATE LICENSE ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "Activer ta license", "premier démarrage"); addFooter(s, 5); s.addText("Au premier lancement, le badge en haut au centre de la fenêtre indique « 🔒 Aucune license » en rouge.", { x: 0.5, y: 1.4, w: W - 1, h: 0.45, fontFace: F_BODY, fontSize: 13, color: COL.text, margin: 0 }); // Badge mockup addAccentCard(s, 0.5, 1.95, 4.5, 1.6, COL.red); s.addText("🔒 Aucune license", { x: 0.7, y: 2.05, w: 4, h: 0.4, fontFace: F_TITLE, fontSize: 16, bold: true, color: COL.red, margin: 0 }); s.addText("Visible dans la barre du haut au centre", { x: 0.7, y: 2.4, w: 4, h: 0.3, fontFace: F_BODY, fontSize: 11, italic: true, color: COL.muted, margin: 0 }); s.addText("👉 Clique dessus !", { x: 0.7, y: 2.85, w: 4, h: 0.5, fontFace: F_TITLE, fontSize: 16, bold: true, color: COL.green, margin: 0 }); // Then addAccentCard(s, 5.2, 1.95, 4.3, 1.6, COL.green); s.addText("Dialog d'activation", { x: 5.4, y: 2.05, w: 4, h: 0.3, fontFace: F_TITLE, fontSize: 14, bold: true, color: COL.text, margin: 0 }); addBullets(s, 5.4, 2.4, 4, 1.1, [ "Colle ta clé PRSRV-…", "Clique « Activer »", "Le badge passe en vert ✓", ], { fontSize: 11 }); // Result addCard(s, 0.5, 3.85, W - 1, 1.0); s.addText("Une fois activée :", { x: 0.7, y: 3.95, w: 4, h: 0.3, fontFace: F_TITLE, fontSize: 13, bold: true, color: COL.green, margin: 0 }); s.addText("La barre indique le nom du client + la date de validité. Tu peux maintenant télécharger les versions de Proserve auxquelles ta license te donne accès.", { x: 0.7, y: 4.25, w: W - 1.4, h: 0.6, fontFace: F_BODY, fontSize: 11, color: COL.muted, margin: 0 }); } // ===================== SLIDE 6: LIBRARY OVERVIEW ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "La fenêtre principale", "ta bibliothèque"); addFooter(s, 6); // Hero card simulated addAccentCard(s, 0.5, 1.4, W - 1, 1.2, COL.green); s.addText("VERSION COURANTE", { x: 0.75, y: 1.5, w: 4, h: 0.3, fontFace: F_BODY, fontSize: 10, bold: true, color: COL.muted, charSpacing: 4, margin: 0 }); s.addText("Proserve v1.4.7", { x: 0.75, y: 1.78, w: 5, h: 0.5, fontFace: F_TITLE, fontSize: 24, bold: true, color: COL.text, margin: 0 }); s.addText("● Installée • Sortie le 29/04/2026 • 14 Go", { x: 0.75, y: 2.25, w: 5, h: 0.3, fontFace: F_BODY, fontSize: 11, color: COL.muted, margin: 0 }); // Big launcher button mockup s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 7.4, y: 1.7, w: 1.8, h: 0.6, fill: { color: COL.green }, line: { type: "none" }, rectRadius: 0.05 }); s.addText("▶ LANCER", { x: 7.4, y: 1.7, w: 1.8, h: 0.6, fontFace: F_TITLE, fontSize: 16, bold: true, color: "FFFFFF", align: "center", valign: "middle", margin: 0 }); // Section header s.addText("AUTRES VERSIONS", { x: 0.5, y: 2.85, w: 3, h: 0.3, fontFace: F_BODY, fontSize: 10, bold: true, color: COL.muted, charSpacing: 4, margin: 0 }); // Other rows const rowY1 = 3.2, rowY2 = 4.0; addAccentCard(s, 0.5, rowY1, W - 1, 0.7, COL.green); s.addText("v1.4.6 ● Installée", { x: 0.75, y: rowY1 + 0.1, w: 5, h: 0.3, fontFace: F_TITLE, fontSize: 13, bold: true, color: COL.text, margin: 0 }); s.addText("14 Go • 15/04/2026", { x: 0.75, y: rowY1 + 0.4, w: 5, h: 0.3, fontFace: F_BODY, fontSize: 10, color: COL.muted, margin: 0 }); s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 8.3, y: rowY1 + 0.18, w: 1.05, h: 0.4, fill: { color: COL.green }, line: { type: "none" }, rectRadius: 0.05 }); s.addText("▶ Lancer", { x: 8.3, y: rowY1 + 0.18, w: 1.05, h: 0.4, fontFace: F_BODY, fontSize: 11, bold: true, color: "FFFFFF", align: "center", valign: "middle", margin: 0 }); addAccentCard(s, 0.5, rowY2, W - 1, 0.7, COL.accent); s.addText("v1.4.5 ○ Disponible", { x: 0.75, y: rowY2 + 0.1, w: 5, h: 0.3, fontFace: F_TITLE, fontSize: 13, bold: true, color: COL.text, margin: 0 }); s.addText("448 Mo • 15/04/2026", { x: 0.75, y: rowY2 + 0.4, w: 5, h: 0.3, fontFace: F_BODY, fontSize: 10, color: COL.muted, margin: 0 }); s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 8.1, y: rowY2 + 0.18, w: 1.25, h: 0.4, fill: { color: COL.accent }, line: { type: "none" }, rectRadius: 0.05 }); s.addText("⬇ Installer", { x: 8.1, y: rowY2 + 0.18, w: 1.25, h: 0.4, fontFace: F_BODY, fontSize: 11, bold: true, color: "FFFFFF", align: "center", valign: "middle", margin: 0 }); } // ===================== SLIDE 7: LAUNCH A VERSION ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "Lancer une version", "▶ jouer"); addFooter(s, 7); s.addText("Deux possibilités :", { x: 0.5, y: 1.4, w: W - 1, h: 0.3, fontFace: F_BODY, fontSize: 14, color: COL.text, margin: 0 }); addAccentCard(s, 0.5, 1.85, 4.5, 2.5, COL.green); s.addText("LA PLUS RÉCENTE", { x: 0.7, y: 1.95, w: 4, h: 0.3, fontFace: F_BODY, fontSize: 11, bold: true, color: COL.green, charSpacing: 3, margin: 0 }); s.addText("Le gros bouton vert dans la carte « Version courante » lance la version la plus récente que tu as installée.", { x: 0.7, y: 2.3, w: 4, h: 1.2, fontFace: F_BODY, fontSize: 12, color: COL.text, margin: 0 }); s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.7, y: 3.55, w: 4, h: 0.6, fill: { color: COL.green }, line: { type: "none" }, rectRadius: 0.05 }); s.addText("▶ LANCER", { x: 0.7, y: 3.55, w: 4, h: 0.6, fontFace: F_TITLE, fontSize: 16, bold: true, color: "FFFFFF", align: "center", valign: "middle", margin: 0 }); addAccentCard(s, 5.2, 1.85, 4.3, 2.5, COL.green); s.addText("UNE VERSION ANCIENNE", { x: 5.4, y: 1.95, w: 4, h: 0.3, fontFace: F_BODY, fontSize: 11, bold: true, color: COL.green, charSpacing: 3, margin: 0 }); s.addText("Dans la section « Autres versions », chaque ligne installée a son propre bouton ▶ Lancer pour démarrer cette version précisément.", { x: 5.4, y: 2.3, w: 4, h: 1.5, fontFace: F_BODY, fontSize: 12, color: COL.text, margin: 0 }); // Behavior addCard(s, 0.5, 4.55, W - 1, 0.7); s.addText("ℹ", { x: 0.7, y: 4.65, w: 0.5, h: 0.5, fontFace: F_TITLE, fontSize: 18, bold: true, color: COL.accent, align: "center", margin: 0 }); s.addText("La fenêtre du launcher se réduit automatiquement dans la barre des tâches pour laisser la place à Proserve.", { x: 1.2, y: 4.7, w: W - 1.7, h: 0.5, fontFace: F_BODY, fontSize: 11, color: COL.muted, margin: 0 }); } // ===================== SLIDE 8: INSTALL NEW VERSION ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "Installer une nouvelle version", "📦 télécharger"); addFooter(s, 8); const steps = [ ["1", "Vérifie les MAJ", "Bouton « 🔄 Vérifier les MAJ » en bas à gauche.\nLe launcher contacte le serveur et liste les nouvelles versions."], ["2", "Repère la ligne bleue", "Une ligne « ○ Disponible » apparaît avec un bouton bleu « ⬇ Installer X.Y.Z »."], ["3", "Clique « ⬇ Installer »", "Une fenêtre s'ouvre avec les notes de version (Markdown). Lis et clique « Télécharger » pour confirmer."], ["4", "Patience pendant le DL", "La barre de progression en bas montre la vitesse, l'avancement, l'ETA. Tu peux mettre en pause ou annuler."], ["5", "Installation auto", "Une fois le ZIP vérifié (SHA-256), il est extrait dans le dossier d'install à côté des autres versions."], ]; let y = 1.45; steps.forEach(([num, title, desc]) => { addCard(s, 0.5, y, W - 1, 0.7); s.addShape(pres.shapes.OVAL, { x: 0.7, y: y + 0.13, w: 0.4, h: 0.4, fill: { color: COL.accent }, line: { type: "none" } }); s.addText(num, { x: 0.7, y: y + 0.13, w: 0.4, h: 0.4, fontFace: F_TITLE, fontSize: 14, bold: true, color: "FFFFFF", align: "center", valign: "middle", margin: 0 }); s.addText(title, { x: 1.3, y: y + 0.07, w: 8, h: 0.27, fontFace: F_TITLE, fontSize: 12, bold: true, color: COL.text, margin: 0 }); s.addText(desc, { x: 1.3, y: y + 0.32, w: 8, h: 0.4, fontFace: F_BODY, fontSize: 10, color: COL.muted, margin: 0 }); y += 0.78; }); } // ===================== SLIDE 9: PROGRESS / RESUME ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "Suivre un téléchargement", "barre du bas"); addFooter(s, 9); // Mock footer addCard(s, 0.5, 1.5, W - 1, 0.7); s.addText("⬇ v1.4.7 : 4,2 / 14,0 Go • 38 Mo/s • ETA 4 min", { x: 0.75, y: 1.6, w: 7.5, h: 0.3, fontFace: F_CODE, fontSize: 12, color: COL.muted, margin: 0 }); // Progress bar s.addShape(pres.shapes.RECTANGLE, { x: 0.75, y: 1.95, w: 7.5, h: 0.1, fill: { color: "2A2A30" }, line: { type: "none" } }); s.addShape(pres.shapes.RECTANGLE, { x: 0.75, y: 1.95, w: 2.25, h: 0.1, fill: { color: COL.accent }, line: { type: "none" } }); // Cancel button s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 8.5, y: 1.62, w: 0.85, h: 0.4, fill: { color: "3A3A40" }, line: { type: "none" }, rectRadius: 0.05 }); s.addText("Annuler", { x: 8.5, y: 1.62, w: 0.85, h: 0.4, fontFace: F_BODY, fontSize: 11, color: COL.text, align: "center", valign: "middle", margin: 0 }); // Features s.addText("Ce que tu peux faire pendant le DL", { x: 0.5, y: 2.5, w: W - 1, h: 0.3, fontFace: F_TITLE, fontSize: 14, bold: true, color: COL.text, margin: 0 }); addBullets(s, 0.5, 2.85, W - 1, 1.1, [ "Annuler à tout moment (le ZIP partiel est conservé pour reprendre plus tard)", "Fermer le launcher : la prochaine ouverture proposera de reprendre", "Couper le réseau : le launcher attend (retry exponentiel) puis reprend automatiquement", ], { fontSize: 12 }); // Resume callout addAccentCard(s, 0.5, 4.15, W - 1, 0.95, COL.amber); s.addText("↻ Reprendre", { x: 0.75, y: 4.25, w: 2, h: 0.35, fontFace: F_TITLE, fontSize: 14, bold: true, color: COL.amber, margin: 0 }); s.addText("Un DL interrompu apparaît avec un bouton « ↻ Reprendre (X%) » à la place de « Installer ». Le téléchargement reprend là où il s'était arrêté — pas besoin de tout recommencer.", { x: 0.75, y: 4.55, w: W - 1.5, h: 0.6, fontFace: F_BODY, fontSize: 11, color: COL.muted, margin: 0 }); } // ===================== SLIDE 10: VERSION MENU ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "Menu d'une version", "bouton ⋯"); addFooter(s, 10); s.addText("Le bouton « ⋯ » à droite de chaque ligne ouvre un menu contextuel.", { x: 0.5, y: 1.4, w: W - 1, h: 0.4, fontFace: F_BODY, fontSize: 13, color: COL.muted, italic: true, margin: 0 }); // Menu mockup addCard(s, 0.5, 1.95, 4.5, 2.4); s.addText("📜 Voir les release notes", { x: 0.75, y: 2.1, w: 4, h: 0.4, fontFace: F_BODY, fontSize: 13, color: COL.text, margin: 0 }); s.addShape(pres.shapes.LINE, { x: 0.75, y: 2.5, w: 4, h: 0, line: { color: COL.border, width: 0.5 } }); s.addText("📁 Ouvrir le dossier", { x: 0.75, y: 2.6, w: 4, h: 0.4, fontFace: F_BODY, fontSize: 13, color: COL.text, margin: 0 }); s.addShape(pres.shapes.LINE, { x: 0.75, y: 3.0, w: 4, h: 0, line: { color: COL.border, width: 0.5 } }); s.addText("🗑 Supprimer cette version…", { x: 0.75, y: 3.1, w: 4, h: 0.4, fontFace: F_BODY, fontSize: 13, color: COL.text, margin: 0 }); // Description addBullets(s, 5.3, 2.1, 4.2, 2.4, [ "Release notes : disponibles aussi sur les versions non installées", "Ouvrir le dossier : utile pour vérifier l'installation", "Supprimer : libère l'espace disque (≈ 14 Go) avec confirmation. Garde tes anciennes versions tant que tu veux pouvoir y revenir.", ], { fontSize: 11 }); // Tip addAccentCard(s, 0.5, 4.55, W - 1, 0.65, COL.green); s.addText("✓ Aucune suppression automatique : c'est toujours toi qui décides quand effacer une vieille version.", { x: 0.75, y: 4.65, w: W - 1.5, h: 0.5, fontFace: F_BODY, fontSize: 11, color: COL.text, margin: 0 }); } // ===================== SLIDE 11: SETTINGS ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "Paramètres ⚙", "bouton en haut à droite"); addFooter(s, 11); const sections = [ ["🔑", "License", "Statut, propriétaire, date d'expiration. Identifiant machine anonyme (à communiquer à ASTERION en cas de souci de slot machine)."], ["🌐", "Serveur", "URL de l'API ASTERION. À ne changer que si tu y es invité par le support."], ["📁", "Installation", "Dossier où sont posées les versions de Proserve. Par défaut C:\\ASTERION_VR. Bouton « Parcourir » pour changer."], ["💾", "Cache", "Taille du cache de téléchargements. Bouton « Vider » pour libérer de l'espace si besoin."], ["📋", "Logs", "Dossier des logs (.log) — utile en cas de souci, à transmettre au support."], ]; let y = 1.4; sections.forEach(([icon, title, desc]) => { addCard(s, 0.5, y, W - 1, 0.7); s.addText(icon, { x: 0.7, y: y + 0.12, w: 0.5, h: 0.45, fontFace: F_TITLE, fontSize: 18, color: COL.green, align: "center", margin: 0 }); s.addText(title, { x: 1.25, y: y + 0.07, w: 2, h: 0.3, fontFace: F_TITLE, fontSize: 13, bold: true, color: COL.text, margin: 0 }); s.addText(desc, { x: 1.25, y: y + 0.33, w: W - 1.7, h: 0.4, fontFace: F_BODY, fontSize: 10, color: COL.muted, margin: 0 }); y += 0.78; }); } // ===================== SLIDE 12: AUTO-UPDATE ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "Mises à jour du launcher", "🔄 automatiques"); addFooter(s, 12); s.addText("Le launcher se met à jour tout seul quand ASTERION pousse une nouvelle version.", { x: 0.5, y: 1.4, w: W - 1, h: 0.4, fontFace: F_BODY, fontSize: 13, color: COL.text, margin: 0 }); const flow = [ ["1", "Détection", "Au démarrage et à chaque clic « Vérifier les MAJ », le launcher contacte le serveur."], ["2", "Notification", "Si une nouvelle version du launcher existe, une popup t'informe et propose de mettre à jour."], ["3", "Téléchargement", "Quelques secondes (le launcher fait ~80 Mo)."], ["4", "Redémarrage automatique", "L'application se ferme, est remplacée, puis se relance avec la nouvelle version."], ]; let y = 1.95; flow.forEach(([num, title, desc]) => { addCard(s, 0.5, y, W - 1, 0.65); s.addShape(pres.shapes.OVAL, { x: 0.7, y: y + 0.12, w: 0.4, h: 0.4, fill: { color: COL.green }, line: { type: "none" } }); s.addText(num, { x: 0.7, y: y + 0.12, w: 0.4, h: 0.4, fontFace: F_TITLE, fontSize: 14, bold: true, color: "FFFFFF", align: "center", valign: "middle", margin: 0 }); s.addText(title, { x: 1.3, y: y + 0.07, w: 8, h: 0.27, fontFace: F_TITLE, fontSize: 12, bold: true, color: COL.text, margin: 0 }); s.addText(desc, { x: 1.3, y: y + 0.32, w: 8, h: 0.32, fontFace: F_BODY, fontSize: 10, color: COL.muted, margin: 0 }); y += 0.73; }); addAccentCard(s, 0.5, 4.95, W - 1, 0.5, COL.green); s.addText("✓ Tu peux toujours refuser et reporter — clique « Plus tard ».", { x: 0.75, y: 5.0, w: W - 1.5, h: 0.4, fontFace: F_BODY, fontSize: 11, color: COL.text, margin: 0 }); } // ===================== SLIDE 13: FAQ ===================== { const s = pres.addSlide(); fillBg(s); addHeader(s, "FAQ", "questions fréquentes"); addFooter(s, 13); const qs = [ ["❓", "Ma license est expirée. Que se passe-t-il ?", "Tu peux toujours utiliser les versions déjà installées. Seul le téléchargement de nouvelles versions est bloqué jusqu'à renouvellement.", COL.amber], ["❓", "Pas de connexion internet — le launcher marche-t-il ?", "Oui, pendant 7 jours après la dernière validation en ligne. Au-delà, la license est considérée comme à revérifier.", COL.accent], ["❓", "Comment changer de PC ?", "Désactive ta license sur l'ancien (Settings → bouton Désactiver), puis active-la sur le nouveau avec la même clé.", COL.green], ["❓", "Le téléchargement échoue avec « SHA-256 invalide » ?", "Réseau bruité ou ZIP modifié côté serveur entre-temps. Le partial est jeté ; le DL recommence proprement au prochain clic.", COL.red], ]; let y = 1.5; qs.forEach(([icon, q, a, color]) => { addAccentCard(s, 0.5, y, W - 1, 0.85, color); s.addText(icon, { x: 0.7, y: y + 0.18, w: 0.4, h: 0.45, fontFace: F_TITLE, fontSize: 16, color, align: "center", margin: 0 }); s.addText(q, { x: 1.2, y: y + 0.1, w: W - 1.7, h: 0.3, fontFace: F_TITLE, fontSize: 12, bold: true, color: COL.text, margin: 0 }); s.addText(a, { x: 1.2, y: y + 0.4, w: W - 1.7, h: 0.45, fontFace: F_BODY, fontSize: 10, color: COL.muted, margin: 0 }); y += 0.95; }); } // ===================== SLIDE 14: SUPPORT ===================== { const s = pres.addSlide(); fillBg(s); // Big band s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 1.3, w: W, h: 1.3, fill: { color: COL.greenDk }, line: { type: "none" } }); s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 1.3, w: W, h: 0.05, fill: { color: COL.green }, line: { type: "none" } }); s.addText("Besoin d'aide ?", { x: 0.5, y: 1.55, w: W - 1, h: 0.6, fontFace: F_TITLE, fontSize: 32, bold: true, color: COL.text, margin: 0 }); s.addText("Contacte ASTERION VR avec ces infos pour un support efficace :", { x: 0.5, y: 2.1, w: W - 1, h: 0.4, fontFace: F_BODY, fontSize: 14, italic: true, color: COL.muted, margin: 0 }); // Three cards const ix = 0.5, iy = 3.05, iw = 3.0, gap = 0.15; const refs = [ ["🔑", "Ta clé license", "PRSRV-XXXX-XXXX-XXXX-XXXX", COL.green], ["💻", "Ton ID machine", "Settings → License\nbouton 📋 Copier", COL.accent], ["📋", "Tes logs", "Settings → Logs\nbouton 📁 Ouvrir", COL.amber], ]; refs.forEach(([icon, title, body, color], i) => { const x = ix + i * (iw + gap); addAccentCard(s, x, iy, iw, 1.7, color); s.addText(icon, { x: x + 0.2, y: iy + 0.15, w: iw - 0.4, h: 0.45, fontFace: F_TITLE, fontSize: 22, color, margin: 0 }); s.addText(title, { x: x + 0.2, y: iy + 0.65, w: iw - 0.4, h: 0.3, fontFace: F_TITLE, fontSize: 13, bold: true, color: COL.text, margin: 0 }); s.addText(body, { x: x + 0.2, y: iy + 0.95, w: iw - 0.4, h: 0.7, fontFace: F_CODE, fontSize: 10, color: COL.muted, margin: 0 }); }); // Footer brand s.addShape(pres.shapes.RECTANGLE, { x: 0, y: H - 0.5, w: W, h: 0.5, fill: { color: COL.card }, line: { type: "none" } }); s.addText("© 2026 ASTERION VR — Tous droits réservés", { x: 0.5, y: H - 0.45, w: W - 1, h: 0.4, fontFace: F_BODY, fontSize: 11, color: COL.muted, align: "center", margin: 0 }); } pres.writeFile({ fileName: "C:\\ASTERION\\GIT\\PS_Launcher\\docs\\PS_Launcher-Guide-Utilisateur.pptx" }) .then(f => console.log("Generated:", f));