Planificateur de posts, sniper de topics et historique pour Onche.org
// ==UserScript==
// @name Horlonche
// @namespace http://tampermonkey.net/
// @version 14.0
// @description Planificateur de posts, sniper de topics et historique pour Onche.org
// @author Musclor1000
// @match https://onche.org/topic/*
// @match https://onche.org/forum/*
// @match https://onche.org/
// @grant none
// ==/UserScript==
(function () {
'use strict';
var estForum = window.location.pathname.indexOf('/forum/') === 0;
var DELAI_MIN_POSTS = 8000;
var dernierPost = 0;
var postEnCours = false;
var fileAttente = [];
var idCounter = 0;
function sauvegarderFile() {
var data = fileAttente.map(function(item) {
return { id: item.id, mode: item.mode, titre: item.titre, message: item.message, tsEcheance: item.tsEcheance, label: item.label, cibleInfo: item.cibleInfo || null, pageUrl: item.pageUrl || null };
}).filter(function(item) { return item.tsEcheance > Date.now(); });
sessionStorage.setItem('horlonche_file', JSON.stringify(data));
}
function restaurerFile() {
var raw = sessionStorage.getItem('horlonche_file');
if (!raw) return;
try {
var data = JSON.parse(raw);
for (var i = 0; i < data.length; i++) {
var item = data[i];
if (item.tsEcheance > Date.now()) { if (item.id >= idCounter) idCounter = item.id; ajouterFile(item); }
}
} catch(e) {}
}
var vueActive = 'liste';
var modeChoisi = null;
var panel = document.createElement('div');
panel.style.cssText = 'position:fixed;bottom:20px;right:20px;background:#1e2a3a;border:1px solid #4a90d9;border-radius:8px;padding:14px;z-index:99999;width:270px;font-family:sans-serif;font-size:13px;color:#eee;box-shadow:0 4px 15px rgba(0,0,0,0.5)';
panel.innerHTML = ''
+ '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">'
+ '<span style="font-weight:bold;font-size:14px;color:#4a90d9">Horlonche</span>'
+ '<div style="display:flex;gap:4px">'
+ '<button type="button" id="os-btn-sniper" title="Sniper de topic" style="background:none;border:1px solid #e74c3c;color:#e74c3c;border-radius:4px;width:24px;height:24px;cursor:pointer;font-size:13px;line-height:1;padding:0">🎯</button>'
+ '<button type="button" id="os-btn-watchdog" title="Watchdog" style="background:none;border:1px solid #e67e22;color:#e67e22;border-radius:4px;width:24px;height:24px;cursor:pointer;font-size:13px;line-height:1;padding:0">🐕</button>'
+ '<button type="button" id="os-btn-plus" title="Ajouter un post" style="background:none;border:1px solid #4a90d9;color:#4a90d9;border-radius:4px;width:24px;height:24px;cursor:pointer;font-size:16px;line-height:1;padding:0">+</button>'
+ '</div>'
+ '</div>'
+ '<div id="os-vue-liste">'
+ '<div id="os-file-vide" style="color:#aaa;font-size:12px;text-align:center;padding:10px 0">Aucun post programme.<br>Clique sur <b>+</b> pour en ajouter un.</div>'
+ '<div id="os-file-liste"></div>'
+ '<div id="os-cooldown" style="margin-top:6px;padding:5px 8px;background:#1a0000;border-left:3px solid #e74c3c;border-radius:3px;font-size:11px;color:#e74c3c;font-family:monospace">⚠ Delai min entre posts : <b>8s</b> — Cloudflare</div>'
+ '</div>'
+ '<div id="os-vue-form" style="display:none">'
+ '<div id="os-etape1">'
+ '<div style="margin-bottom:8px;color:#aaa;font-size:12px">Que veux-tu faire ?</div>'
+ (estForum
? '<button type="button" class="os-mode-btn" data-mode="nouveau" style="width:100%;padding:7px;margin-bottom:6px;background:#2c3e50;color:#eee;border:1px solid #4a90d9;border-radius:4px;cursor:pointer;text-align:left">📝 Creer un nouveau topic</button>'
: '<button type="button" class="os-mode-btn" data-mode="topic" style="width:100%;padding:7px;margin-bottom:6px;background:#2c3e50;color:#eee;border:1px solid #4a90d9;border-radius:4px;cursor:pointer;text-align:left">💬 Repondre dans le topic</button>'
+ '<button type="button" class="os-mode-btn" data-mode="citation" style="width:100%;padding:7px;margin-bottom:6px;background:#2c3e50;color:#eee;border:1px solid #4a90d9;border-radius:4px;cursor:pointer;text-align:left">↩ Citer / repondre a un message</button>'
)
+ '<button type="button" id="os-btn-annuler-form" style="width:100%;padding:5px;margin-top:4px;background:#2c3e50;color:#aaa;border:1px solid #555;border-radius:4px;cursor:pointer;font-size:12px">← Retour</button>'
+ '</div>'
+ '<div id="os-etape2" style="display:none">'
+ '<div id="os-label-mode" style="margin-bottom:10px;padding:5px 8px;background:#0d1b2a;border-radius:4px;font-size:12px;color:#4a90d9"></div>'
+ '<div id="os-instruction-citation" style="display:none;margin-bottom:10px;padding:6px;background:#2c1a00;border:1px solid #f39c12;border-radius:4px;font-size:11px;color:#f39c12">⚠ Clique sur la fleche du message AVANT de cliquer "Ajouter"</div>'
+ '<div id="os-champ-titre" style="display:none">'
+ '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px">'
+ '<label>Titre du topic</label>'
+ '<label style="font-size:10px;color:#f39c12;cursor:pointer;display:flex;align-items:center;gap:4px"><input type="checkbox" id="os-chk-troll" style="cursor:pointer"> Fantome</label>'
+ '</div>'
+ '<input id="os-titre" type="text" placeholder="Titre..." style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #4a90d9;border-radius:4px;margin-bottom:4px;box-sizing:border-box">'
+ '<div id="os-titre-troll-info" style="display:none;padding:5px 7px;background:#0d1b2a;border-left:3px solid #f39c12;border-radius:3px;font-size:10px;color:#f39c12;margin-bottom:6px">Onche recevra ton emoji seul — slug vide garanti.<br>Laisse vide pour un topic sans titre visible.<br>Ton titre sera poste en 1er message automatiquement.</div>'
+ '</div>'
+ '<div id="os-champ-url-cible" style="margin-bottom:8px">'
+ '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:3px">'
+ '<label style="font-size:12px;color:#aaa">URL cible (optionnel)</label>'
+ '<button type="button" id="os-btn-detecter-url" style="padding:2px 6px;background:none;border:1px solid #4a90d9;color:#4a90d9;border-radius:3px;cursor:pointer;font-size:10px">Auto</button>'
+ '</div>'
+ '<input id="os-url-cible" type="text" placeholder="Laisser vide = page courante" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #2c3e50;border-radius:4px;font-size:11px;box-sizing:border-box;margin-bottom:4px">'
+ '<div id="os-url-info" style="display:none;padding:5px 7px;background:#0d1b2a;border-left:3px solid #f39c12;border-radius:3px;font-size:10px;color:#f39c12"></div>'
+ '</div>'
+ '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px">'
+ '<label>Heure (HH:MM:SS)</label>'
+ '<label style="font-size:11px;color:#aaa;cursor:pointer;display:flex;align-items:center;gap:4px"><input type="checkbox" id="os-chk-jour" style="cursor:pointer"> Jour</label>'
+ '</div>'
+ '<input id="os-heure" type="time" step="1" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #4a90d9;border-radius:4px;margin-bottom:6px;box-sizing:border-box">'
+ '<div id="os-champ-jour" style="display:none;margin-bottom:6px"><input id="os-jour" type="date" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #4a90d9;border-radius:4px;box-sizing:border-box"></div>'
+ '<label style="display:block;margin-bottom:4px">Message</label>'
+ '<textarea id="os-message" rows="3" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #4a90d9;border-radius:4px;margin-bottom:6px;box-sizing:border-box;resize:vertical"></textarea>'
+ '<button type="button" id="os-btn-preview" style="width:100%;padding:5px;background:#2c3e50;color:#aaa;border:1px solid #4a90d9;border-radius:4px;cursor:pointer;font-size:12px;margin-bottom:8px">👁 Previsualiser</button>'
+ '<button type="button" id="os-btn-start" style="width:100%;padding:7px;background:#4a90d9;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px;margin-bottom:6px">Ajouter a la file</button>'
+ '<button type="button" id="os-btn-back" style="width:100%;padding:5px;background:#2c3e50;color:#aaa;border:1px solid #4a90d9;border-radius:4px;cursor:pointer;font-size:12px">← Retour</button>'
+ '</div>'
+ '</div>'
+ '<div id="os-vue-sniper" style="display:none">'
+ '<div style="margin-bottom:8px;color:#e74c3c;font-weight:bold;font-size:13px">🎯 Sniper de topic</div>'
+ '<label style="display:block;margin-bottom:4px;font-size:12px">Forums a scanner</label>'
+ '<div id="os-sniper-forums-liste" style="margin-bottom:4px"></div>'
+ '<div style="display:flex;gap:4px;margin-bottom:8px">'
+ '<input id="os-sniper-url-input" type="text" placeholder="https://onche.org/forum/..." style="flex:1;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #e74c3c;border-radius:4px;font-size:11px;box-sizing:border-box">'
+ '<button type="button" id="os-sniper-url-add" style="padding:5px 8px;background:#e74c3c;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px">+</button>'
+ '</div>'
+ '<label style="display:block;margin-bottom:4px;font-size:12px">Mots cles (separes par virgules)</label>'
+ '<input id="os-sniper-mot" type="text" placeholder="ex: crypto, bonjour..." style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #e74c3c;border-radius:4px;margin-bottom:8px;box-sizing:border-box">'
+ '<label style="display:block;margin-bottom:4px;font-size:12px">Message a poster</label>'
+ '<textarea id="os-sniper-message" rows="3" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #e74c3c;border-radius:4px;margin-bottom:8px;box-sizing:border-box;resize:vertical"></textarea>'
+ '<label style="display:block;margin-bottom:4px;font-size:12px">Intervalle de scan (secondes)</label>'
+ '<input id="os-sniper-intervalle" type="number" value="10" min="5" max="60" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #e74c3c;border-radius:4px;margin-bottom:8px;box-sizing:border-box">'
+ '<button type="button" id="os-sniper-start" style="width:100%;padding:7px;background:#e74c3c;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px;margin-bottom:6px">Activer le sniper</button>'
+ '<button type="button" id="os-sniper-stop" style="display:none;width:100%;padding:7px;background:#c0392b;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px;margin-bottom:6px">Desactiver</button>'
+ '<div style="display:flex;gap:4px">'
+ '<button type="button" id="os-sniper-retour" style="flex:1;padding:5px;background:#2c3e50;color:#aaa;border:1px solid #555;border-radius:4px;cursor:pointer;font-size:12px">← Retour</button>'
+ '<button type="button" id="os-sniper-historique-btn" style="padding:5px 8px;background:#2c3e50;color:#f39c12;border:1px solid #f39c12;border-radius:4px;cursor:pointer;font-size:12px">📋</button>'
+ '</div>'
+ '<div id="os-sniper-status" style="margin-top:8px;font-size:11px;color:#aaa;text-align:center"></div>'
+ '<div id="os-sniper-log" style="margin-top:6px;max-height:80px;overflow-y:auto;font-size:10px;color:#666"></div>'
+ '</div>'
+ '<div id="os-vue-watchdog" style="display:none">'
+ '<div id="os-wd-vue-config">'
+ '<div style="margin-bottom:8px;color:#e67e22;font-weight:bold;font-size:13px">🐕 Watchdog</div>'
+ '<label style="display:block;margin-bottom:4px;font-size:12px">Pseudos a surveiller</label>'
+ '<div id="os-wd-pseudos-liste" style="margin-bottom:4px"></div>'
+ '<div style="display:flex;gap:4px;margin-bottom:8px">'
+ '<input id="os-wd-pseudo-input" type="text" placeholder="Pseudo Onche..." style="flex:1;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #e67e22;border-radius:4px;font-size:11px;box-sizing:border-box">'
+ '<button type="button" id="os-wd-pseudo-add" style="padding:5px 8px;background:#e67e22;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px">+</button>'
+ '</div>'
+ '<label style="display:block;margin-bottom:4px;font-size:12px">Forums a surveiller</label>'
+ '<div id="os-wd-forums-liste" style="margin-bottom:4px"></div>'
+ '<div style="display:flex;gap:4px;margin-bottom:8px">'
+ '<input id="os-wd-forum-input" type="text" placeholder="https://onche.org/forum/..." style="flex:1;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #e67e22;border-radius:4px;font-size:11px;box-sizing:border-box">'
+ '<button type="button" id="os-wd-forum-add" style="padding:5px 8px;background:#e67e22;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px">+</button>'
+ '</div>'
+ '<label style="display:block;margin-bottom:4px;font-size:12px">Message auto (optionnel)</label>'
+ '<textarea id="os-wd-message" rows="2" placeholder="Laisser vide = pas de reponse auto" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #e67e22;border-radius:4px;margin-bottom:8px;box-sizing:border-box;resize:vertical;font-size:12px"></textarea>'
+ '<label style="display:block;margin-bottom:4px;font-size:12px">Intervalle de scan (secondes)</label>'
+ '<input id="os-wd-intervalle" type="number" value="15" min="5" max="120" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #e67e22;border-radius:4px;margin-bottom:8px;box-sizing:border-box">'
+ '<div style="display:flex;gap:4px;margin-bottom:6px">'
+ '<button type="button" id="os-wd-start" style="flex:1;padding:7px;background:#e67e22;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:12px">▶ Activer</button>'
+ '<button type="button" id="os-wd-stop" style="display:none;flex:1;padding:7px;background:#c0392b;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:12px">⏹ Stop</button>'
+ '<button type="button" id="os-wd-scan-now" style="flex:1;padding:7px;background:#2c3e50;color:#e67e22;border:1px solid #e67e22;border-radius:4px;cursor:pointer;font-size:12px">🔍 Scan</button>'
+ '</div>'
+ '<div id="os-wd-status" style="margin-bottom:4px;font-size:11px;color:#aaa;text-align:center"></div>'
+ '<div style="display:flex;gap:4px;margin-top:6px">'
+ '<button type="button" id="os-wd-retour" style="flex:1;padding:5px;background:#2c3e50;color:#aaa;border:1px solid #555;border-radius:4px;cursor:pointer;font-size:12px">← Retour</button>'
+ '<button type="button" id="os-wd-voir-topics" style="flex:1;padding:5px;background:#2c3e50;color:#e67e22;border:1px solid #e67e22;border-radius:4px;cursor:pointer;font-size:12px">📋 Topics</button>'
+ '<button type="button" id="os-wd-historique-btn" style="padding:5px 8px;background:#2c3e50;color:#f39c12;border:1px solid #f39c12;border-radius:4px;cursor:pointer;font-size:12px">📋</button>'
+ '</div>'
+ '</div>'
+ '<div id="os-wd-vue-topics" style="display:none">'
+ '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">'
+ '<span style="font-weight:bold;font-size:13px;color:#e67e22">📋 Topics detectes</span>'
+ '<button type="button" id="os-wd-topics-retour" style="padding:3px 8px;background:#2c3e50;color:#aaa;border:1px solid #555;border-radius:3px;cursor:pointer;font-size:11px">← Retour</button>'
+ '</div>'
+ '<div id="os-wd-topics-liste" style="max-height:220px;overflow-y:auto;margin-bottom:8px;background:#0d1b2a;border-radius:4px;padding:4px">'
+ '<span style="color:#666;font-size:10px">Lancer le scan pour voir les topics...</span>'
+ '</div>'
+ '<div id="os-wd-log" style="max-height:50px;overflow-y:auto;font-size:10px;color:#666;margin-bottom:6px"></div>'
+ '<div style="display:flex;gap:4px">'
+ '<button type="button" id="os-wd-poster-selection" style="flex:1;padding:6px;background:#e67e22;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:11px">📤 Selection</button>'
+ '<button type="button" id="os-wd-poster-tous" style="flex:1;padding:6px;background:#c0392b;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:11px">📤 Tous</button>'
+ '</div>'
+ '</div>'
+ '</div>'
+ '<div id="os-vue-wd-historique" style="display:none">'
+ '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">'
+ '<span style="font-weight:bold;font-size:13px;color:#e67e22">🐕 Historique Watchdog</span>'
+ '<button type="button" id="os-wd-hist-clear" style="padding:3px 8px;background:none;border:1px solid #c0392b;color:#c0392b;border-radius:3px;cursor:pointer;font-size:11px">Vider</button>'
+ '</div>'
+ '<div id="os-wd-hist-liste" style="max-height:300px;overflow-y:auto"></div>'
+ '<button type="button" id="os-wd-hist-retour" style="width:100%;padding:5px;margin-top:8px;background:#2c3e50;color:#aaa;border:1px solid #555;border-radius:4px;cursor:pointer;font-size:12px">← Retour</button>'
+ '</div>'
+ '<div id="os-vue-historique" style="display:none">'
+ '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">'
+ '<span style="font-weight:bold;font-size:13px;color:#f39c12">📋 Historique</span>'
+ '<button type="button" id="os-historique-clear" style="padding:3px 8px;background:none;border:1px solid #c0392b;color:#c0392b;border-radius:3px;cursor:pointer;font-size:11px">Vider</button>'
+ '</div>'
+ '<div style="display:flex;gap:4px;margin-bottom:8px">'
+ '<button type="button" id="os-hist-tab-tracking" style="flex:1;padding:5px;background:#4a90d9;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:11px">Tracking (0)</button>'
+ '<button type="button" id="os-hist-tab-posting" style="flex:1;padding:5px;background:#2c3e50;color:#aaa;border:1px solid #2ecc71;border-radius:4px;cursor:pointer;font-size:11px">Posting (0)</button>'
+ '</div>'
+ '<div id="os-historique-liste" style="max-height:260px;overflow-y:auto"></div>'
+ '<button type="button" id="os-historique-retour" style="width:100%;padding:5px;margin-top:8px;background:#2c3e50;color:#aaa;border:1px solid #555;border-radius:4px;cursor:pointer;font-size:12px">← Retour</button>'
+ '</div>'
+ '</div>';
document.body.appendChild(panel);
restaurerFile();
function normaliserUrlTopic(url) {
if (!url) return window.location.href.split('#')[0];
if (url.indexOf('http') !== 0) url = 'https://onche.org' + url;
var ancre = '';
var urlSansAncre = url;
var hashIdx = url.indexOf('#');
if (hashIdx !== -1) {
var ancreVal = url.substring(hashIdx + 1);
urlSansAncre = url.substring(0, hashIdx);
if (/^message_\d+$/.test(ancreVal)) ancre = '#' + ancreVal;
else if (ancreVal.indexOf('http') !== -1 || ancreVal.length > 50) ancre = '';
else ancre = '#' + ancreVal;
}
var mId = urlSansAncre.match(/onche\.org\/topic\/(\d+)/);
if (!mId) return url;
var topicId = mId[1];
var reste = urlSansAncre.split('/topic/' + topicId)[1] || '';
var parties = reste.split('/');
var slug = parties.length > 1 ? parties[1] : '';
var page = parties.length > 2 ? parties[2] : '';
var slugVisible = slug;
try { slugVisible = decodeURIComponent(slug); } catch(e) { return 'https://onche.org/topic/' + topicId + '/' + ancre; }
slugVisible = slugVisible.replace(/[\u0000-\u001F\u007F-\u009F\u200B-\u200D\uFEFF\u00AD\u00A0\u2028\u2029]/g, '').trim();
if (!slugVisible) return 'https://onche.org/topic/' + topicId + '/' + ancre;
if (slugVisible.length > 120) slugVisible = slugVisible.substring(0, 120);
var pageNum = 1;
if (page) { pageNum = parseInt(page) || 1; if (pageNum < 1) pageNum = 1; if (pageNum > 9999) pageNum = 1; }
return 'https://onche.org/topic/' + topicId + '/' + slugVisible + '/' + pageNum + ancre;
}
setTimeout(function() {
if (window.location.href.indexOf('/topic/') === -1) return;
try {
var urlCorrigee = normaliserUrlTopic(window.location.href);
if (urlCorrigee !== window.location.href && urlCorrigee !== window.location.href.split('#')[0]) window.location.replace(urlCorrigee);
} catch(e) {}
function corrigerLiens() {
document.querySelectorAll('a[href*="/topic/"]').forEach(function(a) {
var href = a.getAttribute('href');
if (!href) return;
var abs = href.indexOf('http') === 0 ? href : 'https://onche.org' + href;
var norm = normaliserUrlTopic(abs);
if (norm !== abs) { a.setAttribute('href', norm); a.title = 'Lien corrige : ' + norm; }
});
}
corrigerLiens();
var debounce = null;
new MutationObserver(function() { if (debounce) clearTimeout(debounce); debounce = setTimeout(corrigerLiens, 300); }).observe(document.body, { childList: true, subtree: false });
}, 100);
function detecterInfosTopic() {
var url = window.location.href;
var info = document.getElementById('os-url-info');
var inp = document.getElementById('os-url-cible');
if (!info || !inp) return;
var m = url.match(/onche\.org\/topic\/(\d+)\/([^\/]*)\/?(\d*)/);
if (!m) { info.style.display = 'none'; return; }
var topicId = m[1], slug = m[2] || '', page = m[3] || '1';
var messages = [];
if (!slug || slug.length === 0) {
messages.push('⚠ Troll #1 : slug vide !');
inp.value = 'https://onche.org/topic/' + topicId + '/';
var pc = parseInt(page) || 1;
messages.push('Page ' + pc + ' — suivante : https://onche.org/topic/' + topicId + '//' + (pc + 1));
}
if (messages.length > 0) {
info.style.display = 'block'; info.style.borderLeftColor = '#f39c12'; info.style.color = '#f39c12';
info.innerHTML = messages.join('<br>');
} else {
var pn = parseInt(page) || 1;
info.style.display = 'block'; info.style.borderLeftColor = '#2ecc71'; info.style.color = '#2ecc71';
info.innerHTML = '✓ Normal — page ' + pn + ' — suivante : https://onche.org/topic/' + topicId + '/' + slug + '/' + (pn+1);
}
}
function getUrlCible() {
var inp = document.getElementById('os-url-cible');
if (inp && inp.value.trim()) {
var url = inp.value.trim();
if (url.indexOf('https://onche.org/') !== 0) { inp.style.borderColor = '#e74c3c'; return window.location.href.split('#')[0]; }
inp.style.borderColor = '#2ecc71';
return url;
}
return window.location.href.split('#')[0];
}
setTimeout(function() { var btnAuto = document.getElementById('os-btn-detecter-url'); if (btnAuto) btnAuto.addEventListener('click', detecterInfosTopic); }, 350);
var sniperTimer = null, sniperActif = false, sniperTopicsVus = {};
try { var raw = sessionStorage.getItem('horlonche_sniper_vus'); if (raw) sniperTopicsVus = JSON.parse(raw); } catch(e) {}
function sauvegarderTopicsVus() { try { sessionStorage.setItem('horlonche_sniper_vus', JSON.stringify(sniperTopicsVus)); } catch(e) {} }
var sniperForums = ['https://onche.org/forum/1/blabla-general'];
function afficherForums() {
var liste = document.getElementById('os-sniper-forums-liste');
if (!liste) return;
liste.innerHTML = '';
sniperForums.forEach(function(url, idx) {
var ligne = document.createElement('div');
ligne.style.cssText = 'display:flex;align-items:center;gap:4px;margin-bottom:4px;background:#0d1b2a;border:1px solid #3a2000;border-radius:4px;padding:3px 6px';
var nom = url.replace('https://onche.org/forum/','').replace(/\/.*/,'');
nom = ({1:'Blabla General',4:'Goulag',7:'Finance',8:'Jeux Video',9:'Autonomie',13:'Videoclub'})[nom] || url.split('/').pop();
ligne.innerHTML = '<span style="flex:1;color:#eee;font-size:11px">' + nom + '</span><button type="button" data-idx="' + idx + '" style="background:none;border:none;color:#c0392b;cursor:pointer;font-size:13px;padding:0 2px">✕</button>';
ligne.querySelector('button').addEventListener('click', function() { sniperForums.splice(parseInt(this.getAttribute('data-idx')),1); afficherForums(); });
liste.appendChild(ligne);
});
}
setTimeout(function() {
afficherForums();
document.getElementById('os-sniper-url-add').addEventListener('click', function() {
var url = document.getElementById('os-sniper-url-input').value.trim();
if (!url) return;
if (url.indexOf('onche.org/forum/') === -1) { alert('URL invalide'); return; }
if (sniperForums.indexOf(url) !== -1) { alert('Forum deja dans la liste'); return; }
sniperForums.push(url); document.getElementById('os-sniper-url-input').value = ''; afficherForums();
});
document.getElementById('os-sniper-url-input').addEventListener('keydown', function(e) { if (e.key==='Enter') document.getElementById('os-sniper-url-add').click(); });
}, 400);
function ajouterHistorique(type, data) {
var today = new Date().toLocaleDateString();
var raw = localStorage.getItem('horlonche_historique_' + today);
var liste = [];
try { if (raw) liste = JSON.parse(raw); } catch(e) {}
liste.unshift(Object.assign({ heure: new Date().toLocaleTimeString(), type: type }, data));
if (liste.length > 500) liste = liste.slice(0, 500);
localStorage.setItem('horlonche_historique_' + today, JSON.stringify(liste));
}
var ongletHistActif = 'tracking';
function chargerEntrees() {
var entrees = [];
for (var d = 0; d < 7; d++) {
var date = new Date(); date.setDate(date.getDate() - d);
var raw = localStorage.getItem('horlonche_historique_' + date.toLocaleDateString());
try { if (raw) { var items = JSON.parse(raw); items.forEach(function(i){i.date=date.toLocaleDateString();}); entrees = entrees.concat(items); } } catch(e) {}
}
return entrees;
}
function afficherHistorique() {
var liste = document.getElementById('os-historique-liste');
if (!liste) return;
liste.innerHTML = '';
var entrees = chargerEntrees();
var filtrees = entrees.filter(function(e) { return ongletHistActif==='tracking' ? e.type==='trouve' : (e.type==='poste'||e.type==='erreur'); });
var nbT = entrees.filter(function(e){return e.type==='trouve';}).length;
var nbP = entrees.filter(function(e){return e.type==='poste'||e.type==='erreur';}).length;
var btnT = document.getElementById('os-hist-tab-tracking');
var btnP = document.getElementById('os-hist-tab-posting');
if (btnT) btnT.textContent = 'Tracking (' + nbT + ')';
if (btnP) btnP.textContent = 'Posting (' + nbP + ')';
if (filtrees.length === 0) { liste.innerHTML = '<div style="color:#aaa;text-align:center;padding:20px;font-size:12px">Aucune entree</div>'; return; }
filtrees.forEach(function(item) {
var ligne = document.createElement('div');
ligne.style.cssText = 'padding:7px 8px;margin-bottom:5px;background:#0d1b2a;border-radius:4px;font-size:11px;' + (item.type==='trouve'?'border-left:3px solid #4a90d9':item.type==='poste'?'border-left:3px solid #2ecc71':'border-left:3px solid #e74c3c');
var html = '<div style="display:flex;justify-content:space-between;margin-bottom:4px"><span style="color:#888">' + item.date + ' ' + item.heure + '</span></div>';
if (item.type==='trouve') {
html += '<div style="color:#4a90d9;font-weight:bold;margin-bottom:3px">' + (item.titre||'(sans titre)') + '</div>';
if (item.auteur) html += '<div style="color:#aaa">Auteur : <span style="color:#eee">' + item.auteur + '</span></div>';
if (item.topicUrl) html += '<a href="' + item.topicUrl + '" target="_blank" style="color:#4a90d9;text-decoration:none;font-size:10px">Voir →</a>';
} else {
html += '<div style="color:#aaa">Topic : <a href="' + (item.topicUrl||'#') + '" target="_blank" style="color:#2ecc71;text-decoration:none">' + (item.topicTitre||'?') + '</a></div>';
if (item.message) html += '<div style="color:#eee;background:#111;padding:4px 6px;border-radius:3px;margin-top:3px">' + item.message.substring(0,100) + '</div>';
}
ligne.innerHTML = html;
liste.appendChild(ligne);
});
}
document.getElementById('os-sniper-historique-btn').addEventListener('click', function() { document.getElementById('os-vue-sniper').style.display='none'; document.getElementById('os-vue-historique').style.display='block'; afficherHistorique(); });
document.getElementById('os-historique-retour').addEventListener('click', function() { document.getElementById('os-vue-historique').style.display='none'; document.getElementById('os-vue-sniper').style.display='block'; });
document.getElementById('os-hist-tab-tracking').addEventListener('click', function() { ongletHistActif='tracking'; this.style.background='#4a90d9'; this.style.color='#fff'; this.style.border='none'; var p=document.getElementById('os-hist-tab-posting'); p.style.background='#2c3e50'; p.style.color='#aaa'; p.style.border='1px solid #2ecc71'; afficherHistorique(); });
document.getElementById('os-hist-tab-posting').addEventListener('click', function() { ongletHistActif='posting'; this.style.background='#2ecc71'; this.style.color='#fff'; this.style.border='none'; var t=document.getElementById('os-hist-tab-tracking'); t.style.background='#2c3e50'; t.style.color='#aaa'; t.style.border='1px solid #4a90d9'; afficherHistorique(); });
document.getElementById('os-historique-clear').addEventListener('click', function() { if (!confirm("Vider l'historique ?")) return; for (var d=0;d<7;d++){var date=new Date();date.setDate(date.getDate()-d);localStorage.removeItem('horlonche_historique_'+date.toLocaleDateString());} afficherHistorique(); });
function restaurerSniper() {
var raw = sessionStorage.getItem('horlonche_sniper_config');
if (!raw) return;
try {
var config = JSON.parse(raw);
if (!config.actif) return;
document.getElementById('os-sniper-mot').value = config.mot;
document.getElementById('os-sniper-message').value = config.message;
document.getElementById('os-sniper-intervalle').value = config.intervalle;
if (config.forums && Array.isArray(config.forums)) { sniperForums = config.forums; afficherForums(); }
document.getElementById('os-sniper-start').click();
} catch(e) {}
}
setTimeout(restaurerSniper, 300);
document.getElementById('os-btn-sniper').addEventListener('click', function() { document.getElementById('os-vue-liste').style.display='none'; document.getElementById('os-vue-form').style.display='none'; document.getElementById('os-vue-sniper').style.display='block'; });
document.getElementById('os-sniper-retour').addEventListener('click', function() { document.getElementById('os-vue-sniper').style.display='none'; document.getElementById('os-vue-liste').style.display='block'; });
document.getElementById('os-sniper-start').addEventListener('click', function() {
var mot = document.getElementById('os-sniper-mot').value.trim().toLowerCase().replace(/\s*,\s*/g,',');
var message = document.getElementById('os-sniper-message').value.trim();
var intervalle = parseInt(document.getElementById('os-sniper-intervalle').value) || 10;
var scanUrl = sniperForums.length > 0 ? sniperForums : ['https://onche.org/forum/1/blabla-general'];
if (!mot) { alert('Ecris un mot cle !'); return; }
sniperActif = true;
document.getElementById('os-sniper-start').style.display = 'none';
document.getElementById('os-sniper-stop').style.display = 'block';
setSniperStatus('Actif — scan toutes les ' + intervalle + 's', '#2ecc71');
sessionStorage.setItem('horlonche_sniper_config', JSON.stringify({actif:true,mot:mot,message:message,intervalle:intervalle,scanUrl:scanUrl,forums:sniperForums}));
var forumsAScan = Array.isArray(scanUrl) ? scanUrl : [scanUrl];
forumsAScan.forEach(function(url) { scannerTopics(mot, message, url); });
sniperTimer = setInterval(function() { forumsAScan.forEach(function(url) { scannerTopics(mot,message,url); }); }, intervalle*1000);
});
document.getElementById('os-sniper-stop').addEventListener('click', function() {
if (sniperTimer) clearInterval(sniperTimer);
sniperTimer = null; sniperActif = false;
document.getElementById('os-sniper-start').style.display = 'block';
document.getElementById('os-sniper-stop').style.display = 'none';
setSniperStatus('Inactif', '#aaa');
sessionStorage.removeItem('horlonche_sniper_config');
});
function scannerTopics(mot, message, scanUrl) {
fetch(scanUrl||'https://onche.org/forum/1/blabla-general', {credentials:'include'}).then(function(r){return r.text();}).then(function(html) {
var doc = new DOMParser().parseFromString(html,'text/html');
doc.querySelectorAll('a.topic-subject, a[href*="/topic/"]').forEach(function(lien) {
var titre = lien.textContent.trim().toLowerCase();
var href = lien.getAttribute('href');
if (!href || href.indexOf('/topic/')===-1) return;
var matchId = href.match(/\/topic\/(\d+)\//);
if (!matchId) return;
var topicId = matchId[1];
if (sniperTopicsVus[topicId]) return;
var mots = mot.split(',').map(function(m){return m.trim();}).filter(Boolean);
if (!mots.some(function(m){return titre.indexOf(m)!==-1;})) return;
sniperTopicsVus[topicId] = true; sauvegarderTopicsVus();
ajouterLogSniper('🎯 ' + lien.textContent.trim().substring(0,40), 'trouve');
ajouterHistorique('trouve',{titre:lien.textContent.trim(),auteur:'',forum:scanUrl,topicUrl:'https://onche.org'+href});
posterDansTopicSniper(href, message, topicId);
});
setSniperStatus('Actif — dernier scan : ' + new Date().toLocaleTimeString(), '#2ecc71');
}).catch(function() { setSniperStatus('Erreur de scan','#e74c3c'); });
}
function posterDansTopicSniper(topicHref, message, topicId) {
var topicUrl = topicHref.indexOf('https://')===0 ? topicHref : 'https://onche.org' + topicHref.replace(/\/\d+$/,'/1');
fetch(topicUrl,{credentials:'include'}).then(function(r){return r.text();}).then(function(html) {
var match = html.match(/name="token"[^>]*value="([^"]+)"/) || html.match(/value="([^"]+)"[^>]*name="token"/) || html.match(/data-token="([^"]+)"/);
var token = match ? match[1] : '';
if (!token) { ajouterLogSniper('❌ Token introuvable #'+topicId,'erreur'); return; }
var body = new URLSearchParams();
body.append('message',message); body.append('poll_question',''); body.append('poll[]',''); body.append('token',token);
return fetch(topicUrl.split('#')[0]+'#last',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:body.toString(),credentials:'include'});
}).then(function(r) {
if (r&&(r.ok||r.redirected)) { ajouterLogSniper('✅ Poste #'+topicId,'poste'); ajouterHistorique('poste',{topicUrl:topicUrl,topicTitre:'Topic #'+topicId,message:message}); }
else if (r) ajouterLogSniper('❌ Erreur '+r.status+' #'+topicId,'erreur');
}).catch(function() { ajouterLogSniper('❌ Reseau #'+topicId,'erreur'); });
}
function setSniperStatus(t,c) { var el=document.getElementById('os-sniper-status'); if(el){el.textContent=t;el.style.color=c||'#aaa';} }
function ajouterLogSniper(texte, type) {
var log = document.getElementById('os-sniper-log');
if (log) {
var l=document.createElement('div');
l.style.color=type==='poste'?'#2ecc71':type==='erreur'?'#e74c3c':type==='trouve'?'#4a90d9':'#888';
l.textContent=new Date().toLocaleTimeString()+' — '+texte;
log.insertBefore(l,log.firstChild);
while(log.children.length>20) log.removeChild(log.lastChild);
}
}
var messageCibleCapture = null;
document.addEventListener('click', function(e) {
var fleche = e.target.closest('[data-message-quote]');
if (!fleche) return;
var messageEl = fleche.closest('[data-id]');
if (!messageEl) return;
messageCibleCapture = { messageId: messageEl.getAttribute('data-id'), username: messageEl.getAttribute('data-username') || '' };
}, true);
var previewBox = document.createElement('div');
previewBox.style.cssText = 'display:none;position:fixed;bottom:20px;right:310px;background:#1e2a3a;border:1px solid #4a90d9;border-radius:8px;padding:14px;z-index:99998;width:320px;max-height:280px;font-family:sans-serif;font-size:14px;color:#eee;box-shadow:0 4px 15px rgba(0,0,0,0.5);overflow-y:auto;word-break:break-word;white-space:pre-wrap;line-height:1.6';
document.body.appendChild(previewBox);
var previewOuvert = false;
document.getElementById('os-btn-preview').addEventListener('click', function() {
if (!previewOuvert) {
majPreview();
previewBox.style.display = 'block';
this.textContent = '✕ Fermer la previsualisation'; this.style.color = '#4a90d9';
previewOuvert = true;
document.getElementById('os-message').addEventListener('input', majPreview);
var chkSpear = document.getElementById('os-chk-spear');
} else {
previewBox.style.display = 'none';
this.textContent = '👁 Previsualiser'; this.style.color = '#aaa';
previewOuvert = false;
document.getElementById('os-message').removeEventListener('input', majPreview);
}
});
function majPreview() {
var msg = document.getElementById('os-message').value || '';
previewBox.innerHTML = '<div style="color:#eee;font-size:13px;white-space:pre-wrap">' + escHtml(msg || '(message vide)') + '</div>';
}
document.getElementById('os-btn-plus').addEventListener('click', function() { document.getElementById('os-vue-liste').style.display='none'; document.getElementById('os-vue-form').style.display='block'; document.getElementById('os-etape1').style.display='block'; document.getElementById('os-etape2').style.display='none'; vueActive='formulaire'; });
document.getElementById('os-btn-annuler-form').addEventListener('click', retourListe);
document.getElementById('os-btn-back').addEventListener('click', function() { document.getElementById('os-etape2').style.display='none'; document.getElementById('os-etape1').style.display='block'; modeChoisi=null; });
function retourListe() {
document.getElementById('os-vue-form').style.display = 'none';
document.getElementById('os-vue-liste').style.display = 'block';
vueActive = 'liste'; modeChoisi = null;
var btnSp = document.getElementById('os-chk-spear'); if(btnSp) btnSp.style.display='';
if (previewOuvert) document.getElementById('os-btn-preview').click();
}
var modeBtns = panel.querySelectorAll('.os-mode-btn');
for (var i = 0; i < modeBtns.length; i++) {
modeBtns[i].addEventListener('click', function() {
modeChoisi = this.getAttribute('data-mode');
document.getElementById('os-etape1').style.display = 'none';
document.getElementById('os-etape2').style.display = 'block';
try { detecterInfosTopic(); } catch(e) {}
var labels = {'topic':'Repondre dans le topic','citation':'Citer un message','nouveau':'Nouveau topic'};
document.getElementById('os-label-mode').textContent = '→ ' + labels[modeChoisi];
document.getElementById('os-instruction-citation').style.display = (modeChoisi==='citation') ? 'block' : 'none';
document.getElementById('os-champ-titre').style.display = (modeChoisi==='nouveau') ? 'block' : 'none';
var btnSp = document.getElementById('os-chk-spear');
if(btnSp) btnSp.style.display = (modeChoisi==='citation') ? 'none' : '';
});
}
document.getElementById('os-chk-jour').addEventListener('change', function() {
var champ = document.getElementById('os-champ-jour');
if (this.checked) { champ.style.display='block'; var auj=new Date(); document.getElementById('os-jour').value=auj.getFullYear()+'-'+pad(auj.getMonth()+1)+'-'+pad(auj.getDate()); }
else { champ.style.display='none'; document.getElementById('os-jour').value=''; }
});
setTimeout(function() {
var chk = document.getElementById('os-chk-troll');
if (!chk) return;
chk.addEventListener('change', function() {
var info=document.getElementById('os-titre-troll-info'), titre=document.getElementById('os-titre');
if (!info||!titre) return;
if (this.checked) { info.style.display='block'; titre.style.borderColor='#f39c12'; titre.placeholder='Titre visible dans le 1er message...'; }
else { info.style.display='none'; titre.style.borderColor='#4a90d9'; titre.placeholder='Titre...'; }
});
}, 400);
document.getElementById('os-btn-start').addEventListener('click', function() {
var heureVal = document.getElementById('os-heure').value;
var heureVal = document.getElementById('os-heure').value;
var messageVal = document.getElementById('os-message').value;
var titreEl = document.getElementById('os-titre');
var titreVal = titreEl ? titreEl.value.trim() : '';
var jourVal = document.getElementById('os-jour').value;
var modeTroll = document.getElementById('os-chk-troll') && document.getElementById('os-chk-troll').checked;
var vraiTitre = null;
if (!heureVal) { alert('Choisis une heure !'); return; }
if (modeChoisi === 'nouveau' && !titreVal && !modeTroll) { alert('Ecris un titre !'); return; }
if (modeTroll) { vraiTitre=titreVal; if (!titreVal||titreVal.trim()==='') titreVal='\u200B'; }
var parts = heureVal.split(':');
var cible = new Date();
if (jourVal) { var jp=jourVal.split('-'); cible.setFullYear(parseInt(jp[0]),parseInt(jp[1])-1,parseInt(jp[2])); }
cible.setHours(parseInt(parts[0]),parseInt(parts[1]),parseInt(parts[2]||0),0);
if (!jourVal && cible.getTime() <= Date.now()) cible.setDate(cible.getDate()+1);
var labels = {'topic':'💬','citation':'↩','nouveau':'📝'};
var labelJour = jourVal ? jourVal.split('-').reverse().join('/')+' ' : '';
var labelAffiche = labels[modeChoisi]+' '+labelJour+heureVal;
if (modeChoisi==='nouveau' && titreVal) labelAffiche += ' — '+titreVal.substring(0,20);
if (modeChoisi==='citation' && messageCibleCapture) labelAffiche += ' (@'+(messageCibleCapture.username||'?')+')';
var cibleInfoPourCetItem = (modeChoisi==='citation') ? messageCibleCapture : null;
messageCibleCapture = null;
if (modeChoisi==='citation' && !cibleInfoPourCetItem) { alert('Aucun message cible !'); return; }
ajouterFile({ id:++idCounter, mode:modeChoisi, titre:titreVal, vraiTitre:vraiTitre||null, message:messageVal, tsEcheance:cible.getTime(), label:labelAffiche, heure:heureVal, pageUrl:window.location.href.split('#')[0], cibleInfo:cibleInfoPourCetItem });
document.getElementById('os-heure').value = '';
document.getElementById('os-message').value = '';
if (titreEl) titreEl.value = '';
document.getElementById('os-chk-jour').checked = false;
document.getElementById('os-champ-jour').style.display = 'none';
document.getElementById('os-jour').value = '';
retourListe();
});
function ajouterFile(item) {
fileAttente.push(item);
afficherFile(); sauvegarderFile();
item.timer = setInterval(function() {
var resteMs = item.tsEcheance - Date.now();
if (resteMs <= 0) { clearInterval(item.timer); executerItem(item); return; }
var el = document.getElementById('os-countdown-'+item.id);
if (el) { var s=Math.floor(resteMs/1000); el.textContent=pad(Math.floor(s/3600))+':'+pad(Math.floor((s%3600)/60))+':'+pad(s%60); }
}, 200);
}
function supprimerFile(id) {
for (var i=0;i<fileAttente.length;i++) { if (fileAttente[i].id===id) { clearInterval(fileAttente[i].timer); fileAttente.splice(i,1); break; } }
afficherFile(); sauvegarderFile();
}
function afficherFile() {
var liste=document.getElementById('os-file-liste'), vide=document.getElementById('os-file-vide');
liste.style.cssText='max-height:220px;overflow-y:auto';
if (fileAttente.length===0) { vide.style.display='block'; liste.innerHTML=''; return; }
vide.style.display='none'; liste.innerHTML='';
for (var i=0;i<fileAttente.length;i++) {
(function(item) {
var apercu = (item.message||'').replace(/[\u2800-\u28FF\u200B-\u200D\uFEFF\u00AD]/g,'').substring(0,40)+(item.message.length>40?'...':'');
var ligne=document.createElement('div');
ligne.style.cssText='padding:6px 8px;margin-bottom:5px;background:#0d1b2a;border:1px solid #2a3f55;border-radius:4px;font-size:12px';
ligne.innerHTML='<div style="display:flex;align-items:center;justify-content:space-between"><span style="color:#eee;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:160px">'+item.label+'</span><div style="display:flex;align-items:center;gap:6px"><span id="os-countdown-'+item.id+'" style="color:#4a90d9;font-size:11px;font-weight:bold">--:--:--</span><button type="button" data-id="'+item.id+'" style="background:none;border:1px solid #c0392b;color:#c0392b;border-radius:3px;cursor:pointer;font-size:11px;padding:2px 5px">✕</button></div></div><div style="color:#8aa8c8;font-size:11px;margin-top:3px;font-style:italic;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">'+apercu+'</div>';
ligne.querySelector('button').addEventListener('click', function() { supprimerFile(parseInt(this.getAttribute('data-id'))); });
liste.appendChild(ligne);
})(fileAttente[i]);
}
}
function executerItem(item) {
var el = document.getElementById('os-countdown-'+item.id);
if (el) { el.textContent='Envoi...'; el.style.color='#f39c12'; }
if (item.mode==='citation') posterAvecFetch(item,true);
else if (item.mode==='nouveau') posterNouveauTopic(item);
else posterAvecFetch(item,false);
}
function terminerItem(id, succes, msg) {
var el = document.getElementById('os-countdown-'+id);
if (el) { el.textContent=msg; el.style.color=succes?'#2ecc71':'#e74c3c'; }
if (succes) demarrerCooldownAffichage();
setTimeout(function() { for (var i=0;i<fileAttente.length;i++) { if(fileAttente[i].id===id){fileAttente.splice(i,1);break;} } afficherFile(); sauvegarderFile(); }, 3000);
}
var cooldownInterval = null;
function demarrerCooldownAffichage() {
var cdEl = document.getElementById('os-cooldown');
if (!cdEl) return;
if (cooldownInterval) clearInterval(cooldownInterval);
cooldownInterval = setInterval(function() {
var reste = Math.ceil((DELAI_MIN_POSTS-(Date.now()-dernierPost))/1000);
if (reste<=0) { cdEl.innerHTML='⚠ Delai min entre posts : <b>8s</b> — Cloudflare'; clearInterval(cooldownInterval); cooldownInterval=null; }
else cdEl.innerHTML='⚠ Prochain post dans <b>'+reste+'s</b> — Cloudflare actif';
}, 250);
}
function posterAvecFetch(item, estCitation) {
if (postEnCours) { terminerItem(item.id,false,'Post en cours, attends !'); return; }
if ((Date.now()-dernierPost) < DELAI_MIN_POSTS && dernierPost>0) { var att=Math.ceil((DELAI_MIN_POSTS-(Date.now()-dernierPost))/1000); terminerItem(item.id,false,'Trop rapide ! Attends '+att+'s'); return; }
postEnCours = true;
var failsafe = setTimeout(function(){if(postEnCours)postEnCours=false;},30000);
var pageUrl = normaliserUrlTopic((item.pageUrl||getUrlCible()).split('#')[0]);
fetch(pageUrl,{credentials:'include'}).then(function(r){return r.text();}).then(function(html) {
var match = html.match(/name="token"[^>]*value="([^"]+)"/) || html.match(/value="([^"]+)"[^>]*name="token"/) || html.match(/data-token="([^"]+)"/);
var token = match ? match[1] : '';
if (!token||token.length<10) { clearTimeout(failsafe); postEnCours=false; terminerItem(item.id,false,'Token invalide !'); return; }
var body = new URLSearchParams();
if (estCitation&&item.cibleInfo&&item.cibleInfo.messageId) { var mid=parseInt(item.cibleInfo.messageId); if(mid>0) body.append('answer',mid); }
body.append('message',item.message); body.append('poll_question',''); body.append('poll[]',''); body.append('token',token);
return fetch(pageUrl+'#last',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:body.toString(),credentials:'include'});
}).then(function(r) {
clearTimeout(failsafe); postEnCours=false;
if (r&&(r.ok||r.redirected)) { dernierPost=Date.now(); terminerItem(item.id,true,estCitation?'Citation postee !':'Poste !'); }
else if (r) { if(r.status===429){terminerItem(item.id,false,'Rate limit 429 !');DELAI_MIN_POSTS=Math.min(DELAI_MIN_POSTS+5000,30000);}else terminerItem(item.id,false,'Erreur '+r.status); }
}).catch(function(){clearTimeout(failsafe);postEnCours=false;terminerItem(item.id,false,'Erreur reseau !');});
}
function posterNouveauTopic(item) {
if (postEnCours) { terminerItem(item.id,false,'Post en cours, attends !'); return; }
if ((Date.now()-dernierPost)<DELAI_MIN_POSTS && dernierPost>0) { var att=Math.ceil((DELAI_MIN_POSTS-(Date.now()-dernierPost))/1000); terminerItem(item.id,false,'Trop rapide ! Attends '+att+'s'); return; }
postEnCours = true;
var pageUrl = normaliserUrlTopic((item.pageUrl||window.location.href).split('#')[0]);
fetch(pageUrl,{credentials:'include'}).then(function(r){return r.text();}).then(function(html) {
var match = html.match(/name="token"[^>]*value="([^"]+)"/) || html.match(/value="([^"]+)"[^>]*name="token"/) || html.match(/data-token="([^"]+)"/);
var token = match ? match[1] : '';
if (!token||token.length<10) { postEnCours=false; terminerItem(item.id,false,'Token introuvable !'); return; }
var body = new URLSearchParams();
body.append('title',item.titre); body.append('message',item.message); body.append('poll[]',''); body.append('token',token);
return fetch(pageUrl+'#post',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:body.toString(),credentials:'include'});
}).then(function(r) {
postEnCours=false;
if (r&&(r.ok||r.redirected)) {
dernierPost=Date.now();
if (item.vraiTitre) { var mId=(r.url||'').match(/\/topic\/(\d+)\//); if(mId) setTimeout(function(){ posterPremierMessage('https://onche.org/topic/'+mId[1]+'/', item.vraiTitre); }, 2000); terminerItem(item.id,true,'Topic troll cree !'); }
else terminerItem(item.id,true,'Topic cree !');
} else if (r) terminerItem(item.id,false,'Erreur '+r.status);
}).catch(function(){postEnCours=false;terminerItem(item.id,false,'Erreur reseau !');});
}
function posterPremierMessage(topicUrl, texte) {
fetch(topicUrl,{credentials:'include'}).then(function(r){return r.text();}).then(function(html) {
var match = html.match(/name="token"[^>]*value="([^"]+)"/) || html.match(/value="([^"]+)"[^>]*name="token"/) || html.match(/data-token="([^"]+)"/);
var token = match ? match[1] : '';
if (!token||token.length<10) return;
var body=new URLSearchParams(); body.append('message',texte); body.append('poll_question',''); body.append('poll[]',''); body.append('token',token);
fetch(topicUrl+'#last',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:body.toString(),credentials:'include'});
}).catch(function(){});
}
// =========================================================
// WATCHDOG
// =========================================================
var watchdogTimer = null, watchdogActif = false;
var watchdogPseudos = [];
var watchdogForums = ['https://onche.org/forum/1/blabla-general'];
var watchdogMessagesVus = {};
var watchdogTopicsDetectes = {}; // topicId -> {url, titre, pseudo}
try { var rawWD = sessionStorage.getItem('horlonche_watchdog_vus'); if (rawWD) watchdogMessagesVus = JSON.parse(rawWD); } catch(e) {}
function sauvegarderWatchdogVus() {
try {
var keys = Object.keys(watchdogMessagesVus);
if (keys.length > 500) { var n={}; keys.slice(-500).forEach(function(k){n[k]=true;}); watchdogMessagesVus=n; }
sessionStorage.setItem('horlonche_watchdog_vus', JSON.stringify(watchdogMessagesVus));
} catch(e) {}
}
function ajouterHistoriqueWatchdog(data) {
var today = new Date().toLocaleDateString();
var key = 'horlonche_watchdog_hist_' + today;
var liste = [];
try { var r = localStorage.getItem(key); if (r) liste = JSON.parse(r); } catch(e) {}
liste.unshift(Object.assign({ heure: new Date().toLocaleTimeString() }, data));
if (liste.length > 200) liste = liste.slice(0, 200);
try { localStorage.setItem(key, JSON.stringify(liste)); } catch(e) {}
}
function chargerHistoriqueWatchdog() {
var entrees = [];
for (var d = 0; d < 7; d++) {
var date = new Date(); date.setDate(date.getDate() - d);
var raw = localStorage.getItem('horlonche_watchdog_hist_' + date.toLocaleDateString());
try { if (raw) { var items = JSON.parse(raw); items.forEach(function(i){i.date=date.toLocaleDateString();}); entrees = entrees.concat(items); } } catch(e) {}
}
return entrees;
}
function afficherHistoriqueWatchdog() {
var liste = document.getElementById('os-wd-hist-liste');
if (!liste) return;
liste.innerHTML = '';
var entrees = chargerHistoriqueWatchdog();
if (entrees.length === 0) { liste.innerHTML = '<div style="color:#aaa;text-align:center;padding:20px;font-size:12px">Aucune detection</div>'; return; }
entrees.forEach(function(item) {
var ligne = document.createElement('div');
ligne.style.cssText = 'padding:7px 8px;margin-bottom:5px;background:#0d1b2a;border-radius:4px;font-size:11px;' + (item.type==='erreur'?'border-left:3px solid #e74c3c':'border-left:3px solid #9b59b6');
var html = '<div style="display:flex;justify-content:space-between;margin-bottom:4px"><span style="color:#888">' + (item.date||'') + ' ' + item.heure + '</span><span style="color:#e67e22;font-weight:bold">@' + escHtml(item.pseudo||'') + '</span></div>';
html += '<div style="color:#aaa;margin-bottom:2px">' + escHtml(item.topicTitre||'') + '</div>';
if (item.extrait) html += '<div style="color:#eee;background:#111;padding:4px 6px;border-radius:3px;margin-top:3px">' + escHtml(item.extrait) + '</div>';
if (item.topicUrl) html += '<a href="' + escHtml(item.topicUrl) + '" target="_blank" style="color:#9b59b6;font-size:10px;text-decoration:none">Voir →</a>';
if (item.erreur) html += '<div style="color:#e74c3c">' + escHtml(item.erreur) + '</div>';
ligne.innerHTML = html;
liste.appendChild(ligne);
});
}
function afficherWatchdogPseudos() {
var el = document.getElementById('os-wd-pseudos-liste');
if (!el) return;
el.innerHTML = '';
watchdogPseudos.forEach(function(p, idx) {
var ligne = document.createElement('div');
ligne.style.cssText = 'display:flex;align-items:center;gap:4px;margin-bottom:4px;background:#0d1b2a;border:1px solid #3a2000;border-radius:4px;padding:3px 6px';
ligne.innerHTML = '<span style="flex:1;color:#eee;font-size:11px">' + escHtml(p) + '</span><button type="button" data-idx="' + idx + '" style="background:none;border:none;color:#c0392b;cursor:pointer;font-size:13px;padding:0 2px">✕</button>';
ligne.querySelector('button').addEventListener('click', function() { watchdogPseudos.splice(parseInt(this.getAttribute('data-idx')),1); afficherWatchdogPseudos(); });
el.appendChild(ligne);
});
}
function afficherWatchdogForums() {
var el = document.getElementById('os-wd-forums-liste');
if (!el) return;
el.innerHTML = '';
watchdogForums.forEach(function(url, idx) {
var ligne = document.createElement('div');
ligne.style.cssText = 'display:flex;align-items:center;gap:4px;margin-bottom:4px;background:#0d1b2a;border:1px solid #3a2000;border-radius:4px;padding:3px 6px';
var nom = url.replace('https://onche.org/forum/','').replace(/\/.*/,'');
nom = ({1:'Blabla General',4:'Goulag',7:'Finance',8:'Jeux Video',9:'Autonomie',13:'Videoclub'})[nom] || url.split('/').pop();
ligne.innerHTML = '<span style="flex:1;color:#eee;font-size:11px">' + nom + '</span><button type="button" data-idx="' + idx + '" style="background:none;border:none;color:#c0392b;cursor:pointer;font-size:13px;padding:0 2px">✕</button>';
ligne.querySelector('button').addEventListener('click', function() { watchdogForums.splice(parseInt(this.getAttribute('data-idx')),1); afficherWatchdogForums(); });
el.appendChild(ligne);
});
}
function scannerWatchdog() {
if (watchdogPseudos.length === 0) return;
watchdogForums.forEach(function(forumUrl) {
fetch(forumUrl, { credentials: 'include' }).then(function(r){return r.text();}).then(function(html) {
var doc = new DOMParser().parseFromString(html, 'text/html');
var topicEls = doc.querySelectorAll('.topic');
topicEls.forEach(function(topicEl) {
var pseudoEl = topicEl.querySelector('.topic-username');
if (!pseudoEl) return;
var dernierPosteur = pseudoEl.textContent.trim().toLowerCase();
var surveille = watchdogPseudos.some(function(p){ return dernierPosteur === p.toLowerCase(); });
if (!surveille) return;
var lienEl = topicEl.querySelector('a.topic-subject');
if (!lienEl) return;
var href = lienEl.getAttribute('href');
var matchId = href ? href.match(/\/topic\/(\d+)/) : null;
if (!matchId) return;
var topicId = matchId[1];
// Titre : premier span sans classe topic-nb
var titre = '';
var spans = lienEl.querySelectorAll('span');
for (var si=0; si<spans.length; si++) {
if (!spans[si].className || spans[si].className.indexOf('topic-nb')===-1) {
titre = spans[si].textContent.trim();
if (titre) break;
}
}
if (!titre) titre = lienEl.firstChild && lienEl.firstChild.textContent ? lienEl.firstChild.textContent.trim() : '';
if (!titre) titre = 'Topic #' + topicId;
var topicUrl = href.indexOf('https://') === 0 ? href : 'https://onche.org' + href;
topicUrl = topicUrl.split('#')[0];
if (!/\/\d+$/.test(topicUrl)) topicUrl = topicUrl + '/1';
entrerDansTopicWatchdog(topicId, topicUrl, titre);
});
setWatchdogStatus('Actif — dernier scan : ' + new Date().toLocaleTimeString(), '#2ecc71');
}).catch(function(){ setWatchdogStatus('Erreur de scan', '#e74c3c'); });
});
}
function entrerDansTopicWatchdog(topicId, topicUrl, topicTitre) {
var baseUrl = topicUrl.split('#')[0];
if (baseUrl.indexOf('http') !== 0) baseUrl = 'https://onche.org' + baseUrl;
baseUrl = baseUrl.replace(/\/\d+$/, '');
var pageUrl = baseUrl + '/1';
fetch(pageUrl, { credentials: 'include' }).then(function(r){return r.text();}).then(function(html) {
var doc = new DOMParser().parseFromString(html, 'text/html');
var lastPageBtn = doc.querySelector('a.mdi-chevron-right:not(.disabled)');
if (lastPageBtn) {
var lastHref = lastPageBtn.getAttribute('href') || '';
var lastMatch = lastHref.match(/\/topic\/\d+\/[^/]+\/(\d+)/);
if (lastMatch) {
var lastUrl = baseUrl + '/' + parseInt(lastMatch[1]);
fetch(lastUrl, { credentials: 'include' }).then(function(r2){return r2.text();}).then(function(html2){ parseMessagesWatchdog(html2, topicId, topicUrl, topicTitre, baseUrl); }).catch(function(){});
return;
}
}
parseMessagesWatchdog(html, topicId, topicUrl, topicTitre, baseUrl);
}).catch(function(){});
}
function parseMessagesWatchdog(html, topicId, topicUrl, topicTitre, baseUrl) {
var doc = new DOMParser().parseFromString(html, 'text/html');
var tous = doc.querySelectorAll('.message[data-id][data-username]');
var messages = Array.prototype.filter.call(tous, function(el){ return !el.classList.contains('answer'); });
messages.forEach(function(msgEl) {
var msgId = msgEl.getAttribute('data-id');
var username = (msgEl.getAttribute('data-username') || '').toLowerCase();
var surveille = watchdogPseudos.some(function(p){ return username === p.toLowerCase(); });
if (!surveille) return;
var cle = username + '_msg_' + msgId;
if (watchdogMessagesVus[cle]) return;
watchdogMessagesVus[cle] = true; sauvegarderWatchdogVus();
var contenuEl = msgEl.querySelector('.message-content');
var extrait = contenuEl ? contenuEl.textContent.trim().substring(0, 80) : '';
var topicBase = topicUrl.indexOf('https://') === 0 ? topicUrl : 'https://onche.org' + topicUrl;
var topicUrlPropre = topicBase.split('#')[0] + '#message_' + msgId;
setWatchdogStatus('🐕 @' + username + ' detecte dans ' + topicTitre.substring(0, 20), '#9b59b6');
ajouterLogWatchdog('🐕 @' + username + ' — ' + topicTitre.substring(0,30), '#9b59b6');
// Stocker le topic pour la liste cliquable
if (!watchdogTopicsDetectes[topicId]) {
watchdogTopicsDetectes[topicId] = { url: topicBase.split('#')[0] + '/1', titre: topicTitre, pseudo: username };
afficherTopicsDetectes();
}
ajouterHistoriqueWatchdog({ type:'detection', pseudo:username, topicUrl:topicUrlPropre, topicTitre:topicTitre, extrait:extrait });
// Mise a jour de l'historique commun aussi
ajouterHistorique('trouve', {titre:topicTitre, auteur:username, topicUrl:topicUrlPropre});
var reponse = document.getElementById('os-wd-message') ? document.getElementById('os-wd-message').value.trim() : '';
if (reponse) posterReponseWatchdog(topicUrlPropre, msgId, topicTitre, username, reponse);
});
}
function posterReponseWatchdog(topicUrl, msgId, topicTitre, pseudo, reponse) {
var baseUrl = topicUrl.indexOf('https://') === 0 ? topicUrl : 'https://onche.org' + topicUrl;
var topicBase = baseUrl.split('#')[0].replace(/\/\d+$/, '');
var pageUrl = topicBase + '/1';
fetch(pageUrl, { credentials: 'include' }).then(function(r){return r.text();}).then(function(html) {
var match = html.match(/name="token"[^>]*value="([^"]+)"/) || html.match(/value="([^"]+)"[^>]*name="token"/) || html.match(/data-token="([^"]+)"/);
var token = match ? match[1] : '';
if (!token || token.length < 10) { ajouterHistoriqueWatchdog({type:'erreur',pseudo:pseudo,topicUrl:baseUrl,topicTitre:topicTitre,erreur:'Token introuvable'}); return; }
var body = new URLSearchParams();
body.append('message', reponse); body.append('poll_question',''); body.append('poll[]',''); body.append('token', token);
return fetch(topicBase + '/1#last', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body:body.toString(), credentials:'include'});
}).then(function(r) {
if (r&&(r.ok||r.redirected)) { ajouterLogWatchdog('✅ Reponse postee', '#2ecc71'); ajouterHistorique('poste',{topicUrl:topicUrl,topicTitre:topicTitre,message:reponse}); }
else if (r) ajouterLogWatchdog('❌ Erreur ' + r.status, '#e74c3c');
}).catch(function(){ ajouterLogWatchdog('❌ Erreur reseau', '#e74c3c'); });
}
function setWatchdogStatus(t, c) { var el=document.getElementById('os-wd-status'); if(el){el.textContent=t;el.style.color=c||'#aaa';} }
function afficherTopicsDetectes() {
var liste = document.getElementById('os-wd-topics-liste');
if (!liste) return;
var ids = Object.keys(watchdogTopicsDetectes);
if (ids.length === 0) {
liste.innerHTML = '<span style="color:#666;font-size:10px">Aucun topic trouve pour ces pseudos.</span>';
return;
}
liste.innerHTML = '';
ids.forEach(function(id) {
var t = watchdogTopicsDetectes[id];
var ligne = document.createElement('div');
ligne.style.cssText = 'display:flex;align-items:center;gap:5px;margin-bottom:4px;padding:3px 5px;background:#1a2a3a;border-radius:3px';
var cbId = 'os-wd-cb-' + id;
ligne.innerHTML = '<input type="checkbox" id="' + cbId + '" data-id="' + id + '" checked style="cursor:pointer;flex-shrink:0">'
+ '<span style="color:#e67e22;font-size:10px;flex-shrink:0">@' + escHtml(t.pseudo) + '</span>'
+ '<a href="' + escHtml(t.url) + '" target="_blank" style="flex:1;color:#eee;font-size:10px;text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis" title="' + escHtml(t.titre) + '">' + escHtml(t.titre.substring(0,35)) + '</a>';
liste.appendChild(ligne);
});
}
function scannerTopicsManuellement() {
if (watchdogPseudos.length === 0) { alert('Ajoute au moins un pseudo a surveiller !'); return; }
var btn = document.getElementById('os-wd-scan-now');
if (btn) { btn.textContent = '⏳ Scan...'; btn.disabled = true; }
watchdogTopicsDetectes = {};
var liste = document.getElementById('os-wd-topics-liste');
if (liste) liste.innerHTML = '<span style="color:#e67e22;font-size:10px">Scan en cours...</span>';
var forums = watchdogForums.length > 0 ? watchdogForums : ['https://onche.org/forum/1/blabla-general'];
var total = forums.length, done = 0;
forums.forEach(function(forumUrl) {
fetch(forumUrl, { credentials: 'include' }).then(function(r){return r.text();}).then(function(html) {
var doc = new DOMParser().parseFromString(html, 'text/html');
doc.querySelectorAll('.topic').forEach(function(topicEl) {
var pseudoEl = topicEl.querySelector('.topic-username');
if (!pseudoEl) return;
var dernierPosteur = pseudoEl.textContent.trim().toLowerCase();
var surveille = watchdogPseudos.some(function(p){ return dernierPosteur === p.toLowerCase(); });
if (!surveille) return;
var lienEl = topicEl.querySelector('a.topic-subject');
if (!lienEl) return;
var href = lienEl.getAttribute('href');
var matchId = href ? href.match(/\/topic\/(\d+)/) : null;
if (!matchId) return;
var topicId = matchId[1];
// Titre : premier span direct, sans topic-nb
var titre = '';
var spans = lienEl.querySelectorAll('span');
for (var si=0; si<spans.length; si++) {
if (!spans[si].className || spans[si].className.indexOf('topic-nb')===-1) {
titre = spans[si].textContent.trim();
if (titre) break;
}
}
if (!titre) titre = lienEl.firstChild && lienEl.firstChild.textContent ? lienEl.firstChild.textContent.trim() : '';
if (!titre) titre = 'Topic #' + topicId;
var topicUrl = (href.indexOf('https://')===0?href:'https://onche.org'+href).split('#')[0];
if (!/\/\d+$/.test(topicUrl)) topicUrl += '/1';
watchdogTopicsDetectes[topicId] = { url: topicUrl, titre: titre, pseudo: dernierPosteur };
});
}).catch(function(){}).then(function() {
done++;
if (done >= total) {
// Ouvrir la vue topics et afficher les resultats
var vConfig = document.getElementById('os-wd-vue-config');
var vTopics = document.getElementById('os-wd-vue-topics');
if (vConfig) vConfig.style.display = 'none';
if (vTopics) vTopics.style.display = 'block';
afficherTopicsDetectes();
if (btn) { btn.textContent = '🔍 Scan'; btn.disabled = false; }
}
});
});
}
var wdPosterEnCours = false;
function posterSurListe(ids, btnId) {
var msg = document.getElementById('os-wd-message') ? document.getElementById('os-wd-message').value.trim() : '';
if (!msg) { alert('Ecris un message dans le champ Message auto !'); return; }
if (wdPosterEnCours) { alert('Envoi en cours...'); return; }
if (ids.length === 0) { alert('Aucun topic selectionne !'); return; }
wdPosterEnCours = true;
var i = 0;
var btn = document.getElementById(btnId);
var labelOriginal = btn ? btn.textContent : '';
function envoyerProchain() {
if (i >= ids.length) {
wdPosterEnCours = false;
if (btn) { btn.textContent = labelOriginal; btn.disabled = false; }
ajouterLogWatchdog('✅ Envoi termine sur ' + ids.length + ' topics', '#2ecc71');
return;
}
var t = watchdogTopicsDetectes[ids[i]];
if (!t) { i++; envoyerProchain(); return; }
if (btn) btn.textContent = 'Envoi ' + (i+1) + '/' + ids.length + '...';
posterReponseWatchdog(t.url, null, t.titre, t.pseudo, msg);
ajouterLogWatchdog('📤 ' + (i+1) + '/' + ids.length + ' — ' + t.titre.substring(0,25), '#2ecc71');
i++;
if (i < ids.length) setTimeout(envoyerProchain, 8500);
else {
wdPosterEnCours = false;
if (btn) { btn.textContent = labelOriginal; btn.disabled = false; }
ajouterLogWatchdog('✅ Envoi termine sur ' + ids.length + ' topics', '#2ecc71');
}
}
if (btn) btn.disabled = true;
envoyerProchain();
}
function posterSurSelection() {
var ids = [];
document.querySelectorAll('#os-wd-topics-liste input[type="checkbox"]').forEach(function(cb) {
if (cb.checked) ids.push(cb.getAttribute('data-id'));
});
posterSurListe(ids, 'os-wd-poster-selection');
}
function posterSurTous() {
var ids = Object.keys(watchdogTopicsDetectes);
posterSurListe(ids, 'os-wd-poster-tous');
}
function ajouterLogWatchdog(texte, couleur) {
var log = document.getElementById('os-wd-log');
if (log) {
var l = document.createElement('div');
l.style.color = couleur || '#888';
l.textContent = new Date().toLocaleTimeString() + ' — ' + texte;
log.insertBefore(l, log.firstChild);
while (log.children.length > 20) log.removeChild(log.lastChild);
}
}
// Listeners Watchdog
setTimeout(function() {
var btnWD = document.getElementById('os-btn-watchdog');
if (btnWD) btnWD.addEventListener('click', function() {
['os-vue-liste','os-vue-form','os-vue-sniper','os-vue-historique'].forEach(function(id){var el=document.getElementById(id);if(el)el.style.display='none';});
var vw = document.getElementById('os-vue-watchdog'); if(vw) vw.style.display='block';
afficherWatchdogPseudos(); afficherWatchdogForums();
});
var btnWDRetour = document.getElementById('os-wd-retour');
if (btnWDRetour) btnWDRetour.addEventListener('click', function() {
var vw=document.getElementById('os-vue-watchdog');if(vw)vw.style.display='none';
var vl=document.getElementById('os-vue-liste');if(vl)vl.style.display='block';
});
var btnPseudoAdd = document.getElementById('os-wd-pseudo-add');
if (btnPseudoAdd) btnPseudoAdd.addEventListener('click', function() {
var inp = document.getElementById('os-wd-pseudo-input');
var val = inp ? inp.value.trim() : '';
if (!val) return;
if (watchdogPseudos.indexOf(val) !== -1) { alert('Pseudo deja dans la liste'); return; }
watchdogPseudos.push(val); inp.value = ''; afficherWatchdogPseudos();
});
var btnForumAdd = document.getElementById('os-wd-forum-add');
if (btnForumAdd) btnForumAdd.addEventListener('click', function() {
var inp = document.getElementById('os-wd-forum-input');
var url = inp ? inp.value.trim() : '';
if (!url) return;
if (url.indexOf('onche.org/forum/') === -1) { alert('URL invalide'); return; }
if (watchdogForums.indexOf(url) !== -1) { alert('Forum deja dans la liste'); return; }
watchdogForums.push(url); inp.value = ''; afficherWatchdogForums();
});
var btnWDStart = document.getElementById('os-wd-start');
if (btnWDStart) btnWDStart.addEventListener('click', function() {
if (watchdogPseudos.length === 0) { alert('Ajoute au moins un pseudo !'); return; }
var intervalle = parseInt(document.getElementById('os-wd-intervalle').value) || 15;
watchdogActif = true;
document.getElementById('os-wd-start').style.display = 'none';
document.getElementById('os-wd-stop').style.display = 'block';
setWatchdogStatus('Actif — scan toutes les ' + intervalle + 's', '#2ecc71');
scannerWatchdog();
watchdogTimer = setInterval(scannerWatchdog, intervalle * 1000);
});
var btnWDHist = document.getElementById('os-wd-historique-btn');
if (btnWDHist) btnWDHist.addEventListener('click', function() {
document.getElementById('os-vue-watchdog').style.display = 'none';
document.getElementById('os-vue-wd-historique').style.display = 'block';
afficherHistoriqueWatchdog();
});
var btnWDHistRetour = document.getElementById('os-wd-hist-retour');
if (btnWDHistRetour) btnWDHistRetour.addEventListener('click', function() {
document.getElementById('os-vue-wd-historique').style.display = 'none';
document.getElementById('os-vue-watchdog').style.display = 'block';
});
var btnWDHistClear = document.getElementById('os-wd-hist-clear');
if (btnWDHistClear) btnWDHistClear.addEventListener('click', function() {
if (!confirm("Vider l'historique Watchdog ?")) return;
for (var d=0;d<7;d++){var date=new Date();date.setDate(date.getDate()-d);localStorage.removeItem('horlonche_watchdog_hist_'+date.toLocaleDateString());}
afficherHistoriqueWatchdog();
});
var btnScanNow = document.getElementById('os-wd-scan-now');
if (btnScanNow) btnScanNow.addEventListener('click', scannerTopicsManuellement);
var btnVoirTopics = document.getElementById('os-wd-voir-topics');
if (btnVoirTopics) btnVoirTopics.addEventListener('click', function() {
document.getElementById('os-wd-vue-config').style.display = 'none';
document.getElementById('os-wd-vue-topics').style.display = 'block';
afficherTopicsDetectes();
});
var btnTopicsRetour = document.getElementById('os-wd-topics-retour');
if (btnTopicsRetour) btnTopicsRetour.addEventListener('click', function() {
document.getElementById('os-wd-vue-topics').style.display = 'none';
document.getElementById('os-wd-vue-config').style.display = 'block';
});
var btnPosterSelection = document.getElementById('os-wd-poster-selection');
if (btnPosterSelection) btnPosterSelection.addEventListener('click', posterSurSelection);
var btnPosterTous = document.getElementById('os-wd-poster-tous');
if (btnPosterTous) btnPosterTous.addEventListener('click', posterSurTous);
var btnWDStop = document.getElementById('os-wd-stop');
if (btnWDStop) btnWDStop.addEventListener('click', function() {
if (watchdogTimer) clearInterval(watchdogTimer);
watchdogTimer = null; watchdogActif = false;
watchdogTopicsDetectes = {};
afficherTopicsDetectes();
document.getElementById('os-wd-start').style.display = 'block';
document.getElementById('os-wd-stop').style.display = 'none';
setWatchdogStatus('Inactif', '#aaa');
});
}, 500);
function pad(n) { return n < 10 ? '0'+n : ''+n; }
function escHtml(s){ return s?String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'):''; }
})();