diff --git a/CTFd/themes/core/assets/css/includes/utils/min-height.scss b/CTFd/themes/core/assets/css/includes/utils/min-height.scss
new file mode 100644
index 0000000..b2e8c36
--- /dev/null
+++ b/CTFd/themes/core/assets/css/includes/utils/min-height.scss
@@ -0,0 +1,5 @@
+.min-vh-0 { min-height: 0vh !important; }
+.min-vh-25 { min-height: 25vh !important; }
+.min-vh-50 { min-height: 50vh !important; }
+.min-vh-75 { min-height: 75vh !important; }
+.min-vh-100 { min-height: 100vh !important; }
\ No newline at end of file
diff --git a/CTFd/themes/core/assets/css/includes/utils/opacity.scss b/CTFd/themes/core/assets/css/includes/utils/opacity.scss
new file mode 100644
index 0000000..7763e27
--- /dev/null
+++ b/CTFd/themes/core/assets/css/includes/utils/opacity.scss
@@ -0,0 +1,15 @@
+.opacity-0 {
+ opacity: 0 !important;
+}
+.opacity-25 {
+ opacity: 0.25 !important;
+}
+.opacity-50 {
+ opacity: 0.5 !important;
+}
+.opacity-75 {
+ opacity: 0.75 !important;
+}
+.opacity-100 {
+ opacity: 1 !important;
+}
diff --git a/CTFd/themes/core/assets/css/main.scss b/CTFd/themes/core/assets/css/main.scss
index ae92c06..7c4d532 100644
--- a/CTFd/themes/core/assets/css/main.scss
+++ b/CTFd/themes/core/assets/css/main.scss
@@ -3,6 +3,8 @@
@import "includes/sticky-footer.css";
@import "includes/award-icons.scss";
@import "includes/flag-icons.scss";
+@import "includes/utils/opacity.scss";
+@import "includes/utils/min-height.scss";
html,
body,
diff --git a/CTFd/themes/core/assets/js/pages/scoreboard.js b/CTFd/themes/core/assets/js/pages/scoreboard.js
index 1324506..e826c44 100644
--- a/CTFd/themes/core/assets/js/pages/scoreboard.js
+++ b/CTFd/themes/core/assets/js/pages/scoreboard.js
@@ -65,7 +65,7 @@ const createGraph = () => {
if (teams.length === 0) {
// Replace spinner
graph.html(
- '
No solves yet
'
+ '
No solves yet
'
);
return;
}
diff --git a/CTFd/themes/core/static/css/main.dev.css b/CTFd/themes/core/static/css/main.dev.css
index 6db9e2d..e5951d4 100644
--- a/CTFd/themes/core/static/css/main.dev.css
+++ b/CTFd/themes/core/static/css/main.dev.css
@@ -9,5 +9,5 @@ body{padding-top:3.5rem}
html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:1px;width:100%;height:60px;line-height:60px;z-index:-20}
-.award-icon{font-family:"Font Awesome 5 Free", "Font Awesome 5 Free Offline";font-weight:900;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.award-shield:before{content:"\f3ed"}.award-bug:before{content:"\f188"}.award-crown:before{content:"\f521"}.award-crosshairs:before{content:"\f05b"}.award-ban:before{content:"\f05e"}.award-lightning:before{content:"\f0e7"}.award-code:before{content:"\f121"}.award-cowboy:before{content:"\f8c0"}.award-angry:before{content:"\f556"}[class^="flag-"]{font-style:normal}.flag-ad:before{content:"🇦🇩"}.flag-ae:before{content:"🇦🇪"}.flag-af:before{content:"🇦🇫"}.flag-ag:before{content:"🇦🇬"}.flag-ai:before{content:"🇦🇮"}.flag-al:before{content:"🇦🇱"}.flag-am:before{content:"🇦🇲"}.flag-ao:before{content:"🇦🇴"}.flag-aq:before{content:"🇦🇶"}.flag-ar:before{content:"🇦🇷"}.flag-as:before{content:"🇦🇸"}.flag-at:before{content:"🇦🇹"}.flag-au:before{content:"🇦🇺"}.flag-aw:before{content:"🇦🇼"}.flag-ax:before{content:"🇦🇽"}.flag-az:before{content:"🇦🇿"}.flag-ba:before{content:"🇧🇦"}.flag-bb:before{content:"🇧🇧"}.flag-bd:before{content:"🇧🇩"}.flag-be:before{content:"🇧🇪"}.flag-bf:before{content:"🇧🇫"}.flag-bg:before{content:"🇧🇬"}.flag-bh:before{content:"🇧🇭"}.flag-bi:before{content:"🇧🇮"}.flag-bj:before{content:"🇧🇯"}.flag-bl:before{content:"🇧🇱"}.flag-bm:before{content:"🇧🇲"}.flag-bn:before{content:"🇧🇳"}.flag-bo:before{content:"🇧🇴"}.flag-bq:before{content:"🇧🇶"}.flag-br:before{content:"🇧🇷"}.flag-bs:before{content:"🇧🇸"}.flag-bt:before{content:"🇧🇹"}.flag-bv:before{content:"🇧🇻"}.flag-bw:before{content:"🇧🇼"}.flag-by:before{content:"🇧🇾"}.flag-bz:before{content:"🇧🇿"}.flag-ca:before{content:"🇨🇦"}.flag-cc:before{content:"🇨🇨"}.flag-cd:before{content:"🇨🇩"}.flag-cf:before{content:"🇨🇫"}.flag-cg:before{content:"🇨🇬"}.flag-ch:before{content:"🇨🇭"}.flag-ci:before{content:"🇨🇮"}.flag-ck:before{content:"🇨🇰"}.flag-cl:before{content:"🇨🇱"}.flag-cm:before{content:"🇨🇲"}.flag-cn:before{content:"🇨🇳"}.flag-co:before{content:"🇨🇴"}.flag-cr:before{content:"🇨🇷"}.flag-cu:before{content:"🇨🇺"}.flag-cv:before{content:"🇨🇻"}.flag-cw:before{content:"🇨🇼"}.flag-cx:before{content:"🇨🇽"}.flag-cy:before{content:"🇨🇾"}.flag-cz:before{content:"🇨🇿"}.flag-de:before{content:"🇩🇪"}.flag-dj:before{content:"🇩🇯"}.flag-dk:before{content:"🇩🇰"}.flag-dm:before{content:"🇩🇲"}.flag-do:before{content:"🇩🇴"}.flag-dz:before{content:"🇩🇿"}.flag-ec:before{content:"🇪🇨"}.flag-ee:before{content:"🇪🇪"}.flag-eg:before{content:"🇪🇬"}.flag-eh:before{content:"🇪🇭"}.flag-er:before{content:"🇪🇷"}.flag-es:before{content:"🇪🇸"}.flag-et:before{content:"🇪🇹"}.flag-fi:before{content:"🇫🇮"}.flag-fj:before{content:"🇫🇯"}.flag-fk:before{content:"🇫🇰"}.flag-fm:before{content:"🇫🇲"}.flag-fo:before{content:"🇫🇴"}.flag-fr:before{content:"🇫🇷"}.flag-ga:before{content:"🇬🇦"}.flag-gb:before{content:"🇬🇧"}.flag-gd:before{content:"🇬🇩"}.flag-ge:before{content:"🇬🇪"}.flag-gf:before{content:"🇬🇫"}.flag-gg:before{content:"🇬🇬"}.flag-gh:before{content:"🇬🇭"}.flag-gi:before{content:"🇬🇮"}.flag-gl:before{content:"🇬🇱"}.flag-gm:before{content:"🇬🇲"}.flag-gn:before{content:"🇬🇳"}.flag-gp:before{content:"🇬🇵"}.flag-gq:before{content:"🇬🇶"}.flag-gr:before{content:"🇬🇷"}.flag-gs:before{content:"🇬🇸"}.flag-gt:before{content:"🇬🇹"}.flag-gu:before{content:"🇬🇺"}.flag-gw:before{content:"🇬🇼"}.flag-gy:before{content:"🇬🇾"}.flag-hk:before{content:"🇭🇰"}.flag-hm:before{content:"🇭🇲"}.flag-hn:before{content:"🇭🇳"}.flag-hr:before{content:"🇭🇷"}.flag-ht:before{content:"🇭🇹"}.flag-hu:before{content:"🇭🇺"}.flag-id:before{content:"🇮🇩"}.flag-ie:before{content:"🇮🇪"}.flag-il:before{content:"🇮🇱"}.flag-im:before{content:"🇮🇲"}.flag-in:before{content:"🇮🇳"}.flag-io:before{content:"🇮🇴"}.flag-iq:before{content:"🇮🇶"}.flag-ir:before{content:"🇮🇷"}.flag-is:before{content:"🇮🇸"}.flag-it:before{content:"🇮🇹"}.flag-je:before{content:"🇯🇪"}.flag-jm:before{content:"🇯🇲"}.flag-jo:before{content:"🇯🇴"}.flag-jp:before{content:"🇯🇵"}.flag-ke:before{content:"🇰🇪"}.flag-kg:before{content:"🇰🇬"}.flag-kh:before{content:"🇰🇭"}.flag-ki:before{content:"🇰🇮"}.flag-km:before{content:"🇰🇲"}.flag-kn:before{content:"🇰🇳"}.flag-kp:before{content:"🇰🇵"}.flag-kr:before{content:"🇰🇷"}.flag-kw:before{content:"🇰🇼"}.flag-ky:before{content:"🇰🇾"}.flag-kz:before{content:"🇰🇿"}.flag-la:before{content:"🇱🇦"}.flag-lb:before{content:"🇱🇧"}.flag-lc:before{content:"🇱🇨"}.flag-li:before{content:"🇱🇮"}.flag-lk:before{content:"🇱🇰"}.flag-lr:before{content:"🇱🇷"}.flag-ls:before{content:"🇱🇸"}.flag-lt:before{content:"🇱🇹"}.flag-lu:before{content:"🇱🇺"}.flag-lv:before{content:"🇱🇻"}.flag-ly:before{content:"🇱🇾"}.flag-ma:before{content:"🇲🇦"}.flag-mc:before{content:"🇲🇨"}.flag-md:before{content:"🇲🇩"}.flag-me:before{content:"🇲🇪"}.flag-mf:before{content:"🇲🇫"}.flag-mg:before{content:"🇲🇬"}.flag-mh:before{content:"🇲🇭"}.flag-mk:before{content:"🇲🇰"}.flag-ml:before{content:"🇲🇱"}.flag-mm:before{content:"🇲🇲"}.flag-mn:before{content:"🇲🇳"}.flag-mo:before{content:"🇲🇴"}.flag-mp:before{content:"🇲🇵"}.flag-mq:before{content:"🇲🇶"}.flag-mr:before{content:"🇲🇷"}.flag-ms:before{content:"🇲🇸"}.flag-mt:before{content:"🇲🇹"}.flag-mu:before{content:"🇲🇺"}.flag-mv:before{content:"🇲🇻"}.flag-mw:before{content:"🇲🇼"}.flag-mx:before{content:"🇲🇽"}.flag-my:before{content:"🇲🇾"}.flag-mz:before{content:"🇲🇿"}.flag-na:before{content:"🇳🇦"}.flag-nc:before{content:"🇳🇨"}.flag-ne:before{content:"🇳🇪"}.flag-nf:before{content:"🇳🇫"}.flag-ng:before{content:"🇳🇬"}.flag-ni:before{content:"🇳🇮"}.flag-nl:before{content:"🇳🇱"}.flag-no:before{content:"🇳🇴"}.flag-np:before{content:"🇳🇵"}.flag-nr:before{content:"🇳🇷"}.flag-nu:before{content:"🇳🇺"}.flag-nz:before{content:"🇳🇿"}.flag-om:before{content:"🇴🇲"}.flag-pa:before{content:"🇵🇦"}.flag-pe:before{content:"🇵🇪"}.flag-pf:before{content:"🇵🇫"}.flag-pg:before{content:"🇵🇬"}.flag-ph:before{content:"🇵🇭"}.flag-pk:before{content:"🇵🇰"}.flag-pl:before{content:"🇵🇱"}.flag-pm:before{content:"🇵🇲"}.flag-pn:before{content:"🇵🇳"}.flag-pr:before{content:"🇵🇷"}.flag-ps:before{content:"🇵🇸"}.flag-pt:before{content:"🇵🇹"}.flag-pw:before{content:"🇵🇼"}.flag-py:before{content:"🇵🇾"}.flag-qa:before{content:"🇶🇦"}.flag-re:before{content:"🇷🇪"}.flag-ro:before{content:"🇷🇴"}.flag-rs:before{content:"🇷🇸"}.flag-ru:before{content:"🇷🇺"}.flag-rw:before{content:"🇷🇼"}.flag-sa:before{content:"🇸🇦"}.flag-sb:before{content:"🇸🇧"}.flag-sc:before{content:"🇸🇨"}.flag-sd:before{content:"🇸🇩"}.flag-se:before{content:"🇸🇪"}.flag-sg:before{content:"🇸🇬"}.flag-sh:before{content:"🇸🇭"}.flag-si:before{content:"🇸🇮"}.flag-sj:before{content:"🇸🇯"}.flag-sk:before{content:"🇸🇰"}.flag-sl:before{content:"🇸🇱"}.flag-sm:before{content:"🇸🇲"}.flag-sn:before{content:"🇸🇳"}.flag-so:before{content:"🇸🇴"}.flag-sr:before{content:"🇸🇷"}.flag-ss:before{content:"🇸🇸"}.flag-st:before{content:"🇸🇹"}.flag-sv:before{content:"🇸🇻"}.flag-sx:before{content:"🇸🇽"}.flag-sy:before{content:"🇸🇾"}.flag-sz:before{content:"🇸🇿"}.flag-tc:before{content:"🇹🇨"}.flag-td:before{content:"🇹🇩"}.flag-tf:before{content:"🇹🇫"}.flag-tg:before{content:"🇹🇬"}.flag-th:before{content:"🇹🇭"}.flag-tj:before{content:"🇹🇯"}.flag-tk:before{content:"🇹🇰"}.flag-tl:before{content:"🇹🇱"}.flag-tm:before{content:"🇹🇲"}.flag-tn:before{content:"🇹🇳"}.flag-to:before{content:"🇹🇴"}.flag-tr:before{content:"🇹🇷"}.flag-tt:before{content:"🇹🇹"}.flag-tv:before{content:"🇹🇻"}.flag-tw:before{content:"🇹🇼"}.flag-tz:before{content:"🇹🇿"}.flag-ua:before{content:"🇺🇦"}.flag-ug:before{content:"🇺🇬"}.flag-um:before{content:"🇺🇲"}.flag-us:before{content:"🇺🇸"}.flag-uy:before{content:"🇺🇾"}.flag-uz:before{content:"🇺🇿"}.flag-va:before{content:"🇻🇦"}.flag-vc:before{content:"🇻🇨"}.flag-ve:before{content:"🇻🇪"}.flag-vg:before{content:"🇻🇬"}.flag-vi:before{content:"🇻🇮"}.flag-vn:before{content:"🇻🇳"}.flag-vu:before{content:"🇻🇺"}.flag-wf:before{content:"🇼🇫"}.flag-ws:before{content:"🇼🇸"}.flag-ye:before{content:"🇾🇪"}.flag-yt:before{content:"🇾🇹"}.flag-za:before{content:"🇿🇦"}.flag-zm:before{content:"🇿🇲"}.flag-zw:before{content:"🇿🇼"}html,body,.container{font-family:"Lato", "LatoOffline", sans-serif}h1,h2{font-family:"Raleway", "RalewayOffline", sans-serif;font-weight:500;letter-spacing:2px}a{color:#337ab7;text-decoration:none}table>thead>tr>td{border-top:none !important}.fa-spin.spinner{margin-top:225px;text-align:center;opacity:0.5}.spinner-error{padding-top:20vh;text-align:center;opacity:0.5}.jumbotron{border-radius:0;text-align:center}.form-control:focus{background-color:transparent;border-color:#a3d39c;box-shadow:0 0 0 0.2rem #a3d39c;transition:background-color 0.3s, border-color 0.3s}.input-filled-valid{background-color:transparent !important;border-color:#a3d39c;box-shadow:0 0 0 0.2rem #a3d39c;transition:background-color 0.3s, border-color 0.3s}.input-filled-invalid{background-color:transparent !important;border-color:#d46767;box-shadow:0 0 0 0.2rem #d46767;transition:background-color 0.3s, border-color 0.3s}.btn-outlined.btn-theme{background:none;color:#545454;border-color:#545454;border:3px solid}.btn-outlined{border-radius:0;-webkit-transition:all 0.3s;-moz-transition:all 0.3s;transition:all 0.3s}.btn{letter-spacing:1px;text-decoration:none;-moz-user-select:none;border-radius:0;cursor:pointer;display:inline-block;margin-bottom:0;vertical-align:middle;white-space:nowrap;font-size:14px;line-height:20px;font-weight:700;padding:8px 20px}.btn-info{background-color:#5b7290 !important;border-color:#5b7290 !important}.badge-info{background-color:#5b7290 !important}.alert{border-radius:0 !important;padding:0.8em}.btn-fa{cursor:pointer}.close{cursor:pointer}.cursor-pointer{cursor:pointer}.cursor-help{cursor:help}.modal-content{-webkit-border-radius:0 !important;-moz-border-radius:0 !important;border-radius:0 !important}.fa-disabled{opacity:0.5;cursor:not-allowed}.badge-notification{vertical-align:top;margin-left:-1.5em;font-size:50%}
+.award-icon{font-family:"Font Awesome 5 Free", "Font Awesome 5 Free Offline";font-weight:900;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.award-shield:before{content:"\f3ed"}.award-bug:before{content:"\f188"}.award-crown:before{content:"\f521"}.award-crosshairs:before{content:"\f05b"}.award-ban:before{content:"\f05e"}.award-lightning:before{content:"\f0e7"}.award-code:before{content:"\f121"}.award-cowboy:before{content:"\f8c0"}.award-angry:before{content:"\f556"}[class^="flag-"]{font-style:normal}.flag-ad:before{content:"🇦🇩"}.flag-ae:before{content:"🇦🇪"}.flag-af:before{content:"🇦🇫"}.flag-ag:before{content:"🇦🇬"}.flag-ai:before{content:"🇦🇮"}.flag-al:before{content:"🇦🇱"}.flag-am:before{content:"🇦🇲"}.flag-ao:before{content:"🇦🇴"}.flag-aq:before{content:"🇦🇶"}.flag-ar:before{content:"🇦🇷"}.flag-as:before{content:"🇦🇸"}.flag-at:before{content:"🇦🇹"}.flag-au:before{content:"🇦🇺"}.flag-aw:before{content:"🇦🇼"}.flag-ax:before{content:"🇦🇽"}.flag-az:before{content:"🇦🇿"}.flag-ba:before{content:"🇧🇦"}.flag-bb:before{content:"🇧🇧"}.flag-bd:before{content:"🇧🇩"}.flag-be:before{content:"🇧🇪"}.flag-bf:before{content:"🇧🇫"}.flag-bg:before{content:"🇧🇬"}.flag-bh:before{content:"🇧🇭"}.flag-bi:before{content:"🇧🇮"}.flag-bj:before{content:"🇧🇯"}.flag-bl:before{content:"🇧🇱"}.flag-bm:before{content:"🇧🇲"}.flag-bn:before{content:"🇧🇳"}.flag-bo:before{content:"🇧🇴"}.flag-bq:before{content:"🇧🇶"}.flag-br:before{content:"🇧🇷"}.flag-bs:before{content:"🇧🇸"}.flag-bt:before{content:"🇧🇹"}.flag-bv:before{content:"🇧🇻"}.flag-bw:before{content:"🇧🇼"}.flag-by:before{content:"🇧🇾"}.flag-bz:before{content:"🇧🇿"}.flag-ca:before{content:"🇨🇦"}.flag-cc:before{content:"🇨🇨"}.flag-cd:before{content:"🇨🇩"}.flag-cf:before{content:"🇨🇫"}.flag-cg:before{content:"🇨🇬"}.flag-ch:before{content:"🇨🇭"}.flag-ci:before{content:"🇨🇮"}.flag-ck:before{content:"🇨🇰"}.flag-cl:before{content:"🇨🇱"}.flag-cm:before{content:"🇨🇲"}.flag-cn:before{content:"🇨🇳"}.flag-co:before{content:"🇨🇴"}.flag-cr:before{content:"🇨🇷"}.flag-cu:before{content:"🇨🇺"}.flag-cv:before{content:"🇨🇻"}.flag-cw:before{content:"🇨🇼"}.flag-cx:before{content:"🇨🇽"}.flag-cy:before{content:"🇨🇾"}.flag-cz:before{content:"🇨🇿"}.flag-de:before{content:"🇩🇪"}.flag-dj:before{content:"🇩🇯"}.flag-dk:before{content:"🇩🇰"}.flag-dm:before{content:"🇩🇲"}.flag-do:before{content:"🇩🇴"}.flag-dz:before{content:"🇩🇿"}.flag-ec:before{content:"🇪🇨"}.flag-ee:before{content:"🇪🇪"}.flag-eg:before{content:"🇪🇬"}.flag-eh:before{content:"🇪🇭"}.flag-er:before{content:"🇪🇷"}.flag-es:before{content:"🇪🇸"}.flag-et:before{content:"🇪🇹"}.flag-fi:before{content:"🇫🇮"}.flag-fj:before{content:"🇫🇯"}.flag-fk:before{content:"🇫🇰"}.flag-fm:before{content:"🇫🇲"}.flag-fo:before{content:"🇫🇴"}.flag-fr:before{content:"🇫🇷"}.flag-ga:before{content:"🇬🇦"}.flag-gb:before{content:"🇬🇧"}.flag-gd:before{content:"🇬🇩"}.flag-ge:before{content:"🇬🇪"}.flag-gf:before{content:"🇬🇫"}.flag-gg:before{content:"🇬🇬"}.flag-gh:before{content:"🇬🇭"}.flag-gi:before{content:"🇬🇮"}.flag-gl:before{content:"🇬🇱"}.flag-gm:before{content:"🇬🇲"}.flag-gn:before{content:"🇬🇳"}.flag-gp:before{content:"🇬🇵"}.flag-gq:before{content:"🇬🇶"}.flag-gr:before{content:"🇬🇷"}.flag-gs:before{content:"🇬🇸"}.flag-gt:before{content:"🇬🇹"}.flag-gu:before{content:"🇬🇺"}.flag-gw:before{content:"🇬🇼"}.flag-gy:before{content:"🇬🇾"}.flag-hk:before{content:"🇭🇰"}.flag-hm:before{content:"🇭🇲"}.flag-hn:before{content:"🇭🇳"}.flag-hr:before{content:"🇭🇷"}.flag-ht:before{content:"🇭🇹"}.flag-hu:before{content:"🇭🇺"}.flag-id:before{content:"🇮🇩"}.flag-ie:before{content:"🇮🇪"}.flag-il:before{content:"🇮🇱"}.flag-im:before{content:"🇮🇲"}.flag-in:before{content:"🇮🇳"}.flag-io:before{content:"🇮🇴"}.flag-iq:before{content:"🇮🇶"}.flag-ir:before{content:"🇮🇷"}.flag-is:before{content:"🇮🇸"}.flag-it:before{content:"🇮🇹"}.flag-je:before{content:"🇯🇪"}.flag-jm:before{content:"🇯🇲"}.flag-jo:before{content:"🇯🇴"}.flag-jp:before{content:"🇯🇵"}.flag-ke:before{content:"🇰🇪"}.flag-kg:before{content:"🇰🇬"}.flag-kh:before{content:"🇰🇭"}.flag-ki:before{content:"🇰🇮"}.flag-km:before{content:"🇰🇲"}.flag-kn:before{content:"🇰🇳"}.flag-kp:before{content:"🇰🇵"}.flag-kr:before{content:"🇰🇷"}.flag-kw:before{content:"🇰🇼"}.flag-ky:before{content:"🇰🇾"}.flag-kz:before{content:"🇰🇿"}.flag-la:before{content:"🇱🇦"}.flag-lb:before{content:"🇱🇧"}.flag-lc:before{content:"🇱🇨"}.flag-li:before{content:"🇱🇮"}.flag-lk:before{content:"🇱🇰"}.flag-lr:before{content:"🇱🇷"}.flag-ls:before{content:"🇱🇸"}.flag-lt:before{content:"🇱🇹"}.flag-lu:before{content:"🇱🇺"}.flag-lv:before{content:"🇱🇻"}.flag-ly:before{content:"🇱🇾"}.flag-ma:before{content:"🇲🇦"}.flag-mc:before{content:"🇲🇨"}.flag-md:before{content:"🇲🇩"}.flag-me:before{content:"🇲🇪"}.flag-mf:before{content:"🇲🇫"}.flag-mg:before{content:"🇲🇬"}.flag-mh:before{content:"🇲🇭"}.flag-mk:before{content:"🇲🇰"}.flag-ml:before{content:"🇲🇱"}.flag-mm:before{content:"🇲🇲"}.flag-mn:before{content:"🇲🇳"}.flag-mo:before{content:"🇲🇴"}.flag-mp:before{content:"🇲🇵"}.flag-mq:before{content:"🇲🇶"}.flag-mr:before{content:"🇲🇷"}.flag-ms:before{content:"🇲🇸"}.flag-mt:before{content:"🇲🇹"}.flag-mu:before{content:"🇲🇺"}.flag-mv:before{content:"🇲🇻"}.flag-mw:before{content:"🇲🇼"}.flag-mx:before{content:"🇲🇽"}.flag-my:before{content:"🇲🇾"}.flag-mz:before{content:"🇲🇿"}.flag-na:before{content:"🇳🇦"}.flag-nc:before{content:"🇳🇨"}.flag-ne:before{content:"🇳🇪"}.flag-nf:before{content:"🇳🇫"}.flag-ng:before{content:"🇳🇬"}.flag-ni:before{content:"🇳🇮"}.flag-nl:before{content:"🇳🇱"}.flag-no:before{content:"🇳🇴"}.flag-np:before{content:"🇳🇵"}.flag-nr:before{content:"🇳🇷"}.flag-nu:before{content:"🇳🇺"}.flag-nz:before{content:"🇳🇿"}.flag-om:before{content:"🇴🇲"}.flag-pa:before{content:"🇵🇦"}.flag-pe:before{content:"🇵🇪"}.flag-pf:before{content:"🇵🇫"}.flag-pg:before{content:"🇵🇬"}.flag-ph:before{content:"🇵🇭"}.flag-pk:before{content:"🇵🇰"}.flag-pl:before{content:"🇵🇱"}.flag-pm:before{content:"🇵🇲"}.flag-pn:before{content:"🇵🇳"}.flag-pr:before{content:"🇵🇷"}.flag-ps:before{content:"🇵🇸"}.flag-pt:before{content:"🇵🇹"}.flag-pw:before{content:"🇵🇼"}.flag-py:before{content:"🇵🇾"}.flag-qa:before{content:"🇶🇦"}.flag-re:before{content:"🇷🇪"}.flag-ro:before{content:"🇷🇴"}.flag-rs:before{content:"🇷🇸"}.flag-ru:before{content:"🇷🇺"}.flag-rw:before{content:"🇷🇼"}.flag-sa:before{content:"🇸🇦"}.flag-sb:before{content:"🇸🇧"}.flag-sc:before{content:"🇸🇨"}.flag-sd:before{content:"🇸🇩"}.flag-se:before{content:"🇸🇪"}.flag-sg:before{content:"🇸🇬"}.flag-sh:before{content:"🇸🇭"}.flag-si:before{content:"🇸🇮"}.flag-sj:before{content:"🇸🇯"}.flag-sk:before{content:"🇸🇰"}.flag-sl:before{content:"🇸🇱"}.flag-sm:before{content:"🇸🇲"}.flag-sn:before{content:"🇸🇳"}.flag-so:before{content:"🇸🇴"}.flag-sr:before{content:"🇸🇷"}.flag-ss:before{content:"🇸🇸"}.flag-st:before{content:"🇸🇹"}.flag-sv:before{content:"🇸🇻"}.flag-sx:before{content:"🇸🇽"}.flag-sy:before{content:"🇸🇾"}.flag-sz:before{content:"🇸🇿"}.flag-tc:before{content:"🇹🇨"}.flag-td:before{content:"🇹🇩"}.flag-tf:before{content:"🇹🇫"}.flag-tg:before{content:"🇹🇬"}.flag-th:before{content:"🇹🇭"}.flag-tj:before{content:"🇹🇯"}.flag-tk:before{content:"🇹🇰"}.flag-tl:before{content:"🇹🇱"}.flag-tm:before{content:"🇹🇲"}.flag-tn:before{content:"🇹🇳"}.flag-to:before{content:"🇹🇴"}.flag-tr:before{content:"🇹🇷"}.flag-tt:before{content:"🇹🇹"}.flag-tv:before{content:"🇹🇻"}.flag-tw:before{content:"🇹🇼"}.flag-tz:before{content:"🇹🇿"}.flag-ua:before{content:"🇺🇦"}.flag-ug:before{content:"🇺🇬"}.flag-um:before{content:"🇺🇲"}.flag-us:before{content:"🇺🇸"}.flag-uy:before{content:"🇺🇾"}.flag-uz:before{content:"🇺🇿"}.flag-va:before{content:"🇻🇦"}.flag-vc:before{content:"🇻🇨"}.flag-ve:before{content:"🇻🇪"}.flag-vg:before{content:"🇻🇬"}.flag-vi:before{content:"🇻🇮"}.flag-vn:before{content:"🇻🇳"}.flag-vu:before{content:"🇻🇺"}.flag-wf:before{content:"🇼🇫"}.flag-ws:before{content:"🇼🇸"}.flag-ye:before{content:"🇾🇪"}.flag-yt:before{content:"🇾🇹"}.flag-za:before{content:"🇿🇦"}.flag-zm:before{content:"🇿🇲"}.flag-zw:before{content:"🇿🇼"}.opacity-0{opacity:0 !important}.opacity-25{opacity:0.25 !important}.opacity-50{opacity:0.5 !important}.opacity-75{opacity:0.75 !important}.opacity-100{opacity:1 !important}.min-vh-0{min-height:0vh !important}.min-vh-25{min-height:25vh !important}.min-vh-50{min-height:50vh !important}.min-vh-75{min-height:75vh !important}.min-vh-100{min-height:100vh !important}html,body,.container{font-family:"Lato", "LatoOffline", sans-serif}h1,h2{font-family:"Raleway", "RalewayOffline", sans-serif;font-weight:500;letter-spacing:2px}a{color:#337ab7;text-decoration:none}table>thead>tr>td{border-top:none !important}.fa-spin.spinner{margin-top:225px;text-align:center;opacity:0.5}.spinner-error{padding-top:20vh;text-align:center;opacity:0.5}.jumbotron{border-radius:0;text-align:center}.form-control:focus{background-color:transparent;border-color:#a3d39c;box-shadow:0 0 0 0.2rem #a3d39c;transition:background-color 0.3s, border-color 0.3s}.input-filled-valid{background-color:transparent !important;border-color:#a3d39c;box-shadow:0 0 0 0.2rem #a3d39c;transition:background-color 0.3s, border-color 0.3s}.input-filled-invalid{background-color:transparent !important;border-color:#d46767;box-shadow:0 0 0 0.2rem #d46767;transition:background-color 0.3s, border-color 0.3s}.btn-outlined.btn-theme{background:none;color:#545454;border-color:#545454;border:3px solid}.btn-outlined{border-radius:0;-webkit-transition:all 0.3s;-moz-transition:all 0.3s;transition:all 0.3s}.btn{letter-spacing:1px;text-decoration:none;-moz-user-select:none;border-radius:0;cursor:pointer;display:inline-block;margin-bottom:0;vertical-align:middle;white-space:nowrap;font-size:14px;line-height:20px;font-weight:700;padding:8px 20px}.btn-info{background-color:#5b7290 !important;border-color:#5b7290 !important}.badge-info{background-color:#5b7290 !important}.alert{border-radius:0 !important;padding:0.8em}.btn-fa{cursor:pointer}.close{cursor:pointer}.cursor-pointer{cursor:pointer}.cursor-help{cursor:help}.modal-content{-webkit-border-radius:0 !important;-moz-border-radius:0 !important;border-radius:0 !important}.fa-disabled{opacity:0.5;cursor:not-allowed}.badge-notification{vertical-align:top;margin-left:-1.5em;font-size:50%}
diff --git a/CTFd/themes/core/static/js/pages/scoreboard.dev.js b/CTFd/themes/core/static/js/pages/scoreboard.dev.js
index 8c46586..cd26e1e 100644
--- a/CTFd/themes/core/static/js/pages/scoreboard.dev.js
+++ b/CTFd/themes/core/static/js/pages/scoreboard.dev.js
@@ -162,7 +162,7 @@
/***/ (function(module, exports, __webpack_require__) {
;
-eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/core/assets/js/pages/main.js\");\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! ../CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _plotly = _interopRequireDefault(__webpack_require__(/*! plotly.js-basic-dist */ \"./node_modules/plotly.js-basic-dist/plotly-basic.js\"));\n\nvar _moment = _interopRequireDefault(__webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\"));\n\nvar _utils = __webpack_require__(/*! ../utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar graph = (0, _jquery.default)(\"#score-graph\");\nvar table = (0, _jquery.default)(\"#scoreboard tbody\");\nvar config = {\n displaylogo: false,\n responsive: true\n};\nvar layout = {\n title: \"Top 10 \" + (window.userMode === \"teams\" ? \"Teams\" : \"Users\"),\n paper_bgcolor: \"rgba(0,0,0,0)\",\n plot_bgcolor: \"rgba(0,0,0,0)\",\n hovermode: \"closest\",\n xaxis: {\n showgrid: false,\n showspikes: true\n },\n yaxis: {\n showgrid: false,\n showspikes: true\n },\n legend: {\n orientation: \"h\"\n }\n};\n\nvar updateScores = function updateScores() {\n _CTFd.default.api.get_scoreboard_list().then(function (response) {\n var teams = response.data;\n table.empty();\n\n for (var i = 0; i < teams.length; i++) {\n var row = [\"
\", '', i + 1, \" | \", ''.format(_CTFd.default.config.urlRoot, teams[i].account_id), (0, _utils.htmlEntities)(teams[i].name), \" | \", \"\", teams[i].score, \" | \", \"
\"].join(\"\");\n table.append(row);\n }\n });\n};\n\nvar createGraph = function createGraph() {\n _CTFd.default.api.get_scoreboard_detail({\n count: 10\n }).then(function (response) {\n var places = response.data;\n var teams = Object.keys(places);\n var traces = [];\n\n if (teams.length === 0) {\n // Replace spinner\n graph.html('
No solves yet
');\n return;\n }\n\n for (var i = 0; i < teams.length; i++) {\n var team_score = [];\n var times = [];\n\n for (var j = 0; j < places[teams[i]][\"solves\"].length; j++) {\n team_score.push(places[teams[i]][\"solves\"][j].value);\n var date = (0, _moment.default)(places[teams[i]][\"solves\"][j].date);\n times.push(date.toDate());\n }\n\n var trace = {\n x: times,\n y: (0, _utils.cumulativeSum)(team_score),\n mode: \"lines+markers\",\n name: places[teams[i]][\"name\"],\n marker: {\n color: (0, _utils.colorHash)(places[teams[i]][\"name\"] + places[teams[i]][\"id\"])\n },\n line: {\n color: (0, _utils.colorHash)(places[teams[i]][\"name\"] + places[teams[i]][\"id\"])\n }\n };\n traces.push(trace);\n }\n\n traces.sort(function (a, b) {\n var score_diff = b[\"y\"][b[\"y\"].length - 1] - a[\"y\"][a[\"y\"].length - 1];\n\n if (!score_diff) {\n return a[\"x\"][a[\"x\"].length - 1] - b[\"x\"][b[\"x\"].length - 1];\n }\n\n return score_diff;\n });\n graph.empty(); // Remove spinners\n\n graph[0].fn = \"CTFd_scoreboard_\" + new Date().toISOString().slice(0, 19);\n\n _plotly.default.newPlot(graph[0], traces, layout, config);\n });\n};\n\nvar updateGraph = function updateGraph() {\n _CTFd.default.api.get_scoreboard_detail({\n count: 10\n }).then(function (response) {\n var places = response.data;\n var teams = Object.keys(places);\n var traces = [];\n\n if (teams.length === 0) {\n return;\n }\n\n for (var i = 0; i < teams.length; i++) {\n var team_score = [];\n var times = [];\n\n for (var j = 0; j < places[teams[i]][\"solves\"].length; j++) {\n team_score.push(places[teams[i]][\"solves\"][j].value);\n var date = (0, _moment.default)(places[teams[i]][\"solves\"][j].date);\n times.push(date.toDate());\n }\n\n var trace = {\n x: times,\n y: (0, _utils.cumulativeSum)(team_score),\n mode: \"lines+markers\",\n name: places[teams[i]][\"name\"],\n marker: {\n color: (0, _utils.colorHash)(places[teams[i]][\"name\"] + places[teams[i]][\"id\"])\n },\n line: {\n color: (0, _utils.colorHash)(places[teams[i]][\"name\"] + places[teams[i]][\"id\"])\n }\n };\n traces.push(trace);\n }\n\n traces.sort(function (a, b) {\n var score_diff = b[\"y\"][b[\"y\"].length - 1] - a[\"y\"][a[\"y\"].length - 1];\n\n if (!score_diff) {\n return a[\"x\"][a[\"x\"].length - 1] - b[\"x\"][b[\"x\"].length - 1];\n }\n\n return score_diff;\n });\n\n _plotly.default.react(graph[0], traces, layout, config);\n });\n};\n\nfunction update() {\n updateScores();\n updateGraph();\n}\n\n(0, _jquery.default)(function () {\n setInterval(update, 300000); // Update scores every 5 minutes\n\n createGraph();\n updateGraph();\n});\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/pages/scoreboard.js?");
+eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/core/assets/js/pages/main.js\");\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! ../CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _plotly = _interopRequireDefault(__webpack_require__(/*! plotly.js-basic-dist */ \"./node_modules/plotly.js-basic-dist/plotly-basic.js\"));\n\nvar _moment = _interopRequireDefault(__webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\"));\n\nvar _utils = __webpack_require__(/*! ../utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar graph = (0, _jquery.default)(\"#score-graph\");\nvar table = (0, _jquery.default)(\"#scoreboard tbody\");\nvar config = {\n displaylogo: false,\n responsive: true\n};\nvar layout = {\n title: \"Top 10 \" + (window.userMode === \"teams\" ? \"Teams\" : \"Users\"),\n paper_bgcolor: \"rgba(0,0,0,0)\",\n plot_bgcolor: \"rgba(0,0,0,0)\",\n hovermode: \"closest\",\n xaxis: {\n showgrid: false,\n showspikes: true\n },\n yaxis: {\n showgrid: false,\n showspikes: true\n },\n legend: {\n orientation: \"h\"\n }\n};\n\nvar updateScores = function updateScores() {\n _CTFd.default.api.get_scoreboard_list().then(function (response) {\n var teams = response.data;\n table.empty();\n\n for (var i = 0; i < teams.length; i++) {\n var row = [\"
\", '', i + 1, \" | \", ''.format(_CTFd.default.config.urlRoot, teams[i].account_id), (0, _utils.htmlEntities)(teams[i].name), \" | \", \"\", teams[i].score, \" | \", \"
\"].join(\"\");\n table.append(row);\n }\n });\n};\n\nvar createGraph = function createGraph() {\n _CTFd.default.api.get_scoreboard_detail({\n count: 10\n }).then(function (response) {\n var places = response.data;\n var teams = Object.keys(places);\n var traces = [];\n\n if (teams.length === 0) {\n // Replace spinner\n graph.html('
No solves yet
');\n return;\n }\n\n for (var i = 0; i < teams.length; i++) {\n var team_score = [];\n var times = [];\n\n for (var j = 0; j < places[teams[i]][\"solves\"].length; j++) {\n team_score.push(places[teams[i]][\"solves\"][j].value);\n var date = (0, _moment.default)(places[teams[i]][\"solves\"][j].date);\n times.push(date.toDate());\n }\n\n var trace = {\n x: times,\n y: (0, _utils.cumulativeSum)(team_score),\n mode: \"lines+markers\",\n name: places[teams[i]][\"name\"],\n marker: {\n color: (0, _utils.colorHash)(places[teams[i]][\"name\"] + places[teams[i]][\"id\"])\n },\n line: {\n color: (0, _utils.colorHash)(places[teams[i]][\"name\"] + places[teams[i]][\"id\"])\n }\n };\n traces.push(trace);\n }\n\n traces.sort(function (a, b) {\n var score_diff = b[\"y\"][b[\"y\"].length - 1] - a[\"y\"][a[\"y\"].length - 1];\n\n if (!score_diff) {\n return a[\"x\"][a[\"x\"].length - 1] - b[\"x\"][b[\"x\"].length - 1];\n }\n\n return score_diff;\n });\n graph.empty(); // Remove spinners\n\n graph[0].fn = \"CTFd_scoreboard_\" + new Date().toISOString().slice(0, 19);\n\n _plotly.default.newPlot(graph[0], traces, layout, config);\n });\n};\n\nvar updateGraph = function updateGraph() {\n _CTFd.default.api.get_scoreboard_detail({\n count: 10\n }).then(function (response) {\n var places = response.data;\n var teams = Object.keys(places);\n var traces = [];\n\n if (teams.length === 0) {\n return;\n }\n\n for (var i = 0; i < teams.length; i++) {\n var team_score = [];\n var times = [];\n\n for (var j = 0; j < places[teams[i]][\"solves\"].length; j++) {\n team_score.push(places[teams[i]][\"solves\"][j].value);\n var date = (0, _moment.default)(places[teams[i]][\"solves\"][j].date);\n times.push(date.toDate());\n }\n\n var trace = {\n x: times,\n y: (0, _utils.cumulativeSum)(team_score),\n mode: \"lines+markers\",\n name: places[teams[i]][\"name\"],\n marker: {\n color: (0, _utils.colorHash)(places[teams[i]][\"name\"] + places[teams[i]][\"id\"])\n },\n line: {\n color: (0, _utils.colorHash)(places[teams[i]][\"name\"] + places[teams[i]][\"id\"])\n }\n };\n traces.push(trace);\n }\n\n traces.sort(function (a, b) {\n var score_diff = b[\"y\"][b[\"y\"].length - 1] - a[\"y\"][a[\"y\"].length - 1];\n\n if (!score_diff) {\n return a[\"x\"][a[\"x\"].length - 1] - b[\"x\"][b[\"x\"].length - 1];\n }\n\n return score_diff;\n });\n\n _plotly.default.react(graph[0], traces, layout, config);\n });\n};\n\nfunction update() {\n updateScores();\n updateGraph();\n}\n\n(0, _jquery.default)(function () {\n setInterval(update, 300000); // Update scores every 5 minutes\n\n createGraph();\n updateGraph();\n});\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/pages/scoreboard.js?");
/***/ })
diff --git a/CTFd/themes/core/templates/teams/private.html b/CTFd/themes/core/templates/teams/private.html
index 4543fed..2b8e5ee 100644
--- a/CTFd/themes/core/templates/teams/private.html
+++ b/CTFd/themes/core/templates/teams/private.html
@@ -189,7 +189,7 @@
-
+
Members
@@ -290,7 +290,11 @@
{% else %}
- No solves yet
+
+
+ No solves yet
+
+
{% endif %}
{% endif %}
diff --git a/CTFd/themes/core/templates/teams/public.html b/CTFd/themes/core/templates/teams/public.html
index 531b997..77febfe 100644
--- a/CTFd/themes/core/templates/teams/public.html
+++ b/CTFd/themes/core/templates/teams/public.html
@@ -168,7 +168,11 @@
{% else %}
- No solves yet
+
+
+ No solves yet
+
+
{% endif %}
{% endif %}
diff --git a/CTFd/themes/core/templates/users/private.html b/CTFd/themes/core/templates/users/private.html
index 407b79a..dfc7019 100644
--- a/CTFd/themes/core/templates/users/private.html
+++ b/CTFd/themes/core/templates/users/private.html
@@ -172,7 +172,11 @@
{% else %}
- No solves yet
+
+
+ No solves yet
+
+
{% endif %}
{% endif %}
diff --git a/CTFd/themes/core/templates/users/public.html b/CTFd/themes/core/templates/users/public.html
index 4eac95e..da68cc7 100644
--- a/CTFd/themes/core/templates/users/public.html
+++ b/CTFd/themes/core/templates/users/public.html
@@ -175,7 +175,11 @@
{% else %}
- No solves yet
+
+
+ No solves yet
+
+
{% endif %}
{% endif %}