MediaWiki:Common.js: Perbedaan antara revisi

Tidak ada ringkasan suntingan
Tanda: Suntingan perangkat seluler Suntingan peramban seluler
Tidak ada ringkasan suntingan
Tanda: Pengembalian manual Suntingan perangkat seluler Suntingan peramban seluler
 
(122 revisi perantara oleh 2 pengguna tidak ditampilkan)
Baris 1: Baris 1:
/* Script Estimasi Waktu Baca - Spesialis Mobile (Minerva) & Desktop */
/* Script Estimasi Waktu Baca - Spesialis Mobile (Minerva) & Desktop */
$(document).ready(function() {
$(document).ready(function() {
     // Hanya jalan di halaman artikel asli
     // Hanya jalan di halaman artikel asli dan BUKAN di Halaman Utama
     if (mw.config.get('wgIsArticle') && mw.config.get('wgAction') === 'view' && mw.config.get('wgNamespaceNumber') === 0) {
     if (mw.config.get('wgIsArticle') && mw.config.get('wgAction') === 'view' && mw.config.get('wgNamespaceNumber') === 0 && !mw.config.get('wgIsMainPage')) {
          
          
         function hitungWaktuBaca() {
         function hitungWaktuBaca() {
Baris 15: Baris 15:
             // Bikin elemen tampilannya
             // Bikin elemen tampilannya
             var icon = '🕒'; // Emoji jam biar simpel dan ringan
             var icon = '🕒'; // Emoji jam biar simpel dan ringan
             var label = (readingTime <= 1) ? 'Kurang dari 1 menit' : readingTime + ' menit';
             var label = (readingTime <= 1) ? '- 1 menit' : readingTime + ' menit';
              
              
             var html = '<div id="reading-time-auto" style="font-size: 0.9em; color: #54595d; margin-bottom: 15px; display: flex; align-items: center; font-family: sans-serif;">';
             var html = '<div id="reading-time-auto" style="font-size: 0.9em; color: #54595d; margin-bottom: 15px; display: flex; align-items: center; font-family: sans-serif;">';
             html += '<span style="margin-right: 5px;">' + icon + '</span>';
             html += '<span style="margin-right: 5px;">' + icon + '</span>';
             html += '<span>Estimasi waktu baca: <b>' + label + '</b></span>';
             html += '<span>Estimasi waktu baca : <b>' + label + '</b></span>';
             html += '</div>';
             html += '</div>';


Baris 36: Baris 36:
     }
     }
});
});


/* Script Tombol Back to Top (Spesial Mobile) */
/* Script Tombol Back to Top (Spesial Mobile) */
Baris 59: Baris 58:
     });
     });
});
});
/* Smart Glossary Pop-up (Pratinjau Link Ringan) */
$(document).ready(function() {
    if (mw.config.get('wgIsArticle') && mw.config.get('wgAction') === 'view') {
       
        var timer;
        // Targetkan link di dalam konten artikel saja
        $('#mw-content-text a').on('mouseenter touchstart', function(e) {
            var $link = $(this);
            var title = $link.attr('title');
           
            // Jangan jalan kalau link-nya bukan artikel (misal link luar atau redlink)
            if (!title || $link.hasClass('new') || $link.hasClass('external')) return;
            timer = setTimeout(function() {
                $.getJSON(mw.util.wikiScript('api'), {
                    action: 'query',
                    prop: 'extracts',
                    exintro: true,
                    exsentences: 2, // Ambil 2 kalimat aja biar singkat
                    titles: title,
                    explaintext: true,
                    format: 'json'
                }, function(data) {
                    var pages = data.query.pages;
                    var pageId = Object.keys(pages)[0];
                    var extract = pages[pageId].extract;
                    if (extract) {
                        // Hapus pop-up lama kalau ada
                        $('.wiki-preview').remove();
                        var preview = $('<div class="wiki-preview" style="position:absolute; background:#fff; color:#202122; border:1px solid #a2a9b1; padding:12px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.2); z-index:10001; font-size:13px; max-width:250px; line-height:1.4; opacity:0; transition:opacity 0.3s ease;"></div>');
                        preview.text(extract);
                       
                        $('body').append(preview);
                        // Atur posisi pop-up di deket link
                        var offset = $link.offset();
                        preview.css({
                            top: offset.top + 25,
                            left: Math.min(offset.left, $(window).width() - 270),
                            opacity: 1
                        });
                        // Hilang kalau klik di mana aja atau setelah 5 detik
                        setTimeout(function() { $('.wiki-preview').fadeOut(function() { $(this).remove(); }); }, 5000);
                    }
                });
            }, 600); // Delay 0.6 detik biar gak ganggu kalau cuma scrolling lewat
        }).on('mouseleave', function() {
            clearTimeout(timer);
        });
        $(document).on('mousedown touchstart', function() {
            $('.wiki-preview').remove();
        });
    }
});
/* 3. Notifikasi Link Luar */
$(document).ready(function() {
    $('a.external').click(function(e) {
        var url = $(this).attr('href');
        if (!confirm('Anda akan meninggalkan Mippedia menuju situs luar:\n' + url + '\n\nLanjutkan?')) {
            e.preventDefault();
        }
    });
});


