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: Baris 1:
/**
/**
  * ====================================================================
  * ====================================================================
  * MIPPEDIA DATA - ADVANCED STRUCTURED DATA SYSTEM (V8.0 ULTIMATE PRO)
  * MIPPEDIA DATA - ADVANCED STRUCTURED DATA SYSTEM (V8.0 ULTIMATE)
  * Fitur Baru: Accordion References, Visit Site Button, Toast Notifs,
  * Fitur Utama: Collapsible References, Direct Visit Links, Toast UI,  
  * Auto-Save Drafts, Reorder Data (Up/Down), File Export/Import,  
  * Dark Mode Ready, Move Up/Down, Auto-Domain, 45+ Pro Features.
* 30+ Social Platforms, Glassmorphism UI, Mobile Perfect Animations.
  * ====================================================================
  * ====================================================================
  */
  */
Baris 21: Baris 20:
         var api = new mw.Api();
         var api = new mw.Api();


         // 1. DATA MASTER PLATFORM MEDIA SOSIAL & MUSIK (DITAMBAH BANYAK PLATFORM)
         // 1. DATA MASTER PLATFORM MEDIA SOSIAL & MUSIK (DIPERLUAS 20+ PLATFORM)
         var SOCIAL_PLATFORMS = {
         var SOCIAL_PLATFORMS = {
             applemusic: { name: 'Apple Music', base: 'https://music.apple.com/artist/', color: '#fc3c44', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm3.32 12.383c-.328.232-.82.418-1.32.418-1.238 0-1.922-.828-1.922-2.191v-4.14l4.312-.868v1.398l-2.91.586v2.805c0 .734.336 1.148.977 1.148.336 0 .617-.094.863-.258v1.102z"/></svg>' },
             applemusic: { name: 'Apple Music', base: 'https://music.apple.com/artist/', color: '#fc3c44', icon: '🎵' },
             spotify: { name: 'Spotify', base: 'https://open.spotify.com/artist/', color: '#1db954', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm4.586 14.424c-.18.295-.563.387-.857.207-2.35-1.434-5.308-1.758-8.793-.963-.335.077-.67-.133-.746-.468-.077-.334.132-.67.467-.745 3.816-.87 7.092-.493 9.72 1.112.294.18.386.563.209.857zm1.213-2.71c-.226.368-.703.483-1.07.258-2.688-1.652-6.785-2.13-9.965-1.164-.413.125-.85-.108-.975-.522-.125-.413.108-.85.522-.975 3.633-1.102 8.157-.568 11.23 1.332.368.226.483.703.258 1.071zm.14-2.827c-3.225-1.915-8.54-2.092-11.614-1.16-.503.153-1.037-.133-1.19-.636-.152-.503.133-1.037.636-1.19 3.532-1.072 9.404-.865 13.115 1.338.45.267.598.85.33 1.3-.267.45-.85.598-1.3.33z"/></svg>' },
             spotify: { name: 'Spotify', base: 'https://open.spotify.com/artist/', color: '#1db954', icon: '🎧' },
             soundcloud: { name: 'SoundCloud', base: 'https://soundcloud.com/', color: '#ff5500', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M1.175 12.225c-.062 0-.115.053-.115.116v4.636c0 .062.053.115.115.115h.411c.063 0 .116-.053.116-.115v-4.636c0-.063-.053-.116-.116-.116h-.411zm1.312-1.28c-.062 0-.115.052-.115.115v6.52c0 .063.053.115.115.115h.43c.062 0 .115-.052.115-.115v-6.52c0-.063-.053-.115-.115-.115h-.43zm1.33-1.258c-.063 0-.115.052-.115.115v8.322c0 .063.052.115.115.115h.43c.063 0 .115-.052.115-.115V9.802c0-.063-.052-.115-.115-.115h-.43zm1.33-.86c-.063 0-.115.053-.115.116v9.542c0 .063.052.115.115.115h.43c.063 0 .115-.052.115-.115V8.942c0-.063-.052-.116-.115-.116h-.43zm21.43 3.652c-.413 0-.802.08-1.157.228-.312-2.73-2.613-4.858-5.422-4.858-1.08 0-2.083.315-2.928.858-.2-.702-.592-1.332-1.12-1.826-.78-.727-1.812-1.13-2.882-1.13-.815 0-1.6.236-2.272.684v10.822c0 .063.052.115.115.115h15.666c1.666 0 3.018-1.352 3.018-3.018 0-1.666-1.352-3.018-3.018-3.018z"/></svg>' },
             soundcloud: { name: 'SoundCloud', base: 'https://soundcloud.com/', color: '#ff5500', icon: '☁️' },
             tidal: { name: 'Tidal', base: 'https://tidal.com/browse/artist/', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 4l4 4-4 4-4-4 4-4zm0 8l4 4-4 4-4-4 4-4zm8-8l4 4-4 4-4-4 4-4z"/></svg>' },
             bandcamp: { name: 'Bandcamp', base: 'https://bandcamp.com/', color: '#1da0c3', icon: '🎸' },
             youtube: { name: 'YouTube', base: 'https://youtube.com/@', color: '#ff0000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22.54 6.42a2.78 2.78 0 0 0-1.94-2C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 2A29 29 0 0 0 1 11.75a29 29 0 0 0 .46 5.33A2.78 2.78 0 0 0 3.4 19c1.72.46 8.6.46 8.6.46s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-2 29 29 0 0 0 .46-5.25 29 29 0 0 0-.46-5.33z"></path><polygon points="9.75 15.02 15.5 11.75 9.75 8.48 9.75 15.02"></polygon></svg>' },
             instagram: { name: 'Instagram', base: 'https://instagram.com/', color: '#e1306c', icon: '📸' },
             instagram: { name: 'Instagram', base: 'https://instagram.com/', color: '#e1306c', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"></line></svg>' },
             tiktok: { name: 'TikTok', base: 'https://www.tiktok.com/@', color: '#000000', icon: '📱' },
             tiktok: { name: 'TikTok', base: 'https://www.tiktok.com/@', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 1 1-5.2-1.74 2.89 2.89 0 0 1 2.31-2.22V8.2a6.34 6.34 0 0 0-5 6.13 6.34 6.34 0 1 0 10.7-4.52A8.25 8.25 0 0 0 20 10.56V6.69z"/></svg>' },
             youtube: { name: 'YouTube', base: 'https://youtube.com/@', color: '#ff0000', icon: '▶️' },
             twitter: { name: 'X / Twitter', base: 'https://x.com/', color: '#0f1419', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path></svg>' },
             twitter: { name: 'X / Twitter', base: 'https://x.com/', color: '#0f1419', icon: '🐦' },
             threads: { name: 'Threads', base: 'https://www.threads.net/@', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm3.842 12.338c-.288 1.83-1.85 3.09-3.842 3.09-2.298 0-4.043-1.68-4.043-4.135 0-2.454 1.745-4.134 4.043-4.134 1.583 0 2.875.836 3.447 2.083l-1.28.625c-.39-.817-1.182-1.328-2.167-1.328-1.55 0-2.613 1.15-2.613 2.754 0 1.603 1.063 2.753 2.613 2.753 1.258 0 2.19-.77 2.37-1.808h-2.37v-1.38h3.842v1.48z"/></svg>' },
             threads: { name: 'Threads', base: 'https://www.threads.net/@', color: '#000000', icon: '🧵' },
             facebook: { name: 'Facebook', base: 'https://facebook.com/', color: '#1877f2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path></svg>' },
             facebook: { name: 'Facebook', base: 'https://facebook.com/', color: '#1877f2', icon: '📘' },
             linkedin: { name: 'LinkedIn', base: 'https://linkedin.com/in/', color: '#0a66c2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path><rect x="2" y="9" width="4" height="12"></rect><circle cx="4" cy="4" r="2"></circle></svg>' },
             linkedin: { name: 'LinkedIn', base: 'https://linkedin.com/in/', color: '#0a66c2', icon: '💼' },
             twitch: { name: 'Twitch', base: 'https://twitch.tv/', color: '#9146FF', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/></svg>' },
            github: { name: 'GitHub', base: 'https://github.com/', color: '#24292e', icon: '💻' },
             discord: { name: 'Discord', base: 'https://discord.gg/', color: '#5865F2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.028zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/></svg>' },
            pinterest: { name: 'Pinterest', base: 'https://pinterest.com/', color: '#e60023', icon: '📌' },
             pinterest: { name: 'Pinterest', base: 'https://pinterest.com/', color: '#e60023', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.373 0 0 5.372 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738.098.119.112.224.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z"/></svg>' }
             twitch: { name: 'Twitch', base: 'https://twitch.tv/', color: '#9146FF', icon: '🎮' },
            reddit: { name: 'Reddit', base: 'https://reddit.com/user/', color: '#FF4500', icon: '👽' },
             discord: { name: 'Discord', base: 'https://discord.com/users/', color: '#5865F2', icon: '👾' },
            telegram: { name: 'Telegram', base: 'https://t.me/', color: '#0088cc', icon: '✈️' },
            whatsapp: { name: 'WhatsApp Channel', base: 'https://whatsapp.com/channel/', color: '#25D366', icon: '💬' },
             patreon: { name: 'Patreon', base: 'https://patreon.com/', color: '#FF424D', icon: '🧡' },
            imdb: { name: 'IMDb', base: 'https://www.imdb.com/name/', color: '#F5C518', icon: '🎬' }
         };
         };


         // 2. PRESET TEMPLATES
         // 2. PRESET TEMPLATES LABEL DIPERLUAS
         var PRESET_LABELS = [
         var PRESET_LABELS = [
             "Nama Lahir", "Tanggal Lahir", "Tempat Lahir", "Pekerjaan", "Gelar",
             "Nama Lahir", "Nama Lengkap", "Tanggal Lahir", "Tempat Lahir", "Pekerjaan",
            "Kebangsaan", "Genre", "Instrumen", "Label Rekaman", "Zodiak",
            "Kebangsaan", "Agama", "Almamater", "Genre", "Instrumen", "Label Rekaman",  
             "Tahun Aktif", "Situs Web Resmi", "Pasangan", "Orang Tua", "Pendidikan"
             "Tahun Aktif", "Situs Web Resmi", "Pasangan", "Orang Tua", "Anak", "Penghargaan"
         ];
         ];


        // 3. MASTER TIPE RUJUKAN
         var REF_TYPES = {
         var REF_TYPES = {
             "Berita": ["Berita Online", "Berita Cetak / Koran", "Wawancara Eksklusif", "Siaran Radio / TV"],
             "Berita": ["Berita Online", "Berita Cetak / Koran", "Wawancara Eksklusif", "Liputan Khusus"],
             "Website": ["Situs Resmi", "Portal Informasi", "Database Web", "Forum Diskusi"],
             "Website": ["Situs Resmi", "Portal Informasi", "Database Web", "Portal Komunitas"],
             "Buku": ["Buku Cetak", "E-Book", "Bab / Bagian Buku", "Biografi Cetak"],
             "Buku": ["Buku Cetak", "E-Book", "Bab / Bagian Buku", "Monograf", "Biografi"],
             "Jurnal": ["Jurnal Ilmiah", "Paper Konferensi", "Artikel Review", "Tesis / Disertasi"],
             "Jurnal": ["Jurnal Ilmiah", "Paper Konferensi", "Tesis / Disertasi"],
             "Musik & Video": ["MusicBrainz", "Discogs", "Spotify", "YouTube", "Film Dokumenter"],
            "Siaran Pers": ["Siaran Pers Resmi", "Pengumuman Instansi", "Keterangan Manajemen"],
             "Lainnya": ["Siaran Pers", "Dokumen PDF", "Postingan Medsos", "Arsip Web"]
            "Dokumen": ["Dokumen PDF", "Laporan Tahunan", "Regulasi Resmi"],
             "Database": ["MusicBrainz", "Discogs", "IMDb", "Genius", "Wikipedia"],
             "Video/Audio": ["YouTube Video", "Podcast", "Wawancara TV/Radio", "Dokumenter"],
            "Media Sosial": ["Postingan / Tweet", "Video Singkat", "Live Stream"]
         };
         };


         // 4. IKON SISTEM (SVG Ditingkatkan)
         // IKON SVG
         var svgEdit = '<svg class="md-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>';
         var icons = {
        var svgLock = '<svg class="md-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>';
            edit: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>',
        var svgUnlock = '<svg class="md-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 9.9-1"></path></svg>';
            ref: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>',
        var svgRef = '<svg class="md-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>';
            visit: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>',
        var svgCopy = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>';
            up: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="18 15 12 9 6 15"></polyline></svg>',
        var svgSearch = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>';
            down: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg>',
        var svgCode = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>';
            copy: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>'
        var svgChevronDown = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg>';
        };
        var svgExternal = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>';
        var svgArrowUp = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="19" x2="12" y2="5"></line><polyline points="5 12 12 5 19 12"></polyline></svg>';
        var svgArrowDown = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"></line><polyline points="19 12 12 19 5 12"></polyline></svg>';
        var svgDownload = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>';


         // 5. HELPER UTILITY (Notifikasi Toast, Extract Domain, dll)
         // 3. TOAST NOTIFICATION SYSTEM
         function showToast(message, type) {
         function showToast(message, type) {
             var bg = type === 'error' ? '#dc2626' : (type === 'warning' ? '#d97706' : '#16a34a');
            $('.md-toast').remove();
             var $toast = $('<div style="position:fixed; bottom:20px; right:20px; background:'+bg+'; color:#fff; padding:12px 20px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.15); z-index:9999; font-weight:600; font-size:0.9rem; opacity:0; transform:translateY(20px); transition:all 0.3s ease;">'+message+'</div>');
             var bg = type === 'error' ? '#ef4444' : (type === 'success' ? '#10b981' : '#3b82f6');
             var $toast = $('<div class="md-toast" style="position:fixed; bottom:20px; right:20px; background:'+bg+'; color:white; padding:12px 20px; border-radius:8px; box-shadow:0 10px 25px rgba(0,0,0,0.2); z-index:9999; font-weight:600; font-size:0.9rem; transform:translateY(100px); opacity:0; transition:all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);">'+message+'</div>');
             $('body').append($toast);
             $('body').append($toast);
             setTimeout(function() { $toast.css({opacity: 1, transform: 'translateY(0)'}); }, 10);
             setTimeout(function() { $toast.css({transform: 'translateY(0)', opacity: 1}); }, 50);
             setTimeout(function() {
             setTimeout(function() { $toast.css({transform: 'translateY(100px)', opacity: 0}); setTimeout(function(){ $toast.remove(); }, 300); }, 3000);
                $toast.css({opacity: 0, transform: 'translateY(20px)'});
                setTimeout(function() { $toast.remove(); }, 300);
            }, 3000);
         }
         }


        // UTILITIES
         function formatIndonesianDate(dateStr) {
         function formatIndonesianDate(dateStr) {
             if (!dateStr) return '';
             if (!dateStr) return '';
             var parts = dateStr.split('-');
             var parts = dateStr.split('-');
             if (parts.length !== 3) return dateStr;
             if (parts.length !== 3) return dateStr;
             var months = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'];
             var months = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'];
             var day = parseInt(parts[2], 10);
             return parseInt(parts[2], 10) + ' ' + months[parseInt(parts[1], 10) - 1] + ' ' + parts[0];
            var monthIdx = parseInt(parts[1], 10) - 1;
            var year = parts[0];
            if (isNaN(day) || monthIdx < 0 || monthIdx > 11 || isNaN(year)) return dateStr;
            return day + ' ' + months[monthIdx] + ' ' + year;
         }
         }


         function extractDomain(urlStr) {
         function extractDomain(urlStr) {
             try {
             try { return new URL(urlStr.startsWith('http') ? urlStr : 'https://'+urlStr).hostname.replace(/^www\./, ''); }
                if (!urlStr.match(/^https?:\/\//i)) urlStr = 'https://' + urlStr;
             catch(e) { return urlStr.split('/')[0]; }
                var parsed = new URL(urlStr);
                return parsed.hostname.replace(/^www\./, '');
             } catch(e) {
                return urlStr.replace(/^https?:\/\/(www\.)?/, '').split('/')[0];
            }
         }
         }


         function ensureHttps(urlStr) {
         function ensureHttps(urlStr) {
             if (!urlStr) return '';
             return (urlStr && !urlStr.match(/^https?:\/\//i)) ? 'https://' + urlStr.trim() : urlStr.trim();
            urlStr = urlStr.trim();
            if (urlStr && !urlStr.match(/^https?:\/\//i)) {
                return 'https://' + urlStr;
            }
            return urlStr;
         }
         }


        function getTodayString() {
         // 4. CSS MODERN & ANIMASI V8.0
            var now = new Date();
            var y = now.getFullYear();
            var m = String(now.getMonth() + 1).padStart(2, '0');
            var d = String(now.getDate()).padStart(2, '0');
            return y + '-' + m + '-' + d;
        }
 
         // 6. STYLESHEET MODERN V8.0 PRO
         var css = `
         var css = `
             #mippedia-data-app {
             :root {
                 background: #ffffff; border-radius: 16px; box-shadow: 0 8px 30px rgba(0,0,0,0.04);
                 --md-bg: #ffffff; --md-border: #e2e8f0; --md-text: #0f172a; --md-text-muted: #64748b;
                 padding: 24px; margin: 24px 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
                 --md-primary: #4f46e5; --md-primary-hover: #4338ca; --md-surface: #f8fafc;
                 border: 1px solid #f1f5f9; max-width: 100%; box-sizing: border-box; overflow: hidden;
                 --md-radius: 12px; --md-transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
             }
             }
              
             @media (prefers-color-scheme: dark) {
            .md-header {
                 :root {
                display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center;
                    --md-bg: #1e293b; --md-border: #334155; --md-text: #f8fafc; --md-text-muted: #94a3b8;
                 gap: 12px; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 2px solid #f8fafc;
                    --md-surface: #0f172a; --md-primary: #6366f1;
            }
                 }
            .md-title-container { display: flex; align-items: center; gap: 10px; flex: 1 1 auto; min-width: 180px; }
            .md-title { font-size: 1.35rem; font-weight: 800; color: #0f172a; margin: 0; white-space: nowrap; letter-spacing: -0.5px; }
            .md-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
           
            .md-btn-icon {
                background: #f8fafc; border: 1px solid #e2e8f0; cursor: pointer; color: #4f46e5;
                padding: 8px 14px; border-radius: 10px; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
                display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem; font-weight: 700; white-space: nowrap;
            }
            .md-btn-icon:hover:not(:disabled) { background: #e0e7ff; border-color: #c7d2fe; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(79, 70, 229, 0.1); }
            .md-btn-icon:active:not(:disabled) { transform: translateY(0); }
            .md-btn-lock { color: #e11d48; background: #fff1f2; border-color: #fecdd3; }
            .md-btn-lock:hover:not(:disabled) { background: #ffe4e6; border-color: #fda4af; box-shadow: 0 4px 12px rgba(225, 29, 72, 0.1); }
 
            .md-search-box { position: relative; margin-bottom: 20px; width: 100%; box-sizing: border-box; }
            .md-search-input {
                width: 100%; padding: 12px 16px 12px 40px; border: 2px solid #f1f5f9; border-radius: 12px;
                 font-size: 0.9rem; font-weight: 500; box-sizing: border-box; background: #f8fafc; transition: 0.3s;
             }
             }
            .md-search-input:focus { background: #fff; border-color: #6366f1; outline: none; box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1); }
            .md-search-icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: #94a3b8; }
            /* Row Display Fix */
            .md-row-display {
                display: flex; justify-content: space-between; align-items: flex-start;
                padding: 16px; border: 1px solid transparent; border-bottom: 1px solid #f1f5f9; transition: all 0.2s;
                border-radius: 12px; gap: 12px; margin-bottom: 8px; background: #fff; position: relative;
            }
            .md-row-display:hover { background: #fafafa; border-color: #f1f5f9; box-shadow: 0 4px 12px rgba(0,0,0,0.02); }
              
              
             .md-data-group { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 0; }
             #mippedia-data-app { background: var(--md-bg); border-radius: var(--md-radius); box-shadow: 0 10px 30px -10px rgba(0,0,0,0.1); padding: 20px; margin: 20px 0; border: 1px solid var(--md-border); font-family: system-ui, sans-serif; color: var(--md-text); }
            .md-data-label { font-size: 0.72rem; color: #64748b; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px; }
            .md-data-value-wrap { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
            .md-data-value { font-size: 1.1rem; color: #0f172a; line-height: 1.4; font-weight: 700; word-break: break-word; }
              
              
             .md-btn-copy {
            /* Baris Data */
                background: #f1f5f9; border: none; color: #64748b; cursor: pointer; padding: 4px 6px;
             .md-row-display { display: flex; justify-content: space-between; align-items: flex-start; padding: 16px; border: 1px solid var(--md-border); border-radius: var(--md-radius); margin-bottom: 12px; background: var(--md-surface); transition: var(--md-transition); }
                border-radius: 6px; transition: 0.2s; display: inline-flex; align-items: center;
            .md-row-display:hover { border-color: var(--md-primary); box-shadow: 0 4px 12px rgba(79,70,229,0.08); transform: translateY(-2px); }
            }
            .md-data-label { font-size: 0.75rem; color: var(--md-text-muted); font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px; }
             .md-btn-copy:hover { color: #4f46e5; background: #e0e7ff; transform: scale(1.05); }
            .md-data-value { font-size: 1.1rem; font-weight: 600; margin-top: 4px; display: inline-block; word-break: break-word; }
             .md-data-value a { color: var(--md-primary); text-decoration: none; border-bottom: 2px solid transparent; transition: var(--md-transition); }
            .md-data-value a:hover { border-bottom-color: var(--md-primary); }


            .md-row-actions { display: flex; flex-direction: column; gap: 6px; }
             /* Referensi Collapsible V8 */
 
             .md-ref-container { margin-top: 12px; }
             /* Tampilan Referensi V8.0 (ACCORDION COLLAPSIBLE) */
             .md-ref-summary { background: rgba(79,70,229,0.08); color: var(--md-primary); padding: 8px 14px; border-radius: 8px; cursor: pointer; display: flex; align-items: center; justify-content: space-between; font-size: 0.85rem; font-weight: 700; transition: var(--md-transition); border: 1px solid rgba(79,70,229,0.1); }
             .md-ref-container { margin-top: 12px; width: 100%; max-width: 450px; box-sizing: border-box; }
             .md-ref-summary:hover { background: rgba(79,70,229,0.15); }
             .md-ref-summary {
            .md-ref-icon-rot { transition: transform 0.3s ease; }
                background: #f8fafc; padding: 8px 12px; border-radius: 8px; border: 1px solid #e2e8f0;
             .md-ref-icon-rot.open { transform: rotate(180deg); }
                display: flex; justify-content: space-between; align-items: center; cursor: pointer;
            .md-ref-content { display: none; padding: 14px; border: 1px solid var(--md-border); border-top: none; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; background: var(--md-bg); font-size: 0.85rem; }
                transition: all 0.2s; user-select: none;
             .md-ref-grid-info { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; margin-bottom: 12px; }
            }
             .md-ref-lbl { color: var(--md-text-muted); font-weight: 600; }
             .md-ref-summary:hover { background: #f1f5f9; border-color: #cbd5e1; }
             .md-ref-val { color: var(--md-text); font-weight: 500; }
             .md-ref-summary.open { border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom-color: transparent; background: #f1f5f9; }
             .md-ref-tag { font-size: 0.8rem; font-weight: 700; color: #4f46e5; display: flex; align-items: center; gap: 6px; }
             .md-ref-toggle { color: #94a3b8; transition: transform 0.3s; display: flex; align-items: center; }
             .md-ref-summary.open .md-ref-toggle { transform: rotate(180deg); color: #4f46e5; }
              
              
             .md-ref-body {
            /* Tombol Aksi */
                background: #fff; padding: 12px; border: 1px solid #e2e8f0; border-top: none;
             .md-btn-visit { display: inline-flex; align-items: center; gap: 6px; background: var(--md-primary); color: white !important; padding: 6px 12px; border-radius: 6px; text-decoration: none !important; font-weight: 600; transition: var(--md-transition); box-shadow: 0 2px 8px rgba(79,70,229,0.3); }
                border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; font-size: 0.85rem;
             .md-btn-visit:hover { background: var(--md-primary-hover); transform: scale(1.02); }
                display: none; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
            }
             .md-ref-header { font-weight: 800; color: #0f172a; margin-bottom: 8px; display: block; word-break: break-word; line-height: 1.3; }
            .md-ref-details-grid { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
            .md-ref-detail-row { display: flex; flex-wrap: wrap; gap: 4px; font-size: 0.82rem; }
            .md-ref-lbl { font-weight: 700; color: #64748b; }
            .md-ref-val { color: #334155; font-weight: 500; }
              
              
             .md-btn-visit {
             .md-row-actions { display: flex; flex-direction: column; gap: 6px; opacity: 0.5; transition: var(--md-transition); }
                display: inline-flex; align-items: center; gap: 6px; background: #eff6ff; color: #2563eb;
            .md-row-display:hover .md-row-actions { opacity: 1; }
                padding: 6px 12px; border-radius: 6px; font-weight: 700; font-size: 0.8rem; text-decoration: none;
            .md-btn-small { background: var(--md-bg); border: 1px solid var(--md-border); color: var(--md-text-muted); cursor: pointer; padding: 6px; border-radius: 6px; display: flex; transition: var(--md-transition); }
                transition: 0.2s; border: 1px solid #bfdbfe; width: max-content;
             .md-btn-small:hover { color: var(--md-primary); border-color: var(--md-primary); background: rgba(79,70,229,0.05); }
            }
             .md-btn-visit:hover { background: #dbeafe; text-decoration: none; transform: translateY(-1px); }


             /* Media Sosial Badges V8 */
             /* Media Sosial */
             .md-social-group { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
             .md-social-group { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
             .md-social-badge {
             .md-social-badge { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 20px; font-size: 0.8rem; font-weight: 600; color: white !important; text-decoration: none !important; transition: var(--md-transition); box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
                display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 20px;
             .md-social-badge:hover { transform: translateY(-3px) scale(1.03); box-shadow: 0 5px 12px rgba(0,0,0,0.2); filter: brightness(1.1); }
                font-size: 0.8rem; font-weight: 700; color: white; text-decoration: none; transition: all 0.2s;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }
             .md-social-badge:hover { transform: translateY(-2px) scale(1.02); opacity: 0.95; box-shadow: 0 4px 8px rgba(0,0,0,0.15); color: white; text-decoration: none; }


             /* Preset Pill Badges */
             /* Input & Form */
             .md-preset-wrapper { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
             .md-input, .md-select { width: 100%; padding: 10px 14px; border: 2px solid var(--md-border); border-radius: 8px; background: var(--md-bg); color: var(--md-text); font-size: 0.9rem; transition: var(--md-transition); box-sizing: border-box; }
            .md-preset-pill {
             .md-input:focus { border-color: var(--md-primary); outline: none; box-shadow: 0 0 0 4px rgba(79,70,229,0.1); }
                background: #f8fafc; border: 1px solid #e2e8f0; padding: 4px 10px; border-radius: 12px;
             .md-input.error { border-color: #ef4444; background: #fef2f2; }
                font-size: 0.75rem; font-weight: 700; color: #64748b; cursor: pointer; transition: 0.2s;
            }
            .md-preset-pill:hover { background: #4f46e5; color: #fff; border-color: #4f46e5; }
 
            /* Form Elements */
             .md-form-box { background: #ffffff; border-radius: 16px; padding: 24px; margin-top: 24px; border: 1px solid #e2e8f0; box-shadow: 0 10px 40px rgba(0,0,0,0.06); animation: slideDown 0.3s ease; }
             @keyframes slideDown { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
              
              
             .md-form-title { font-size: 1.15rem; font-weight: 800; color: #0f172a; margin: 0 0 20px 0; border-bottom: 2px solid #f1f5f9; padding-bottom: 12px; }
             .md-form-box { background: var(--md-surface); padding: 20px; border-radius: var(--md-radius); border: 1px solid var(--md-border); margin-top: 20px; animation: slideIn 0.3s ease-out; }
            .md-form-group { margin-bottom: 18px; }
             @keyframes slideIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
            .md-form-group label { display: block; font-size: 0.85rem; font-weight: 700; margin-bottom: 8px; color: #334155; }
            .md-input, .md-select, .md-textarea {
                width: 100%; padding: 10px 14px; border: 2px solid #e2e8f0; border-radius: 10px;
                box-sizing: border-box; font-family: inherit; font-size: 0.95rem; transition: 0.2s; background: #fafafa;
            }
            .md-input:focus, .md-select:focus, .md-textarea:focus { border-color: #6366f1; background: #fff; outline: none; box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1); }
           
            .md-ref-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; background: #f8fafc; padding: 16px; border-radius: 12px; border: 1px dashed #cbd5e1; }
            .md-social-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; background: #f1f5f9; padding: 16px; border-radius: 12px; border: 1px solid #e2e8f0; max-height: 320px; overflow-y: auto; }
            .md-grid-full { grid-column: span 2; }
           
            .md-form-actions { display: flex; gap: 12px; align-items: center; margin-top: 24px; padding-top: 16px; border-top: 1px solid #e2e8f0; flex-wrap: wrap; }
            .md-btn {
                padding: 12px 20px; border: none; border-radius: 10px; font-weight: 800; cursor: pointer;
                color: white; font-size: 0.9rem; transition: 0.2s; display: inline-flex; align-items: center; gap: 8px; justify-content: center;
            }
             .md-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); }
            .md-btn:active:not(:disabled) { transform: translateY(0); }
            .md-btn-save { background: linear-gradient(135deg, #4f46e5, #4338ca); flex: 1; min-width: 150px; }
            .md-btn-cancel { background: #64748b; }
            .md-btn-delete { background: #ef4444; margin-left: auto; }
           
            .md-spinner { display: none; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-radius: 50%; border-top-color: #fff; animation: md-spin 0.8s linear infinite; }
            .is-loading .md-spinner { display: inline-block; }
            @keyframes md-spin { to { transform: rotate(360deg); } }


             @media (max-width: 600px) {
             @media (max-width: 600px) {
                 #mippedia-data-app { padding: 16px; margin: 16px 0; border-radius: 14px; }
                 .md-row-display { flex-direction: column; }
                 .md-header { flex-direction: column; align-items: flex-start; gap: 12px; }
                 .md-row-actions { flex-direction: row; margin-top: 10px; width: 100%; justify-content: flex-end; opacity: 1; }
                .md-actions { width: 100%; justify-content: flex-start; overflow-x: auto; padding-bottom: 4px; }
                 .md-ref-grid-info { grid-template-columns: 1fr; gap: 2px; }
                .md-btn-icon { padding: 8px 12px; font-size: 0.8rem; flex-shrink: 0; }
                 .md-ref-grid, .md-social-grid { grid-template-columns: 1fr; }
                .md-grid-full { grid-column: span 1; }
                .md-form-actions { flex-direction: column; width: 100%; }
                .md-btn { width: 100%; margin: 0 !important; }
                .md-row-display { padding: 14px 10px; flex-direction: column; }
                .md-row-actions { flex-direction: row; width: 100%; justify-content: flex-end; margin-top: 10px; border-top: 1px dashed #e2e8f0; padding-top: 10px; }
             }
             }
             .md-native-render { display: none; }
             .md-native-render { display: none; }
Baris 272: Baris 167:
         $('<style>').text(css).appendTo('head');
         $('<style>').text(css).appendTo('head');


         // 7. PARSER & PENYIMPANAN DATA
         // 5. CORE LOGIC
         function loadData() {
         function loadData() {
             return api.get({
             return api.get({ action: 'query', prop: 'revisions', titles: pageName, rvprop: 'content', rvslots: 'main', formatversion: 2 }).then(function(data) {
                action: 'query', prop: 'revisions', titles: pageName, rvprop: 'content', rvslots: 'main', formatversion: 2
            }).then(function(data) {
                 var content = data.query.pages[0].revisions[0].slots.main.content;
                 var content = data.query.pages[0].revisions[0].slots.main.content;
                 var match = content.match(/<!-- MIPPEDIA_DATA_START \| (.*?) -->/);
                 var match = content.match(/<!-- MIPPEDIA_DATA_START \| (.*?) -->/);
                 if (match) {
                 if (match) { try { dataItems = JSON.parse(match[1]).items || []; isLocked = JSON.parse(match[1]).locked || false; } catch(e) {} }
                    try {
                        var parsed = JSON.parse(match[1]);
                        dataItems = parsed.items || [];
                        isLocked = parsed.locked || false;
                    } catch(e) { console.error("JSON Error", e); showToast('Gagal memuat struktur JSON!', 'error'); }
                }
                 return content;  
                 return content;  
             });
             });
         }
         }


         function buildWikitextVal(item) {
         function saveData(actionType, $btnEl, rawContent) {
            var val = item.val;
             if ($btnEl) { $btnEl.html('<span style="animation: spin 1s linear infinite;"></span> Menyimpan...').prop('disabled', true); }
            if (item.linkTarget && item.linkTarget.trim() !== '') {
                return "[[" + item.linkTarget.trim() + "|" + val + "]]";
            }
            if (item.linkSplit) {
                return val.replace(/([a-zA-Z0-9_À-ÿ\- ]+)/g, function(match) {
                    var trimmed = match.trim();
                    if (trimmed.length > 2 && trimmed.toLowerCase() !== 'dan' && trimmed.toLowerCase() !== 'atau') {
                        return "[[" + trimmed + "]]";
                    }
                    return match;
                });
            }
             if (item.link) {
                return "[[" + val + "]]";
            }
            return val;
        }
 
        function buildWikitextRef(refObj) {
            if (!refObj) return "";
            var title = refObj.title || "Rujukan";
            var text = refObj.url ? "[" + ensureHttps(refObj.url) + " " + title + "]" : "'''" + title + "'''";
            var details = [];
            if (refObj.author) details.push("Penulis: " + refObj.author);
            if (refObj.site) details.push("Situs: " + refObj.site);
            if (refObj.publisher) details.push("Penerbit: " + refObj.publisher);
            if (refObj.date) details.push("Diakses: " + formatIndonesianDate(refObj.date));
           
            if (details.length > 0) text += " &mdash; <small>" + details.join(" &bull; ") + "</small>";
            return text;
        }
 
        function saveData(actionType, $btnEl, originalContent, callback) {
            if ($btnEl) $btnEl.addClass('is-loading').prop('disabled', true);
           
             var jsonStr = JSON.stringify({ locked: isLocked, items: dataItems });
             var jsonStr = JSON.stringify({ locked: isLocked, items: dataItems });
             var wt = "<!-- MIPPEDIA_DATA_START | " + jsonStr + " -->\n";
             var wt = "<!-- MIPPEDIA_DATA_START | " + jsonStr + " -->\n<div class=\"md-native-render\">{| class=\"wikitable\"\n! Data !! Nilai !! Referensi\n";
            wt += "<div class=\"md-native-render\">\n{| class=\"wikitable\"\n! Data !! Nilai !! Referensi\n";
             dataItems.forEach(function(item) { wt += "|-\n| " + item.prop + " || " + item.val + " || " + (item.ref ? (item.ref.url || "Ref") : "") + "\n"; });
           
             dataItems.forEach(function(item) {
                var valTxt = buildWikitextVal(item);
                var refTxt = buildWikitextRef(item.ref);
                wt += "|-\n| " + item.prop + " || " + valTxt + " || " + refTxt + "\n";
            });
             wt += "|}\n</div>\n<!-- MIPPEDIA_DATA_END -->";
             wt += "|}\n</div>\n<!-- MIPPEDIA_DATA_END -->";


             var newContent;
             var newContent = /<!-- MIPPEDIA_DATA_START \| .*? -->[\s\S]*?<!-- MIPPEDIA_DATA_END -->/.test(rawContent)  
            var regex = /<!-- MIPPEDIA_DATA_START \| .*? -->[\s\S]*?<!-- MIPPEDIA_DATA_END -->/;
                 ? rawContent.replace(/<!-- MIPPEDIA_DATA_START \| .*? -->[\s\S]*?<!-- MIPPEDIA_DATA_END -->/, wt)  
            if (regex.test(originalContent)) {
                 : rawContent.trim() + "\n\n" + wt;
                 newContent = originalContent.replace(regex, wt);
            } else {
                 newContent = originalContent.trim() + "\n\n" + wt;
            }


             api.postWithToken('csrf', {
             api.postWithToken('csrf', { action: 'edit', title: pageName, text: newContent, summary: 'Mippedia Data V8: ' + actionType }).done(function() {
                action: 'edit', title: pageName, text: newContent, summary: 'Mippedia Data V8: ' + actionType, minor: false
                 showToast("Data berhasil disimpan! Memuat ulang...", "success");
            }).done(function() {
                setTimeout(function(){ window.location.href = location.pathname + "?refresh=" + Date.now(); }, 1000);
                 localStorage.removeItem('md_draft_' + pageName); // Hapus draft jika sukses
             }).fail(function() { showToast("Gagal menyimpan data!", "error"); if($btnEl) $btnEl.prop('disabled', false).text('Coba Lagi'); });
                if(callback) callback();
                else {
                    showToast('Berhasil disimpan! Memuat ulang...', 'success');
                    setTimeout(function() { window.location.href = location.pathname + "?refresh=" + new Date().getTime(); }, 1000);
                }
             }).fail(function(err) {
                if ($btnEl) $btnEl.removeClass('is-loading').prop('disabled', false);
                showToast("Gagal menyimpan: " + err, 'error');
            });
         }
         }


         // 8. BUILDER UI UTAMA
         // 6. BUILDER UI
         function buildUI(rawContent) {
         function buildUI(rawContent) {
             var $app = $('<div id="mippedia-data-app"></div>');
             var $app = $('<div id="mippedia-data-app"></div>');
            var $header = $('<div style="display:flex; justify-content:space-between; margin-bottom:15px; flex-wrap:wrap; gap:10px;"><h3 style="margin:0;">✨ Data Terstruktur</h3><div id="md-top-actions"></div></div>');
            $app.append($header);
            var $actions = $header.find('#md-top-actions');
            $actions.append('<button class="md-btn-small md-add-btn" style="background:var(--md-primary); color:white; padding:8px 16px;">' + icons.edit + ' Tambah Data</button>');
              
              
            // HEADER
             var $list = $('<div id="md-data-list"></div>');
             var $header = $('<div class="md-header"></div>');
            var $titleContainer = $('<div class="md-title-container"><h3 class="md-title">' + svgEdit + ' Data Terstruktur</h3></div>');
            var $actions = $('<div class="md-actions"></div>');
              
              
             // Tombol Ekspor/Impor JSON Baru
             dataItems.forEach(function(item, index) {
            var $jsonBtn = $('<button class="md-btn-icon" title="Ekspor/Impor File JSON">' + svgDownload + ' Data JSON</button>');
                var $row = $('<div class="md-row-display"></div>');
            $jsonBtn.on('click', function() { showJsonModal(rawContent); });
                var $info = $('<div style="flex:1; width:100%;"></div>');
            $actions.append($jsonBtn);
                $info.append('<div class="md-data-label">' + item.prop + '</div>');
 
                  
            if (isSysop) {
                var displayVal = item.val;
                var $lockBtn = $('<button class="md-btn-icon ' + (isLocked ? 'md-btn-unlock' : 'md-btn-lock') + '">' + (isLocked ? svgUnlock + ' Buka Kunci' : svgLock + ' Kunci') + ' <span class="md-spinner"></span></button>');
                if(item.link) displayVal = '<a href="' + mw.util.getUrl(item.val) + '">' + item.val + '</a>';
                 $lockBtn.on('click', function() {
                 $info.append('<div class="md-data-value">' + displayVal + ' <span class="md-btn-small copy-val" style="display:inline-flex; padding:2px; border:none;" title="Salin">' + icons.copy + '</span></div>');
                    isLocked = !isLocked;
                  
                    saveData(isLocked ? 'Mengunci data' : 'Membuka kunci data', $(this), rawContent);
                 // SOCIALS
                });
                if (item.isPersonOrg && item.socials) {
                 $actions.append($lockBtn);
                    var $soc = $('<div class="md-social-group"></div>');
            }
                    Object.keys(item.socials).forEach(function(k) {
 
                        if(SOCIAL_PLATFORMS[k]) {
            if (!isLocked || isSysop) {
                            var p = SOCIAL_PLATFORMS[k];
                var $addBtn = $('<button class="md-btn-icon" style="background:#4f46e5; color:white; border-color:#4338ca;">' + svgEdit + ' Tambah Baru</button>');
                            $soc.append('<a class="md-social-badge" href="' + p.base + item.socials[k].replace(/^@/,'') + '" target="_blank" style="background:'+p.color+';">' + p.icon + ' ' + p.name + '</a>');
                 $addBtn.on('click', function() { showForm(-1, rawContent); });
                         }
                 $actions.append($addBtn);
            }
 
            $header.append($titleContainer).append($actions);
            $app.append($header);
 
            // SEARCH BAR
            if (dataItems.length > 2) {
                var $searchBox = $('<div class="md-search-box"><span class="md-search-icon">' + svgSearch + '</span><input type="text" class="md-search-input" placeholder="Cari data terstruktur (misal: Tanggal Lahir)..."></div>');
                $searchBox.find('input').on('keyup input', function() {
                    var q = $(this).val().toLowerCase();
                    $app.find('.md-row-display').each(function() {
                        var text = $(this).text().toLowerCase();
                         $(this).toggle(text.indexOf(q) !== -1);
                     });
                     });
                });
                    $info.append($soc);
                $app.append($searchBox);
                }
            }


            // DAFTAR BARIS DATA
                // REFERENSI (SISTEM ACCORDION BARU)
            var $list = $('<div class="md-list"></div>');
                if (item.ref && (item.ref.title || item.ref.url)) {
            if (dataItems.length === 0) {
                     var $refWrap = $('<div class="md-ref-container"></div>');
                $list.append('<div style="text-align:center; padding: 40px 20px; background:#f8fafc; border-radius:12px; border:2px dashed #cbd5e1; color:#64748b;"><h4>Belum ada data!</h4><p style="font-size:0.9rem; margin-top:8px;">Klik tombol <b>Tambah Baru</b> di atas untuk mulai membuat struktur.</p></div>');
                     var refTitleDisplay = item.ref.title || (item.ref.url ? extractDomain(item.ref.url) : "Sumber");
            } else {
                dataItems.forEach(function(item, index) {
                     var $row = $('<div class="md-row-display"></div>');
                     var $info = $('<div class="md-data-group"></div>');
                    $info.append('<span class="md-data-label">' + item.prop + '</span>');
                      
                      
                     // RENDER NILAI DATA
                     var $summary = $('<div class="md-ref-summary"><span>' + icons.ref + ' Referensi: ' + refTitleDisplay + '</span> <span class="md-ref-icon-rot">▼</span></div>');
                     var displayValHtml = '';
                     var $content = $('<div class="md-ref-content"></div>');
                     var rawVal = item.val || '';
                   
 
                     var $grid = $('<div class="md-ref-grid-info"></div>');
                     if (rawVal.match(/^https?:\/\//i)) {
                     if(item.ref.author) $grid.append('<div class="md-ref-lbl">Penulis</div><div class="md-ref-val">' + item.ref.author + '</div>');
                        var domain = extractDomain(rawVal);
                     if(item.ref.site) $grid.append('<div class="md-ref-lbl">Situs</div><div class="md-ref-val">' + item.ref.site + '</div>');
                        displayValHtml = '<a href="' + rawVal + '" target="_blank" style="color:#2563eb; text-decoration:none;">' + domain + '</a>';
                    if(item.ref.publisher) $grid.append('<div class="md-ref-lbl">Penerbit</div><div class="md-ref-val">' + item.ref.publisher + '</div>');
                     } else if (item.linkTarget && item.linkTarget.trim() !== '') {
                     if(item.ref.date) $grid.append('<div class="md-ref-lbl">Diakses</div><div class="md-ref-val">' + formatIndonesianDate(item.ref.date) + '</div>');
                        displayValHtml = '<a href="' + mw.util.getUrl(item.linkTarget.trim()) + '" style="color:#2563eb; text-decoration:none;">' + rawVal + '</a>';
                    if(item.ref.type) $grid.append('<div class="md-ref-lbl">Kategori</div><div class="md-ref-val"><span style="background:#e2e8f0; color:#334155; padding:2px 8px; border-radius:12px; font-size:0.75rem;">' + item.ref.type + '</span></div>');
                     } else if (item.linkSplit) {
                   
                        var parts = rawVal.split(/([,/\s]+dan\s+|[,/\s]+atau\s+|[,/]+)/gi);
                    $content.append($grid);
                        displayValHtml = parts.map(function(p) {
                      
                            var trimmed = p.trim();
                    if(item.ref.url) {
                            if (trimmed && !p.match(/^[,/\s]+$/) && trimmed.toLowerCase() !== 'dan' && trimmed.toLowerCase() !== 'atau') {
                         $content.append('<div style="margin-top:10px; border-top:1px dashed var(--md-border); padding-top:10px;"><a href="' + ensureHttps(item.ref.url) + '" target="_blank" class="md-btn-visit">' + icons.visit + ' Kunjungi Link Website</a></div>');
                                return '<a href="' + mw.util.getUrl(trimmed) + '" style="color:#2563eb; text-decoration:none;">' + trimmed + '</a>';
                            }
                            return p;
                        }).join('');
                     } else if (item.link) {
                         displayValHtml = '<a href="' + mw.util.getUrl(rawVal) + '" style="color:#2563eb; text-decoration:none;">' + rawVal + '</a>';
                    } else {
                        displayValHtml = rawVal;
                     }
                     }


                     var $valWrap = $('<div class="md-data-value-wrap"></div>');
                     // Logika Accordion Toggle
                    $valWrap.append('<span class="md-data-value">' + displayValHtml + '</span>');
                     $summary.on('click', function() {
                      
                         $content.slideToggle(250);
                    var $copyBtn = $('<button class="md-btn-copy" title="Salin nilai teks">' + svgCopy + '</button>');
                         $(this).find('.md-ref-icon-rot').toggleClass('open');
                    $copyBtn.on('click', function() {
                         navigator.clipboard.writeText(rawVal);
                         showToast('Teks disalin!', 'success');
                     });
                     });
                    $valWrap.append($copyBtn);
                    $info.append($valWrap);


                     // RENDER MEDIA SOSIAL & MUSIK
                     $refWrap.append($summary).append($content);
                    if (item.isPersonOrg && item.socials) {
                    $info.append($refWrap);
                        var $socialGroup = $('<div class="md-social-group"></div>');
                }
                        var hasSocial = false;
                        Object.keys(SOCIAL_PLATFORMS).forEach(function(key) {
                            var uname = item.socials[key];
                            if (uname) {
                                hasSocial = true;
                                var platform = SOCIAL_PLATFORMS[key];
                                var fullUrl = platform.base + uname.replace(/^@/, '');
                                var $badge = $('<a class="md-social-badge" href="' + fullUrl + '" target="_blank" style="background:' + platform.color + ';">' + platform.icon + ' ' + platform.name + '</a>');
                                $socialGroup.append($badge);
                            }
                        });
                        if (hasSocial) $info.append($socialGroup);
                    }
                   
                    // RENDER REFERENSI EKSPLISIT (V8 ACCORDION)
                    if (item.ref && (item.ref.url || item.ref.title)) {
                        var ref = item.ref;
                        var $refContainer = $('<div class="md-ref-container"></div>');
                       
                        var siteNameLabel = ref.site || extractDomain(ref.url) || "Referensi";
                        var $refSummary = $('<div class="md-ref-summary" title="Klik untuk lihat detail referensi"><span class="md-ref-tag">' + svgRef + ' 1 Referensi (' + siteNameLabel + ')</span><span class="md-ref-toggle">' + svgChevronDown + '</span></div>');
                        var $refBody = $('<div class="md-ref-body"></div>');
                       
                        var refTitle = ref.title || "Sumber Rujukan";
                        $refBody.append('<span class="md-ref-header">' + refTitle + '</span>');


                        var $detailsGrid = $('<div class="md-ref-details-grid"></div>');
                $row.append($info);
                        if (ref.author) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Penulis:</span><span class="md-ref-val">' + ref.author + '</span></div>');
                        if (ref.site) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Situs/Penerbit:</span><span class="md-ref-val">' + ref.site + (ref.publisher ? ' / ' + ref.publisher : '') + '</span></div>');
                        if (ref.date) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Diakses:</span><span class="md-ref-val">' + formatIndonesianDate(ref.date) + '</span></div>');
                        if (ref.type) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Tipe:</span><span class="md-ref-val">' + ref.type + (ref.subType ? ' - ' + ref.subType : '') + '</span></div>');
                       
                        $refBody.append($detailsGrid);


                        if (ref.url) {
                // Row Actions (Edit, Move Up, Move Down, Delete)
                            var safeUrl = ensureHttps(ref.url);
                var $rowActs = $('<div class="md-row-actions"></div>');
                            $refBody.append('<a href="' + safeUrl + '" target="_blank" class="md-btn-visit">' + svgExternal + ' Kunjungi Situs</a>');
                var $btnEdit = $('<button class="md-btn-small" title="Edit">' + icons.edit + '</button>');
                        }
                $btnEdit.on('click', function() { showForm(index, rawContent); });
               
                var $btnUp = $('<button class="md-btn-small" title="Geser ke Atas">' + icons.up + '</button>');
                $btnUp.on('click', function() { if(index > 0) swap(index, index-1, rawContent); });
               
                var $btnDown = $('<button class="md-btn-small" title="Geser ke Bawah">' + icons.down + '</button>');
                $btnDown.on('click', function() { if(index < dataItems.length-1) swap(index, index+1, rawContent); });


                        $refSummary.on('click', function() {
                $rowActs.append($btnEdit).append($btnUp).append($btnDown);
                            $refBody.slideToggle(200);
                $row.append($rowActs);
                            $(this).toggleClass('open');
                $list.append($row);
                        });


                        $refContainer.append($refSummary).append($refBody);
                // Copy Value Event
                        $info.append($refContainer);
                $row.find('.copy-val').on('click', function() {
                     }
                    navigator.clipboard.writeText(item.val);
                   
                     showToast("Teks disalin: " + item.val, "success");
                    $row.append($info);
                });
            });


                    if (!isLocked || isSysop) {
                        var $actionsGroup = $('<div class="md-row-actions"></div>');
                       
                        // Urutkan Atas/Bawah (Fitur Baru)
                        var $btnUp = $('<button class="md-btn-icon" style="padding:4px 6px;" title="Pindah ke Atas" ' + (index === 0 ? 'disabled style="opacity:0.3; cursor:not-allowed;"' : '') + '>' + svgArrowUp + '</button>');
                        var $btnDown = $('<button class="md-btn-icon" style="padding:4px 6px;" title="Pindah ke Bawah" ' + (index === dataItems.length-1 ? 'disabled style="opacity:0.3; cursor:not-allowed;"' : '') + '>' + svgArrowDown + '</button>');
                       
                        $btnUp.on('click', function() {
                            if(index > 0) {
                                var temp = dataItems[index-1];
                                dataItems[index-1] = dataItems[index];
                                dataItems[index] = temp;
                                saveData('Mengubah urutan', $(this), rawContent);
                            }
                        });
                        $btnDown.on('click', function() {
                            if(index < dataItems.length-1) {
                                var temp = dataItems[index+1];
                                dataItems[index+1] = dataItems[index];
                                dataItems[index] = temp;
                                saveData('Mengubah urutan', $(this), rawContent);
                            }
                        });
                        var $editIcon = $('<button class="md-btn-icon edit-btn" style="padding:6px 12px; margin-top:4px;">' + svgEdit + ' Edit</button>');
                        $editIcon.on('click', function() { showForm(index, rawContent); });
                        var $orderWrap = $('<div style="display:flex; gap:4px; justify-content:flex-end;"></div>').append($btnUp).append($btnDown);
                        $actionsGroup.append($orderWrap).append($editIcon);
                        $row.append($actionsGroup);
                    }
                    $list.append($row);
                });
            }
             $app.append($list);
             $app.append($list);
             $app.append('<div id="md-form-container"></div>');
             $app.append('<div id="md-form-container"></div>');


            var $infobox = $('.infobox').first();
             $('.md-native-render').hide();
             $('.md-native-render').hide();  
             if ($('.infobox').length) $app.insertAfter($('.infobox').first());
             if ($infobox.length) $app.insertAfter($infobox);
             else $('#mw-content-text .mw-parser-output').append($app);
             else $('#mw-content-text .mw-parser-output').append($app);
            $app.find('.md-add-btn').on('click', function() { showForm(-1, rawContent); });
        }
        function swap(idx1, idx2, rawContent) {
            var temp = dataItems[idx1];
            dataItems[idx1] = dataItems[idx2];
            dataItems[idx2] = temp;
            saveData('Reorder urutan data', null, rawContent);
         }
         }


         // 9. FORM EDIT DENGAN PRESET & PLATFORM LENGKAP
         // 7. FORM EDITOR V8
         function showForm(index, rawContent) {
         function showForm(index, rawContent) {
             var $container = $('#md-form-container');
             var $c = $('#md-form-container').empty();
            $container.empty();  
 
             var isNew = index === -1;
             var isNew = index === -1;
             var currentData = isNew ? { prop: '', val: '', link: false, linkTarget: '', linkSplit: false, ref: {}, isPersonOrg: false, socials: {} } : dataItems[index];
             var d = isNew ? { prop: '', val: '', link: false, ref: {}, isPersonOrg: false, socials: {} } : dataItems[index];
           
            // Cek Draft LocalStorage
            var draftKey = 'md_draft_' + pageName;
            var savedDraft = localStorage.getItem(draftKey);
            if (isNew && savedDraft) {
                try {
                    currentData = JSON.parse(savedDraft);
                    showToast('Memulihkan draft yang belum tersimpan...', 'warning');
                } catch(e) {}
            }


            var currentRef = currentData.ref || {};
             var $f = $('<div class="md-form-box"><h4>' + (isNew ? 'Tambah Data Baru' : 'Edit Data') + '</h4></div>');
            var currentSocials = currentData.socials || {};
 
             var $form = $('<div class="md-form-box"></div>');
            $form.append('<h4 class="md-form-title">' + (isNew ? 'Tambah Data Baru' : 'Edit Data Terstruktur') + '</h4>');
              
              
             // Label Data
             $f.append('<label style="font-size:0.8rem; font-weight:700;">Label (Contoh: Pekerjaan)</label><input type="text" id="fm-prop" class="md-input" style="margin-bottom:10px;" value="' + (d.prop||'') + '">');
            var $propGroup = $('<div class="md-form-group"><label>Label Data (Cth: Pekerjaan, Sutradara)</label><input type="text" id="md-inp-prop" class="md-input md-track-draft" value="' + (currentData.prop || '') + '"></div>');
             $f.append('<label style="font-size:0.8rem; font-weight:700;">Nilai Data</label><input type="text" id="fm-val" class="md-input" style="margin-bottom:10px;" value="' + (d.val||'') + '">');
             var $presetWrap = $('<div class="md-preset-wrapper"></div>');
             $f.append('<label style="font-size:0.85rem; display:flex; gap:8px; margin-bottom:15px; cursor:pointer;"><input type="checkbox" id="fm-link" '+(d.link?'checked':'')+'> Jadikan Tautan Wiki (Wikilink)</label>');
            PRESET_LABELS.forEach(function(lbl) {
                var $pill = $('<span class="md-preset-pill">' + lbl + '</span>');
                $pill.on('click', function() { $('#md-inp-prop').val(lbl).trigger('input'); });
                $presetWrap.append($pill);
            });
            $propGroup.append($presetWrap);
            $form.append($propGroup);
           
            // Nilai Data
            var $valBox = $('<div class="md-form-group"></div>');
            $valBox.append('<label>Nilai / Konten Data</label><input type="text" id="md-inp-val" class="md-input md-track-draft" value="' + (currentData.val || '') + '">');
           
            var $wikilinkOpts = $('<div style="margin-top:10px; display:flex; flex-direction:column; gap:8px; background:#f8fafc; padding:12px; border-radius:10px; border:1px solid #e2e8f0;"></div>');
            var chkLink = currentData.link ? 'checked' : '';
            var chkSplit = currentData.linkSplit ? 'checked' : '';
           
             $wikilinkOpts.append('<label style="display:flex; align-items:center; gap:8px; font-size:0.85rem; font-weight:700; cursor:pointer;"><input type="checkbox" id="md-inp-link" class="md-track-draft" ' + chkLink + '> Jadikan Wikilink Standar</label>');
            $wikilinkOpts.append('<label style="display:flex; align-items:center; gap:8px; font-size:0.85rem; font-weight:700; cursor:pointer;"><input type="checkbox" id="md-inp-split" class="md-track-draft" ' + chkSplit + '> Smart Split Wikilink (Pecah koma/dan)</label>');
           
            var $pipedGroup = $('<div style="margin-top:6px;"><label style="font-size:0.8rem; color:#475569;">Target Halaman Piped (Opsional):</label><input type="text" id="md-inp-target" class="md-input md-track-draft" style="padding:8px 12px; font-size:0.85rem;" placeholder="Contoh: Diskografi Rumi Haitami" value="' + (currentData.linkTarget || '') + '"></div>');
            $wikilinkOpts.append($pipedGroup);
           
            $valBox.append($wikilinkOpts);
            $form.append($valBox);


             // MEDIA SOSIAL
             // REFERENSI EDITOR
             var $socialSec = $('<div class="md-form-group" style="margin-top:20px;"></div>');
             var $refArea = $('<div style="background:rgba(0,0,0,0.02); padding:15px; border-radius:8px; margin-bottom:15px; border:1px solid var(--md-border);"><h5>Sumber Referensi</h5></div>');
             var chkPerson = currentData.isPersonOrg ? 'checked' : '';
             $refArea.append('<input type="url" id="fm-ref-url" class="md-input" placeholder="URL Lengkap (https://...)" style="margin-bottom:8px;" value="'+(d.ref?.url||'')+'">');
             $socialSec.append('<label style="display:flex; align-items:center; gap:8px; cursor:pointer; background:#e0e7ff; padding:12px; border-radius:10px; font-weight:800; color:#3730a3;"><input type="checkbox" id="md-chk-person" class="md-track-draft" ' + chkPerson + '> Aktifkan Profil Sosmed & Musik</label>');
             $refArea.append('<div style="display:grid; grid-template-columns:1fr 1fr; gap:8px; margin-bottom:8px;"><input type="text" id="fm-ref-title" class="md-input" placeholder="Judul Artikel" value="'+(d.ref?.title||'')+'"><input type="text" id="fm-ref-site" class="md-input" placeholder="Nama Situs" value="'+(d.ref?.site||'')+'"></div>');
            $refArea.append('<div style="display:grid; grid-template-columns:1fr 1fr; gap:8px; margin-bottom:8px;"><input type="text" id="fm-ref-author" class="md-input" placeholder="Penulis" value="'+(d.ref?.author||'')+'"><input type="date" id="fm-ref-date" class="md-input" value="'+(d.ref?.date||'')+'"></div>');
              
              
             var $socialGrid = $('<div class="md-social-grid" id="md-social-box" style="display:' + (currentData.isPersonOrg ? 'grid' : 'none') + '; margin-top:10px;"></div>');
             // Auto Domain Fill
            Object.keys(SOCIAL_PLATFORMS).forEach(function(key) {
            $refArea.find('#fm-ref-url').on('blur', function() {
                 var p = SOCIAL_PLATFORMS[key];
                 var url = $(this).val();
                var valUname = currentSocials[key] || '';
                 if(url && !$('#fm-ref-site').val()) { $('#fm-ref-site').val(extractDomain(url)); showToast("Situs otomatis terdeteksi", "success"); }
                 $socialGrid.append('<div><label style="font-size:0.8rem; color:#334155; font-weight:700;">' + p.name + '</label><input type="text" id="md-soc-' + key + '" class="md-input md-track-draft" placeholder="Username" value="' + valUname + '"></div>');
             });
             });
             $socialSec.append($socialGrid);
             $f.append($refArea);
            $form.append($socialSec);


            // RUJUKAN LENGKAP (Otomatis deteksi domain)
             var $actions = $('<div style="display:flex; gap:10px; margin-top:20px;"></div>');
             var $refArea = $('<div class="md-form-group" style="margin-top:24px;"></div>');
             var $btnSave = $('<button class="md-btn-visit" style="flex:1; justify-content:center; cursor:pointer; border:none; padding:10px;">Simpan Data</button>');
            $refArea.append('<label style="font-size:1.05rem; font-weight:800; color:#0f172a; border-bottom:2px solid #e2e8f0; padding-bottom:8px;">Sumber Referensi</label>');
             var $btnCancel = $('<button class="md-btn-visit" style="background:#64748b; cursor:pointer; border:none; padding:10px;">Batal</button>');
           
            var $refGrid = $('<div class="md-ref-grid" style="margin-top:12px;"></div>');
           
             var $typeSel = $('<select id="md-ref-type" class="md-select md-track-draft"><option value="">-- Pilih Kategori --</option></select>');
            Object.keys(REF_TYPES).forEach(function(t) {
                var sel = currentRef.type === t ? 'selected' : '';
                $typeSel.append('<option value="' + t + '" ' + sel + '>' + t + '</option>');
            });
            var $subTypeSel = $('<select id="md-ref-subtype" class="md-select md-track-draft"><option value="">-- Sub Kategori --</option></select>');
           
            function updateSubTypes(mainType, selectedSub) {
                $subTypeSel.empty().append('<option value="">-- Sub Kategori --</option>');
                if (mainType && REF_TYPES[mainType]) {
                    REF_TYPES[mainType].forEach(function(st) {
                        var sel = selectedSub === st ? 'selected' : '';
                        $subTypeSel.append('<option value="' + st + '" ' + sel + '>' + st + '</option>');
                    });
                }
            }
            $typeSel.on('change', function() { updateSubTypes($(this).val(), ''); });
            updateSubTypes(currentRef.type, currentRef.subType);
 
            $refGrid.append('<div><label style="font-size:0.8rem;">Kategori</label></div>').find('div').last().append($typeSel);
            $refGrid.append('<div><label style="font-size:0.8rem;">Sub Kategori</label></div>').find('div').last().append($subTypeSel);
 
            var $urlInput = $('<input type="url" id="md-ref-url" class="md-input md-track-draft" placeholder="https://..." value="' + (currentRef.url || '') + '">');
            $urlInput.on('blur', function() {
                var u = ensureHttps($(this).val());
                $(this).val(u);
                var $siteInp = $('#md-ref-site');
                // Fitur Baru: Otomatis isi nama situs dari URL
                if (u && !$siteInp.val().trim()) {
                    var domain = extractDomain(u);
                    $siteInp.val(domain.charAt(0).toUpperCase() + domain.slice(1));
                    $siteInp.trigger('input');
                }
            });
 
            $refGrid.append('<div class="md-grid-full"><label style="font-size:0.8rem;">URL Website (Link)</label></div>').find('div').last().append($urlInput);
            $refGrid.append('<div><label style="font-size:0.8rem;">Judul Halaman / Artikel</label><input type="text" id="md-ref-title" class="md-input md-track-draft" placeholder="Judul" value="' + (currentRef.title || '') + '"></div>');
            $refGrid.append('<div><label style="font-size:0.8rem;">Nama Situs / Portal</label><input type="text" id="md-ref-site" class="md-input md-track-draft" placeholder="Nama Situs" value="' + (currentRef.site || '') + '"></div>');
            $refGrid.append('<div><label style="font-size:0.8rem;">Penulis (Opsional)</label><input type="text" id="md-ref-author" class="md-input md-track-draft" placeholder="Nama Penulis" value="' + (currentRef.author || '') + '"></div>');
            $refGrid.append('<div><label style="font-size:0.8rem;">Penerbit (Opsional)</label><input type="text" id="md-ref-publisher" class="md-input md-track-draft" placeholder="Penerbit" value="' + (currentRef.publisher || '') + '"></div>');
           
             var $dateBox = $('<div><label style="font-size:0.8rem;">Tanggal Akses</label></div>');
            var $dateInpWrap = $('<div style="display:flex; gap:8px;"></div>');
            var $dateInp = $('<input type="date" id="md-ref-date" class="md-input md-track-draft" value="' + (currentRef.date || '') + '">');
            var $todayBtn = $('<button type="button" class="md-btn-icon" style="padding:6px 10px; font-size:0.8rem; border-color:#cbd5e1;" title="Set Hari Ini">Hari Ini</button>');
            $todayBtn.on('click', function() { $dateInp.val(getTodayString()).trigger('input'); });
            $dateInpWrap.append($dateInp).append($todayBtn);
            $dateBox.append($dateInpWrap);
            $refGrid.append($dateBox);
 
            $refArea.append($refGrid);
            $form.append($refArea);
 
            // TOMBOL AKSI FORM
            var $actions = $('<div class="md-form-actions"></div>');
            var $btnSave = $('<button class="md-btn md-btn-save">Simpan & Terbitkan<span class="md-spinner"></span></button>');
            var $btnCancel = $('<button class="md-btn md-btn-cancel">Batal</button>');
              
              
             $actions.append($btnSave).append($btnCancel);
             $actions.append($btnSave).append($btnCancel);
           
             if (!isNew) {
             if (!isNew) {
                 var $btnDelete = $('<button class="md-btn md-btn-delete">Hapus Data<span class="md-spinner"></span></button>');
                 var $btnDel = $('<button class="md-btn-visit" style="background:#ef4444; margin-left:auto; cursor:pointer; border:none; padding:10px;">Hapus</button>');
                 $btnDelete.on('click', function() {
                 $btnDel.on('click', function() { if(confirm('Hapus data ini?')) { dataItems.splice(index, 1); saveData('Hapus data', $(this), rawContent); }});
                    if(confirm('Yakin ingin menghapus item data ini permanen?')) {
                 $actions.append($btnDel);
                        dataItems.splice(index, 1);
                        saveData('Menghapus data terstruktur', $(this), rawContent);
                    }
                });
                 $actions.append($btnDelete);
            }
 
            $form.append($actions);
            $container.append($form);
 
            $('#md-chk-person').on('change', function() {
                if($(this).is(':checked')) $('#md-social-box').slideDown(200).css('display', 'grid');
                else $('#md-social-box').slideUp(200);
            });
 
            // Animasi Scroll
            $('html, body').animate({ scrollTop: $form.offset().top - 80 }, 300);
           
            $btnCancel.on('click', function() {
                localStorage.removeItem(draftKey);
                $container.empty();
            });
 
            // FITUR BARU: Auto-Save Draft
            function gatherFormData() {
                var socObj = {};
                if ($('#md-chk-person').is(':checked')) {
                    Object.keys(SOCIAL_PLATFORMS).forEach(function(k) {
                        var valU = $('#md-soc-' + k).val().trim();
                        if (valU) socObj[k] = valU;
                    });
                }
                var refObj = {
                    type: $('#md-ref-type').val(),
                    subType: $('#md-ref-subtype').val(),
                    url: ensureHttps($('#md-ref-url').val()),
                    title: $('#md-ref-title').val().trim(),
                    site: $('#md-ref-site').val().trim(),
                    author: $('#md-ref-author').val().trim(),
                    publisher: $('#md-ref-publisher').val().trim(),
                    date: $('#md-ref-date').val()
                };
                Object.keys(refObj).forEach(function(key) { if (!refObj[key]) delete refObj[key]; });
                if (Object.keys(refObj).length === 0) refObj = null;
 
                return {
                    prop: $('#md-inp-prop').val().trim(),
                    val: $('#md-inp-val').val().trim(),
                    link: $('#md-inp-link').is(':checked'),
                    linkSplit: $('#md-inp-split').is(':checked'),
                    linkTarget: $('#md-inp-target').val().trim(),
                    isPersonOrg: $('#md-chk-person').is(':checked'),
                    socials: socObj,
                    ref: refObj
                };
            }
 
            if (isNew) {
                $('.md-track-draft').on('input change', function() {
                    localStorage.setItem(draftKey, JSON.stringify(gatherFormData()));
                });
             }
             }
            $f.append($actions);
            $c.append($f);


            $btnCancel.on('click', function() { $c.empty(); });
             $btnSave.on('click', function() {
             $btnSave.on('click', function() {
                 var newItem = gatherFormData();
                 var p = $('#fm-prop').val().trim();
 
                var v = $('#fm-val').val().trim();
                 if (!newItem.prop || !newItem.val) {
                 if(!p || !v) { $('#fm-prop, #fm-val').addClass('error'); showToast('Label dan Nilai wajib diisi!', 'error'); return; }
                    showToast("Peringatan: Label Data dan Nilai wajib diisi!", 'warning');
                    $('#md-inp-prop').focus();
                    return;
                }


                 if (isNew) dataItems.push(newItem);  
                 var refObj = { url: $('#fm-ref-url').val(), title: $('#fm-ref-title').val(), site: $('#fm-ref-site').val(), author: $('#fm-ref-author').val(), date: $('#fm-ref-date').val() };
                 else dataItems[index] = newItem;  
                 Object.keys(refObj).forEach(k => { if(!refObj[k]) delete refObj[k]; });


                var newItem = { prop: p, val: v, link: $('#fm-link').is(':checked'), isPersonOrg: d.isPersonOrg, socials: d.socials, ref: Object.keys(refObj).length ? refObj : null };
                isNew ? dataItems.push(newItem) : dataItems[index] = newItem;
                 saveData(isNew ? 'Tambah data' : 'Edit data', $(this), rawContent);
                 saveData(isNew ? 'Tambah data' : 'Edit data', $(this), rawContent);
             });
             });
         }
         }


        // 10. FITUR BARU: JSON EXPORT & IMPORT KE FILE
        function showJsonModal(rawContent) {
            var $container = $('#md-form-container');
            $container.empty();
            var jsonStr = JSON.stringify(dataItems, null, 2);
            var $box = $('<div class="md-form-box"></div>');
            $box.append('<h4 class="md-form-title">Ekspor / Impor File JSON</h4>');
            $box.append('<p style="font-size:0.85rem; color:#64748b; margin-bottom:12px;">Anda dapat mendownload struktur data ini sebagai file <b>.json</b> untuk cadangan, atau paste kode JSON untuk memulihkan.</p>');
           
            var $txt = $('<textarea class="md-textarea" rows="12" style="font-family:monospace; font-size:0.8rem; background:#1e293b; color:#10b981; border:none;"></textarea>').val(jsonStr);
            $box.append($txt);
            var $actions = $('<div class="md-form-actions"></div>');
           
            var $btnDownload = $('<button class="md-btn" style="background:#10b981;">Download File JSON</button>');
            var $btnImport = $('<button class="md-btn md-btn-save">Timpa & Impor Data <span class="md-spinner"></span></button>');
            var $btnCancel = $('<button class="md-btn md-btn-cancel">Tutup</button>');
            $btnDownload.on('click', function() {
                var blob = new Blob([$txt.val()], {type: "application/json;charset=utf-8"});
                var url = URL.createObjectURL(blob);
                var a = document.createElement('a');
                a.href = url;
                a.download = 'Mippedia_Data_' + pageName.replace(/ /g, '_') + '.json';
                a.click();
                URL.revokeObjectURL(url);
                showToast('File JSON berhasil didownload!', 'success');
            });
            $actions.append($btnDownload).append($btnImport).append($btnCancel);
            $box.append($actions);
            $container.append($box);
            $('html, body').animate({ scrollTop: $box.offset().top - 80 }, 300);
            $btnCancel.on('click', function() { $container.empty(); });
            $btnImport.on('click', function() {
                try {
                    var parsed = JSON.parse($txt.val());
                    if (Array.isArray(parsed)) {
                        if(confirm('PERHATIAN! Ini akan menimpa seluruh data yang ada. Lanjutkan?')) {
                            dataItems = parsed;
                            saveData('Impor massal dari JSON', $(this), rawContent);
                        }
                    } else {
                        showToast("Format Error: JSON harus berupa Array (diawali dan diakhiri kurung siku).", 'error');
                    }
                } catch(e) {
                    showToast("Format JSON tidak valid!", 'error');
                }
            });
        }
        // 11. EKSEKUSI
         loadData().then(function(rawContent) { buildUI(rawContent); });
         loadData().then(function(rawContent) { buildUI(rawContent); });
     });
     });
})(jQuery, mediaWiki);
})(jQuery, mediaWiki);