{"id":553,"date":"2026-02-21T19:42:03","date_gmt":"2026-02-21T18:42:03","guid":{"rendered":"https:\/\/www.ingilog.com\/sugardelta_prod\/?page_id=553"},"modified":"2026-05-25T16:25:10","modified_gmt":"2026-05-25T14:25:10","slug":"logs-et-activations","status":"publish","type":"page","link":"https:\/\/www.ingilog.com\/sugardelta_prod\/logs-et-activations\/","title":{"rendered":"Logs et Activations"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"553\" class=\"elementor elementor-553\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f45f501 e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"f45f501\" 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-11fa603 elementor-widget elementor-widget-html\" data-id=\"11fa603\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!-- ============================================================\n  HAM RADIO ACTIVATIONS \u2014 Widget Elementor\n  Requiert : window.hamActConfig (inject\u00e9 par WPCode), jQuery, Leaflet\n============================================================ -->\n<link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/leaflet\/1.9.4\/leaflet.min.css\">\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/leaflet\/1.9.4\/leaflet.min.js\"><\/script>\n\n<style>\n:root {\n  --ha-bg:#0d1117;--ha-surface:#161b22;--ha-border:#30363d;\n  --ha-accent:#238636;--ha-blue:#1f6feb;--ha-danger:#da3633;\n  --ha-text:#ffffff;--ha-muted:#b0bac5;--ha-radius:8px;\n  --ha-shadow:0 4px 24px rgba(0,0,0,.5);\n}\n#ham-activations *{box-sizing:border-box;}\n#ham-activations h1,#ham-activations h2,#ham-activations h3,\n#ham-activations h4,#ham-activations p,#ham-activations dl,\n#ham-activations dd,#ham-activations dt{margin:0;padding:0;}\n#ham-activations ul,#ham-activations ol{margin:0;padding:0;list-style:none;}\n\n#ham-activations{\n  font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;\n  font-weight:500;\n  background:var(--ha-bg);color:var(--ha-text);\n  border-radius:var(--ha-radius);padding:20px 28px;\n}\n\n\/* ---- Header ---- *\/\n\n\/* ---- Filtres ---- *\/\n.ha-filters{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:22px;}\n.ha-filter-btn{padding:5px 12px;border-radius:20px;border:1px solid var(--ha-border);background:transparent;color:var(--ha-muted);font-size:.78rem;font-weight:600;cursor:pointer;transition:all .15s;white-space:nowrap;flex-shrink:0;}\n.ha-filter-btn.active{background:var(--ha-blue);color:#fff;border-color:var(--ha-blue);}\n\n\/* ---- Table ---- *\/\n.ha-table-wrap{overflow-x:hidden;border-radius:var(--ha-radius);border:1px solid var(--ha-border);width:100%;}\n.ha-table{width:100%;border-collapse:collapse;font-size:.88rem;font-weight:500;table-layout:fixed;}\n.ha-table th{background:var(--ha-surface);color:var(--ha-muted);font-weight:500;text-transform:uppercase;font-size:.72rem;letter-spacing:.05em;padding:10px 14px;text-align:left;border-bottom:1px solid var(--ha-border);font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}\n.ha-table td{padding:10px 14px;border-bottom:1px solid var(--ha-border);vertical-align:middle;color:#ffffff;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}\n.ha-table tr:last-child td{border-bottom:none;}\n.ha-table tbody tr{cursor:pointer;transition:background .12s;}\n.ha-table tbody tr:hover{background:rgba(255,255,255,.04);}\n\n\/* ---- Badges ---- *\/\n.ha-badge{display:inline-block;padding:4px 11px;border-radius:12px;font-size:.78rem;font-weight:700;white-space:nowrap;}\n.ha-badge-planned{background:rgba(31,111,235,.2);color:#58a6ff;border:1px solid rgba(31,111,235,.4);}\n.ha-badge-active{background:rgba(35,134,54,.2);color:#3fb950;border:1px solid rgba(35,134,54,.4);}\n.ha-badge-completed{background:rgba(139,148,158,.15);color:var(--ha-muted);border:1px solid var(--ha-border);}\n.ha-program-tag{display:inline-block;background:rgba(210,153,34,.15);color:#d29922;border:1px solid rgba(210,153,34,.3);padding:3px 10px;border-radius:10px;font-size:.78rem;font-weight:700;}\n\n\/* ---- Loading \/ Empty ---- *\/\n.ha-loading{display:flex;align-items:center;justify-content:center;gap:10px;padding:40px;color:var(--ha-muted);}\n.ha-empty{text-align:center;padding:40px;color:var(--ha-muted);}\n.ha-spinner{width:18px;height:18px;border:2px solid var(--ha-border);border-top-color:var(--ha-blue);border-radius:50%;animation:haSpin .7s linear infinite;}\n@keyframes haSpin{to{transform:rotate(360deg);}}\n\n\/* ---- Pagination ---- *\/\n.ha-pagination{display:flex;align-items:center;justify-content:center;gap:8px;margin-top:20px;}\n.ha-page-btn{padding:7px 16px;border-radius:6px;border:1px solid var(--ha-border);background:transparent;color:#ffffff;cursor:pointer;font-size:.87rem;font-weight:600;transition:all .15s;}\n.ha-page-btn:hover{border-color:var(--ha-blue);color:var(--ha-blue);}\n.ha-page-btn.active{background:var(--ha-blue);color:#fff;border-color:var(--ha-blue);}\n.ha-page-btn:disabled{opacity:.4;cursor:not-allowed;}\n\n\/* ---- Boutons ---- *\/\n.ha-btn{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:var(--ha-radius);border:none;cursor:pointer;font-size:.86rem;font-weight:700;white-space:nowrap;flex-shrink:0;transition:filter .15s,transform .1s;}\n.ha-btn:active{transform:scale(.97);}\n.ha-btn:hover{filter:brightness(1.1);}\n.ha-btn-primary{background:var(--ha-accent);color:#fff;}\n.ha-btn-blue{background:var(--ha-blue);color:#fff;}\n.ha-btn-ghost{background:transparent;color:var(--ha-text);border:1px solid var(--ha-border);}\n.ha-btn-danger{background:var(--ha-danger);color:#fff;}\n.ha-btn-sm{padding:5px 12px;font-size:.78rem;}\n\n\/* ---- Toast ---- *\/\n.ha-toast{position:fixed;bottom:26px;right:26px;z-index:99999;max-width:320px;padding:12px 18px;border-radius:var(--ha-radius);font-size:.85rem;font-weight:500;box-shadow:var(--ha-shadow);animation:haSlide .3s ease;}\n.ha-toast-success{background:#238636;color:#fff;}\n.ha-toast-error{background:#da3633;color:#fff;}\n@keyframes haSlide{from{transform:translateY(14px);opacity:0;}}\n\n\/* ---- Overlay \/ Modal ---- *\/\n.ha-overlay{position:fixed;inset:0;background:rgba(0,0,0,.78);backdrop-filter:blur(3px);z-index:9999;display:flex;align-items:flex-start;justify-content:center;padding:20px;overflow-y:auto;}\n.ha-overlay.hidden{display:none;}\n.ha-modal{background:var(--ha-surface);border:1px solid var(--ha-border);border-radius:12px;width:100%;box-shadow:var(--ha-shadow);display:flex;flex-direction:column;margin:auto;}\n.ha-modal-form{max-width:700px;}\n.ha-modal-detail{max-width:1100px;}\n.ha-modal-head{display:flex;align-items:center;justify-content:space-between;padding:18px 36px;border-bottom:1px solid var(--ha-border);position:sticky;top:0;background:var(--ha-surface);z-index:2;}\n.ha-modal-head h3{font-size:1.08rem;font-weight:800;color:#ffffff;}\n.ha-modal-close{background:none;border:none;color:var(--ha-muted);cursor:pointer;font-size:1.4rem;line-height:1;padding:2px 6px;border-radius:4px;}\n.ha-modal-close:hover{color:var(--ha-text);}\n.ha-modal-body{padding:24px 32px;}\n.ha-modal-foot{padding:14px 32px;border-top:1px solid var(--ha-border);display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap;position:sticky;bottom:0;background:var(--ha-surface);}\n\n\/* ---- Formulaire ---- *\/\n.ha-form{display:flex;flex-direction:column;gap:18px;}\n.ha-row{display:grid;gap:14px;}\n.ha-row.c2{grid-template-columns:1fr 1fr;gap:12px 20px;}\n.ha-row.c3{grid-template-columns:1fr 1fr 1fr;gap:12px 16px;}\n.ha-field{display:flex;flex-direction:column;gap:5px;}\n.ha-field label{font-size:.76rem;font-weight:700;color:var(--ha-muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:3px;}\n.ha-field input,.ha-field select,.ha-field textarea{\n  background:#0d1117;border:1px solid var(--ha-border);border-radius:6px;\n  color:#ffffff;padding:11px 16px;font-size:.92rem;font-weight:500;font-family:inherit;\n  outline:none;width:100%;transition:border-color .15s;\n}\n.ha-field input:focus,.ha-field select:focus,.ha-field textarea:focus{border-color:var(--ha-blue);}\n.ha-field input::placeholder,.ha-field textarea::placeholder{color:var(--ha-muted);}\n.ha-field textarea{resize:vertical;min-height:60px;}\n\n\/* ---- Modes checkboxes ---- *\/\n.ha-modes{display:flex;gap:10px;flex-wrap:wrap;margin-top:4px;}\n.ha-mode-chip{display:flex;align-items:center;gap:6px;padding:8px 18px;border:1px solid var(--ha-border);border-radius:20px;cursor:pointer;font-size:.88rem;font-weight:600;color:#ffffff;transition:all .15s;user-select:none;}\n.ha-mode-chip input{display:none;}\n.ha-mode-chip.checked{background:var(--ha-blue);border-color:var(--ha-blue);color:#fff;}\n\n\/* ---- Recherche membres ---- *\/\n.ha-member-search{position:relative;}\n.ha-member-results{position:absolute;top:100%;left:0;right:0;z-index:50;background:var(--ha-surface);border:1px solid var(--ha-border);border-top:none;border-radius:0 0 6px 6px;max-height:200px;overflow-y:auto;}\n.ha-member-result-item{padding:11px 14px;cursor:pointer;font-size:.88rem;transition:background .12s;display:flex;align-items:center;gap:10px;color:#ffffff;}\n.ha-member-result-item:hover{background:rgba(255,255,255,.06);}\n.ha-member-result-item .cs{font-weight:600;}\n.ha-member-result-item .loc{color:var(--ha-muted);font-size:.75rem;}\n\n\/* ---- Liste membres ---- *\/\n.ha-members-list{display:flex;flex-direction:column;gap:8px;margin-top:10px;}\n.ha-member-row{display:flex;align-items:center;gap:14px;background:#0d1117;border:1px solid var(--ha-border);border-radius:6px;padding:12px 18px;}\n.ha-member-row .cs{font-weight:700;font-size:.9rem;color:#ffffff;flex:0 0 auto;}\n.ha-member-row input[type=text]{flex:1;background:transparent;border:none;border-bottom:1px solid var(--ha-border);color:var(--ha-text);font-size:.82rem;padding:2px 4px;outline:none;}\n.ha-member-row input[type=text]:focus{border-bottom-color:var(--ha-blue);}\n.ha-member-row input::placeholder{color:var(--ha-muted);}\n.ha-member-remove{background:none;border:none;color:var(--ha-muted);cursor:pointer;font-size:1rem;padding:2px 4px;border-radius:4px;transition:color .15s;margin-left:auto;}\n.ha-member-remove:hover{color:var(--ha-danger);}\n\n\/* ---- Detail popup layout ---- *\/\n.ha-detail-layout{display:grid;grid-template-columns:1fr 380px;gap:24px;align-items:start;}\n.ha-detail-left{display:flex;flex-direction:column;gap:20px;}\n.ha-detail-right{position:sticky;top:0;}\n.ha-detail-map{border-radius:var(--ha-radius);overflow:hidden;border:1px solid var(--ha-border);}\n.ha-detail-map-el{height:480px;background:#0d1117;}\n\n\/* ---- Infos detail ---- *\/\n.ha-info-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px 28px;}\n.ha-info-grid dt{font-size:.73rem;font-weight:600;color:var(--ha-muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:4px;}\n.ha-info-grid dd{font-weight:600;font-size:.95rem;color:#ffffff;}\n.ha-detail-section{background:#0d1117;border:1px solid var(--ha-border);border-radius:var(--ha-radius);padding:16px 20px;}\n.ha-detail-section h4{font-size:.84rem;font-weight:700;color:var(--ha-muted);text-transform:uppercase;letter-spacing:.06em;margin-bottom:16px;}\n\n\/* ---- QSO Members detail ---- *\/\n.ha-qso-member-row{display:flex;align-items:center;gap:16px;padding:12px 8px;border-bottom:1px solid var(--ha-border);font-size:.9rem;font-weight:500;color:#ffffff;}\n.ha-qso-member-row:last-child{border-bottom:none;}\n.ha-qso-member-row .cs{font-weight:700;}\n.ha-qso-member-row .loc-badge{font-size:.74rem;color:#b0bac5;background:rgba(255,255,255,.08);padding:2px 8px;border-radius:10px;}\n.ha-flag{width:16px;height:12px;vertical-align:middle;border-radius:2px;}\n\n\/* ---- Toggle carte ---- *\/\n.ha-map-toggle{display:flex;gap:6px;margin-bottom:8px;}\n.ha-map-toggle-btn{flex:1;padding:5px;border:1px solid var(--ha-border);background:transparent;color:var(--ha-muted);border-radius:6px;cursor:pointer;font-size:.78rem;transition:all .15s;}\n.ha-map-toggle-btn.active{background:var(--ha-blue);color:#fff;border-color:var(--ha-blue);}\n\n\/* ---- Notes ---- *\/\n.ha-notes{font-size:.92rem;font-weight:500;color:#c8d0d8;line-height:1.7;white-space:pre-wrap;}\n\n@media(max-width:800px){\n  .ha-detail-layout{grid-template-columns:1fr;}\n  .ha-detail-right{position:static;}\n  .ha-row.c2,.ha-row.c3{grid-template-columns:1fr;}\n}\n\n\/* ---- Responsive ---- *\/\n@media(max-width:800px){\n  #ham-activations{padding:16px 16px;}\n  .ha-modal-body{padding:22px 24px;}\n  .ha-modal-head{padding:18px 24px;}\n  .ha-modal-foot{padding:16px 24px;}\n  .ha-table th,.ha-table td{padding:8px 10px;font-size:.8rem;}\n  .ha-topbar{flex-direction:column;align-items:flex-start;}\n}\n\n\/* Largeurs colonnes pour tenir sur une ligne *\/\n.ha-table th:nth-child(1),.ha-table td:nth-child(1){width:12%;}  \/* Indicatif *\/\n.ha-table th:nth-child(2),.ha-table td:nth-child(2){width:18%;}  \/* Programme *\/\n.ha-table th:nth-child(3),.ha-table td:nth-child(3){width:22%;}  \/* Lieu *\/\n.ha-table th:nth-child(4),.ha-table td:nth-child(4){width:16%;}  \/* Date *\/\n.ha-table th:nth-child(5),.ha-table td:nth-child(5){width:14%;}  \/* Modes *\/\n.ha-table th:nth-child(6),.ha-table td:nth-child(6){width:8%;}   \/* QSO *\/\n.ha-table th:nth-child(7),.ha-table td:nth-child(7){width:10%;}  \/* Statut *\/\n<\/style>\n\n<!-- ============================================================\n  STRUCTURE PRINCIPALE\n============================================================ -->\n<div id=\"ham-activations\">\n\n  <div class=\"ha-topbar\">\n    <div class=\"ha-filters\" id=\"ha-filters\">\n    <button class=\"ha-filter-btn active\" data-program=\"\">Tous<\/button>\n    <button class=\"ha-filter-btn\" data-program=\"\/DX\">\/DX<\/button>\n    <button class=\"ha-filter-btn\" data-program=\"\/0\">\/0<\/button>\n    <button class=\"ha-filter-btn\" data-program=\"\/Indicatif\">\/Indicatif<\/button>\n    <button class=\"ha-filter-btn\" data-program=\"SOTA\">SOTA<\/button>\n    <button class=\"ha-filter-btn\" data-program=\"POTA\">POTA<\/button>\n    <button class=\"ha-filter-btn\" data-program=\"IOTA\">IOTA<\/button>\n    <button class=\"ha-filter-btn\" data-program=\"WWFF\">WWFF<\/button>\n    <button class=\"ha-filter-btn\" data-program=\"LIGHTHOUSE\">Lighthouse<\/button>\n    <button class=\"ha-filter-btn\" data-program=\"OTHER\">Autre<\/button>\n    <\/div>\n    <button class=\"ha-btn ha-btn-primary\" id=\"ha-btn-new\" style=\"display:none\">\n      <svg width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" viewBox=\"0 0 24 24\"><path d=\"M12 5v14M5 12h14\"\/><\/svg>\n      Nouvelle activation\n    <\/button>\n  <\/div>\n\n  <div class=\"ha-table-wrap\">\n    <table class=\"ha-table\">\n      <thead>\n        <tr>\n          <th>Indicatif<\/th>\n          <th>Programme \/ Ref<\/th>\n          <th>Lieu<\/th>\n          <th>Date<\/th>\n          <th>Modes<\/th>\n          <th>QSO<\/th>\n          <th>Statut<\/th>\n        <\/tr>\n      <\/thead>\n      <tbody id=\"ha-tbody\">\n        <tr><td colspan=\"7\"><div class=\"ha-loading\"><div class=\"ha-spinner\"><\/div> Chargement...<\/div><\/td><\/tr>\n      <\/tbody>\n    <\/table>\n  <\/div>\n  <div class=\"ha-pagination\" id=\"ha-pagination\"><\/div>\n\n<\/div>\n\n<!-- ============================================================\n  MODAL FORMULAIRE\n============================================================ -->\n<div class=\"ha-overlay hidden\" id=\"ha-overlay-form\">\n  <div class=\"ha-modal ha-modal-form\">\n    <div class=\"ha-modal-head\">\n      <h3 id=\"ha-form-title\">&#128246; Nouvelle activation<\/h3>\n      <button class=\"ha-modal-close\" data-close=\"ha-overlay-form\">&#215;<\/button>\n    <\/div>\n    <div class=\"ha-modal-body\">\n      <div class=\"ha-form\">\n\n        <div class=\"ha-row c2\">\n          <div class=\"ha-field\">\n            <label>Indicatif *<\/label>\n            <input type=\"text\" id=\"ha-f-callsign\" placeholder=\"F4ABC\/P\" style=\"text-transform:uppercase\">\n          <\/div>\n          <div class=\"ha-field\">\n            <label>Programme *<\/label>\n            <select id=\"ha-f-program\">\n              <option value=\"\">&mdash; Choisir &mdash;<\/option>\n              <option value=\"\/DX\">\/DX<\/option>\n              <option value=\"\/0\">\/0<\/option>\n              <option value=\"\/Indicatif\">\/Indicatif<\/option>\n              <option>SOTA<\/option>\n              <option>POTA<\/option>\n              <option>IOTA<\/option>\n              <option>WWFF<\/option>\n              <option>LIGHTHOUSE<\/option>\n              <option value=\"OTHER\">Autre<\/option>\n            <\/select>\n          <\/div>\n        <\/div>\n\n        <div class=\"ha-row c2\">\n          <div class=\"ha-field\">\n            <label>R\u00e9f\u00e9rence (ex: F\/MC-001)<\/label>\n            <input type=\"text\" id=\"ha-f-reference\" placeholder=\"F\/MC-001\" style=\"text-transform:uppercase\">\n          <\/div>\n          <div class=\"ha-field\">\n            <label>Titre personnalis\u00e9<\/label>\n            <input type=\"text\" id=\"ha-f-title\" placeholder=\"Laissez vide pour auto-g\u00e9n\u00e9rer\">\n          <\/div>\n        <\/div>\n\n        <div class=\"ha-row c3\">\n          <div class=\"ha-field\">\n            <label>Date de d\u00e9but *<\/label>\n            <input type=\"date\" id=\"ha-f-date-start\">\n          <\/div>\n          <div class=\"ha-field\">\n            <label>Date de fin<\/label>\n            <input type=\"date\" id=\"ha-f-date-end\">\n          <\/div>\n          <div class=\"ha-field\">\n            <label>Statut<\/label>\n            <select id=\"ha-f-status\">\n              <option value=\"planned\">Planifi\u00e9e<\/option>\n              <option value=\"active\">En cours<\/option>\n              <option value=\"completed\">Termin\u00e9e<\/option>\n            <\/select>\n          <\/div>\n        <\/div>\n\n        <div class=\"ha-row c2\">\n          <div class=\"ha-field\">\n            <label>Nom du lieu<\/label>\n            <input type=\"text\" id=\"ha-f-location\" placeholder=\"Sommet du Mont-Blanc\">\n          <\/div>\n          <div class=\"ha-field\">\n            <label>QTH Locator<\/label>\n            <input type=\"text\" id=\"ha-f-locator\" placeholder=\"JN96CB\" maxlength=\"8\" style=\"text-transform:uppercase\">\n          <\/div>\n        <\/div>\n\n        <div class=\"ha-field\">\n          <label>Modes<\/label>\n          <div class=\"ha-modes\" id=\"ha-f-modes\">\n            <label class=\"ha-mode-chip\"><input type=\"checkbox\" value=\"USB\">USB<\/label>\n            <label class=\"ha-mode-chip\"><input type=\"checkbox\" value=\"LSB\">LSB<\/label>\n            <label class=\"ha-mode-chip\"><input type=\"checkbox\" value=\"AM\">AM<\/label>\n            <label class=\"ha-mode-chip\"><input type=\"checkbox\" value=\"FM\">FM<\/label>\n            <label class=\"ha-mode-chip\"><input type=\"checkbox\" value=\"FT8\">FT8<\/label>\n          <\/div>\n        <\/div>\n\n        <div class=\"ha-row c2\">\n          <div class=\"ha-field\">\n            <label>Nombre de QSO<\/label>\n            <input type=\"number\" id=\"ha-f-qso-count\" placeholder=\"0\" min=\"0\">\n          <\/div>\n        <\/div>\n\n        <div class=\"ha-field\">\n          <label>Membres du site ayant particip\u00e9<\/label>\n          <div class=\"ha-member-search\">\n            <input type=\"text\" id=\"ha-f-member-search\" placeholder=\"Rechercher un indicatif ou un nom...\" autocomplete=\"off\">\n            <div class=\"ha-member-results hidden\" id=\"ha-member-results\"><\/div>\n          <\/div>\n          <div class=\"ha-members-list\" id=\"ha-members-list\"><\/div>\n          <p style=\"font-size:.75rem;color:var(--ha-muted);margin-top:6px\">\n            Pour chaque membre, entrez son QTH Locator pour l'afficher sur la carte de l'activation.\n          <\/p>\n        <\/div>\n\n        <div class=\"ha-field\">\n          <label>Notes<\/label>\n          <textarea id=\"ha-f-notes\" placeholder=\"Conditions de propagation, commentaires...\"><\/textarea>\n        <\/div>\n\n      <\/div>\n    <\/div>\n    <div class=\"ha-modal-foot\">\n      <button class=\"ha-btn ha-btn-ghost\" data-close=\"ha-overlay-form\">Annuler<\/button>\n      <button class=\"ha-btn ha-btn-primary\" id=\"ha-btn-save\">\n        <svg width=\"12\" height=\"12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" viewBox=\"0 0 24 24\"><path d=\"M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v13a2 2 0 01-2 2z\"\/><polyline points=\"17 21 17 13 7 13 7 21\"\/><polyline points=\"7 3 7 8 15 8\"\/><\/svg>\n        <span id=\"ha-btn-save-label\">Enregistrer<\/span>\n      <\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- ============================================================\n  MODAL DETAIL\n============================================================ -->\n<div class=\"ha-overlay hidden\" id=\"ha-overlay-detail\">\n  <div class=\"ha-modal ha-modal-detail\">\n    <div class=\"ha-modal-head\">\n      <h3 id=\"ha-det-title\">Activation<\/h3>\n      <button class=\"ha-modal-close\" data-close=\"ha-overlay-detail\">&#215;<\/button>\n    <\/div>\n    <div class=\"ha-modal-body\">\n      <div class=\"ha-detail-layout\">\n\n        <!-- Gauche : infos -->\n        <div class=\"ha-detail-left\">\n\n          <div class=\"ha-detail-section\">\n            <h4>Informations<\/h4>\n            <dl class=\"ha-info-grid\" id=\"ha-det-info\"><\/dl>\n          <\/div>\n\n          <div class=\"ha-detail-section\" id=\"ha-det-members-section\" style=\"display:none\">\n            <h4>Membres participants<\/h4>\n            <div id=\"ha-det-members\"><\/div>\n          <\/div>\n\n          <div class=\"ha-detail-section\" id=\"ha-det-notes-section\" style=\"display:none\">\n            <h4>Notes<\/h4>\n            <div class=\"ha-notes\" id=\"ha-det-notes\"><\/div>\n          <\/div>\n\n        <\/div>\n\n        <!-- Droite : carte -->\n        <div class=\"ha-detail-right\">\n          <div class=\"ha-map-toggle\">\n            <button class=\"ha-map-toggle-btn active\" id=\"ha-map-btn-all\">Tous les membres<\/button>\n            <button class=\"ha-map-toggle-btn\" id=\"ha-map-btn-solo\">Activation seule<\/button>\n          <\/div>\n          <div class=\"ha-detail-map\">\n            <div class=\"ha-detail-map-el\" id=\"ha-det-map\"><\/div>\n          <\/div>\n        <\/div>\n\n      <\/div>\n    <\/div>\n    <div class=\"ha-modal-foot\">\n      <button class=\"ha-btn ha-btn-blue\" id=\"ha-btn-edit-activation\" style=\"display:none\">\n        <svg width=\"12\" height=\"12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" viewBox=\"0 0 24 24\"><path d=\"M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z\"\/><\/svg>\n        Modifier\n      <\/button>\n      <button class=\"ha-btn ha-btn-ghost\" data-close=\"ha-overlay-detail\">Fermer<\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function($) {\n'use strict';\n\n\/* ----------------------------------------------------------------\n   Config (injectee par WPCode via wp_footer)\n---------------------------------------------------------------- *\/\n\/* Attendre que hamActConfig soit injecte par wp_footer avant d'init *\/\nvar AJAX    = '\/sugardelta_prod\/wp-admin\/admin-ajax.php';\nvar NONCE   = '';\nvar CAN_ADD = false;\n\n\n\nvar currentPage = 1;\nvar currentProgram = '';\nvar detailMap = null;\nvar detailMapLayers = [];\nvar mapMode = 'all';\nvar currentDetail = null;\nvar memberSearchTimer = null;\nvar selectedMembers = [];\nvar editId = null; \/* null = creation, number = edition *\/  \/* [{id, callsign, country, locator, locatorOverride}] *\/\n\n\/* ----------------------------------------------------------------\n   Init \u2014 attend hamActConfig injecte par wp_footer\n---------------------------------------------------------------- *\/\n$(document).ready(function() {\n  bindEvents(); \/* bind d'abord pour que les clics fonctionnent *\/\n  var tries = 0;\n  var waitCfg = setInterval(function() {\n    tries++;\n    var cfg = window.hamActConfig;\n    if (cfg && cfg.nonce) {\n      clearInterval(waitCfg);\n      AJAX    = cfg.ajaxUrl    || AJAX;\n      NONCE   = cfg.nonce;\n      CAN_ADD = !!cfg.canAddActivation;\n      if (CAN_ADD) $('#ha-btn-new').show();\n      loadActivations();\n    } else if (tries > 40) {\n      clearInterval(waitCfg);\n      \/* Dernier recours : charger sans nonce (lecture publique) *\/\n      loadActivations();\n    }\n  }, 100);\n});\n\n\/* ----------------------------------------------------------------\n   Toast\n---------------------------------------------------------------- *\/\nfunction toast(msg, type) {\n  type = type || 'success';\n  var el = $('<div class=\"ha-toast ha-toast-' + type + '\">' + msg + '<\/div>').appendTo('body');\n  setTimeout(function() { el.animate({opacity:0}, 300, function(){el.remove();}); }, 3800);\n}\n\n\/* ----------------------------------------------------------------\n   Drapeaux depuis QTH Locator (reverse geocoding, cache)\n---------------------------------------------------------------- *\/\nvar _flagCache = {};\n\nfunction locatorToLatLng(loc) {\n  if (!loc) return null;\n  loc = loc.toUpperCase().trim();\n  if (loc.length < 4) return null;\n  var lng = (loc.charCodeAt(0) - 65) * 20 - 180;\n  var lat = (loc.charCodeAt(1) - 65) * 10 - 90;\n  if (isNaN(parseInt(loc[2])) || isNaN(parseInt(loc[3]))) return null;\n  lng += parseInt(loc[2]) * 2;\n  lat += parseInt(loc[3]);\n  if (loc.length >= 6) {\n    lng += (loc.charCodeAt(4) - 65) * (5\/60) + (2.5\/60);\n    lat += (loc.charCodeAt(5) - 65) * (2.5\/60) + (1.25\/60);\n  } else { lng += 1; lat += 0.5; }\n  return [lat, lng];\n}\n\nfunction fetchCountryCode(lat, lng) {\n  return new Promise(function(resolve) {\n    fetch('https:\/\/api.bigdatacloud.net\/data\/reverse-geocode-client?latitude=' + lat + '&longitude=' + lng + '&localityLanguage=en')\n      .then(function(r) { return r.json(); })\n      .then(function(d) { resolve(d.countryCode ? d.countryCode.toLowerCase() : null); })\n      .catch(function() { resolve(null); });\n  });\n}\n\nfunction getFlag(locator) {\n  return new Promise(function(resolve) {\n    if (!locator) { resolve(null); return; }\n    var key = locator.toUpperCase().trim();\n    if (key in _flagCache) { resolve(_flagCache[key]); return; }\n    var ll = locatorToLatLng(key);\n    if (!ll) { _flagCache[key] = null; resolve(null); return; }\n    fetchCountryCode(ll[0], ll[1]).then(function(code) {\n      _flagCache[key] = code;\n      resolve(code);\n    });\n  });\n}\n\nfunction flagImg(code) {\n  if (!code) return '';\n  return '<img decoding=\"async\" class=\"ha-flag\" src=\"https:\/\/flagcdn.com\/16x12\/' + code + '.png\" alt=\"' + code + '\" onerror=\"this.style.display=\\'none\\'\">';\n}\n\n\/* ----------------------------------------------------------------\n   Formatage\n---------------------------------------------------------------- *\/\nfunction formatDate(d) {\n  if (!d) return '';\n  if (d.indexOf('-') !== -1) { var p = d.split('-'); return p[2]+'\/'+p[1]+'\/'+p[0]; }\n  return d;\n}\n\nfunction statusLabel(s) {\n  var map = {planned:'Planifiee', active:'En cours', completed:'Terminee'};\n  var cls = {planned:'ha-badge-planned', active:'ha-badge-active', completed:'ha-badge-completed'};\n  return '<span class=\"ha-badge ' + (cls[s]||'') + '\">' + (map[s]||s) + '<\/span>';\n}\n\n\/* ----------------------------------------------------------------\n   Chargement de la liste\n---------------------------------------------------------------- *\/\nfunction loadActivations() {\n  $('#ha-tbody').html('<tr><td colspan=\"7\"><div class=\"ha-loading\"><div class=\"ha-spinner\"><\/div> Chargement...<\/div><\/td><\/tr>');\n  $('#ha-pagination').empty();\n  $.ajax({\n    url: AJAX,\n    method: 'GET',\n    data: { action:'ham_get_activations', nonce:NONCE, paged:currentPage, program:currentProgram },\n    success: function(r) {\n      if (!r.success) { showError(); return; }\n      renderList(r.data);\n    },\n    error: function() { showError(); }\n  });\n}\n\nfunction showError() {\n  $('#ha-tbody').html('<tr><td colspan=\"7\"><div class=\"ha-empty\">&#9888;&#65039; Erreur de chargement.<\/div><\/td><\/tr>');\n}\n\nfunction renderList(data) {\n  var acts = data.activations;\n  if (!acts || !acts.length) {\n    $('#ha-tbody').html('<tr><td colspan=\"7\"><div class=\"ha-empty\">&#128230; Aucune activation pour ce filtre.<\/div><\/td><\/tr>');\n    return;\n  }\n  var rows = '';\n  acts.forEach(function(a) {\n    var ref = a.reference ? ' <span style=\"color:var(--ha-muted);font-size:.78rem\">' + a.reference + '<\/span>' : '';\n    var dateStr = formatDate(a.date) + (a.date_end && a.date_end !== a.date ? ' &rarr; ' + formatDate(a.date_end) : '');\n    rows += '<tr data-id=\"' + a.id + '\">'\n      + '<td><strong>' + (a.callsign || '&mdash;') + '<\/strong><\/td>'\n      + '<td><span class=\"ha-program-tag\">' + (a.program||'') + '<\/span>' + ref + '<\/td>'\n      + '<td>' + (a.location_name || '&mdash;') + '<\/td>'\n      + '<td style=\"white-space:nowrap\">' + dateStr + '<\/td>'\n      + '<td style=\"color:var(--ha-muted);font-size:.78rem\">' + (a.modes || '&mdash;') + '<\/td>'\n      + '<td>' + (a.qso_count || '0') + '<\/td>'\n      + '<td>' + statusLabel(a.status) + '<\/td>'\n      + '<\/tr>';\n  });\n  $('#ha-tbody').html(rows);\n  renderPagination(data.total, data.pages);\n}\n\nfunction renderPagination(total, pages) {\n  if (pages <= 1) return;\n  var html = '<button class=\"ha-page-btn\" id=\"ha-pg-prev\" ' + (currentPage===1?'disabled':'') + '>&laquo;<\/button>';\n  var start = Math.max(1, currentPage-2), end = Math.min(pages, currentPage+2);\n  for (var i = start; i <= end; i++) {\n    html += '<button class=\"ha-page-btn' + (i===currentPage?' active':'') + '\" data-page=\"' + i + '\">' + i + '<\/button>';\n  }\n  html += '<button class=\"ha-page-btn\" id=\"ha-pg-next\" ' + (currentPage===pages?'disabled':'') + '>&raquo;<\/button>';\n  html += '<span style=\"font-size:.75rem;color:var(--ha-muted);margin-left:6px\">' + total + ' activation' + (total>1?'s':'') + '<\/span>';\n  $('#ha-pagination').html(html);\n}\n\n\/* ----------------------------------------------------------------\n   Evenements principaux\n---------------------------------------------------------------- *\/\nfunction bindEvents() {\n\n  \/* Filtres *\/\n  $(document).on('click', '.ha-filter-btn', function() {\n    $('.ha-filter-btn').removeClass('active');\n    $(this).addClass('active');\n    currentProgram = $(this).data('program');\n    currentPage = 1;\n    loadActivations();\n  });\n\n  \/* Pagination *\/\n  $(document).on('click', '.ha-page-btn[data-page]', function() {\n    currentPage = parseInt($(this).data('page'));\n    loadActivations();\n  });\n  $(document).on('click', '#ha-pg-prev', function() { if (currentPage > 1) { currentPage--; loadActivations(); } });\n  $(document).on('click', '#ha-pg-next', function() { currentPage++; loadActivations(); });\n\n  \/* Clic ligne *\/\n  $(document).on('click', '#ha-tbody tr[data-id]', function() {\n    openDetail(parseInt($(this).data('id')));\n  });\n\n  \/* Modals *\/\n  $(document).on('click', '[data-close]', function() { closeModal($(this).data('close')); });\n  $(document).on('click', '.ha-overlay', function(e) {\n    if ($(e.target).hasClass('ha-overlay')) closeModal($(e.target).attr('id'));\n  });\n  $(document).on('keydown', function(e) { if (e.key==='Escape') $('.ha-overlay:not(.hidden)').each(function(){ closeModal($(this).attr('id')); }); });\n\n  \/* Bouton nouvelle activation *\/\n  $('#ha-btn-new').on('click', function() {\n    if (!CAN_ADD) { toast('Acces refuse', 'error'); return; }\n    resetForm();\n    openModal('ha-overlay-form');\n  });\n\n  \/* Mode chips *\/\n  $(document).on('change', '.ha-mode-chip input', function() {\n    $(this).closest('.ha-mode-chip').toggleClass('checked', this.checked);\n  });\n\n  \/* Recherche membres *\/\n  $('#ha-f-member-search').on('input', function() {\n    clearTimeout(memberSearchTimer);\n    var q = $(this).val().trim();\n    if (q.length < 2) { $('#ha-member-results').addClass('hidden').empty(); return; }\n    memberSearchTimer = setTimeout(function() {\n      $.ajax({\n        url: AJAX, method:'GET',\n        data: { action:'ham_search_members', nonce:NONCE, q:q },\n        success: function(r) {\n          if (!r.success || !r.data.length) {\n            $('#ha-member-results').html('<div class=\"ha-member-result-item\" style=\"color:var(--ha-muted)\">Aucun resultat<\/div>').removeClass('hidden');\n            return;\n          }\n          var html = '';\n          r.data.forEach(function(u) {\n            if (selectedMembers.find(function(m){return m.id===u.id;})) return;\n            html += '<div class=\"ha-member-result-item\" data-id=\"'+u.id+'\" data-cs=\"'+u.callsign+'\" data-country=\"'+u.country+'\" data-locator=\"'+u.locator+'\">'\n              + '<span class=\"cs\">'+u.callsign+'<\/span>'\n              + (u.locator ? '<span class=\"loc\">'+u.locator+'<\/span>' : '')\n              + '<\/div>';\n          });\n          if (!html) html = '<div class=\"ha-member-result-item\" style=\"color:var(--ha-muted)\">Deja ajoute<\/div>';\n          $('#ha-member-results').html(html).removeClass('hidden');\n        }\n      });\n    }, 300);\n  });\n\n  $(document).on('click', function(e) {\n    if (!$(e.target).closest('.ha-member-search').length) $('#ha-member-results').addClass('hidden');\n  });\n\n  $(document).on('click', '.ha-member-result-item[data-id]', function() {\n    addMember({\n      id:      parseInt($(this).data('id')),\n      callsign:$(this).data('cs'),\n      country: $(this).data('country'),\n      locator: $(this).data('locator'),\n      locatorOverride: ''\n    });\n    $('#ha-f-member-search').val('');\n    $('#ha-member-results').addClass('hidden');\n  });\n\n  $(document).on('click', '.ha-member-remove', function() {\n    var uid = parseInt($(this).data('uid'));\n    selectedMembers = selectedMembers.filter(function(m){return m.id!==uid;});\n    $(this).closest('.ha-member-row').remove();\n  });\n\n  \/* Sauvegarder *\/\n  $('#ha-btn-save').on('click', saveActivation);\n\n  \/* Bouton modifier dans le detail *\/\n  $('#ha-btn-edit-activation').on('click', function() {\n    if (!CAN_ADD || !currentDetail) return;\n    openEditForm(currentDetail);\n  });\n\n  \/* Toggle carte detail *\/\n  $('#ha-map-btn-all').on('click', function() {\n    mapMode = 'all';\n    $('#ha-map-btn-all').addClass('active');\n    $('#ha-map-btn-solo').removeClass('active');\n    if (currentDetail) renderDetailMap(currentDetail);\n  });\n  $('#ha-map-btn-solo').on('click', function() {\n    mapMode = 'solo';\n    $('#ha-map-btn-solo').addClass('active');\n    $('#ha-map-btn-all').removeClass('active');\n    if (currentDetail) renderDetailMap(currentDetail);\n  });\n}\n\n\/* ----------------------------------------------------------------\n   Modals\n---------------------------------------------------------------- *\/\nfunction openModal(id) {\n  $('#'+id).removeClass('hidden');\n  $('body').css('overflow','hidden');\n}\nfunction closeModal(id) {\n  $('#'+id).addClass('hidden');\n  $('body').css('overflow','');\n}\n\n\/* ----------------------------------------------------------------\n   Formulaire - reset\n---------------------------------------------------------------- *\/\nfunction resetForm() {\n  editId = null;\n  $('#ha-form-title').html('&#128230; Nouvelle activation');\n  $('#ha-btn-save-label').text('Enregistrer');\n  $('#ha-f-callsign,#ha-f-reference,#ha-f-title,#ha-f-date-start,#ha-f-date-end,#ha-f-location,#ha-f-locator,#ha-f-qso-count,#ha-f-notes,#ha-f-member-search').val('');\n  $('#ha-f-program').val('');\n  $('#ha-f-status').val('planned');\n  $('.ha-mode-chip').removeClass('checked').find('input').prop('checked', false);\n  selectedMembers = [];\n  $('#ha-members-list').empty();\n}\n\n\/* ----------------------------------------------------------------\n   Ajouter un membre au formulaire\n---------------------------------------------------------------- *\/\nfunction addMember(m) {\n  selectedMembers.push(m);\n  var row = '<div class=\"ha-member-row\" data-uid=\"'+m.id+'\">'\n    + '<span class=\"cs\">'+m.callsign+'<\/span>'\n    + '<input type=\"text\" placeholder=\"QTH Locator (ex: JN03HA)\" value=\"'+m.locatorOverride+'\" data-uid=\"'+m.id+'\" class=\"ha-member-locator-input\" maxlength=\"8\" style=\"text-transform:uppercase\">'\n    + '<button class=\"ha-member-remove\" data-uid=\"'+m.id+'\" title=\"Retirer\">&#215;<\/button>'\n    + '<\/div>';\n  $('#ha-members-list').append(row);\n}\n\n$(document).on('input', '.ha-member-locator-input', function() {\n  var uid = parseInt($(this).data('uid'));\n  var val = $(this).val().toUpperCase();\n  $(this).val(val);\n  var m = selectedMembers.find(function(x){return x.id===uid;});\n  if (m) m.locatorOverride = val;\n});\n\n\/* ----------------------------------------------------------------\n   Sauvegarder une activation\n---------------------------------------------------------------- *\/\n\/* ----------------------------------------------------------------\n   Pre-remplir le formulaire pour edition\n---------------------------------------------------------------- *\/\nfunction openEditForm(d) {\n  editId = d.id;\n  $('#ha-form-title').text('Modifier activation');\n  $('#ha-btn-save-label').text('Mettre a jour');\n\n  \/* Champs simples *\/\n  $('#ha-f-callsign').val(d.callsign || '');\n  $('#ha-f-program').val(d.program  || '');\n  $('#ha-f-reference').val(d.reference || '');\n  $('#ha-f-title').val(d.title || '');\n  $('#ha-f-date-start').val(d.date_start || '');\n  $('#ha-f-date-end').val(d.date_end || '');\n  $('#ha-f-location').val(d.location_name || '');\n  $('#ha-f-locator').val(d.qth_locator || '');\n  $('#ha-f-qso-count').val(d.qso_count || 0);\n  $('#ha-f-notes').val(d.notes || '');\n  $('#ha-f-status').val(d.status || 'planned');\n\n  \/* Modes *\/\n  var modes = Array.isArray(d.modes) ? d.modes : [];\n  $('.ha-mode-chip').each(function() {\n    var val = $(this).find('input').val();\n    var checked = modes.indexOf(val) !== -1;\n    $(this).find('input').prop('checked', checked);\n    $(this).toggleClass('checked', checked);\n  });\n\n  \/* Membres *\/\n  selectedMembers = [];\n  $('#ha-members-list').empty();\n  var members = d.qso_members || [];\n  members.forEach(function(m) {\n    addMember({\n      id:              m.id,\n      callsign:        m.callsign,\n      country:         m.country || '',\n      locator:         m.locator || '',\n      locatorOverride: m.locator || ''\n    });\n  });\n\n  closeModal('ha-overlay-detail');\n  openModal('ha-overlay-form');\n}\n\nfunction saveActivation() {\n  if (!CAN_ADD) { toast('Acces refuse', 'error'); return; }\n  var callsign = $('#ha-f-callsign').val().trim().toUpperCase();\n  var program  = $('#ha-f-program').val();\n  var dateStart= $('#ha-f-date-start').val();\n  if (!callsign || !program || !dateStart) {\n    toast('Indicatif, programme et date de debut obligatoires', 'error'); return;\n  }\n  var modes = [];\n  $('.ha-mode-chip input:checked').each(function(){modes.push(this.value);});\n  var memberIds = selectedMembers.map(function(m){return m.id;});\n  var memberLocs= selectedMembers.map(function(m){return m.locatorOverride||'';});\n\n  var btn = $('#ha-btn-save').text('Enregistrement...').prop('disabled',true);\n  \/* Construire le FormData manuellement pour envoyer\n     les tableaux correctement sans perte d'elements *\/\n  var fd = new FormData();\n  fd.append('action',        editId ? 'ham_update_activation' : 'ham_save_activation');\n  if (editId) fd.append('post_id', editId);\n  fd.append('nonce',         NONCE);\n  fd.append('callsign',      callsign);\n  fd.append('program',       program);\n  fd.append('reference',     $('#ha-f-reference').val().trim().toUpperCase());\n  fd.append('title',         $('#ha-f-title').val().trim());\n  fd.append('date_start',    dateStart);\n  fd.append('date_end',      $('#ha-f-date-end').val());\n  fd.append('location_name', $('#ha-f-location').val().trim());\n  fd.append('qth_locator',   $('#ha-f-locator').val().trim().toUpperCase());\n  fd.append('qso_count',     parseInt($('#ha-f-qso-count').val()||0));\n  fd.append('notes',         $('#ha-f-notes').val().trim());\n  fd.append('status',        $('#ha-f-status').val());\n  \/* Tableaux : envoyer chaque element individuellement *\/\n  modes.forEach(function(m)    { fd.append('modes[]', m); });\n  memberIds.forEach(function(id, i) {\n    fd.append('qso_members[]', id);\n    fd.append('qso_member_locators[]', memberLocs[i] || '');\n  });\n\n  $.ajax({\n    url: AJAX, method:'POST',\n    data: fd,\n    processData: false,\n    contentType: false,\n    success: function(r) {\n      btn.text('Enregistrer').prop('disabled',false);\n      if (r.success) {\n        toast(editId ? 'Activation mise a jour !' : 'Activation enregistree !');\n        editId = null;\n        closeModal('ha-overlay-form');\n        currentPage = 1;\n        loadActivations();\n      } else {\n        toast(r.data || 'Erreur', 'error');\n      }\n    },\n    error: function() {\n      btn.text('Enregistrer').prop('disabled',false);\n      toast('Erreur reseau', 'error');\n    }\n  });\n}\n\n\/* ----------------------------------------------------------------\n   Detail activation\n---------------------------------------------------------------- *\/\nfunction openDetail(id) {\n  $('#ha-det-title').text('Chargement...');\n  $('#ha-det-info,#ha-det-members,#ha-det-notes').empty();\n  $('#ha-det-members-section,#ha-det-notes-section').hide();\n  openModal('ha-overlay-detail');\n  mapMode = 'all';\n  $('#ha-map-btn-all').addClass('active');\n  $('#ha-map-btn-solo').removeClass('active');\n\n  $.ajax({\n    url: AJAX, method:'GET',\n    data: { action:'ham_get_activation_detail', nonce:NONCE, id:id },\n    success: function(r) {\n      if (!r.success) { toast('Activation introuvable', 'error'); closeModal('ha-overlay-detail'); return; }\n      currentDetail = r.data;\n      renderDetail(r.data);\n    }\n  });\n}\n\nfunction renderDetail(d) {\n  $('#ha-det-title').html(\n    (d.callsign||'') + ' &mdash; ' +\n    '<span class=\"ha-program-tag\">'+d.program+'<\/span>' +\n    (d.reference ? ' <span style=\"color:var(--ha-muted)\">'+d.reference+'<\/span>' : '')\n  );\n\n  var dateStr = formatDate(d.date_start) + (d.date_end && d.date_end !== d.date_start ? ' &rarr; ' + formatDate(d.date_end) : '');\n  var modes   = Array.isArray(d.modes) && d.modes.length ? d.modes.join(', ') : '&mdash;';\n\n  $('#ha-det-info').html(\n    '<div><dt>Indicatif<\/dt><dd>'+(d.callsign||'&mdash;')+'<\/dd><\/div>'\n    +'<div><dt>Programme<\/dt><dd><span class=\"ha-program-tag\">'+d.program+'<\/span>'+(d.reference?' '+d.reference:'')+'<\/dd><\/div>'\n    +'<div><dt>Lieu<\/dt><dd>'+(d.location_name||'&mdash;')+'<\/dd><\/div>'\n    +'<div><dt>QTH Locator<\/dt><dd>'+(d.qth_locator||'&mdash;')+'<\/dd><\/div>'\n    +'<div><dt>Date<\/dt><dd>'+dateStr+'<\/dd><\/div>'\n    +'<div><dt>Statut<\/dt><dd>'+statusLabel(d.status)+'<\/dd><\/div>'\n    +'<div><dt>Modes<\/dt><dd>'+modes+'<\/dd><\/div>'\n    +'<div><dt>QSO<\/dt><dd>'+(d.qso_count||'0')+'<\/dd><\/div>'\n    +'<div><dt>Publiee le<\/dt><dd>'+(d.created_at||'&mdash;')+'<\/dd><\/div>'\n  );\n\n  \/* Membres *\/\n  var members = d.qso_members || [];\n  if (members.length) {\n    $('#ha-det-members-section').show();\n    var mHtml = '';\n    members.forEach(function(m) {\n      var code = m.locator ? _flagCache[m.locator.toUpperCase()] : null;\n      var flag = code ? flagImg(code) : '';\n      mHtml += '<div class=\"ha-qso-member-row\">'\n        + flag\n        + '<span class=\"cs\">'+m.callsign+'<\/span>'\n        + (m.locator ? '<span class=\"loc-badge\">'+m.locator+'<\/span>' : '')\n        + '<\/div>';\n    });\n    $('#ha-det-members').html(mHtml);\n  }\n\n  \/* Notes *\/\n  if (d.notes) { $('#ha-det-notes-section').show(); $('#ha-det-notes').text(d.notes); }\n\n  \/* Bouton modifier (admins\/mods seulement) *\/\n  if (CAN_ADD) $('#ha-btn-edit-activation').show();\n  else $('#ha-btn-edit-activation').hide();\n\n  \/* Precharger les flags puis rendu carte *\/\n  var locs = [d.qth_locator].concat(members.map(function(m){return m.locator;})).filter(Boolean);\n  Promise.all(locs.map(function(l){return getFlag(l);})).then(function() {\n    \/* Mettre a jour les drapeaux membres maintenant qu'on a les codes *\/\n    var mHtml2 = '';\n    members.forEach(function(m) {\n      var code = m.locator ? _flagCache[m.locator.toUpperCase()] : null;\n      var flag = code ? flagImg(code) : '';\n      mHtml2 += '<div class=\"ha-qso-member-row\">'\n        + flag + ' <span class=\"cs\">'+m.callsign+'<\/span>'\n        + (m.locator ? '<span class=\"loc-badge\">'+m.locator+'<\/span>' : '')\n        + '<\/div>';\n    });\n    if (members.length) $('#ha-det-members').html(mHtml2);\n    renderDetailMap(d);\n  });\n}\n\n\/* ----------------------------------------------------------------\n   Carte detail\n---------------------------------------------------------------- *\/\nfunction initDetailMap() {\n  if (detailMap) return;\n  detailMap = L.map('ha-det-map', {center:[20,10], zoom:2});\n  L.tileLayer('https:\/\/{s}.basemaps.cartocdn.com\/dark_all\/{z}\/{x}\/{y}{r}.png', {\n    attribution:'&copy; OpenStreetMap | &copy; CartoDB', maxZoom:18, subdomains:'abcd'\n  }).addTo(detailMap);\n}\n\nfunction clearDetailMap() {\n  detailMapLayers.forEach(function(l){detailMap.removeLayer(l);});\n  detailMapLayers = [];\n}\n\nfunction renderDetailMap(d) {\n  initDetailMap();\n  clearDetailMap();\n\n  var actLL = (d.lat && d.lng) ? [parseFloat(d.lat), parseFloat(d.lng)] : (d.qth_locator ? locatorToLatLng(d.qth_locator) : null);\n  if (!actLL) {\n    setTimeout(function(){detailMap.invalidateSize();}, 100);\n    return;\n  }\n\n  var bounds = [];\n\n  \/* Pin activation (toujours visible) *\/\n  var actCode = d.qth_locator ? _flagCache[d.qth_locator.toUpperCase()] : null;\n  var actFlagUrl = actCode ? 'https:\/\/flagcdn.com\/20x15\/'+actCode+'.png' : null;\n  var actIconHtml = actFlagUrl\n    ? '<div style=\"position:relative\"><img decoding=\"async\" src=\"'+actFlagUrl+'\" style=\"width:24px;height:18px;border-radius:2px;box-shadow:0 1px 4px rgba(0,0,0,.6)\" onerror=\"this.parentNode.innerHTML=\\'<div style=&quot;width:12px;height:12px;background:#d29922;border:2px solid #fff;border-radius:50%&quot;><\/div>\\'\"><div style=\"position:absolute;top:-4px;right:-4px;width:8px;height:8px;background:#d29922;border-radius:50%;border:1px solid #fff\"><\/div><\/div>'\n    : '<div style=\"width:14px;height:14px;background:#d29922;border:2px solid #fff;border-radius:50%;box-shadow:0 0 6px rgba(0,0,0,.5)\"><\/div>';\n  var actIcon = L.divIcon({html:actIconHtml, className:'', iconAnchor:[12,9]});\n  var actMarker = L.marker(actLL, {icon:actIcon})\n    .bindPopup('<strong>'+(d.callsign||'')+'<\/strong><br>'+(d.location_name||d.qth_locator||''))\n    .addTo(detailMap);\n  detailMapLayers.push(actMarker);\n  bounds.push(actLL);\n\n  \/* Membres (seulement en mode 'all') *\/\n  if (mapMode === 'all' && d.qso_members && d.qso_members.length) {\n    d.qso_members.forEach(function(m) {\n      if (!m.lat || !m.lng) return;\n      var mLL = [parseFloat(m.lat), parseFloat(m.lng)];\n      \/* Ligne *\/\n      var line = L.polyline([actLL, mLL], {color:'#1f6feb', weight:2, opacity:.7, dashArray:'4,3'}).addTo(detailMap);\n      detailMapLayers.push(line);\n      \/* Pin membre *\/\n      var mCode = m.locator ? _flagCache[m.locator.toUpperCase()] : null;\n      var mFlagUrl = mCode ? 'https:\/\/flagcdn.com\/20x15\/'+mCode+'.png' : null;\n      var mIconHtml = mFlagUrl\n        ? '<img decoding=\"async\" src=\"'+mFlagUrl+'\" style=\"width:20px;height:15px;border-radius:2px;box-shadow:0 1px 4px rgba(0,0,0,.6)\" onerror=\"this.style.display=\\'none\\'\">'\n        : '<div style=\"width:10px;height:10px;background:#3fb950;border:2px solid #fff;border-radius:50%\"><\/div>';\n      var mIcon = L.divIcon({html:mIconHtml, className:'', iconAnchor:[10,8]});\n      var mMarker = L.marker(mLL, {icon:mIcon})\n        .bindPopup('<strong>'+m.callsign+'<\/strong>'+(m.locator?'<br>'+m.locator:''))\n        .addTo(detailMap);\n      detailMapLayers.push(mMarker);\n      bounds.push(mLL);\n    });\n  }\n\n  \/* Ajuster la vue *\/\n  if (bounds.length > 1) {\n    detailMap.fitBounds(L.latLngBounds(bounds).pad(0.2));\n  } else {\n    detailMap.setView(actLL, 8);\n  }\n  setTimeout(function(){detailMap.invalidateSize();}, 100);\n}\n\n\/* Invalidate map quand la modal s'ouvre *\/\n$(document).on('click', '#ha-tbody tr[data-id]', function() {\n  setTimeout(function(){if(detailMap)detailMap.invalidateSize();}, 200);\n});\n\n})(jQuery);\n<\/script>\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>Tous \/DX \/0 \/Indicatif SOTA POTA IOTA WWFF Lighthouse Autre Nouvelle activation Indicatif Programme \/ Ref Lieu Date Modes QSO Statut Chargement&#8230; &#128246; Nouvelle activation &#215; Indicatif * Programme * &mdash; Choisir &mdash;\/DX\/0\/IndicatifSOTAPOTAIOTAWWFFLIGHTHOUSEAutre R\u00e9f\u00e9rence (ex: F\/MC-001) Titre personnalis\u00e9 Date de d\u00e9but * Date de fin Statut Planifi\u00e9eEn coursTermin\u00e9e Nom du lieu QTH Locator Modes USB LSB AM FM FT8 Nombre de QSO Membres du site ayant particip\u00e9 Pour chaque membre, entrez son QTH Locator pour l&#8217;afficher sur la carte de l&#8217;activation. Notes Annuler Enregistrer Activation &#215; Informations Membres participants Notes Tous les membres Activation seule Modifier Fermer<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"class_list":["post-553","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/pages\/553","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/comments?post=553"}],"version-history":[{"count":28,"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/pages\/553\/revisions"}],"predecessor-version":[{"id":659,"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/pages\/553\/revisions\/659"}],"wp:attachment":[{"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/media?parent=553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}