# /shy/ recap script
## User Script
// ==UserScript==
// @name shy-Fluttershy
// @version 1
// @description See the last 4chan recap
// @author FlutterOP
// @match *://*.8kun.top/fluttershy/*
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
// CONFIGURATION (MANDATORY!)
const BOARD_4CHAN = 'mlp'; // 4chan board (e.g., 'mlp', 'pol', 'vip')
const THREAD_ID_4CHAN = '42132656'; // Main thread ID on 4chan
const ARCHIVE = 'desuarchive'; // 'desuarchive', 'archivedmoe', or '4b4k'
console.log('[Migrator] Script started. Board:', BOARD_4CHAN, '| Thread:', THREAD_ID_4CHAN, '| Archive:', ARCHIVE);
// Corrected main function
function convertPostReferences() {
// Enhanced selector for 8kun
const posts = document.querySelectorAll('.body, .postMessage, .post-body, .post_content, .post-text');
posts.forEach(post => {
if (post.dataset.desuConverted) return;
post.dataset.desuConverted = 'true';
const originalHTML = post.innerHTML;
let newHTML = originalHTML;
// Convert >12345678 into links
newHTML = newHTML.replace(
/(^|\s|>)>(\d{8,})/g,
(match, prefix, postId) => {
return `${prefix}<a href="${getArchiveUrl(postId)}"
target="_blank"
style="color:#0f0c5d;font-weight:bold;text-decoration:underline;"
class="desu-link">>>${postId}</a>`;
}
);
// Convert >>12345678 (if they exist)
newHTML = newHTML.replace(
/(>>)(\d{8,})/g,
(match, arrows, postId) => {
return `<a href="${getArchiveUrl(postId)}"
target="_blank"
style="color:#0f0c5d;font-weight:bold;text-decoration:underline;"
class="desu-link">${arrows}${postId}</a>`;
}
);
if (newHTML !== originalHTML) {
post.innerHTML = newHTML;
}
});
}
// Corrected URL generator
function getArchiveUrl(postId) {
// Only for Desuarchive and Archived.moe we use the format /thread/THREAD_ID/#pPOST_ID
if (ARCHIVE === 'desuarchive' || ARCHIVE === 'archivedmoe') {
return `https://${ARCHIVE === 'desuarchive' ? 'desuarchive.org' : 'archived.moe'}/${BOARD_4CHAN}/thread/${THREAD_ID_4CHAN}/#${postId}`;
}
// For 4b4k
else if (ARCHIVE === '4b4k') {
return `https://arch.b4k.co/4chan/${BOARD_4CHAN}/search/num/${postId}`;
}
}
// Initialization
function init() {
// Immediate execution
convertPostReferences();
// Observer for new posts
const observer = new MutationObserver(() => {
convertPostReferences();
});
observer.observe(document, {
childList: true,
subtree: true
});
// Additional retry for SPAs
setTimeout(convertPostReferences, 3000);
}
// Trigger initialization
if (document.readyState === 'complete') {
init();
} else {
window.addEventListener('load', init);
}
})();