/* 3. Anti-Ghosting pada Link Kosong (Redlinks) */
/* 3. Anti-Ghosting pada Link Kosong (Redlinks) */
Baris 139: Baris 67:
         }
         }
     });
     });
});
/* 1. Navigasi Bab Melayang (Vertical Stack Edition) */
$(document).ready(function() {
    if (mw.config.get('wgIsArticle') && $('#toc').length) {
       
        // CSS untuk posisi menumpuk secara vertikal
        var $quickNav = $('<div id="quick-nav" style="position:fixed; bottom:20px; right:20px; width:45px; height:45px; background:#36c; color:#fff; border-radius:50%; display:flex; align-items:center; justify-content:center; z-index:9996; box-shadow:0 4px 12px rgba(0,0,0,0.2); cursor:pointer; font-size:20px; transition: all 0.3s ease;">≡</div>');
       
        // Tombol Back to Top lo biasanya di bottom: 80px atau 90px kan?
        // Kita paksa Back to Top naik sedikit, dan navigasi bab ada di bawahnya.
        // Script ini bakal otomatis menyesuaikan posisi tombol panah atas lo.
       
        $('body').append($quickNav);
        // Menyesuaikan posisi tombol Back to Top bawaan (jika ada) biar gak tabrakan
        // Kita set navigasi di bottom 20px, dan Back to Top di bottom 80px
        $('.back-to-top, #mw-mf-back-to-top').css('bottom', '85px');
        $quickNav.click(function() {
            var $toc = $('#toc ul').first().clone();
            var $modal = $('<div id="nav-modal" style="position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); z-index:20001; display:flex; align-items:flex-end; justify-content:center; backdrop-filter:blur(5px); opacity:0; transition:opacity 0.3s ease;">' +
                '<div id="nav-card" style="background:#fff; width:100%; max-height:75%; overflow-y:auto; border-top-left-radius:30px; border-top-right-radius:30px; padding:25px; transform:translateY(100%); transition:transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);">' +
                '<div style="width:50px; height:5px; background:#eee; border-radius:10px; margin:0 auto 20px;"></div>' +
                '<h3 style="margin-top:0; color:#36c; font-size:1.3em; text-align:center;">Daftar Isi</h3>' +
                '<div id="nav-list" style="margin-top:10px;"></div>' +
                '</div></div>');
           
            $('body').append($modal);
            $modal.find('#nav-list').append($toc);
           
            setTimeout(function() {
                $modal.css('opacity', '1');
                $modal.find('#nav-card').css('transform', 'translateY(0)');
            }, 10);
            // Styling link agar terasa seperti menu aplikasi
            $modal.find('a').css({
                'display':'block',
                'padding':'15px 10px',
                'color':'#333',
                'text-decoration':'none',
                'border-bottom':'1px solid #f9f9f9',
                'font-size':'1.1em'
            });
            function closeModal() {
                $modal.find('#nav-card').css('transform', 'translateY(100%)');
                $modal.css('opacity', '0');
                setTimeout(function() { $modal.remove(); }, 400);
            }
            $modal.on('click', function(e) { if(e.target === this) closeModal(); });
        });
    }
});
/* 2. Auto-Night Shift (Berdasarkan Jam Lokal) */
$(document).ready(function() {
    var hour = new Date().getHours();
    if (hour >= 21 || hour < 6) { // Jam 9 malem sampe 6 pagi
        $("<style id='night-shift'>").prop("type", "text/css").html(`
            body::after {
                content: "";
                position: fixed;
                top: 0; left: 0;
                width: 100vw; height: 100vh;
                background: rgba(255, 165, 0, 0.05); /* Filter orange tipis */
                pointer-events: none;
                z-index: 99999;
            }
        `).appendTo("head");
    }
});
/* 3. Smooth Fade-In saat Ganti Halaman */
$(document).ready(function() {
    $('body').css({'opacity': '0', 'transition': 'opacity 0.5s ease'});
    setTimeout(function() { $('body').css('opacity', '1'); }, 100);
});
/* 2. Auto-Source on Copy (Kredit Otomatis) */
document.addEventListener('copy', function(e) {
    var selection = window.getSelection();
    if (selection.toString().length > 1) { // Hanya aktif kalau copy lebih dari 50 karakter
        var body_element = document.getElementsByTagName('body')[0];
        var newdiv = document.createElement('div');
        newdiv.style.position = 'absolute';
        newdiv.style.left = '-99999px';
        body_element.appendChild(newdiv);
        newdiv.innerHTML = selection + '<br /><br />Sumber: ' + document.title + '<br />Link: ' + window.location.href;
        selection.selectAllChildren(newdiv);
        window.setTimeout(function() {
            body_element.removeChild(newdiv);
        }, 0);
    }
});
/* ==========================================================
  🚀 MIPPEDIA DATA INTEGRATION (Global Version)
  Berfungsi untuk: User Login & Anonim
  Posisi: Di bawah Estimasi Waktu Baca (Header)
  ========================================================== */
