{"id":1968,"date":"2026-03-30T07:15:32","date_gmt":"2026-03-30T07:15:32","guid":{"rendered":"https:\/\/marineconservation.id\/?page_id=1968"},"modified":"2026-07-24T01:07:52","modified_gmt":"2026-07-24T01:07:52","slug":"find-your-turtle","status":"publish","type":"page","link":"https:\/\/marineconservation.id\/id\/find-your-turtle\/","title":{"rendered":"Find Your Turtle!"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1968\" class=\"elementor elementor-1968\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6c0f7f7 e-con-full e-flex e-con e-parent\" data-id=\"6c0f7f7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-48b012e elementor-widget elementor-widget-image\" data-id=\"48b012e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-1024x576.png\" class=\"attachment-large size-large wp-image-1816\" alt=\"Sea Turtle Identifcation and Data Collection for Marine Conservation\" srcset=\"https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-1024x576.png 1024w, https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-300x169.png 300w, https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-768x432.png 768w, https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-1536x864.png 1536w, https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-18x10.png 18w, https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau.png 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-a552a6e e-flex e-con-boxed e-con e-parent\" data-id=\"a552a6e\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-420a91c elementor-widget elementor-widget-html\" data-id=\"420a91c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"id\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">\r\n    <title>e-Tu rtle Indonesia \u2013 Upload & Isi Data Penyu<\/title>\r\n    <!-- Leaflet & MarkerCluster -->\r\n    <link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.css\" \/>\r\n    <link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet.markercluster@1.4.1\/dist\/MarkerCluster.css\" \/>\r\n    <link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet.markercluster@1.4.1\/dist\/MarkerCluster.Default.css\" \/>\r\n    <!-- Cropper -->\r\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/cropperjs\/1.5.13\/cropper.min.css\" \/>\r\n    <style>\r\n        * { box-sizing: border-box; }\r\n        body { \r\n            font-family: 'Segoe UI', Arial, sans-serif; \r\n            background: #f8fbff; \r\n            margin: 0; \r\n            padding: 20px; \r\n        }\r\n        .container { max-width: 1400px; margin: 0 auto; }\r\n        \r\n        \/* HEADER *\/\r\n        .header { \r\n            display: flex; \r\n            justify-content: space-between; \r\n            align-items: center; \r\n            flex-wrap: wrap; \r\n            margin-bottom: 24px; \r\n            background: white; \r\n            padding: 18px 24px; \r\n            border-radius: 18px; \r\n            box-shadow: 0 8px 24px rgba(0,0,0,0.08); \r\n        }\r\n        h1 { \r\n            margin: 0; \r\n            color: #0284c7; \r\n            display: flex; \r\n            align-items: center; \r\n            gap: 10px; \r\n            font-size: 1.8rem; \r\n        }\r\n        .language-selector { \r\n            padding: 6px 14px; \r\n            border-radius: 20px; \r\n            border: 1px solid #cbd5e1; \r\n            background: #f8fafc; \r\n            font-size: 14px; \r\n            cursor: pointer; \r\n        }\r\n        \r\n        \/* GRID UTAMA *\/\r\n        .grid { display: flex; flex-wrap: wrap; gap: 24px; }\r\n        \r\n        \/* UPLOAD PANEL - lebih besar (40%) *\/\r\n        .upload-panel { \r\n            flex: 1.2; \r\n            min-width: 380px; \r\n            background: white; \r\n            padding: 24px; \r\n            border-radius: 18px; \r\n            box-shadow: 0 8px 24px rgba(0,0,0,0.08); \r\n            margin-bottom: 24px;\r\n        }\r\n        \r\n        \/* MAP PANEL - lebih kecil (60%) *\/\r\n        .map-panel { \r\n            flex: 2; \r\n            min-width: 300px; \r\n            position: sticky;\r\n            top: 20px;\r\n            align-self: flex-start;\r\n        }\r\n        \r\n        \/* UPLOAD AREA - card besar modern *\/\r\n        .upload-area { \r\n            border: 2px dashed #cbd5e1; \r\n            border-radius: 18px; \r\n            padding: 40px 30px; \r\n            text-align: center; \r\n            margin: 16px 0 20px 0; \r\n            transition: all 0.3s; \r\n            cursor: pointer; \r\n            background: #fafcff; \r\n        }\r\n        .upload-area:hover { \r\n            border-color: #0284c7; \r\n            background: #f0f8ff; \r\n        }\r\n        .upload-area .icon { font-size: 48px; display: block; margin-bottom: 12px; }\r\n        .upload-area h3 { margin: 8px 0 4px 0; color: #1e293b; }\r\n        .upload-area p { color: #64748b; margin: 4px 0; }\r\n        .upload-area .or-text { color: #94a3b8; margin: 8px 0; }\r\n        .upload-area .btn-choose { \r\n            background: #0284c7; \r\n            color: white; \r\n            border: none; \r\n            padding: 10px 32px; \r\n            border-radius: 30px; \r\n            cursor: pointer; \r\n            font-size: 15px; \r\n            font-weight: 600;\r\n            transition: background 0.2s;\r\n            margin-top: 8px;\r\n        }\r\n        .upload-area .btn-choose:hover { background: #0369a1; }\r\n        .upload-area .formats { color: #94a3b8; font-size: 12px; margin-top: 8px; }\r\n        \r\n        .example-section { \r\n            display: flex; \r\n            align-items: center; \r\n            gap: 12px; \r\n            margin: 12px 0;\r\n            padding: 12px 16px;\r\n            background: #f1f5f9;\r\n            border-radius: 12px;\r\n        }\r\n        .example-img { \r\n            max-width: 60px; \r\n            max-height: 60px; \r\n            border-radius: 8px; \r\n            border: 1px solid #e2e8f0; \r\n        }\r\n        .example-text { font-size: 13px; color: #475569; }\r\n        \r\n        \/* FILTER CARD *\/\r\n        .filter-card {\r\n            background: white;\r\n            border-radius: 18px;\r\n            padding: 20px 24px;\r\n            margin-bottom: 16px;\r\n            box-shadow: 0 8px 24px rgba(0,0,0,0.08);\r\n        }\r\n        .filter-card h4 {\r\n            margin: 0 0 14px 0;\r\n            color: #1e293b;\r\n            font-size: 14px;\r\n            font-weight: 600;\r\n        }\r\n        .filter-grid {\r\n            display: grid;\r\n            grid-template-columns: 1fr 1fr;\r\n            gap: 10px;\r\n        }\r\n        .filter-grid .full-width {\r\n            grid-column: 1 \/ -1;\r\n        }\r\n        .filter-grid select,\r\n        .filter-grid input,\r\n        .filter-grid button {\r\n            padding: 8px 12px;\r\n            border-radius: 8px;\r\n            border: 1px solid #e2e8f0;\r\n            font-size: 13px;\r\n            width: 100%;\r\n            background: #f8fafc;\r\n            transition: border-color 0.2s;\r\n        }\r\n        .filter-grid select:focus,\r\n        .filter-grid input:focus {\r\n            border-color: #0284c7;\r\n            outline: none;\r\n            background: white;\r\n        }\r\n        .filter-grid button {\r\n            background: #0284c7;\r\n            color: white;\r\n            border: none;\r\n            font-weight: 600;\r\n            cursor: pointer;\r\n            padding: 10px;\r\n        }\r\n        .filter-grid button:hover { background: #0369a1; }\r\n        \r\n        \/* ========== PERBAIKAN FILTER PENCARIAN ========== *\/\r\n        \/* Override spesifik untuk filter pencarian *\/\r\n        .filter-grid .full-width {\r\n            grid-column: 1 \/ -1;\r\n            display: flex;\r\n            gap: 8px;\r\n            width: 100%;\r\n        }\r\n\r\n        \/* Aturan spesifik untuk input pencarian di dalam .full-width *\/\r\n        .filter-grid .full-width input[type=\"text\"] {\r\n            flex: 1;\r\n            width: auto; \/* override width:100% dari aturan global *\/\r\n            min-width: 0; \/* mencegah overflow *\/\r\n            padding: 8px 12px;\r\n            border-radius: 8px;\r\n            border: 1px solid #e2e8f0;\r\n            font-size: 13px;\r\n            background: #f8fafc;\r\n            transition: border-color 0.2s;\r\n        }\r\n\r\n        \/* Aturan spesifik untuk tombol pencarian di dalam .full-width *\/\r\n        .filter-grid .full-width button {\r\n            flex: 0 0 auto;\r\n            width: auto; \/* override width:100% dari aturan global *\/\r\n            min-width: 60px;\r\n            max-width: 80px;\r\n            padding: 8px 16px;\r\n            border-radius: 8px;\r\n            border: none;\r\n            font-size: 13px;\r\n            font-weight: 600;\r\n            background: #0284c7;\r\n            color: white;\r\n            cursor: pointer;\r\n            transition: background 0.2s;\r\n            white-space: nowrap; \/* mencegah teks turun ke bawah *\/\r\n        }\r\n\r\n        .filter-grid .full-width button:hover {\r\n            background: #0369a1;\r\n        }\r\n\r\n        \/* Aturan untuk memastikan tinggi tombol dan input sama *\/\r\n        .filter-grid .full-width input[type=\"text\"],\r\n        .filter-grid .full-width button {\r\n            height: 40px;\r\n            line-height: 1.5;\r\n            box-sizing: border-box;\r\n        }\r\n        \/* ========== AKHIR PERBAIKAN FILTER PENCARIAN ========== *\/\r\n        \r\n        \/* MAP *\/\r\n        #map { \r\n            height: 420px; \r\n            border-radius: 18px; \r\n            overflow: hidden; \r\n            box-shadow: 0 8px 24px rgba(0,0,0,0.08); \r\n            background: #e5e5e5; \r\n        }\r\n        \r\n        \/* CONTRIBUTOR STATS - lebih ringkas *\/\r\n        .contributor-stats {\r\n            background: white;\r\n            border-radius: 18px;\r\n            padding: 14px 20px;\r\n            margin-top: 16px;\r\n            box-shadow: 0 8px 24px rgba(0,0,0,0.08);\r\n        }\r\n        .contributor-stats h4 {\r\n            margin: 0 0 8px 0;\r\n            color: #1e293b;\r\n            font-size: 14px;\r\n            font-weight: 600;\r\n        }\r\n        .contributor-list {\r\n            display: flex;\r\n            flex-wrap: wrap;\r\n            gap: 8px;\r\n            max-height: 100px;\r\n            overflow-y: auto;\r\n            font-size: 13px;\r\n        }\r\n        .contributor-item {\r\n            background: #e0f2fe;\r\n            padding: 4px 14px;\r\n            border-radius: 20px;\r\n            display: inline-flex;\r\n            align-items: center;\r\n            gap: 6px;\r\n            font-weight: 500;\r\n        }\r\n        .contributor-name { color: #1e293b; }\r\n        .contributor-count {\r\n            background: #0284c7;\r\n            color: white;\r\n            border-radius: 20px;\r\n            padding: 0 10px;\r\n            font-size: 12px;\r\n            font-weight: bold;\r\n        }\r\n        \r\n        \/* PROGRESS STEP *\/\r\n        .progress-steps {\r\n            display: flex;\r\n            justify-content: space-between;\r\n            align-items: center;\r\n            margin: 16px 0 20px 0;\r\n            padding: 0 4px;\r\n        }\r\n        .step {\r\n            display: flex;\r\n            flex-direction: column;\r\n            align-items: center;\r\n            flex: 1;\r\n            position: relative;\r\n        }\r\n        .step .circle {\r\n            width: 32px;\r\n            height: 32px;\r\n            border-radius: 50%;\r\n            background: #e2e8f0;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            font-weight: 700;\r\n            font-size: 13px;\r\n            color: #94a3b8;\r\n            transition: all 0.3s;\r\n            border: 2px solid transparent;\r\n        }\r\n        .step.active .circle {\r\n            background: #0284c7;\r\n            color: white;\r\n            border-color: #0284c7;\r\n            box-shadow: 0 0 0 4px rgba(2,132,199,0.15);\r\n        }\r\n        .step.done .circle {\r\n            background: #16a34a;\r\n            color: white;\r\n            border-color: #16a34a;\r\n        }\r\n        .step .label {\r\n            font-size: 10px;\r\n            margin-top: 4px;\r\n            color: #94a3b8;\r\n            text-align: center;\r\n            font-weight: 600;\r\n        }\r\n        .step.active .label { color: #0284c7; }\r\n        .step.done .label { color: #16a34a; }\r\n        .step .line {\r\n            flex: 1;\r\n            height: 2px;\r\n            background: #e2e8f0;\r\n            position: absolute;\r\n            top: 16px;\r\n            left: calc(50% + 20px);\r\n            right: calc(-50% + 20px);\r\n        }\r\n        .step:last-child .line { display: none; }\r\n        .step.done .line { background: #16a34a; }\r\n        \r\n        \/* RESULT CARD *\/\r\n        .result-box { \r\n            margin-top: 16px; \r\n            padding: 20px; \r\n            border-radius: 18px; \r\n            background: #f8fafc; \r\n            border: 1px solid #e2e8f0;\r\n        }\r\n        .result-match {\r\n            background: #f0fdf4;\r\n            border-left: 4px solid #16a34a;\r\n            padding: 16px;\r\n            border-radius: 12px;\r\n            margin-bottom: 12px;\r\n        }\r\n        .result-new {\r\n            background: #eff6ff;\r\n            border-left: 4px solid #0284c7;\r\n            padding: 16px;\r\n            border-radius: 12px;\r\n            margin-bottom: 12px;\r\n        }\r\n        .result-badge {\r\n            display: inline-block;\r\n            padding: 4px 14px;\r\n            border-radius: 20px;\r\n            font-weight: 600;\r\n            font-size: 13px;\r\n            margin-bottom: 8px;\r\n        }\r\n        .badge-match { background: #16a34a; color: white; }\r\n        .badge-new { background: #0284c7; color: white; }\r\n        .comparison {\r\n            display: flex;\r\n            gap: 16px;\r\n            flex-wrap: wrap;\r\n            margin-top: 12px;\r\n            padding: 12px;\r\n            background: white;\r\n            border-radius: 12px;\r\n        }\r\n        .comparison .photo-box {\r\n            text-align: center;\r\n            flex: 1;\r\n            min-width: 80px;\r\n        }\r\n        .comparison .photo-box img {\r\n            max-width: 100px;\r\n            max-height: 100px;\r\n            border-radius: 8px;\r\n            border: 2px solid #e2e8f0;\r\n            object-fit: cover;\r\n        }\r\n        .comparison .photo-box .label {\r\n            font-size: 11px;\r\n            color: #64748b;\r\n            margin-top: 4px;\r\n        }\r\n        \r\n        \/* DATA FORM - section *\/\r\n        .data-form {\r\n            margin-top: 16px;\r\n        }\r\n        .data-form .hidden-form { display: none; }\r\n        .data-form .form-section {\r\n            margin-bottom: 16px;\r\n            padding: 16px 18px;\r\n            background: #f8fafc;\r\n            border-radius: 12px;\r\n            border: 1px solid #e2e8f0;\r\n        }\r\n        .data-form .form-section h5 {\r\n            margin: 0 0 12px 0;\r\n            color: #1e293b;\r\n            font-size: 14px;\r\n            font-weight: 600;\r\n            display: flex;\r\n            align-items: center;\r\n            gap: 8px;\r\n        }\r\n        .form-group {\r\n            margin-bottom: 12px;\r\n        }\r\n        .form-group:last-child { margin-bottom: 0; }\r\n        .form-group label {\r\n            display: block;\r\n            font-weight: 600;\r\n            margin-bottom: 4px;\r\n            font-size: 13px;\r\n            color: #334155;\r\n        }\r\n        .form-group label .icon { margin-right: 6px; }\r\n        .form-group input,\r\n        .form-group select {\r\n            width: 100%;\r\n            padding: 8px 12px;\r\n            border: 1px solid #e2e8f0;\r\n            border-radius: 8px;\r\n            font-size: 13px;\r\n            background: white;\r\n            transition: border-color 0.2s;\r\n        }\r\n        .form-group input:focus,\r\n        .form-group select:focus {\r\n            border-color: #0284c7;\r\n            outline: none;\r\n            box-shadow: 0 0 0 3px rgba(2,132,199,0.1);\r\n        }\r\n        .coordinate-row {\r\n            display: flex;\r\n            gap: 8px;\r\n        }\r\n        .coordinate-row input { flex: 1; }\r\n        .mini-map {\r\n            height: 150px;\r\n            border-radius: 12px;\r\n            margin-bottom: 8px;\r\n            background: #e5e5e5;\r\n        }\r\n        .suggestion-badge {\r\n            background: #e6f7ff;\r\n            border-left: 3px solid #0284c7;\r\n            padding: 10px 14px;\r\n            margin: 8px 0 12px 0;\r\n            font-size: 13px;\r\n            border-radius: 8px;\r\n            color: #1e293b;\r\n        }\r\n        \r\n        \/* SAVE BUTTON - besar *\/\r\n        .btn-save {\r\n            background: #16a34a;\r\n            color: white;\r\n            border: none;\r\n            padding: 14px 20px;\r\n            border-radius: 12px;\r\n            cursor: pointer;\r\n            font-size: 16px;\r\n            font-weight: 700;\r\n            width: 100%;\r\n            transition: background 0.2s;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 10px;\r\n        }\r\n        .btn-save:hover { background: #15803d; }\r\n        \r\n        \/* SUMMARY CARD *\/\r\n        .summary-card {\r\n            background: #f1f5f9;\r\n            border-radius: 12px;\r\n            padding: 16px 18px;\r\n            margin-bottom: 16px;\r\n            border: 1px solid #e2e8f0;\r\n        }\r\n        .summary-card h5 {\r\n            margin: 0 0 10px 0;\r\n            font-size: 13px;\r\n            color: #475569;\r\n        }\r\n        .summary-item {\r\n            display: flex;\r\n            justify-content: space-between;\r\n            padding: 4px 0;\r\n            font-size: 13px;\r\n            border-bottom: 1px solid #e2e8f0;\r\n        }\r\n        .summary-item:last-child { border-bottom: none; }\r\n        .summary-item .key { color: #64748b; }\r\n        .summary-item .value { color: #1e293b; font-weight: 500; }\r\n        \r\n        #saveStatus { margin-top: 12px; }\r\n        .loading {\r\n            display: inline-block;\r\n            width: 20px;\r\n            height: 20px;\r\n            border: 3px solid #f3f3f3;\r\n            border-top: 3px solid #0284c7;\r\n            border-radius: 50%;\r\n            animation: spin 1s linear infinite;\r\n            vertical-align: middle;\r\n            margin-left: 10px;\r\n        }\r\n        @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\r\n        \r\n        footer {\r\n            text-align: center;\r\n            margin-top: 30px;\r\n            font-size: 12px;\r\n            color: #94a3b8;\r\n        }\r\n        \r\n        \/* RESPONSIVE MOBILE *\/\r\n        @media (max-width: 768px) {\r\n            .grid { flex-direction: column; }\r\n            .upload-panel { order: 1; min-width: auto; }\r\n            .map-panel { order: 2; position: static; }\r\n            .filter-grid { grid-template-columns: 1fr; }\r\n            .filter-grid .full-width { grid-column: 1; }\r\n            .progress-steps { flex-wrap: wrap; gap: 8px; }\r\n            .step { flex: 0 0 auto; }\r\n            .step .line { display: none; }\r\n            .comparison { flex-direction: column; align-items: center; }\r\n            .header { flex-direction: column; gap: 12px; text-align: center; }\r\n            \r\n            \/* Perbaikan filter mobile *\/\r\n            .filter-grid .full-width {\r\n                flex-wrap: nowrap;\r\n                gap: 6px;\r\n            }\r\n            \r\n            .filter-grid .full-width input[type=\"text\"] {\r\n                flex: 1;\r\n                min-width: 0;\r\n                font-size: 12px;\r\n                padding: 8px 10px;\r\n            }\r\n            \r\n            .filter-grid .full-width button {\r\n                flex: 0 0 auto;\r\n                min-width: 50px;\r\n                max-width: 70px;\r\n                padding: 8px 12px;\r\n                font-size: 12px;\r\n                white-space: nowrap;\r\n                overflow: hidden;\r\n                text-overflow: ellipsis;\r\n            }\r\n        }\r\n        @media (max-width: 480px) {\r\n            body { padding: 12px; }\r\n            .upload-panel { padding: 16px; }\r\n            .upload-area { padding: 24px 16px; }\r\n            \r\n            \/* Perbaikan filter mobile kecil *\/\r\n            .filter-grid .full-width input[type=\"text\"] {\r\n                font-size: 11px;\r\n                padding: 6px 8px;\r\n            }\r\n            \r\n            .filter-grid .full-width button {\r\n                min-width: 44px;\r\n                max-width: 60px;\r\n                padding: 6px 10px;\r\n                font-size: 11px;\r\n            }\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n<div class=\"container\">\r\n    <!-- HEADER -->\r\n    <div class=\"header\">\r\n        <h1>\ud83d\udc22 <span id=\"titleText\">e-Turtle Indonesia<\/span><\/h1>\r\n        <select id=\"languageSelect\" class=\"language-selector\">\r\n            <option value=\"id\">\ud83c\uddee\ud83c\udde9 Indonesia<\/option>\r\n            <option value=\"en\">\ud83c\uddec\ud83c\udde7 English<\/option>\r\n        <\/select>\r\n    <\/div>\r\n    \r\n    <div class=\"grid\">\r\n        <!-- UPLOAD PANEL (kiri) -->\r\n        <div class=\"upload-panel\" id=\"uploadPanel\">\r\n            <h3 id=\"uploadTitle\">\ud83d\udc22 Upload Foto Sisi Kiri<\/h3>\r\n            <p id=\"uploadDesc\" style=\"color:#64748b;font-size:14px;margin:4px 0 12px 0;\">Upload foto sisi kiri penyu untuk identifikasi<\/p>\r\n            \r\n            <!-- PROGRESS STEP -->\r\n            <div class=\"progress-steps\" id=\"progressSteps\">\r\n                <div class=\"step active\" id=\"step1\">\r\n                    <div class=\"circle\">1<\/div>\r\n                    <div class=\"label\">Upload<\/div>\r\n                    <div class=\"line\"><\/div>\r\n                <\/div>\r\n                <div class=\"step\" id=\"step2\">\r\n                    <div class=\"circle\">2<\/div>\r\n                    <div class=\"label\">Crop<\/div>\r\n                    <div class=\"line\"><\/div>\r\n                <\/div>\r\n                <div class=\"step\" id=\"step3\">\r\n                    <div class=\"circle\">3<\/div>\r\n                    <div class=\"label\">Analisis<\/div>\r\n                    <div class=\"line\"><\/div>\r\n                <\/div>\r\n                <div class=\"step\" id=\"step4\">\r\n                    <div class=\"circle\">4<\/div>\r\n                    <div class=\"label\">Data<\/div>\r\n                    <div class=\"line\"><\/div>\r\n                <\/div>\r\n                <div class=\"step\" id=\"step5\">\r\n                    <div class=\"circle\">5<\/div>\r\n                    <div class=\"label\">Simpan<\/div>\r\n                <\/div>\r\n            <\/div>\r\n            \r\n            <!-- UPLOAD AREA -->\r\n            <div class=\"upload-area\" id=\"uploadArea\">\r\n                <span class=\"icon\">\ud83d\udcf7<\/span>\r\n                <h3 id=\"uploadAreaTitle\">Upload Left Turtle Photo<\/h3>\r\n                <p id=\"dragText\">Drag &amp; Drop<\/p>\r\n                <p class=\"or-text\">atau<\/p>\r\n                <button id=\"uploadBtn\" class=\"btn-choose\">\ud83d\udcc2 Choose Photo<\/button>\r\n                <p class=\"formats\">PNG \u00b7 JPG \u00b7 JPEG<\/p>\r\n                <input type=\"file\" id=\"leftPhotoInput\" accept=\"image\/*\" style=\"display:none;\">\r\n            <\/div>\r\n            \r\n            <!-- EXAMPLE -->\r\n            <div class=\"example-section\">\r\n                <span id=\"exampleLabel\" style=\"font-weight:500;font-size:13px;color:#475569;\">Contoh foto kiri:<\/span>\r\n                <div id=\"exampleContent\" style=\"display:flex;align-items:center;gap:8px;flex:1;\">Memuat contoh...<\/div>\r\n            <\/div>\r\n            \r\n            <!-- RESULT -->\r\n            <div id=\"analysisResult\" style=\"display:none;\" class=\"result-box\"><\/div>\r\n            \r\n            <!-- DATA FORM -->\r\n            <div id=\"dataForm\" class=\"data-form hidden-form\">\r\n                <div class=\"form-section\">\r\n                    <h5>\ud83d\udc22 Turtle Information<\/h5>\r\n                    <div class=\"form-group\">\r\n                        <label id=\"speciesLabel\"><span class=\"icon\">\ud83d\udc22<\/span>Spesies<\/label>\r\n                        <select id=\"speciesSelect\">\r\n                            <option value=\"\">-- Pilih --<\/option>\r\n                            <option value=\"Chelonia mydas\">Penyu Hijau (Chelonia mydas)<\/option>\r\n                            <option value=\"Eretmochelys imbricata\">Penyu Sisik (Eretmochelys imbricata)<\/option>\r\n                            <option value=\"Lepidochelys olivacea\">Penyu Lekang (Lepidochelys olivacea)<\/option>\r\n                            <option value=\"Caretta caretta\">Penyu Tempayan (Caretta caretta)<\/option>\r\n                            <option value=\"Dermochelys coriacea\">Penyu Belimbing (Dermochelys coriacea)<\/option>\r\n                            <option value=\"Natator depressus\">Penyu Pipih (Natator depressus)<\/option>\r\n                        <\/select>\r\n                    <\/div>\r\n                    <div id=\"newNameGroup\" class=\"form-group\" style=\"display:none;\">\r\n                        <label id=\"newNameLabel\"><span class=\"icon\">\ud83c\udff7\ufe0f<\/span>Nama individu baru (opsional)<\/label>\r\n                        <input type=\"text\" id=\"newTurtleName\" placeholder=\"Contoh: Penyu Hijau Betina 01\">\r\n                    <\/div>\r\n                    <div id=\"suggestionBox\" class=\"suggestion-badge\" style=\"display:none;\"><\/div>\r\n                    <div id=\"matchInfo\" style=\"display:none;padding:10px 14px;background:#e6f7ff;border-radius:8px;font-size:13px;margin-bottom:8px;\"><\/div>\r\n                <\/div>\r\n                \r\n                <div class=\"form-section\">\r\n                    <h5>\ud83d\udccd Location<\/h5>\r\n                    <div class=\"form-group\">\r\n                        <label id=\"locNameLabel\"><span class=\"icon\">\ud83d\udccd<\/span>Nama Lokasi<\/label>\r\n                        <input type=\"text\" id=\"locationName\" placeholder=\"Contoh: Pantai Trisik\">\r\n                    <\/div>\r\n                    <div class=\"form-group\">\r\n                        <label id=\"coordinateLabel\"><span class=\"icon\">\ud83d\uddfa\ufe0f<\/span>Koordinat (klik peta mini)<\/label>\r\n                        <div id=\"miniMap\" class=\"mini-map\"><\/div>\r\n                        <div class=\"coordinate-row\">\r\n                            <input type=\"number\" step=\"any\" id=\"latitude\" placeholder=\"Latitude\">\r\n                            <input type=\"number\" step=\"any\" id=\"longitude\" placeholder=\"Longitude\">\r\n                        <\/div>\r\n                    <\/div>\r\n                    <div class=\"form-group\">\r\n                        <label id=\"provinceLabel\"><span class=\"icon\">\ud83c\udfdb\ufe0f<\/span>Provinsi<\/label>\r\n                        <select id=\"provinceSelect\"><option value=\"\">Pilih Provinsi<\/option><\/select>\r\n                    <\/div>\r\n                    <div class=\"form-group\">\r\n                        <label id=\"districtLabel\"><span class=\"icon\">\ud83c\udfd9\ufe0f<\/span>Kabupaten\/Kota<\/label>\r\n                        <select id=\"districtSelect\"><option value=\"\">Pilih Kab\/Kota<\/option><\/select>\r\n                    <\/div>\r\n                <\/div>\r\n                \r\n                <div class=\"form-section\">\r\n                    <h5>\ud83d\udccb Observation<\/h5>\r\n                    <div class=\"form-group\">\r\n                        <label id=\"dateLabel\"><span class=\"icon\">\ud83d\udcc5<\/span>Tanggal<\/label>\r\n                        <input type=\"date\" id=\"surveyDate\">\r\n                    <\/div>\r\n                    <div class=\"form-group\">\r\n                        <label id=\"contributorLabel\"><span class=\"icon\">\ud83d\udc64<\/span>Nama Kontributor (opsional)<\/label>\r\n                        <input type=\"text\" id=\"contributorName\" placeholder=\"Contoh: Yayasan Penyu Indonesia\">\r\n                    <\/div>\r\n                <\/div>\r\n                \r\n                <!-- SUMMARY -->\r\n                <div class=\"summary-card\" id=\"summaryCard\">\r\n                    <h5>\ud83d\udccb Ringkasan Data<\/h5>\r\n                    <div class=\"summary-item\"><span class=\"key\">Spesies<\/span><span class=\"value\" id=\"summarySpecies\">-<\/span><\/div>\r\n                    <div class=\"summary-item\"><span class=\"key\">Lokasi<\/span><span class=\"value\" id=\"summaryLocation\">-<\/span><\/div>\r\n                    <div class=\"summary-item\"><span class=\"key\">Tanggal<\/span><span class=\"value\" id=\"summaryDate\">-<\/span><\/div>\r\n                    <div class=\"summary-item\"><span class=\"key\">Kontributor<\/span><span class=\"value\" id=\"summaryContributor\">-<\/span><\/div>\r\n                <\/div>\r\n                \r\n                <!-- SAVE BUTTON -->\r\n                <button id=\"submitDataBtn\" class=\"btn-save\">\ud83d\udcbe Simpan Turtle Record<\/button>\r\n                <div id=\"saveStatus\" style=\"display:none;margin-top:12px;\"><\/div>\r\n            <\/div>\r\n        <\/div>\r\n        \r\n        <!-- MAP PANEL (kanan) -->\r\n        <div class=\"map-panel\">\r\n            <!-- FILTER CARD -->\r\n            <div class=\"filter-card\">\r\n                <h4>\ud83d\udd0d Filter Data<\/h4>\r\n                <div class=\"filter-grid\">\r\n                    <select id=\"filterProvince\"><option value=\"\">Semua Provinsi<\/option><\/select>\r\n                    <select id=\"filterDistrict\"><option value=\"\">Semua Kab\/Kota<\/option><\/select>\r\n                    <select id=\"filterSex\"><option value=\"\">Semua Kelamin<\/option><option value=\"Jantan\">Jantan<\/option><option value=\"Betina\">Betina<\/option><\/select>\r\n                    <input type=\"number\" id=\"filterMinCCL\" placeholder=\"Min CCL (cm)\" step=\"0.1\">\r\n                    <!-- PERBAIKAN: Hapus inline style pada input dan button -->\r\n                    <div class=\"full-width\" style=\"display:flex;gap:8px;\">\r\n                        <input type=\"text\" id=\"searchInput\" placeholder=\"Cari ID, lokasi...\">\r\n                        <button id=\"applyFilter\">\ud83d\udd0d Cari<\/button>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n            \r\n            <!-- MAP -->\r\n            <div id=\"map\"><\/div>\r\n            \r\n            <!-- CONTRIBUTOR STATS -->\r\n            <div class=\"contributor-stats\" id=\"contributorStats\">\r\n                <h4>\ud83c\udfc6 <span id=\"contributorTitle\">Kontributor Terbanyak<\/span><\/h4>\r\n                <div id=\"contributorList\" class=\"contributor-list\">Memuat data...<\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n    \r\n    <footer id=\"footerText\">\u00a9 e-Turtle Indonesia \u2013 Data publik, tanpa login.<\/footer>\r\n<\/div>\r\n\r\n<script src=\"https:\/\/code.jquery.com\/jquery-3.6.0.min.js\"><\/script>\r\n<script src=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js\"><\/script>\r\n<script src=\"https:\/\/unpkg.com\/leaflet.markercluster@1.4.1\/dist\/leaflet.markercluster.js\"><\/script>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/cropperjs\/1.5.13\/cropper.min.js\"><\/script>\r\n\r\n<script>\r\n\/\/ ========== KONFIGURASI ==========\r\nconst themeFolder = 'astra';\r\nconst analyzeEndpoint = `\/wp-content\/themes\/${themeFolder}\/turtle-api\/turtle-analyze.php`;\r\nconst getDataEndpoint = `\/wp-content\/themes\/${themeFolder}\/turtle-api\/turtle-get.php`;\r\nconst saveEndpoint = `\/wp-content\/themes\/${themeFolder}\/turtle-api\/turtle-save.php`;\r\n\r\n\/\/ ========== BAHASA ==========\r\nconst translations = {\r\n    id: {\r\n        title:\"e-Turtle Indonesia\", uploadTitle:\"\ud83d\udc22 Upload Foto Sisi Kiri\", uploadDesc:\"Upload foto sisi kiri penyu untuk identifikasi\",\r\n        uploadAreaTitle:\"Upload Left Turtle Photo\", dragText:\"Drag & Drop\", orText:\"atau\", chooseBtn:\"\ud83d\udcc2 Pilih Foto\", formats:\"PNG \u00b7 JPG \u00b7 JPEG\",\r\n        exampleLabel:\"Contoh foto kiri:\",\r\n        analyzing:\"\ud83d\udd0d Menganalisis pola...\", matchFound:\"\u2705 Individu Ditemukan\", newIndividual:\"\ud83c\udd95 Individu Baru\",\r\n        saving:\"\ud83d\udcbe Menyimpan...\", saveSuccess:\"\u2705 Data berhasil disimpan!\", saveError:\"\u274c Gagal menyimpan: \",\r\n        errorMsg:\"\u274c Gagal menganalisis: \", serverError:\"\u274c Gagal hubungi server: \", processError:\"\u274c Gagal proses foto: \",\r\n        noExample:\"Belum ada contoh.\", similarity:\"Kemiripan\", id:\"ID\", name:\"Nama\", species:\"Spesies\",\r\n        photoUpload:\"Foto Upload\", photoDB:\"Foto DB\", photoNotAvailable:\"Tidak ada\", suggestedSpecies:\"Spesies saran: \",\r\n        footer:\"\u00a9 e-Turtle Indonesia \u2013 Data publik, tanpa login.\",\r\n        speciesLabel:\"Spesies\", locNameLabel:\"Nama Lokasi\", coordinateLabel:\"Koordinat (klik peta mini)\", provinceLabel:\"Provinsi\",\r\n        districtLabel:\"Kabupaten\/Kota\", dateLabel:\"Tanggal\", contributorLabel:\"Nama Kontributor (opsional)\",\r\n        newNameLabel:\"Nama individu baru (opsional)\", submitBtn:\"\ud83d\udcbe Simpan Turtle Record\",\r\n        matchInfoText:\"Individu cocok: {name} (ID: {id}) - Kemiripan {conf}%\",\r\n        previousLocationSuggestion:\"\ud83d\udccd Lokasi pertemuan sebelumnya: {loc} ({date})\",\r\n        loginError:\"\u274c Endpoint memerlukan login. Periksa kembali backend.\",\r\n        contributorTitle:\"\ud83c\udfc6 Kontributor Terbanyak\",\r\n        allProvince:\"Semua Provinsi\", allDistrict:\"Semua Kab\/Kota\", searchPlaceholder:\"Cari ID, lokasi...\",\r\n        allSex:\"Semua Kelamin\", male:\"Jantan\", female:\"Betina\", minCclPlaceholder:\"Min CCL (cm)\",\r\n        selectProvince:\"Pilih Provinsi\", selectDistrict:\"Pilih Kab\/Kota\", contributorPlaceholder:\"Contoh: Yayasan Penyu Indonesia\",\r\n        newTurtlePlaceholder:\"Contoh: Penyu Hijau Betina 01\", latPlaceholder:\"Contoh: -8.4095\", lngPlaceholder:\"Contoh: 115.1889\",\r\n        locationPlaceholder:\"Contoh: Pantai Trisik\", loadingData:\"Memuat data...\", noContributorData:\"Belum ada data\",\r\n        cropModalTitle:\"Crop Foto\", cancelCrop:\"Batal\", cropBtn:\"Crop\", contributorPopup:\"Kontributor:\",\r\n        alertRequired:\"Harap isi semua field wajib (tanggal, koordinat, spesies)\", alertCropInit:\"Gagal memuat editor crop. Silakan coba lagi.\",\r\n        alertCropWait:\"Mohon tunggu sebentar, editor crop masih bersiap.\", alertCropFail:\"Gagal memotong gambar, coba lagi.\",\r\n        alertInvalidFile:\"Harap unggah file gambar.\", alertImageLoad:\"Gagal memuat gambar. Coba file lain.\",\r\n        summaryTitle:\"Ringkasan Data\", summarySpecies:\"Spesies\", summaryLocation:\"Lokasi\", summaryDate:\"Tanggal\", summaryContributor:\"Kontributor\"\r\n    },\r\n    en: {\r\n        title:\"e-Turtle Indonesia\", uploadTitle:\"\ud83d\udc22 Upload Left Side Photo\", uploadDesc:\"Upload left side photo for identification\",\r\n        uploadAreaTitle:\"Upload Left Turtle Photo\", dragText:\"Drag & Drop\", orText:\"or\", chooseBtn:\"\ud83d\udcc2 Choose Photo\", formats:\"PNG \u00b7 JPG \u00b7 JPEG\",\r\n        exampleLabel:\"Example left photo:\",\r\n        analyzing:\"\ud83d\udd0d Analyzing pattern...\", matchFound:\"\u2705 Individual Found\", newIndividual:\"\ud83c\udd95 New Individual\",\r\n        saving:\"\ud83d\udcbe Saving...\", saveSuccess:\"\u2705 Data saved successfully!\", saveError:\"\u274c Save failed: \",\r\n        errorMsg:\"\u274c Analysis failed: \", serverError:\"\u274c Server error: \", processError:\"\u274c Photo processing failed: \",\r\n        noExample:\"No example yet.\", similarity:\"Similarity\", id:\"ID\", name:\"Name\", species:\"Species\",\r\n        photoUpload:\"Uploaded Photo\", photoDB:\"Database Photo\", photoNotAvailable:\"N\/A\", suggestedSpecies:\"Suggested species: \",\r\n        footer:\"\u00a9 e-Turtle Indonesia \u2013 Public data, no login.\",\r\n        speciesLabel:\"Species\", locNameLabel:\"Location Name\", coordinateLabel:\"Coordinates (click on mini map)\", provinceLabel:\"Province\",\r\n        districtLabel:\"Regency\/City\", dateLabel:\"Date\", contributorLabel:\"Contributor Name (optional)\",\r\n        newNameLabel:\"New individual name (optional)\", submitBtn:\"\ud83d\udcbe Save Turtle Record\",\r\n        matchInfoText:\"Matching: {name} (ID: {id}) - {conf}% similarity\",\r\n        previousLocationSuggestion:\"\ud83d\udccd Previous location: {loc} ({date})\",\r\n        loginError:\"\u274c Endpoint requires login. Please check backend.\",\r\n        contributorTitle:\"\ud83c\udfc6 Top Contributors\",\r\n        allProvince:\"All Provinces\", allDistrict:\"All Regencies\/Cities\", searchPlaceholder:\"Search ID, location...\",\r\n        allSex:\"All Sexes\", male:\"Male\", female:\"Female\", minCclPlaceholder:\"Min CCL (cm)\",\r\n        selectProvince:\"Select Province\", selectDistrict:\"Select Regency\/City\", contributorPlaceholder:\"e.g., Turtle Foundation\",\r\n        newTurtlePlaceholder:\"e.g., Green Female 01\", latPlaceholder:\"e.g., -8.4095\", lngPlaceholder:\"e.g., 115.1889\",\r\n        locationPlaceholder:\"e.g., Kuta Beach\", loadingData:\"Loading data...\", noContributorData:\"No data yet\",\r\n        cropModalTitle:\"Crop Photo\", cancelCrop:\"Cancel\", cropBtn:\"Crop\", contributorPopup:\"Contributor:\",\r\n        alertRequired:\"Please fill all required fields (date, coordinates, species)\", alertCropInit:\"Failed to load crop editor. Please try again.\",\r\n        alertCropWait:\"Please wait, crop editor is initializing.\", alertCropFail:\"Failed to crop image, try again.\",\r\n        alertInvalidFile:\"Please upload an image file.\", alertImageLoad:\"Failed to load image. Try another file.\",\r\n        summaryTitle:\"Data Summary\", summarySpecies:\"Species\", summaryLocation:\"Location\", summaryDate:\"Date\", summaryContributor:\"Contributor\"\r\n    }\r\n};\r\n\r\nlet currentLang = 'id';\r\nlet allData = [], filteredAllData = [], map, markersCluster, miniMap, miniMarker;\r\nlet currentMatch = null, currentPhotoBase64 = null, suggestedSpecies = null, currentTempId = null, isNewIndividual = false;\r\n\r\nfunction getText(k) { return translations[currentLang][k] || translations.id[k]; }\r\n\r\n\/\/ ========== UPDATE UI ==========\r\nfunction updateUI() {\r\n    const t = translations[currentLang];\r\n    document.getElementById('titleText').innerText = t.title;\r\n    document.getElementById('uploadTitle').innerHTML = t.uploadTitle;\r\n    document.getElementById('uploadDesc').innerHTML = t.uploadDesc;\r\n    document.getElementById('uploadAreaTitle').innerHTML = t.uploadAreaTitle;\r\n    document.getElementById('dragText').innerHTML = t.dragText;\r\n    document.querySelector('.upload-area .or-text').innerHTML = t.orText;\r\n    document.querySelector('.btn-choose').innerHTML = t.chooseBtn;\r\n    document.querySelector('.upload-area .formats').innerHTML = t.formats;\r\n    document.getElementById('exampleLabel').innerHTML = t.exampleLabel;\r\n    document.getElementById('footerText').innerHTML = t.footer;\r\n    document.getElementById('speciesLabel').innerHTML = '<span class=\"icon\">\ud83d\udc22<\/span>' + t.speciesLabel;\r\n    document.getElementById('locNameLabel').innerHTML = '<span class=\"icon\">\ud83d\udccd<\/span>' + t.locNameLabel;\r\n    document.getElementById('coordinateLabel').innerHTML = '<span class=\"icon\">\ud83d\uddfa\ufe0f<\/span>' + t.coordinateLabel;\r\n    document.getElementById('provinceLabel').innerHTML = '<span class=\"icon\">\ud83c\udfdb\ufe0f<\/span>' + t.provinceLabel;\r\n    document.getElementById('districtLabel').innerHTML = '<span class=\"icon\">\ud83c\udfd9\ufe0f<\/span>' + t.districtLabel;\r\n    document.getElementById('dateLabel').innerHTML = '<span class=\"icon\">\ud83d\udcc5<\/span>' + t.dateLabel;\r\n    document.getElementById('contributorLabel').innerHTML = '<span class=\"icon\">\ud83d\udc64<\/span>' + t.contributorLabel;\r\n    document.getElementById('newNameLabel').innerHTML = '<span class=\"icon\">\ud83c\udff7\ufe0f<\/span>' + t.newNameLabel;\r\n    document.getElementById('submitDataBtn').innerHTML = '\ud83d\udcbe ' + t.submitBtn;\r\n    document.getElementById('contributorTitle').innerHTML = t.contributorTitle;\r\n    document.getElementById('summarySpecies').innerHTML = t.summarySpecies;\r\n    document.getElementById('summaryLocation').innerHTML = t.summaryLocation;\r\n    document.getElementById('summaryDate').innerHTML = t.summaryDate;\r\n    document.getElementById('summaryContributor').innerHTML = t.summaryContributor;\r\n    \r\n    \/\/ Placeholder\r\n    document.getElementById('searchInput').placeholder = t.searchPlaceholder;\r\n    document.getElementById('filterMinCCL').placeholder = t.minCclPlaceholder;\r\n    document.getElementById('locationName').placeholder = t.locationPlaceholder;\r\n    document.getElementById('latitude').placeholder = t.latPlaceholder;\r\n    document.getElementById('longitude').placeholder = t.lngPlaceholder;\r\n    document.getElementById('contributorName').placeholder = t.contributorPlaceholder;\r\n    document.getElementById('newTurtleName').placeholder = t.newTurtlePlaceholder;\r\n    \r\n    \/\/ Filter sex\r\n    const sexSelect = document.getElementById('filterSex');\r\n    sexSelect.innerHTML = `<option value=\"\">${t.allSex}<\/option>\r\n                           <option value=\"Jantan\">${t.male}<\/option>\r\n                           <option value=\"Betina\">${t.female}<\/option>`;\r\n    \r\n    \/\/ Modal crop\r\n    const modalTitle = document.querySelector('#cropModal h3');\r\n    if (modalTitle) modalTitle.innerText = t.cropModalTitle;\r\n    const cancelBtn = document.getElementById('cancelCrop');\r\n    if (cancelBtn) cancelBtn.innerText = t.cancelCrop;\r\n    const cropBtnModal = document.getElementById('cropButton');\r\n    if (cropBtnModal) cropBtnModal.innerText = t.cropBtn;\r\n    \r\n    refreshMapSize();\r\n}\r\n\r\n\/\/ ========== REFRESH MAP ==========\r\nfunction refreshMapSize() {\r\n    setTimeout(() => {\r\n        if (map) map.invalidateSize();\r\n        if (miniMap) miniMap.invalidateSize();\r\n    }, 100);\r\n}\r\n\r\n\/\/ ========== ESCAPE HTML ==========\r\nfunction escapeHtml(str) {\r\n    return str.replace(\/[&<>]\/g, function(m) {\r\n        if (m === '&') return '&amp;';\r\n        if (m === '<') return '&lt;';\r\n        if (m === '>') return '&gt;';\r\n        return m;\r\n    });\r\n}\r\n\r\n\/\/ ========== PROGRESS STEPS ==========\r\nfunction updateProgress(step) {\r\n    for (let i = 1; i <= 5; i++) {\r\n        const el = document.getElementById('step' + i);\r\n        el.classList.remove('active', 'done');\r\n        if (i < step) el.classList.add('done');\r\n        else if (i === step) el.classList.add('active');\r\n    }\r\n}\r\n\r\n\/\/ ========== API FETCH ==========\r\nasync function apiFetch(url, options = {}) {\r\n    const res = await fetch(url, { ...options, credentials: 'omit' });\r\n    if (res.status === 401 || res.status === 403) throw new Error(getText('loginError'));\r\n    if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n    return res.json();\r\n}\r\n\r\n\/\/ ========== RENDER CONTRIBUTOR ==========\r\nfunction renderContributorStats(data) {\r\n    const container = document.getElementById('contributorList');\r\n    if (!container) return;\r\n    const freq = {};\r\n    data.forEach(item => {\r\n        let contr = item.contributor || 'Anonymous';\r\n        if (contr === '') contr = 'Anonymous';\r\n        freq[contr] = (freq[contr] || 0) + 1;\r\n    });\r\n    const sorted = Object.entries(freq).sort((a,b) => b[1] - a[1]);\r\n    if (sorted.length === 0) {\r\n        container.innerHTML = '<span style=\"color:#94a3b8;font-size:13px;\">' + getText('noContributorData') + '<\/span>';\r\n        return;\r\n    }\r\n    let html = '';\r\n    const medals = ['\ud83e\udd47', '\ud83e\udd48', '\ud83e\udd49'];\r\n    sorted.slice(0, 10).forEach(([name, count], idx) => {\r\n        const medal = idx < 3 ? medals[idx] : `${idx+1}.`;\r\n        html += `<div class=\"contributor-item\"><span>${medal}<\/span><span class=\"contributor-name\">${escapeHtml(name)}<\/span><span class=\"contributor-count\">${count}<\/span><\/div>`;\r\n    });\r\n    container.innerHTML = html;\r\n}\r\n\r\n\/\/ ========== LOAD DATA ==========\r\nasync function loadData() {\r\n    try {\r\n        const data = await apiFetch(getDataEndpoint);\r\n        allData = data;\r\n        filteredAllData = [...allData];\r\n        const provinces = [...new Set(allData.map(d => d.province).filter(p => p))];\r\n        const districts = [...new Set(allData.map(d => d.district).filter(d => d))];\r\n        document.getElementById('filterProvince').innerHTML = '<option value=\"\">' + getText('allProvince') + '<\/option>' + provinces.sort().map(p => `<option value=\"${p}\">${p}<\/option>`).join('');\r\n        document.getElementById('filterDistrict').innerHTML = '<option value=\"\">' + getText('allDistrict') + '<\/option>' + districts.sort().map(d => `<option value=\"${d}\">${d}<\/option>`).join('');\r\n        filterData();\r\n        const example = allData.find(d => d.left_photo_url);\r\n        document.getElementById('exampleContent').innerHTML = example ? \r\n            `<img decoding=\"async\" src=\"${example.left_photo_url}\" class=\"example-img\"><span class=\"example-text\">${getText('id')}: ${example.turtle_id}<\/span>` : \r\n            `<span class=\"example-text\">${getText('noExample')}<\/span>`;\r\n        renderContributorStats(allData);\r\n        refreshMapSize();\r\n    } catch (err) { console.error(err); document.getElementById('exampleContent').innerHTML = `<span style=\"color:red;font-size:13px;\">${err.message}<\/span>`; }\r\n}\r\n\r\n\/\/ ========== FILTER DATA ==========\r\nfunction filterData() {\r\n    const province = document.getElementById('filterProvince').value;\r\n    const district = document.getElementById('filterDistrict').value;\r\n    const search = document.getElementById('searchInput').value.toLowerCase();\r\n    const sex = document.getElementById('filterSex').value;\r\n    const minCCL = parseFloat(document.getElementById('filterMinCCL').value);\r\n    filteredAllData = allData.filter(item => {\r\n        if (province && item.province !== province) return false;\r\n        if (district && item.district !== district) return false;\r\n        if (search && !Object.values(item).join(' ').toLowerCase().includes(search)) return false;\r\n        if (sex && item.sex !== sex) return false;\r\n        if (!isNaN(minCCL) && (parseFloat(item.ccl) || 0) < minCCL) return false;\r\n        return true;\r\n    });\r\n    updateMapMarkers(filteredAllData);\r\n    refreshMapSize();\r\n}\r\n\r\n\/\/ ========== UPDATE MAP ==========\r\nfunction updateMapMarkers(data) {\r\n    if (!map) return;\r\n    if (markersCluster) map.removeLayer(markersCluster);\r\n    markersCluster = L.markerClusterGroup({ chunkedLoading: true });\r\n    const nameMap = new Map(); allData.forEach(i => { if(i.turtle_id && i.turtle_name) nameMap.set(i.turtle_id, i.turtle_name); });\r\n    data.forEach(item => {\r\n        const lat = parseFloat(item.latitude), lng = parseFloat(item.longitude);\r\n        if (isNaN(lat) || isNaN(lng)) return;\r\n        let displayName = nameMap.get(item.turtle_id) || item.turtle_name || 'Penyu';\r\n        let contributorText = item.contributor ? `${getText('contributorPopup')} ${item.contributor}` : `${getText('contributorPopup')} -`;\r\n        L.marker([lat, lng]).bindPopup(`<b>${displayName}<\/b><br><img decoding=\"async\" src=\"${item.left_photo_url}\" style=\"max-width:100px;\"><br>${getText('id')}: ${item.turtle_id}<br>${getText('dateLabel')}: ${item.survey_date}<br>${getText('speciesLabel')}: ${item.species}<br>${contributorText}`).addTo(markersCluster);\r\n    });\r\n    map.addLayer(markersCluster);\r\n    if(data.length){ \r\n        let bounds = L.featureGroup(data.map(d=>L.marker([d.latitude,d.longitude]))).getBounds(); \r\n        if(bounds.isValid()) map.fitBounds(bounds); \r\n    } else map.setView([-2.5,118],5);\r\n    refreshMapSize();\r\n}\r\n\r\nfunction initMapMain(){ \r\n    map = L.map('map').setView([-2.5,118],5); \r\n    L.tileLayer('https:\/\/server.arcgisonline.com\/ArcGIS\/rest\/services\/World_Imagery\/MapServer\/tile\/{z}\/{y}\/{x}', { attribution: 'Tiles &copy; Esri' }).addTo(map); \r\n    markersCluster = L.markerClusterGroup(); \r\n    map.addLayer(markersCluster);\r\n    refreshMapSize();\r\n    window.addEventListener('resize', () => refreshMapSize());\r\n    document.addEventListener('visibilitychange', () => { if(!document.hidden) refreshMapSize(); });\r\n}\r\n\r\n\/\/ ========== MINI MAP ==========\r\nfunction initMiniMap(){\r\n    miniMap = L.map('miniMap').setView([-2.5,118],5);\r\n    L.tileLayer('https:\/\/server.arcgisonline.com\/ArcGIS\/rest\/services\/World_Imagery\/MapServer\/tile\/{z}\/{y}\/{x}', { attribution: 'Tiles &copy; Esri' }).addTo(miniMap);\r\n    miniMarker = null;\r\n    miniMap.on('click', e => { let lat=e.latlng.lat.toFixed(6), lng=e.latlng.lng.toFixed(6); document.getElementById('latitude').value=lat; document.getElementById('longitude').value=lng; if(miniMarker) miniMap.removeLayer(miniMarker); miniMarker = L.marker([lat,lng]).addTo(miniMap); miniMap.setView([lat,lng],10); fillFromCoordinates(lat,lng); refreshMapSize(); });\r\n    const latI=document.getElementById('latitude'), lngI=document.getElementById('longitude');\r\n    latI.addEventListener('input',()=>updateMiniMarker()); lngI.addEventListener('input',()=>updateMiniMarker());\r\n    function updateMiniMarker(){ let lat=parseFloat(latI.value), lng=parseFloat(lngI.value); if(!isNaN(lat)&&!isNaN(lng)){ if(miniMarker) miniMap.removeLayer(miniMarker); miniMarker = L.marker([lat,lng]).addTo(miniMap); miniMap.setView([lat,lng],10); fillFromCoordinates(lat,lng); refreshMapSize(); } }\r\n    refreshMapSize();\r\n}\r\n\r\nasync function fillFromCoordinates(lat,lng){\r\n    try{ let res=await fetch(`https:\/\/api.bigdatacloud.net\/data\/reverse-geocode-client?latitude=${lat}&longitude=${lng}&localityLanguage=id&radius=10000`); let data=await res.json(); let province='', city=''; data.localityInfo.administrative.forEach(a=>{ if(a.adminLevel===4) province=a.name; if(a.adminLevel===6) city=a.name; }); let provSelect=document.getElementById('provinceSelect'); for(let i=0;i<provSelect.options.length;i++) if(provSelect.options[i].text===province){ provSelect.value=provSelect.options[i].value; provSelect.dispatchEvent(new Event('change')); setTimeout(()=>{ let distSelect=document.getElementById('districtSelect'); for(let j=0;j<distSelect.options.length;j++) if(distSelect.options[j].text===city) distSelect.value=distSelect.options[j].value; refreshMapSize(); },300); break; } }catch(e){console.error(e);} \r\n}\r\n\r\n\/\/ ========== REGIONS ==========\r\nconst indonesiaRegions = {\r\n    \"Aceh\": [\"Aceh Barat\", \"Aceh Barat Daya\", \"Aceh Besar\", \"Aceh Jaya\", \"Aceh Selatan\", \"Aceh Singkil\", \"Aceh Tamiang\", \"Aceh Tengah\", \"Aceh Tenggara\", \"Aceh Timur\", \"Aceh Utara\", \"Bener Meriah\", \"Bireuen\", \"Gayo Lues\", \"Nagan Raya\", \"Pidie\", \"Pidie Jaya\", \"Simeulue\", \"Kota Banda Aceh\", \"Kota Langsa\", \"Kota Lhokseumawe\", \"Kota Sabang\", \"Kota Subulussalam\"],\r\n    \"Sumatera Utara\": [\"Asahan\", \"Batu Bara\", \"Dairi\", \"Deli Serdang\", \"Humbang Hasundutan\", \"Karo\", \"Labuhanbatu\", \"Labuhanbatu Selatan\", \"Labuhanbatu Utara\", \"Langkat\", \"Mandailing Natal\", \"Nias\", \"Nias Barat\", \"Nias Selatan\", \"Nias Utara\", \"Padang Lawas\", \"Padang Lawas Utara\", \"Pakpak Bharat\", \"Samosir\", \"Serdang Bedagai\", \"Simalungun\", \"Tapanuli Selatan\", \"Tapanuli Tengah\", \"Tapanuli Utara\", \"Toba\", \"Kota Binjai\", \"Kota Gunungsitoli\", \"Kota Medan\", \"Kota Padangsidimpuan\", \"Kota Pematangsiantar\", \"Kota Sibolga\", \"Kota Tanjungbalai\", \"Kota Tebing Tinggi\"],\r\n    \"Sumatera Barat\": [\"Agam\", \"Dharmasraya\", \"Kepulauan Mentawai\", \"Lima Puluh Kota\", \"Padang Pariaman\", \"Pasaman\", \"Pasaman Barat\", \"Pesisir Selatan\", \"Sijunjung\", \"Solok\", \"Solok Selatan\", \"Tanah Datar\", \"Kota Bukittinggi\", \"Kota Padang\", \"Kota Padang Panjang\", \"Kota Pariaman\", \"Kota Payakumbuh\", \"Kota Sawahlunto\", \"Kota Solok\"],\r\n    \"Riau\": [\"Bengkalis\", \"Indragiri Hilir\", \"Indragiri Hulu\", \"Kampar\", \"Kepulauan Meranti\", \"Kuantan Singingi\", \"Pelalawan\", \"Rokan Hilir\", \"Rokan Hulu\", \"Siak\", \"Kota Dumai\", \"Kota Pekanbaru\"],\r\n    \"Kepulauan Riau\": [\"Bintan\", \"Karimun\", \"Kepulauan Anambas\", \"Lingga\", \"Natuna\", \"Kota Batam\", \"Kota Tanjungpinang\"],\r\n    \"Jambi\": [\"Batanghari\", \"Bungo\", \"Kerinci\", \"Merangin\", \"Muaro Jambi\", \"Sarolangun\", \"Tanjung Jabung Barat\", \"Tanjung Jabung Timur\", \"Tebo\", \"Kota Jambi\", \"Kota Sungai Penuh\"],\r\n    \"Bengkulu\": [\"Bengkulu Selatan\", \"Bengkulu Tengah\", \"Bengkulu Utara\", \"Kaur\", \"Kepahiang\", \"Lebong\", \"Muko Muko\", \"Rejang Lebong\", \"Seluma\", \"Kota Bengkulu\"],\r\n    \"Sumatera Selatan\": [\"Banyuasin\", \"Empat Lawang\", \"Lahat\", \"Muara Enim\", \"Musi Banyuasin\", \"Musi Rawas\", \"Musi Rawas Utara\", \"Ogan Ilir\", \"Ogan Komering Ilir\", \"Ogan Komering Ulu\", \"Ogan Komering Ulu Selatan\", \"Ogan Komering Ulu Timur\", \"Penukal Abab Lematang Ilir\", \"Kota Lubuklinggau\", \"Kota Pagar Alam\", \"Kota Palembang\", \"Kota Prabumulih\"],\r\n    \"Bangka Belitung\": [\"Bangka\", \"Bangka Barat\", \"Bangka Selatan\", \"Bangka Tengah\", \"Belitung\", \"Belitung Timur\", \"Kota Pangkalpinang\"],\r\n    \"Lampung\": [\"Lampung Barat\", \"Lampung Selatan\", \"Lampung Tengah\", \"Lampung Timur\", \"Lampung Utara\", \"Mesuji\", \"Pesawaran\", \"Pesisir Barat\", \"Pringsewu\", \"Tanggamus\", \"Tulang Bawang\", \"Tulang Bawang Barat\", \"Way Kanan\", \"Kota Bandar Lampung\", \"Kota Metro\"],\r\n    \"Banten\": [\"Lebak\", \"Pandeglang\", \"Serang\", \"Tangerang\", \"Kota Cilegon\", \"Kota Serang\", \"Kota Tangerang\", \"Kota Tangerang Selatan\"],\r\n    \"DKI Jakarta\": [\"Kepulauan Seribu\", \"Kota Jakarta Barat\", \"Kota Jakarta Pusat\", \"Kota Jakarta Selatan\", \"Kota Jakarta Timur\", \"Kota Jakarta Utara\"],\r\n    \"Jawa Barat\": [\"Bandung\", \"Bandung Barat\", \"Bekasi\", \"Bogor\", \"Ciamis\", \"Cianjur\", \"Cirebon\", \"Garut\", \"Indramayu\", \"Karawang\", \"Kuningan\", \"Majalengka\", \"Pangandaran\", \"Purwakarta\", \"Subang\", \"Sukabumi\", \"Sumedang\", \"Tasikmalaya\", \"Kota Bandung\", \"Kota Banjar\", \"Kota Bekasi\", \"Kota Bogor\", \"Kota Cimahi\", \"Kota Cirebon\", \"Kota Depok\", \"Kota Sukabumi\", \"Kota Tasikmalaya\"],\r\n    \"Jawa Tengah\": [\"Banjarnegara\", \"Banyumas\", \"Batang\", \"Blora\", \"Boyolali\", \"Brebes\", \"Cilacap\", \"Demak\", \"Grobogan\", \"Jepara\", \"Karanganyar\", \"Kebumen\", \"Kendal\", \"Klaten\", \"Kudus\", \"Magelang\", \"Pati\", \"Pekalongan\", \"Pemalang\", \"Purbalingga\", \"Purworejo\", \"Rembang\", \"Semarang\", \"Sragen\", \"Sukoharjo\", \"Tegal\", \"Temanggung\", \"Wonogiri\", \"Wonosobo\", \"Kota Magelang\", \"Kota Pekalongan\", \"Kota Salatiga\", \"Kota Semarang\", \"Kota Surakarta\", \"Kota Tegal\"],\r\n    \"DI Yogyakarta\": [\"Bantul\", \"Gunungkidul\", \"Kulon Progo\", \"Sleman\", \"Kota Yogyakarta\"],\r\n    \"Jawa Timur\": [\"Bangkalan\", \"Banyuwangi\", \"Blitar\", \"Bojonegoro\", \"Bondowoso\", \"Gresik\", \"Jember\", \"Jombang\", \"Kediri\", \"Lamongan\", \"Lumajang\", \"Madiun\", \"Magetan\", \"Malang\", \"Mojokerto\", \"Nganjuk\", \"Ngawi\", \"Pacitan\", \"Pamekasan\", \"Pasuruan\", \"Ponorogo\", \"Probolinggo\", \"Sampang\", \"Sidoarjo\", \"Situbondo\", \"Sumenep\", \"Trenggalek\", \"Tuban\", \"Tulungagung\", \"Kota Batu\", \"Kota Blitar\", \"Kota Kediri\", \"Kota Madiun\", \"Kota Malang\", \"Kota Mojokerto\", \"Kota Pasuruan\", \"Kota Probolinggo\", \"Kota Surabaya\"],\r\n    \"Bali\": [\"Badung\", \"Bangli\", \"Buleleng\", \"Gianyar\", \"Jembrana\", \"Karangasem\", \"Klungkung\", \"Tabanan\", \"Kota Denpasar\"],\r\n    \"Nusa Tenggara Barat\": [\"Bima\", \"Dompu\", \"Lombok Barat\", \"Lombok Tengah\", \"Lombok Timur\", \"Lombok Utara\", \"Sumbawa\", \"Sumbawa Barat\", \"Kota Bima\", \"Kota Mataram\"],\r\n    \"Nusa Tenggara Timur\": [\"Alor\", \"Belu\", \"Ende\", \"Flores Timur\", \"Kupang\", \"Lembata\", \"Malaka\", \"Manggarai\", \"Manggarai Barat\", \"Manggarai Timur\", \"Nagekeo\", \"Ngada\", \"Rote Ndao\", \"Sabu Raijua\", \"Sikka\", \"Sumba Barat\", \"Sumba Barat Daya\", \"Sumba Tengah\", \"Sumba Timur\", \"Timor Tengah Selatan\", \"Timor Tengah Utara\", \"Kota Kupang\"],\r\n    \"Kalimantan Barat\": [\"Bengkayang\", \"Kapuas Hulu\", \"Kayong Utara\", \"Ketapang\", \"Kubu Raya\", \"Landak\", \"Melawi\", \"Mempawah\", \"Sambas\", \"Sanggau\", \"Sekadau\", \"Sintang\", \"Kota Pontianak\", \"Kota Singkawang\"],\r\n    \"Kalimantan Tengah\": [\"Barito Selatan\", \"Barito Timur\", \"Barito Utara\", \"Gunung Mas\", \"Kapuas\", \"Katingan\", \"Kotawaringin Barat\", \"Kotawaringin Timur\", \"Lamandau\", \"Murung Raya\", \"Pulang Pisau\", \"Sukamara\", \"Seruyan\", \"Kota Palangka Raya\"],\r\n    \"Kalimantan Selatan\": [\"Balangan\", \"Banjar\", \"Barito Kuala\", \"Hulu Sungai Selatan\", \"Hulu Sungai Tengah\", \"Hulu Sungai Utara\", \"Kotabaru\", \"Tabalong\", \"Tanah Bumbu\", \"Tanah Laut\", \"Tapin\", \"Kota Banjarbaru\", \"Kota Banjarmasin\"],\r\n    \"Kalimantan Timur\": [\"Berau\", \"Kutai Barat\", \"Kutai Kartanegara\", \"Kutai Timur\", \"Mahakam Ulu\", \"Paser\", \"Penajam Paser Utara\", \"Kota Balikpapan\", \"Kota Bontang\", \"Kota Samarinda\"],\r\n    \"Kalimantan Utara\": [\"Bulungan\", \"Malinau\", \"Nunukan\", \"Tana Tidung\", \"Kota Tarakan\"],\r\n    \"Sulawesi Utara\": [\"Bolaang Mongondow\", \"Bolaang Mongondow Selatan\", \"Bolaang Mongondow Timur\", \"Bolaang Mongondow Utara\", \"Kepulauan Sangihe\", \"Kepulauan Siau Tagulandang Biaro\", \"Kepulauan Talaud\", \"Minahasa\", \"Minahasa Selatan\", \"Minahasa Tenggara\", \"Minahasa Utara\", \"Kota Bitung\", \"Kota Kotamobagu\", \"Kota Manado\", \"Kota Tomohon\"],\r\n    \"Gorontalo\": [\"Boalemo\", \"Bone Bolango\", \"Gorontalo\", \"Gorontalo Utara\", \"Pohuwato\", \"Kota Gorontalo\"],\r\n    \"Sulawesi Tengah\": [\"Banggai\", \"Banggai Kepulauan\", \"Banggai Laut\", \"Buol\", \"Donggala\", \"Morowali\", \"Morowali Utara\", \"Parigi Moutong\", \"Poso\", \"Sigi\", \"Tojo Una-Una\", \"Toli-Toli\", \"Kota Palu\"],\r\n    \"Sulawesi Barat\": [\"Majene\", \"Mamasa\", \"Mamuju\", \"Mamuju Tengah\", \"Pasangkayu\", \"Polewali Mandar\"],\r\n    \"Sulawesi Selatan\": [\"Bantaeng\", \"Barru\", \"Bone\", \"Bulukumba\", \"Enrekang\", \"Gowa\", \"Jeneponto\", \"Kepulauan Selayar\", \"Luwu\", \"Luwu Timur\", \"Luwu Utara\", \"Maros\", \"Pangkajene dan Kepulauan\", \"Pinrang\", \"Sidenreng Rappang\", \"Sinjai\", \"Soppeng\", \"Takalar\", \"Tana Toraja\", \"Toraja Utara\", \"Wajo\", \"Kota Makassar\", \"Kota Palopo\", \"Kota Parepare\"],\r\n    \"Sulawesi Tenggara\": [\"Bombana\", \"Buton\", \"Buton Selatan\", \"Buton Tengah\", \"Buton Utara\", \"Kolaka\", \"Kolaka Timur\", \"Kolaka Utara\", \"Konawe\", \"Konawe Kepulauan\", \"Konawe Selatan\", \"Konawe Utara\", \"Muna\", \"Muna Barat\", \"Wakatobi\", \"Kota Bau-Bau\", \"Kota Kendari\"],\r\n    \"Maluku\": [\"Buru\", \"Buru Selatan\", \"Kepulauan Aru\", \"Maluku Barat Daya\", \"Maluku Tengah\", \"Maluku Tenggara\", \"Maluku Tenggara Barat\", \"Seram Bagian Barat\", \"Seram Bagian Timur\", \"Kota Ambon\", \"Kota Tual\"],\r\n    \"Maluku Utara\": [\"Halmahera Barat\", \"Halmahera Tengah\", \"Halmahera Timur\", \"Halmahera Selatan\", \"Halmahera Utara\", \"Kepulauan Sula\", \"Pulau Morotai\", \"Pulau Taliabu\", \"Kota Ternate\", \"Kota Tidore Kepulauan\"],\r\n    \"Papua Barat\": [\"Fakfak\", \"Kaimana\", \"Manokwari\", \"Manokwari Selatan\", \"Maybrat\", \"Pegunungan Arfak\", \"Raja Ampat\", \"Sorong\", \"Sorong Selatan\", \"Tambrauw\", \"Teluk Bintuni\", \"Teluk Wondama\", \"Kota Sorong\"],\r\n    \"Papua\": [\"Asmat\", \"Biak Numfor\", \"Boven Digoel\", \"Deiyai\", \"Dogiyai\", \"Intan Jaya\", \"Jayapura\", \"Jayawijaya\", \"Keerom\", \"Kepulauan Yapen\", \"Lanny Jaya\", \"Mamberamo Raya\", \"Mamberamo Tengah\", \"Mappi\", \"Merauke\", \"Mimika\", \"Nabire\", \"Nduga\", \"Paniai\", \"Pegunungan Bintang\", \"Puncak\", \"Puncak Jaya\", \"Sarmi\", \"Supiori\", \"Tolikara\", \"Waropen\", \"Yahukimo\", \"Yalimo\", \"Kota Jayapura\"]\r\n};\r\n\r\nfunction initRegionDropdowns(){ \r\n    let provSelect = document.getElementById('provinceSelect');\r\n    let distSelect = document.getElementById('districtSelect');\r\n    provSelect.innerHTML = '<option value=\"\">' + getText('selectProvince') + '<\/option>';\r\n    Object.keys(indonesiaRegions).sort().forEach(prov => {\r\n        let opt = document.createElement('option');\r\n        opt.value = prov;\r\n        opt.textContent = prov;\r\n        provSelect.appendChild(opt);\r\n    });\r\n    provSelect.addEventListener('change', function() {\r\n        let selected = this.value;\r\n        distSelect.innerHTML = '<option value=\"\">' + getText('selectDistrict') + '<\/option>';\r\n        if (selected && indonesiaRegions[selected]) {\r\n            indonesiaRegions[selected].sort().forEach(city => {\r\n                let opt = document.createElement('option');\r\n                opt.value = city;\r\n                opt.textContent = city;\r\n                distSelect.appendChild(opt);\r\n            });\r\n        }\r\n        refreshMapSize();\r\n    });\r\n}\r\n\r\n\/\/ ========== SUGESTI LOKASI ==========\r\nfunction populateLastLocation(turtle_id) {\r\n    const records = allData.filter(item => item.turtle_id === turtle_id);\r\n    if (records.length === 0) return;\r\n    records.sort((a,b) => (b.survey_date || '').localeCompare(a.survey_date || ''));\r\n    const last = records[0];\r\n    if (!last.latitude || !last.longitude) return;\r\n    document.getElementById('locationName').value = last.location_name || '';\r\n    document.getElementById('latitude').value = last.latitude;\r\n    document.getElementById('longitude').value = last.longitude;\r\n    if (miniMarker) miniMap.removeLayer(miniMarker);\r\n    miniMarker = L.marker([last.latitude, last.longitude]).addTo(miniMap);\r\n    miniMap.setView([last.latitude, last.longitude], 10);\r\n    const provSelect = document.getElementById('provinceSelect');\r\n    let provFound = false;\r\n    for (let i=0; i<provSelect.options.length; i++) {\r\n        if (provSelect.options[i].value === last.province || provSelect.options[i].text === last.province) {\r\n            provSelect.value = provSelect.options[i].value;\r\n            provFound = true;\r\n            break;\r\n        }\r\n    }\r\n    if (provFound) {\r\n        provSelect.dispatchEvent(new Event('change'));\r\n        setTimeout(() => {\r\n            const distSelect = document.getElementById('districtSelect');\r\n            for (let i=0; i<distSelect.options.length; i++) {\r\n                if (distSelect.options[i].value === last.district || distSelect.options[i].text === last.district) {\r\n                    distSelect.value = distSelect.options[i].value;\r\n                    break;\r\n                }\r\n            }\r\n            refreshMapSize();\r\n        }, 300);\r\n    }\r\n    const suggestionBox = document.getElementById('suggestionBox');\r\n    const locText = last.location_name || `${last.latitude}, ${last.longitude}`;\r\n    const dateText = last.survey_date || '';\r\n    suggestionBox.style.display = 'block';\r\n    suggestionBox.innerHTML = getText('previousLocationSuggestion').replace('{loc}', locText).replace('{date}', dateText);\r\n    refreshMapSize();\r\n}\r\n\r\n\/\/ ========== UPDATE SUMMARY ==========\r\nfunction updateSummary() {\r\n    const species = document.getElementById('speciesSelect').value || '-';\r\n    const location = document.getElementById('locationName').value || '-';\r\n    const date = document.getElementById('surveyDate').value || '-';\r\n    const contributor = document.getElementById('contributorName').value || '-';\r\n    document.getElementById('summarySpecies').textContent = species;\r\n    document.getElementById('summaryLocation').textContent = location;\r\n    document.getElementById('summaryDate').textContent = date;\r\n    document.getElementById('summaryContributor').textContent = contributor;\r\n}\r\n\r\n\/\/ ========== CROP & ANALISIS ==========\r\nlet cropper;\r\nlet isProcessing = false;\r\nlet cropperReady = false;\r\n\r\nconst modalHTML = `<div id=\"cropModal\" style=\"display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);z-index:10000;justify-content:center;align-items:center;\"><div style=\"background:#fff;padding:24px;border-radius:18px;width:90%;max-width:800px;box-shadow:0 20px 60px rgba(0,0,0,0.3);\"><div style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;\"><h3 style=\"margin:0;color:#1e293b;\">Crop Foto<\/h3><button id=\"closeCropModal\" style=\"background:none;border:none;font-size:28px;cursor:pointer;color:#94a3b8;\">&times;<\/button><\/div><div style=\"margin:16px 0;\"><img decoding=\"async\" id=\"cropImage\" src=\"\" style=\"max-width:100%;max-height:70vh;\"><\/div><div style=\"display:flex;justify-content:flex-end;gap:12px;\"><button id=\"cancelCrop\" style=\"background:#e2e8f0;color:#475569;border:none;padding:10px 24px;border-radius:30px;cursor:pointer;font-weight:600;\">Batal<\/button><button id=\"cropButton\" style=\"background:#0284c7;color:white;border:none;padding:10px 32px;border-radius:30px;cursor:pointer;font-weight:600;\">Crop<\/button><\/div><\/div><\/div>`;\r\ndocument.body.insertAdjacentHTML('beforeend',modalHTML);\r\nconst cropModal = document.getElementById('cropModal');\r\nconst cropImage = document.getElementById('cropImage');\r\nconst cropBtn = document.getElementById('cropButton');\r\nconst closeCrop = document.getElementById('closeCropModal');\r\nconst cancelCrop = document.getElementById('cancelCrop');\r\n\r\nfunction showCropModal() { cropModal.style.display = 'flex'; refreshMapSize(); }\r\nfunction hideCropModal() { cropModal.style.display = 'none'; if (cropper) { cropper.destroy(); cropper = null; cropperReady = false; } refreshMapSize(); }\r\ncloseCrop.addEventListener('click', hideCropModal);\r\ncancelCrop.addEventListener('click', hideCropModal);\r\n\r\nfunction compressImage(file, quality = 0.85) {\r\n    return new Promise((resolve, reject) => {\r\n        const reader = new FileReader();\r\n        reader.onload = (e) => {\r\n            const img = new Image();\r\n            img.onload = () => {\r\n                const canvas = document.createElement('canvas');\r\n                canvas.width = img.width;\r\n                canvas.height = img.height;\r\n                canvas.getContext('2d').drawImage(img, 0, 0);\r\n                canvas.toBlob((blob) => {\r\n                    if (!blob) reject(new Error('Gagal kompresi'));\r\n                    else resolve(new File([blob], file.name, { type: 'image\/jpeg' }));\r\n                }, 'image\/jpeg', quality);\r\n            };\r\n            img.onerror = reject;\r\n            img.src = e.target.result;\r\n        };\r\n        reader.onerror = reject;\r\n        reader.readAsDataURL(file);\r\n    });\r\n}\r\n\r\nfunction showAnalysisResult(message, type, isMatch = false) {\r\n    const resultDiv = document.getElementById('analysisResult');\r\n    resultDiv.style.display = 'block';\r\n    if (type === 'loading') {\r\n        resultDiv.innerHTML = `<p style=\"color:#475569;\">${message}<span class=\"loading\"><\/span><\/p>`;\r\n        return;\r\n    }\r\n    resultDiv.innerHTML = `<p style=\"color:${type === 'error' ? '#dc2626' : '#1e293b'};\">${message}<\/p>`;\r\n}\r\n\r\nasync function handleCroppedFile(blob) {\r\n    if (isProcessing) return;\r\n    isProcessing = true;\r\n    updateProgress(2);\r\n    try {\r\n        const file = new File([blob], 'cropped.jpg', { type: 'image\/jpeg' });\r\n        const compressed = await compressImage(file, 0.85);\r\n        const reader = new FileReader();\r\n        reader.onload = (e) => {\r\n            currentPhotoBase64 = e.target.result;\r\n            analyzePhoto(currentPhotoBase64);\r\n            isProcessing = false;\r\n        };\r\n        reader.readAsDataURL(compressed);\r\n    } catch (err) {\r\n        console.error('Error handleCroppedFile:', err);\r\n        showAnalysisResult(getText('processError') + err.message, 'error');\r\n        isProcessing = false;\r\n    }\r\n}\r\n\r\nasync function analyzePhoto(base64) {\r\n    const resultDiv = document.getElementById('analysisResult');\r\n    resultDiv.style.display = 'block';\r\n    resultDiv.innerHTML = `<p style=\"color:#475569;\">${getText('analyzing')}<span class=\"loading\"><\/span><\/p>`;\r\n    updateProgress(3);\r\n    try {\r\n        const formData = new FormData();\r\n        formData.append('left_photo_base64', base64);\r\n        formData.append('species', '');\r\n        formData.append('survey_date', '');\r\n        const result = await apiFetch(analyzeEndpoint, { method: 'POST', body: formData });\r\n        if (result.status === 'match') {\r\n            const match = result.matchData;\r\n            currentMatch = { id: match.id, name: match.name, species: match.species, left_photo_url: match.left_photo_url, confidence: Math.round(match.confidence * 100) };\r\n            isNewIndividual = false;\r\n            resultDiv.innerHTML = `\r\n                <div class=\"result-match\">\r\n                    <div><span class=\"result-badge badge-match\">${getText('matchFound')}<\/span><\/div>\r\n                    <p style=\"margin:6px 0;\"><strong>${getText('similarity')}:<\/strong> ${currentMatch.confidence}%<\/p>\r\n                    <p style=\"margin:4px 0;\"><strong>${getText('id')}:<\/strong> ${match.id}<\/p>\r\n                    <p style=\"margin:4px 0;\"><strong>${getText('name')}:<\/strong> ${match.name||'-'}<\/p>\r\n                    <p style=\"margin:4px 0;\"><strong>${getText('species')}:<\/strong> ${match.species||'-'}<\/p>\r\n                    <div class=\"comparison\">\r\n                        <div class=\"photo-box\"><img decoding=\"async\" src=\"${base64}\"><div class=\"label\">${getText('photoUpload')}<\/div><\/div>\r\n                        <div class=\"photo-box\">${match.left_photo_url ? `<img decoding=\"async\" src=\"${match.left_photo_url}\">` : `<p>${getText('photoNotAvailable')}<\/p>`}<div class=\"label\">${getText('photoDB')}<\/div><\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n            showDataForm();\r\n            document.getElementById('speciesSelect').value = match.species || '';\r\n            document.getElementById('newNameGroup').style.display = 'none';\r\n            document.getElementById('matchInfo').style.display = 'block';\r\n            document.getElementById('matchInfo').innerHTML = getText('matchInfoText').replace('{name}', match.name||'-').replace('{id}', match.id).replace('{conf}', currentMatch.confidence);\r\n            populateLastLocation(match.id);\r\n            updateSummary();\r\n            updateProgress(4);\r\n        } else if (result.status === 'new') {\r\n            currentMatch = null;\r\n            isNewIndividual = true;\r\n            suggestedSpecies = result.suggested_species || (result.feature_data?.suggested_species) || 'Chelonia mydas';\r\n            currentTempId = result.temp_id || result.feature_data?.temp_id || null;\r\n            resultDiv.innerHTML = `\r\n                <div class=\"result-new\">\r\n                    <div><span class=\"result-badge badge-new\">${getText('newIndividual')}<\/span><\/div>\r\n                    <p style=\"margin:6px 0;\">${getText('suggestedSpecies')}<strong> ${suggestedSpecies}<\/strong><\/p>\r\n                    <div style=\"margin-top:8px;\"><strong>${getText('photoUpload')}<\/strong><br><img decoding=\"async\" src=\"${base64}\" style=\"max-width:120px;border-radius:8px;border:2px solid #e2e8f0;margin-top:4px;\"><\/div>\r\n                <\/div>\r\n            `;\r\n            showDataForm();\r\n            document.getElementById('speciesSelect').value = suggestedSpecies;\r\n            document.getElementById('newNameGroup').style.display = 'block';\r\n            document.getElementById('matchInfo').style.display = 'none';\r\n            document.getElementById('suggestionBox').style.display = 'none';\r\n            updateSummary();\r\n            updateProgress(4);\r\n        } else {\r\n            resultDiv.innerHTML = `<p style=\"color:#dc2626;\">${getText('errorMsg')}${result.message||''}<\/p>`;\r\n        }\r\n    } catch (err) {\r\n        resultDiv.innerHTML = `<p style=\"color:#dc2626;\">${err.message}<\/p>`;\r\n    }\r\n}\r\n\r\nfunction showDataForm(){\r\n    document.getElementById('dataForm').classList.remove('hidden-form');\r\n    if(!document.getElementById('surveyDate').value) document.getElementById('surveyDate').value = new Date().toISOString().slice(0,10);\r\n    refreshMapSize();\r\n}\r\n\r\n\/\/ ========== SIMPAN DATA ==========\r\nasync function saveData(){\r\n    const lat=document.getElementById('latitude').value, lng=document.getElementById('longitude').value;\r\n    const province=document.getElementById('provinceSelect').value, district=document.getElementById('districtSelect').value;\r\n    const locationName=document.getElementById('locationName').value, surveyDate=document.getElementById('surveyDate').value;\r\n    const species=document.getElementById('speciesSelect').value;\r\n    let contributor = document.getElementById('contributorName').value.trim();\r\n    if(contributor === '') contributor = 'Anonymous';\r\n    if(!surveyDate||!lat||!lng||!species){ alert(getText('alertRequired')); return; }\r\n    let turtleName='';\r\n    if(isNewIndividual){ const inp=document.getElementById('newTurtleName'); if(inp) turtleName=inp.value.trim(); }\r\n    const fd=new FormData();\r\n    fd.append('left_photo_base64',currentPhotoBase64);\r\n    fd.append('species',species);\r\n    fd.append('survey_date',surveyDate);\r\n    fd.append('contributor',contributor);\r\n    fd.append('latitude',lat);\r\n    fd.append('longitude',lng);\r\n    fd.append('province',province);\r\n    fd.append('district',district);\r\n    fd.append('location_name',locationName);\r\n    if(!isNewIndividual && currentMatch){\r\n        fd.append('individual_id',currentMatch.id);\r\n    } else {\r\n        if(currentTempId) fd.append('temp_id',currentTempId);\r\n        if(turtleName) fd.append('turtle_name',turtleName);\r\n    }\r\n    fd.append('survey_time',''); fd.append('ccl',''); fd.append('ccw',''); fd.append('sex','');\r\n    fd.append('depth',''); fd.append('behaviour',''); fd.append('health',''); fd.append('health_notes','');\r\n    fd.append('surveyor',''); fd.append('institution','');\r\n\r\n    const statusDiv=document.getElementById('saveStatus');\r\n    statusDiv.style.display='block';\r\n    statusDiv.innerHTML=`<p style=\"color:#475569;\">${getText('saving')}<span class=\"loading\"><\/span><\/p>`;\r\n    try{\r\n        const result=await apiFetch(saveEndpoint,{method:'POST',body:fd});\r\n        if(result.success){\r\n            statusDiv.innerHTML=`<p style=\"color:#16a34a;font-weight:600;\">\u2705 ${getText('saveSuccess')}<\/p>`;\r\n            document.getElementById('dataForm').classList.add('hidden-form');\r\n            document.getElementById('analysisResult').style.display='none';\r\n            document.getElementById('leftPhotoInput').value='';\r\n            currentPhotoBase64=null; currentMatch=null; currentTempId=null;\r\n            updateProgress(5);\r\n            await loadData();\r\n            refreshMapSize();\r\n            setTimeout(()=>{statusDiv.style.display='none';},3000);\r\n        } else {\r\n            statusDiv.innerHTML=`<p style=\"color:#dc2626;\">${getText('saveError')}${result.message||''}<\/p>`;\r\n        }\r\n    } catch(err){\r\n        statusDiv.innerHTML=`<p style=\"color:#dc2626;\">${err.message}<\/p>`;\r\n    }\r\n}\r\n\r\n\/\/ ========== EVENT LISTENERS ==========\r\ndocument.getElementById('submitDataBtn').addEventListener('click',saveData);\r\ndocument.getElementById('applyFilter').addEventListener('click',filterData);\r\ndocument.getElementById('searchInput').addEventListener('keyup',e=>{if(e.key==='Enter')filterData();});\r\ndocument.getElementById('filterProvince').addEventListener('change',filterData);\r\ndocument.getElementById('filterDistrict').addEventListener('change',filterData);\r\ndocument.getElementById('filterSex').addEventListener('change',filterData);\r\ndocument.getElementById('filterMinCCL').addEventListener('keyup',e=>{if(e.key==='Enter')filterData();});\r\n\r\n\/\/ Update summary on form change\r\ndocument.getElementById('speciesSelect').addEventListener('change', updateSummary);\r\ndocument.getElementById('locationName').addEventListener('input', updateSummary);\r\ndocument.getElementById('surveyDate').addEventListener('change', updateSummary);\r\ndocument.getElementById('contributorName').addEventListener('input', updateSummary);\r\n\r\nconst leftInput=document.getElementById('leftPhotoInput'), uploadBtn=document.getElementById('uploadBtn'), uploadArea=document.getElementById('uploadArea');\r\n\r\nuploadBtn.addEventListener('click', (e) => {\r\n    e.stopPropagation();\r\n    leftInput.click();\r\n});\r\n\r\nuploadArea.addEventListener('click', (e) => {\r\n    if (e.target === uploadBtn || uploadBtn.contains(e.target)) return;\r\n    leftInput.click();\r\n});\r\n\r\nleftInput.addEventListener('change', function(e) {\r\n    const file = this.files[0];\r\n    if (!file) return;\r\n    updateProgress(1);\r\n    if (cropper) {\r\n        cropper.destroy();\r\n        cropper = null;\r\n    }\r\n    cropperReady = false;\r\n    cropImage.src = '';\r\n    const reader = new FileReader();\r\n    reader.onload = function(event) {\r\n        cropImage.src = event.target.result;\r\n        cropImage.onload = () => {\r\n            showCropModal();\r\n            setTimeout(() => {\r\n                try {\r\n                    cropper = new Cropper(cropImage, {\r\n                        aspectRatio: NaN,\r\n                        viewMode: 1,\r\n                        autoCropArea: 1,\r\n                        responsive: true,\r\n                        checkOrientation: false\r\n                    });\r\n                    cropperReady = true;\r\n                } catch (err) {\r\n                    console.error('Cropper init error:', err);\r\n                    alert(getText('alertCropInit'));\r\n                    hideCropModal();\r\n                }\r\n            }, 150);\r\n        };\r\n        cropImage.onerror = () => {\r\n            alert(getText('alertImageLoad'));\r\n            hideCropModal();\r\n        };\r\n    };\r\n    reader.readAsDataURL(file);\r\n});\r\n\r\ncropBtn.addEventListener('click', () => {\r\n    if (!cropperReady || !cropper) {\r\n        alert(getText('alertCropWait'));\r\n        return;\r\n    }\r\n    const canvas = cropper.getCroppedCanvas();\r\n    if (!canvas) {\r\n        alert(getText('alertCropFail'));\r\n        return;\r\n    }\r\n    canvas.toBlob(blob => {\r\n        hideCropModal();\r\n        handleCroppedFile(blob);\r\n        refreshMapSize();\r\n    }, 'image\/jpeg');\r\n});\r\n\r\nuploadArea.addEventListener('dragover',e=>{e.preventDefault();uploadArea.style.borderColor='#0284c7';});\r\nuploadArea.addEventListener('dragleave',e=>{e.preventDefault();uploadArea.style.borderColor='#cbd5e1';});\r\nuploadArea.addEventListener('drop',e=>{\r\n    e.preventDefault();\r\n    uploadArea.style.borderColor='#cbd5e1';\r\n    const file=e.dataTransfer.files[0];\r\n    if(file&&file.type.startsWith('image\/')){\r\n        leftInput.files=e.dataTransfer.files;\r\n        leftInput.dispatchEvent(new Event('change',{bubbles:true}));\r\n    } else alert(getText('alertInvalidFile'));\r\n});\r\n\r\ndocument.getElementById('languageSelect').addEventListener('change',e=>{currentLang=e.target.value;updateUI();updateMapMarkers(filteredAllData);renderContributorStats(allData);refreshMapSize();});\r\n\r\n\/\/ ========== INIT ==========\r\ninitMapMain();\r\ninitMiniMap();\r\ninitRegionDropdowns();\r\nloadData();\r\nupdateUI();\r\nupdateProgress(1);\r\n<\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-c50b5b7 e-flex e-con-boxed e-con e-parent\" data-id=\"c50b5b7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-aae6470 elementor-widget elementor-widget-html\" data-id=\"aae6470\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!-- ==================== TOMBOL LIHAT GALERI DI TENGAH ==================== -->\r\n<div style=\"display: flex; justify-content: center; align-items: center; margin: 30px 0; width: 100%;\">\r\n    <button id=\"toggleGalleryBtn\" style=\"\r\n        background: linear-gradient(135deg, #0284c7, #0369a1);\r\n        color: white;\r\n        border: none;\r\n        padding: 16px 48px;\r\n        border-radius: 50px;\r\n        font-size: 1.2rem;\r\n        font-weight: 700;\r\n        cursor: pointer;\r\n        transition: all 0.3s ease;\r\n        box-shadow: 0 8px 25px rgba(2, 132, 199, 0.4);\r\n        display: flex;\r\n        align-items: center;\r\n        gap: 12px;\r\n        letter-spacing: 0.5px;\r\n    \"\r\n    onmouseover=\"this.style.transform='scale(1.05)'; this.style.boxShadow='0 12px 35px rgba(2, 132, 199, 0.5)';\"\r\n    onmouseout=\"this.style.transform='scale(1)'; this.style.boxShadow='0 8px 25px rgba(2, 132, 199, 0.4)';\"\r\n    onmousedown=\"this.style.transform='scale(0.95)';\"\r\n    onmouseup=\"this.style.transform='scale(1.05)';\"\r\n    >\r\n        <span style=\"font-size: 1.8rem;\">\ud83d\udcf8<\/span>\r\n        <span id=\"toggleGalleryText\">Lihat Galeri Foto<\/span>\r\n        <span id=\"toggleGalleryIcon\" style=\"font-size: 1.2rem;\">\u25bc<\/span>\r\n    <\/button>\r\n<\/div>\r\n\r\n<!-- ==================== GALERI SECTION ==================== -->\r\n<div class=\"gallery-section\" id=\"gallerySection\" style=\"display:none; margin-top: 20px; width: 100%;\">\r\n    <div class=\"gallery-header\">\r\n        <div class=\"title-section\">\r\n            <h1>\ud83d\udc22 e-Turtle Indonesia \u00b7 Galeri Foto<\/h1>\r\n            <p>\ud83d\udcf8 Jelajahi koleksi penyu dari seluruh Nusantara | Klik foto untuk melihat detail<\/p>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"filter-bar\">\r\n        <div class=\"filter-group\">\r\n            <label>\ud83c\udf3f Spesies<\/label>\r\n            <select id=\"galleryFilterSpecies\"><option value=\"\">Semua Spesies<\/option><\/select>\r\n        <\/div>\r\n        <div class=\"filter-group\">\r\n            <label>\ud83d\udccd Provinsi<\/label>\r\n            <select id=\"galleryFilterProvince\"><option value=\"\">Semua Provinsi<\/option><\/select>\r\n        <\/div>\r\n        <div class=\"filter-group search-group\">\r\n            <label>\ud83d\udd0d Cari (ID \/ Lokasi \/ Kontributor \/ Nama dari Foto)<\/label>\r\n            <input type=\"text\" id=\"gallerySearchText\" placeholder=\"Misal: Thalhah, Hijau, Pantai...\">\r\n        <\/div>\r\n        <div>\r\n            <button id=\"galleryResetFiltersBtn\" class=\"reset-btn\">\u27f3 Reset Filter<\/button>\r\n        <\/div>\r\n        <div class=\"stats-badge\">\r\n            \ud83d\uddbc\ufe0f <span id=\"galleryPhotoCount\">0<\/span> foto\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div id=\"galleryContainer\">\r\n        <div class=\"loading-state\">\r\n            <div class=\"spinner\"><\/div>\r\n            <p>Memuat galeri foto penyu...<\/p>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div id=\"galleryPaginationControls\" style=\"display: none;\"><\/div>\r\n<\/div>\r\n\r\n<!-- GALLERY LIGHTBOX MODAL -->\r\n<div id=\"galleryLightboxModal\" class=\"lightbox\" style=\"display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.92); z-index:9999; justify-content:center; align-items:center; backdrop-filter:blur(4px);\">\r\n    <button class=\"close-lightbox\" id=\"galleryCloseLightboxBtn\" style=\"position:absolute; top:16px; right:24px; background:rgba(0,0,0,0.6); color:white; border:none; font-size:28px; width:40px; height:40px; border-radius:50%; cursor:pointer; z-index:10000; transition:background 0.2s;\">&times;<\/button>\r\n    <div class=\"lightbox-content\" style=\"max-width:95vw; max-height:90vh; background:#1e293b; border-radius:32px; overflow:hidden; display:flex; flex-direction:column; position:relative; width:900px;\">\r\n        <div style=\"display:flex; flex-direction:column; max-height:90vh; overflow-y:auto;\">\r\n            <img id=\"galleryLightboxImg\" style=\"width:100%; max-height:50vh; object-fit:contain; background:#0f172a; padding:10px;\" alt=\"Foto penyu\">\r\n            <div id=\"galleryLightboxDetails\" style=\"background:white; padding:20px 24px; border-radius:0 0 32px 32px; color:#0a2b3e;\"><\/div>\r\n        <\/div>\r\n    <\/div>\r\n<\/div>\r\n\r\n<!-- ==================== CSS ==================== -->\r\n<style>\r\n    .gallery-section {\r\n        width: 100%;\r\n        margin-top: 40px;\r\n    }\r\n    .gallery-section .gallery-header {\r\n        background: white;\r\n        border-radius: 28px;\r\n        padding: 20px 28px;\r\n        margin-bottom: 28px;\r\n        box-shadow: 0 8px 20px rgba(0,0,0,0.05);\r\n        display: flex;\r\n        flex-wrap: wrap;\r\n        justify-content: space-between;\r\n        align-items: center;\r\n        gap: 16px;\r\n    }\r\n    .gallery-section .gallery-header h1 {\r\n        font-size: 1.9rem;\r\n        color: #0284c7;\r\n        display: flex;\r\n        align-items: center;\r\n        gap: 10px;\r\n        margin: 0;\r\n    }\r\n    .gallery-section .gallery-header p {\r\n        color: #2c5f7a;\r\n        margin-top: 6px;\r\n        font-size: 0.9rem;\r\n    }\r\n    .gallery-section .filter-bar {\r\n        background: white;\r\n        border-radius: 24px;\r\n        padding: 18px 24px;\r\n        margin-bottom: 28px;\r\n        box-shadow: 0 4px 12px rgba(0,0,0,0.03);\r\n        display: flex;\r\n        flex-wrap: wrap;\r\n        align-items: flex-end;\r\n        gap: 18px;\r\n    }\r\n    .gallery-section .filter-group {\r\n        display: flex;\r\n        flex-direction: column;\r\n        gap: 6px;\r\n        min-width: 140px;\r\n    }\r\n    .gallery-section .filter-group label {\r\n        font-size: 0.75rem;\r\n        font-weight: 700;\r\n        text-transform: uppercase;\r\n        letter-spacing: 0.5px;\r\n        color: #1e6f9f;\r\n    }\r\n    .gallery-section .filter-group select,\r\n    .gallery-section .filter-group input {\r\n        padding: 8px 12px;\r\n        border-radius: 20px;\r\n        border: 1px solid #cbd5e6;\r\n        background: #fefefe;\r\n        font-size: 0.85rem;\r\n        color: #000000;\r\n        transition: border-color 0.2s, box-shadow 0.2s;\r\n    }\r\n    .gallery-section .filter-group select:focus,\r\n    .gallery-section .filter-group input:focus {\r\n        border-color: #0284c7;\r\n        outline: none;\r\n        box-shadow: 0 0 0 3px rgba(2,132,199,0.1);\r\n    }\r\n    .gallery-section .filter-group select option {\r\n        color: #000000;\r\n        background: white;\r\n    }\r\n    .gallery-section .reset-btn {\r\n        background: #e2e8f0;\r\n        border: none;\r\n        padding: 8px 20px;\r\n        border-radius: 32px;\r\n        font-weight: 600;\r\n        cursor: pointer;\r\n        color: #1e293b;\r\n        transition: background 0.2s;\r\n        height: 40px;\r\n        align-self: flex-end;\r\n    }\r\n    .gallery-section .reset-btn:hover {\r\n        background: #cbd5e1;\r\n    }\r\n    .gallery-section .stats-badge {\r\n        background: #d9effa;\r\n        border-radius: 40px;\r\n        padding: 6px 18px;\r\n        font-size: 0.8rem;\r\n        font-weight: 500;\r\n        display: inline-flex;\r\n        align-items: center;\r\n        gap: 8px;\r\n        color: #0a2b3e;\r\n        height: 40px;\r\n        align-self: flex-end;\r\n    }\r\n    .gallery-section .gallery-grid {\r\n        display: grid;\r\n        grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));\r\n        gap: 24px;\r\n        margin: 20px 0 30px;\r\n    }\r\n    .gallery-section .turtle-card {\r\n        background: white;\r\n        border-radius: 24px;\r\n        overflow: hidden;\r\n        transition: transform 0.2s, box-shadow 0.2s;\r\n        box-shadow: 0 6px 14px rgba(0,0,0,0.05);\r\n        display: flex;\r\n        flex-direction: column;\r\n    }\r\n    .gallery-section .turtle-card:hover {\r\n        transform: translateY(-6px);\r\n        box-shadow: 0 20px 30px -12px rgba(2,132,199,0.2);\r\n    }\r\n    .gallery-section .photo-wrapper {\r\n        aspect-ratio: 1 \/ 1;\r\n        background: #eef2f5;\r\n        overflow: hidden;\r\n        cursor: pointer;\r\n        position: relative;\r\n    }\r\n    .gallery-section .photo-wrapper img {\r\n        width: 100%;\r\n        height: 100%;\r\n        object-fit: cover;\r\n        transition: transform 0.3s ease;\r\n    }\r\n    .gallery-section .turtle-card:hover .photo-wrapper img {\r\n        transform: scale(1.02);\r\n    }\r\n    .gallery-section .card-info {\r\n        padding: 16px 18px 20px;\r\n        flex: 1;\r\n    }\r\n    .gallery-section .turtle-name {\r\n        font-weight: 800;\r\n        font-size: 1.25rem;\r\n        color: #0c4a6e;\r\n        margin-bottom: 6px;\r\n        display: flex;\r\n        justify-content: space-between;\r\n        align-items: baseline;\r\n        flex-wrap: wrap;\r\n    }\r\n    .gallery-section .turtle-id {\r\n        font-size: 0.7rem;\r\n        background: #e2f0f7;\r\n        padding: 2px 8px;\r\n        border-radius: 30px;\r\n        color: #0369a1;\r\n    }\r\n    .gallery-section .species-badge {\r\n        background: #dcfce7;\r\n        color: #166534;\r\n        padding: 4px 12px;\r\n        border-radius: 30px;\r\n        font-size: 0.7rem;\r\n        font-weight: 600;\r\n        display: inline-block;\r\n        margin: 8px 0 6px;\r\n    }\r\n    .gallery-section .meta-row {\r\n        display: flex;\r\n        align-items: center;\r\n        gap: 12px;\r\n        font-size: 0.75rem;\r\n        color: #2c5f7a;\r\n        margin: 10px 0 6px;\r\n        flex-wrap: wrap;\r\n    }\r\n    .gallery-section .contributor {\r\n        font-size: 0.7rem;\r\n        background: #f1f5f9;\r\n        display: inline-block;\r\n        padding: 4px 12px;\r\n        border-radius: 40px;\r\n        margin-top: 10px;\r\n        color: #334155;\r\n    }\r\n    .gallery-section .view-detail {\r\n        margin-top: 12px;\r\n        text-align: right;\r\n    }\r\n    .gallery-section .view-detail button {\r\n        background: none;\r\n        border: 1px solid #0284c7;\r\n        color: #0284c7;\r\n        padding: 6px 14px;\r\n        border-radius: 40px;\r\n        font-size: 0.7rem;\r\n        font-weight: 600;\r\n        cursor: pointer;\r\n        transition: 0.2s;\r\n    }\r\n    .gallery-section .view-detail button:hover {\r\n        background: #0284c7;\r\n        color: white;\r\n    }\r\n    .gallery-section .pagination {\r\n        display: flex;\r\n        justify-content: center;\r\n        gap: 12px;\r\n        margin: 40px 0 20px;\r\n        flex-wrap: wrap;\r\n    }\r\n    .gallery-section .page-btn {\r\n        background: white;\r\n        border: 1px solid #cbd5e1;\r\n        padding: 8px 16px;\r\n        border-radius: 40px;\r\n        cursor: pointer;\r\n        font-weight: 500;\r\n        transition: 0.2s;\r\n        color: #0a2b3e;\r\n    }\r\n    .gallery-section .page-btn.active {\r\n        background: #0284c7;\r\n        border-color: #0284c7;\r\n        color: white;\r\n    }\r\n    .gallery-section .page-btn:hover:not(.active) {\r\n        background: #eef2ff;\r\n    }\r\n    .gallery-section .page-btn:disabled {\r\n        opacity: 0.5;\r\n        cursor: not-allowed;\r\n    }\r\n    .gallery-section .loading-state,\r\n    .gallery-section .error-state {\r\n        text-align: center;\r\n        padding: 60px 20px;\r\n        background: white;\r\n        border-radius: 32px;\r\n        color: #0a2b3e;\r\n    }\r\n    .gallery-section .spinner {\r\n        border: 4px solid #e2e8f0;\r\n        border-top: 4px solid #0284c7;\r\n        border-radius: 50%;\r\n        width: 48px;\r\n        height: 48px;\r\n        animation: spin 0.8s linear infinite;\r\n        margin: 0 auto 20px;\r\n    }\r\n    \r\n    \/* Lightbox Map *\/\r\n    #galleryLightboxModal .lightbox-map {\r\n        height: 250px;\r\n        border-radius: 12px;\r\n        margin: 12px 0;\r\n        background: #e5e5e5;\r\n        border: 2px solid #e2e8f0;\r\n        width: 100%;\r\n    }\r\n    \r\n    \/* Leaflet popup customization *\/\r\n    #galleryLightboxModal .leaflet-popup-content {\r\n        min-width: 220px;\r\n    }\r\n    #galleryLightboxModal .leaflet-popup-content-wrapper {\r\n        border-radius: 12px;\r\n    }\r\n    \r\n    .gallery-section.show {\r\n        display: block !important;\r\n        animation: fadeSlideDown 0.5s ease forwards;\r\n    }\r\n    .gallery-section.hide {\r\n        animation: fadeSlideUp 0.3s ease forwards;\r\n    }\r\n    \r\n    @keyframes fadeSlideDown {\r\n        from { opacity: 0; transform: translateY(-20px); }\r\n        to { opacity: 1; transform: translateY(0); }\r\n    }\r\n    @keyframes fadeSlideUp {\r\n        from { opacity: 1; transform: translateY(0); }\r\n        to { opacity: 0; transform: translateY(-20px); }\r\n    }\r\n    @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\r\n    \r\n    body.gallery-lightbox-open {\r\n        overflow: hidden !important;\r\n    }\r\n    \r\n    @media (max-width: 680px) {\r\n        .gallery-section .gallery-header { flex-direction: column; align-items: stretch; }\r\n        .gallery-section .filter-bar { flex-direction: column; align-items: stretch; }\r\n        .gallery-section .filter-group { min-width: auto; }\r\n        .gallery-section .search-group { flex: 1; }\r\n        .gallery-section .reset-btn { align-self: stretch; }\r\n        .gallery-section .stats-badge { align-self: stretch; justify-content: center; }\r\n        .gallery-section .gallery-grid {\r\n            grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\r\n            gap: 16px;\r\n        }\r\n        #galleryLightboxModal .lightbox-map { height: 180px; }\r\n        #galleryLightboxModal .lightbox-content { max-width: 98vw; }\r\n        #toggleGalleryBtn {\r\n            padding: 14px 32px !important;\r\n            font-size: 1rem !important;\r\n        }\r\n    }\r\n    @media (max-width: 480px) {\r\n        .gallery-section .gallery-grid { grid-template-columns: 1fr; gap: 16px; }\r\n        #galleryLightboxModal .lightbox-map { height: 150px; }\r\n        #toggleGalleryBtn {\r\n            padding: 12px 24px !important;\r\n            font-size: 0.9rem !important;\r\n            width: 90%;\r\n        }\r\n    }\r\n<\/style>\r\n\r\n<!-- ==================== SCRIPT GALERI ==================== -->\r\n<script>\r\n(function() {\r\n    'use strict';\r\n    \r\n    const galleryContainer = document.getElementById('galleryContainer');\r\n    if (!galleryContainer) return;\r\n    \r\n    const DATA_ENDPOINT = '\/wp-content\/themes\/astra\/turtle-api\/turtle-get.php';\r\n    \r\n    let galleryRawData = [];\r\n    let galleryFilteredData = [];\r\n    let galleryCurrentPage = 1;\r\n    const GALLERY_ITEMS_PER_PAGE = 21;\r\n    let galleryDetailMap = null;\r\n    let galleryDetailMarker = null;\r\n    let isLightboxOpen = false;\r\n    \r\n    const galleryContainerEl = galleryContainer;\r\n    const paginationDiv = document.getElementById('galleryPaginationControls');\r\n    const filterSpecies = document.getElementById('galleryFilterSpecies');\r\n    const filterProvince = document.getElementById('galleryFilterProvince');\r\n    const searchText = document.getElementById('gallerySearchText');\r\n    const resetBtn = document.getElementById('galleryResetFiltersBtn');\r\n    const statsSpan = document.getElementById('galleryPhotoCount');\r\n    \r\n    const lightbox = document.getElementById('galleryLightboxModal');\r\n    const lightboxImg = document.getElementById('galleryLightboxImg');\r\n    const lightboxDetails = document.getElementById('galleryLightboxDetails');\r\n    const closeLightbox = document.getElementById('galleryCloseLightboxBtn');\r\n    \r\n    const toggleBtn = document.getElementById('toggleGalleryBtn');\r\n    const toggleText = document.getElementById('toggleGalleryText');\r\n    const toggleIcon = document.getElementById('toggleGalleryIcon');\r\n    const gallerySection = document.getElementById('gallerySection');\r\n    let isGalleryVisible = false;\r\n    \r\n    function escapeHtml(str) {\r\n        if (!str) return '';\r\n        return String(str).replace(\/[&<>]\/g, function(m) {\r\n            if (m === '&') return '&amp;';\r\n            if (m === '<') return '&lt;';\r\n            if (m === '>') return '&gt;';\r\n            return m;\r\n        });\r\n    }\r\n    \r\n    function extractNameFromPhotoUrl(url) {\r\n        if (!url) return null;\r\n        try {\r\n            let filename = url.split('\/').pop();\r\n            filename = filename.split('?')[0];\r\n            const lastDot = filename.lastIndexOf('.');\r\n            if (lastDot !== -1) filename = filename.substring(0, lastDot);\r\n            const parts = filename.split('_');\r\n            if (parts.length >= 2) {\r\n                let name = parts[1];\r\n                if (name && name.trim() !== '') return name.trim();\r\n            }\r\n            return null;\r\n        } catch(e) {\r\n            return null;\r\n        }\r\n    }\r\n    \r\n    function getDisplayName(turtle) {\r\n        if (turtle.left_photo_url) {\r\n            const extracted = extractNameFromPhotoUrl(turtle.left_photo_url);\r\n            if (extracted && extracted !== '') return extracted;\r\n        }\r\n        if (turtle.turtle_name && turtle.turtle_name.trim() !== '') {\r\n            return turtle.turtle_name.trim();\r\n        }\r\n        if (turtle.turtle_id && turtle.turtle_id.trim() !== '') {\r\n            return `#${turtle.turtle_id.trim()}`;\r\n        }\r\n        return 'Penyu';\r\n    }\r\n    \r\n    function getSearchableText(turtle) {\r\n        const searchableParts = [];\r\n        if (turtle.turtle_id) searchableParts.push(String(turtle.turtle_id));\r\n        if (turtle.location_name) searchableParts.push(String(turtle.location_name));\r\n        if (turtle.contributor) searchableParts.push(String(turtle.contributor));\r\n        if (turtle.district) searchableParts.push(String(turtle.district));\r\n        if (turtle.turtle_name) searchableParts.push(String(turtle.turtle_name));\r\n        if (turtle.species) searchableParts.push(String(turtle.species));\r\n        const extractedName = extractNameFromPhotoUrl(turtle.left_photo_url);\r\n        if (extractedName) searchableParts.push(extractedName);\r\n        return searchableParts.join(' ').toLowerCase();\r\n    }\r\n    \r\n    async function fetchGalleryData() {\r\n        try {\r\n            const response = await fetch(DATA_ENDPOINT, {\r\n                method: 'GET',\r\n                credentials: 'omit',\r\n                headers: { 'Accept': 'application\/json' }\r\n            });\r\n            if (!response.ok) {\r\n                throw new Error(`HTTP ${response.status} - Gagal mengambil data`);\r\n            }\r\n            const data = await response.json();\r\n            if (!Array.isArray(data)) {\r\n                if (data.data && Array.isArray(data.data)) return data.data;\r\n                throw new Error('Format data tidak sesuai (array diperlukan)');\r\n            }\r\n            return data;\r\n        } catch (err) {\r\n            console.error('Gallery fetch error:', err);\r\n            throw new Error(`\u274c ${err.message}`);\r\n        }\r\n    }\r\n    \r\n    function populateGalleryFilters(data) {\r\n        const speciesSet = new Set();\r\n        const provinceSet = new Set();\r\n        \r\n        data.forEach(item => {\r\n            const species = String(item.species ?? '').trim();\r\n            if (species !== '') {\r\n                speciesSet.add(species);\r\n            }\r\n            const province = String(\r\n                item.province ??\r\n                item.provinsi ??\r\n                item.province_name ??\r\n                item.provinceName ??\r\n                ''\r\n            ).trim();\r\n            if (province !== '') {\r\n                provinceSet.add(province);\r\n            }\r\n        });\r\n        \r\n        const sortedSpecies = Array.from(speciesSet).sort();\r\n        const sortedProvinces = Array.from(provinceSet).sort();\r\n        \r\n        filterSpecies.innerHTML = '<option value=\"\">Semua Spesies<\/option>' + \r\n            sortedSpecies.map(sp => `<option value=\"${escapeHtml(sp)}\">${escapeHtml(sp)}<\/option>`).join('');\r\n        filterProvince.innerHTML = '<option value=\"\">Semua Provinsi<\/option>' + \r\n            sortedProvinces.map(pr => `<option value=\"${escapeHtml(pr)}\">${escapeHtml(pr)}<\/option>`).join('');\r\n    }\r\n    \r\n    function applyGalleryFilters() {\r\n        let result = [...galleryRawData];\r\n        const speciesVal = filterSpecies.value;\r\n        const provinceVal = filterProvince.value;\r\n        const searchVal = searchText.value.trim().toLowerCase();\r\n        \r\n        if (speciesVal) {\r\n            result = result.filter(item => item.species === speciesVal);\r\n        }\r\n        if (provinceVal) {\r\n            result = result.filter(item => {\r\n                const itemProvince = String(\r\n                    item.province ??\r\n                    item.provinsi ??\r\n                    item.province_name ??\r\n                    item.provinceName ??\r\n                    ''\r\n                ).trim();\r\n                return itemProvince === provinceVal;\r\n            });\r\n        }\r\n        if (searchVal) {\r\n            result = result.filter(item => {\r\n                const searchable = getSearchableText(item);\r\n                return searchable.includes(searchVal);\r\n            });\r\n        }\r\n        result = result.filter(item => item.left_photo_url && item.left_photo_url.trim() !== '');\r\n        galleryFilteredData = result;\r\n        statsSpan.innerText = galleryFilteredData.length;\r\n        galleryCurrentPage = 1;\r\n        renderGallery();\r\n        renderGalleryPagination();\r\n    }\r\n    \r\n    function renderGallery() {\r\n        if (!galleryFilteredData.length) {\r\n            galleryContainerEl.innerHTML = `<div class=\"error-state\" style=\"padding:50px;text-align:center;\">\ud83d\udc22 Belum ada foto yang cocok. Coba ubah filter atau pastikan data tersedia.<\/div>`;\r\n            paginationDiv.style.display = 'none';\r\n            return;\r\n        }\r\n        paginationDiv.style.display = 'flex';\r\n        const startIdx = (galleryCurrentPage - 1) * GALLERY_ITEMS_PER_PAGE;\r\n        const pageItems = galleryFilteredData.slice(startIdx, startIdx + GALLERY_ITEMS_PER_PAGE);\r\n        \r\n        let cardsHtml = '<div class=\"gallery-grid\">';\r\n        for (const turtle of pageItems) {\r\n            const photoUrl = turtle.left_photo_url || '';\r\n            const turtleId = turtle.turtle_id || '\u2014';\r\n            const displayName = getDisplayName(turtle);\r\n            const species = turtle.species || 'Tidak diketahui';\r\n            const locationParts = [];\r\n            if (turtle.location_name) locationParts.push(turtle.location_name);\r\n            if (turtle.district) locationParts.push(turtle.district);\r\n            const provinceVal = String(\r\n                turtle.province ??\r\n                turtle.provinsi ??\r\n                turtle.province_name ??\r\n                turtle.provinceName ??\r\n                ''\r\n            ).trim();\r\n            if (provinceVal) locationParts.push(provinceVal);\r\n            const locationStr = locationParts.join(', ') || 'Lokasi tidak tersedia';\r\n            const surveyDate = turtle.survey_date ? new Date(turtle.survey_date).toLocaleDateString('id-ID') : 'Tanggal ?';\r\n            const contributor = turtle.contributor || 'Anonim';\r\n            const sexIcon = turtle.sex === 'Jantan' ? '\u2642\ufe0f' : (turtle.sex === 'Betina' ? '\u2640\ufe0f' : '');\r\n            \r\n            const safePhotoUrl = escapeHtml(photoUrl);\r\n            const safeTurtleId = escapeHtml(turtleId);\r\n            const safeDisplayName = escapeHtml(displayName);\r\n            const safeSpecies = escapeHtml(species);\r\n            const safeLocationStr = escapeHtml(locationStr.substring(0, 55));\r\n            const safeSurveyDate = escapeHtml(surveyDate);\r\n            const safeContributor = escapeHtml(contributor);\r\n            \r\n            const dataAttr = encodeURIComponent(JSON.stringify(turtle));\r\n            \r\n            cardsHtml += `\r\n                <div class=\"turtle-card\" data-id=\"${safeTurtleId}\">\r\n                    <div class=\"photo-wrapper\" onclick=\"window.galleryOpenLightbox('${safePhotoUrl}', '${dataAttr}')\">\r\n                        <img decoding=\"async\" src=\"${safePhotoUrl}\" loading=\"lazy\" alt=\"Foto penyu ${safeTurtleId}\" onerror=\"this.onerror=null;this.src='data:image\/svg+xml,%3Csvg xmlns=%22http:\/\/www.w3.org\/2000\/svg%22 width=%22400%22 height=%22400%22%3E%3Crect width=%22400%22 height=%22400%22 fill=%22%23eef2f5%22\/%3E%3Ctext x=%2250%22 y=%22200%22 font-family=%22sans-serif%22 font-size=%2230%22 fill=%22%2394a3b8%22%3EGambar Tidak Tersedia%3C\/text%3E%3C\/svg%3E';\">\r\n                    <\/div>\r\n                    <div class=\"card-info\">\r\n                        <div class=\"turtle-name\">\r\n                            <span>${safeDisplayName}<\/span>\r\n                            <span class=\"turtle-id\">#${safeTurtleId}<\/span>\r\n                        <\/div>\r\n                        <div class=\"species-badge\">\ud83d\udc22 ${safeSpecies} ${sexIcon}<\/div>\r\n                        <div class=\"meta-row\">\r\n                            <span class=\"location\">\ud83d\udccd ${safeLocationStr}<\/span>\r\n                            <span class=\"date\">\ud83d\udcc5 ${safeSurveyDate}<\/span>\r\n                        <\/div>\r\n                        <div class=\"contributor\">\ud83d\udc65 Kontributor: ${safeContributor}<\/div>\r\n                        <div class=\"view-detail\">\r\n                            <button onclick=\"window.galleryOpenLightbox('${safePhotoUrl}', '${dataAttr}')\">\ud83d\udd0d Lihat Detail<\/button>\r\n                        <\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n        }\r\n        cardsHtml += '<\/div>';\r\n        galleryContainerEl.innerHTML = cardsHtml;\r\n    }\r\n    \r\n    function renderGalleryPagination() {\r\n        const totalPages = Math.ceil(galleryFilteredData.length \/ GALLERY_ITEMS_PER_PAGE);\r\n        if (totalPages <= 1) {\r\n            paginationDiv.innerHTML = '';\r\n            paginationDiv.style.display = 'none';\r\n            return;\r\n        }\r\n        paginationDiv.style.display = 'flex';\r\n        let pagHtml = '<div class=\"pagination\">';\r\n        pagHtml += `<button class=\"page-btn\" data-page=\"${galleryCurrentPage-1}\" ${galleryCurrentPage === 1 ? 'disabled' : ''}>\u2039 Sebelumnya<\/button>`;\r\n        let startPage = Math.max(1, galleryCurrentPage - 2);\r\n        let endPage = Math.min(totalPages, galleryCurrentPage + 2);\r\n        if (startPage > 1) pagHtml += `<button class=\"page-btn\" data-page=\"1\">1<\/button>${startPage > 2 ? '<span style=\"padding:8px;\">...<\/span>' : ''}`;\r\n        for (let i = startPage; i <= endPage; i++) {\r\n            pagHtml += `<button class=\"page-btn ${i === galleryCurrentPage ? 'active' : ''}\" data-page=\"${i}\">${i}<\/button>`;\r\n        }\r\n        if (endPage < totalPages) pagHtml += `${endPage < totalPages-1 ? '<span style=\"padding:8px;\">...<\/span>' : ''}<button class=\"page-btn\" data-page=\"${totalPages}\">${totalPages}<\/button>`;\r\n        pagHtml += `<button class=\"page-btn\" data-page=\"${galleryCurrentPage+1}\" ${galleryCurrentPage === totalPages ? 'disabled' : ''}>Berikutnya \u203a<\/button>`;\r\n        pagHtml += '<\/div>';\r\n        paginationDiv.innerHTML = pagHtml;\r\n        \r\n        document.querySelectorAll('.page-btn[data-page]').forEach(btn => {\r\n            btn.addEventListener('click', (e) => {\r\n                let newPage = parseInt(btn.dataset.page);\r\n                if (!isNaN(newPage) && newPage >= 1 && newPage <= totalPages) {\r\n                    galleryCurrentPage = newPage;\r\n                    renderGallery();\r\n                    renderGalleryPagination();\r\n                    window.scrollTo({ top: 380, behavior: 'smooth' });\r\n                }\r\n            });\r\n        });\r\n    }\r\n    \r\n    \/\/ ======================== LIGHTBOX DENGAN PETA (SEPERTI HALAMAN UTAMA) ========================\r\n    \r\n    function initGalleryDetailMap(lat, lng, turtle) {\r\n        \/\/ Hapus peta lama\r\n        if (galleryDetailMap) {\r\n            try {\r\n                galleryDetailMap.remove();\r\n            } catch(e) {}\r\n            galleryDetailMap = null;\r\n            galleryDetailMarker = null;\r\n        }\r\n        \r\n        const container = document.getElementById('galleryDetailMapContainer');\r\n        if (!container) {\r\n            console.warn('Map container not found');\r\n            return;\r\n        }\r\n        \r\n        \/\/ Bersihkan container\r\n        if (container._leaflet_id) {\r\n            container._leaflet_id = null;\r\n        }\r\n        container.innerHTML = '';\r\n        \r\n        try {\r\n            \/\/ Inisialisasi peta dengan zoom yang lebih dekat\r\n            const map = L.map('galleryDetailMapContainer', {\r\n                center: [lat, lng],\r\n                zoom: 14\r\n            });\r\n            galleryDetailMap = map;\r\n            \r\n            \/\/ Tile layer - sama dengan halaman utama\r\n            L.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png', {\r\n                attribution: '&copy; <a href=\"https:\/\/www.openstreetmap.org\/copyright\">OpenStreetMap<\/a>'\r\n            }).addTo(map);\r\n            \r\n            \/\/ Buat popup dengan detail lengkap - SEPERTI HALAMAN UTAMA\r\n            const displayName = getDisplayName(turtle);\r\n            const species = turtle.species || 'Tidak diketahui';\r\n            const locationFull = [turtle.location_name, turtle.district, turtle.province].filter(v=>v).join(', ') || 'Lokasi tidak tersedia';\r\n            const surveyDate = turtle.survey_date ? new Date(turtle.survey_date).toLocaleDateString('id-ID', { year:'numeric', month:'long', day:'numeric' }) : 'Tidak ada';\r\n            const contributor = turtle.contributor || 'Anonim';\r\n            const sexText = turtle.sex ? (turtle.sex === 'Jantan' ? 'Jantan \u2642\ufe0f' : (turtle.sex === 'Betina' ? 'Betina \u2640\ufe0f' : turtle.sex)) : 'Tidak tercatat';\r\n            const ccl = turtle.ccl ? `${turtle.ccl} cm` : '-';\r\n            \r\n            const popupContent = `\r\n                <div style=\"min-width:220px; max-width:300px;\">\r\n                    <div style=\"font-weight:700;font-size:1.2rem;color:#0c4a6e;margin-bottom:4px;\">\r\n                        \ud83d\udc22 ${escapeHtml(displayName)}\r\n                    <\/div>\r\n                    <div style=\"font-size:0.8rem;color:#64748b;margin-bottom:6px;\">\r\n                        ID: ${escapeHtml(turtle.turtle_id || '-')}\r\n                    <\/div>\r\n                    <div style=\"margin:4px 0;\">\r\n                        <span style=\"background:#e0f2fe;padding:2px 10px;border-radius:20px;font-size:0.8rem;font-weight:600;\">\r\n                            ${escapeHtml(species)}\r\n                        <\/span>\r\n                        ${sexText ? `<span style=\"background:#f1f5f9;padding:2px 10px;border-radius:20px;font-size:0.8rem;margin-left:6px;\">${escapeHtml(sexText)}<\/span>` : ''}\r\n                        ${ccl !== '-' ? `<span style=\"background:#f1f5f9;padding:2px 10px;border-radius:20px;font-size:0.8rem;margin-left:6px;\">\ud83d\udccf ${escapeHtml(ccl)}<\/span>` : ''}\r\n                    <\/div>\r\n                    <div style=\"font-size:0.85rem;margin:6px 0;color:#2c5f7a;\">\r\n                        \ud83d\udccd ${escapeHtml(locationFull)}\r\n                    <\/div>\r\n                    <div style=\"font-size:0.85rem;margin:4px 0;color:#2c5f7a;\">\r\n                        \ud83d\udcc5 ${escapeHtml(surveyDate)}\r\n                    <\/div>\r\n                    <div style=\"font-size:0.8rem;margin:4px 0;color:#334155;\">\r\n                        \ud83d\udc64 ${escapeHtml(contributor)}\r\n                    <\/div>\r\n                    <div style=\"font-size:0.7rem;color:#94a3b8;margin-top:6px;border-top:1px solid #e2e8f0;padding-top:6px;\">\r\n                        \ud83d\udccd ${lat.toFixed(5)}, ${lng.toFixed(5)}\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n            \r\n            \/\/ Buat marker dengan popup\r\n            galleryDetailMarker = L.marker([lat, lng])\r\n                .addTo(map)\r\n                .bindPopup(popupContent, {\r\n                    maxWidth: 320,\r\n                    className: 'gallery-detail-popup'\r\n                });\r\n            \r\n            \/\/ Zoom dan fly ke lokasi\r\n            map.flyTo([lat, lng], 14, {\r\n                duration: 1.5,\r\n                easeLinearity: 0.25\r\n            });\r\n            \r\n            \/\/ Buka popup setelah animasi selesai\r\n            map.once('moveend', function() {\r\n                if (galleryDetailMarker) {\r\n                    galleryDetailMarker.openPopup();\r\n                }\r\n            });\r\n            \r\n            \/\/ Refresh ukuran map\r\n            setTimeout(function() {\r\n                if (galleryDetailMap) {\r\n                    galleryDetailMap.invalidateSize();\r\n                }\r\n            }, 300);\r\n            \r\n            \/\/ Refresh lagi setelah lightbox fully visible\r\n            setTimeout(function() {\r\n                if (galleryDetailMap) {\r\n                    galleryDetailMap.invalidateSize();\r\n                }\r\n            }, 800);\r\n            \r\n        } catch(e) {\r\n            console.error('Error initializing map:', e);\r\n        }\r\n    }\r\n    \r\n    \/\/ Expose function ke global\r\n    window.galleryOpenLightbox = function(photoUrl, dataAttr) {\r\n        if (!photoUrl) return;\r\n        \r\n        let turtle;\r\n        try {\r\n            turtle = JSON.parse(decodeURIComponent(dataAttr));\r\n        } catch(e) {\r\n            console.error('Error parsing turtle data:', e);\r\n            return;\r\n        }\r\n        \r\n        \/\/ Tampilkan lightbox\r\n        lightbox.style.display = 'flex';\r\n        document.body.classList.add('gallery-lightbox-open');\r\n        isLightboxOpen = true;\r\n        \r\n        \/\/ Set image\r\n        lightboxImg.src = photoUrl;\r\n        \r\n        \/\/ Detail informasi - SEPERTI HALAMAN UTAMA\r\n        const displayName = getDisplayName(turtle);\r\n        const speciesText = turtle.species || 'Tidak diketahui';\r\n        const sexText = turtle.sex ? (turtle.sex === 'Jantan' ? 'Jantan \u2642\ufe0f' : (turtle.sex === 'Betina' ? 'Betina \u2640\ufe0f' : turtle.sex)) : 'Tidak tercatat';\r\n        const ccl = turtle.ccl ? `${turtle.ccl} cm` : '-';\r\n        const locationFull = [turtle.location_name, turtle.district, turtle.province].filter(v=>v).join(', ') || 'Lokasi tidak tersedia';\r\n        const dateLocale = turtle.survey_date ? new Date(turtle.survey_date).toLocaleDateString('id-ID', { year:'numeric', month:'long', day:'numeric' }) : 'Tidak ada';\r\n        const contributorName = turtle.contributor || 'Anonim';\r\n        const additional = [];\r\n        if (turtle.behaviour) additional.push(`Perilaku: ${turtle.behaviour}`);\r\n        if (turtle.health) additional.push(`Kesehatan: ${turtle.health}`);\r\n        const extraInfo = additional.length ? `<div style=\"margin-top:8px;font-size:0.8rem;\">\ud83d\udccb ${additional.join(' \u00b7 ')}<\/div>` : '';\r\n        \r\n        const lat = parseFloat(turtle.latitude);\r\n        const lng = parseFloat(turtle.longitude);\r\n        const hasValidCoords = !isNaN(lat) && !isNaN(lng) && lat !== 0 && lng !== 0;\r\n        \r\n        let mapHtml = '';\r\n        if (hasValidCoords) {\r\n            mapHtml = `\r\n                <div style=\"margin: 12px 0;\">\r\n                    <div style=\"font-weight:600;font-size:0.85rem;color:#1e6f9f;margin-bottom:8px;\">\ud83d\udccd Lokasi Penyu di Peta<\/div>\r\n                    <div id=\"galleryDetailMapContainer\" class=\"lightbox-map\"><\/div>\r\n                <\/div>\r\n            `;\r\n        } else {\r\n            mapHtml = `\r\n                <div style=\"margin: 12px 0; padding: 16px; background: #fef2f2; border-radius: 12px; border-left: 4px solid #dc2626;\">\r\n                    <p style=\"color: #dc2626; font-size: 0.9rem; margin: 0;\">\u26a0\ufe0f Koordinat tidak tersedia untuk lokasi ini<\/p>\r\n                <\/div>\r\n            `;\r\n        }\r\n        \r\n        lightboxDetails.innerHTML = `\r\n            <div style=\"display:flex; justify-content:space-between; flex-wrap:wrap; align-items:baseline; margin-bottom:8px;\">\r\n                <h2 style=\"color:#0c4a6e; margin:0; font-size:1.5rem;\">\r\n                    \ud83d\udc22 ${escapeHtml(displayName)}\r\n                    <span style=\"font-size:0.8rem; background:#e2e8f0; padding:2px 10px; border-radius:20px; font-weight:400; margin-left:8px;\">\r\n                        ID: ${escapeHtml(turtle.turtle_id || '-')}\r\n                    <\/span>\r\n                <\/h2>\r\n            <\/div>\r\n            <div style=\"display:flex; flex-wrap:wrap; gap: 10px; margin-bottom:12px;\">\r\n                <span style=\"background:#e0f2fe; padding:4px 14px; border-radius:30px; font-size:0.8rem; font-weight:600;\">\r\n                    ${escapeHtml(speciesText)}\r\n                <\/span>\r\n                <span style=\"background:#f1f5f9; padding:4px 14px; border-radius:30px; font-size:0.8rem;\">\r\n                    ${escapeHtml(sexText)}\r\n                <\/span>\r\n                ${ccl !== '-' ? `<span style=\"background:#f1f5f9; padding:4px 14px; border-radius:30px; font-size:0.8rem;\">\ud83d\udccf CCL: ${escapeHtml(ccl)}<\/span>` : ''}\r\n            <\/div>\r\n            <div style=\"display:flex; flex-wrap:wrap; gap: 16px; font-size:0.9rem; color:#2c5f7a; margin-bottom:8px;\">\r\n                <span>\ud83d\udccd ${escapeHtml(locationFull)}<\/span>\r\n                <span>\ud83d\udcc5 ${escapeHtml(dateLocale)}<\/span>\r\n            <\/div>\r\n            <div style=\"font-size:0.9rem; color:#334155; margin-bottom:4px;\">\r\n                \ud83d\udc64 Kontributor: <strong>${escapeHtml(contributorName)}<\/strong>\r\n            <\/div>\r\n            ${extraInfo}\r\n            ${mapHtml}\r\n            <hr style=\"margin: 16px 0 8px 0; border: none; border-top: 1px solid #e2e8f0;\">\r\n            <div style=\"font-size:0.75rem; color:#94a3b8;\">\ud83d\udcf8 Foto sisi kiri | e-Turtle Indonesia Database<\/div>\r\n        `;\r\n        \r\n        \/\/ Inisialisasi peta jika ada koordinat valid\r\n        if (hasValidCoords) {\r\n            \/\/ Beri waktu untuk DOM merender container peta\r\n            setTimeout(function() {\r\n                initGalleryDetailMap(lat, lng, turtle);\r\n            }, 500);\r\n        }\r\n    };\r\n    \r\n    function closeGalleryLightbox() {\r\n        lightbox.style.display = 'none';\r\n        lightboxImg.src = '';\r\n        lightboxDetails.innerHTML = '';\r\n        document.body.classList.remove('gallery-lightbox-open');\r\n        isLightboxOpen = false;\r\n        \r\n        \/\/ Hapus peta\r\n        if (galleryDetailMap) {\r\n            try {\r\n                galleryDetailMap.remove();\r\n            } catch(e) {}\r\n            galleryDetailMap = null;\r\n            galleryDetailMarker = null;\r\n        }\r\n        \r\n        const container = document.getElementById('galleryDetailMapContainer');\r\n        if (container) {\r\n            container.innerHTML = '';\r\n            if (container._leaflet_id) {\r\n                container._leaflet_id = null;\r\n            }\r\n        }\r\n    }\r\n    \r\n    function resetGalleryFilters() {\r\n        filterSpecies.value = '';\r\n        filterProvince.value = '';\r\n        searchText.value = '';\r\n        applyGalleryFilters();\r\n    }\r\n    \r\n    async function loadGalleryData() {\r\n        galleryContainerEl.innerHTML = `<div class=\"loading-state\"><div class=\"spinner\"><\/div><p>\ud83d\udd04 Mengunduh data galeri dari server...<\/p><\/div>`;\r\n        paginationDiv.style.display = 'none';\r\n        try {\r\n            const data = await fetchGalleryData();\r\n            if (!data.length) {\r\n                galleryContainerEl.innerHTML = `<div class=\"error-state\">\u26a0\ufe0f Belum ada data penyu. Pastikan database terisi dan endpoint tersedia.<\/div>`;\r\n                galleryRawData = [];\r\n                galleryFilteredData = [];\r\n                statsSpan.innerText = '0';\r\n                return;\r\n            }\r\n            galleryRawData = data;\r\n            populateGalleryFilters(galleryRawData);\r\n            applyGalleryFilters();\r\n        } catch (err) {\r\n            galleryContainerEl.innerHTML = `<div class=\"error-state\"><strong>\u274c Gagal memuat galeri<\/strong><br>${err.message}<br><br>\ud83d\udca1 Pastikan endpoint API dapat diakses dan mengembalikan data format JSON.<\/div>`;\r\n            galleryRawData = [];\r\n            galleryFilteredData = [];\r\n            statsSpan.innerText = '0';\r\n            paginationDiv.style.display = 'none';\r\n        }\r\n    }\r\n    \r\n    \/\/ Toggle Galeri\r\n    function toggleGallery() {\r\n        isGalleryVisible = !isGalleryVisible;\r\n        \r\n        if (isGalleryVisible) {\r\n            gallerySection.style.display = 'block';\r\n            gallerySection.className = 'gallery-section show';\r\n            toggleText.textContent = 'Tutup Galeri Foto';\r\n            toggleIcon.textContent = '\u25b2';\r\n            toggleBtn.style.background = 'linear-gradient(135deg, #dc2626, #b91c1c)';\r\n            \r\n            if (!galleryRawData.length) {\r\n                loadGalleryData();\r\n            }\r\n        } else {\r\n            gallerySection.className = 'gallery-section hide';\r\n            setTimeout(function() {\r\n                gallerySection.style.display = 'none';\r\n            }, 300);\r\n            toggleText.textContent = 'Lihat Galeri Foto';\r\n            toggleIcon.textContent = '\u25bc';\r\n            toggleBtn.style.background = 'linear-gradient(135deg, #0284c7, #0369a1)';\r\n        }\r\n    }\r\n    \r\n    \/\/ Event listeners\r\n    toggleBtn.addEventListener('click', toggleGallery);\r\n    resetBtn.addEventListener('click', resetGalleryFilters);\r\n    filterSpecies.addEventListener('change', applyGalleryFilters);\r\n    filterProvince.addEventListener('change', applyGalleryFilters);\r\n    searchText.addEventListener('input', applyGalleryFilters);\r\n    closeLightbox.addEventListener('click', closeGalleryLightbox);\r\n    \r\n    lightbox.addEventListener('click', function(e) {\r\n        if (e.target === lightbox) {\r\n            closeGalleryLightbox();\r\n        }\r\n    });\r\n    \r\n    document.addEventListener('keydown', function(e) {\r\n        if (e.key === 'Escape' && isLightboxOpen) {\r\n            closeGalleryLightbox();\r\n        }\r\n    });\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>e-Tu rtle Indonesia \u2013 Upload &#038; Isi Data Penyu \ud83d\udc22 e-Turtle Indonesia \ud83c\uddee\ud83c\udde9 Indonesia\ud83c\uddec\ud83c\udde7 English \ud83d\udc22 Upload Foto Sisi Kiri [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-1968","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v22.3 (Yoast SEO v24.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Find Your Turtle! - marineconservation.id<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/marineconservation.id\/id\/find-your-turtle\/\" \/>\n<meta property=\"og:locale\" content=\"id_ID\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Find Your Turtle!\" \/>\n<meta property=\"og:description\" content=\"e-Tu rtle Indonesia \u2013 Upload &#038; Isi Data Penyu \ud83d\udc22 e-Turtle Indonesia \ud83c\uddee\ud83c\udde9 Indonesia\ud83c\uddec\ud83c\udde7 English \ud83d\udc22 Upload Foto Sisi Kiri [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/marineconservation.id\/id\/find-your-turtle\/\" \/>\n<meta property=\"og:site_name\" content=\"marineconservation.id\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/profile.php?id=61572311944591\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-24T01:07:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Estimasi waktu membaca\" \/>\n\t<meta name=\"twitter:data1\" content=\"8 menit\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/marineconservation.id\/find-your-turtle\/\",\"url\":\"https:\/\/marineconservation.id\/find-your-turtle\/\",\"name\":\"Find Your Turtle! - marineconservation.id\",\"isPartOf\":{\"@id\":\"https:\/\/marineconservation.id\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/marineconservation.id\/find-your-turtle\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/marineconservation.id\/find-your-turtle\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-1024x576.png\",\"datePublished\":\"2026-03-30T07:15:32+00:00\",\"dateModified\":\"2026-07-24T01:07:52+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/marineconservation.id\/find-your-turtle\/#breadcrumb\"},\"inLanguage\":\"id\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/marineconservation.id\/find-your-turtle\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"id\",\"@id\":\"https:\/\/marineconservation.id\/find-your-turtle\/#primaryimage\",\"url\":\"https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-1024x576.png\",\"contentUrl\":\"https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-1024x576.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/marineconservation.id\/find-your-turtle\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/marineconservation.id\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Find Your Turtle!\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/marineconservation.id\/#website\",\"url\":\"https:\/\/marineconservation.id\/\",\"name\":\"marineconservation.id\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/marineconservation.id\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/marineconservation.id\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"id\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/marineconservation.id\/#organization\",\"name\":\"marineconservation.id\",\"url\":\"https:\/\/marineconservation.id\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"id\",\"@id\":\"https:\/\/marineconservation.id\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/marineconservation.id\/wp-content\/uploads\/2025\/02\/Marine-Conservation-Indonesia.png\",\"contentUrl\":\"https:\/\/marineconservation.id\/wp-content\/uploads\/2025\/02\/Marine-Conservation-Indonesia.png\",\"width\":500,\"height\":500,\"caption\":\"marineconservation.id\"},\"image\":{\"@id\":\"https:\/\/marineconservation.id\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/profile.php?id=61572311944591\",\"https:\/\/www.instagram.com\/marineconservation.id\/\",\"https:\/\/www.youtube.com\/watch?v=nOmjtk-dTg8&list=LL\"]}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Find Your Turtle! - marineconservation.id","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/marineconservation.id\/id\/find-your-turtle\/","og_locale":"id_ID","og_type":"article","og_title":"Find Your Turtle!","og_description":"e-Tu rtle Indonesia \u2013 Upload &#038; Isi Data Penyu \ud83d\udc22 e-Turtle Indonesia \ud83c\uddee\ud83c\udde9 Indonesia\ud83c\uddec\ud83c\udde7 English \ud83d\udc22 Upload Foto Sisi Kiri [&hellip;]","og_url":"https:\/\/marineconservation.id\/id\/find-your-turtle\/","og_site_name":"marineconservation.id","article_publisher":"https:\/\/www.facebook.com\/profile.php?id=61572311944591","article_modified_time":"2026-07-24T01:07:52+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Estimasi waktu membaca":"8 menit"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/marineconservation.id\/find-your-turtle\/","url":"https:\/\/marineconservation.id\/find-your-turtle\/","name":"Find Your Turtle! - marineconservation.id","isPartOf":{"@id":"https:\/\/marineconservation.id\/#website"},"primaryImageOfPage":{"@id":"https:\/\/marineconservation.id\/find-your-turtle\/#primaryimage"},"image":{"@id":"https:\/\/marineconservation.id\/find-your-turtle\/#primaryimage"},"thumbnailUrl":"https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-1024x576.png","datePublished":"2026-03-30T07:15:32+00:00","dateModified":"2026-07-24T01:07:52+00:00","breadcrumb":{"@id":"https:\/\/marineconservation.id\/find-your-turtle\/#breadcrumb"},"inLanguage":"id","potentialAction":[{"@type":"ReadAction","target":["https:\/\/marineconservation.id\/find-your-turtle\/"]}]},{"@type":"ImageObject","inLanguage":"id","@id":"https:\/\/marineconservation.id\/find-your-turtle\/#primaryimage","url":"https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-1024x576.png","contentUrl":"https:\/\/marineconservation.id\/wp-content\/uploads\/2026\/03\/Penyu-Hijau-1024x576.png"},{"@type":"BreadcrumbList","@id":"https:\/\/marineconservation.id\/find-your-turtle\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/marineconservation.id\/"},{"@type":"ListItem","position":2,"name":"Find Your Turtle!"}]},{"@type":"WebSite","@id":"https:\/\/marineconservation.id\/#website","url":"https:\/\/marineconservation.id\/","name":"marineconservation.id","description":"","publisher":{"@id":"https:\/\/marineconservation.id\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/marineconservation.id\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"id"},{"@type":"Organization","@id":"https:\/\/marineconservation.id\/#organization","name":"marineconservation.id","url":"https:\/\/marineconservation.id\/","logo":{"@type":"ImageObject","inLanguage":"id","@id":"https:\/\/marineconservation.id\/#\/schema\/logo\/image\/","url":"https:\/\/marineconservation.id\/wp-content\/uploads\/2025\/02\/Marine-Conservation-Indonesia.png","contentUrl":"https:\/\/marineconservation.id\/wp-content\/uploads\/2025\/02\/Marine-Conservation-Indonesia.png","width":500,"height":500,"caption":"marineconservation.id"},"image":{"@id":"https:\/\/marineconservation.id\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/profile.php?id=61572311944591","https:\/\/www.instagram.com\/marineconservation.id\/","https:\/\/www.youtube.com\/watch?v=nOmjtk-dTg8&list=LL"]}]}},"_links":{"self":[{"href":"https:\/\/marineconservation.id\/id\/wp-json\/wp\/v2\/pages\/1968","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/marineconservation.id\/id\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/marineconservation.id\/id\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/marineconservation.id\/id\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/marineconservation.id\/id\/wp-json\/wp\/v2\/comments?post=1968"}],"version-history":[{"count":238,"href":"https:\/\/marineconservation.id\/id\/wp-json\/wp\/v2\/pages\/1968\/revisions"}],"predecessor-version":[{"id":2610,"href":"https:\/\/marineconservation.id\/id\/wp-json\/wp\/v2\/pages\/1968\/revisions\/2610"}],"wp:attachment":[{"href":"https:\/\/marineconservation.id\/id\/wp-json\/wp\/v2\/media?parent=1968"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}