diff --git a/CTFd/plugins/sport_challenges/assets/update.html b/CTFd/plugins/sport_challenges/assets/update.html
index 8801d1d467a42bfa24b8e11e8d764ed0b2c001d3..0d7f1f0654f04fec73dd7fe225c22cc410612ab7 100644
--- a/CTFd/plugins/sport_challenges/assets/update.html
+++ b/CTFd/plugins/sport_challenges/assets/update.html
@@ -5,12 +5,12 @@
     <div class="mb-3">
         <div class="row">
             <div class="col-md-6">
-                <label>{% trans %}Unit{% endtrans %}</label>
+                <label>{% trans %}Unité{% endtrans %}</label>
                 <input required class="form-control" id="unit" type="text" name="unit" placeholder="Enter unit" value="{{ challenge.unit }}">
             </div>
             <div class="col-md-6">
-                <label>{% trans %}Max Points{% endtrans %}</label>
-                <input required class="form-control" id="max-points" type="number" name="max_points" placeholder="Enter max points" value="{{ challenge.max_points }}" min="0" >
+                <label>{% trans %}Points maximum{% endtrans %}</label>
+                <input required class="form-control" id="max-points" type="number" name="max_points" placeholder="Enter max points" value="{{ challenge.max_points }}" min="1" >
             </div>
         </div>
     </div>
diff --git a/CTFd/themes/admin/assets/js/pages/challenges.js b/CTFd/themes/admin/assets/js/pages/challenges.js
index b115578f29428c4361e305d7ec2a0cd7a257f5e2..2c860f14074c5fc2d65009f32da2a83142a3ae3a 100644
--- a/CTFd/themes/admin/assets/js/pages/challenges.js
+++ b/CTFd/themes/admin/assets/js/pages/challenges.js
@@ -162,6 +162,19 @@ document.addEventListener("DOMContentLoaded", function (event) {
       category.hidden = true;
     }
   }
