diff --git a/includes/config.php b/includes/config.php
index 384caa1..402e7f4 100644
--- a/includes/config.php
+++ b/includes/config.php
@@ -38,10 +38,10 @@ $config = [
     'misskey_api_endpoint' => '/api/notes/favorites/create',
     
     // Paramètres pour le traitement
-    'batch_size' => 5,    // Nombre de favoris à traiter en une fois
-    'timeout' => 45,       // Timeout des requêtes en secondes
-    'max_retries' => 3,    // Nombre maximal de tentatives par favori
-    'delay_between_requests' => 2000 // Délai entre les requêtes en millisecondes (pour éviter le rate limiting)
+    'batch_size' => 2,
+    'timeout' => 90,
+    'max_retries' => 3,
+    'delay_between_requests' => 3000
 ];
 
 // Session
diff --git a/includes/functions.php b/includes/functions.php
index 84095aa..fa9ebc9 100644
--- a/includes/functions.php
+++ b/includes/functions.php
@@ -225,49 +225,127 @@ function validate_misskey_token($instance, $token) {
  * @return array Résultat de la recherche
  */
 function search_federated_note($instance, $url, $token) {
+    // Nettoyer l'URL (enlever les éventuels paramètres)
+    $cleanUrl = strtok($url, '?');
+    
+    // Journal de débogage
+    error_log("Recherche fédérée pour: " . $cleanUrl);
+    
     // Méthode principale: Utiliser ap/show qui fonctionne avec la plupart des instances
     $endpoint = '/api/ap/show';
     $data = [
-        'uri' => $url
+        'uri' => $cleanUrl
     ];
     
     // Effectuer la requête
     $result = misskey_api_request($instance, $endpoint, $data, $token);
     
-    // Si la méthode principale a réussi, retourner le résultat
-    if ($result['success'] && isset($result['data']) && !empty($result['data'])) {
-        return $result;
+    // Journal pour le format de la réponse
+    if ($result['success'] && isset($result['data'])) {
+        error_log("Format de réponse ap/show: " . json_encode(array_keys($result['data'])));
     }
     
-    // Méthode de secours 1: Essayer search-by-url (ancienne méthode)
-    $fallback_result = misskey_api_request($instance, '/api/notes/search-by-url', ['url' => $url], $token);
-    
-    if ($fallback_result['success'] && isset($fallback_result['data']) && !empty($fallback_result['data'])) {
-        return $fallback_result;
-    }
-    
-    // Méthode de secours 2: Extraction et recherche par ID distant
-    $urlParts = parse_url($url);
-    $pathParts = isset($urlParts['path']) ? explode('/', trim($urlParts['path'], '/')) : [];
-    
-    if (count($pathParts) >= 4 && $pathParts[count($pathParts) - 2] === 'statuses') {
-        $statusId = end($pathParts);
-        $username = $pathParts[count($pathParts) - 3];
-        $acctDomain = isset($urlParts['host']) ? $urlParts['host'] : '';
+    // Si la méthode principale a réussi et renvoie un ID, retourner le résultat
+    if ($result['success'] && isset($result['data'])) {
+        // Vérifier si l'ID existe directement
+        if (isset($result['data']['id'])) {
+            return $result;
+        }
         
-        if ($statusId && $username && $acctDomain) {
-            $remoteId = "https://{$acctDomain}/users/{$username}/statuses/{$statusId}";
+        // Certaines instances peuvent avoir l'ID dans 'note'
+        if (isset($result['data']['note']) && isset($result['data']['note']['id'])) {
+            // Remonter l'ID au niveau principal
+            $result['data']['id'] = $result['data']['note']['id'];
+            return $result;
+        }
+        
+        // Pour les instances plus récentes qui utilisent un format différent
+        if (!empty($result['data'])) {
+            // Rechercher un champ qui pourrait contenir l'ID
+            foreach (['id', 'noteId', 'objectId', 'originalId'] as $possibleIdField) {
+                if (isset($result['data'][$possibleIdField])) {
+                    $result['data']['id'] = $result['data'][$possibleIdField];
+                    return $result;
+                }
+            }
             
-            $remote_result = misskey_api_request($instance, '/api/notes/show', ['uri' => $remoteId], $token);
-            
-            if ($remote_result['success'] && isset($remote_result['data']) && !empty($remote_result['data'])) {
-                return $remote_result;
+            // Si toujours pas d'ID, examiner la structure pour le trouver
+            foreach ($result['data'] as $key => $value) {
+                if (is_array($value) && isset($value['id'])) {
+                    $result['data']['id'] = $value['id'];
+                    return $result;
+                }
             }
         }
     }
     
-    // Si aucune méthode n'a fonctionné, retourner le résultat de la méthode principale
-    return $result;
+    // Méthode de secours 1: Essayer notes/search-by-url (parfois utilisé dans les anciennes versions)
+    $fallback_result = misskey_api_request($instance, '/api/notes/search-by-url', ['url' => $cleanUrl], $token);
+    
+    if ($fallback_result['success'] && isset($fallback_result['data'])) {
+        error_log("Format de réponse search-by-url: " . json_encode(array_keys($fallback_result['data'])));
+        
+        // Vérifier si nous avons un résultat avec un ID
+        if (isset($fallback_result['data']['id'])) {
+            return $fallback_result;
+        }
+        
+        // Si le résultat est un tableau (certaines instances renvoient un tableau)
+        if (is_array($fallback_result['data']) && !isset($fallback_result['data']['id'])) {
+            // Chercher le premier élément avec un ID
+            foreach ($fallback_result['data'] as $item) {
+                if (is_array($item) && isset($item['id'])) {
+                    $fallback_result['data'] = $item; // Utiliser cet élément comme résultat
+                    return $fallback_result;
+                }
+            }
+        }
+    }
+    
+    // Méthode de secours 2: Extraction et recherche par ID distant
+    $urlParts = parse_url($cleanUrl);
+    if (isset($urlParts['path'])) {
+        $pathParts = explode('/', trim($urlParts['path'], '/'));
+        
+        if (count($pathParts) >= 4 && $pathParts[count($pathParts) - 2] === 'statuses') {
+            $statusId = end($pathParts);
+            $username = $pathParts[count($pathParts) - 3];
+            $acctDomain = isset($urlParts['host']) ? $urlParts['host'] : '';
+            
+            if ($statusId && $username && $acctDomain) {
+                $remoteId = "https://{$acctDomain}/users/{$username}/statuses/{$statusId}";
+                
+                // Essayer d'abord avec /api/notes/show
+                $remote_result = misskey_api_request($instance, '/api/notes/show', ['uri' => $remoteId], $token);
+                
+                if ($remote_result['success'] && isset($remote_result['data']['id'])) {
+                    return $remote_result;
+                }
+                
+                // Dernier recours: essayer renotes/search
+                $renote_result = misskey_api_request($instance, '/api/notes/search', [
+                    'query' => "@{$username}@{$acctDomain} {$statusId}",
+                    'limit' => 10
+                ], $token);
+                
+                if ($renote_result['success'] && !empty($renote_result['data'])) {
+                    // Parcourir les résultats pour trouver une correspondance
+                    foreach ($renote_result['data'] as $note) {
+                        if (isset($note['id'])) {
+                            $renote_result['data'] = $note;
+                            return $renote_result;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    // Si aucune méthode n'a fonctionné, retourner une erreur
+    return [
+        'success' => false,
+        'message' => "Impossible de trouver la publication sur le réseau fédéré après plusieurs tentatives"
+    ];
 }
 
 /**
diff --git a/js/app.js b/js/app.js
index a885213..f5ba176 100644
--- a/js/app.js
+++ b/js/app.js
@@ -366,7 +366,7 @@ document.addEventListener('DOMContentLoaded', function() {
         }
         
         // Nombre d'éléments à traiter dans ce lot
-        const batchSize = 5;
+        const batchSize = 2; // Réduit de 5 à 2 pour limiter les risques de timeout
         const endIndex = Math.min(currentIndex + batchSize, totalItems);
         
         // Préparer les éléments du lot
@@ -376,73 +376,112 @@ document.addEventListener('DOMContentLoaded', function() {
         currentProgress.classList.add('active');
         updateProgress();
         
-        // Simuler le traitement (à remplacer par l'appel API réel)
+        // Ajouter une entrée dans le journal
         addLogEntry(`Traitement du lot ${currentIndex + 1} à ${endIndex}...`, 'info');
         
-        // Envoyer la requête au serveur
-        fetch('process.php', {
-            method: 'POST',
-            headers: {
-                'Content-Type': 'application/json'
-            },
-            body: JSON.stringify({
-                batch: batch,
-                currentIndex: currentIndex,
-                totalItems: totalItems
+        // Compteur de tentatives pour cette requête
+        let retryAttempt = 0;
+        const maxRetries = 3;
+        
+        // Fonction pour envoyer la requête avec retry automatique
+        function sendRequest() {
+            fetch('process.php', {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json'
+                },
+                body: JSON.stringify({
+                    batch: batch,
+                    currentIndex: currentIndex,
+                    totalItems: totalItems
+                }),
+                // Augmenter le timeout pour éviter les erreurs de limite de temps
+                timeout: 60000
             })
-        })
-        .then(response => response.json())
-        .then(data => {
-            if (data.success) {
-                // Traiter les résultats
-                if (data.results && data.results.length) {
-                    data.results.forEach(result => {
-                        addLogEntry(result.message, result.status);
-                        
-                        // Mettre à jour les compteurs
-                        if (result.status === 'success') {
-                            successCount++;
-                        } else if (result.status === 'error') {
-                            errorCount++;
-                        } else if (result.status === 'info') {
-                            skippedCount++;
-                        }
+            .then(response => {
+                // Vérifier si la réponse est au format JSON
+                const contentType = response.headers.get('content-type');
+                if (!contentType || !contentType.includes('application/json')) {
+                    // Si ce n'est pas du JSON, récupérer le texte pour déboguer
+                    return response.text().then(text => {
+                        throw new Error(`Réponse non-JSON reçue: ${text.substring(0, 100)}${text.length > 100 ? '...' : ''}`);
                     });
                 }
+                return response.json();
+            })
+            .then(data => {
+                if (data.success) {
+                    // Traiter les résultats
+                    if (data.results && data.results.length) {
+                        data.results.forEach(result => {
+                            addLogEntry(result.message, result.status);
+                            
+                            // Mettre à jour les compteurs
+                            if (result.status === 'success') {
+                                successCount++;
+                            } else if (result.status === 'error') {
+                                errorCount++;
+                            } else if (result.status === 'info') {
+                                skippedCount++;
+                            }
+                        });
+                    }
+                    
+                    // Mettre à jour l'index
+                    currentIndex = endIndex;
+                    
+                    // Mettre à jour la progression
+                    updateProgress(data.progress.percentage);
+                    
+                    // Mettre à jour les données de migration
+                    updateMigrationData('in_progress', data.progress);
+                    
+                    // Traiter le lot suivant après un court délai
+                    setTimeout(processBatch, 1000);
+                } else {
+                    // Gérer l'erreur
+                    addLogEntry('Erreur: ' + data.message, 'error');
+                    
+                    // Pause en cas d'erreur
+                    isPaused = true;
+                    pauseMigration.textContent = 'Reprendre';
+                    currentProgress.classList.remove('active');
+                    
+                    // Mettre à jour le statut de la migration
+                    updateMigrationData('error');
+                }
+            })
+            .catch(error => {
+                // Afficher l'erreur détaillée dans la console pour le débogage
+                console.error('Erreur complète:', error);
                 
-                // Mettre à jour l'index
-                currentIndex = endIndex;
+                // Ajouter l'erreur au journal
+                addLogEntry('Erreur de connexion: ' + error.message, 'error');
                 
-                // Mettre à jour la progression
-                updateProgress(data.progress.percentage);
-                
-                // Mettre à jour les données de migration
-                updateMigrationData('in_progress', data.progress);
-                
-                // Traiter le lot suivant après un court délai
-                setTimeout(processBatch, 1000);
-            } else {
-                // Gérer l'erreur
-                addLogEntry('Erreur: ' + data.message, 'error');
-                
-                // Pause en cas d'erreur
-                isPaused = true;
-                pauseMigration.textContent = 'Reprendre';
-                currentProgress.classList.remove('active');
-                
-                // Mettre à jour le statut de la migration
-                updateMigrationData('error');
-            }
-        })
-        .catch(error => {
-            // Gérer l'erreur réseau
-            addLogEntry('Erreur de connexion: ' + error.message, 'error');
-            
-            // Pause en cas d'erreur
-            isPaused = true;
-            pauseMigration.textContent = 'Reprendre';
-            currentProgress.classList.remove('active');
-        });
+                // Retenter si nous n'avons pas atteint le nombre maximum de tentatives
+                if (retryAttempt < maxRetries) {
+                    retryAttempt++;
+                    const waitTime = Math.pow(2, retryAttempt) * 1000; // Backoff exponentiel
+                    
+                    addLogEntry(`Nouvelle tentative (${retryAttempt}/${maxRetries}) dans ${waitTime/1000} secondes...`, 'warning');
+                    
+                    setTimeout(sendRequest, waitTime);
+                } else {
+                    // Pause après plusieurs échecs
+                    isPaused = true;
+                    pauseMigration.textContent = 'Reprendre';
+                    currentProgress.classList.remove('active');
+                    
+                    // Mettre à jour le statut de la migration
+                    updateMigrationData('error');
+                    
+                    addLogEntry(`Échec après ${maxRetries} tentatives. Veuillez reprendre manuellement.`, 'error');
+                }
+            });
+        }
+        
+        // Lancer la requête
+        sendRequest();
     }
     
     /**
diff --git a/process.php b/process.php
index 70386b8..6118c23 100644
--- a/process.php
+++ b/process.php
@@ -6,119 +6,171 @@
 // Définir la constante pour inclure les fichiers
 define('FAVMASTOKEY', true);
 
-// Inclure les fichiers requis
-require_once 'includes/config.php';
-require_once 'includes/functions.php';
+// Forcer les en-têtes JSON dès le début pour éviter tout conflit
+header('Content-Type: application/json');
 
-// Vérifier que la requête est en POST
-if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
-    http_response_code(405);
-    echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
+// Activer la capture d'erreurs
+set_error_handler(function($errno, $errstr, $errfile, $errline) {
+    echo json_encode([
+        'success' => false,
+        'message' => "Erreur PHP: $errstr (ligne $errline dans $errfile)",
+    ]);
     exit;
-}
+});
 
-// Vérifier que l'utilisateur est authentifié
-if (!isset($_SESSION['misskey_token']) || empty($_SESSION['misskey_token'])) {
-    http_response_code(401);
-    echo json_encode(['success' => false, 'message' => 'Non authentifié']);
-    exit;
-}
+try {
+    // Inclure les fichiers requis
+    require_once 'includes/config.php';
+    require_once 'includes/functions.php';
 
-// Récupérer l'instance Misskey
-$misskey_instance = isset($_SESSION['misskey_instance']) ? $_SESSION['misskey_instance'] : '';
-if (empty($misskey_instance)) {
-    http_response_code(400);
-    echo json_encode(['success' => false, 'message' => 'Instance Misskey non définie']);
-    exit;
-}
-
-// Récupérer le token d'accès
-$token = $_SESSION['misskey_token'];
-
-// Récupérer les données envoyées
-$input = json_decode(file_get_contents('php://input'), true);
-if (!$input || !isset($input['batch']) || !is_array($input['batch'])) {
-    http_response_code(400);
-    echo json_encode(['success' => false, 'message' => 'Données invalides']);
-    exit;
-}
-
-// Récupérer le lot à traiter
-$batch = $input['batch'];
-$currentIndex = isset($input['currentIndex']) ? (int)$input['currentIndex'] : 0;
-$totalItems = isset($input['totalItems']) ? (int)$input['totalItems'] : count($batch);
-
-// Résultats du traitement
-$results = [];
-
-// Traiter chaque URL du lot
-foreach ($batch as $index => $url) {
-    // Extraire les informations de l'URL
-    $urlParts = parse_url($url);
-    
-    // Vérifier que l'URL est valide
-    if (!$urlParts || !isset($urlParts['host']) || !isset($urlParts['path'])) {
-        $results[] = [
-            'status' => 'error',
-            'message' => "URL invalide: $url"
-        ];
-        continue;
+    // Vérifier que la requête est en POST
+    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
+        http_response_code(405);
+        echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
+        exit;
     }
+
+    // Vérifier que l'utilisateur est authentifié
+    if (!isset($_SESSION['misskey_token']) || empty($_SESSION['misskey_token'])) {
+        http_response_code(401);
+        echo json_encode(['success' => false, 'message' => 'Non authentifié']);
+        exit;
+    }
+
+    // Récupérer l'instance Misskey
+    $misskey_instance = isset($_SESSION['misskey_instance']) ? $_SESSION['misskey_instance'] : '';
+    if (empty($misskey_instance)) {
+        http_response_code(400);
+        echo json_encode(['success' => false, 'message' => 'Instance Misskey non définie']);
+        exit;
+    }
+
+    // Récupérer le token d'accès
+    $token = $_SESSION['misskey_token'];
+
+    // Récupérer les données envoyées
+    $input_data = file_get_contents('php://input');
+    $input = json_decode($input_data, true);
     
-    // Rechercher la note sur Misskey à partir de l'URL
-    $searchResult = search_federated_note($misskey_instance, $url, $token);
-    
-    if ($searchResult['success'] && isset($searchResult['data']) && !empty($searchResult['data'])) {
-        // Note trouvée, récupérer son ID
-        $noteId = $searchResult['data']['id'];
+    if (!$input || !isset($input['batch']) || !is_array($input['batch'])) {
+        http_response_code(400);
+        echo json_encode([
+            'success' => false, 
+            'message' => 'Données invalides',
+            'debug' => [
+                'received' => $input_data ? substr($input_data, 0, 200) . '...' : 'Aucune donnée reçue'
+            ]
+        ]);
+        exit;
+    }
+
+    // Récupérer le lot à traiter
+    $batch = $input['batch'];
+    $currentIndex = isset($input['currentIndex']) ? (int)$input['currentIndex'] : 0;
+    $totalItems = isset($input['totalItems']) ? (int)$input['totalItems'] : count($batch);
+
+    // Résultats du traitement
+    $results = [];
+
+    // Traiter chaque URL du lot
+    foreach ($batch as $index => $url) {
+        // Extraire les informations de l'URL
+        $urlParts = parse_url($url);
         
-        // Tenter d'ajouter la note aux favoris
-        $favoriteResult = add_to_favorites($misskey_instance, $noteId, $token);
-        
-        if ($favoriteResult['success']) {
+        // Vérifier que l'URL est valide
+        if (!$urlParts || !isset($urlParts['host']) || !isset($urlParts['path'])) {
             $results[] = [
-                'status' => 'success',
-                'message' => "Ajouté aux favoris: $url"
+                'status' => 'error',
+                'message' => "URL invalide: $url"
             ];
-        } else {
-            // Vérifier si c'est une erreur de "déjà ajouté aux favoris"
-            $errorMessage = isset($favoriteResult['data']['error']['message']) 
-                ? $favoriteResult['data']['error']['message'] 
-                : $favoriteResult['message'];
-            
-            if (strpos($errorMessage, 'already') !== false) {
-                $results[] = [
-                    'status' => 'info',
-                    'message' => "Déjà dans vos favoris: $url"
-                ];
+            continue;
+        }
+        
+        // Ajouter un log pour déboguer
+        error_log("Recherche de l'URL: " . $url . " sur l'instance: " . $misskey_instance);
+        
+        // Rechercher la note sur Misskey à partir de l'URL
+        $searchResult = search_federated_note($misskey_instance, $url, $token);
+        
+        // Vérifier si la recherche a réussi ET si les données contiennent un ID valide
+        if ($searchResult['success'] && isset($searchResult['data']) && !empty($searchResult['data'])) {
+            // Vérifier et extraire l'ID de manière sécurisée
+            if (isset($searchResult['data']['id']) && !empty($searchResult['data']['id'])) {
+                $noteId = $searchResult['data']['id'];
+                
+                // Tenter d'ajouter la note aux favoris
+                $favoriteResult = add_to_favorites($misskey_instance, $noteId, $token);
+                
+                if ($favoriteResult['success']) {
+                    $results[] = [
+                        'status' => 'success',
+                        'message' => "Ajouté aux favoris: $url"
+                    ];
+                } else {
+                    // Vérifier si c'est une erreur de "déjà ajouté aux favoris"
+                    $errorMessage = isset($favoriteResult['data']['error']['message']) 
+                        ? $favoriteResult['data']['error']['message'] 
+                        : (isset($favoriteResult['message']) ? $favoriteResult['message'] : 'Erreur inconnue');
+                    
+                    if (strpos($errorMessage, 'already') !== false) {
+                        $results[] = [
+                            'status' => 'info',
+                            'message' => "Déjà dans vos favoris: $url"
+                        ];
+                    } else {
+                        $results[] = [
+                            'status' => 'error',
+                            'message' => "Erreur lors de l'ajout aux favoris: $errorMessage"
+                        ];
+                    }
+                }
             } else {
+                // L'ID est manquant ou vide dans la réponse
+                $dataKeys = is_array($searchResult['data']) ? array_keys($searchResult['data']) : ['non_array'];
                 $results[] = [
                     'status' => 'error',
-                    'message' => "Erreur lors de l'ajout aux favoris: $errorMessage"
+                    'message' => "Note trouvée mais sans ID valide: $url. Clés disponibles: " . implode(', ', $dataKeys)
                 ];
+                
+                // Log pour déboguer
+                error_log("Structure de données reçue: " . json_encode($searchResult['data']));
+            }
+        } else {
+            // Note non trouvée ou erreur de recherche
+            $errorMessage = isset($searchResult['message']) ? $searchResult['message'] : "Publication introuvable";
+            
+            $results[] = [
+                'status' => 'error',
+                'message' => "Publication non trouvée sur le réseau fédéré: $url ($errorMessage)"
+            ];
+            
+            // Ajouter des infos de debug
+            if (isset($searchResult['data']) && is_array($searchResult['data'])) {
+                error_log("Données reçues pour URL $url: " . json_encode($searchResult['data']));
             }
         }
-    } else {
-        // Note non trouvée
-        $errorMessage = isset($searchResult['message']) ? $searchResult['message'] : "Publication introuvable";
         
-        $results[] = [
-            'status' => 'error',
-            'message' => "Publication non trouvée sur le réseau fédéré: $url ($errorMessage)"
-        ];
+        // Pause pour éviter le rate limiting
+        usleep($config['delay_between_requests'] * 1000);
     }
-    
-    // Pause pour éviter le rate limiting
-    usleep($config['delay_between_requests'] * 1000);
-}
 
-// Renvoyer les résultats
-echo json_encode([
-    'success' => true,
-    'results' => $results,
-    'progress' => [
-        'current' => $currentIndex + count($batch),
-        'total' => $totalItems,
-        'percentage' => round((($currentIndex + count($batch)) / $totalItems) * 100, 2)
-    ]
-]);
\ No newline at end of file
+    // Renvoyer les résultats
+    echo json_encode([
+        'success' => true,
+        'results' => $results,
+        'progress' => [
+            'current' => $currentIndex + count($batch),
+            'total' => $totalItems,
+            'percentage' => round((($currentIndex + count($batch)) / $totalItems) * 100, 2)
+        ]
+    ]);
+
+} catch (Exception $e) {
+    // Capturer toutes les exceptions et renvoyer un message d'erreur formaté en JSON
+    echo json_encode([
+        'success' => false,
+        'message' => 'Exception: ' . $e->getMessage(),
+        'file' => $e->getFile(),
+        'line' => $e->getLine()
+    ]);
+}
\ No newline at end of file
diff --git a/test-url.php b/test-url.php
deleted file mode 100644
index c881127..0000000
--- a/test-url.php
+++ /dev/null
@@ -1,393 +0,0 @@
-<?php
-/**
- * FavMasToKey - Test d'URL
- * Ce script permet de tester manuellement une URL pour voir comment Misskey la traite
- */
-
-// Définir la constante pour inclure les fichiers
-define('FAVMASTOKEY', true);
-
-// Inclure les fichiers requis
-require_once 'includes/config.php';
-require_once 'includes/functions.php';
-
-// Initialiser les variables
-$url = '';
-$test_results = [];
-$detailed_results = [];
-$misskey_instance = isset($_SESSION['misskey_instance']) ? $_SESSION['misskey_instance'] : '';
-$token = isset($_SESSION['misskey_token']) ? $_SESSION['misskey_token'] : '';
-$connected = !empty($misskey_instance) && !empty($token);
-
-// Si non connecté, permettre de saisir les informations d'authentification
-if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'connect') {
-    if (isset($_POST['misskey_instance']) && isset($_POST['misskey_token'])) {
-        $misskey_instance = trim($_POST['misskey_instance']);
-        $token = trim($_POST['misskey_token']);
-        
-        // Valider le format de l'instance
-        $misskey_instance = preg_replace('/^https?:\/\//', '', $misskey_instance);
-        $misskey_instance = rtrim($misskey_instance, '/');
-        
-        if (!empty($misskey_instance) && !empty($token)) {
-            // Vérifier la validité du token en effectuant une requête test
-            $validate_result = validate_misskey_token($misskey_instance, $token);
-            
-            if ($validate_result['success']) {
-                // Connecté avec succès
-                $connected = true;
-                
-                // Stockage temporaire pour cette session uniquement
-                $_SESSION['misskey_token_temp'] = $token;
-                $_SESSION['misskey_instance_temp'] = $misskey_instance;
-                
-                $success_message = "Connecté temporairement à {$misskey_instance} pour les tests.";
-            } else {
-                $error_message = "Impossible de se connecter à l'instance avec ce token.";
-            }
-        } else {
-            $error_message = "Veuillez renseigner à la fois l'instance et le token.";
-        }
-    }
-}
-
-// Récupérer les valeurs temporaires si disponibles
-if (!$connected && isset($_SESSION['misskey_token_temp']) && isset($_SESSION['misskey_instance_temp'])) {
-    $token = $_SESSION['misskey_token_temp'];
-    $misskey_instance = $_SESSION['misskey_instance_temp'];
-    $connected = true;
-}
-
-// Traiter le test d'URL
-if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'test' && $connected) {
-    if (isset($_POST['url'])) {
-        $url = trim($_POST['url']);
-        
-        if (!empty($url)) {
-            // Méthode 1: search-by-url
-            $test_results[] = [
-                'method' => 'search-by-url',
-                'endpoint' => '/api/notes/search-by-url',
-                'result' => misskey_api_request($misskey_instance, '/api/notes/search-by-url', ['url' => $url], $token)
-            ];
-            
-            // Méthode 2: ap/show
-            $test_results[] = [
-                'method' => 'ap/show',
-                'endpoint' => '/api/ap/show',
-                'result' => misskey_api_request($misskey_instance, '/api/ap/show', ['uri' => $url], $token)
-            ];
-            
-            // Méthode 3: Extraction et recherche par ID distant
-            $urlParts = parse_url($url);
-            $pathParts = isset($urlParts['path']) ? explode('/', trim($urlParts['path'], '/')) : [];
-            
-            if (count($pathParts) >= 4 && $pathParts[count($pathParts) - 2] === 'statuses') {
-                $statusId = end($pathParts);
-                $username = $pathParts[count($pathParts) - 3];
-                $acctDomain = isset($urlParts['host']) ? $urlParts['host'] : '';
-                
-                if ($statusId && $username && $acctDomain) {
-                    $remoteId = "https://{$acctDomain}/users/{$username}/statuses/{$statusId}";
-                    
-                    $test_results[] = [
-                        'method' => 'notes/show (uri)',
-                        'endpoint' => '/api/notes/show',
-                        'params' => ['uri' => $remoteId],
-                        'result' => misskey_api_request($misskey_instance, '/api/notes/show', ['uri' => $remoteId], $token)
-                    ];
-                }
-            }
-            
-            // Méthode 4: Forcer la fédération
-            if (curl_init()) {
-                $ch = curl_init($url);
-                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-                curl_setopt($ch, CURLOPT_HEADER, false);
-                curl_setopt($ch, CURLOPT_HTTPHEADER, [
-                    'Accept: application/activity+json'
-                ]);
-                curl_setopt($ch, CURLOPT_TIMEOUT, 5);
-                $response = curl_exec($ch);
-                $info = curl_getinfo($ch);
-                curl_close($ch);
-                
-                $detailed_results['direct_request'] = [
-                    'url' => $url,
-                    'http_code' => $info['http_code'],
-                    'content_type' => $info['content_type'],
-                    'response_size' => strlen($response),
-                    'response_preview' => substr($response, 0, 500) . (strlen($response) > 500 ? '...' : '')
-                ];
-                
-                // Attendre un moment pour que l'instance ait le temps de fédérer
-                sleep(2);
-                
-                // Réessayer avec search-by-url après avoir forcé la fédération
-                $test_results[] = [
-                    'method' => 'search-by-url (après tentative de fédération)',
-                    'endpoint' => '/api/notes/search-by-url',
-                    'result' => misskey_api_request($misskey_instance, '/api/notes/search-by-url', ['url' => $url], $token)
-                ];
-            }
-            
-            // Essayer la recherche par contenu
-            // Cette méthode est moins précise mais peut aider dans certains cas
-            if (curl_init()) {
-                $ch = curl_init($url);
-                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-                curl_setopt($ch, CURLOPT_HEADER, false);
-                curl_setopt($ch, CURLOPT_TIMEOUT, 10);
-                $html = curl_exec($ch);
-                curl_close($ch);
-                
-                // Extraction simple du contenu (très basique)
-                $content = '';
-                if (preg_match('/<article[^>]*>(.*?)<\/article>/is', $html, $matches)) {
-                    $content = strip_tags($matches[1]);
-                    $content = preg_replace('/\s+/', ' ', $content);
-                    $content = trim($content);
-                    
-                    if (strlen($content) > 5) {
-                        $detailed_results['content_search'] = [
-                            'extracted_content' => substr($content, 0, 200) . (strlen($content) > 200 ? '...' : ''),
-                            'content_length' => strlen($content)
-                        ];
-                        
-                        // Rechercher par les premiers mots du contenu
-                        $searchWords = implode(' ', array_slice(explode(' ', $content), 0, 10));
-                        
-                        $test_results[] = [
-                            'method' => 'notes/search (par contenu)',
-                            'endpoint' => '/api/notes/search',
-                            'params' => ['query' => $searchWords, 'limit' => 5],
-                            'result' => misskey_api_request($misskey_instance, '/api/notes/search', ['query' => $searchWords, 'limit' => 5], $token)
-                        ];
-                    }
-                }
-            }
-        } else {
-            $error_message = "Veuillez entrer une URL à tester.";
-        }
-    }
-}
-?>
-<!DOCTYPE html>
-<html lang="fr" data-bs-theme="dark">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="theme-color" content="#7e57c2">
-    <link rel="icon" href="images/favicon.svg" type="image/svg+xml">
-    <title>Test d'URL - FavMasToKey</title>
-    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
-    <link rel="stylesheet" href="css/styles.css">
-</head>
-<body>
-    <div class="container py-5">
-        <header class="text-center mb-4">
-            <h1>FavMasToKey - Test d'URL</h1>
-            <p class="lead">Outil de diagnostic pour tester la résolution d'URL Mastodon</p>
-            <p><a href="index.php" class="btn btn-primary">Retour à l'application</a></p>
-        </header>
-        
-        <?php if (isset($error_message)): ?>
-        <div class="alert alert-danger alert-dismissible fade show" role="alert">
-            <?php echo $error_message; ?>
-            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Fermer"></button>
-        </div>
-        <?php endif; ?>
-        
-        <?php if (isset($success_message)): ?>
-        <div class="alert alert-success alert-dismissible fade show" role="alert">
-            <?php echo $success_message; ?>
-            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Fermer"></button>
-        </div>
-        <?php endif; ?>
-        
-        <?php if (!$connected): ?>
-        <div class="card mb-4">
-            <div class="card-header">
-                <h2 class="card-title h5 mb-0">Connexion à Misskey pour les tests</h2>
-            </div>
-            <div class="card-body">
-                <div class="alert alert-info">
-                    <strong>Information:</strong> Vous devez vous connecter à votre instance Misskey pour tester les URLs.
-                    <p class="mb-0">Cette connexion est temporaire et utilisée uniquement pour cette page de test.</p>
-                </div>
-                
-                <form method="post" action="">
-                    <input type="hidden" name="action" value="connect">
-                    <div class="mb-3">
-                        <label for="misskey-instance" class="form-label">Instance Misskey</label>
-                        <input type="text" class="form-control" id="misskey-instance" name="misskey_instance" 
-                               placeholder="misskey.io" required>
-                        <div class="form-text">Entrez le nom de domaine de votre instance Misskey (ex: misskey.io)</div>
-                    </div>
-                    <div class="mb-3">
-                        <label for="misskey-token" class="form-label">Jeton d'accès</label>
-                        <input type="password" class="form-control" id="misskey-token" name="misskey_token" 
-                               placeholder="Votre jeton d'accès Misskey" required>
-                        <div class="form-text">Collez le jeton d'accès généré dans les paramètres de votre compte Misskey</div>
-                    </div>
-                    <button type="submit" class="btn btn-primary">Se connecter pour les tests</button>
-                </form>
-            </div>
-        </div>
-        <?php else: ?>
-        <div class="card mb-4">
-            <div class="card-header d-flex justify-content-between align-items-center">
-                <h2 class="card-title h5 mb-0">Tester une URL</h2>
-                <span class="badge bg-success">Connecté à <?php echo htmlspecialchars($misskey_instance); ?></span>
-            </div>
-            <div class="card-body">
-                <form method="post" action="">
-                    <input type="hidden" name="action" value="test">
-                    <div class="mb-3">
-                        <label for="url" class="form-label">URL d'une publication Mastodon</label>
-                        <input type="url" class="form-control" id="url" name="url" 
-                               placeholder="https://instance.tld/users/username/statuses/123456" 
-                               value="<?php echo htmlspecialchars($url); ?>" required>
-                        <div class="form-text">
-                            Entrez l'URL complète d'une publication Mastodon que vous souhaitez tester.
-                        </div>
-                    </div>
-                    <button type="submit" class="btn btn-primary">Tester cette URL</button>
-                </form>
-            </div>
-        </div>
-        
-        <?php if (!empty($test_results)): ?>
-        <div class="card mb-4">
-            <div class="card-header">
-                <h2 class="card-title h5 mb-0">Résultats de la recherche pour <?php echo htmlspecialchars($url); ?></h2>
-            </div>
-            <div class="card-body">
-                <div class="mb-4">
-                    <h3 class="h6">Structure de l'URL</h3>
-                    <?php
-                    $urlParts = parse_url($url);
-                    $pathParts = isset($urlParts['path']) ? explode('/', trim($urlParts['path'], '/')) : [];
-                    ?>
-                    <pre class="bg-dark text-light p-3"><?php
-                        echo "Schema: " . (isset($urlParts['scheme']) ? $urlParts['scheme'] : 'non défini') . "\n";
-                        echo "Host: " . (isset($urlParts['host']) ? $urlParts['host'] : 'non défini') . "\n";
-                        echo "Path: " . (isset($urlParts['path']) ? $urlParts['path'] : 'non défini') . "\n";
-                        
-                        if (count($pathParts) >= 4 && $pathParts[count($pathParts) - 2] === 'statuses') {
-                            $statusId = end($pathParts);
-                            $username = $pathParts[count($pathParts) - 3];
-                            echo "\nFormat reconnu comme URL Mastodon: Oui\n";
-                            echo "Username: {$username}\n";
-                            echo "Status ID: {$statusId}\n";
-                            echo "ActivityPub URI: https://{$urlParts['host']}/users/{$username}/statuses/{$statusId}\n";
-                        } else {
-                            echo "\nFormat reconnu comme URL Mastodon: Non\n";
-                            echo "Segments du chemin: " . implode(', ', $pathParts);
-                        }
-                    ?></pre>
-                </div>
-                
-                <?php foreach ($test_results as $index => $result): ?>
-                <div class="mb-4">
-                    <h3 class="h6 mb-2">Méthode <?php echo $index + 1; ?>: <?php echo htmlspecialchars($result['method']); ?></h3>
-                    <div class="card bg-dark">
-                        <div class="card-header d-flex justify-content-between align-items-center">
-                            <span>Endpoint: <?php echo htmlspecialchars($result['endpoint']); ?></span>
-                            <span class="badge <?php echo $result['result']['success'] ? 'bg-success' : 'bg-danger'; ?>">
-                                <?php echo $result['result']['success'] ? 'Succès' : 'Échec'; ?>
-                            </span>
-                        </div>
-                        <div class="card-body">
-                            <?php if (isset($result['params'])): ?>
-                            <h4 class="h6">Paramètres</h4>
-                            <pre class="text-light"><?php print_r($result['params']); ?></pre>
-                            <?php endif; ?>
-                            
-                            <h4 class="h6">Code HTTP: <?php echo $result['result']['http_code']; ?></h4>
-                            
-                            <?php if ($result['result']['success'] && isset($result['result']['data']) && !empty($result['result']['data'])): ?>
-                                <h4 class="h6 text-success">Publication trouvée!</h4>
-                                <pre class="text-light"><?php print_r($result['result']['data']); ?></pre>
-                            <?php else: ?>
-                                <h4 class="h6 text-danger">Publication non trouvée</h4>
-                                <pre class="text-light"><?php 
-                                    if (isset($result['result']['message'])) {
-                                        echo "Message: " . print_r($result['result']['message'], true);
-                                    }
-                                    if (isset($result['result']['data'])) {
-                                        echo "\nDonnées: " . print_r($result['result']['data'], true);
-                                    }
-                                ?></pre>
-                            <?php endif; ?>
-                        </div>
-                    </div>
-                </div>
-                <?php endforeach; ?>
-                
-                <?php if (!empty($detailed_results)): ?>
-                <div class="mb-4">
-                    <h3 class="h6">Détails supplémentaires</h3>
-                    <pre class="bg-dark text-light p-3"><?php print_r($detailed_results); ?></pre>
-                </div>
-                <?php endif; ?>
-                
-                <div class="mt-4">
-                    <h3 class="h6">Recommandations</h3>
-                    <ul>
-                        <?php
-                        $successFound = false;
-                        $bestMethod = '';
-                        
-                        foreach ($test_results as $result) {
-                            if ($result['result']['success'] && isset($result['result']['data']) && !empty($result['result']['data'])) {
-                                $successFound = true;
-                                $bestMethod = $result['method'];
-                                break;
-                            }
-                        }
-                        
-                        if ($successFound):
-                        ?>
-                            <li class="text-success">
-                                <strong>Bonne nouvelle!</strong> Publication trouvée avec la méthode "<?php echo htmlspecialchars($bestMethod); ?>".
-                                <p class="mt-2">Vous devriez modifier la fonction <code>search_federated_note</code> pour utiliser cette méthode en priorité.</p>
-                                <div class="alert alert-info">
-                                    <p class="mb-1"><strong>Suggestion pour la fonction search_federated_note:</strong></p>
-                                    <pre class="text-dark mb-0">
-function search_federated_note($instance, $url, $token) {
-    // Pour cette publication spécifique, utiliser la méthode qui fonctionne
-    if ($url === "<?php echo htmlspecialchars($url); ?>") {
-        return misskey_api_request($instance, "<?php echo $result['endpoint']; ?>", 
-            <?php echo isset($result['params']) 
-                ? var_export($result['params'], true) 
-                : "['url' => \$url]"; ?>, $token);
-    }
-    
-    // Pour les autres publications, essayer les différentes méthodes...
-    // [reste du code actuel]
-}</pre>
-                                </div>
-                            </li>
-                        <?php else: ?>
-                            <li class="text-warning">
-                                <strong>Publication non trouvée</strong> avec aucune des méthodes testées. Voici quelques suggestions:
-                                <ul class="mt-2">
-                                    <li>Vérifiez que la publication existe toujours et est publique</li>
-                                    <li>Assurez-vous que votre instance Misskey peut se fédérer avec l'instance d'origine</li>
-                                    <li>Visitez manuellement l'URL depuis votre instance Misskey pour forcer la fédération</li>
-                                    <li>Si c'est un problème récurrent, ajustez les délais entre les requêtes dans config.php</li>
-                                </ul>
-                            </li>
-                        <?php endif; ?>
-                    </ul>
-                </div>
-            </div>
-        </div>
-        <?php endif; ?>
-        <?php endif; ?>
-    </div>
-
-    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
-</body>
-</html>
\ No newline at end of file