<!DOCTYPE html>
<html lang="fr" style="margin: 0; padding: 0; height: auto; min-height: auto;">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Calcul du périmètre</title>
    <!-- Bootstrap 4 CDN avec intégrité et crossorigin pour la sécurité -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" xintegrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
</head>
<body style="margin: 0; padding: 0; height: auto; min-height: auto; overflow-x: hidden; overflow-y: hidden; background-color: #f8f9fa; font-family: Arial, sans-serif;">

    <div id="scorm-main-wrapper" style="padding: 20px; display: flex; flex-direction: column; align-items: center; width: 100%; max-width: 800px; margin: 0 auto;">
        
        <!-- Boîte alerte pour la consigne -->
        <div class="alert alert-info w-100 text-center font-weight-bold" role="alert" style="border-radius: 8px; font-size: 1.2rem;">
            Trouve le périmètre des 3 figures géométriques
        </div>

        <!-- Conteneur principal de l'activité -->
        <div id="activity-container" class="card w-100 shadow-sm" style="border-radius: 10px; border: none;">
            <div class="card-body d-flex flex-column align-items-center" style="padding: 30px;">
                
                <!-- Indicateur de progression -->
                <h5 id="question-counter" class="text-muted mb-4" style="font-size: 1rem;">Question 1 sur 3</h5>

                <!-- Zone de la figure géométrique -->
                <div id="shape-container" class="mb-4 d-flex justify-content-center w-100" style="min-height: 200px; align-items: center;">
                    <!-- Le SVG sera injecté ici par JS -->
                </div>

                <!-- Zone de saisie de la réponse -->
                <div id="input-section" class="w-100 d-flex flex-column align-items-center">
                    <label for="answer-input" class="font-weight-bold" style="font-size: 1.1rem;">Quel est le périmètre ? (en cm)</label>
                    <div class="d-flex w-100 justify-content-center mb-3" style="max-width: 300px;">
                        <input type="number" id="answer-input" class="form-control text-center font-weight-bold" style="font-size: 1.2rem; border-radius: 8px;" placeholder="Ex: 12">
                    </div>
                    <button id="btn-validate" class="btn btn-primary btn-lg px-5 font-weight-bold" style="border-radius: 8px;">Valider</button>
                </div>

                <!-- Zone de rétroaction (cachée par défaut) -->
                <div id="feedback-section" class="w-100 mt-4" style="display: none;">
                    <div id="feedback-alert" class="alert d-flex flex-column align-items-start" role="alert" style="border-radius: 8px;">
                        
                        <div class="d-flex align-items-center mb-3 w-100">
                            <div id="feedback-icon" class="mr-3">
                                <!-- Icône SVG injectée ici -->
                            </div>
                            <h4 id="feedback-title" class="mb-0 font-weight-bold"></h4>
                        </div>

                        <div class="w-100 p-3 mb-3" style="background-color: rgba(255,255,255,0.6); border-radius: 6px; border-left: 4px solid #17a2b8;">
                            <span style="font-size: 1.2rem;">📢</span> <strong>LE HAUT-PARLEUR (Pensée interne) :</strong><br>
                            <em id="feedback-speaker" style="color: #495057; font-size: 1.05rem;"></em>
                        </div>

                        <div class="w-100 p-3" style="background-color: rgba(255,255,255,0.6); border-radius: 6px; border-left: 4px solid #28a745;">
                            <span style="font-size: 1.2rem;">✅</span> <strong>ACTION CONSEILLÉE :</strong><br>
                            <span id="feedback-action" style="color: #212529; font-weight: bold; font-size: 1.05rem;"></span>
                        </div>

                        <div class="w-100 d-flex justify-content-center mt-4">
                            <button id="btn-next" class="btn btn-success btn-lg px-5 font-weight-bold" style="display: none; border-radius: 8px;">Question suivante</button>
                            <button id="btn-retry" class="btn btn-warning btn-lg px-5 font-weight-bold text-dark" style="display: none; border-radius: 8px;">Réessayer</button>
                        </div>
                    </div>
                </div>

                <!-- Écran de fin -->
                <div id="end-screen" class="w-100 text-center" style="display: none;">
                    <h2 class="text-success font-weight-bold mb-3">Félicitations !</h2>
                    <p style="font-size: 1.2rem;">Tu as terminé l'activité avec succès et tu maîtrises le calcul du périmètre.</p>
                    <div class="mt-4">
                        <svg width="100" height="100" viewBox="0 0 24 24" fill="none" stroke="#28a745" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                            <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
                            <polyline points="22 4 12 14.01 9 11.01"></polyline>
                        </svg>
                    </div>
                </div>

            </div>
        </div>
    </div>

    <!-- SCRIPT DE L'INTERACTIVITÉ ET SCORM -->
    <script>
        // --- 1. DONNÉES DE L'ACTIVITÉ ---
        const questions = [
            {
                id: 1,
                svg: `<svg width="240" height="160" viewBox="0 0 240 160">
                        <rect x="40" y="30" width="160" height="100" fill="#e3f2fd" stroke="#007bff" stroke-width="3"/>
                        <text x="120" y="20" text-anchor="middle" font-family="Arial" font-size="16" font-weight="bold" fill="#333">6 cm</text>
                        <text x="215" y="85" text-anchor="middle" font-family="Arial" font-size="16" font-weight="bold" fill="#333">4 cm</text>
                      </svg>`,
                correctAnswer: 20,
                hautParleurError: "Je vois un rectangle. Le périmètre, c'est le contour de la figure. Si j'additionne seulement deux côtés (6 + 4 = 10), je ne fais que la moitié du chemin. Il faut additionner les 4 côtés : 6 + 4 + 6 + 4. La bonne réponse est donc 20 cm.",
                actionError: "Inscris la réponse révélée (20) pour continuer, puis assure-toi d'additionner la mesure de TOUS les côtés la prochaine fois.",
                hautParleurSuccess: "J'ai bien fait le tour complet de la figure. J'ai additionné les 4 côtés : 6 + 4 + 6 + 4 = 20. Mon calcul est logique.",
                actionSuccess: "Bravo ! Tu as bien compris. Passe à la figure suivante."
            },
            {
                id: 2,
                svg: `<svg width="180" height="180" viewBox="0 0 180 180">
                        <rect x="30" y="30" width="120" height="120" fill="#fff3cd" stroke="#ffc107" stroke-width="3"/>
                        <text x="90" y="20" text-anchor="middle" font-family="Arial" font-size="16" font-weight="bold" fill="#333">5 cm</text>
                        <!-- Indicateurs de côtés égaux -->
                        <line x1="85" y1="25" x2="95" y2="35" stroke="#ffc107" stroke-width="2"/><line x1="85" y1="145" x2="95" y2="155" stroke="#ffc107" stroke-width="2"/>
                        <line x1="25" y1="85" x2="35" y2="95" stroke="#ffc107" stroke-width="2"/><line x1="145" y1="85" x2="155" y2="95" stroke="#ffc107" stroke-width="2"/>
                      </svg>`,
                correctAnswer: 20,
                hautParleurError: "C'est un carré, donc tous ses côtés sont de la même longueur. Si je n'ai qu'un seul chiffre (5), je dois me rappeler qu'il y a 4 côtés identiques (5 + 5 + 5 + 5 = 20). Je ne dois pas calculer l'aire (5 x 5). La bonne réponse est 20 cm.",
                actionError: "Inscris 20 pour continuer. Rappelle-toi : pour un carré, on additionne le même chiffre 4 fois.",
                hautParleurSuccess: "Puisque c'est un carré, les 4 côtés mesurent 5 cm. J'ai fait 5 + 5 + 5 + 5 (ou 4 x 5) pour trouver 20. C'est la bonne stratégie.",
                actionSuccess: "Excellente logique ! Passe à la dernière figure."
            },
            {
                id: 3,
                svg: `<svg width="200" height="180" viewBox="0 0 200 180">
                        <polygon points="100,30 40,140 180,140" fill="#d4edda" stroke="#28a745" stroke-width="3"/>
                        <text x="50" y="80" text-anchor="middle" font-family="Arial" font-size="16" font-weight="bold" fill="#333">5 cm</text>
                        <text x="160" y="80" text-anchor="middle" font-family="Arial" font-size="16" font-weight="bold" fill="#333">6 cm</text>
                        <text x="110" y="160" text-anchor="middle" font-family="Arial" font-size="16" font-weight="bold" fill="#333">8 cm</text>
                      </svg>`,
                correctAnswer: 19,
                hautParleurError: "Je dois trouver le contour de ce triangle. Il a trois côtés de longueurs différentes (5, 6 et 8). Je dois m'assurer de n'oublier aucun côté et de simplement les additionner : 5 + 6 + 8 = 19. La bonne réponse est 19 cm.",
                actionError: "Inscris 19 pour valider. Pense à toujours additionner la longueur des trois côtés ensemble.",
                hautParleurSuccess: "J'ai additionné les 3 côtés du triangle (5 + 6 + 8 = 19). J'ai fait le tour complet de la figure sans rien oublier.",
                actionSuccess: "Mission accomplie ! Tu as trouvé le périmètre."
            }
        ];

        // --- 2. VARIABLES D'ÉTAT ---
        let currentQuestionIndex = 0;
        let scormAPI = null;
        let isScorm2004 = false;

        // Icônes SVG
        const iconCorrect = `<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#155724" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>`;
        const iconIncorrect = `<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#721c24" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>`;

        // --- 3. GESTION SCORM (API FINDER SÉCURISÉ) ---
        function findAPI(win) {
            var findAttempts = 0;
            var findAttemptLimit = 500;
            while ((!win.API && !win.API_1484_11) && (win.parent != null) && (win.parent != win)) {
                findAttempts++;
                if (findAttempts > findAttemptLimit) return null;
                try {
                    win = win.parent;
                    // Test d'accès pour déclencher l'erreur cross-origin si présente
                    var test = win.API || win.API_1484_11;
                } catch (e) {
                    // Erreur cross-origin ignorée silencieusement
                    return null;
                }
            }
            return win.API || win.API_1484_11;
        }

        function initSCORM() {
            scormAPI = findAPI(window);
            if (!scormAPI && window.top && window.top != window) {
                scormAPI = findAPI(window.top);
            }

            if (scormAPI) {
                if (scormAPI.Initialize) {
                    isScorm2004 = true;
                    scormAPI.Initialize("");
                } else if (scormAPI.LMSInitialize) {
                    isScorm2004 = false;
                    scormAPI.LMSInitialize("");
                }
                
                // Restaurer la progression
                let savedLocation = "";
                if (isScorm2004) {
                    savedLocation = scormAPI.GetValue("cmi.location");
                } else {
                    savedLocation = scormAPI.LMSGetValue("cmi.core.lesson_location");
                }

                if (savedLocation && !isNaN(savedLocation)) {
                    let loc = parseInt(savedLocation, 10);
                    if (loc >= 0 && loc < questions.length) {
                        currentQuestionIndex = loc;
                    } else if (loc >= questions.length) {
                        currentQuestionIndex = questions.length - 1; // Sécurité
                    }
                }
            } else {
                console.log("Mode Autonome: Aucune API SCORM trouvée.");
            }
        }

        function saveSCORMLocation() {
            if (!scormAPI) return;
            if (isScorm2004) {
                scormAPI.SetValue("cmi.location", currentQuestionIndex.toString());
                scormAPI.Commit("");
            } else {
                scormAPI.LMSSetValue("cmi.core.lesson_location", currentQuestionIndex.toString());
                scormAPI.LMSCommit("");
            }
        }

        function completeSCORM() {
            if (!scormAPI) return;
            if (isScorm2004) {
                scormAPI.SetValue("cmi.completion_status", "completed");
                scormAPI.SetValue("cmi.success_status", "passed");
                scormAPI.SetValue("cmi.score.raw", "100");
                scormAPI.Commit("");
                scormAPI.Terminate("");
            } else {
                scormAPI.LMSSetValue("cmi.core.lesson_status", "completed");
                scormAPI.LMSSetValue("cmi.core.score.raw", "100");
                scormAPI.LMSCommit("");
                scormAPI.LMSFinish("");
            }
        }

        // --- 4. LOGIQUE DE L'INTERFACE UTILISATEUR ---
        
        function renderQuestion() {
            if (currentQuestionIndex >= questions.length) {
                showEndScreen();
                return;
            }

            const q = questions[currentQuestionIndex];
            
            // Mise à jour de l'UI
            document.getElementById('question-counter').innerText = `Question ${currentQuestionIndex + 1} sur ${questions.length}`;
            document.getElementById('shape-container').innerHTML = q.svg;
            document.getElementById('answer-input').value = '';
            document.getElementById('answer-input').disabled = false;
            
            // Réinitialiser les sections
            document.getElementById('input-section').style.display = 'flex';
            document.getElementById('feedback-section').style.display = 'none';
            document.getElementById('btn-validate').style.display = 'block';
            
            // Focus sur l'input
            setTimeout(() => { document.getElementById('answer-input').focus(); }, 100);
            
            // Mettre à jour LMS
            saveSCORMLocation();
            
            // Forcer le redimensionnement Moodle
            if (typeof resizeLMSIframe === 'function') resizeLMSIframe();
        }

        function showFeedback(isCorrect) {
            const q = questions[currentQuestionIndex];
            const alertBox = document.getElementById('feedback-alert');
            const iconBox = document.getElementById('feedback-icon');
            const titleBox = document.getElementById('feedback-title');
            const speakerBox = document.getElementById('feedback-speaker');
            const actionBox = document.getElementById('feedback-action');
            
            document.getElementById('feedback-section').style.display = 'block';
            document.getElementById('btn-validate').style.display = 'none';

            // Retirer classes précédentes
            alertBox.classList.remove('alert-success', 'alert-danger');

            if (isCorrect) {
                alertBox.classList.add('alert-success');
                iconBox.innerHTML = iconCorrect;
                titleBox.innerText = "Excellente réponse !";
                titleBox.style.color = "#155724";
                speakerBox.innerText = q.hautParleurSuccess;
                actionBox.innerText = q.actionSuccess;
                
                document.getElementById('btn-next').style.display = 'block';
                document.getElementById('btn-retry').style.display = 'none';
                document.getElementById('answer-input').disabled = true;
            } else {
                alertBox.classList.add('alert-danger');
                iconBox.innerHTML = iconIncorrect;
                titleBox.innerText = "Ce n'est pas tout à fait ça.";
                titleBox.style.color = "#721c24";
                speakerBox.innerText = q.hautParleurError;
                actionBox.innerText = q.actionError;
                
                document.getElementById('btn-next').style.display = 'none';
                document.getElementById('btn-retry').style.display = 'block';
            }

            if (typeof resizeLMSIframe === 'function') resizeLMSIframe();
        }

        function showEndScreen() {
            document.getElementById('question-counter').style.display = 'none';
            document.getElementById('shape-container').style.display = 'none';
            document.getElementById('input-section').style.display = 'none';
            document.getElementById('feedback-section').style.display = 'none';
            document.getElementById('end-screen').style.display = 'block';
            completeSCORM();
            if (typeof resizeLMSIframe === 'function') resizeLMSIframe();
        }

        // --- 5. ÉVÉNEMENTS ---
        
        document.getElementById('btn-validate').addEventListener('click', function() {
            const inputVal = document.getElementById('answer-input').value.trim();
            if (inputVal === "") return; // Ignorer si vide
            
            const numVal = parseFloat(inputVal.replace(',', '.'));
            const q = questions[currentQuestionIndex];
            
            if (numVal === q.correctAnswer) {
                showFeedback(true);
            } else {
                showFeedback(false);
            }
        });

        document.getElementById('btn-next').addEventListener('click', function() {
            // Jamais de location.reload(), on avance manuellement
            currentQuestionIndex++;
            renderQuestion();
        });

        document.getElementById('btn-retry').addEventListener('click', function() {
            // L'élève a eu la réponse révélée, on lui redonne l'input pour valider
            document.getElementById('feedback-section').style.display = 'none';
            document.getElementById('btn-validate').style.display = 'block';
            document.getElementById('answer-input').value = '';
            document.getElementById('answer-input').focus();
            if (typeof resizeLMSIframe === 'function') resizeLMSIframe();
        });

        // Validation avec la touche Entrée
        document.getElementById('answer-input').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                if (document.getElementById('btn-validate').style.display !== 'none') {
                    document.getElementById('btn-validate').click();
                } else if (document.getElementById('btn-next').style.display !== 'none') {
                    document.getElementById('btn-next').click();
                } else if (document.getElementById('btn-retry').style.display !== 'none') {
                    document.getElementById('btn-retry').click();
                }
            }
        });

        // --- 6. INITIALISATION ---
        window.onload = function() {
            initSCORM();
            renderQuestion();
        };
    </script>

    <!-- SCRIPT DE REDIMENSIONNEMENT IMPÉRATIF POUR LMS -->
    <script>
        function resizeLMSIframe() {
            const wrapper = document.getElementById('scorm-main-wrapper');
            const height = (wrapper ? wrapper.offsetHeight : document.body.scrollHeight) + 50;
            try {
                if (window.frameElement) {
                    window.frameElement.style.height = height + 'px';
                    window.frameElement.setAttribute('scrolling', 'no');
                    window.frameElement.style.overflow = 'hidden';
                }
                if (window.parent && window.parent.document) {
                    const parentDoc = window.parent.document;
                    const scormContent = parentDoc.getElementById('scorm_content');
                    const scormLayout = parentDoc.getElementById('scorm_layout');
                    const scormObject = parentDoc.getElementById('scorm_object');
                    if (scormContent) { scormContent.style.height = 'auto'; scormContent.style.overflow = 'hidden'; }
                    if (scormLayout) { scormLayout.style.height = 'auto'; scormLayout.style.overflow = 'hidden'; }
                    if (scormObject) { scormObject.style.height = height + 'px'; scormObject.style.overflow = 'hidden'; }
                }
                window.parent.postMessage({ type: 'setHeight', height: height }, '*');
            } catch (e) {
                // Ignore silent cross-origin errors
            }
        }
        const resizeObserver = new ResizeObserver(resizeLMSIframe);
        resizeObserver.observe(document.body);
        const mutationObserver = new MutationObserver(resizeLMSIframe);
        mutationObserver.observe(document.body, { childList: true, subtree: true, attributes: true });
        window.addEventListener('load', resizeLMSIframe);
    </script>