$(document).ready(function() {
    function injectMippediaData() {
        // 1. Cari template asli
        var $dataTemplate = $('.mw-parser-output div:contains("Mippedia Data")').first();
        var dataUrl = $dataTemplate.find('a').attr('href');
        // 2. Jika ketemu dan belum pernah di-inject sebelumnya
        if ($dataTemplate.length && dataUrl && $('#mippedia-data-btn').length === 0) {
           
            // Buat tombol bergaya metadata yang premium
            var $newBtn = $(`
                <div id="mippedia-data-btn" style="margin: 10px 0; display: inline-block;">
                    <a href="${dataUrl}" target="_blank" style="text-decoration: none !important;">
                        <div style="display: flex; align-items: center; background: #36c; color: #fff; padding: 6px 12px; border-radius: 8px; font-family: sans-serif; box-shadow: 0 4px 10px rgba(54,102,204,0.25);">
                            <span style="font-size: 14px; margin-right: 8px;"></span>
                            <span style="font-size: 11px; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase;">Lihat di Mippedia Data</span>
                        </div>
                    </a>
                </div>
            `);
            // 3. PENEMPATAN POSISI (Target: Di bawah estimasi waktu baca)
            var $targetHeader = $('.tagline, .minerva__subtitle, .estimasi-baca-container');
           
            if ($targetHeader.length) {
                // Taruh tepat di bawah estimasi waktu baca atau subtitle
                $targetHeader.last().after($newBtn);
                // Hapus template lama dari dalam artikel agar tidak dobel
                $dataTemplate.hide();
            } else {
                // Fallback: Jika header tidak ketemu, taruh di bawah judul utama
                $('#firstHeading').after($newBtn);
                $dataTemplate.hide();
            }
        }
    }
    // Jalankan segera dan ulangi sekali lagi untuk memastikan render mobile selesai
    injectMippediaData();
    setTimeout(injectMippediaData, 1500);
});
/* Smart Random Toaster Mippedia (Fixed: Article & Main Page Only) */
$(document).ready(function() {
    var ns = mw.config.get('wgNamespaceNumber');
    var action = mw.config.get('wgAction');
    var isMainPage = mw.config.get('wgIsMainPage');
    var isDiff = mw.config.get('wgDiffOldId') !== null;
    // VALIDASI: Cuma di Artikel (NS 0), Halaman Utama, dan saat 'View' saja
    if ((ns === 0 || isMainPage) && action === 'view' && !isDiff) {
       
        var mippediaDatabase = [
            // KATEGORI: FAKTA UNIK (💡)
            { type: "💡 FAKTA UNIK", text: "Mippedia adalah proyek ensiklopedia mandiri yang berfokus pada sejarah, musik, dan teknologi." },
            { type: "💡 FAKTA UNIK", text: "Rumi Haitami, pendiri Mippedia, adalah musisi dan pengusaha muda asal Indonesia." },
            { type: "💡 FAKTA UNIK", text: "Nama 'Mippedia' merepresentasikan identitas kolektif dari Mippedia Community." },
            { type: "💡 FAKTA UNIK", text: "Mippedia tidak berafiliasi dengan Wikimedia Foundation dan mengelola server secara mandiri." },
            { type: "💡 FAKTA UNIK", text: "Sugar Store Id merupakan bagian dari ekosistem bisnis yang dikembangkan pendiri Mippedia." },
            { type: "💡 FAKTA UNIK", text: "Mippedia memiliki ribuan item data yang terhubung melalui sistem Mippedia Data." },
            { type: "💡 FAKTA UNIK", text: "Proyek ini dimulai dengan visi untuk mendokumentasikan pengetahuan secara profesional dan bebas." },
            { type: "💡 FAKTA UNIK", text: "Logo Mippedia melambangkan integrasi ilmu pengetahuan global dan lokal." },
            { type: "💡 FAKTA UNIK", text: "Mippedia Community terdiri dari kontributor yang ahli di bidang teknologi dan dokumentasi digital." },
            { type: "💡 FAKTA UNIK", text: "Selain ensiklopedia, ekosistem Mippedia juga mencakup label rekaman musik." },
            { type: "💡 FAKTA UNIK", text: "Mippedia mendukung standarisasi Wikidata untuk sinkronisasi informasi tokoh." },
            { type: "💡 FAKTA UNIK", text: "Setiap artikel di sini melewati proses kurasi oleh tim administrator Mippedia." },
            { type: "💡 FAKTA UNIK", text: "Sistem pencarian Mippedia dirancang untuk menemukan artikel dalam hitungan milidetik." },
            { type: "💡 FAKTA UNIK", text: "Mippedia menggunakan platform MediaWiki yang telah dimodifikasi secara ekstrim untuk kenyamanan pengguna." },
            { type: "💡 FAKTA UNIK", text: "Warna biru pada tema Mippedia melambangkan kepercayaan, profesionalisme, dan teknologi." },
            { type: "💡 FAKTA UNIK", text: "Mippedia adalah salah satu proyek wiki independen terbesar yang dikelola oleh komunitas lokal." },
            { type: "💡 FAKTA UNIK", text: "Konten musik di Mippedia mencakup diskografi lengkap dari artis-artis di bawah label Mippedia." },
            { type: "💡 FAKTA UNIK", text: "Mippedia menyediakan portal khusus bagi administrator untuk mengelola sistem secara real-time." },
            { type: "💡 FAKTA UNIK", text: "Data kelahiran dan riwayat tokoh di Mippedia diambil dari sumber primer yang tervalidasi." },
            { type: "💡 FAKTA UNIK", text: "Mippedia sering melakukan pembaruan sistem pesan sistem untuk menjaga keamanan komunitas." },
            { type: "💡 FAKTA UNIK", text: "User interface Mippedia dioptimasi agar ramah bagi pengguna perangkat mobile." },
            { type: "💡 FAKTA UNIK", text: "Mippedia memiliki kebijakan privasi yang ketat untuk melindungi data setiap pembacanya." },
            { type: "💡 FAKTA UNIK", text: "Sistem 'Dengarkan Artikel' di Mippedia menggunakan teknologi sintesis suara yang jernih." },
            { type: "💡 FAKTA UNIK", text: "Mippedia secara aktif mengarsipkan dokumen sejarah yang jarang ditemukan di tempat lain." },
            { type: "💡 FAKTA UNIK", text: "Setiap gambar yang diunggah ke Mippedia disimpan dalam repositori lokal yang aman." },
            // KATEGORI: INFORMASI (ℹ️)
            { type: "ℹ️ INFORMASI", text: "Anda dapat mendengarkan isi artikel ini dengan mengklik ikon 🔊 di bagian atas halaman." },
            { type: "ℹ️ INFORMASI", text: "Klik ikon ≡ di pojok kanan bawah untuk melihat daftar isi dan melompat antar bagian." },
            { type: "ℹ️ INFORMASI", text: "Gunakan fitur 'Back to Top' (ikon panah) untuk kembali ke atas halaman dengan cepat." },
            { type: "ℹ️ INFORMASI", text: "Artikel ini terakhir diperbarui sesuai dengan log aktivitas Mippedia Community." },
            { type: "ℹ️ INFORMASI", text: "Anda bisa membagikan artikel ini melalui tombol share yang tersedia di akhir tulisan." },
            { type: "ℹ️ INFORMASI", text: "Mippedia Data menyediakan basis data teknis yang terhubung dengan artikel ini." },
            { type: "ℹ️ INFORMASI", text: "Aktifkan Mode Malam pada browser Anda untuk pengalaman membaca yang lebih nyaman di Mippedia." },
            { type: "ℹ️ INFORMASI", text: "Seluruh konten di sini dilindungi oleh lisensi Creative Commons BY-SA 4.0." },
            { type: "ℹ️ INFORMASI", text: "Untuk bantuan teknis atau laporan bug, silakan hubungi tim administrator Mippedia." },
            { type: "ℹ️ INFORMASI", text: "Anda bisa melihat estimasi waktu baca artikel tepat di bawah judul halaman." },
            { type: "ℹ️ INFORMASI", text: "Mippedia menyediakan fitur pencarian pintar di header untuk menemukan topik terkait." },
            { type: "ℹ️ INFORMASI", text: "Pastikan Anda melihat bagian 'Referensi' untuk memverifikasi keaslian data artikel." },
            { type: "ℹ️ INFORMASI", text: "Pendaftaran kontributor Mippedia Community dibuka secara berkala melalui pengumuman resmi." },
            { type: "ℹ️ INFORMASI", text: "Sistem Mippedia secara otomatis mendeteksi perangkat Anda untuk memberikan tampilan terbaik." },
            { type: "ℹ️ INFORMASI", text: "Ikon DATA di sebelah tab Pembicaraan akan mengarahkan Anda ke metadata lengkap tokoh tersebut." },
            { type: "ℹ️ INFORMASI", text: "Mippedia menjaga integritas data dengan sistem proteksi halaman dari suntingan anonim berbahaya." },
            { type: "ℹ️ INFORMASI", text: "Anda bisa mengunduh artikel Mippedia dalam format PDF melalui menu aksi di pojok kanan." },
            { type: "ℹ️ INFORMASI", text: "Jaringan Mippedia mencakup berbagai subdomain untuk proyek bahasa yang berbeda." },
            { type: "ℹ️ INFORMASI", text: "Gunakan fitur seleksi teks untuk mencari istilah yang tidak Anda mengerti di dalam Mippedia." },
            { type: "ℹ️ INFORMASI", text: "Pesan toast ini hanya muncul sekali per sesi halaman untuk kenyamanan membaca Anda." },
            { type: "ℹ️ INFORMASI", text: "Mippedia Community berkomitmen menjaga netralitas informasi di setiap artikel sejarah." },
            { type: "ℹ️ INFORMASI", text: "Pembaruan basis data Mippedia dilakukan setiap hari untuk memastikan akurasi informasi." },
            { type: "ℹ️ INFORMASI", text: "Anda dapat melihat riwayat penyuntingan artikel melalui tab 'History' di menu navigasi." },
            { type: "ℹ️ INFORMASI", text: "Mippedia mendukung integrasi media kaya seperti audio dan video berkualitas tinggi." },
            { type: "ℹ️ INFORMASI", text: "Terima kasih telah menjadi bagian dari pembaca setia Mippedia Community!" }
        ];
        var randomItem = mippediaDatabase[Math.floor(Math.random() * mippediaDatabase.length)];
       
        setTimeout(function() {
            if ($('input:focus, textarea:focus').length > 0) return;
            var $toaster = $('<div id="smart-toaster" style="position:fixed; top:25px; left:20px; right:20px; background:rgba(255,255,255,0.98); border-left:5px solid #36c; color:#333; padding:15px; border-radius:12px; z-index:11000; box-shadow:0 10px 30px rgba(0,0,0,0.15); backdrop-filter:blur(10px); display:none; font-family:sans-serif;">' +
                '<div style="color:#36c; font-weight:bold; font-size:11px; margin-bottom:5px; text-transform:uppercase; letter-spacing:1px;">' + randomItem.type + '</div>' +
                '<div style="font-size:13px; line-height:1.4; color:#444;">' + randomItem.text + '</div>' +
                '</div>');
           
            $('body').append($toaster);
            $toaster.slideDown(500).delay(7000).slideUp(500, function() { $(this).remove(); });
        }, 5000);
    }
});
});