+  function swapValueForSportConfig() {
+    const params = $("#challenge-create-options-quick").serializeJSON();
+    let value = document.getElementById("value-input");
+    let sportConfigForm = document.getElementById("sport-config-button");
+
+    if(params.type == "sport"){
+      value.hidden = true;
+      sportConfigForm.hidden = false;
+    } else{
+      value.hidden = false;
+      sportConfigForm.hidden = true;
+    }
+  }
   function processDateTime(datetime) {
     let date_picker = document.querySelector(`#${datetime}-date`);
     let time_picker = document.querySelector(`#${datetime}-time`);
@@ -176,10 +189,25 @@ document.addEventListener("DOMContentLoaded", function (event) {
     } else {
       document.querySelector(`#${datetime}-preview`).value = unix_time;
     }
-    console.log("hit");
   }
 
-  function changeTimePeriode(event) {
+  function processSportConfig() {
+    let unit = document.getElementById("unit-input-config");
+    let max_points = document.getElementById("max-points-input-config");
+    let pointsPerUnit = document.getElementById("value-input-config");
+    let pointsPerUnit_preview = document.getElementById("value-input");
+    let unit_preview = document.getElementById("unit-preview");
+    let max_points_preview = document.getElementById("max-points-preview");
+
+    console.log(unit.value);
+
+    pointsPerUnit_preview.value = pointsPerUnit.value;
+    unit_preview.value = unit.value;
+    max_points_preview.value = max_points.value;
+  }
+  window.processSportConfig = processSportConfig;
+
+  function changeTimePeriode() {
     ezAlert({
       title: "Choisir Période",
       body: `<div class="mb-3" style="text-align: center;">
@@ -263,11 +291,106 @@ document.addEventListener("DOMContentLoaded", function (event) {
     });
   }
 
-  function loadAndhandleChallenge(event) {
+  function configSportChallenge() {
+    ezAlert({
+      title: "Configurer le défi Sportif",
+      body: `<div class="tab-pane" id="challenge-points" role="tabpanel">
+                <div class="mb-3">
+                    <div class="row center">
+                        <div class="col-md-6">
+                            <label>Unité</label>
+                            <input required class="form-control" id="unit-input-config" type="text" placeholder="Entrez l'unité" value="km" onchange="processSportConfig()">
+                        </div>
+                        <div class="col-md-6">
+                            <label>Points maximum</label>
+                            <input required class="form-control" id="max-points-input-config" type="number" placeholder="Entrez le nombre de points maximum (0 pour infini)" value="1" min="1" onchange="processSportConfig()">
+                        </div>
+                        <div class="col-md-6">
+                            <label>Points par Unité</label>
+                            <input type="number" class="form-control chal-value" id="value-input-config" value="1" onchange="processSportConfig()" min="1" required>
+                        </div>
+                        <div class="col-md-6">
+                            <label>
+                                <span>Informations</span> 
+                                <span class="info-icon">ℹ
+                                    <span class="tooltip-text">
+                                        <p>Par exemple, un défi avec "km" comme unité, "100" comme points maximum et "5" pour points par unité donnera 5 points pour chaque km parcouru.</p>
+                                        <p>Le nombre de points maximum est pour l'équipe au complet.</p>
+                                    </span>
+                                </span>
+                            </label>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <style>
+                  .center {
+                    align-items: center;
+                    justify-content: center;
+                  }
+                  .info-icon {
+                    position: relative;
+                    cursor: pointer;
+                    font-style: normal;
+                    font-size: 1.2em;
+                    font-weight: bold;
+                    display: inline-flex;
+                    align-items: center;
+                    justify-content: center;
+                    width: 24px;
+                    height: 24px;
+                    border: 2px solid #333;
+                    border-radius: 50%;
+                    color: #333;
+                    text-align: center;
+                    margin-left: 10px;
+                  }
+
+                  .info-icon .tooltip-text {
+                      visibility: hidden;
+                      width: 300px; /* Fixed width instead of percentage */
+                      max-width: 500px;
+                      background-color: rgba(0, 0, 0, 0.8);
+                      color: #fff;
+                      text-align: center;
+                      padding: 15px;
+                      border-radius: 10px;
+                      position: absolute;
+                      top: 50%;
+                      left: 50%;
+                      transform: translate(-50%, -50%);
+                      opacity: 0;
+                      transition: opacity 0.3s ease-in-out;
+                      z-index: 9999;
+                      box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
+                      white-space: normal; /* Ensure text wraps properly */
+                  }
+
+                  .info-icon:hover .tooltip-text {
+                    visibility: visible;
+                    opacity: 1;
+                  }
+
+                  .tooltip-text p {
+                    margin-bottom: 15px;
+                  }
+            </style>`,
+      button: "Ok",
+      success: function () {
+        console.log("done");
+      },
+    });
+  }
+
+  function loadAndhandleChallenge() {
     const params = $("#challenge-create-options-quick").serializeJSON();
     delete params.challenge_id;
     delete params.flag_type;
 
+    if (params.type !== "sport") {
+      delete params.unit;
+      delete params.max_points;
+    } //TODO: Validation des données défi sport
     if (params.type != "flash") {
       delete params.startTime;
       delete params.endTime;
@@ -316,7 +439,7 @@ document.addEventListener("DOMContentLoaded", function (event) {
           }
           setTimeout(function () {
             window.location.reload(true);
-          }, 500);
+          }, 400);
         } else {
           let body = "";
           for (const k in response.errors) {
@@ -353,6 +476,7 @@ document.addEventListener("DOMContentLoaded", function (event) {
     .getElementById("challenge-type")
     .addEventListener("change", function (event) {
       swapCategoryWithEndTimeInput();
+      swapValueForSportConfig();
     });
   document
     .getElementById("time-selector-input")
@@ -360,6 +484,12 @@ document.addEventListener("DOMContentLoaded", function (event) {
       event.preventDefault();
       changeTimePeriode(event);
     });
+  document
+    .getElementById("sport-config-button")
+    .addEventListener("click", function (event) {
+      event.preventDefault();
+      configSportChallenge(event);
+    });
 });
 
 function deleteSelectedChallenges(_event) {
diff --git a/CTFd/themes/admin/static/assets/pages/challenges.a6549073.js b/CTFd/themes/admin/static/assets/pages/challenges.a6549073.js
deleted file mode 100644
index cbac62cac2cc68a997815c52203e33504349b817..0000000000000000000000000000000000000000
--- a/CTFd/themes/admin/static/assets/pages/challenges.a6549073.js
+++ /dev/null
@@ -1,104 +0,0 @@
-import{s as E,C as m,$ as i,B as p,u as S}from"./main.71d0edc5.js";document.addEventListener("DOMContentLoaded",function(g){document.getElementById("btn-file-input").addEventListener("click",function(t){document.getElementById("thumbsnail-get-path").click()}),document.getElementById("thumbsnail-get-path").addEventListener("change",function(t){const e=t.target.files[0];let a=document.getElementById("thumbsnail-upload-form");const l=new FormData(a);if(l.append("file",e),E.files.upload(l,a,function(r){const f=r.data[0],c=m.config.urlRoot+"/files/"+f.location;document.getElementById("thumbsnail-path").value=c,console.log("Miniature t\xE9l\xE9charg\xE9e avec succ\xE8s:",c);const v=document.getElementById("image-preview");v.src=c,v.style.display="block"}),e){const r=new FileReader;r.onload=function(f){const c=document.getElementById("image-preview");c.src=f.target.result,c.style.display="block"},r.readAsDataURL(e)}});const o=Object.keys(document.categories),d=document.getElementById("categories-selector");o.forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,e.textContent!="D\xE9fi Flash"&&d.appendChild(e)});const s=document.createElement("option");s.value="other",s.textContent="Other (type below)",d.appendChild(s);const n=document.getElementById("categories-selector-input");d.value=="other"||o.length==0?(n.style.display="block",n.name="category"):(n.style.display="none",n.value="",n.name=""),d.addEventListener("change",function(){d.value=="other"||o.length==0?(n.style.display="block",n.name="category"):(n.style.display="none",n.value="",n.name="")});let u=0;document.querySelectorAll("td.id").forEach(function(t){const e=parseInt(t.textContent);!isNaN(e)&&e>u&&(u=e)});const h=u+1;document.getElementById("challenge_id_texte").textContent=h,document.getElementById("challenge_id").value=h;function D(){const t=i("#challenge-create-options-quick").serializeJSON();let e=document.getElementById("categories-selector"),a=document.getElementById("categories-selector-input"),l=document.getElementById("time-selector-input");e.hidden&&t.type!="flash"?(l.hidden=!0,a.hidden=!1,e.hidden=!1):!e.hidden&&t.type=="flash"&&(l.hidden=!1,a.hidden=!0,e.hidden=!0)}function b(t){p({title:"Choisir P\xE9riode",body:`<div class="mb-3" style="text-align: center;">
-              <label>D\xE9but</label>
-              <div class="row" style="justify-content: space-around;">
-              
-                  <div class="col-md-4" >
-                      <label>Date</label>
-                      <input required class="form-control start-date" id="start-date" type="date" placeholder="yyyy-mm-dd"  onchange="processDateTime('start')" />
-                  </div>
-                  <div class="col-md-4">
-                      <label>Temps</label>
-                      <input required class="form-control start-time" id="start-time" type="time" placeholder="hh:mm" data-preview="#start" onchange="processDateTime('start')"/>
-                  </div>
-                
-              </div>
-              <small class="form-text text-muted">
-                
-              </small>
-          </div>
-
-          <div class="mb-3" style="text-align: center;">
-              <label>Fin</label>
-              <div class="row" style="justify-content: space-around;">
-                  
-                  <div class="col-md-4">
-                      <label>Date</label>
-                      <input required class="form-control end-date" id="end-date" type="date" placeholder="yyyy-mm-dd" data-preview="#end" onchange="processDateTime('end')"/>
-                  </div>
-                  <div class="col-md-4">
-                      <label>Temps</label>
-                      <input required class="form-control end-time" id="end-time" type="time" placeholder="hh:mm" data-preview="#end" onchange="processDateTime('end')"/>
-                  </div>
-                  
-              </div>
-          
-          </div>
-          <script>
-          endDate = new Date(document.getElementById("end-preview").value * 1000);
-          startDate = new Date(document.getElementById("start-preview").value * 1000);
-
-          //faut remodeler le time formater pour avoir YYYY-MM-JJ
-          timeFormatterYMD = new Intl.DateTimeFormat("en-US");
-          endDateYMDNotformated = timeFormatterYMD .format(endDate);
-          endDateYMD = endDateYMDNotformated.split("/")[2]+"-"+(endDateYMDNotformated.split("/")[0].length < 2 ? "0"+endDateYMDNotformated.split("/")[0]: endDateYMDNotformated.split("/")[0])
-          +"-"+(endDateYMDNotformated.split("/")[1].length < 2 ? "0"+endDateYMDNotformated.split("/")[1]: endDateYMDNotformated.split("/")[1]);
-          timeDateEnd = document.getElementsByClassName("end-date");
-          for (let i = 0; i < timeDateEnd.length; i++) {
-            timeDateEnd.item(i).value = endDateYMD;
-          }
-
-
-          startDateYMDNotformated = timeFormatterYMD .format(startDate);
-          startDateYMD = startDateYMDNotformated.split("/")[2]+"-"+(startDateYMDNotformated.split("/")[0].length < 2 ? "0"+startDateYMDNotformated.split("/")[0]: startDateYMDNotformated.split("/")[0])
-          +"-"+(startDateYMDNotformated.split("/")[1].length < 2 ? "0"+startDateYMDNotformated.split("/")[1]: startDateYMDNotformated.split("/")[1]);
-          timeDateStart = document.getElementsByClassName("start-date");
-          for (let i = 0; i < timeDateStart.length; i++) {
-            timeDateStart.item(i).value = startDateYMD;
-          }
-
-          timeFormatterHS = new Intl.DateTimeFormat(undefined, { timeStyle: 'medium' });
-          console.log(timeFormatterHS.format(endDate))
-          endDateHS = timeFormatterHS.format(endDate).split(":")[0]+":"+timeFormatterHS.format(endDate).split(":")[1]
-          timeHSEnd = document.getElementsByClassName("end-time");
-          for (let i = 0; i < timeHSEnd.length; i++) {
-            timeHSEnd.item(i).value = endDateHS;
-          }
-
-          startDateHS  = timeFormatterHS.format(startDate).split(":")[0]+":"+timeFormatterHS.format(startDate).split(":")[1]
-          timeHSStart = document.getElementsByClassName("start-time");
-          for (let i = 0; i < timeHSStart.length; i++) {
-            timeHSStart.item(i).value = startDateHS;
-          }
-          
-
-          <\/script>`,button:"Ok",success:function(){console.log("done")}})}function y(t){const e=i("#challenge-create-options-quick").serializeJSON();if(delete e.challenge_id,delete e.flag_type,e.type!="flash")delete e.startTime,delete e.endTime;else if(e.category="D\xE9fi Flash",e.startTime>=e.endTime)return p({title:"P\xE9riode de temps invalide",body:"Veuillez choisir une p\xE9riode de temps valide",button:"Ok"}),!1;e.description="",m.fetch("/api/v1/challenges",{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(e)}).then(function(a){return console.log("hello2"),a.json()}).then(function(a){if(a.success){if(a.data.type=="manualRecursive"){const l={value:"R\xE9cursif",challenge:a.data.id};m.api.post_tag_list({},l).then(r=>{})}if(a.data.type=="flash"){const l={value:"Flash",challenge:a.data.id};m.api.post_tag_list({},l).then(r=>{})}setTimeout(function(){window.location.reload(!0)},500)}else{let l="";for(const r in a.errors)l+=a.errors[r].join(`
-`),l+=`
-`;p({title:"Erreur",body:l,button:"Ok"})}})}document.getElementById("submit-button").addEventListener("click",function(t){t.preventDefault(),y()}),document.getElementById("challenge-create-options-quick-selector").addEventListener("keypress",function(t){t.key==="Enter"&&(t.preventDefault(),y())}),document.getElementById("challenge-type").addEventListener("change",function(t){D()}),document.getElementById("time-selector-input").addEventListener("click",function(t){t.preventDefault(),b()})});function M(g){let o=i("input[data-challenge-id]:checked").map(function(){return i(this).data("challenge-id")}),d=o.length===1?"challenge":"challenges";S({title:"Supprimer un d\xE9fi",body:`\xCAtes-vous certain de vouloir supprimer ${o.length} ${d}?`,success:function(){const s=[];for(var n of o)s.push(m.fetch(`/api/v1/challenges/${n}`,{method:"DELETE"}));Promise.all(s).then(u=>{window.location.reload()})}})}function I(g){let o=i("input[data-challenge-id]:checked").map(function(){return i(this).data("challenge-id")});p({title:"Modifier un d\xE9fi",body:i(`
-    <form id="challenges-bulk-edit">
-      <div class="form-group">
-        <label>Cat\xE9gorie</label>
-        <input type="text" name="category" data-initial="" value="">
-      </div>
-      <div class="form-group">
-        <label>Valeur</label>
-        <input type="number" name="value" data-initial="" value="">
-      </div>
-      <div class="form-group">
-        <label>State</label>
-        <select name="state" data-initial="">
-          <option value="">--</option>
-          <option value="visible">Visible</option>
-          <option value="hidden">Cach\xE9</option>
-        </select>
-      </div>
-      <div class="form-group">
-        <label>Type</label>
-        <select name="type" data-initial="">
-          <option value="">--</option>
-          <option value="standard">Standard</option>
-          <option value="manual">Manuel</option>
-          <option value="manualRecursive">Manuel R\xE9cursif</option>
-        </select>
-      </div>
-    </form>
-    `),button:"Soumettre",success:function(){let d=i("#challenges-bulk-edit").serializeJSON(!0);const s=[];for(var n of o)s.push(m.fetch(`/api/v1/challenges/${n}`,{method:"PATCH",body:JSON.stringify(d)}));Promise.all(s).then(u=>{window.location.reload()})}})}i(()=>{i("#challenges-delete-button").click(M),i("#challenges-edit-button").click(I)});
diff --git a/CTFd/themes/admin/static/assets/pages/challenges.e190ff8d.js b/CTFd/themes/admin/static/assets/pages/challenges.e190ff8d.js
new file mode 100644
index 0000000000000000000000000000000000000000..85ff2dd04179851563fc04870803c114ed213afd
--- /dev/null
+++ b/CTFd/themes/admin/static/assets/pages/challenges.e190ff8d.js
@@ -0,0 +1,184 @@
+import{s as w,C as m,$ as i,B as f,u as I}from"./main.71d0edc5.js";document.addEventListener("DOMContentLoaded",function(g){document.getElementById("btn-file-input").addEventListener("click",function(e){document.getElementById("thumbsnail-get-path").click()}),document.getElementById("thumbsnail-get-path").addEventListener("change",function(e){const t=e.target.files[0];let n=document.getElementById("thumbsnail-upload-form");const o=new FormData(n);if(o.append("file",t),w.files.upload(o,n,function(r){const p=r.data[0],c=m.config.urlRoot+"/files/"+p.location;document.getElementById("thumbsnail-path").value=c,console.log("Miniature t\xE9l\xE9charg\xE9e avec succ\xE8s:",c);const y=document.getElementById("image-preview");y.src=c,y.style.display="block"}),t){const r=new FileReader;r.onload=function(p){const c=document.getElementById("image-preview");c.src=p.target.result,c.style.display="block"},r.readAsDataURL(t)}});const l=Object.keys(document.categories),s=document.getElementById("categories-selector");l.forEach(e=>{const t=document.createElement("option");t.value=e,t.textContent=e,t.textContent!="D\xE9fi Flash"&&s.appendChild(t)});const d=document.createElement("option");d.value="other",d.textContent="Other (type below)",s.appendChild(d);const a=document.getElementById("categories-selector-input");s.value=="other"||l.length==0?(a.style.display="block",a.name="category"):(a.style.display="none",a.value="",a.name=""),s.addEventListener("change",function(){s.value=="other"||l.length==0?(a.style.display="block",a.name="category"):(a.style.display="none",a.value="",a.name="")});let u=0;document.querySelectorAll("td.id").forEach(function(e){const t=parseInt(e.textContent);!isNaN(t)&&t>u&&(u=t)});const h=u+1;document.getElementById("challenge_id_texte").textContent=h,document.getElementById("challenge_id").value=h;function b(){const e=i("#challenge-create-options-quick").serializeJSON();let t=document.getElementById("categories-selector"),n=document.getElementById("categories-selector-input"),o=document.getElementById("time-selector-input");t.hidden&&e.type!="flash"?(o.hidden=!0,n.hidden=!1,t.hidden=!1):!t.hidden&&e.type=="flash"&&(o.hidden=!1,n.hidden=!0,t.hidden=!0)}function D(){const e=i("#challenge-create-options-quick").serializeJSON();let t=document.getElementById("value-input"),n=document.getElementById("sport-config-button");e.type=="sport"?(t.hidden=!0,n.hidden=!1):(t.hidden=!1,n.hidden=!0)}function E(){let e=document.getElementById("unit-input-config"),t=document.getElementById("max-points-input-config"),n=document.getElementById("value-input-config"),o=document.getElementById("value-input"),r=document.getElementById("unit-preview"),p=document.getElementById("max-points-preview");console.log(e.value),o.value=n.value,r.value=e.value,p.value=t.value}window.processSportConfig=E;function x(){f({title:"Choisir P\xE9riode",body:`<div class="mb-3" style="text-align: center;">
+              <label>D\xE9but</label>
+              <div class="row" style="justify-content: space-around;">
+              
+                  <div class="col-md-4" >
+                      <label>Date</label>
+                      <input required class="form-control start-date" id="start-date" type="date" placeholder="yyyy-mm-dd"  onchange="processDateTime('start')" />
+                  </div>
+                  <div class="col-md-4">
+                      <label>Temps</label>
+                      <input required class="form-control start-time" id="start-time" type="time" placeholder="hh:mm" data-preview="#start" onchange="processDateTime('start')"/>
+                  </div>
+                
+              </div>
+              <small class="form-text text-muted">
+                
+              </small>
+          </div>
+
+          <div class="mb-3" style="text-align: center;">
+              <label>Fin</label>
+              <div class="row" style="justify-content: space-around;">
+                  
+                  <div class="col-md-4">
+                      <label>Date</label>
+                      <input required class="form-control end-date" id="end-date" type="date" placeholder="yyyy-mm-dd" data-preview="#end" onchange="processDateTime('end')"/>
+                  </div>
+                  <div class="col-md-4">
+                      <label>Temps</label>
+                      <input required class="form-control end-time" id="end-time" type="time" placeholder="hh:mm" data-preview="#end" onchange="processDateTime('end')"/>
+                  </div>
+                  
+              </div>
+          
+          </div>
+          <script>
+          endDate = new Date(document.getElementById("end-preview").value * 1000);
+          startDate = new Date(document.getElementById("start-preview").value * 1000);
+
+          //faut remodeler le time formater pour avoir YYYY-MM-JJ
+          timeFormatterYMD = new Intl.DateTimeFormat("en-US");
+          endDateYMDNotformated = timeFormatterYMD .format(endDate);
+          endDateYMD = endDateYMDNotformated.split("/")[2]+"-"+(endDateYMDNotformated.split("/")[0].length < 2 ? "0"+endDateYMDNotformated.split("/")[0]: endDateYMDNotformated.split("/")[0])
+          +"-"+(endDateYMDNotformated.split("/")[1].length < 2 ? "0"+endDateYMDNotformated.split("/")[1]: endDateYMDNotformated.split("/")[1]);
+          timeDateEnd = document.getElementsByClassName("end-date");
+          for (let i = 0; i < timeDateEnd.length; i++) {
+            timeDateEnd.item(i).value = endDateYMD;
+          }
+
+
+          startDateYMDNotformated = timeFormatterYMD .format(startDate);
+          startDateYMD = startDateYMDNotformated.split("/")[2]+"-"+(startDateYMDNotformated.split("/")[0].length < 2 ? "0"+startDateYMDNotformated.split("/")[0]: startDateYMDNotformated.split("/")[0])
+          +"-"+(startDateYMDNotformated.split("/")[1].length < 2 ? "0"+startDateYMDNotformated.split("/")[1]: startDateYMDNotformated.split("/")[1]);
+          timeDateStart = document.getElementsByClassName("start-date");
+          for (let i = 0; i < timeDateStart.length; i++) {
+            timeDateStart.item(i).value = startDateYMD;
+          }
+
+          timeFormatterHS = new Intl.DateTimeFormat(undefined, { timeStyle: 'medium' });
+          console.log(timeFormatterHS.format(endDate))
+          endDateHS = timeFormatterHS.format(endDate).split(":")[0]+":"+timeFormatterHS.format(endDate).split(":")[1]
+          timeHSEnd = document.getElementsByClassName("end-time");
+          for (let i = 0; i < timeHSEnd.length; i++) {
+            timeHSEnd.item(i).value = endDateHS;
+          }
+
+          startDateHS  = timeFormatterHS.format(startDate).split(":")[0]+":"+timeFormatterHS.format(startDate).split(":")[1]
+          timeHSStart = document.getElementsByClassName("start-time");
+          for (let i = 0; i < timeHSStart.length; i++) {
+            timeHSStart.item(i).value = startDateHS;
+          }
+          
+
+          <\/script>`,button:"Ok",success:function(){console.log("done")}})}function S(){f({title:"Configurer le d\xE9fi Sportif",body:`<div class="tab-pane" id="challenge-points" role="tabpanel">
+                <div class="mb-3">
+                    <div class="row center">
+                        <div class="col-md-6">
+                            <label>Unit\xE9</label>
+                            <input required class="form-control" id="unit-input-config" type="text" placeholder="Entrez l'unit\xE9" value="km" onchange="processSportConfig()">
+                        </div>
+                        <div class="col-md-6">
+                            <label>Points maximum</label>
+                            <input required class="form-control" id="max-points-input-config" type="number" placeholder="Entrez le nombre de points maximum (0 pour infini)" value="1" min="1" onchange="processSportConfig()">
+                        </div>
+                        <div class="col-md-6">
+                            <label>Points par Unit\xE9</label>
+                            <input type="number" class="form-control chal-value" id="value-input-config" value="1" onchange="processSportConfig()" min="1" required>
+                        </div>
+                        <div class="col-md-6">
+                            <label>
+                                <span>Informations</span> 
+                                <span class="info-icon">\u2139
+                                    <span class="tooltip-text">
+                                        <p>Par exemple, un d\xE9fi avec "km" comme unit\xE9, "100" comme points maximum et "5" pour points par unit\xE9 donnera 5 points pour chaque km parcouru.</p>
+                                        <p>Le nombre de points maximum est pour l'\xE9quipe au complet.</p>
+                                    </span>
+                                </span>
+                            </label>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <style>
+                  .center {
+                    align-items: center;
+                    justify-content: center;
+                  }
+                  .info-icon {
+                    position: relative;
+                    cursor: pointer;
+                    font-style: normal;
+                    font-size: 1.2em;
+                    font-weight: bold;
+                    display: inline-flex;
+                    align-items: center;
+                    justify-content: center;
+                    width: 24px;
+                    height: 24px;
+                    border: 2px solid #333;
+                    border-radius: 50%;
+                    color: #333;
+                    text-align: center;
+                    margin-left: 10px;
+                  }
+
+                  .info-icon .tooltip-text {
+                      visibility: hidden;
+                      width: 300px; /* Fixed width instead of percentage */
+                      max-width: 500px;
+                      background-color: rgba(0, 0, 0, 0.8);
+                      color: #fff;
+                      text-align: center;
+                      padding: 15px;
+                      border-radius: 10px;
+                      position: absolute;
+                      top: 50%;
+                      left: 50%;
+                      transform: translate(-50%, -50%);
+                      opacity: 0;
+                      transition: opacity 0.3s ease-in-out;
+                      z-index: 9999;
+                      box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
+                      white-space: normal; /* Ensure text wraps properly */
+                  }
+
+                  .info-icon:hover .tooltip-text {
+                    visibility: visible;
+                    opacity: 1;
+                  }
+
+                  .tooltip-text p {
+                    margin-bottom: 15px;
+                  }
+            </style>`,button:"Ok",success:function(){console.log("done")}})}function v(){const e=i("#challenge-create-options-quick").serializeJSON();if(delete e.challenge_id,delete e.flag_type,e.type!=="sport"&&(delete e.unit,delete e.max_points),e.type!="flash")delete e.startTime,delete e.endTime;else if(e.category="D\xE9fi Flash",e.startTime>=e.endTime)return f({title:"P\xE9riode de temps invalide",body:"Veuillez choisir une p\xE9riode de temps valide",button:"Ok"}),!1;e.description="",m.fetch("/api/v1/challenges",{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(e)}).then(function(t){return console.log("hello2"),t.json()}).then(function(t){if(t.success){if(t.data.type=="manualRecursive"){const n={value:"R\xE9cursif",challenge:t.data.id};m.api.post_tag_list({},n).then(o=>{})}if(t.data.type=="flash"){const n={value:"Flash",challenge:t.data.id};m.api.post_tag_list({},n).then(o=>{})}setTimeout(function(){window.location.reload(!0)},400)}else{let n="";for(const o in t.errors)n+=t.errors[o].join(`
+`),n+=`
+`;f({title:"Erreur",body:n,button:"Ok"})}})}document.getElementById("submit-button").addEventListener("click",function(e){e.preventDefault(),v()}),document.getElementById("challenge-create-options-quick-selector").addEventListener("keypress",function(e){e.key==="Enter"&&(e.preventDefault(),v())}),document.getElementById("challenge-type").addEventListener("change",function(e){b(),D()}),document.getElementById("time-selector-input").addEventListener("click",function(e){e.preventDefault(),x()}),document.getElementById("sport-config-button").addEventListener("click",function(e){e.preventDefault(),S()})});function B(g){let l=i("input[data-challenge-id]:checked").map(function(){return i(this).data("challenge-id")}),s=l.length===1?"challenge":"challenges";I({title:"Supprimer un d\xE9fi",body:`\xCAtes-vous certain de vouloir supprimer ${l.length} ${s}?`,success:function(){const d=[];for(var a of l)d.push(m.fetch(`/api/v1/challenges/${a}`,{method:"DELETE"}));Promise.all(d).then(u=>{window.location.reload()})}})}function k(g){let l=i("input[data-challenge-id]:checked").map(function(){return i(this).data("challenge-id")});f({title:"Modifier un d\xE9fi",body:i(`
+    <form id="challenges-bulk-edit">
+      <div class="form-group">
+        <label>Cat\xE9gorie</label>
+        <input type="text" name="category" data-initial="" value="">
+      </div>
+      <div class="form-group">
+        <label>Valeur</label>
+        <input type="number" name="value" data-initial="" value="">
+      </div>
+      <div class="form-group">
+        <label>State</label>
+        <select name="state" data-initial="">
+          <option value="">--</option>
+          <option value="visible">Visible</option>
+          <option value="hidden">Cach\xE9</option>
+        </select>
+      </div>
+      <div class="form-group">
+        <label>Type</label>
+        <select name="type" data-initial="">
+          <option value="">--</option>
+          <option value="standard">Standard</option>
+          <option value="manual">Manuel</option>
+          <option value="manualRecursive">Manuel R\xE9cursif</option>
+        </select>
+      </div>
+    </form>
+    `),button:"Soumettre",success:function(){let s=i("#challenges-bulk-edit").serializeJSON(!0);const d=[];for(var a of l)d.push(m.fetch(`/api/v1/challenges/${a}`,{method:"PATCH",body:JSON.stringify(s)}));Promise.all(d).then(u=>{window.location.reload()})}})}i(()=>{i("#challenges-delete-button").click(B),i("#challenges-edit-button").click(k)});
diff --git a/CTFd/themes/admin/static/manifest.json b/CTFd/themes/admin/static/manifest.json
index 1405b0e6e7d6930178e6ad5fd5a23d90de63ccc8..1807147b260a8c3178d9e2b63820f004aad620e6 100644
--- a/CTFd/themes/admin/static/manifest.json
+++ b/CTFd/themes/admin/static/manifest.json
@@ -18,7 +18,7 @@
     ]
   },
   "assets/js/pages/challenges.js": {
-    "file": "assets/pages/challenges.a6549073.js",
+    "file": "assets/pages/challenges.e190ff8d.js",
     "src": "assets/js/pages/challenges.js",
     "isEntry": true,
     "imports": [
@@ -138,14 +138,14 @@
   "_echarts.7b83cee2.js": {
     "file": "assets/echarts.7b83cee2.js"
   },
-  "_tab.facb6ef1.js": {
-    "file": "assets/tab.facb6ef1.js",
+  "_tab.21ccc1b9.js": {
+    "file": "assets/tab.21ccc1b9.js",
     "imports": [
       "assets/js/pages/main.js"
     ]
   },
-  "_CommentBox.f5ce8d13.js": {
-    "file": "assets/CommentBox.f5ce8d13.js",
+  "_CommentBox.0d8a3850.js": {
+    "file": "assets/CommentBox.0d8a3850.js",
     "imports": [
       "assets/js/pages/main.js"
     ],
@@ -153,29 +153,29 @@
       "assets/CommentBox.23213b39.css"
     ]
   },
-  "_htmlmixed.e85df030.js": {
-    "file": "assets/htmlmixed.e85df030.js",
+  "_htmlmixed.38cc7a65.js": {
+    "file": "assets/htmlmixed.38cc7a65.js",
     "imports": [
       "assets/js/pages/main.js"
     ]
   },
-  "_echarts.common.a0aaa3a0.js": {
-    "file": "assets/echarts.common.a0aaa3a0.js",
+  "_echarts.common.5eba8a0a.js": {
+    "file": "assets/echarts.common.5eba8a0a.js",
     "imports": [
       "assets/js/pages/main.js"
     ]
   },
-  "_visual.0867334a.js": {
-    "file": "assets/visual.0867334a.js",
+  "_visual.17795e29.js": {
+    "file": "assets/visual.17795e29.js",
     "imports": [
       "assets/js/pages/main.js"
     ]
   },
-  "_graphs.253aebe5.js": {
-    "file": "assets/graphs.253aebe5.js",
+  "_graphs.5c638a7f.js": {
+    "file": "assets/graphs.5c638a7f.js",
     "imports": [
       "assets/js/pages/main.js",
-      "_echarts.common.a0aaa3a0.js"
+      "_echarts.common.5eba8a0a.js"
     ]
   },
   "CommentBox.css": {
@@ -186,16 +186,16 @@
     "file": "assets/challenge.66ec3ebe.css",
     "src": "assets/js/pages/challenge.css"
   },
-  "assets/css/admin.scss": {
-    "file": "assets/admin.3594ea3f.css",
-    "src": "assets/css/admin.scss",
-    "isEntry": true
-  },
   "assets/css/challenge-board.scss": {
     "file": "assets/challenge-board.44e07e05.css",
     "src": "assets/css/challenge-board.scss",
     "isEntry": true
   },
+  "assets/css/admin.scss": {
+    "file": "assets/admin.3594ea3f.css",
+    "src": "assets/css/admin.scss",
+    "isEntry": true
+  },
   "assets/css/codemirror.scss": {
     "file": "assets/codemirror.d74a88bc.css",
     "src": "assets/css/codemirror.scss",
@@ -210,5 +210,51 @@
     "file": "assets/main.088f55c6.css",
     "src": "assets/css/main.scss",
     "isEntry": true
+  },
+  "_htmlmixed.5e629dd9.js": {
+    "file": "assets/htmlmixed.5e629dd9.js",
+    "imports": [
+      "assets/js/pages/main.js"
+    ]
+  },
+  "_tab.facb6ef1.js": {
+    "file": "assets/tab.facb6ef1.js",
+    "imports": [
+      "assets/js/pages/main.js"
+    ]
+  },
+  "_CommentBox.f5ce8d13.js": {
+    "file": "assets/CommentBox.f5ce8d13.js",
+    "imports": [
+      "assets/js/pages/main.js"
+    ],
+    "css": [
+      "assets/CommentBox.23213b39.css"
+    ]
+  },
+  "_htmlmixed.e85df030.js": {
+    "file": "assets/htmlmixed.e85df030.js",
+    "imports": [
+      "assets/js/pages/main.js"
+    ]
+  },
+  "_echarts.common.a0aaa3a0.js": {
+    "file": "assets/echarts.common.a0aaa3a0.js",
+    "imports": [
+      "assets/js/pages/main.js"
+    ]
+  },
+  "_visual.0867334a.js": {
+    "file": "assets/visual.0867334a.js",
+    "imports": [
+      "assets/js/pages/main.js"
+    ]
+  },
+  "_graphs.253aebe5.js": {
+    "file": "assets/graphs.253aebe5.js",
+    "imports": [
+      "assets/js/pages/main.js",
+      "_echarts.common.a0aaa3a0.js"
+    ]
   }
 }
\ No newline at end of file
diff --git a/CTFd/themes/admin/templates/challenges/challenges.html b/CTFd/themes/admin/templates/challenges/challenges.html
index 2f73b6bb364c2026327e83ad2e46dfe0a700f33e..636dd57f2beefe0fc060a90cea60759aedf86a53 100644
--- a/CTFd/themes/admin/templates/challenges/challenges.html
+++ b/CTFd/themes/admin/templates/challenges/challenges.html
@@ -66,7 +66,7 @@
 				<table id="challenges" class="table table-striped border">
 					<thead>
 					<tr>
-						<td class="d-block border-right border-bottom text-center" data-checkbox>
+						<td class="border-right border-bottom text-center" data-checkbox>
 							<div class="form-check">
 								<input type="checkbox" class="form-check-input" autocomplete="off" data-checkbox-all>&nbsp;
 							</div>
@@ -92,7 +92,7 @@
 							document.lastCategorie = "{{challenge.category}}";
 						</script>
 						<tr data-href="{{ url_for('admin.challenges_detail', challenge_id=challenge.id) }}">
-							<td class="d-block border-right text-center" data-checkbox>
+							<td class="border-right text-center" data-checkbox>
 								<div class="form-check">
 									<input type="checkbox" class="form-check-input" value="{{ challenge.id }}" autocomplete="off" data-challenge-id="{{ challenge.id }}">&nbsp;
 								</div>
@@ -138,7 +138,7 @@
 						</style>
 							<tr data-href="" id="challenge-create-options-quick-selector">
 								<form id="challenge-create-options-quick" method="POST">
-									<td class="d-block border-right text-center" data-checkbox>
+									<td class="border-right text-center" data-checkbox>
 										<div class="form-check">
 											<input type="checkbox" class="form-check-input" value="0" autocomplete="off" data-challenge-id="0">&nbsp;
 										</div>
@@ -159,9 +159,10 @@
 										
 									</td>
 									<td class="editable text-center" data-editable="value">
-										<input class="form-text-input" name="value" required></input>
+										<input class="form-text-input" name="value" id="value-input" required></input>
+										<button class="btn btn-secondary" id="sport-config-button" hidden>Configurer</button>
 									</td>
-									<td class="d-block editable" data-checkbox>
+									<td class="editable" data-checkbox>
 										<select class="form-control custom-select" id="categories-selector" name="category">
 											<!-- Existing categories will be dynamically added here by JavaScript -->
 										</select>
@@ -179,9 +180,11 @@
 									<input type="hidden" name="thumbsnail" id="thumbsnail-path" form="challenge-create-options-quick"></input>
 									<input type="number" class="form-control" name="startTime" id="start-preview" required hidden>
 									<input type="number" class="form-control" name="endTime" id="end-preview" required hidden>
+									<input type="text" class="form-control" name="unit" id="unit-preview" required hidden>
+									<input type="number" class="form-control" name="max_points" id="max-points-preview" required hidden>
 								</form>
 								<form id="thumbsnail-upload-form" class="form-upload" method="POST" enctype="multipart/form-data">
-									<td class="editable" data-editable="thumbsnail" style="display: flex; justify-content: center; flex-wrap: wrap; align-items: center;">
+									<td class="editable" data-editable="thumbsnail">
 										<button id="btn-file-input" class="btn btn-secondary" type="button">Sélectionner un fichier</button>
 										<img id="image-preview" style="display: none; width: 100px; height: 100px; margin-top: 10px;">
 									</td>
diff --git a/CTFd/themes/admin/templates/challenges/update.html b/CTFd/themes/admin/templates/challenges/update.html
index 9400ddbc5a36628d3aefb988f004482cb12a08f7..0a8ffe5f789bdcafc647c10b609453f0719f2837 100644
--- a/CTFd/themes/admin/templates/challenges/update.html
+++ b/CTFd/themes/admin/templates/challenges/update.html
@@ -39,18 +39,6 @@
 	</div>
 	{% endblock %}
 
-	{% block connection_info %}
-	<div class="form-group">
-		<label>
-			Informations sur la connexion<br>
-			<small class="form-text text-muted">
-				Utilisez-le pour spécifier un lien, un nom d'hôte ou des instructions de connexion pour votre défi.
-			</small>
-		</label>
-		<input type="text" class="form-control chal-connection-info" name="connection_info" value="{{ challenge.connection_info | default('', true) }}">
-	</div>
-	{% endblock %}
-
 	{% if challenge.type != "sport" %}
 		{% block value %}
 		<div class="form-group">
@@ -63,19 +51,28 @@
 			<input type="number" class="form-control chal-value" name="value" value="{{ challenge.value }}" required>
 		</div>
 		{% endblock %}
+		{% block max_attempts %}
+		<div class="form-group">
+			<label>
+				Tentatives maximales<br>
+				<small class="form-text text-muted">Montant maximum de tentatives que les utilisateurs reçoivent. Laisser à 0 pour illimité.</small>
+			</label>
+	
+			<input type="number" class="form-control chal-attempts" name="max_attempts" value="{{ challenge.max_attempts }}">
+		</div>
+		{% endblock %}
+	{% else %}
+		<div class="form-group">
+			<label for="value">
+				Points par Unité (Value)<br>
+				<small class="form-text text-muted">
+					C'est le nombre de points que les équipes recevront par Unité.
+				</small>
+			</label>
+			<input type="number" class="form-control chal-value" name="value" value="{{ challenge.value }}" required>
+		</div>
 	{% endif %}
 
-	{% block max_attempts %}
-	<div class="form-group">
-		<label>
-			Tentatives maximales<br>
-			<small class="form-text text-muted">Montant maximum de tentatives que les utilisateurs reçoivent. Laisser à 0 pour illimité.</small>
-		</label>
-
-		<input type="number" class="form-control chal-attempts" name="max_attempts" value="{{ challenge.max_attempts }}">
-	</div>
-	{% endblock %}
-
 	{% block state %}
 	<div class="form-group">
 		<label>
diff --git a/serve.py b/serve.py
index 251a26653555c90849aadaf73b541db254b325ec..e43566a5ec65cea7763e81fff8fdc8a5cac212bc 100644
--- a/serve.py
+++ b/serve.py
@@ -1,7 +1,7 @@
 import argparse
 
 parser = argparse.ArgumentParser()
-parser.add_argument("--port", help="Port for debug server to listen on", default=8080)
+parser.add_argument("--port", help="Port for debug server to listen on", default=8001)
 parser.add_argument(
     "--profile", help="Enable flask_profiler profiling", action="store_true"
 )
@@ -38,6 +38,6 @@ if args.profile:
 
     toolbar = DebugToolbarExtension()
     toolbar.init_app(app)
-    print(" * Flask profiling running at http://0.0.0.0:8000/flask-profiler/")
+    print(" * Flask profiling running at http://0.0.0.0:8001/flask-profiler/")
 
 app.run(debug=True, threaded=True, host="0.0.0.0", port=args.port)