MediaWiki:Common.js: Perbedaan antara revisi

Tidak ada ringkasan suntingan
Tanda: Suntingan perangkat seluler Suntingan peramban seluler
Tidak ada ringkasan suntingan
Tanda: Suntingan perangkat seluler Suntingan peramban seluler
Baris 1.165: Baris 1.165:


/* ==========================================================
/* ==========================================================
   🛡️ MIPPEDIA SYSTEM - ULTIMATE NEURAL ENGINE (V6 - SILENT)
   🛡️ MIPPEDIA CORE SYSTEM - NEURAL VIEW ENGINE
   Fitur: Anti-Refresh, Anti-Template, Anti-Header, Anti-Category
   Logika: Auto-Patrol (Patroli) & Global Assistant (All Users)
   ========================================================== */
   ========================================================== */
mw.hook('postEdit').add(function() {
(function() {
     var currentUser = mw.config.get('wgUserName');
     var config = mw.config.get(['wgNamespaceNumber', 'wgPageName', 'wgUserName', 'wgRevisionId', 'wgAction']);
     if (!currentUser) return;
     if (config.wgNamespaceNumber !== 0 || config.wgAction !== 'view') return;
   
 
     var normalizedUser = currentUser.replace(/_/g, ' ');
     // --- BRANKAS MEMORI: Biar nggak kerja dua kali di revisi yang sama ---
     var isPatroli = (normalizedUser === 'Mippedia Patroli');
     var storageKey = 'mippedia_done_' + config.wgRevisionId;
     if (mw.config.get('wgNamespaceNumber') !== 0) return;
     if (localStorage.getItem(storageKey)) return;


     var api = new mw.Api();
     var api = new mw.Api();
     var pageTitle = mw.config.get('wgPageName').replace(/_/g, ' ');
     var pageTitle = config.wgPageName.replace(/_/g, ' ');
    var currentUser = (config.wgUserName || 'Anonim').replace(/_/g, ' ');
    var isPatroli = (currentUser === 'Mippedia Patroli');


     api.get({
     api.get({
Baris 1.190: Baris 1.192:
         api.get({
         api.get({
             action: 'query',
             action: 'query',
             titles: pageTitle,
             titles: config.wgPageName,
             prop: 'revisions|categories',
             prop: 'revisions|categories',
             rvprop: 'content',
             rvprop: 'content',
Baris 1.198: Baris 1.200:
             var rawContent = page.revisions[0]['*'];
             var rawContent = page.revisions[0]['*'];
             var content = rawContent;
             var content = rawContent;
            var summary = [];


             // --- 1. SMART RELATED (MAX 3, NO [[ ]], SILENT) ---
             // --- 1. GLOBAL ENGINE: RELATED ARTICLES (UNTUK SEMUA USER/ANONIM) ---
             if (content.indexOf('{{#related:') === -1) {
             if (content.indexOf('{{#related:') === -1) {
                var currentKeywords = pageTitle.split(' ');
                 var foundRelated = [];
                 var foundRelated = [];
                var keywords = pageTitle.split(' ').filter(k => k.length > 3);
                 for (var k = 0; k < allTitles.length; k++) {
                 for (var k = 0; k < allTitles.length; k++) {
                     var otherTitle = allTitles[k];
                     if (allTitles[k] === pageTitle) continue;
                    if (otherTitle === pageTitle) continue;
                     if (keywords.some(kw => allTitles[k].toLowerCase().includes(kw.toLowerCase()))) {
                     var isMatch = currentKeywords.some(kw =>  
                        foundRelated.push('{{#related: ' + allTitles[k] + '}}');
                        kw.length > 3 && otherTitle.toLowerCase().indexOf(kw.toLowerCase()) !== -1
                    }
                    );
                    if (isMatch) foundRelated.push('{{#related: ' + otherTitle + '}}');
                     if (foundRelated.length >= 3) break;
                     if (foundRelated.length >= 3) break;
                 }
                 }
                 if (foundRelated.length > 0) content += '\n\n' + foundRelated.join('\n');
                 if (foundRelated.length > 0) {
                    content += '\n\n' + foundRelated.join('\n');
                    summary.push('Auto-Related');
                }
            }
 
            // --- 2. GLOBAL ENGINE: AUTO-MAINTENANCE TAGS (REF, KAT, RINTISAN, PROMO) ---
            // A. Cek Referensi
            if (!/<ref[\s>]/i.test(content) && !/\{\{Butuh Referensi/i.test(content)) {
                content = '{{Butuh Referensi|date=April 2026}}\n' + content;
                summary.push('+RefTag');
            }
            // B. Cek Kategori
            if ((!page.categories || page.categories.length === 0) && !/\{\{Butuh Kategori/i.test(content)) {
                content = '{{Butuh Kategori|date=April 2026}}\n' + content;
                summary.push('+CatTag');
            }
            // C. Cek Artikel Rintisan (< 200 kata)
            var wordCount = rawContent.split(/\s+/).length;
            if (wordCount < 200 && !/\{\{Artikel Rintisan/i.test(content)) {
                content = '{{Artikel Rintisan}}\n' + content;
                summary.push('+StubTag');
            }
            // D. Cek Promosi (Smart Filter)
            var promoWords = ['memang hebat', 'terpercaya sekali', 'terbaik di dunia', 'hubungi nomor kami', 'harga murah', 'kualitas terjamin'];
            if (promoWords.some(p => rawContent.toLowerCase().includes(p)) && !/\{\{Hapus/i.test(content)) {
                content = '{{Hapus|Alasan: Terdeteksi promosi otomatis}}\n' + content;
                summary.push('+PromoTag');
             }
             }


             // --- 2. PATROLI ENGINE (SILENT PROTECTION) ---
             // --- 3. PATROLI ENGINE: AUTO-LINKING (KHUSUS MIPPEDIA PATROLI) ---
             if (isPatroli) {
             if (isPatroli) {
                 var placeholders = [];
                 var placeholders = [];
                 // Lindungi Template, Header, dan Kategori
                 // Lindungi: Template, Header, Kategori, dan PARAGRAF PERTAMA (Sebelum "adalah")
                 content = content.replace(/(\{\{[\s\S]*?\}\}|==+.*?==+|\[\[Kategori:.*?\]\])/gi, function(match) {
                 content = content.replace(/(\{\{[\s\S]*?\}\}|==+.*?==+|\[\[Kategori:.*?\]\]|^.*?adalah)/gi, function(match) {
                     placeholders.push(match);
                     placeholders.push(match);
                     return '___MIP_SKIP_' + (placeholders.length - 1) + '___';
                     return '___MIP_SKIP_' + (placeholders.length - 1) + '___';
Baris 1.231: Baris 1.259:
                     if (inLink || tokens[i].trim().length < 3 || tokens[i].includes('___MIP_SKIP_')) continue;
                     if (inLink || tokens[i].trim().length < 3 || tokens[i].includes('___MIP_SKIP_')) continue;


                     var words = tokens[i].match(/\b\w+\b/g);
                     var wordsInToken = tokens[i].match(/\b\w+\b/g);
                     if (!words) continue;
                     if (wordsInToken) {
                    words.forEach(function(word) {
                        wordsInToken.forEach(function(word) {
                        var lowerWord = word.toLowerCase();
                            var lowerW = word.toLowerCase();
                        if (lowerWord === pageTitle.toLowerCase()) return;
                            if (lowerW === pageTitle.toLowerCase()) return;
                        var idx = lowerTitles.indexOf(lowerWord);
                            var idx = lowerTitles.indexOf(lowerW);
                        if (idx !== -1) {
                            if (idx !== -1) {
                            var regex = new RegExp('\\b' + word + '\\b', 'g');
                                tokens[i] = tokens[i].replace(new RegExp('\\b'+word+'\\b', 'g'), '[['+allTitles[idx]+'|'+word+']]');
                            tokens[i] = tokens[i].replace(regex, '[[' + allTitles[idx] + '|' + word + ']]');
                        } else {
                            for (var j = 0; j < allTitles.length; j++) {
                                if (Math.abs(word.length - allTitles[j].length) <= 1) {
                                    if (levenshtein(lowerWord, allTitles[j].toLowerCase()) === 1) {
                                        tokens[i] = tokens[i].replace(word, '[[' + allTitles[j] + ']]');
                                        break;
                                    }
                                }
                             }
                             }
                         }
                         });
                     });
                     }
                 }
                 }
                 content = tokens.join('');
                 content = tokens.join('');
                 content = content.replace(/___MIP_SKIP_(\d+)___/g, function(match, id) { return placeholders[id]; });
                 content = content.replace(/___MIP_SKIP_(\d+)___/g, function(m, id) { return placeholders[id]; });
                 content = content.replace(/\[\[([^|\]:]+)\]\]/g, function(match, p1) {
                // Clean Red Links
                     return lowerTitles.includes(p1.toLowerCase()) ? match : p1;
                 content = content.replace(/\[\[([^|\]:]+)\]\]/g, function(m, p1) {
                     return lowerTitles.includes(p1.toLowerCase()) ? m : p1;
                 });
                 });
             }
             }


             // --- 3. EXECUTE (NO REFRESH) ---
             // --- 4. EKSEKUSI: SIMPAN SECARA SENYAP ---
             if (content !== rawContent) {
             if (content !== rawContent) {
                 api.postWithToken('edit', {
                 api.postWithToken('edit', {
                     action: 'edit',
                     action: 'edit', title: config.wgPageName, text: content,
                    title: pageTitle,
                     summary: 'Mippedia Intelligence: ' + summary.join(', '),
                    text: content,
                     summary: 'Mippedia System: Background auto-optimization',
                     bot: true, markasbot: true
                     bot: true, markasbot: true
                 }); // Selesai tanpa .done(reload)
                 }).done(function() {
                    localStorage.setItem(storageKey, 'true');
                    console.log('Mippedia System: Optimization Complete.');
                });
            } else {
                localStorage.setItem(storageKey, 'true'); // Tandai kalau sudah bersih
             }
             }
         });
         });
     });
     });
 
})();
    function levenshtein(a, b) {
        var row = [], i, j, tmp, res;
        for (i = 0; i <= a.length; i++) row[i] = i;
        for (i = 1; i <= b.length; i++) {
            res = i;
            for (j = 1; j <= a.length; j++) {
                tmp = row[j - 1];
                row[j - 1] = res;
                res = b[i - 1] === a[j - 1] ? tmp : Math.min(tmp, res, row[j]) + 1;
            }
            row[a.length] = res;
        }
        return row[a.length];
    }
});