Baris 375: Baris 78:
     // Tambah atau hapus di dalam kurung siku ini. Gunakan koma sebagai pemisah.
     // Tambah atau hapus di dalam kurung siku ini. Gunakan koma sebagai pemisah.
     var protectedPages = [
     var protectedPages = [
         "MediaWiki:",  
         "MediaWiki:Common.js",
         "Mippedia:Privasi",
         "Istimewa:Versi"
        "Mippedia:Kebijakan",
        "Spesial:Versi",
        "Mippedia:Ketentuan_penggunaan"
     ];
     ];


Baris 481: Baris 181:
         // Ubah judul tab browser
         // Ubah judul tab browser
         document.title = "Akses Dilindungi - Mippedia bahasa Indonesia, ensiklopedia umum";
         document.title = "Akses Dilindungi - Mippedia bahasa Indonesia, ensiklopedia umum";
    }
});
/* ==========================================================
  🛡️ MIPPEDIA FILE VERIFICATION SYSTEM v3.1 (PRECISION)
  Fix: Kotak lebih ramping & Ikon lebih proporsional
  ========================================================== */
$(document).ready(function() {
    if (mw.config.get('wgNamespaceNumber') === 6) {
       
        var $content = $('#mw-content-text');
        var pageText = $content.text();
        var badgeTitle = "";
        var badgeStyle = "";
        if (pageText.includes("Aset Resmi")) {
            badgeTitle = "ASET RESMI";
            badgeStyle = "border: 1px solid #36c; background: #f0f7ff;";
        } else if (pageText.includes("Terverifikasi")) {
            badgeTitle = "TERVERIFIKASI";
            badgeStyle = "border: 1px solid #00af89; background: #e6fffb;";
        }
        if (badgeTitle !== "") {
            // Ukuran gambar dinaikin ke 24px biar lebih jelas centangnya
            var fileName = "Verified_Badge.png";
           
            new mw.Api().parse('[[Berkas:' + fileName + '|24px|link=]]')
                .done(function(renderedImage) {
                    var badgeHTML = `
                        <div id="mippedia-sleek-badge" style="display: inline-flex; align-items: center; border-radius: 8px; padding: 2px 8px; margin: 5px 0 12px 0; height: 32px; box-sizing: border-box; font-family: sans-serif; vertical-align: middle; ${badgeStyle}">
                            <div style="margin-right: 6px; display: flex; align-items: center; justify-content: center; width: 24px;">${renderedImage}</div>
                            <span style="font-weight: 800; font-size: 11px; letter-spacing: 0.5px; color: #1a1a1a; text-transform: uppercase; white-space: nowrap; line-height: 1;">${badgeTitle}</span>
                        </div>
                    `;
                    $('#firstHeading').after(badgeHTML);
                    $('.mippedia-hidden-key').hide();
                });
            $content.find(':contains("Aset Resmi"), :contains("Terverifikasi")').each(function() {
                var $this = $(this);
                if ($this.children().length === 0 && ($this.text().trim() === "Aset Resmi" || $this.text().trim() === "Terverifikasi")) {
                    $this.addClass('mippedia-hidden-key').css('display', 'none');
                }
            });
        }
     }
     }
});
});
Baris 1.165: Baris 818:


/* ==========================================================
/* ==========================================================
   🔍 MIPPEDIA SYSTEM - INDEPENDENT BOT (TEST: RUDOL)
   🛡️ MIPPEDIA CORE SYSTEM - NEURAL ENGINE V12
  Update: Brain Upgrade - Semantic Search & Anti-Duplicate
  Semua fitur asli (Patroli, Promo, Kategori) tetap UTUH.
   ========================================================== */
   ========================================================== */
mw.hook('postEdit').add(function() {
mw.hook('postEdit').add(function() {
    var rawUser = mw.config.get('wgUserName');
    var userName = rawUser ? rawUser.replace(/_/g, ' ') : 'Anonim';
    var isPatroli = (userName === 'Mippedia Patroli');
   
     if (mw.config.get('wgNamespaceNumber') !== 0) return;
     if (mw.config.get('wgNamespaceNumber') !== 0) return;


     var api = new mw.Api();
     var api = new mw.Api();
     var pageTitle = mw.config.get('wgPageName');
     var pageTitle = mw.config.get('wgPageName').replace(/_/g, ' ');
   
    // KREDENSIAL BOT
    var botUser = 'Rudol@Rudol';
    var botPass = '3prf56v7uuic2hn0b7jh3cvbkdtn6k1g';  


     api.get({
     api.get({
         action: 'query',
         action: 'query',
         titles: pageTitle,
         titles: pageTitle,
         prop: 'categories|revisions',
         prop: 'revisions|categories|links',
         rvprop: 'content',
         rvprop: 'content',
         clshow: '!hidden'
         clshow: '!hidden',
     }).done(function(data) {
        pllimit: 'max'
         var page = data.query.pages[Object.keys(data.query.pages)[0]];
     }).done(function(resData) {
         var content = page.revisions[0]['*'];
         var page = resData.query.pages[Object.keys(resData.query.pages)[0]];
         if (!page || !page.revisions) return;
 
        var rawContent = page.revisions[0]['*'];
        var content = rawContent;
        var summaryParts = [];
 
        // --- 1. GLOBAL ENGINE: MAINTENANCE (FITUR ASLI) ---
        if ((!page.categories || page.categories.length === 0) && !/\{\{Butuh Kategori/i.test(content) && !/\[\[Kategori:/i.test(content)) {
            content = '{{Butuh Kategori|date=April 2026}}\n' + content;
            summaryParts.push('+Cat');
        }
       
        // --- UPGRADE ENGINE: DETEKSI SMART STUB PARAMETER & POSISI BAWAH ---
        var wordCount = rawContent.trim().split(/\s+/).length;
        if (wordCount < 200 && !/\{\{Stub/i.test(content) && !/\{\{Artikel Rintisan/i.test(content)) {
            var lowerContent = rawContent.toLowerCase();
            var stubParam = '';
 
            // Mapping Otak Pintar berdasarkan Kata Kunci Semantik (19 Parameter)
            if (/\b(lahir|wafat|tokoh|pria|wanita|biografi|sosok|pahlawan|presiden|menteri)\b/i.test(lowerContent)) {
                stubParam = 'biografi tokoh';
            } else if (/\b(musik|lagu|album|konser|penyanyi|band|vokal|gitar|single|nada)\b/i.test(lowerContent)) {
                stubParam = 'musik';
            } else if (/\b(geografi|negara|kota|desa|kecamatan|kabupaten|provinsi|pulau|gunung|sungai)\b/i.test(lowerContent)) {
                stubParam = 'geografi';
            } else if (/\b(teknologi|komputer|aplikasi|software|hardware|internet|digital|android|sistem|gawai)\b/i.test(lowerContent)) {
                stubParam = 'teknologi';
            } else if (/\b(sejarah|kerajaan|perang|prasasti|arkeo|masa lalu|kuno|dinasti|peristiwa|abad)\b/i.test(lowerContent)) {
                stubParam = 'sejarah';
            } else if (/\b(olahraga|atlet|sepak|bola|stadion|juara|klub|tanding|liga|olimpiade)\b/i.test(lowerContent)) {
                stubParam = 'olahraga';
            } else if (/\b(film|bioskop|aktor|aktris|sutradara|drama|sinema|serial|movie|tayang)\b/i.test(lowerContent)) {
                stubParam = 'film';
            } else if (/\b(perusahaan|pt|perbangkan|bisnis|saham|industri|korporasi|merek|ceo|didirikan)\b/i.test(lowerContent)) {
                stubParam = 'perusahaan';
            } else if (/\b(ilmu pengetahuan|sains|kimia|fisika|matematika|biologi|riset|laboratorium|teori|molekul)\b/i.test(lowerContent)) {
                stubParam = 'ilmu pengetahuan';
            } else if (/\b(seni|lukisan|patung|pameran|budaya|teater|rupa|desain|kriya|estetika)\b/i.test(lowerContent)) {
                stubParam = 'seni';
            } else if (/\b(politik|partai|pemilu|dpr|pemerintah|kebijakan|demokrasi|suara|kampanye|negara)\b/i.test(lowerContent)) {
                stubParam = 'politik';
            } else if (/\b(militer|tni|tentara|perang|senjata|pasukan|jenderal|alutsista|batalyon|operasi)\b/i.test(lowerContent)) {
                stubParam = 'militer';
            } else if (/\b(transportasi|kereta|pesawat|mobil|kapal|bandara|stasiun|pelabuhan|rute|kendaraan)\b/i.test(lowerContent)) {
                stubParam = 'transportasi';
            } else if (/\b(literatur|buku|novel|puisi|sastra|penulis|penerbit|komik|cerpen|fiksi)\b/i.test(lowerContent)) {
                stubParam = 'literatur';
            } else if (/\b(makanan|kuliner|resep|masakan|minuman|rasa|koki|restoran|hidangan|bahan)\b/i.test(lowerContent)) {
                stubParam = 'makanan';
            } else if (/\b(kesehatan|medis|dokter|penyakit|obat|rumah sakit|klinik|terapi|virus|gejala)\b/i.test(lowerContent)) {
                stubParam = 'kesehatan';
            } else if (/\b(astronomi|bintang|planet|galaksi|teleskop|antariksa|nasa|komet|orbit|luar angkasa)\b/i.test(lowerContent)) {
                stubParam = 'astronomi';
            } else if (/\b(agama|ibadah|kitab|tuhan|nabi|gereja|masjid|pura|vihara|iman)\b/i.test(lowerContent)) {
                stubParam = 'agama';
            } else if (/\b(bahasa|dialek|aksara|kamus|linguistik|kata|kalimat|suku|ucapan|fonem)\b/i.test(lowerContent)) {
                stubParam = 'bahasa';
            } else if (/\b(hukum|undang|pasal|pengadilan|hakim|jaksa|pengacara|pidana|perdata|legal)\b/i.test(lowerContent)) {
                stubParam = 'hukum';
            }
 
            // Gabungkan teks template Stub pilihan di baris paling bawah artikel
            var stubTag = stubParam ? '{{Stub|' + stubParam + '}}' : '{{Stub}}';
            content = content.trim() + '\n\n' + stubTag;
            summaryParts.push('+SmartStub(' + (stubParam || 'umum') + ')');
        }
 
        var promoList = ['memang hebat', 'terpercaya sekali', 'terbaik di dunia', 'hubungi nomor kami', 'harga murah', 'kualitas terjamin'];
        if (promoList.some(p => rawContent.toLowerCase().indexOf(p) !== -1) && !/\{\{Hapus/i.test(content)) {
            content = '{{Hapus|Deteksi kalimat promosi otomatis}}\n' + content;
            summaryParts.push('+Promo');
        }
 
        // --- 2. SUPER INTELLIGENCE RELATED (UPGRADE OTAK V12) ---
        var currentRelatedMatch = content.match(/\{\{#related:.*?\}\}/g) || [];
       
        if (currentRelatedMatch.length < 3) {
            content = content.replace(/\n*\{\{#related:.*?\}\}/g, '');
 
            api.get({
                action: 'query',
                list: 'search',
                srsearch: pageTitle,
                srlimit: 15,
                srprop: ''
            }).done(function(searchRes) {
                var candidates = {};
 
                if (searchRes.query && searchRes.query.search) {
                    searchRes.query.search.forEach(function(item, index) {
                        if (item.title === pageTitle) return;
                        candidates[item.title] = (15 - index);
                    });
                }
 
                if (page.links) {
                    page.links.forEach(function(link) {
                        if (link.title === pageTitle) return;
                        candidates[link.title] = (candidates[link.title] || 0) + 5;
                    });
                }
 
                var sortedTitles = Object.keys(candidates).sort(function(a, b) {
                    return candidates[b] - candidates[a];
                });
 
                var finalRelated = sortedTitles.filter(t => t.indexOf(':') === -1).slice(0, 3);
 
                if (finalRelated.length > 0) {
                    var relatedTags = '\n\n' + finalRelated.map(t => '{{#related: ' + t + '}}').join('\n');
                    content += relatedTags;
                    summaryParts.push('NeuralRelated');
                }
               
                runPatroliAndSave();
            });
        } else {
            runPatroliAndSave();
        }
 
        function runPatroliAndSave() {
            // --- 3. PATROLI ENGINE (FITUR ASLI - TETAP BERFUNGSI) ---
            if (isPatroli) {
                var placeholders = [];
                content = content.replace(/(\{\{[\s\S]*?\}\}|==+.*?==+|\[\[Kategori:.*?\]\]|<ref[\s\S]*?<\/ref>|^.*?adalah)/gi, function(match) {
                    placeholders.push(match);
                    return '___MIP_SKIP_' + (placeholders.length - 1) + '___';
                });
 
                api.get({ action: 'query', list: 'allpages', apnamespace: 0, aplimit: 'max' }).done(function(apData) {
                    var allTitles = apData.query.allpages.map(p => p.title);
                    var lowerTitles = allTitles.map(t => t.toLowerCase());
 
                    var tokens = content.split(/(\s+|\[\[|\]\])/);
                    var inLink = false;
                    for (var i = 0; i < tokens.length; i++) {
                        if (tokens[i] === '[[' ) { inLink = true; continue; }
                        if (tokens[i] === ']]' ) { inLink = false; continue; }
                        if (inLink || tokens[i].trim().length < 3 || tokens[i].includes('___MIP_SKIP_')) continue;
 
                        var wordsInToken = tokens[i].match(/\b\w+\b/g);
                        if (wordsInToken) {
                            wordsInToken.forEach(function(word) {
                                var idx = lowerTitles.indexOf(word.toLowerCase());
                                if (idx !== -1 && allTitles[idx] !== pageTitle) {
                                    tokens[i] = tokens[i].replace(new RegExp('\\b' + word + '\\b', 'g'), '[[' + allTitles[idx] + '|' + word + ']]');
                                }
                            });
                        }
                    }
                    content = tokens.join('');
                   
                    content = content.replace(/___MIP_SKIP_(\d+)___/g, function(match, id) { return placeholders[id]; });
 
                    content = content.replace(/\[\[([^|\]:]+)\]\]/g, function(match, p1) {
                        return lowerTitles.includes(p1.toLowerCase()) ? match : p1;
                    });
 
                    saveAction();
                });
            } else {
                saveAction();
            }
        }
 
        function saveAction() {
            // --- 4. EKSEKUSI ---
            if (content.trim() !== rawContent.trim()) {
                api.postWithToken('edit', {
                    action: 'edit',
                    title: pageTitle,
                    text: content,
                    summary: 'Mippedia Neural Engine V12: ' + summaryParts.join(', '),
                    bot: true, markasbot: true
                }).done(function() { location.reload(); });
            }
        }
    });
});
 
/* ==========================================================
  🚀 MIPPEDIA DATA BUTTON ONLY (Otomatis)
  Hanya memunculkan tombol jika data tersedia di pusat.
  ========================================================== */
$(document).ready(function() {
    var pageName = mw.config.get('wgPageName');
    var namespace = mw.config.get('wgNamespaceNumber');
    var dataDomain = 'https://data.mippedia.org';
 
    // Jalankan hanya di namespace artikel
    if (namespace === 0) {
        // Cek apakah halaman tersebut ada di Mippedia Data
        $.ajax({
            url: dataDomain + '/api.php',
            data: {
                action: 'query',
                titles: pageName,
                format: 'json',
                origin: '*'
            },
            dataType: 'jsonp',
            success: function(res) {
                var pages = res.query.pages;
                var isExist = false;
               
                // Cek apakah ID halaman > 0 (artinya halaman ada)
                for (var id in pages) {
                    if (parseInt(id) > 0) {
                        isExist = true;
                        break;
                    }
                }
 
                // Jika data ditemukan, munculkan tombol melayang
                if (isExist) {
                    injectFloatingDataBtn(pageName, dataDomain);
                }
            }
        });
    }
 
    function injectFloatingDataBtn(name, domain) {
        if ($('#mippedia-data-btn').length) return;
 
        var $btn = $('<a>', {
            id: 'mippedia-data-btn',
            href: domain + '/wiki/' + encodeURIComponent(name),
            target: '_blank',
            style: 'position: absolute; right: 10px; top: -32px; background: #36c; color: #fff; padding: 4px 10px; border-radius: 4px; font-weight: bold; font-size: 10px; text-decoration: none; z-index: 1000; box-shadow: 0 2px 4px rgba(0,0,0,0.1);',
            text: 'DATA'
        });
 
        // Target: Area menu aksi (dekat ikon pensil)
        // Mendukung skin Mobile (Minerva) dan Desktop
        var $target = $('.page-actions-menu, .mw-editsection-visualeditor, #ca-edit, .minerva__tab-container').first();
       
        if ($target.length) {
            $target.css('position', 'relative').append($btn);
        } else {
            // Fallback jika header tidak standar
            $('#firstHeading').css('position', 'relative').append($btn);
        }
    }
});
 
/* ==========================================================
  🚀 MIPPEDIA COMMAND CENTER: AUTO-SYNC ENGINE (V4)
  Status: Global Login User | Auto-Purge | High Reliability
  ========================================================== */
(function($, mw) {
    "use strict";
 
    var conf = mw.config.get(['wgNamespaceNumber', 'wgAction', 'wgPageName', 'wgIsMainPage', 'wgUserName']);
    // Filter: Hanya artikel, hanya saat baca, hanya user yang sudah login
    if (conf.wgNamespaceNumber !== 0 || conf.wgAction !== 'view' || conf.wgIsMainPage || conf.wgUserName === null) return;
 
    $(document).ready(function() {
        var currentTitle = conf.wgPageName;
        // Penentuan subdomain (id, en, concise)
        var hostParts = window.location.hostname.split('.');
        var langKey = hostParts[0] === 'mippedia' || hostParts[0] === 'www' ? 'id' : hostParts[0];
 
        $.ajax({
            url: 'https://data.mippedia.org/api.php',
            data: {
                action: 'query',
                prop: 'revisions',
                titles: 'MediaWiki:ShortDesc-Data.json',
                rvprop: 'content',
                format: 'json',
                origin: '*'
            },
            dataType: 'jsonp',
            success: function(res) {
                try {
                    var pages = res.query.pages;
                    var pageId = Object.keys(pages)[0];
                    if (pageId === "-1") return;
 
                    var fullData = JSON.parse(pages[pageId].revisions[0]['*']);
                    var targetDesc = (fullData[currentTitle] && fullData[currentTitle][langKey]) ? fullData[currentTitle][langKey].trim() : "";
 
                    syncMetadata(currentTitle, targetDesc);
                } catch (e) {
                    console.log("Mippedia System: Data sync not required or entry missing.");
                }
            }
        });
 
        function syncMetadata(title, dataCenterDesc) {
            var api = new mw.Api();
            api.get({
                action: 'query',
                prop: 'revisions',
                titles: title,
                rvprop: 'content',
                formatversion: 2
            }).done(function(data) {
                var content = data.query.pages[0].revisions[0].content;
                var shortDescPattern = /\{\{SHORTDESC:.*?\}\}\n?/gi;
                var hasLocalDesc = shortDescPattern.test(content);
               
                var localMatch = content.match(/\{\{SHORTDESC:(.*?)\}\}/i);
                var currentLocalDesc = localMatch ? localMatch[1].trim() : "";


        // Cek apakah kategori kosong & belum ada template-nya
                // AKSI 1: HAPUS (Jika di pusat kosong/dihapus, tapi di artikel lokal masih ada)
        if ((!page.categories || page.categories.length === 0) &&
                if (dataCenterDesc === "" && hasLocalDesc) {
            content.indexOf('{{Tanpa kategori') === -1) {
                    console.log("Mippedia: Purging metadata...");
           
                    saveEdit(title, content.replace(shortDescPattern, ""), "Purge out-of-sync metadata");
            var newContent = '{{Tanpa kategori|date=April 2026}}\n' + content;
                }
                // AKSI 2: UPDATE/TAMBAH (Jika data di pusat ada dan beda dengan lokal)
                else if (dataCenterDesc !== "" && dataCenterDesc !== currentLocalDesc) {
                    console.log("Mippedia: Syncing with Data Center...");
                    var cleanedContent = content.replace(shortDescPattern, "");
                    // Menaruh di paling atas agar terbaca Extension ShortDescription
                    var newContent = '{{SHORTDESC:' + dataCenterDesc + '}}\n' + cleanedContent;
                    saveEdit(title, newContent, "Sync metadata: " + dataCenterDesc);
                }
            });
        }


             // PROSES EDIT: Langsung tembak dengan identitas bot
        function saveEdit(title, text, summary) {
             api.postWithToken('edit', {
             // Menggunakan token user yang sedang login saat ini
             new mw.Api().postWithEditToken({
                 action: 'edit',
                 action: 'edit',
                 title: pageTitle,
                 title: title,
                 text: newContent,
                 text: text,
                 summary: 'Bot: Menandai artikel tanpa kategori',
                 summary: '🤖 ' + summary,
                 bot: true, // Menandai sebagai suntingan bot
                 minor: true // Menandai sebagai suntingan kecil
                 markasbot: true,
                 // Parameter 'bot: true' DIHAPUS agar bisa dijalankan semua pengguna login
                watchlist: 'nochange'
             }).done(function() {
             }).done(function() {
                 console.log('Kategori berhasil dicek oleh sistem.');
                 console.log("Mippedia: " + title + " synced successfully.");
             });
             });
        }
    });
})(jQuery, mediaWiki);
/* ==========================================================
  🚀 MIPPEDIA METADATA GUARD - RADAR SYSTEM (V5)
  Status: Professional Messaging | Hybrid Mobile/Desktop
  ========================================================== */
(function($, mw) {
    "use strict";
    var ns = mw.config.get('wgNamespaceNumber');
    if (ns !== 0 || mw.config.get('wgIsMainPage')) return;
    var shortDescRegex = /\{\{SHORTDESC:.*?\}\}/gi;
    var originalShortDesc = null;
    function validateAndBlock(e) {
        var $textbox = $('#wpTextbox1, textarea.previewable-render, .editor-container textarea, textarea[name="wpTextbox1"]');
        if (!$textbox.length) return true;
        var currentContent = $textbox.val() || "";
        var currentMatch = currentContent.match(shortDescRegex);
        var currentShortDesc = currentMatch ? currentMatch[0] : "";
        if (originalShortDesc === null) {
            originalShortDesc = currentShortDesc;
            return true;
        }
        if (originalShortDesc !== currentShortDesc) {
            // --- PESAN PROFESIONAL BARU ---
            window.alert(
                "MIPPEDIA SYSTEM NOTIFICATION\n" +
                "────────────────────────────\n\n" +
                "Suntingan anda tidak bisa di lanjutkan untuk di terbitkan, Karena sinkronisasi otomatis terdeteksi tidak valid.\n\n" +
                "Untuk menjaga integritas metadata, deskripsi singkat (ShortDescription) wajib dikelola melalui repositori Mippedia Data.\n\n" +
                "Harap urungkan perubahan manual pada kode {{SHORTDESC}} untuk melanjutkan proses penyimpanan."
            );
           
            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
            return false;
        }
        return true;
    }
    // Radar untuk menangkap elemen editor saat muncul (terutama di Mobile)
    var observer = new MutationObserver(function() {
        var $textbox = $('#wpTextbox1, .editor-container textarea, textarea[name="wpTextbox1"]');
        if ($textbox.length && originalShortDesc === null) {
            var content = $textbox.val() || "";
            var match = content.match(shortDescRegex);
            originalShortDesc = match ? match[0] : "";
        }
    });
    observer.observe(document.body, { childList: true, subtree: true });
    // Event listener untuk tombol simpan di berbagai platform
    $(document).on('click mousedown touchstart',
        '#wpSave, .mw-ui-button.primary, button.submit, .editor-save, .save-button, button[type="submit"]',
        function(e) {
            return validateAndBlock(e);
        }
    );
    window.addEventListener('submit', function(e) {
        if (!validateAndBlock(e)) e.preventDefault();
    }, true);
})(jQuery, mediaWiki);
$(function() {
    $('.ambox-learn-more').on('click', function(e) {
        e.preventDefault();
        var $parentBox = $(this).closest('.ambox');
       
        $parentBox.toggleClass('ambox-active');
        $parentBox.find('.ambox-text-long').slideToggle('fast');
       
        // Ubah teks tombol pas dibuka
        if ($parentBox.hasClass('ambox-active')) {
            $(this).text('Sembunyikan');
        } else {
            $(this).text('Pelajari selengkapnya');
         }
         }
     });
     });
});
});