File size: 22,321 Bytes
9181d0f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1a6b8ef
898a131
 
 
 
 
 
 
1a6b8ef
898a131
 
 
1a6b8ef
898a131
 
 
 
 
 
 
 
 
 
1a6b8ef
9181d0f
898a131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9181d0f
 
898a131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1a6b8ef
898a131
 
 
 
 
 
 
 
 
 
 
1a6b8ef
 
9181d0f
 
898a131
9181d0f
 
898a131
 
 
 
9181d0f
898a131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1a6b8ef
 
 
 
898a131
 
 
1a6b8ef
898a131
 
1a6b8ef
898a131
 
 
 
 
 
 
9181d0f
 
898a131
 
 
1a6b8ef
898a131
 
 
 
 
 
 
 
 
 
 
 
1a6b8ef
898a131
 
 
 
 
 
 
 
 
1a6b8ef
9181d0f
898a131
 
 
9181d0f
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>La Baleine IA | Espace Codage</title>
    <link rel="stylesheet" href="style.css">
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://unpkg.com/feather-icons"></script>
</head>
<body class="bg-gray-900 text-gray-100">
    <div class="app-container h-screen flex">
        <!-- Sidebar (same as index.html) -->
        <aside class="w-80 bg-gray-800 border-r border-gray-700 flex flex-col">
            <div class="p-4 border-b border-gray-700 flex items-center gap-3">
                <div class="w-3 h-3 rounded-full bg-blue-500 shadow-lg shadow-blue-500/30"></div>
                <h1 class="font-bold">Espace Codage</h1>
            </div>

            <nav class="flex-1 overflow-y-auto p-2">
                <h2 class="text-xs uppercase tracking-wider text-gray-500 px-3 py-2">Générateurs IA</h2>
                <a href="baleine.html" class="flex items-center gap-3 px-3 py-2 rounded-lg bg-blue-900/30 border border-blue-800/50 text-blue-200 mb-1">
                    <div class="p-2 rounded-lg bg-blue-900/50 border border-blue-800/50">
                        <i data-feather="image" class="w-4 h-4"></i>
                    </div>
                    <span class="truncate">La Baleine IA</span>
                </a>
                <a href="rosalinda.html" class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-gray-750/50 border border-transparent hover:border-gray-700 text-gray-300 mb-1">
                    <div class="p-2 rounded-lg bg-gray-750 border border-gray-700">
                        <i data-feather="message-circle" class="w-4 h-4"></i>
                    </div>
                    <span class="truncate">Rosalinda IA</span>
                </a>
            </nav>
        </aside>
        <!-- Main Content -->
        <main class="flex-1 bg-gray-850/50 overflow-auto">
            <!-- Interface La Baleine IA -->
            <div id="interface-baleine" class="interface-ia">
                
                <!-- En-tête -->
                <div class="ia-header" style="padding: 20px; background: linear-gradient(135deg, #1a237e, #4fc3f7); color: white; border-radius: 12px 12px 0 0;">
                    <h2 style="margin: 0;">🐋 La Baleine IA - Générateur Multimédia</h2>
                    <p style="margin: 5px 0 0 0; opacity: 0.9;">Génération d'images et vidéos par IA - Explications en temps réel</p>
                </div>
                
                <!-- Contenu principal -->
                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; padding: 20px; height: 70vh;">
                    
                    <!-- Colonne gauche : Chat et explications -->
                    <div class="colonne-gauche" style="display: flex; flex-direction: column;">
                        <div id="chat-baleine" style="flex-grow: 1; overflow-y: auto; background: #f8f9fa; border-radius: 10px; padding: 15px; margin-bottom: 15px;">
                            <div class="message-ia">
                                <strong>🐋 La Baleine :</strong> Bonjour ! Je suis votre générateur IA multimédia. Décrivez une scène, et je créerai l'image ou la vidéo correspondante tout en vous expliquant le processus.
                            </div>
                        </div>
                        
                        <div id="explications-baleine" style="background: #e8f5e9; border: 1px solid #c8e6c9; border-radius: 8px; padding: 12px; font-size: 14px; color: #2e7d32;">
                            <strong>📊 Explications en direct :</strong> En attente de votre demande...
                        </div>
                    </div>
                    
                    <!-- Colonne droite : Résultats visuels -->
                    <div class="colonne-droite" style="display: flex; flex-direction: column;">
                        <div id="resultats-baleine" style="flex-grow: 1; background: #263238; border-radius: 10px; padding: 20px; overflow-y: auto; text-align: center;">
                            <h4 style="color: #4fc3f7; margin-top: 0;">🎬 Zone de Génération</h4>
                            <div id="media-container" style="min-height: 300px; display: flex; align-items: center; justify-content: center; color: #78909c;">
                                <p>Votre média généré apparaîtra ici</p>
                            </div>
                        </div>
                        
                        <div class="controles-baleine" style="margin-top: 15px; display: flex; gap: 10px;">
                            <button onclick="telechargerMediaBaleine()" class="btn-success" style="flex: 1;">
                                📥 Télécharger
                            </button>
                            <button onclick="regenererMediaBaleine()" class="btn-warning" style="flex: 1;">
                                 🔄 Regénérer
                            </button>
                        </div>
                    </div>
                </div>
                
                <!-- Zone de saisie et contrôles -->
                <div style="padding: 15px 20px; background: #f5f5f5; border-radius: 0 0 12px 12px; border-top: 1px solid #ddd;">
                    <div style="display: flex; gap: 10px; align-items: center;">
                        <input type="text" 
                               id="input-baleine" 
                               placeholder="Décrivez votre image ou vidéo (ex: 'un dragon volant au coucher du soleil')" 
                               style="flex-grow: 1; padding: 12px; border: 2px solid #4fc3f7; border-radius: 8px; font-size: 16px;">
                        
                        <button onclick="envoyerPromptBaleine()" 
                                style="background: #4fc3f7; color: white; border: none; padding: 12px 25px; border-radius: 8px; font-weight: bold; cursor: pointer;">
                             Générer
                        </button>
                        
                        <button onclick="activerMicroBaleine()" 
                                id="btn-micro-baleine"
                                style="background: #ff4081; color: white; border: none; padding: 12px; border-radius: 8px; cursor: pointer;">
                             Micro
                        </button>
                    </div>
                    
                    <div style="margin-top: 10px; display: flex; gap: 15px; font-size: 14px;">
                        <label>
                            <input type="radio" name="type-media" value="image" checked>  🖼️ Image
                        </label>
                        <label>
                            <input type="radio" name="type-media" value="video">  🎬 Vidéo
                        </label>
                        <label>
                            <input type="radio" name="type-media" value="animation">  ✨ Animation
                        </label>
                    </div>
                </div>
            </div>
        </main>
    </div>
    <script>
        feather.replace();
        
        // ============================================
        //  MOTEUR DE LA BALEINE IA - GÉNÉRATEUR MULTIMÉDIA
        // ============================================

        class BaleineIA {
            constructor() {
                this.config = {
                    apiKey: "hf_votre_cle_api_gratuite", // À remplacer
                    endpoints: {
                        image: "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0",
                        video: "https://api-inference.huggingface.co/models/cerspense/zeroscope_v2_576w"
                    },
                    maxSteps: 50,
                    guidanceScale: 7.5
                };
                
                this.mediaCourant = null;
                this.recognizer = null;
                this.ecouteActive = false;
                
                this.init();
            }
            
            init() {
                console.log("🐋 La Baleine IA initialisée - Version Générateur Multimédia");
                this.setupEventListeners();
                this.setupReconnaissanceVocale();
            }
            
            setupEventListeners() {
                // Saisie clavier
                const input = document.getElementById('input-baleine');
                if (input) {
                    input.addEventListener('keypress', (e) => {
                        if (e.key === 'Enter') this.processerDemande(input.value);
                    });
                }
            }
            
            setupReconnaissanceVocale() {
                if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
                    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
                    this.recognizer = new SpeechRecognition();
                    this.recognizer.lang = 'fr-FR';
                    this.recognizer.continuous = false;
                    this.recognizer.interimResults = false;
                    
                    this.recognizer.onresult = (event) => {
                        const transcription = event.results[0][0].transcript;
                        document.getElementById('input-baleine').value = transcription;
                        this.processerDemande(transcription);
                        this.ecouteActive = false;
                        document.getElementById('btn-micro-baleine').style.background = '#ff4081';
                    };
                    
                    this.recognizer.onerror = (event) => {
                        console.error("Erreur reconnaissance vocale:", event.error);
                        this.ecouteActive = false;
                        document.getElementById('btn-micro-baleine').style.background = '#ff4081';
                    };
                }
            }
            
            // ==================== PROCESSUS PRINCIPAL ====================
            
            async processerDemande(prompt) {
                if (!prompt.trim()) return;
                
                // 1. Afficher la demande utilisateur
                this.afficherMessageUtilisateur(prompt);
                
                // 2. Déterminer le type de média
                const typeMedia = this.determinerTypeMedia(prompt);
                
                // 3. Explications étape par étape
                await this.expliquerProcessus(prompt, typeMedia);
                
                // 4. Génération réelle
                try {
                    const resultat = await this.genererMedia(prompt, typeMedia);
                    this.afficherResultat(resultat, prompt, typeMedia);
                    this.afficherMessageIA(`✅ Génération réussie ! "${prompt}" est maintenant disponible.`);
                } catch (error) {
                    this.afficherMessageIA(`❌ Erreur : ${error.message}. Tentative avec un modèle de secours...`);
                    await this.genererSecours(prompt, typeMedia);
                }
            }
            
            async expliquerProcessus(prompt, typeMedia) {
                const etapes = [
                    "Analyse sémantique de votre demande...",
                    "Extraction des mots-clés et contexte...",
                    `Préparation du modèle ${typeMedia === 'image' ? 'd\'image' : 'de vidéo'}...`,
                    "Configuration des paramètres de génération...",
                    "Lancement de l'inférence IA...",
                    "Post-traitement et optimisation..."
                ];
                
                for (let i = 0; i < etapes.length; i++) {
                    this.afficherExplication(`Étape ${i+1}/${etapes.length}: ${etapes[i]}`);
                    await this.delai(600); // Pause pour effet réaliste
                }
            }
            
            async genererMedia(prompt, type) {
                this.afficherExplication("⚙️ Connexion à l'API de génération...");
                
                const endpoint = type === 'image' ? this.config.endpoints.image : this.config.endpoints.video;
                
                const response = await fetch(endpoint, {
                    method: 'POST',
                    headers: {
                        'Authorization': `Bearer ${this.config.apiKey}`,
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        inputs: prompt,
                        parameters: {
                            num_inference_steps: this.config.maxSteps,
                            guidance_scale: this.config.guidanceScale,
                            width: type === 'image' ? 768 : 576,
                            height: type === 'image' ? 768 : 320
                        }
                    })
                });
                
                if (!response.ok) {
                    throw new Error(`API non disponible (${response.status})`);
                }
                
                this.afficherExplication("✅ Génération terminée ! Traitement du résultat...");
                
                const blob = await response.blob();
                const url = URL.createObjectURL(blob);
                
                return { type, url, blob, nom: `baleine_${type}_${Date.now()}.${type === 'image' ? 'png' : 'mp4'}` };
            }
            
            genererSecours(prompt, type) {
                // Solution de secours avec API alternative
                this.afficherExplication("🔄 Activation du mode secours...");
                
                // Utiliser une API publique gratuite
                const apiSecours = type === 'image' 
                    ? `https://api.unsplash.com/photos/random?query=${encodeURIComponent(prompt)}&client_id=VOTRE_CLE_UNSPLASH`
                    : `https://api.pexels.com/videos/search?query=${encodeURIComponent(prompt)}&per_page=1`;
                
                return fetch(apiSecours)
                    .then(res => res.json())
                    .then(data => {
                        let url;
                        if (type === 'image') {
                            url = data.urls.regular;
                        } else {
                            url = data.videos[0].video_files[0].link;
                        }
                        
                        return {
                            type,
                            url,
                            nom: `baleine_${type}_secours_${Date.now()}.${type === 'image' ? 'jpg' : 'mp4'}`,
                            source: 'secours'
                        };
                    });
            }
            
            afficherResultat(media, prompt, type) {
                this.mediaCourant = media;
                
                const container = document.getElementById('media-container');
                const typeTexte = type === 'image' ? 'Image générée' : 'Vidéo générée';
                
                let html = `
                    <h5 style="color: #fff; margin-bottom: 20px;">"${prompt}"</h5>
                    <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;">
                `;
                
                if (media.type === 'image') {
                    html += `
                        <img src="${media.url}" 
                             alt="${prompt}"
                             style="max-width: 100%; max-height: 400px; border-radius: 8px; box-shadow: 0 10px 30px rgba(0,0,0,0.5);">
                    `;
                } else {
                    html += `
                        <video controls autoplay 
                               style="max-width: 100%; max-height: 400px; border-radius: 8px; box-shadow: 0 10px 30px rgba(0,0,0,0.5);">
                            <source src="${media.url}" type="video/mp4">
                        </video>
                    `;
                }
                
                html += `
                    <div style="margin-top: 15px; color: #b0bec5;">
                        <small>${typeTexte}${new Date().toLocaleTimeString()}</small>
                    </div>
                    </div>
                `;
                
                container.innerHTML = html;
                
                // Activer les boutons de contrôle
                document.querySelector('.controles-baleine').style.display = 'flex';
            }
            
            // ==================== AFFICHAGE DES MESSAGES ====================
            
            afficherMessageUtilisateur(texte) {
                const chat = document.getElementById('chat-baleine');
                const div = document.createElement('div');
                div.className = 'message-utilisateur';
                div.style.cssText = `
                    background: #007bff; 
                    color: white; 
                    padding: 10px 15px; 
                    border-radius: 15px 15px 0 15px; 
                    margin: 10px 0 10px auto; 
                    max-width: 80%;
                    word-wrap: break-word;
                `;
                div.innerHTML = `<strong>👤 Vous :</strong> ${texte}`;
                chat.appendChild(div);
                chat.scrollTop = chat.scrollHeight;
            }
            
            afficherMessageIA(texte) {
                const chat = document.getElementById('chat-baleine');
                const div = document.createElement('div');
                div.className = 'message-ia';
                div.style.cssText = `
                    background: #e3f2fd; 
                    color: #1565c0; 
                    padding: 10px 15px; 
                    border-radius: 15px 15px 15px 0; 
                    margin: 10px 0; 
                    max-width: 80%;
                    word-wrap: break-word;
                `;
                div.innerHTML = `<strong>🐋 La Baleine :</strong> ${texte}`;
                chat.appendChild(div);
                chat.scrollTop = chat.scrollHeight;
            }
            
            afficherExplication(texte) {
                const explications = document.getElementById('explications-baleine');
                if (explications) {
                    explications.innerHTML = `<strong>📊 Explications en direct :</strong> ${texte}`;
                }
            }
            
            // ==================== FONCTIONS UTILITAIRES ====================
            
            determinerTypeMedia(prompt) {
                const promptLower = prompt.toLowerCase();
                const motsVideo = ['vidéo', 'film', 'animation', 'mouvement', 'cinéma', 'courte', 'gif'];
                const motsImage = ['image', 'photo', 'illustration', 'dessin', 'tableau', 'affiche'];
                
                for (const mot of motsVideo) {
                    if (promptLower.includes(mot)) return 'video';
                }
                
                for (const mot of motsImage) {
                    if (promptLower.includes(mot)) return 'image';
                }
                
                // Par défaut, image
                return document.querySelector('input[name="type-media"]:checked').value;
            }
            
            delai(ms) {
                return new Promise(resolve => setTimeout(resolve, ms));
            }
            
            activerMicro() {
                if (!this.recognizer) {
                    this.afficherMessageIA("⚠️ Reconnaissance vocale non supportée sur ce navigateur.");
                    return;
                }
                
                if (!this.ecouteActive) {
                    this.recognizer.start();
                    this.ecouteActive = true;
                    document.getElementById('btn-micro-baleine').style.background = '#d81b60';
                    this.afficherMessageIA("🎤 Micro activé - Parlez maintenant...");
                } else {
                    this.recognizer.stop();
                    this.ecouteActive = false;
                    document.getElementById('btn-micro-baleine').style.background = '#ff4081';
                }
            }
        }

        // ============================================
        // FONCTIONS GLOBALES POUR LES BOUTONS
        // ============================================

        // Instance globale
        const LaBaleine = new BaleineIA();

        // Fonctions appelées par les boutons HTML
        function envoyerPromptBaleine() {
            const input = document.getElementById('input-baleine');
            if (input.value.trim()) {
                LaBaleine.processerDemande(input.value);
                input.value = '';
            }
        }

        function activerMicroBaleine() {
            LaBaleine.activerMicro();
        }

        function telechargerMediaBaleine() {
            if (LaBaleine.mediaCourant) {
                const a = document.createElement('a');
                a.href = LaBaleine.mediaCourant.url;
                a.download = LaBaleine.mediaCourant.nom;
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                
                LaBaleine.afficherMessageIA(`📥 Téléchargement de "${LaBaleine.mediaCourant.nom}" lancé !`);
            }
        }

        function regenererMediaBaleine() {
            const dernierPrompt = document.querySelector('.message-utilisateur:last-child');
            if (dernierPrompt) {
                const texte = dernierPrompt.textContent.replace('👤 Vous:', '').trim();
                if (texte) {
                    LaBaleine.afficherMessageIA("🔄 Regénération en cours...");
                    LaBaleine.processerDemande(texte);
                }
            }
        }

        // Exporter pour DeepSite
        window.LaBaleineIA = LaBaleine;
</script>
</body>
</html>