</body>
</html>
<!-- RAPPORT_LOI_25_DEBUT -->
Rapport d'analyse de conformité (Loi 25 - Québec) & Sécurité:
1. Protection des renseignements personnels : Le code ne collecte, ne transmet ni ne stocke aucune donnée personnelle identifiante de l'élève. L'état d'avancement est sauvegardé localement dans la session LMS de l'institution via le standard SCORM de façon anonymisée au niveau du paquet.
2. Fuite d'adresses IP (Traqueurs) : Toutes les polices et icônes sont intégrées nativement (SVG inline, polices systèmes standard comme Arial/sans-serif). Aucun appel n'est fait vers Google Fonts, FontAwesome ou des serveurs d'analytique tiers. 
3. Dépendances externes sécurisées : L'unique framework externe (Bootstrap 4) est appelé via un CDN (jsdelivr) sécurisé en HTTPS avec les attributs obligatoires `integrity` (hachage SHA-384) et `crossorigin="anonymous"`, empêchant l'échange de cookies d'identification et protégeant contre l'injection de code malveillant (XSS).
4. Sécurité des iframes (Cross-Origin) : La recherche de l'API SCORM inclut un bloc `try...catch` strict pour prévenir les plantages liés aux politiques de même origine (CORS), assurant une compatibilité sécuritaire dans Google Sites ou Moodle.
5. Gestion des mineurs : Adapté aux moins de 14 ans ; aucune création de profil, aucune publicité, aucun lien sortant non sollicité.
Conclusion : Le code généré est 100% conforme à la Loi 25 et aux standards de cybersécurité pour un public d'âge mineur.
<!-- RAPPORT_LOI_25_FIN -->