{"id":560,"date":"2026-04-23T15:43:38","date_gmt":"2026-04-23T13:43:38","guid":{"rendered":"https:\/\/www.ingilog.com\/sugardelta_prod\/?page_id=560"},"modified":"2026-05-09T17:55:19","modified_gmt":"2026-05-09T15:55:19","slug":"logiciel-sugar-delta","status":"publish","type":"page","link":"https:\/\/www.ingilog.com\/sugardelta_prod\/logiciel-sugar-delta\/","title":{"rendered":"Logiciel Sugar Delta"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"560\" class=\"elementor elementor-560\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c95974b e-con-full e-flex 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=\"c95974b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-bdc574c elementor-widget elementor-widget-html\" data-id=\"bdc574c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!-- ============================================================\n  eQSL \u2013 PAGE D'\u00c9CHANGES v3\n  + Drapeaux pays depuis indicatif callsign\n  + Upload templates dans les modals\n  + T\u00e9l\u00e9chargement eQSL \u00e9changes\n  Requiert : eqslVars, jQuery, WPCode PHP v3, Leaflet CDN\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  --eq-bg:#0d1117;--eq-surface:#161b22;--eq-border:#30363d;\n  --eq-accent:#238636;--eq-accent2:#1f6feb;--eq-danger:#da3633;\n  --eq-text:#e6edf3;--eq-muted:#8b949e;--eq-radius:8px;\n  --eq-shadow:0 4px 24px rgba(0,0,0,.45);\n}\n#eqsl-exchanges *{box-sizing:border-box;margin:0;padding:0;}\n#eqsl-exchanges{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:var(--eq-bg);color:var(--eq-text);border-radius:var(--eq-radius);}\n#eqx-map-wrap{border-radius:var(--eq-radius) var(--eq-radius) 0 0;overflow:hidden;border:1px solid var(--eq-border);border-bottom:none;position:relative;}\n#eqx-map{height:630px;background:#0d1117;}\n#eqx-map-wrap.eqx-fullscreen{position:fixed;inset:0;z-index:99998;border-radius:0;border:none;}\n#eqx-map-wrap.eqx-fullscreen #eqx-map{height:100vh;}\n#eqx-map-legend{position:absolute;top:10px;right:10px;z-index:1000;background:rgba(22,27,34,.88);border:1px solid var(--eq-border);border-radius:6px;padding:8px 12px;font-size:.75rem;color:var(--eq-muted);pointer-events:none;}\n#eqx-fullscreen-btn{position:absolute;top:10px;left:10px;z-index:1000;background:rgba(22,27,34,.88);border:1px solid var(--eq-border);border-radius:6px;padding:6px 10px;cursor:pointer;color:var(--eq-muted);font-size:.75rem;display:flex;align-items:center;gap:6px;transition:color .15s,background .15s;}\n#eqx-fullscreen-btn:hover{color:var(--eq-text);background:rgba(22,27,34,1);}\n#eqx-panels{display:grid;grid-template-columns:1fr 1fr;border:1px solid var(--eq-border);border-radius:0 0 var(--eq-radius) var(--eq-radius);overflow:hidden;}\n.eqx-panel{padding:20px;min-height:300px;}\n.eqx-panel:first-child{border-right:1px solid var(--eq-border);}\n.eqx-panel-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;flex-wrap:wrap;gap:10px;}\n.eqx-panel-header h3{font-size:.98rem;font-weight:600;}\n.eqx-date-nav{display:flex;align-items:center;gap:6px;background:var(--eq-surface);border:1px solid var(--eq-border);border-radius:6px;padding:2px 4px;}\n.eqx-nav-btn{background:none;border:none;color:var(--eq-muted);cursor:pointer;font-size:1rem;padding:3px 7px;border-radius:4px;transition:color .15s,background .15s;}\n.eqx-nav-btn:hover{color:var(--eq-text);background:rgba(255,255,255,.06);}\n#eqx-date-picker{background:none;border:none;color:var(--eq-text);font-size:.82rem;cursor:pointer;outline:none;text-align:center;width:106px;}\n#eqx-date-picker::-webkit-calendar-picker-indicator{filter:invert(.6);cursor:pointer;}\n.eqx-filters{display:flex;gap:6px;margin-bottom:12px;flex-wrap:wrap;}\n.eqx-filter-btn{padding:5px 12px;border-radius:20px;border:1px solid var(--eq-border);background:transparent;color:var(--eq-muted);font-size:.78rem;cursor:pointer;transition:all .15s;}\n.eqx-filter-btn.active{background:var(--eq-accent2);color:#fff;border-color:var(--eq-accent2);}\n.eqx-btn-create{display:inline-flex;align-items:center;gap:6px;padding:7px 14px;border-radius:var(--eq-radius);background:var(--eq-accent);color:#fff;border:none;cursor:pointer;font-size:.84rem;font-weight:600;transition:filter .15s;}\n.eqx-btn-create:hover{filter:brightness(1.1);}\n.eqx-table-wrap{overflow-x:auto;border-radius:6px;border:1px solid var(--eq-border);margin-top:4px;}\n.eqx-table{width:100%;border-collapse:collapse;font-size:.82rem;}\n.eqx-table th{background:var(--eq-surface);color:var(--eq-muted);font-weight:500;text-transform:uppercase;font-size:.7rem;letter-spacing:.05em;padding:8px 12px;text-align:left;border-bottom:1px solid var(--eq-border);}\n.eqx-table td{padding:9px 12px;border-bottom:1px solid var(--eq-border);vertical-align:middle;}\n.eqx-table tr:last-child td{border-bottom:none;}\n.eqx-table tbody tr{cursor:pointer;transition:background .12s;}\n.eqx-table tbody tr:hover{background:rgba(255,255,255,.04);}\n.eqbadge{display:inline-block;padding:2px 8px;border-radius:20px;font-size:.7rem;font-weight:600;}\n.eqbadge-pending{background:rgba(210,153,34,.2);color:#d29922;border:1px solid rgba(210,153,34,.4);}\n.eqbadge-rejected{background:rgba(218,54,51,.2);color:#f85149;border:1px solid rgba(218,54,51,.4);}\n.eqbadge-completed{background:rgba(35,134,54,.2);color:#3fb950;border:1px solid rgba(35,134,54,.4);}\n.eqbadge-incoming{background:rgba(31,111,235,.2);color:#58a6ff;border:1px solid rgba(31,111,235,.4);}\n.eqx-dl-btn{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;border-radius:4px;border:1px solid var(--eq-border);background:transparent;color:var(--eq-text);font-size:.72rem;cursor:pointer;transition:border-color .15s,background .15s;white-space:nowrap;margin:1px;}\n.eqx-dl-btn:hover{border-color:var(--eq-accent2);background:rgba(31,111,235,.1);}\n.eqx-dl-icon{padding:5px 8px;border-radius:6px;}\n.eqx-loading{display:flex;align-items:center;justify-content:center;gap:10px;padding:32px;color:var(--eq-muted);}\n.eqx-empty{text-align:center;padding:32px;color:var(--eq-muted);font-size:.88rem;}\n.eqx-spinner{width:18px;height:18px;border:2px solid var(--eq-border);border-top-color:var(--eq-accent2);border-radius:50%;animation:eqxSpin .7s linear infinite;}\n@keyframes eqxSpin{to{transform:rotate(360deg);}}\n.eqx-toast{position:fixed;bottom:26px;right:26px;z-index:99999;max-width:320px;padding:12px 18px;border-radius:var(--eq-radius);font-size:.85rem;font-weight:500;box-shadow:var(--eq-shadow);animation:eqxSlide .3s ease;}\n.eqx-toast-success{background:#238636;color:#fff;}\n.eqx-toast-error{background:#da3633;color:#fff;}\n@keyframes eqxSlide{from{transform:translateY(16px);opacity:0;}}\n\/* Drapeau *\/\n.eqx-flag{width:16px;height:12px;vertical-align:middle;margin-right:5px;border-radius:2px;object-fit:cover;}\n\/* Modals *\/\n.eqx-overlay{position:fixed;inset:0;background:rgba(0,0,0,.78);backdrop-filter:blur(3px);z-index:9999;display:flex;align-items:center;justify-content:center;padding:16px;overflow-y:auto;}\n.eqx-overlay.hidden{display:none;}\n.eqx-modal{background:var(--eq-surface);border:1px solid var(--eq-border);border-radius:12px;width:100%;max-width:640px;box-shadow:var(--eq-shadow);display:flex;flex-direction:column;max-height:92vh;overflow-y:auto;}\n.eqx-modal-lg{max-width:820px;}\n.eqx-modal-head{display:flex;align-items:center;justify-content:space-between;padding:16px 22px;border-bottom:1px solid var(--eq-border);position:sticky;top:0;background:var(--eq-surface);z-index:1;}\n.eqx-modal-head h3{font-size:1rem;font-weight:600;}\n.eqx-modal-close{background:none;border:none;color:var(--eq-muted);cursor:pointer;font-size:1.4rem;line-height:1;padding:2px 6px;border-radius:4px;}\n.eqx-modal-close:hover{color:var(--eq-text);}\n.eqx-modal-body{padding:22px;}\n.eqx-modal-foot{padding:14px 22px;border-top:1px solid var(--eq-border);display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap;position:sticky;bottom:0;background:var(--eq-surface);}\n\/* Formulaire *\/\n.eqx-form{display:flex;flex-direction:column;gap:14px;}\n.eqx-row{display:grid;gap:12px;}\n.eqx-row.cols-2{grid-template-columns:1fr 1fr;}\n.eqx-row.cols-3{grid-template-columns:1fr 1fr 1fr;}\n.eqx-field{display:flex;flex-direction:column;gap:5px;}\n.eqx-field label{font-size:.72rem;font-weight:600;color:var(--eq-muted);text-transform:uppercase;letter-spacing:.05em;}\n.eqx-field input,.eqx-field select,.eqx-field textarea{background:#0d1117;border:1px solid var(--eq-border);border-radius:6px;color:var(--eq-text);padding:9px 12px;font-size:.88rem;font-family:inherit;outline:none;width:100%;transition:border-color .15s;}\n.eqx-field input:focus,.eqx-field select:focus,.eqx-field textarea:focus{border-color:var(--eq-accent2);}\n.eqx-field input::placeholder,.eqx-field textarea::placeholder{color:var(--eq-muted);}\n.eqx-field textarea{resize:vertical;min-height:56px;}\n\/* Recherche user *\/\n.eqx-user-search-wrap{position:relative;}\n.eqx-user-results{position:absolute;top:100%;left:0;right:0;z-index:100;background:var(--eq-surface);border:1px solid var(--eq-border);border-top:none;border-radius:0 0 6px 6px;max-height:180px;overflow-y:auto;}\n.eqx-user-result-item{padding:9px 12px;cursor:pointer;font-size:.88rem;transition:background .12s;display:flex;align-items:center;gap:8px;}\n.eqx-user-result-item:hover{background:rgba(255,255,255,.07);}\n.eqx-user-result-item .badge{font-size:.7rem;color:var(--eq-muted);}\n.eqx-selected-user{background:rgba(31,111,235,.15);border:1px solid rgba(31,111,235,.4);border-radius:6px;padding:8px 12px;font-size:.88rem;display:flex;align-items:center;justify-content:space-between;color:#ffffff;font-weight:600;}\n.eqx-selected-user button{background:none;border:none;color:var(--eq-muted);cursor:pointer;font-size:1rem;}\n\/* Onglets template *\/\n.eqx-tpl-tabs{display:flex;margin-bottom:10px;border-radius:6px;overflow:hidden;border:1px solid var(--eq-border);}\n.eqx-tpl-tab{flex:1;padding:8px 12px;background:transparent;border:none;color:var(--eq-muted);font-size:.8rem;font-weight:500;cursor:pointer;transition:background .15s,color .15s;text-align:center;}\n.eqx-tpl-tab:not(:last-child){border-right:1px solid var(--eq-border);}\n.eqx-tpl-tab.active{background:var(--eq-accent2);color:#fff;}\n.eqx-tpl-tab:hover:not(.active){background:rgba(255,255,255,.05);color:var(--eq-text);}\n\/* Grille templates *\/\n.eqx-tpl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(90px,1fr));gap:8px;margin-top:4px;}\n.eqx-tpl-card{border:2px solid var(--eq-border);border-radius:6px;overflow:hidden;cursor:pointer;transition:border-color .15s;aspect-ratio:4\/3;position:relative;}\n.eqx-tpl-card img{width:100%;height:100%;object-fit:cover;}\n.eqx-tpl-card.selected{border-color:var(--eq-accent2);}\n.eqx-tpl-card .check{position:absolute;top:4px;right:4px;background:var(--eq-accent2);color:#fff;border-radius:50%;width:18px;height:18px;display:none;align-items:center;justify-content:center;font-size:.65rem;}\n.eqx-tpl-card.selected .check{display:flex;}\n\/* Upload zone *\/\n.eqx-upload-zone{border:2px dashed var(--eq-border);border-radius:var(--eq-radius);padding:20px;text-align:center;cursor:pointer;transition:border-color .15s,background .15s;margin-bottom:10px;}\n.eqx-upload-zone:hover{border-color:var(--eq-accent2);background:rgba(31,111,235,.04);}\n.eqx-upload-zone input[type=file]{display:none;}\n.eqx-upload-selected{color:var(--eq-text);font-size:.82rem;font-weight:500;margin-top:6px;display:none;}\n\/* Boutons *\/\n.eqx-btn{display:inline-flex;align-items:center;gap:6px;padding:9px 18px;border-radius:var(--eq-radius);border:none;cursor:pointer;font-size:.88rem;font-weight:500;transition:filter .15s;}\n.eqx-btn-primary{background:var(--eq-accent);color:#fff;}\n.eqx-btn-blue{background:var(--eq-accent2);color:#fff;}\n.eqx-btn-danger{background:var(--eq-danger);color:#fff;}\n.eqx-btn-ghost{background:transparent;color:var(--eq-text);border:1px solid var(--eq-border);}\n.eqx-btn-sm{padding:5px 12px;font-size:.78rem;}\n.eqx-btn:hover{filter:brightness(1.1);}\n.eqx-recap{background:#0d1117;border:1px solid var(--eq-border);border-radius:var(--eq-radius);padding:14px;font-size:.85rem;margin-bottom:14px;}\n.eqx-recap dl{display:grid;grid-template-columns:1fr 1fr;gap:8px 16px;}\n.eqx-recap dt{color:var(--eq-muted);font-size:.73rem;text-transform:uppercase;margin-bottom:2px;}\n.eqx-recap dd{font-weight:500;}\n@media(max-width:680px){\n  #eqx-panels{grid-template-columns:1fr;}\n  .eqx-panel:first-child{border-right:none;border-bottom:1px solid var(--eq-border);}\n  .eqx-row.cols-2,.eqx-row.cols-3{grid-template-columns:1fr;}\n}\n<\/style>\n\n<div id=\"eqsl-exchanges\">\n  <div id=\"eqx-map-wrap\">\n    <div id=\"eqx-map\"><\/div>\n    <button id=\"eqx-fullscreen-btn\" title=\"Plein \u00e9cran\">\n      <svg id=\"eqx-fs-icon-expand\" width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path d=\"M8 3H5a2 2 0 00-2 2v3M21 8V5a2 2 0 00-2-2h-3M16 21h3a2 2 0 002-2v-3M3 16v3a2 2 0 002 2h3\"\/><\/svg>\n      <svg id=\"eqx-fs-icon-shrink\" width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" style=\"display:none\"><path d=\"M8 3v3a2 2 0 01-2 2H3M21 8h-3a2 2 0 01-2-2V3M3 16h3a2 2 0 012 2v3M16 21v-3a2 2 0 012-2h3\"\/><\/svg>\n      <span id=\"eqx-fs-label\">Plein \u00e9cran<\/span>\n    <\/button>\n    <div id=\"eqx-map-legend\">\n      <span style=\"display:inline-block;width:10px;height:3px;background:#1f6feb;border-radius:2px;margin-right:5px;vertical-align:middle\"><\/span>Ligne d'\u00e9change\n    <\/div>\n  <\/div>\n  <div id=\"eqx-panels\">\n    <div class=\"eqx-panel\">\n      <div class=\"eqx-panel-header\">\n        <h3>\u26a1 \u00c9changes du jour<\/h3>\n        <div class=\"eqx-date-nav\">\n          <button class=\"eqx-nav-btn\" id=\"eqx-prev-day\">\u25c0<\/button>\n          <input type=\"date\" id=\"eqx-date-picker\">\n          <button class=\"eqx-nav-btn\" id=\"eqx-next-day\">\u25b6<\/button>\n        <\/div>\n      <\/div>\n      <div id=\"eqx-day-list\"><div class=\"eqx-loading\"><div class=\"eqx-spinner\"><\/div> Chargement...<\/div><\/div>\n    <\/div>\n    <div class=\"eqx-panel\">\n      <div class=\"eqx-panel-header\">\n        <h3>\ud83d\udccb \u00c9changes en attente<\/h3>\n        <button class=\"eqx-btn-create\" id=\"eqx-btn-create\" style=\"display:none\">\n          <svg width=\"12\" height=\"12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" viewBox=\"0 0 24 24\"><path d=\"M12 5v14M5 12h14\"\/><\/svg>\n          Cr\u00e9er un \u00e9change\n        <\/button>\n      <\/div>\n      <div class=\"eqx-filters\" id=\"eqx-filters\" style=\"display:none\">\n        <button class=\"eqx-filter-btn active\" data-filter=\"all\">Tous<\/button>\n        <button class=\"eqx-filter-btn\" data-filter=\"mine\">Mes demandes<\/button>\n        <button class=\"eqx-filter-btn\" data-filter=\"incoming\">\u00c0 valider<\/button>\n      <\/div>\n      <div id=\"eqx-pending-list\"><div class=\"eqx-empty\">\ud83d\udd12 Connectez-vous pour voir vos \u00e9changes.<\/div><\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- MODAL 1 \u2014 Cr\u00e9er -->\n<div class=\"eqx-overlay hidden\" id=\"eqx-overlay-create\">\n  <div class=\"eqx-modal eqx-modal-lg\">\n    <div class=\"eqx-modal-head\">\n      <h3>\ud83d\udce1 Nouvel \u00e9change d'eQSL<\/h3>\n      <button class=\"eqx-modal-close\" data-close=\"eqx-overlay-create\">\u00d7<\/button>\n    <\/div>\n    <div class=\"eqx-modal-body\"><div class=\"eqx-form\">\n      <div class=\"eqx-field\">\n        <label>Op\u00e9rateur destinataire *<\/label>\n        <div class=\"eqx-user-search-wrap\">\n          <input type=\"text\" id=\"eqx-user-search\" placeholder=\"Rechercher par nom ou identifiant\u2026\" autocomplete=\"off\">\n          <div class=\"eqx-user-results hidden\" id=\"eqx-user-results\"><\/div>\n        <\/div>\n        <div class=\"eqx-selected-user hidden\" id=\"eqx-selected-user-display\">\n          <span id=\"eqx-selected-user-name\"><\/span>\n          <button id=\"eqx-clear-user\">\u2715<\/button>\n        <\/div>\n        <input type=\"hidden\" id=\"eqx-c-user-b-id\">\n      <\/div>\n      <div>\n        <label style=\"font-size:.72rem;font-weight:600;color:var(--eq-muted);text-transform:uppercase;letter-spacing:.05em;display:block;margin-bottom:8px\">Mon template QSL *<\/label>\n        <div class=\"eqx-tpl-tabs\" id=\"eqx-create-tabs\">\n          <button class=\"eqx-tpl-tab active\" data-panel=\"eqx-tpl-lib-create\">\ud83d\udcc2 Mes templates<\/button>\n          <button class=\"eqx-tpl-tab\" data-panel=\"eqx-tpl-up-create\">\u2b06 Ajouter<\/button>\n        <\/div>\n        <div id=\"eqx-tpl-lib-create\">\n          <div class=\"eqx-tpl-grid\" id=\"eqx-tpl-grid-create\"><div class=\"eqx-loading\"><div class=\"eqx-spinner\"><\/div><\/div><\/div>\n        <\/div>\n        <div id=\"eqx-tpl-up-create\" style=\"display:none\">\n          <input type=\"text\" id=\"eqx-c-tpl-name\" placeholder=\"Nom du template\" style=\"margin-bottom:10px;background:#0d1117;border:1px solid var(--eq-border);border-radius:6px;color:var(--eq-text);padding:9px 12px;font-size:.88rem;width:100%;outline:none\">\n          <div class=\"eqx-upload-zone\" id=\"eqx-c-drop-zone\">\n            <input type=\"file\" id=\"eqx-c-tpl-file\" accept=\"image\/jpeg,image\/png,image\/gif\">\n            <svg width=\"28\" height=\"28\" fill=\"none\" stroke=\"var(--eq-muted)\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\"><path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12\"\/><\/svg>\n            <p style=\"color:var(--eq-muted);font-size:.82rem;margin-top:6px\">Glissez ou <strong style=\"color:var(--eq-accent2)\">cliquez<\/strong> \u2014 JPEG\u00b7PNG\u00b7GIF max 5Mo<\/p>\n            <div class=\"eqx-upload-selected\" id=\"eqx-c-tpl-selected\"><\/div>\n          <\/div>\n          <button class=\"eqx-btn eqx-btn-blue eqx-btn-sm\" id=\"eqx-c-btn-upload\">\u2b06 Uploader ce template<\/button>\n        <\/div>\n        <input type=\"hidden\" id=\"eqx-c-tpl-a\">\n      <\/div>\n      <div class=\"eqx-row cols-3\">\n        <div class=\"eqx-field\"><label>Date QSO *<\/label><input type=\"text\" id=\"eqx-c-date\" placeholder=\"DD\/MM\/YYYY\" maxlength=\"10\"><\/div>\n        <div class=\"eqx-field\"><label>Heure (HH:MM) *<\/label><input type=\"text\" id=\"eqx-c-time\" placeholder=\"14:30\" maxlength=\"5\"><\/div>\n        <div class=\"eqx-field\"><label>Fuseau *<\/label><select id=\"eqx-c-tz\"><option>UTC<\/option><option>UTC+1<\/option><option>UTC+2<\/option><option>UTC-1<\/option><option>UTC-5<\/option><\/select><\/div>\n      <\/div>\n      <div class=\"eqx-row cols-3\">\n        <div class=\"eqx-field\"><label>Fr\u00e9quence MHz *<\/label><input type=\"text\" id=\"eqx-c-freq\" placeholder=\"14.225\"><\/div>\n        <div class=\"eqx-field\"><label>Mode *<\/label><select id=\"eqx-c-mode\"><option>SSB<\/option><option>CW<\/option><option>FT8<\/option><option>FT4<\/option><option>PSK31<\/option><option>RTTY<\/option><option>AM<\/option><option>FM<\/option><option>DMR<\/option><option>C4FM<\/option><option>DSTAR<\/option><option>Autre<\/option><\/select><\/div>\n        <div class=\"eqx-field\"><label>Mon RST *<\/label><input type=\"text\" id=\"eqx-c-report\" placeholder=\"59\"><\/div>\n      <\/div>\n      <div class=\"eqx-row cols-2\">\n        <div class=\"eqx-field\"><label>Mon QTH Locator *<\/label><input type=\"text\" id=\"eqx-c-locator\" placeholder=\"IN97AB\" maxlength=\"10\" style=\"text-transform:uppercase\"><\/div>\n        <div class=\"eqx-field\"><label>Message (facultatif)<\/label><textarea id=\"eqx-c-message\" placeholder=\"73 ! Beau signal\u2026\"><\/textarea><\/div>\n      <\/div>\n    <\/div><\/div>\n    <div class=\"eqx-modal-foot\">\n      <button class=\"eqx-btn eqx-btn-ghost\" data-close=\"eqx-overlay-create\">Annuler<\/button>\n      <button class=\"eqx-btn eqx-btn-primary\" id=\"eqx-btn-submit-create\">\ud83d\udce1 Envoyer la demande<\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- MODAL 2 \u2014 D\u00e9tail -->\n<div class=\"eqx-overlay hidden\" id=\"eqx-overlay-detail\">\n  <div class=\"eqx-modal\">\n    <div class=\"eqx-modal-head\">\n      <h3 id=\"eqx-det-title\">D\u00e9tail \u00e9change<\/h3>\n      <button class=\"eqx-modal-close\" data-close=\"eqx-overlay-detail\">\u00d7<\/button>\n    <\/div>\n    <div class=\"eqx-modal-body\">\n      <div class=\"eqx-recap\" id=\"eqx-det-recap\"><\/div>\n      <div id=\"eqx-det-actions-b\" style=\"display:none\">\n        <p style=\"font-size:.83rem;color:var(--eq-muted);margin-bottom:12px\">Acceptez et renseignez vos informations, ou refusez cet \u00e9change.<\/p>\n        <div style=\"display:flex;gap:8px;flex-wrap:wrap\">\n          <button class=\"eqx-btn eqx-btn-danger\" id=\"eqx-btn-reject\">\u2715 Refuser<\/button>\n          <button class=\"eqx-btn eqx-btn-primary\" id=\"eqx-btn-accept-open\">\u2713 Accepter et compl\u00e9ter<\/button>\n        <\/div>\n      <\/div>\n      <div id=\"eqx-det-rejected\" style=\"display:none;background:rgba(218,54,51,.12);border:1px solid rgba(218,54,51,.4);border-radius:var(--eq-radius);padding:12px;font-size:.85rem;color:#f85149\">\u2715 Cet \u00e9change a \u00e9t\u00e9 refus\u00e9.<\/div>\n      <div id=\"eqx-det-completed\" style=\"display:none\">\n        <p style=\"font-size:.83rem;color:var(--eq-muted);margin-bottom:10px\">\u00c9change confirm\u00e9 \u2014 t\u00e9l\u00e9chargez les eQSL :<\/p>\n        <div style=\"display:flex;gap:8px;flex-wrap:wrap\">\n          <button class=\"eqx-btn eqx-btn-blue\" id=\"eqx-btn-dl-a\">\u2b07 eQSL de <span id=\"eqx-dl-name-a\"><\/span><\/button>\n          <button class=\"eqx-btn eqx-btn-blue\" id=\"eqx-btn-dl-b\">\u2b07 eQSL de <span id=\"eqx-dl-name-b\"><\/span><\/button>\n        <\/div>\n      <\/div>\n    <\/div>\n    <div class=\"eqx-modal-foot\"><button class=\"eqx-btn eqx-btn-ghost\" data-close=\"eqx-overlay-detail\">Fermer<\/button><\/div>\n  <\/div>\n<\/div>\n\n<!-- MODAL 3 \u2014 Accepter -->\n<div class=\"eqx-overlay hidden\" id=\"eqx-overlay-accept\">\n  <div class=\"eqx-modal eqx-modal-lg\">\n    <div class=\"eqx-modal-head\">\n      <h3>\u2713 Compl\u00e9ter l'\u00e9change<\/h3>\n      <button class=\"eqx-modal-close\" data-close=\"eqx-overlay-accept\">\u00d7<\/button>\n    <\/div>\n    <div class=\"eqx-modal-body\"><div class=\"eqx-form\">\n      <div>\n        <label style=\"font-size:.72rem;font-weight:600;color:var(--eq-muted);text-transform:uppercase;letter-spacing:.05em;display:block;margin-bottom:8px\">Mon template QSL *<\/label>\n        <div class=\"eqx-tpl-tabs\" id=\"eqx-accept-tabs\">\n          <button class=\"eqx-tpl-tab active\" data-panel=\"eqx-tpl-lib-accept\">\ud83d\udcc2 Mes templates<\/button>\n          <button class=\"eqx-tpl-tab\" data-panel=\"eqx-tpl-up-accept\">\u2b06 Ajouter<\/button>\n        <\/div>\n        <div id=\"eqx-tpl-lib-accept\">\n          <div class=\"eqx-tpl-grid\" id=\"eqx-tpl-grid-accept\"><div class=\"eqx-loading\"><div class=\"eqx-spinner\"><\/div><\/div><\/div>\n        <\/div>\n        <div id=\"eqx-tpl-up-accept\" style=\"display:none\">\n          <input type=\"text\" id=\"eqx-a-tpl-name\" placeholder=\"Nom du template\" style=\"margin-bottom:10px;background:#0d1117;border:1px solid var(--eq-border);border-radius:6px;color:var(--eq-text);padding:9px 12px;font-size:.88rem;width:100%;outline:none\">\n          <div class=\"eqx-upload-zone\" id=\"eqx-a-drop-zone\">\n            <input type=\"file\" id=\"eqx-a-tpl-file\" accept=\"image\/jpeg,image\/png,image\/gif\">\n            <svg width=\"28\" height=\"28\" fill=\"none\" stroke=\"var(--eq-muted)\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\"><path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12\"\/><\/svg>\n            <p style=\"color:var(--eq-muted);font-size:.82rem;margin-top:6px\">Glissez ou <strong style=\"color:var(--eq-accent2)\">cliquez<\/strong> \u2014 JPEG\u00b7PNG\u00b7GIF max 5Mo<\/p>\n            <div class=\"eqx-upload-selected\" id=\"eqx-a-tpl-selected\"><\/div>\n          <\/div>\n          <button class=\"eqx-btn eqx-btn-blue eqx-btn-sm\" id=\"eqx-a-btn-upload\">\u2b06 Uploader ce template<\/button>\n        <\/div>\n        <input type=\"hidden\" id=\"eqx-a-tpl-b\">\n      <\/div>\n      <div class=\"eqx-row cols-3\">\n        <div class=\"eqx-field\"><label>Mon heure (HH:MM) *<\/label><input type=\"text\" id=\"eqx-a-time\" placeholder=\"14:30\" maxlength=\"5\"><\/div>\n        <div class=\"eqx-field\"><label>Mon fuseau *<\/label><select id=\"eqx-a-tz\"><option>UTC<\/option><option>UTC+1<\/option><option>UTC+2<\/option><option>UTC-1<\/option><option>UTC-5<\/option><\/select><\/div>\n        <div class=\"eqx-field\"><label>Mon RST *<\/label><input type=\"text\" id=\"eqx-a-report\" placeholder=\"59\"><\/div>\n      <\/div>\n      <div class=\"eqx-row cols-2\">\n        <div class=\"eqx-field\"><label>Mon QTH Locator *<\/label><input type=\"text\" id=\"eqx-a-locator\" placeholder=\"JN03HA\" maxlength=\"10\" style=\"text-transform:uppercase\"><\/div>\n        <div class=\"eqx-field\"><label>Mon message (facultatif)<\/label><textarea id=\"eqx-a-message\" placeholder=\"73 de mon c\u00f4t\u00e9 !\"><\/textarea><\/div>\n      <\/div>\n    <\/div><\/div>\n    <div class=\"eqx-modal-foot\">\n      <button class=\"eqx-btn eqx-btn-ghost\" data-close=\"eqx-overlay-accept\">Annuler<\/button>\n      <button class=\"eqx-btn eqx-btn-primary\" id=\"eqx-btn-submit-accept\">\u2713 Confirmer l'\u00e9change<\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function($){\n'use strict';\nconst AJAX    =(typeof eqslVars!=='undefined')?eqslVars.ajaxUrl:'\/sugardelta_prod\/wp-admin\/admin-ajax.php';\nconst NONCE   =(typeof eqslVars!=='undefined')?eqslVars.nonce:'';\nconst IS_LOGGED=(typeof eqslVars!=='undefined')?eqslVars.isLoggedIn==='1':false;\nconst MY_ID   =(typeof eqslVars!=='undefined')?parseInt(eqslVars.currentUserId||0):0;\n\nlet leafletMap=null,mapLayers=[],currentExchange=null,currentFilter='all';\n\n\/* -- Drapeaux par QTH Locator (reverse geocoding) ------ *\/\nconst _locCache = {};   \/\/ \"IN97AB\" \u2192 \"fr\" | null\n\n\/\/ Reverse geocoding depuis coordonn\u00e9es (bigdatacloud, gratuit, sans cl\u00e9 API)\nfunction _fetchCountry(lat, lng) {\n  return new Promise(function(resolve) {\n    var url = 'https:\/\/api.bigdatacloud.net\/data\/reverse-geocode-client'\n            + '?latitude=' + lat + '&longitude=' + lng + '&localityLanguage=en';\n    fetch(url)\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\n\/\/ Obtenir le code pays depuis un locator \u2014 met en cache\nfunction locatorToCountry(loc) {\n  return new Promise(function(resolve) {\n    if (!loc) { resolve(null); return; }\n    var key = loc.toUpperCase().trim();\n    if (key in _locCache) { resolve(_locCache[key]); return; }\n    var ll = locatorToLatLng(key);\n    if (!ll) { _locCache[key] = null; resolve(null); return; }\n    _fetchCountry(ll[0], ll[1]).then(function(code) {\n      _locCache[key] = code;\n      resolve(code);\n    });\n  });\n}\n\n\/\/ Pr\u00e9charger tous les drapeaux d'un lot de locators en parall\u00e8le\nfunction preloadFlags(locators) {\n  var unique = locators.filter(function(l){ return !!l; })\n                       .filter(function(l,i,a){ return a.indexOf(l) === i; });\n  return Promise.all(unique.map(function(l){ return locatorToCountry(l); }));\n}\n\n\/\/ <img> du drapeau depuis le cache (synchrone \u2014 appeler apr\u00e8s preloadFlags)\nfunction flagHtml(locator, cls) {\n  if (!locator) return '';\n  var code = _locCache[locator.toUpperCase().trim()];\n  if (!code) return '';\n  cls = cls || 'eqx-flag';\n  return '<img decoding=\"async\" class=\"' + cls + '\" src=\"https:\/\/flagcdn.com\/16x12\/' + code + '.png\"'\n       + ' alt=\"' + code + '\" onerror=\"this.style.display=\\'none\\'\">';\n}\n\n\/* -- Utilitaires ---------------------------------------- *\/\nfunction toast(msg,type){\n  type=type||'success';\n  const el=$('<div class=\"eqx-toast eqx-toast-'+type+'\">'+msg+'<\/div>').appendTo('body');\n  setTimeout(function(){el.animate({opacity:0},300,function(){el.remove();});},3800);\n}\nfunction formatDate(d){if(!d)return'';const p=d.split('-');return p.length===3?p[2]+'\/'+p[1]+'\/'+p[0]:d;}\nfunction todayISO(){return new Date().toISOString().slice(0,10);}\n\n\/* -- QTH Locator \u2192 LatLng ------------------------------- *\/\nfunction locatorToLatLng(loc){\n  loc=(loc||'').toUpperCase().trim();\n  if(loc.length<4)return null;\n  let lng=(loc.charCodeAt(0)-65)*20-180;\n  let 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);\n    lat+=(loc.charCodeAt(5)-65)*(2.5\/60);\n    lng+=2.5\/60;lat+=1.25\/60;\n  }else{lng+=1;lat+=0.5;}\n  return[lat,lng];\n}\n\n\/* -- Carte ---------------------------------------------- *\/\nfunction initMap(){\n  if(leafletMap)return;\n  leafletMap=L.map('eqx-map',{center:[20,10],zoom:2});\n  L.tileLayer('https:\/\/{s}.basemaps.cartocdn.com\/dark_all\/{z}\/{x}\/{y}{r}.png',{attribution:'\u00a9 OpenStreetMap | \u00a9 CartoDB',maxZoom:18,subdomains:'abcd'}).addTo(leafletMap);\n}\nfunction clearMapLayers(){mapLayers.forEach(function(l){leafletMap.removeLayer(l);});mapLayers=[];}\nfunction updateMap(exchanges){\n  clearMapLayers();\n  if(!exchanges||!exchanges.length)return;\n  const locs={};\n  exchanges.forEach(function(ex){\n    const llA=locatorToLatLng(ex.qth_locator_a);\n    const llB=locatorToLatLng(ex.qth_locator_b);\n    if(!llA||!llB)return;\n    const line=L.polyline([llA,llB],{color:'#1f6feb',weight:2,opacity:.7,dashArray:'4,3'}).addTo(leafletMap);\n    mapLayers.push(line);\n    const kA=llA[0].toFixed(3)+','+llA[1].toFixed(3);\n    const kB=llB[0].toFixed(3)+','+llB[1].toFixed(3);\n    if(!locs[kA])locs[kA]={latlng:llA,names:[],logins:[],loc:ex.qth_locator_a};\n    if(locs[kA].names.indexOf(ex.user_a_name)<0){locs[kA].names.push(ex.user_a_name);locs[kA].logins.push(ex.user_a_login||ex.user_a_name);}\n    if(!locs[kB])locs[kB]={latlng:llB,names:[],logins:[],loc:ex.qth_locator_b};\n    if(locs[kB].names.indexOf(ex.user_b_name)<0){locs[kB].names.push(ex.user_b_name);locs[kB].logins.push(ex.user_b_login||ex.user_b_name);}\n  });\n\n  Object.values(locs).forEach(function(l){\n    \/\/ Cr\u00e9er un marker HTML avec drapeau\n    const code=_locCache[(l.loc||'').toUpperCase().trim()]||'';\n    const flagUrl=code?'https:\/\/flagcdn.com\/20x15\/'+code+'.png':'';\n    const iconHtml=flagUrl\n      ?'<div style=\"position:relative;width:24px;height:18px\"><img decoding=\"async\" src=\"'+flagUrl+'\" 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:#3fb950;border:2px solid #fff;border-radius:50%&quot;><\/div>\\'\"><\/div>'\n      :'<div style=\"width:12px;height:12px;background:#3fb950;border:2px solid #fff;border-radius:50%;box-shadow:0 0 6px rgba(0,0,0,.5)\"><\/div>';\n    const icon=L.divIcon({html:iconHtml,className:'',iconAnchor:flagUrl?[12,9]:[6,6]});\n    const popup='<strong>'+l.loc+'<\/strong><br><small>'+l.names.join(', ')+'<\/small>';\n    const m=L.marker(l.latlng,{icon:icon}).bindPopup(popup).addTo(leafletMap);\n    mapLayers.push(m);\n  });\n}\n\n\/* -- Echanges du jour ----------------------------------- *\/\nfunction loadDayExchanges(date){\n  $('#eqx-day-list').html('<div class=\"eqx-loading\"><div class=\"eqx-spinner\"><\/div> Chargement...<\/div>');\n  if(!IS_LOGGED){$('#eqx-day-list').html('<div class=\"eqx-empty\">\ud83d\udd12 Connectez-vous pour voir vos \u00e9changes du jour.<\/div>');clearMapLayers();return;}\n  $.post(AJAX,{action:'eqsl_get_day_exchanges',nonce:NONCE,date:date},function(r){\n    if(!r.success){$('#eqx-day-list').html('<div class=\"eqx-empty\">\u26a0\ufe0f Erreur.<\/div>');return;}\n    var exs=r.data;\n    var locs=[];\n    exs.forEach(function(e){if(e.qth_locator_a)locs.push(e.qth_locator_a);if(e.qth_locator_b)locs.push(e.qth_locator_b);});\n    preloadFlags(locs).then(function(){\n      updateMap(exs);\n      if(!exs.length){$('#eqx-day-list').html('<div class=\"eqx-empty\">\ud83d\udced Aucun \u00e9change ce jour-l\u00e0.<\/div>');return;}\n      var rows='';\n      exs.forEach(function(ex){\n        var isMine=IS_LOGGED&&(MY_ID===parseInt(ex.user_a_id)||MY_ID===parseInt(ex.user_b_id));\n        var nameA=flagHtml(ex.qth_locator_a)+ex.user_a_name;\n        var nameB=flagHtml(ex.qth_locator_b)+ex.user_b_name;\n        var mySide = (MY_ID===parseInt(ex.user_a_id)) ? 'a' : (MY_ID===parseInt(ex.user_b_id)) ? 'b' : null;\n        var dlBtns = mySide\n          ? '<td style=\"text-align:center\"><button class=\"eqx-dl-btn eqx-dl-icon\" data-exid=\"'+ex.id+'\" data-side=\"'+mySide+'\" title=\"T\u00e9l\u00e9charger mon eQSL\"><svg width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" viewBox=\"0 0 24 24\"><path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3\"\/><\/svg><\/button><\/td>'\n          : '<td><\/td>';\n        rows+='<tr><td>'+nameA+' \u2194 '+nameB+'<\/td><td>'+ex.qso_time_a+' '+ex.timezone_a+'<\/td><td>'+ex.frequency+' MHz<\/td><td>'+ex.mode+'<\/td>'+dlBtns+'<\/tr>';\n      });\n      $('#eqx-day-list').html('<div class=\"eqx-table-wrap\"><table class=\"eqx-table\"><thead><tr><th>Op\u00e9rateurs<\/th><th>Heure<\/th><th>Fr\u00e9q.<\/th><th>Mode<\/th><th>T\u00e9l\u00e9charger<\/th><\/tr><\/thead><tbody>'+rows+'<\/tbody><\/table><\/div><p style=\"font-size:.75rem;color:var(--eq-muted);margin-top:8px;text-align:right\">'+exs.length+' \u00e9change'+(exs.length>1?'s':'')+'<\/p>');\n    });\n  }).fail(function(){$('#eqx-day-list').html('<div class=\"eqx-empty\">\u26a0\ufe0f Erreur r\u00e9seau.<\/div>');});\n}\n\n\/* -- Echanges en attente -------------------------------- *\/\nfunction loadPendingExchanges(){\n  if(!IS_LOGGED)return;\n  $('#eqx-pending-list').html('<div class=\"eqx-loading\"><div class=\"eqx-spinner\"><\/div> Chargement...<\/div>');\n  $.post(AJAX,{action:'eqsl_get_pending_exchanges',nonce:NONCE,filter:currentFilter},function(r){\n    if(!r.success||!r.data.length){$('#eqx-pending-list').html('<div class=\"eqx-empty\">\u2713 Aucun \u00e9change en attente.<\/div>');return;}\n    var locs=r.data.map(function(e){return e.qth_locator_a;});\n    preloadFlags(locs).then(function(){\n      var rows='';\n      r.data.forEach(function(ex){\n        var mine=ex.is_mine;\n        var badgeTxt=ex.status==='rejected'?'Refus\u00e9':(mine?'En attente':'\u00c0 valider');\n        var badgeCls=ex.status==='rejected'?'eqbadge-rejected':(mine?'eqbadge-pending':'eqbadge-incoming');\n        var nameA=flagHtml(ex.qth_locator_a)+ex.user_a_name;\n        var nameB=flagHtml(ex.qth_locator_b)+ex.user_b_name;\n        var exJson=JSON.stringify(ex).replace(\/\\\\\/g,'\\\\\\\\').replace(\/'\/g,'&#39;');\n        rows+='<tr data-exid=\"'+ex.id+'\" data-mine=\"'+(mine?1:0)+'\" data-status=\"'+ex.status+'\" data-exobj=\\''+exJson+'\\'><td>'+(mine?('<strong>Moi<\/strong> \u2192 '+nameB):(nameA+' \u2192 <strong>Moi<\/strong>'))+'<\/td><td>'+formatDate(ex.qso_date)+'<\/td><td>'+ex.frequency+' '+ex.mode+'<\/td><td><span class=\"eqbadge '+badgeCls+'\">'+badgeTxt+'<\/span><\/td><\/tr>';\n      });\n      $('#eqx-pending-list').html('<div class=\"eqx-table-wrap\"><table class=\"eqx-table\"><thead><tr><th>Participants<\/th><th>Date<\/th><th>Fr\u00e9q\/Mode<\/th><th>Statut<\/th><\/tr><\/thead><tbody>'+rows+'<\/tbody><\/table><\/div>');\n    });\n  }).fail(function(){$('#eqx-pending-list').html('<div class=\"eqx-empty\">\u26a0\ufe0f Erreur r\u00e9seau.<\/div>');});\n}\n\n\/* -- Navigation date ------------------------------------ *\/\nfunction setDate(iso){$('#eqx-date-picker').val(iso);loadDayExchanges(iso);}\n$('#eqx-prev-day').on('click',function(){const d=new Date($('#eqx-date-picker').val()||todayISO());d.setDate(d.getDate()-1);setDate(d.toISOString().slice(0,10));});\n$('#eqx-next-day').on('click',function(){const d=new Date($('#eqx-date-picker').val()||todayISO());d.setDate(d.getDate()+1);setDate(d.toISOString().slice(0,10));});\n$('#eqx-date-picker').on('change',function(){loadDayExchanges($(this).val());});\n$(document).on('click','.eqx-filter-btn',function(){$('.eqx-filter-btn').removeClass('active');$(this).addClass('active');currentFilter=$(this).data('filter');loadPendingExchanges();});\n\n\/* -- Modals --------------------------------------------- *\/\nfunction openModal(id){$('#'+id).removeClass('hidden');$('body').css('overflow','hidden');}\nfunction closeModal(id){$('#'+id).addClass('hidden');$('body').css('overflow','');}\n$(document).on('click','[data-close]',function(){closeModal($(this).data('close'));});\n$(document).on('click','.eqx-overlay',function(e){if($(e.target).hasClass('eqx-overlay'))closeModal($(e.target).attr('id'));});\n\n\/* -- Onglets template ----------------------------------- *\/\n$(document).on('click','.eqx-tpl-tab',function(){\n  const $tabsContainer=$(this).closest('.eqx-tpl-tabs');\n  $tabsContainer.find('.eqx-tpl-tab').removeClass('active');\n  $(this).addClass('active');\n  const panel=$(this).data('panel');\n  \/\/ Cacher tous les panneaux fr\u00e8res\n  $('#'+panel).siblings('[id^=\"eqx-tpl-\"]').hide();\n  $('#'+panel).show();\n});\n\n\/* -- Drag & drop ---------------------------------------- *\/\nfunction setupDropZone(dropId,fileId,selectedId){\n  const $drop=$('#'+dropId);\n  $drop.on('click',function(e){\n    if($(e.target).is('input[type=file]'))return;\n    e.stopPropagation();\n    document.getElementById(fileId).click();\n  });\n  $drop.on('dragover',function(e){e.preventDefault();$(this).css('border-color','var(--eq-accent2)');});\n  $drop.on('dragleave',function(){$(this).css('border-color','var(--eq-border)');});\n  $drop.on('drop',function(e){\n    e.preventDefault();$(this).css('border-color','var(--eq-border)');\n    const file=e.originalEvent.dataTransfer.files[0];\n    if(file){\n      const dt=new DataTransfer();dt.items.add(file);\n      document.getElementById(fileId).files=dt.files;\n      $('#'+selectedId).text('\ud83d\udcce '+file.name).show();\n    }\n  });\n  $('#'+fileId).on('change',function(){if(this.files[0])$('#'+selectedId).text('\ud83d\udcce '+this.files[0].name).show();});\n}\nsetupDropZone('eqx-c-drop-zone','eqx-c-tpl-file','eqx-c-tpl-selected');\nsetupDropZone('eqx-a-drop-zone','eqx-a-tpl-file','eqx-a-tpl-selected');\n\n\/* -- Upload template ------------------------------------ *\/\nfunction uploadTemplate(fileInputId,nameInputId,gridId,hiddenId,libPanelId,btnId){\n  const fileInput=document.getElementById(fileInputId);\n  const file=fileInput.files[0];\n  if(!file){toast('S\u00e9lectionnez un fichier image','error');return;}\n  const name=$('#'+nameInputId).val().trim()||file.name.replace(\/\\.[^.]+$\/,'');\n  const btn=$('#'+btnId).text('\u23f3 Upload...').prop('disabled',true);\n  const fd=new FormData();\n  fd.append('action','eqsl_upload_template');\n  fd.append('nonce',NONCE);\n  fd.append('template_name',name);\n  fd.append('template_file',file,file.name);\n  const xhr=new XMLHttpRequest();\n  xhr.open('POST',AJAX,true);xhr.withCredentials=true;\n  xhr.onload=function(){\n    btn.text('\u2b06 Uploader ce template').prop('disabled',false);\n    try{\n      const r=JSON.parse(xhr.responseText);\n      if(r.success){\n        toast('Template \"'+name+'\" ajout\u00e9 !');\n        $('#'+nameInputId).val('');fileInput.value='';\n        \/\/ Masquer le nom s\u00e9lectionn\u00e9\n        var selId=fileInputId.replace('-file','-selected');\n        $('#'+selId).hide();\n        \/\/ Basculer sur biblioth\u00e8que et recharger\n        var $libTab=$('#'+libPanelId).prev('.eqx-tpl-tabs').find('[data-panel=\"'+libPanelId+'\"]');\n        if($libTab.length)$libTab.click();\n        else{$('#'+libPanelId).show();$('#'+libPanelId).siblings('[id^=\"eqx-tpl-up-\"]').hide();}\n        loadTplGrid(gridId,hiddenId);\n      }else toast(r.data||'Erreur upload','error');\n    }catch(e){toast('R\u00e9ponse inattendue : '+xhr.responseText.substring(0,200),'error');}\n  };\n  xhr.onerror=function(){btn.text('\u2b06 Uploader ce template').prop('disabled',false);toast('Erreur r\u00e9seau','error');};\n  xhr.send(fd);\n}\n$('#eqx-c-btn-upload').on('click',function(){uploadTemplate('eqx-c-tpl-file','eqx-c-tpl-name','eqx-tpl-grid-create','eqx-c-tpl-a','eqx-tpl-lib-create','eqx-c-btn-upload');});\n$('#eqx-a-btn-upload').on('click',function(){uploadTemplate('eqx-a-tpl-file','eqx-a-tpl-name','eqx-tpl-grid-accept','eqx-a-tpl-b','eqx-tpl-lib-accept','eqx-a-btn-upload');});\n\n\/* -- Grille templates ----------------------------------- *\/\nfunction loadTplGrid(gridId,hiddenId){\n  const $grid=$('#'+gridId);\n  $grid.html('<div class=\"eqx-loading\"><div class=\"eqx-spinner\"><\/div><\/div>');\n  $.post(AJAX,{action:'eqsl_get_templates',nonce:NONCE},function(r){\n    if(!r.success||!r.data.length){$grid.html('<p style=\"color:var(--eq-muted);font-size:.82rem;padding:8px 0\">Aucun template \u2014 uploadez-en un via l\\'onglet \"Ajouter\".<\/p>');return;}\n    let html='';\n    r.data.forEach(function(t){html+='<div class=\"eqx-tpl-card\" data-id=\"'+t.id+'\" data-hidden=\"'+hiddenId+'\"><img decoding=\"async\" src=\"'+t.preview_url+'\" alt=\"'+t.name+'\" loading=\"lazy\"><div class=\"check\">\u2713<\/div><\/div>';});\n    $grid.html(html);\n  }).fail(function(){$grid.html('<p style=\"color:var(--eq-muted);font-size:.82rem\">Erreur chargement.<\/p>');});\n}\n$(document).on('click','.eqx-tpl-card',function(){\n  const hiddenId=$(this).data('hidden');\n  $(this).closest('.eqx-tpl-grid').find('.eqx-tpl-card').removeClass('selected');\n  $(this).addClass('selected');\n  $('#'+hiddenId).val($(this).data('id'));\n});\n\n\/* -- Recherche user ------------------------------------- *\/\nvar searchTimeout=null;\n$('#eqx-user-search').on('input',function(){\n  clearTimeout(searchTimeout);\n  const q=$(this).val().trim();\n  if(q.length<2){$('#eqx-user-results').addClass('hidden').empty();return;}\n  searchTimeout=setTimeout(function(){\n    $.post(AJAX,{action:'eqsl_search_users',nonce:NONCE,q:q},function(r){\n      if(!r.success||!r.data.length){$('#eqx-user-results').html('<div class=\"eqx-user-result-item\" style=\"color:var(--eq-muted)\">Aucun r\u00e9sultat<\/div>').removeClass('hidden');return;}\n      let html='';\n      r.data.forEach(function(u){html+='<div class=\"eqx-user-result-item\" data-id=\"'+u.id+'\" data-name=\"'+u.name+'\">&#128100; '+u.name+' <span class=\"badge\">'+u.login+'<\/span><\/div>';});\n      $('#eqx-user-results').html(html).removeClass('hidden');\n    });\n  },300);\n});\n$(document).on('click','.eqx-user-result-item[data-id]',function(){\n  $('#eqx-c-user-b-id').val($(this).data('id'));\n  $('#eqx-selected-user-name').text($(this).data('name'));\n  $('#eqx-selected-user-display').removeClass('hidden');\n  $('#eqx-user-search').val('').closest('.eqx-user-search-wrap').find('.eqx-user-results').addClass('hidden');\n});\n$('#eqx-clear-user').on('click',function(){$('#eqx-c-user-b-id').val('');$('#eqx-selected-user-display').addClass('hidden');$('#eqx-user-search').val('').focus();});\n$(document).on('click',function(e){if(!$(e.target).closest('.eqx-user-search-wrap').length)$('#eqx-user-results').addClass('hidden');});\n\n\/* -- Auto-format ---------------------------------------- *\/\n$(document).on('input','#eqx-c-date',function(){let v=$(this).val().replace(\/\\D\/g,'');if(v.length>2)v=v.slice(0,2)+'\/'+v.slice(2);if(v.length>5)v=v.slice(0,5)+'\/'+v.slice(5,9);$(this).val(v);});\n$(document).on('input','#eqx-c-time,#eqx-a-time',function(){let v=$(this).val().replace(\/\\D\/g,'');if(v.length>2)v=v.slice(0,2)+':'+v.slice(2,4);$(this).val(v);});\n$(document).on('input','#eqx-c-locator,#eqx-a-locator',function(){$(this).val($(this).val().toUpperCase());});\n\n\/* -- Creer echange -------------------------------------- *\/\n$('#eqx-btn-create').on('click',function(){\n  $('#eqx-c-user-b-id,#eqx-c-tpl-a').val('');\n  $('#eqx-c-date,#eqx-c-time,#eqx-c-freq,#eqx-c-report,#eqx-c-locator,#eqx-c-message,#eqx-c-tpl-name').val('');\n  $('#eqx-selected-user-display').addClass('hidden');$('#eqx-user-search').val('');\n  $('#eqx-tpl-lib-create').show();$('#eqx-tpl-up-create').hide();\n  $('#eqx-create-tabs .eqx-tpl-tab').first().addClass('active').siblings().removeClass('active');\n  loadTplGrid('eqx-tpl-grid-create','eqx-c-tpl-a');\n  openModal('eqx-overlay-create');\n});\n\n$('#eqx-btn-submit-create').on('click',function(){\n  const uid_b=$('#eqx-c-user-b-id').val();\n  const tpl_a=$('#eqx-c-tpl-a').val();\n  const date=$('#eqx-c-date').val().trim();\n  const time=$('#eqx-c-time').val().trim();\n  const freq=$('#eqx-c-freq').val().trim();\n  const report=$('#eqx-c-report').val().trim();\n  const locator=$('#eqx-c-locator').val().trim();\n  if(!uid_b){toast('S\u00e9lectionnez un op\u00e9rateur destinataire','error');return;}\n  if(!tpl_a){toast('S\u00e9lectionnez votre template QSL','error');return;}\n  if(!\/^\\d{2}\\\/\\d{2}\\\/\\d{4}$\/.test(date)){toast('Date invalide (DD\/MM\/YYYY)','error');return;}\n  if(!\/^\\d{2}:\\d{2}$\/.test(time)){toast('Heure invalide (HH:MM)','error');return;}\n  if(!freq||!report||!locator){toast('Fr\u00e9quence, RST et Locator requis','error');return;}\n  if(!\/^[A-Z]{2}\\d{2}([A-Z]{2})?$\/.test(locator)){toast('Locator invalide (ex: IN97AB)','error');return;}\n  const btn=$(this).text('\u23f3 Envoi...').prop('disabled',true);\n  $.post(AJAX,{action:'eqsl_create_exchange',nonce:NONCE,user_b_id:uid_b,template_a_id:tpl_a,qso_date:date,qso_time:time,timezone:$('#eqx-c-tz').val(),frequency:freq,mode:$('#eqx-c-mode').val(),report:report,qth_locator:locator,message:$('#eqx-c-message').val().trim()},function(r){\n    btn.text('\ud83d\udce1 Envoyer la demande').prop('disabled',false);\n    if(r.success){toast('Demande envoy\u00e9e !');closeModal('eqx-overlay-create');loadPendingExchanges();}\n    else toast(r.data||'Erreur','error');\n  }).fail(function(){btn.text('\ud83d\udce1 Envoyer la demande').prop('disabled',false);toast('Erreur r\u00e9seau','error');});\n});\n\n\/* -- Clic ligne en attente ------------------------------ *\/\n$(document).on('click','.eqx-table tbody tr[data-exid]',function(){\n  try{currentExchange=JSON.parse($(this).attr('data-exobj')||'{}');}catch(e){return;}\n  openDetailModal(currentExchange,$(this).data('mine')===1,$(this).data('status'));\n});\n\nfunction openDetailModal(ex,isMine,status){\n  const msgA=ex.message_a?'<div style=\"grid-column:1\/-1\"><dt>Message<\/dt><dd style=\"font-style:italic\">'+ex.message_a+'<\/dd><\/div>':'';\n  const flagA=flagHtml(ex.qth_locator_a);const flagB=flagHtml(ex.qth_locator_b);\n  $('#eqx-det-recap').html('<dl><div><dt>Initiateur<\/dt><dd>'+flagA+ex.user_a_name+'<\/dd><\/div><div><dt>Destinataire<\/dt><dd>'+flagB+ex.user_b_name+'<\/dd><\/div><div><dt>Date<\/dt><dd>'+formatDate(ex.qso_date)+'<\/dd><\/div><div><dt>Heure A<\/dt><dd>'+ex.qso_time_a+' '+ex.timezone_a+'<\/dd><\/div><div><dt>Fr\u00e9quence<\/dt><dd>'+ex.frequency+' MHz<\/dd><\/div><div><dt>Mode<\/dt><dd>'+ex.mode+'<\/dd><\/div><div><dt>RST A<\/dt><dd>'+ex.report_a+'<\/dd><\/div><div><dt>Locator A<\/dt><dd>'+(ex.qth_locator_a||'\u2014')+'<\/dd><\/div>'+msgA+'<\/dl>');\n  $('#eqx-det-title').text((isMine?'Ma demande vers ':'Demande de ')+(isMine?ex.user_b_name:ex.user_a_name));\n  $('#eqx-det-actions-b,#eqx-det-rejected,#eqx-det-completed').hide();\n  if(status==='pending'&&!isMine)$('#eqx-det-actions-b').show();\n  if(status==='rejected')$('#eqx-det-rejected').show();\n  if(status==='completed'){$('#eqx-dl-name-a').text(ex.user_a_name);$('#eqx-dl-name-b').text(ex.user_b_name);$('#eqx-det-completed').show();}\n  openModal('eqx-overlay-detail');\n}\n\n\/* -- Telechargements ------------------------------------ *\/\n$(document).on('click','.eqx-dl-btn',function(){\n  window.location.href=AJAX+'?action=eqsl_download_exchange&exchange_id='+$(this).data('exid')+'&side='+$(this).data('side');\n});\n$('#eqx-btn-dl-a').on('click',function(){if(currentExchange)window.location.href=AJAX+'?action=eqsl_download_exchange&exchange_id='+currentExchange.id+'&side=a';});\n$('#eqx-btn-dl-b').on('click',function(){if(currentExchange)window.location.href=AJAX+'?action=eqsl_download_exchange&exchange_id='+currentExchange.id+'&side=b';});\n\n\/* -- Refuser -------------------------------------------- *\/\n$('#eqx-btn-reject').on('click',function(){\n  if(!currentExchange||!confirm('Confirmer le refus ?'))return;\n  const btn=$(this).text('\u23f3...').prop('disabled',true);\n  $.post(AJAX,{action:'eqsl_respond_exchange',nonce:NONCE,exchange_id:currentExchange.id,response:'reject'},function(r){\n    btn.text('\u2715 Refuser').prop('disabled',false);\n    if(r.success){toast('\u00c9change refus\u00e9');closeModal('eqx-overlay-detail');loadPendingExchanges();}\n    else toast(r.data||'Erreur','error');\n  });\n});\n\n\/* -- Accepter ------------------------------------------- *\/\n$('#eqx-btn-accept-open').on('click',function(){\n  $('#eqx-a-tpl-b').val('');\n  $('#eqx-a-time,#eqx-a-report,#eqx-a-locator,#eqx-a-message,#eqx-a-tpl-name').val('');\n  $('#eqx-tpl-lib-accept').show();$('#eqx-tpl-up-accept').hide();\n  $('#eqx-accept-tabs .eqx-tpl-tab').first().addClass('active').siblings().removeClass('active');\n  loadTplGrid('eqx-tpl-grid-accept','eqx-a-tpl-b');\n  openModal('eqx-overlay-accept');\n});\n\n$('#eqx-btn-submit-accept').on('click',function(){\n  const tpl_b=$('#eqx-a-tpl-b').val();\n  const time_b=$('#eqx-a-time').val().trim();\n  const report_b=$('#eqx-a-report').val().trim();\n  const locator_b=$('#eqx-a-locator').val().trim();\n  if(!tpl_b){toast('S\u00e9lectionnez votre template','error');return;}\n  if(!\/^\\d{2}:\\d{2}$\/.test(time_b)){toast('Heure invalide (HH:MM)','error');return;}\n  if(!report_b||!locator_b){toast('RST et Locator requis','error');return;}\n  if(!\/^[A-Z]{2}\\d{2}([A-Z]{2})?$\/.test(locator_b)){toast('Locator invalide (ex: JN03HA)','error');return;}\n  const btn=$(this).text('\u23f3 Confirmation...').prop('disabled',true);\n  $.post(AJAX,{action:'eqsl_respond_exchange',nonce:NONCE,exchange_id:currentExchange.id,response:'accept',template_b_id:tpl_b,qso_time_b:time_b,timezone_b:$('#eqx-a-tz').val(),report_b:report_b,qth_locator_b:locator_b,message_b:$('#eqx-a-message').val().trim()},function(r){\n    btn.text('\u2713 Confirmer l\\'\u00e9change').prop('disabled',false);\n    if(r.success){\n      toast('\u2705 \u00c9change confirm\u00e9 ! Les eQSL ont \u00e9t\u00e9 envoy\u00e9es par email.');\n      closeModal('eqx-overlay-accept');closeModal('eqx-overlay-detail');\n      loadPendingExchanges();\n      loadDayExchanges($('#eqx-date-picker').val()||todayISO());\n    }else toast(r.data||'Erreur','error');\n  }).fail(function(){btn.text('\u2713 Confirmer l\\'\u00e9change').prop('disabled',false);toast('Erreur r\u00e9seau','error');});\n});\n\n\/* -- Init ----------------------------------------------- *\/\n$(document).ready(function(){\n  initMap();\n  var today=todayISO();\n  $('#eqx-date-picker').val(today);\n  loadDayExchanges(today);\n  if(IS_LOGGED){$('#eqx-btn-create').show();$('#eqx-filters').show();loadPendingExchanges();}\n  setTimeout(function(){if(leafletMap)leafletMap.invalidateSize();},400);\n\n  \/* -- Plein \u00e9cran carte --------------------------------- *\/\n  var isFullscreen=false;\n  $('#eqx-fullscreen-btn').on('click',function(){\n    isFullscreen=!isFullscreen;\n    $('#eqx-map-wrap').toggleClass('eqx-fullscreen',isFullscreen);\n    $('#eqx-fs-icon-expand').toggle(!isFullscreen);\n    $('#eqx-fs-icon-shrink').toggle(isFullscreen);\n    $('#eqx-fs-label').text(isFullscreen?'Quitter':'Plein \u00e9cran');\n    $('body').css('overflow',isFullscreen?'hidden':'');\n    setTimeout(function(){if(leafletMap)leafletMap.invalidateSize();},50);\n  });\n  \/\/ \u00c9chap pour quitter le plein \u00e9cran\n  $(document).on('keydown',function(e){\n    if(e.key==='Escape'&&isFullscreen)$('#eqx-fullscreen-btn').click();\n  });\n});\n\n})(jQuery);\n<\/script>\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>Plein \u00e9cran Ligne d&#8217;\u00e9change \u26a1 \u00c9changes du jour \u25c0 \u25b6 Chargement&#8230; \ud83d\udccb \u00c9changes en attente Cr\u00e9er un \u00e9change Tous Mes demandes \u00c0 valider \ud83d\udd12 Connectez-vous pour voir vos \u00e9changes. \ud83d\udce1 Nouvel \u00e9change d&#8217;eQSL \u00d7 Op\u00e9rateur destinataire * \u2715 Mon template QSL * \ud83d\udcc2 Mes templates \u2b06 Ajouter Glissez ou cliquez \u2014 JPEG\u00b7PNG\u00b7GIF max 5Mo \u2b06 Uploader ce template Date QSO * Heure (HH:MM) * Fuseau *UTCUTC+1UTC+2UTC-1UTC-5 Fr\u00e9quence MHz * Mode *SSBCWFT8FT4PSK31RTTYAMFMDMRC4FMDSTARAutre Mon RST * Mon QTH Locator * Message (facultatif) Annuler \ud83d\udce1 Envoyer la demande D\u00e9tail \u00e9change \u00d7 Acceptez et renseignez vos informations, ou refusez cet \u00e9change. \u2715 Refuser \u2713 Accepter et compl\u00e9ter \u2715 Cet \u00e9change a \u00e9t\u00e9 refus\u00e9. \u00c9change confirm\u00e9 \u2014 t\u00e9l\u00e9chargez les eQSL : \u2b07 eQSL de \u2b07 eQSL de Fermer \u2713 Compl\u00e9ter l&#8217;\u00e9change \u00d7 Mon template QSL * \ud83d\udcc2 Mes templates \u2b06 Ajouter Glissez ou cliquez \u2014 JPEG\u00b7PNG\u00b7GIF max 5Mo \u2b06 Uploader ce template Mon heure (HH:MM) * Mon fuseau *UTCUTC+1UTC+2UTC-1UTC-5 Mon RST * Mon QTH Locator * Mon message (facultatif) Annuler \u2713 Confirmer l&#8217;\u00e9change<\/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-560","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/pages\/560","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=560"}],"version-history":[{"count":35,"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/pages\/560\/revisions"}],"predecessor-version":[{"id":613,"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/pages\/560\/revisions\/613"}],"wp:attachment":[{"href":"https:\/\/www.ingilog.com\/sugardelta_prod\/wp-json\/wp\/v2\/media?parent=560"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}