diff --git a/CTFd/constants/config.py b/CTFd/constants/config.py index a56c2d77..b9171cfc 100644 --- a/CTFd/constants/config.py +++ b/CTFd/constants/config.py @@ -1,3 +1,5 @@ +import json + from CTFd.utils import get_config from CTFd.utils.helpers import markup @@ -18,5 +20,9 @@ class _ConfigsWrapper: def theme_footer(self): return markup(get_config("theme_footer", default="")) + @property + def theme_settings(self): + return json.loads(get_config("theme_settings", default="null")) + Configs = _ConfigsWrapper() diff --git a/CTFd/themes/admin/assets/css/codemirror.scss b/CTFd/themes/admin/assets/css/codemirror.scss index b5553ac4..4e0bf054 100644 --- a/CTFd/themes/admin/assets/css/codemirror.scss +++ b/CTFd/themes/admin/assets/css/codemirror.scss @@ -1,4 +1,5 @@ @import "~codemirror/lib/codemirror.css"; .CodeMirror { font-size: 12px; + border: 1px solid lightgray; } diff --git a/CTFd/themes/admin/assets/js/pages/configs.js b/CTFd/themes/admin/assets/js/pages/configs.js index 91cbc469..2840e1a0 100644 --- a/CTFd/themes/admin/assets/js/pages/configs.js +++ b/CTFd/themes/admin/assets/js/pages/configs.js @@ -251,6 +251,52 @@ $(() => { } ); + const theme_settings_editor = CodeMirror.fromTextArea( + document.getElementById("theme-settings"), + { + lineNumbers: true, + lineWrapping: true, + mode: { name: "javascript", json: true } + } + ); + + // Handle refreshing codemirror when switching tabs. + // Better than the autorefresh approach b/c there's no flicker + $("a[href='#theme']").on("shown.bs.tab", function(e) { + theme_header_editor.refresh(); + theme_footer_editor.refresh(); + theme_settings_editor.refresh(); + }); + + $("#theme-settings-modal form").submit(function(e) { + e.preventDefault(); + theme_settings_editor + .getDoc() + .setValue(JSON.stringify($(this).serializeJSON(), null, 2)); + $("#theme-settings-modal").modal("hide"); + }); + + $("#theme-settings-button").click(function() { + let form = $("#theme-settings-modal form"); + let data = JSON.parse(theme_settings_editor.getValue()); + $.each(data, function(key, value) { + var ctrl = form.find(`[name='${key}']`); + switch (ctrl.prop("type")) { + case "radio": + case "checkbox": + ctrl.each(function() { + if ($(this).attr("value") == value) { + $(this).attr("checked", value); + } + }); + break; + default: + ctrl.val(value); + } + }); + $("#theme-settings-modal").modal(); + }); + insertTimezones($("#start-timezone")); insertTimezones($("#end-timezone")); insertTimezones($("#freeze-timezone")); diff --git a/CTFd/themes/admin/static/css/codemirror.dev.css b/CTFd/themes/admin/static/css/codemirror.dev.css index d9c817f4..5cbdfe42 100644 --- a/CTFd/themes/admin/static/css/codemirror.dev.css +++ b/CTFd/themes/admin/static/css/codemirror.dev.css @@ -1,4 +1,4 @@ .CodeMirror{font-family:monospace;height:300px;color:black;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:white}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:black}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid black;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0 !important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor-mark{background-color:rgba(20,255,20,0.5);-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite;background-color:#7e7}@-moz-keyframes blink{0%{}50%{background-color:transparent}100%{}}@-webkit-keyframes blink{0%{}50%{background-color:transparent}100%{}}@keyframes blink{0%{}50%{background-color:transparent}100%{}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:-20px;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:blue}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:bold}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3,.cm-s-default .cm-type{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error{color:#f00}.cm-invalidchar{color:#f00}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,0.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:white}.CodeMirror-scroll{overflow:scroll !important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:none;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none !important;border:none !important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:0.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:none}.CodeMirror-scroll,.CodeMirror-sizer,.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:rgba(255,255,0,0.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:none} -.CodeMirror{font-size:12px} +.CodeMirror{font-size:12px;border:1px solid lightgray} diff --git a/CTFd/themes/admin/static/css/codemirror.min.css b/CTFd/themes/admin/static/css/codemirror.min.css index 9e9ca66e..3bff1131 100644 --- a/CTFd/themes/admin/static/css/codemirror.min.css +++ b/CTFd/themes/admin/static/css/codemirror.min.css @@ -1 +1 @@ -.CodeMirror{font-family:monospace;height:300px;color:#000;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-gutter-filler,.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:#000}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid #000;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0!important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor-mark{background-color:rgba(20,255,20,.5)}.cm-animate-fat-cursor,.cm-fat-cursor-mark{-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}.cm-animate-fat-cursor{width:auto;border:0;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:-20px;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:#00f}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-type,.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta,.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-invalidchar,.cm-s-default .cm-error{color:red}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:#fff}.CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:none;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none!important;border:none!important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:none}.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber,.CodeMirror-scroll,.CodeMirror-sizer{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.CodeMirror-focused div.CodeMirror-cursors,div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:""}span.CodeMirror-selectedtext{background:none}.CodeMirror{font-size:12px} \ No newline at end of file +.CodeMirror{font-family:monospace;height:300px;color:#000;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-gutter-filler,.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:#000}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid #000;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0!important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor-mark{background-color:rgba(20,255,20,.5)}.cm-animate-fat-cursor,.cm-fat-cursor-mark{-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}.cm-animate-fat-cursor{width:auto;border:0;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:-20px;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:#00f}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-type,.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta,.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-invalidchar,.cm-s-default .cm-error{color:red}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:#fff}.CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:none;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none!important;border:none!important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:none}.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber,.CodeMirror-scroll,.CodeMirror-sizer{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.CodeMirror-focused div.CodeMirror-cursors,div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:""}span.CodeMirror-selectedtext{background:none}.CodeMirror{font-size:12px;border:1px solid #d3d3d3} \ No newline at end of file diff --git a/CTFd/themes/admin/static/js/pages/configs.dev.js b/CTFd/themes/admin/static/js/pages/configs.dev.js index 6aac5609..2700d716 100644 --- a/CTFd/themes/admin/static/js/pages/configs.dev.js +++ b/CTFd/themes/admin/static/js/pages/configs.dev.js @@ -162,7 +162,7 @@ /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\n__webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\n__webpack_require__(/*! bootstrap/js/dist/tab */ \"./node_modules/bootstrap/js/dist/tab.js\");\n\nvar _momentTimezone = _interopRequireDefault(__webpack_require__(/*! moment-timezone */ \"./node_modules/moment-timezone/index.js\"));\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _helpers = _interopRequireDefault(__webpack_require__(/*! core/helpers */ \"./CTFd/themes/core/assets/js/helpers.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nvar _codemirror = _interopRequireDefault(__webpack_require__(/*! codemirror */ \"./node_modules/codemirror/lib/codemirror.js\"));\n\n__webpack_require__(/*! codemirror/mode/htmlmixed/htmlmixed.js */ \"./node_modules/codemirror/mode/htmlmixed/htmlmixed.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction loadTimestamp(place, timestamp) {\n if (typeof timestamp == \"string\") {\n timestamp = parseInt(timestamp, 10);\n }\n\n var m = (0, _momentTimezone.default)(timestamp * 1000);\n (0, _jquery.default)(\"#\" + place + \"-month\").val(m.month() + 1); // Months are zero indexed (http://momentjs.com/docs/#/get-set/month/)\n\n (0, _jquery.default)(\"#\" + place + \"-day\").val(m.date());\n (0, _jquery.default)(\"#\" + place + \"-year\").val(m.year());\n (0, _jquery.default)(\"#\" + place + \"-hour\").val(m.hour());\n (0, _jquery.default)(\"#\" + place + \"-minute\").val(m.minute());\n loadDateValues(place);\n}\n\nfunction loadDateValues(place) {\n var month = (0, _jquery.default)(\"#\" + place + \"-month\").val();\n var day = (0, _jquery.default)(\"#\" + place + \"-day\").val();\n var year = (0, _jquery.default)(\"#\" + place + \"-year\").val();\n var hour = (0, _jquery.default)(\"#\" + place + \"-hour\").val();\n var minute = (0, _jquery.default)(\"#\" + place + \"-minute\").val();\n var timezone = (0, _jquery.default)(\"#\" + place + \"-timezone\").val();\n var utc = convertDateToMoment(month, day, year, hour, minute);\n\n if (isNaN(utc.unix())) {\n (0, _jquery.default)(\"#\" + place).val(\"\");\n (0, _jquery.default)(\"#\" + place + \"-local\").val(\"\");\n (0, _jquery.default)(\"#\" + place + \"-zonetime\").val(\"\");\n } else {\n (0, _jquery.default)(\"#\" + place).val(utc.unix());\n (0, _jquery.default)(\"#\" + place + \"-local\").val(utc.local().format(\"dddd, MMMM Do YYYY, h:mm:ss a zz\"));\n (0, _jquery.default)(\"#\" + place + \"-zonetime\").val(utc.tz(timezone).format(\"dddd, MMMM Do YYYY, h:mm:ss a zz\"));\n }\n}\n\nfunction convertDateToMoment(month, day, year, hour, minute) {\n var month_num = month.toString();\n\n if (month_num.length == 1) {\n month_num = \"0\" + month_num;\n }\n\n var day_str = day.toString();\n\n if (day_str.length == 1) {\n day_str = \"0\" + day_str;\n }\n\n var hour_str = hour.toString();\n\n if (hour_str.length == 1) {\n hour_str = \"0\" + hour_str;\n }\n\n var min_str = minute.toString();\n\n if (min_str.length == 1) {\n min_str = \"0\" + min_str;\n } // 2013-02-08 24:00\n\n\n var date_string = year.toString() + \"-\" + month_num + \"-\" + day_str + \" \" + hour_str + \":\" + min_str + \":00\";\n return (0, _momentTimezone.default)(date_string, _momentTimezone.default.ISO_8601);\n}\n\nfunction updateConfigs(event) {\n event.preventDefault();\n var obj = (0, _jquery.default)(this).serializeJSON();\n var params = {};\n\n if (obj.mail_useauth === false) {\n obj.mail_username = null;\n obj.mail_password = null;\n } else {\n if (obj.mail_username === \"\") {\n delete obj.mail_username;\n }\n\n if (obj.mail_password === \"\") {\n delete obj.mail_password;\n }\n }\n\n Object.keys(obj).forEach(function (x) {\n if (obj[x] === \"true\") {\n params[x] = true;\n } else if (obj[x] === \"false\") {\n params[x] = false;\n } else {\n params[x] = obj[x];\n }\n });\n\n _CTFd.default.api.patch_config_list({}, params).then(function (response) {\n window.location.reload();\n });\n}\n\nfunction uploadLogo(event) {\n event.preventDefault();\n var form = event.target;\n\n _helpers.default.files.upload(form, {}, function (response) {\n var f = response.data[0];\n var params = {\n value: f.location\n };\n\n _CTFd.default.fetch(\"/api/v1/configs/ctf_logo\", {\n method: \"PATCH\",\n body: JSON.stringify(params)\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n if (response.success) {\n window.location.reload();\n } else {\n ezAlert({\n title: \"Error!\",\n body: \"Logo uploading failed!\",\n button: \"Okay\"\n });\n }\n });\n });\n}\n\nfunction removeLogo() {\n (0, _ezq.ezQuery)({\n title: \"Remove logo\",\n body: \"Are you sure you'd like to remove the CTF logo?\",\n success: function success() {\n var params = {\n value: null\n };\n\n _CTFd.default.api.patch_config({\n configKey: \"ctf_logo\"\n }, params).then(function (response) {\n window.location.reload();\n });\n }\n });\n}\n\nfunction importConfig(event) {\n event.preventDefault();\n var import_file = document.getElementById(\"import-file\").files[0];\n var form_data = new FormData();\n form_data.append(\"backup\", import_file);\n form_data.append(\"nonce\", _CTFd.default.config.csrfNonce);\n var pg = (0, _ezq.ezProgressBar)({\n width: 0,\n title: \"Upload Progress\"\n });\n\n _jquery.default.ajax({\n url: _CTFd.default.config.urlRoot + \"/admin/import\",\n type: \"POST\",\n data: form_data,\n processData: false,\n contentType: false,\n statusCode: {\n 500: function _(resp) {\n console.log(resp.responseText);\n alert(resp.responseText);\n }\n },\n xhr: function xhr() {\n var xhr = _jquery.default.ajaxSettings.xhr();\n\n xhr.upload.onprogress = function (e) {\n if (e.lengthComputable) {\n var width = e.loaded / e.total * 100;\n pg = (0, _ezq.ezProgressBar)({\n target: pg,\n width: width\n });\n }\n };\n\n return xhr;\n },\n success: function success(data) {\n pg = (0, _ezq.ezProgressBar)({\n target: pg,\n width: 100\n });\n setTimeout(function () {\n pg.modal(\"hide\");\n }, 500);\n setTimeout(function () {\n window.location.reload();\n }, 700);\n }\n });\n}\n\nfunction exportConfig(event) {\n event.preventDefault();\n var href = _CTFd.default.config.urlRoot + \"/admin/export\";\n window.location.href = (0, _jquery.default)(this).attr(\"href\");\n}\n\nfunction insertTimezones(target) {\n var current = (0, _jquery.default)(\"\").text(_momentTimezone.default.tz.guess());\n (0, _jquery.default)(target).append(current);\n\n var tz_names = _momentTimezone.default.tz.names();\n\n for (var i = 0; i < tz_names.length; i++) {\n var tz = (0, _jquery.default)(\"\").text(tz_names[i]);\n (0, _jquery.default)(target).append(tz);\n }\n}\n\n(0, _jquery.default)(function () {\n var theme_header_editor = _codemirror.default.fromTextArea(document.getElementById(\"theme-header\"), {\n lineNumbers: true,\n lineWrapping: true,\n mode: \"htmlmixed\",\n htmlMode: true\n });\n\n var theme_footer_editor = _codemirror.default.fromTextArea(document.getElementById(\"theme-footer\"), {\n lineNumbers: true,\n lineWrapping: true,\n mode: \"htmlmixed\",\n htmlMode: true\n });\n\n insertTimezones((0, _jquery.default)(\"#start-timezone\"));\n insertTimezones((0, _jquery.default)(\"#end-timezone\"));\n insertTimezones((0, _jquery.default)(\"#freeze-timezone\"));\n (0, _jquery.default)(\".config-section > form:not(.form-upload)\").submit(updateConfigs);\n (0, _jquery.default)(\"#logo-upload\").submit(uploadLogo);\n (0, _jquery.default)(\"#remove-logo\").click(removeLogo);\n (0, _jquery.default)(\"#export-button\").click(exportConfig);\n (0, _jquery.default)(\"#import-button\").click(importConfig);\n (0, _jquery.default)(\"#config-color-update\").click(function () {\n var hex_code = (0, _jquery.default)(\"#config-color-picker\").val();\n var user_css = theme_header_editor.getValue();\n var new_css;\n\n if (user_css.length) {\n var css_vars = \"theme-color: \".concat(hex_code, \";\");\n new_css = user_css.replace(/theme-color: (.*);/, css_vars);\n } else {\n new_css = \"\\n\";\n }\n\n theme_header_editor.getDoc().setValue(new_css);\n });\n (0, _jquery.default)(\".start-date\").change(function () {\n loadDateValues(\"start\");\n });\n (0, _jquery.default)(\".end-date\").change(function () {\n loadDateValues(\"end\");\n });\n (0, _jquery.default)(\".freeze-date\").change(function () {\n loadDateValues(\"freeze\");\n });\n var start = (0, _jquery.default)(\"#start\").val();\n var end = (0, _jquery.default)(\"#end\").val();\n var freeze = (0, _jquery.default)(\"#freeze\").val();\n\n if (start) {\n loadTimestamp(\"start\", start);\n }\n\n if (end) {\n loadTimestamp(\"end\", end);\n }\n\n if (freeze) {\n loadTimestamp(\"freeze\", freeze);\n } // Toggle username and password based on stored value\n\n\n (0, _jquery.default)(\"#mail_useauth\").change(function () {\n (0, _jquery.default)(\"#mail_username_password\").toggle(this.checked);\n }).change();\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/configs.js?"); +eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\n__webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\n__webpack_require__(/*! bootstrap/js/dist/tab */ \"./node_modules/bootstrap/js/dist/tab.js\");\n\nvar _momentTimezone = _interopRequireDefault(__webpack_require__(/*! moment-timezone */ \"./node_modules/moment-timezone/index.js\"));\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _helpers = _interopRequireDefault(__webpack_require__(/*! core/helpers */ \"./CTFd/themes/core/assets/js/helpers.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nvar _codemirror = _interopRequireDefault(__webpack_require__(/*! codemirror */ \"./node_modules/codemirror/lib/codemirror.js\"));\n\n__webpack_require__(/*! codemirror/mode/htmlmixed/htmlmixed.js */ \"./node_modules/codemirror/mode/htmlmixed/htmlmixed.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction loadTimestamp(place, timestamp) {\n if (typeof timestamp == \"string\") {\n timestamp = parseInt(timestamp, 10);\n }\n\n var m = (0, _momentTimezone.default)(timestamp * 1000);\n (0, _jquery.default)(\"#\" + place + \"-month\").val(m.month() + 1); // Months are zero indexed (http://momentjs.com/docs/#/get-set/month/)\n\n (0, _jquery.default)(\"#\" + place + \"-day\").val(m.date());\n (0, _jquery.default)(\"#\" + place + \"-year\").val(m.year());\n (0, _jquery.default)(\"#\" + place + \"-hour\").val(m.hour());\n (0, _jquery.default)(\"#\" + place + \"-minute\").val(m.minute());\n loadDateValues(place);\n}\n\nfunction loadDateValues(place) {\n var month = (0, _jquery.default)(\"#\" + place + \"-month\").val();\n var day = (0, _jquery.default)(\"#\" + place + \"-day\").val();\n var year = (0, _jquery.default)(\"#\" + place + \"-year\").val();\n var hour = (0, _jquery.default)(\"#\" + place + \"-hour\").val();\n var minute = (0, _jquery.default)(\"#\" + place + \"-minute\").val();\n var timezone = (0, _jquery.default)(\"#\" + place + \"-timezone\").val();\n var utc = convertDateToMoment(month, day, year, hour, minute);\n\n if (isNaN(utc.unix())) {\n (0, _jquery.default)(\"#\" + place).val(\"\");\n (0, _jquery.default)(\"#\" + place + \"-local\").val(\"\");\n (0, _jquery.default)(\"#\" + place + \"-zonetime\").val(\"\");\n } else {\n (0, _jquery.default)(\"#\" + place).val(utc.unix());\n (0, _jquery.default)(\"#\" + place + \"-local\").val(utc.local().format(\"dddd, MMMM Do YYYY, h:mm:ss a zz\"));\n (0, _jquery.default)(\"#\" + place + \"-zonetime\").val(utc.tz(timezone).format(\"dddd, MMMM Do YYYY, h:mm:ss a zz\"));\n }\n}\n\nfunction convertDateToMoment(month, day, year, hour, minute) {\n var month_num = month.toString();\n\n if (month_num.length == 1) {\n month_num = \"0\" + month_num;\n }\n\n var day_str = day.toString();\n\n if (day_str.length == 1) {\n day_str = \"0\" + day_str;\n }\n\n var hour_str = hour.toString();\n\n if (hour_str.length == 1) {\n hour_str = \"0\" + hour_str;\n }\n\n var min_str = minute.toString();\n\n if (min_str.length == 1) {\n min_str = \"0\" + min_str;\n } // 2013-02-08 24:00\n\n\n var date_string = year.toString() + \"-\" + month_num + \"-\" + day_str + \" \" + hour_str + \":\" + min_str + \":00\";\n return (0, _momentTimezone.default)(date_string, _momentTimezone.default.ISO_8601);\n}\n\nfunction updateConfigs(event) {\n event.preventDefault();\n var obj = (0, _jquery.default)(this).serializeJSON();\n var params = {};\n\n if (obj.mail_useauth === false) {\n obj.mail_username = null;\n obj.mail_password = null;\n } else {\n if (obj.mail_username === \"\") {\n delete obj.mail_username;\n }\n\n if (obj.mail_password === \"\") {\n delete obj.mail_password;\n }\n }\n\n Object.keys(obj).forEach(function (x) {\n if (obj[x] === \"true\") {\n params[x] = true;\n } else if (obj[x] === \"false\") {\n params[x] = false;\n } else {\n params[x] = obj[x];\n }\n });\n\n _CTFd.default.api.patch_config_list({}, params).then(function (response) {\n window.location.reload();\n });\n}\n\nfunction uploadLogo(event) {\n event.preventDefault();\n var form = event.target;\n\n _helpers.default.files.upload(form, {}, function (response) {\n var f = response.data[0];\n var params = {\n value: f.location\n };\n\n _CTFd.default.fetch(\"/api/v1/configs/ctf_logo\", {\n method: \"PATCH\",\n body: JSON.stringify(params)\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n if (response.success) {\n window.location.reload();\n } else {\n ezAlert({\n title: \"Error!\",\n body: \"Logo uploading failed!\",\n button: \"Okay\"\n });\n }\n });\n });\n}\n\nfunction removeLogo() {\n (0, _ezq.ezQuery)({\n title: \"Remove logo\",\n body: \"Are you sure you'd like to remove the CTF logo?\",\n success: function success() {\n var params = {\n value: null\n };\n\n _CTFd.default.api.patch_config({\n configKey: \"ctf_logo\"\n }, params).then(function (response) {\n window.location.reload();\n });\n }\n });\n}\n\nfunction importConfig(event) {\n event.preventDefault();\n var import_file = document.getElementById(\"import-file\").files[0];\n var form_data = new FormData();\n form_data.append(\"backup\", import_file);\n form_data.append(\"nonce\", _CTFd.default.config.csrfNonce);\n var pg = (0, _ezq.ezProgressBar)({\n width: 0,\n title: \"Upload Progress\"\n });\n\n _jquery.default.ajax({\n url: _CTFd.default.config.urlRoot + \"/admin/import\",\n type: \"POST\",\n data: form_data,\n processData: false,\n contentType: false,\n statusCode: {\n 500: function _(resp) {\n console.log(resp.responseText);\n alert(resp.responseText);\n }\n },\n xhr: function xhr() {\n var xhr = _jquery.default.ajaxSettings.xhr();\n\n xhr.upload.onprogress = function (e) {\n if (e.lengthComputable) {\n var width = e.loaded / e.total * 100;\n pg = (0, _ezq.ezProgressBar)({\n target: pg,\n width: width\n });\n }\n };\n\n return xhr;\n },\n success: function success(data) {\n pg = (0, _ezq.ezProgressBar)({\n target: pg,\n width: 100\n });\n setTimeout(function () {\n pg.modal(\"hide\");\n }, 500);\n setTimeout(function () {\n window.location.reload();\n }, 700);\n }\n });\n}\n\nfunction exportConfig(event) {\n event.preventDefault();\n var href = _CTFd.default.config.urlRoot + \"/admin/export\";\n window.location.href = (0, _jquery.default)(this).attr(\"href\");\n}\n\nfunction insertTimezones(target) {\n var current = (0, _jquery.default)(\"\").text(_momentTimezone.default.tz.guess());\n (0, _jquery.default)(target).append(current);\n\n var tz_names = _momentTimezone.default.tz.names();\n\n for (var i = 0; i < tz_names.length; i++) {\n var tz = (0, _jquery.default)(\"\").text(tz_names[i]);\n (0, _jquery.default)(target).append(tz);\n }\n}\n\n(0, _jquery.default)(function () {\n var theme_header_editor = _codemirror.default.fromTextArea(document.getElementById(\"theme-header\"), {\n lineNumbers: true,\n lineWrapping: true,\n mode: \"htmlmixed\",\n htmlMode: true\n });\n\n var theme_footer_editor = _codemirror.default.fromTextArea(document.getElementById(\"theme-footer\"), {\n lineNumbers: true,\n lineWrapping: true,\n mode: \"htmlmixed\",\n htmlMode: true\n });\n\n var theme_settings_editor = _codemirror.default.fromTextArea(document.getElementById(\"theme-settings\"), {\n lineNumbers: true,\n lineWrapping: true,\n mode: {\n name: \"javascript\",\n json: true\n }\n }); // Handle refreshing codemirror when switching tabs.\n // Better than the autorefresh approach b/c there's no flicker\n\n\n (0, _jquery.default)(\"a[href='#theme']\").on(\"shown.bs.tab\", function (e) {\n theme_header_editor.refresh();\n theme_footer_editor.refresh();\n theme_settings_editor.refresh();\n });\n (0, _jquery.default)(\"#theme-settings-modal form\").submit(function (e) {\n e.preventDefault();\n theme_settings_editor.getDoc().setValue(JSON.stringify((0, _jquery.default)(this).serializeJSON(), null, 2));\n (0, _jquery.default)(\"#theme-settings-modal\").modal(\"hide\");\n });\n (0, _jquery.default)(\"#theme-settings-button\").click(function () {\n var form = (0, _jquery.default)(\"#theme-settings-modal form\");\n var data = JSON.parse(theme_settings_editor.getValue());\n\n _jquery.default.each(data, function (key, value) {\n var ctrl = form.find(\"[name='\".concat(key, \"']\"));\n\n switch (ctrl.prop(\"type\")) {\n case \"radio\":\n case \"checkbox\":\n ctrl.each(function () {\n if ((0, _jquery.default)(this).attr(\"value\") == value) {\n (0, _jquery.default)(this).attr(\"checked\", value);\n }\n });\n break;\n\n default:\n ctrl.val(value);\n }\n });\n\n (0, _jquery.default)(\"#theme-settings-modal\").modal();\n });\n insertTimezones((0, _jquery.default)(\"#start-timezone\"));\n insertTimezones((0, _jquery.default)(\"#end-timezone\"));\n insertTimezones((0, _jquery.default)(\"#freeze-timezone\"));\n (0, _jquery.default)(\".config-section > form:not(.form-upload)\").submit(updateConfigs);\n (0, _jquery.default)(\"#logo-upload\").submit(uploadLogo);\n (0, _jquery.default)(\"#remove-logo\").click(removeLogo);\n (0, _jquery.default)(\"#export-button\").click(exportConfig);\n (0, _jquery.default)(\"#import-button\").click(importConfig);\n (0, _jquery.default)(\"#config-color-update\").click(function () {\n var hex_code = (0, _jquery.default)(\"#config-color-picker\").val();\n var user_css = theme_header_editor.getValue();\n var new_css;\n\n if (user_css.length) {\n var css_vars = \"theme-color: \".concat(hex_code, \";\");\n new_css = user_css.replace(/theme-color: (.*);/, css_vars);\n } else {\n new_css = \"\\n\";\n }\n\n theme_header_editor.getDoc().setValue(new_css);\n });\n (0, _jquery.default)(\".start-date\").change(function () {\n loadDateValues(\"start\");\n });\n (0, _jquery.default)(\".end-date\").change(function () {\n loadDateValues(\"end\");\n });\n (0, _jquery.default)(\".freeze-date\").change(function () {\n loadDateValues(\"freeze\");\n });\n var start = (0, _jquery.default)(\"#start\").val();\n var end = (0, _jquery.default)(\"#end\").val();\n var freeze = (0, _jquery.default)(\"#freeze\").val();\n\n if (start) {\n loadTimestamp(\"start\", start);\n }\n\n if (end) {\n loadTimestamp(\"end\", end);\n }\n\n if (freeze) {\n loadTimestamp(\"freeze\", freeze);\n } // Toggle username and password based on stored value\n\n\n (0, _jquery.default)(\"#mail_useauth\").change(function () {\n (0, _jquery.default)(\"#mail_username_password\").toggle(this.checked);\n }).change();\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/configs.js?"); /***/ }) diff --git a/CTFd/themes/admin/static/js/pages/configs.min.js b/CTFd/themes/admin/static/js/pages/configs.min.js index 64ba64a9..f9651e44 100644 --- a/CTFd/themes/admin/static/js/pages/configs.min.js +++ b/CTFd/themes/admin/static/js/pages/configs.min.js @@ -1 +1 @@ -!function(r){function e(e){for(var t,o,n=e[0],s=e[1],a=e[2],i=0,l=[];i").text(c.default.tz.guess());(0,r.default)(e).append(t);for(var o=c.default.tz.names(),n=0;n").text(o[n]);(0,r.default)(e).append(s)}}o("./node_modules/codemirror/mode/htmlmixed/htmlmixed.js"),(0,r.default)(function(){var s=i.default.fromTextArea(document.getElementById("theme-header"),{lineNumbers:!0,lineWrapping:!0,mode:"htmlmixed",htmlMode:!0});i.default.fromTextArea(document.getElementById("theme-footer"),{lineNumbers:!0,lineWrapping:!0,mode:"htmlmixed",htmlMode:!0});_((0,r.default)("#start-timezone")),_((0,r.default)("#end-timezone")),_((0,r.default)("#freeze-timezone")),(0,r.default)(".config-section > form:not(.form-upload)").submit(m),(0,r.default)("#logo-upload").submit(p),(0,r.default)("#remove-logo").click(f),(0,r.default)("#export-button").click(h),(0,r.default)("#import-button").click(j),(0,r.default)("#config-color-update").click(function(){var e,t=(0,r.default)("#config-color-picker").val(),o=s.getValue();if(o.length){var n="theme-color: ".concat(t,";");e=o.replace(/theme-color: (.*);/,n)}else e='\n";s.getDoc().setValue(e)}),(0,r.default)(".start-date").change(function(){u("start")}),(0,r.default)(".end-date").change(function(){u("end")}),(0,r.default)(".freeze-date").change(function(){u("freeze")});var e=(0,r.default)("#start").val(),t=(0,r.default)("#end").val(),o=(0,r.default)("#freeze").val();e&&d("start",e),t&&d("end",t),o&&d("freeze",o),(0,r.default)("#mail_useauth").change(function(){(0,r.default)("#mail_username_password").toggle(this.checked)}).change()})},"./CTFd/themes/admin/assets/js/pages/main.js":function(e,t,o){var n=m(o("./CTFd/themes/core/assets/js/CTFd.js")),s=m(o("./node_modules/jquery/dist/jquery.js")),a=m(o("./node_modules/moment/moment.js")),i=m(o("./node_modules/nunjucks/browser/nunjucks.js")),l=o("./node_modules/howler/dist/howler.js"),r=m(o("./CTFd/themes/core/assets/js/events.js")),d=m(o("./CTFd/themes/core/assets/js/times.js")),c=m(o("./CTFd/themes/admin/assets/js/styles.js")),u=m(o("./CTFd/themes/core/assets/js/helpers.js"));function m(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=u.default,window.$=s.default,window.Moment=a.default,window.nunjucks=i.default,window.Howl=l.Howl,(0,s.default)(function(){(0,c.default)(),(0,d.default)(),(0,r.default)(n.default.config.urlRoot)})},"./CTFd/themes/admin/assets/js/styles.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/bootstrap/dist/js/bootstrap.bundle.js");var n,s=o("./CTFd/themes/core/assets/js/utils.js"),a=(n=o("./node_modules/jquery/dist/jquery.js"))&&n.__esModule?n:{default:n};t.default=function(){(0,a.default)(":input").each(function(){(0,a.default)(this).data("initial",(0,a.default)(this).val())}),(0,a.default)(".form-control").bind({focus:function(){(0,a.default)(this).addClass("input-filled-valid")},blur:function(){""===(0,a.default)(this).val()&&(0,a.default)(this).removeClass("input-filled-valid")}}),(0,a.default)(".modal").on("show.bs.modal",function(e){(0,a.default)(".form-control").each(function(){(0,a.default)(this).val()&&(0,a.default)(this).addClass("input-filled-valid")})}),(0,a.default)(function(){(0,a.default)(".form-control").each(function(){(0,a.default)(this).val()&&(0,a.default)(this).addClass("input-filled-valid")}),(0,a.default)("tr[data-href], td[data-href]").click(function(){if(!getSelection().toString()){var e=(0,a.default)(this).attr("data-href");e&&(window.location=e)}return!1}),(0,a.default)("[data-checkbox]").click(function(e){(0,a.default)(e.target).is("input[type=checkbox]")?e.stopImmediatePropagation():((0,a.default)(this).find("input[type=checkbox]").click(),e.stopImmediatePropagation())}),(0,a.default)("[data-checkbox-all]").on("click change",function(e){var t=(0,a.default)(this).prop("checked"),o=(0,a.default)(this).index()+1;(0,a.default)(this).closest("table").find("tr td:nth-child(".concat(o,") input[type=checkbox]")).prop("checked",t),e.stopImmediatePropagation()}),(0,a.default)("tr[data-href] a, tr[data-href] button").click(function(e){(0,a.default)(this).attr("data-dismiss")||e.stopPropagation()}),(0,a.default)(".page-select").change(function(){var e=new URL(window.location);e.searchParams.set("page",this.value),window.location.href=e.toString()}),(0,a.default)('a[data-toggle="tab"]').on("shown.bs.tab",function(e){sessionStorage.setItem("activeTab",(0,a.default)(e.target).attr("href"))});var e=sessionStorage.getItem("activeTab");if(e){var t=(0,a.default)('.nav-tabs a[href="'.concat(e,'"], .nav-pills a[href="').concat(e,'"]'));t.length?t.tab("show"):sessionStorage.removeItem("activeTab")}(0,s.makeSortableTables)(),(0,a.default)('[data-toggle="tooltip"]').tooltip()})}},"./CTFd/themes/core/assets/js/CTFd.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=d(o("./CTFd/themes/core/assets/js/fetch.js")),s=d(o("./CTFd/themes/core/assets/js/config.js")),a=o("./CTFd/themes/core/assets/js/api.js");o("./CTFd/themes/core/assets/js/patch.js");var i=d(o("./node_modules/markdown-it/index.js")),l=d(o("./node_modules/jquery/dist/jquery.js")),r=d(o("./CTFd/themes/core/assets/js/ezq.js"));function d(e){return e&&e.__esModule?e:{default:e}}function c(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}var u=new a.API("/"),m={},p={ezq:r.default},f={$:l.default,markdown:function(e){var t=function(t){for(var e=1;e {0} × {1}',i=' ',s='\n Error:\n {0}\n ×\n',d='\n Success!\n {0}\n ×\n',c='{0}',u='No',m='Yes';function p(e){var t=a.format(e.title),o=(0,l.default)(t);"string"==typeof e.body?o.find(".modal-body").append("".concat(e.body,"")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(c.format(e.button));return e.success&&(0,l.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),o.modal("show"),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),o}function f(e){(0,l.default)("#ezq--notifications-toast-container").length||(0,l.default)("body").append((0,l.default)("").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=r.format(e.title,e.body),o=(0,l.default)(t);if(e.onclose&&(0,l.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,l.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,a=!1!==e.animation,i=e.delay||1e4;return(0,l.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:i,animation:a}),o.toast("show"),o}function j(e){var t=a.format(e.title),o=(0,l.default)(t);"string"==typeof e.body?o.find(".modal-body").append("".concat(e.body,"")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(m),s=(0,l.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),(0,l.default)(n).click(function(){e.success()}),o.modal("show"),o}function h(e){if(e.target){var t=(0,l.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=i.format(e.width),n=a.format(e.title),s=(0,l.default)(n);return s.find(".modal-body").append((0,l.default)(o)),(0,l.default)("main").append(s),s.modal("show")}function _(e){var t={success:d,error:s}[e.type].format(e.body);return(0,l.default)(t)}var g={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:h,ezBadge:_};t.default=g},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var a=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,a(e,t)}},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,l=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function a(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function r(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,i.default)("").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,i.default)("th.sort-col").click(function(){var e=(0,i.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=a(e,s),n=a(t,s);return i.default.isNumeric(o)&&i.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,i.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o").text(c.default.tz.guess());(0,r.default)(e).append(t);for(var o=c.default.tz.names(),n=0;n").text(o[n]);(0,r.default)(e).append(s)}}o("./node_modules/codemirror/mode/htmlmixed/htmlmixed.js"),(0,r.default)(function(){var s=i.default.fromTextArea(document.getElementById("theme-header"),{lineNumbers:!0,lineWrapping:!0,mode:"htmlmixed",htmlMode:!0}),t=i.default.fromTextArea(document.getElementById("theme-footer"),{lineNumbers:!0,lineWrapping:!0,mode:"htmlmixed",htmlMode:!0}),o=i.default.fromTextArea(document.getElementById("theme-settings"),{lineNumbers:!0,lineWrapping:!0,mode:{name:"javascript",json:!0}});(0,r.default)("a[href='#theme']").on("shown.bs.tab",function(e){s.refresh(),t.refresh(),o.refresh()}),(0,r.default)("#theme-settings-modal form").submit(function(e){e.preventDefault(),o.getDoc().setValue(JSON.stringify((0,r.default)(this).serializeJSON(),null,2)),(0,r.default)("#theme-settings-modal").modal("hide")}),(0,r.default)("#theme-settings-button").click(function(){var n=(0,r.default)("#theme-settings-modal form"),e=JSON.parse(o.getValue());r.default.each(e,function(e,t){var o=n.find("[name='".concat(e,"']"));switch(o.prop("type")){case"radio":case"checkbox":o.each(function(){(0,r.default)(this).attr("value")==t&&(0,r.default)(this).attr("checked",t)});break;default:o.val(t)}}),(0,r.default)("#theme-settings-modal").modal()}),_((0,r.default)("#start-timezone")),_((0,r.default)("#end-timezone")),_((0,r.default)("#freeze-timezone")),(0,r.default)(".config-section > form:not(.form-upload)").submit(m),(0,r.default)("#logo-upload").submit(p),(0,r.default)("#remove-logo").click(f),(0,r.default)("#export-button").click(h),(0,r.default)("#import-button").click(j),(0,r.default)("#config-color-update").click(function(){var e,t=(0,r.default)("#config-color-picker").val(),o=s.getValue();if(o.length){var n="theme-color: ".concat(t,";");e=o.replace(/theme-color: (.*);/,n)}else e='\n";s.getDoc().setValue(e)}),(0,r.default)(".start-date").change(function(){u("start")}),(0,r.default)(".end-date").change(function(){u("end")}),(0,r.default)(".freeze-date").change(function(){u("freeze")});var e=(0,r.default)("#start").val(),n=(0,r.default)("#end").val(),a=(0,r.default)("#freeze").val();e&&d("start",e),n&&d("end",n),a&&d("freeze",a),(0,r.default)("#mail_useauth").change(function(){(0,r.default)("#mail_username_password").toggle(this.checked)}).change()})},"./CTFd/themes/admin/assets/js/pages/main.js":function(e,t,o){var n=m(o("./CTFd/themes/core/assets/js/CTFd.js")),s=m(o("./node_modules/jquery/dist/jquery.js")),a=m(o("./node_modules/moment/moment.js")),i=m(o("./node_modules/nunjucks/browser/nunjucks.js")),l=o("./node_modules/howler/dist/howler.js"),r=m(o("./CTFd/themes/core/assets/js/events.js")),d=m(o("./CTFd/themes/core/assets/js/times.js")),c=m(o("./CTFd/themes/admin/assets/js/styles.js")),u=m(o("./CTFd/themes/core/assets/js/helpers.js"));function m(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=u.default,window.$=s.default,window.Moment=a.default,window.nunjucks=i.default,window.Howl=l.Howl,(0,s.default)(function(){(0,c.default)(),(0,d.default)(),(0,r.default)(n.default.config.urlRoot)})},"./CTFd/themes/admin/assets/js/styles.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/bootstrap/dist/js/bootstrap.bundle.js");var n,s=o("./CTFd/themes/core/assets/js/utils.js"),a=(n=o("./node_modules/jquery/dist/jquery.js"))&&n.__esModule?n:{default:n};t.default=function(){(0,a.default)(":input").each(function(){(0,a.default)(this).data("initial",(0,a.default)(this).val())}),(0,a.default)(".form-control").bind({focus:function(){(0,a.default)(this).addClass("input-filled-valid")},blur:function(){""===(0,a.default)(this).val()&&(0,a.default)(this).removeClass("input-filled-valid")}}),(0,a.default)(".modal").on("show.bs.modal",function(e){(0,a.default)(".form-control").each(function(){(0,a.default)(this).val()&&(0,a.default)(this).addClass("input-filled-valid")})}),(0,a.default)(function(){(0,a.default)(".form-control").each(function(){(0,a.default)(this).val()&&(0,a.default)(this).addClass("input-filled-valid")}),(0,a.default)("tr[data-href], td[data-href]").click(function(){if(!getSelection().toString()){var e=(0,a.default)(this).attr("data-href");e&&(window.location=e)}return!1}),(0,a.default)("[data-checkbox]").click(function(e){(0,a.default)(e.target).is("input[type=checkbox]")?e.stopImmediatePropagation():((0,a.default)(this).find("input[type=checkbox]").click(),e.stopImmediatePropagation())}),(0,a.default)("[data-checkbox-all]").on("click change",function(e){var t=(0,a.default)(this).prop("checked"),o=(0,a.default)(this).index()+1;(0,a.default)(this).closest("table").find("tr td:nth-child(".concat(o,") input[type=checkbox]")).prop("checked",t),e.stopImmediatePropagation()}),(0,a.default)("tr[data-href] a, tr[data-href] button").click(function(e){(0,a.default)(this).attr("data-dismiss")||e.stopPropagation()}),(0,a.default)(".page-select").change(function(){var e=new URL(window.location);e.searchParams.set("page",this.value),window.location.href=e.toString()}),(0,a.default)('a[data-toggle="tab"]').on("shown.bs.tab",function(e){sessionStorage.setItem("activeTab",(0,a.default)(e.target).attr("href"))});var e=sessionStorage.getItem("activeTab");if(e){var t=(0,a.default)('.nav-tabs a[href="'.concat(e,'"], .nav-pills a[href="').concat(e,'"]'));t.length?t.tab("show"):sessionStorage.removeItem("activeTab")}(0,s.makeSortableTables)(),(0,a.default)('[data-toggle="tooltip"]').tooltip()})}},"./CTFd/themes/core/assets/js/CTFd.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=d(o("./CTFd/themes/core/assets/js/fetch.js")),s=d(o("./CTFd/themes/core/assets/js/config.js")),a=o("./CTFd/themes/core/assets/js/api.js");o("./CTFd/themes/core/assets/js/patch.js");var i=d(o("./node_modules/markdown-it/index.js")),l=d(o("./node_modules/jquery/dist/jquery.js")),r=d(o("./CTFd/themes/core/assets/js/ezq.js"));function d(e){return e&&e.__esModule?e:{default:e}}function c(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}var u=new a.API("/"),m={},p={ezq:r.default},f={$:l.default,markdown:function(e){var t=function(t){for(var e=1;e {0} × {1}',i=' ',s='\n Error:\n {0}\n ×\n',d='\n Success!\n {0}\n ×\n',c='{0}',u='No',m='Yes';function p(e){var t=a.format(e.title),o=(0,l.default)(t);"string"==typeof e.body?o.find(".modal-body").append("".concat(e.body,"")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(c.format(e.button));return e.success&&(0,l.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),o.modal("show"),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),o}function f(e){(0,l.default)("#ezq--notifications-toast-container").length||(0,l.default)("body").append((0,l.default)("").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=r.format(e.title,e.body),o=(0,l.default)(t);if(e.onclose&&(0,l.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,l.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,a=!1!==e.animation,i=e.delay||1e4;return(0,l.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:i,animation:a}),o.toast("show"),o}function j(e){var t=a.format(e.title),o=(0,l.default)(t);"string"==typeof e.body?o.find(".modal-body").append("".concat(e.body,"")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(m),s=(0,l.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),(0,l.default)(n).click(function(){e.success()}),o.modal("show"),o}function h(e){if(e.target){var t=(0,l.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=i.format(e.width),n=a.format(e.title),s=(0,l.default)(n);return s.find(".modal-body").append((0,l.default)(o)),(0,l.default)("main").append(s),s.modal("show")}function _(e){var t={success:d,error:s}[e.type].format(e.body);return(0,l.default)(t)}var g={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:h,ezBadge:_};t.default=g},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var a=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,a(e,t)}},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,l=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function a(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function r(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,i.default)("").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,i.default)("th.sort-col").click(function(){var e=(0,i.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=a(e,s),n=a(t,s);return i.default.isNumeric(o)&&i.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,i.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o Appearance + + Theme + Accounts @@ -54,6 +57,8 @@ {% include "admin/configs/appearance.html" %} + {% include "admin/configs/theme.html" %} + {% include "admin/configs/accounts.html" %} {% include "admin/configs/mlc.html" %} diff --git a/CTFd/themes/admin/templates/configs/appearance.html b/CTFd/themes/admin/templates/configs/appearance.html index ec1f4afa..f501d449 100644 --- a/CTFd/themes/admin/templates/configs/appearance.html +++ b/CTFd/themes/admin/templates/configs/appearance.html @@ -76,56 +76,6 @@ - - - Theme - - Switch themes to change CTFd's aesthetics - - - - {{ ctf_theme }} - {% for theme in themes %} - {{ theme }} - {% endfor %} - - - - - - Theme Color - - Color used by theme to control aesthetics. Requires theme support. - - - - - Update CSS - - - - - - Theme Header - - Theme headers are inserted just before the </head> tag on all public facing pages. - Requires theme support. - - - {{ theme_header or "" }} - - - - - Theme Footer - - Theme footers are inserted just before the </body> tag on all public facing pages. - Requires theme support. - - - {{ theme_footer or "" }} - - Update diff --git a/CTFd/themes/admin/templates/configs/theme.html b/CTFd/themes/admin/templates/configs/theme.html new file mode 100644 index 00000000..d7e49fc9 --- /dev/null +++ b/CTFd/themes/admin/templates/configs/theme.html @@ -0,0 +1,83 @@ + + + + + + Theme Settings + + + {% include "config.html" ignore missing %} + + + + + + + + + Theme + + Switch themes to change CTFd's aesthetics + + + + {{ ctf_theme }} + {% for theme in themes %} + {{ theme }} + {% endfor %} + + + + + + Theme Color + + Color used by theme to control aesthetics. Requires theme support. + + + + + Update CSS + + + + + + Theme Header + + Theme headers are inserted just before the </head> tag on all public facing pages. + Requires theme support. + + + {{ theme_header or "" }} + + + + + Theme Footer + + Theme footers are inserted just before the </body> tag on all public facing pages. + Requires theme support. + + + {{ theme_footer or "" }} + + + + + Theme Settings + + + + Settings Editor + + + {{ theme_settings or "" }} + + Settings specific to the theme + + + + Update + + diff --git a/CTFd/themes/core/assets/js/pages/challenges.js b/CTFd/themes/core/assets/js/pages/challenges.js index 61d0d887..7afa78e1 100644 --- a/CTFd/themes/core/assets/js/pages/challenges.js +++ b/CTFd/themes/core/assets/js/pages/challenges.js @@ -62,6 +62,26 @@ const displayChal = chal => { $("#challenge-window").append(template.render(challenge_data)); + let modal = $("#challenge-window").find(".modal-dialog"); + if ( + window.init.theme_settings && + window.init.theme_settings.challenge_window_size + ) { + switch (window.init.theme_settings.challenge_window_size) { + case "sm": + modal.addClass("modal-sm"); + break; + case "lg": + modal.addClass("modal-lg"); + break; + case "xl": + modal.addClass("modal-xl"); + break; + default: + break; + } + } + $(".challenge-solves").click(function(event) { getSolves($("#challenge-id").val()); }); diff --git a/CTFd/themes/core/static/js/pages/challenges.dev.js b/CTFd/themes/core/static/js/pages/challenges.dev.js index 028b0849..ca5809dc 100644 --- a/CTFd/themes/core/static/js/pages/challenges.dev.js +++ b/CTFd/themes/core/static/js/pages/challenges.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\n__webpack_require__(/*! bootstrap/js/dist/tab */ \"./node_modules/bootstrap/js/dist/tab.js\");\n\nvar _nunjucks = _interopRequireDefault(__webpack_require__(/*! nunjucks */ \"./node_modules/nunjucks/browser/nunjucks.js\"));\n\nvar _ezq = __webpack_require__(/*! ../ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nvar _utils = __webpack_require__(/*! ../utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _moment = _interopRequireDefault(__webpack_require__(/*! moment */ \"./node_modules/moment/moment.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 _config = _interopRequireDefault(__webpack_require__(/*! ../config */ \"./CTFd/themes/core/assets/js/config.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar api_func = {\n teams: function teams(x) {\n return _CTFd.default.api.get_team_solves({\n teamId: x\n });\n },\n users: function users(x) {\n return _CTFd.default.api.get_user_solves({\n userId: x\n });\n }\n};\n\nvar md = _CTFd.default.lib.markdown();\n\n_CTFd.default._internal.challenge = {};\nvar challenges = [];\nvar solves = [];\n\nvar loadChal = function loadChal(id) {\n var chal = _jquery.default.grep(challenges, function (chal) {\n return chal.id == id;\n })[0];\n\n if (chal.type === \"hidden\") {\n (0, _ezq.ezAlert)({\n title: \"Challenge Hidden!\",\n body: \"You haven't unlocked this challenge yet!\",\n button: \"Got it!\"\n });\n return;\n }\n\n displayChal(chal);\n};\n\nvar loadChalByName = function loadChalByName(name) {\n var chal = _jquery.default.grep(challenges, function (chal) {\n return chal.name == name;\n })[0];\n\n displayChal(chal);\n};\n\nvar displayChal = function displayChal(chal) {\n return Promise.all([_CTFd.default.api.get_challenge({\n challengeId: chal.id\n }), _jquery.default.getScript(_config.default.urlRoot + chal.script), _jquery.default.get(_config.default.urlRoot + chal.template)]).then(function (responses) {\n var challenge_data = responses[0].data;\n var template_data = responses[2];\n var challenge = _CTFd.default._internal.challenge;\n (0, _jquery.default)(\"#challenge-window\").empty();\n\n var template = _nunjucks.default.compile(template_data);\n\n challenge.data = challenge_data;\n challenge.preRender();\n challenge_data[\"description\"] = challenge.render(challenge_data[\"description\"]);\n challenge_data[\"script_root\"] = _CTFd.default.config.urlRoot;\n (0, _jquery.default)(\"#challenge-window\").append(template.render(challenge_data));\n (0, _jquery.default)(\".challenge-solves\").click(function (event) {\n getSolves((0, _jquery.default)(\"#challenge-id\").val());\n });\n (0, _jquery.default)(\".nav-tabs a\").click(function (event) {\n event.preventDefault();\n (0, _jquery.default)(this).tab(\"show\");\n }); // Handle modal toggling\n\n (0, _jquery.default)(\"#challenge-window\").on(\"hide.bs.modal\", function (event) {\n (0, _jquery.default)(\"#submission-input\").removeClass(\"wrong\");\n (0, _jquery.default)(\"#submission-input\").removeClass(\"correct\");\n (0, _jquery.default)(\"#incorrect-key\").slideUp();\n (0, _jquery.default)(\"#correct-key\").slideUp();\n (0, _jquery.default)(\"#already-solved\").slideUp();\n (0, _jquery.default)(\"#too-fast\").slideUp();\n });\n (0, _jquery.default)(\".load-hint\").on(\"click\", function (event) {\n loadHint((0, _jquery.default)(this).data(\"hint-id\"));\n });\n (0, _jquery.default)(\"#submit-key\").click(function (event) {\n event.preventDefault();\n (0, _jquery.default)(\"#submit-key\").addClass(\"disabled-button\");\n (0, _jquery.default)(\"#submit-key\").prop(\"disabled\", true);\n\n _CTFd.default._internal.challenge.submit().then(renderSubmissionResponse).then(loadChals).then(markSolves);\n });\n (0, _jquery.default)(\"#submission-input\").keyup(function (event) {\n if (event.keyCode == 13) {\n (0, _jquery.default)(\"#submit-key\").click();\n }\n });\n (0, _jquery.default)(\".input-field\").bind({\n focus: function focus() {\n (0, _jquery.default)(this).parent().addClass(\"input--filled\");\n },\n blur: function blur() {\n var $this = (0, _jquery.default)(this);\n\n if ($this.val() === \"\") {\n $this.parent().removeClass(\"input--filled\");\n var $label = $this.siblings(\".input-label\");\n $label.removeClass(\"input--hide\");\n }\n }\n });\n challenge.postRender();\n window.location.replace(window.location.href.split(\"#\")[0] + \"#\" + chal.name);\n (0, _jquery.default)(\"#challenge-window\").modal();\n });\n};\n\nfunction renderSubmissionResponse(response) {\n var result = response.data;\n var result_message = (0, _jquery.default)(\"#result-message\");\n var result_notification = (0, _jquery.default)(\"#result-notification\");\n var answer_input = (0, _jquery.default)(\"#submission-input\");\n result_notification.removeClass();\n result_message.text(result.message);\n\n if (result.status === \"authentication_required\") {\n window.location = _CTFd.default.config.urlRoot + \"/login?next=\" + _CTFd.default.config.urlRoot + window.location.pathname + window.location.hash;\n return;\n } else if (result.status === \"incorrect\") {\n // Incorrect key\n result_notification.addClass(\"alert alert-danger alert-dismissable text-center\");\n result_notification.slideDown();\n answer_input.removeClass(\"correct\");\n answer_input.addClass(\"wrong\");\n setTimeout(function () {\n answer_input.removeClass(\"wrong\");\n }, 3000);\n } else if (result.status === \"correct\") {\n // Challenge Solved\n result_notification.addClass(\"alert alert-success alert-dismissable text-center\");\n result_notification.slideDown();\n (0, _jquery.default)(\".challenge-solves\").text(parseInt((0, _jquery.default)(\".challenge-solves\").text().split(\" \")[0]) + 1 + \" Solves\");\n answer_input.val(\"\");\n answer_input.removeClass(\"wrong\");\n answer_input.addClass(\"correct\");\n } else if (result.status === \"already_solved\") {\n // Challenge already solved\n result_notification.addClass(\"alert alert-info alert-dismissable text-center\");\n result_notification.slideDown();\n answer_input.addClass(\"correct\");\n } else if (result.status === \"paused\") {\n // CTF is paused\n result_notification.addClass(\"alert alert-warning alert-dismissable text-center\");\n result_notification.slideDown();\n } else if (result.status === \"ratelimited\") {\n // Keys per minute too high\n result_notification.addClass(\"alert alert-warning alert-dismissable text-center\");\n result_notification.slideDown();\n answer_input.addClass(\"too-fast\");\n setTimeout(function () {\n answer_input.removeClass(\"too-fast\");\n }, 3000);\n }\n\n setTimeout(function () {\n (0, _jquery.default)(\".alert\").slideUp();\n (0, _jquery.default)(\"#submit-key\").removeClass(\"disabled-button\");\n (0, _jquery.default)(\"#submit-key\").prop(\"disabled\", false);\n }, 3000);\n}\n\nfunction markSolves() {\n return api_func[_CTFd.default.config.userMode](\"me\").then(function (response) {\n var solves = response.data;\n\n for (var i = solves.length - 1; i >= 0; i--) {\n var btn = (0, _jquery.default)('button[value=\"' + solves[i].challenge_id + '\"]');\n btn.addClass(\"solved-challenge\");\n btn.prepend(\"\");\n }\n });\n}\n\nfunction loadUserSolves() {\n if (_CTFd.default.user.id == 0) {\n return Promise.resolve();\n }\n\n return api_func[_CTFd.default.config.userMode](\"me\").then(function (response) {\n var solves = response.data;\n\n for (var i = solves.length - 1; i >= 0; i--) {\n var chal_id = solves[i].challenge_id;\n solves.push(chal_id);\n }\n });\n}\n\nfunction getSolves(id) {\n return _CTFd.default.api.get_challenge_solves({\n challengeId: id\n }).then(function (response) {\n var data = response.data;\n (0, _jquery.default)(\".challenge-solves\").text(parseInt(data.length) + \" Solves\");\n var box = (0, _jquery.default)(\"#challenge-solves-names\");\n box.empty();\n\n for (var i = 0; i < data.length; i++) {\n var _id = data[i].account_id;\n var name = data[i].name;\n var date = (0, _moment.default)(data[i].date).local().fromNow();\n var account_url = data[i].account_url;\n box.append('{2}{3}'.format(account_url, _id, (0, _utils.htmlEntities)(name), date));\n }\n });\n}\n\nfunction loadChals() {\n return _CTFd.default.api.get_challenge_list().then(function (response) {\n var categories = [];\n var $challenges_board = (0, _jquery.default)(\"#challenges-board\");\n challenges = response.data;\n $challenges_board.empty();\n\n for (var i = challenges.length - 1; i >= 0; i--) {\n challenges[i].solves = 0;\n\n if (_jquery.default.inArray(challenges[i].category, categories) == -1) {\n var category = challenges[i].category;\n categories.push(category);\n var categoryid = category.replace(/ /g, \"-\").hashCode();\n var categoryrow = (0, _jquery.default)(\"\" + ''.format(categoryid) + '' + \"\" + '' + '' + \"\" + \"\");\n categoryrow.find(\".category-header\").append((0, _jquery.default)(\"\" + category + \"\"));\n $challenges_board.append(categoryrow);\n }\n }\n\n for (var _i = 0; _i <= challenges.length - 1; _i++) {\n var chalinfo = challenges[_i];\n var chalid = chalinfo.name.replace(/ /g, \"-\").hashCode();\n var catid = chalinfo.category.replace(/ /g, \"-\").hashCode();\n var chalwrap = (0, _jquery.default)(\"\".format(chalid));\n var chalbutton = void 0;\n\n if (solves.indexOf(chalinfo.id) == -1) {\n chalbutton = (0, _jquery.default)(\"\".format(chalinfo.id));\n } else {\n chalbutton = (0, _jquery.default)(\"\".format(chalinfo.id));\n }\n\n var chalheader = (0, _jquery.default)(\"{0}\".format(chalinfo.name));\n var chalscore = (0, _jquery.default)(\"{0}\".format(chalinfo.value));\n\n for (var j = 0; j < chalinfo.tags.length; j++) {\n var tag = \"tag-\" + chalinfo.tags[j].value.replace(/ /g, \"-\");\n chalwrap.addClass(tag);\n }\n\n chalbutton.append(chalheader);\n chalbutton.append(chalscore);\n chalwrap.append(chalbutton);\n (0, _jquery.default)(\"#\" + catid + \"-row\").find(\".category-challenges > .challenges-row\").append(chalwrap);\n }\n\n (0, _jquery.default)(\".challenge-button\").click(function (event) {\n loadChal(this.value);\n getSolves(this.value);\n });\n });\n}\n\nfunction update() {\n return loadUserSolves() // Load the user's solved challenge ids\n .then(loadChals) // Load the full list of challenges\n .then(markSolves);\n}\n\n(0, _jquery.default)(function () {\n update().then(function () {\n if (window.location.hash.length > 0) {\n loadChalByName(decodeURIComponent(window.location.hash.substring(1)));\n }\n });\n (0, _jquery.default)(\"#submission-input\").keyup(function (event) {\n if (event.keyCode == 13) {\n (0, _jquery.default)(\"#submit-key\").click();\n }\n });\n (0, _jquery.default)(\".nav-tabs a\").click(function (event) {\n event.preventDefault();\n (0, _jquery.default)(this).tab(\"show\");\n });\n (0, _jquery.default)(\"#challenge-window\").on(\"hidden.bs.modal\", function (event) {\n (0, _jquery.default)(\".nav-tabs a:first\").tab(\"show\");\n history.replaceState(\"\", window.document.title, window.location.pathname);\n });\n (0, _jquery.default)(\".challenge-solves\").click(function (event) {\n getSolves((0, _jquery.default)(\"#challenge-id\").val());\n });\n (0, _jquery.default)(\"#challenge-window\").on(\"hide.bs.modal\", function (event) {\n (0, _jquery.default)(\"#submission-input\").removeClass(\"wrong\");\n (0, _jquery.default)(\"#submission-input\").removeClass(\"correct\");\n (0, _jquery.default)(\"#incorrect-key\").slideUp();\n (0, _jquery.default)(\"#correct-key\").slideUp();\n (0, _jquery.default)(\"#already-solved\").slideUp();\n (0, _jquery.default)(\"#too-fast\").slideUp();\n });\n});\nsetInterval(update, 300000); // Update every 5 minutes.\n\nvar displayHint = function displayHint(data) {\n (0, _ezq.ezAlert)({\n title: \"Hint\",\n body: md.render(data.content),\n button: \"Got it!\"\n });\n};\n\nvar displayUnlock = function displayUnlock(id) {\n (0, _ezq.ezQuery)({\n title: \"Unlock Hint?\",\n body: \"Are you sure you want to open this hint?\",\n success: function success() {\n var params = {\n target: id,\n type: \"hints\"\n };\n\n _CTFd.default.api.post_unlock_list({}, params).then(function (response) {\n if (response.success) {\n _CTFd.default.api.get_hint({\n hintId: id\n }).then(function (response) {\n displayHint(response.data);\n });\n\n return;\n }\n\n (0, _ezq.ezAlert)({\n title: \"Error\",\n body: md.render(response.errors.score),\n button: \"Got it!\"\n });\n });\n }\n });\n};\n\nvar loadHint = function loadHint(id) {\n _CTFd.default.api.get_hint({\n hintId: id\n }).then(function (response) {\n if (response.data.content) {\n displayHint(response.data);\n return;\n }\n\n displayUnlock(id);\n });\n};\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/pages/challenges.js?"); +eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/core/assets/js/pages/main.js\");\n\n__webpack_require__(/*! bootstrap/js/dist/tab */ \"./node_modules/bootstrap/js/dist/tab.js\");\n\nvar _nunjucks = _interopRequireDefault(__webpack_require__(/*! nunjucks */ \"./node_modules/nunjucks/browser/nunjucks.js\"));\n\nvar _ezq = __webpack_require__(/*! ../ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nvar _utils = __webpack_require__(/*! ../utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _moment = _interopRequireDefault(__webpack_require__(/*! moment */ \"./node_modules/moment/moment.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 _config = _interopRequireDefault(__webpack_require__(/*! ../config */ \"./CTFd/themes/core/assets/js/config.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar api_func = {\n teams: function teams(x) {\n return _CTFd.default.api.get_team_solves({\n teamId: x\n });\n },\n users: function users(x) {\n return _CTFd.default.api.get_user_solves({\n userId: x\n });\n }\n};\n\nvar md = _CTFd.default.lib.markdown();\n\n_CTFd.default._internal.challenge = {};\nvar challenges = [];\nvar solves = [];\n\nvar loadChal = function loadChal(id) {\n var chal = _jquery.default.grep(challenges, function (chal) {\n return chal.id == id;\n })[0];\n\n if (chal.type === \"hidden\") {\n (0, _ezq.ezAlert)({\n title: \"Challenge Hidden!\",\n body: \"You haven't unlocked this challenge yet!\",\n button: \"Got it!\"\n });\n return;\n }\n\n displayChal(chal);\n};\n\nvar loadChalByName = function loadChalByName(name) {\n var chal = _jquery.default.grep(challenges, function (chal) {\n return chal.name == name;\n })[0];\n\n displayChal(chal);\n};\n\nvar displayChal = function displayChal(chal) {\n return Promise.all([_CTFd.default.api.get_challenge({\n challengeId: chal.id\n }), _jquery.default.getScript(_config.default.urlRoot + chal.script), _jquery.default.get(_config.default.urlRoot + chal.template)]).then(function (responses) {\n var challenge_data = responses[0].data;\n var template_data = responses[2];\n var challenge = _CTFd.default._internal.challenge;\n (0, _jquery.default)(\"#challenge-window\").empty();\n\n var template = _nunjucks.default.compile(template_data);\n\n challenge.data = challenge_data;\n challenge.preRender();\n challenge_data[\"description\"] = challenge.render(challenge_data[\"description\"]);\n challenge_data[\"script_root\"] = _CTFd.default.config.urlRoot;\n (0, _jquery.default)(\"#challenge-window\").append(template.render(challenge_data));\n var modal = (0, _jquery.default)(\"#challenge-window\").find(\".modal-dialog\");\n\n if (window.init.theme_settings && window.init.theme_settings.challenge_window_size) {\n switch (window.init.theme_settings.challenge_window_size) {\n case \"sm\":\n modal.addClass(\"modal-sm\");\n break;\n\n case \"lg\":\n modal.addClass(\"modal-lg\");\n break;\n\n case \"xl\":\n modal.addClass(\"modal-xl\");\n break;\n\n default:\n break;\n }\n }\n\n (0, _jquery.default)(\".challenge-solves\").click(function (event) {\n getSolves((0, _jquery.default)(\"#challenge-id\").val());\n });\n (0, _jquery.default)(\".nav-tabs a\").click(function (event) {\n event.preventDefault();\n (0, _jquery.default)(this).tab(\"show\");\n }); // Handle modal toggling\n\n (0, _jquery.default)(\"#challenge-window\").on(\"hide.bs.modal\", function (event) {\n (0, _jquery.default)(\"#submission-input\").removeClass(\"wrong\");\n (0, _jquery.default)(\"#submission-input\").removeClass(\"correct\");\n (0, _jquery.default)(\"#incorrect-key\").slideUp();\n (0, _jquery.default)(\"#correct-key\").slideUp();\n (0, _jquery.default)(\"#already-solved\").slideUp();\n (0, _jquery.default)(\"#too-fast\").slideUp();\n });\n (0, _jquery.default)(\".load-hint\").on(\"click\", function (event) {\n loadHint((0, _jquery.default)(this).data(\"hint-id\"));\n });\n (0, _jquery.default)(\"#submit-key\").click(function (event) {\n event.preventDefault();\n (0, _jquery.default)(\"#submit-key\").addClass(\"disabled-button\");\n (0, _jquery.default)(\"#submit-key\").prop(\"disabled\", true);\n\n _CTFd.default._internal.challenge.submit().then(renderSubmissionResponse).then(loadChals).then(markSolves);\n });\n (0, _jquery.default)(\"#submission-input\").keyup(function (event) {\n if (event.keyCode == 13) {\n (0, _jquery.default)(\"#submit-key\").click();\n }\n });\n (0, _jquery.default)(\".input-field\").bind({\n focus: function focus() {\n (0, _jquery.default)(this).parent().addClass(\"input--filled\");\n },\n blur: function blur() {\n var $this = (0, _jquery.default)(this);\n\n if ($this.val() === \"\") {\n $this.parent().removeClass(\"input--filled\");\n var $label = $this.siblings(\".input-label\");\n $label.removeClass(\"input--hide\");\n }\n }\n });\n challenge.postRender();\n window.location.replace(window.location.href.split(\"#\")[0] + \"#\" + chal.name);\n (0, _jquery.default)(\"#challenge-window\").modal();\n });\n};\n\nfunction renderSubmissionResponse(response) {\n var result = response.data;\n var result_message = (0, _jquery.default)(\"#result-message\");\n var result_notification = (0, _jquery.default)(\"#result-notification\");\n var answer_input = (0, _jquery.default)(\"#submission-input\");\n result_notification.removeClass();\n result_message.text(result.message);\n\n if (result.status === \"authentication_required\") {\n window.location = _CTFd.default.config.urlRoot + \"/login?next=\" + _CTFd.default.config.urlRoot + window.location.pathname + window.location.hash;\n return;\n } else if (result.status === \"incorrect\") {\n // Incorrect key\n result_notification.addClass(\"alert alert-danger alert-dismissable text-center\");\n result_notification.slideDown();\n answer_input.removeClass(\"correct\");\n answer_input.addClass(\"wrong\");\n setTimeout(function () {\n answer_input.removeClass(\"wrong\");\n }, 3000);\n } else if (result.status === \"correct\") {\n // Challenge Solved\n result_notification.addClass(\"alert alert-success alert-dismissable text-center\");\n result_notification.slideDown();\n (0, _jquery.default)(\".challenge-solves\").text(parseInt((0, _jquery.default)(\".challenge-solves\").text().split(\" \")[0]) + 1 + \" Solves\");\n answer_input.val(\"\");\n answer_input.removeClass(\"wrong\");\n answer_input.addClass(\"correct\");\n } else if (result.status === \"already_solved\") {\n // Challenge already solved\n result_notification.addClass(\"alert alert-info alert-dismissable text-center\");\n result_notification.slideDown();\n answer_input.addClass(\"correct\");\n } else if (result.status === \"paused\") {\n // CTF is paused\n result_notification.addClass(\"alert alert-warning alert-dismissable text-center\");\n result_notification.slideDown();\n } else if (result.status === \"ratelimited\") {\n // Keys per minute too high\n result_notification.addClass(\"alert alert-warning alert-dismissable text-center\");\n result_notification.slideDown();\n answer_input.addClass(\"too-fast\");\n setTimeout(function () {\n answer_input.removeClass(\"too-fast\");\n }, 3000);\n }\n\n setTimeout(function () {\n (0, _jquery.default)(\".alert\").slideUp();\n (0, _jquery.default)(\"#submit-key\").removeClass(\"disabled-button\");\n (0, _jquery.default)(\"#submit-key\").prop(\"disabled\", false);\n }, 3000);\n}\n\nfunction markSolves() {\n return api_func[_CTFd.default.config.userMode](\"me\").then(function (response) {\n var solves = response.data;\n\n for (var i = solves.length - 1; i >= 0; i--) {\n var btn = (0, _jquery.default)('button[value=\"' + solves[i].challenge_id + '\"]');\n btn.addClass(\"solved-challenge\");\n btn.prepend(\"\");\n }\n });\n}\n\nfunction loadUserSolves() {\n if (_CTFd.default.user.id == 0) {\n return Promise.resolve();\n }\n\n return api_func[_CTFd.default.config.userMode](\"me\").then(function (response) {\n var solves = response.data;\n\n for (var i = solves.length - 1; i >= 0; i--) {\n var chal_id = solves[i].challenge_id;\n solves.push(chal_id);\n }\n });\n}\n\nfunction getSolves(id) {\n return _CTFd.default.api.get_challenge_solves({\n challengeId: id\n }).then(function (response) {\n var data = response.data;\n (0, _jquery.default)(\".challenge-solves\").text(parseInt(data.length) + \" Solves\");\n var box = (0, _jquery.default)(\"#challenge-solves-names\");\n box.empty();\n\n for (var i = 0; i < data.length; i++) {\n var _id = data[i].account_id;\n var name = data[i].name;\n var date = (0, _moment.default)(data[i].date).local().fromNow();\n var account_url = data[i].account_url;\n box.append('{2}{3}'.format(account_url, _id, (0, _utils.htmlEntities)(name), date));\n }\n });\n}\n\nfunction loadChals() {\n return _CTFd.default.api.get_challenge_list().then(function (response) {\n var categories = [];\n var $challenges_board = (0, _jquery.default)(\"#challenges-board\");\n challenges = response.data;\n $challenges_board.empty();\n\n for (var i = challenges.length - 1; i >= 0; i--) {\n challenges[i].solves = 0;\n\n if (_jquery.default.inArray(challenges[i].category, categories) == -1) {\n var category = challenges[i].category;\n categories.push(category);\n var categoryid = category.replace(/ /g, \"-\").hashCode();\n var categoryrow = (0, _jquery.default)(\"\" + ''.format(categoryid) + '' + \"\" + '' + '' + \"\" + \"\");\n categoryrow.find(\".category-header\").append((0, _jquery.default)(\"\" + category + \"\"));\n $challenges_board.append(categoryrow);\n }\n }\n\n for (var _i = 0; _i <= challenges.length - 1; _i++) {\n var chalinfo = challenges[_i];\n var chalid = chalinfo.name.replace(/ /g, \"-\").hashCode();\n var catid = chalinfo.category.replace(/ /g, \"-\").hashCode();\n var chalwrap = (0, _jquery.default)(\"\".format(chalid));\n var chalbutton = void 0;\n\n if (solves.indexOf(chalinfo.id) == -1) {\n chalbutton = (0, _jquery.default)(\"\".format(chalinfo.id));\n } else {\n chalbutton = (0, _jquery.default)(\"\".format(chalinfo.id));\n }\n\n var chalheader = (0, _jquery.default)(\"{0}\".format(chalinfo.name));\n var chalscore = (0, _jquery.default)(\"{0}\".format(chalinfo.value));\n\n for (var j = 0; j < chalinfo.tags.length; j++) {\n var tag = \"tag-\" + chalinfo.tags[j].value.replace(/ /g, \"-\");\n chalwrap.addClass(tag);\n }\n\n chalbutton.append(chalheader);\n chalbutton.append(chalscore);\n chalwrap.append(chalbutton);\n (0, _jquery.default)(\"#\" + catid + \"-row\").find(\".category-challenges > .challenges-row\").append(chalwrap);\n }\n\n (0, _jquery.default)(\".challenge-button\").click(function (event) {\n loadChal(this.value);\n getSolves(this.value);\n });\n });\n}\n\nfunction update() {\n return loadUserSolves() // Load the user's solved challenge ids\n .then(loadChals) // Load the full list of challenges\n .then(markSolves);\n}\n\n(0, _jquery.default)(function () {\n update().then(function () {\n if (window.location.hash.length > 0) {\n loadChalByName(decodeURIComponent(window.location.hash.substring(1)));\n }\n });\n (0, _jquery.default)(\"#submission-input\").keyup(function (event) {\n if (event.keyCode == 13) {\n (0, _jquery.default)(\"#submit-key\").click();\n }\n });\n (0, _jquery.default)(\".nav-tabs a\").click(function (event) {\n event.preventDefault();\n (0, _jquery.default)(this).tab(\"show\");\n });\n (0, _jquery.default)(\"#challenge-window\").on(\"hidden.bs.modal\", function (event) {\n (0, _jquery.default)(\".nav-tabs a:first\").tab(\"show\");\n history.replaceState(\"\", window.document.title, window.location.pathname);\n });\n (0, _jquery.default)(\".challenge-solves\").click(function (event) {\n getSolves((0, _jquery.default)(\"#challenge-id\").val());\n });\n (0, _jquery.default)(\"#challenge-window\").on(\"hide.bs.modal\", function (event) {\n (0, _jquery.default)(\"#submission-input\").removeClass(\"wrong\");\n (0, _jquery.default)(\"#submission-input\").removeClass(\"correct\");\n (0, _jquery.default)(\"#incorrect-key\").slideUp();\n (0, _jquery.default)(\"#correct-key\").slideUp();\n (0, _jquery.default)(\"#already-solved\").slideUp();\n (0, _jquery.default)(\"#too-fast\").slideUp();\n });\n});\nsetInterval(update, 300000); // Update every 5 minutes.\n\nvar displayHint = function displayHint(data) {\n (0, _ezq.ezAlert)({\n title: \"Hint\",\n body: md.render(data.content),\n button: \"Got it!\"\n });\n};\n\nvar displayUnlock = function displayUnlock(id) {\n (0, _ezq.ezQuery)({\n title: \"Unlock Hint?\",\n body: \"Are you sure you want to open this hint?\",\n success: function success() {\n var params = {\n target: id,\n type: \"hints\"\n };\n\n _CTFd.default.api.post_unlock_list({}, params).then(function (response) {\n if (response.success) {\n _CTFd.default.api.get_hint({\n hintId: id\n }).then(function (response) {\n displayHint(response.data);\n });\n\n return;\n }\n\n (0, _ezq.ezAlert)({\n title: \"Error\",\n body: md.render(response.errors.score),\n button: \"Got it!\"\n });\n });\n }\n });\n};\n\nvar loadHint = function loadHint(id) {\n _CTFd.default.api.get_hint({\n hintId: id\n }).then(function (response) {\n if (response.data.content) {\n displayHint(response.data);\n return;\n }\n\n displayUnlock(id);\n });\n};\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/pages/challenges.js?"); /***/ }) diff --git a/CTFd/themes/core/static/js/pages/challenges.min.js b/CTFd/themes/core/static/js/pages/challenges.min.js index ea3dfa33..36f3cf50 100644 --- a/CTFd/themes/core/static/js/pages/challenges.min.js +++ b/CTFd/themes/core/static/js/pages/challenges.min.js @@ -1 +1 @@ -!function(r){function e(e){for(var t,o,n=e[0],s=e[1],a=e[2],i=0,l=[];i {0} × {1}',i=' ',s='\n Error:\n {0}\n ×\n',d='\n Success!\n {0}\n ×\n',c='{0}',u='No',m='Yes';function p(e){var t=a.format(e.title),o=(0,l.default)(t);"string"==typeof e.body?o.find(".modal-body").append("".concat(e.body,"")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(c.format(e.button));return e.success&&(0,l.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),o.modal("show"),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),o}function f(e){(0,l.default)("#ezq--notifications-toast-container").length||(0,l.default)("body").append((0,l.default)("").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=r.format(e.title,e.body),o=(0,l.default)(t);if(e.onclose&&(0,l.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,l.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,a=!1!==e.animation,i=e.delay||1e4;return(0,l.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:i,animation:a}),o.toast("show"),o}function j(e){var t=a.format(e.title),o=(0,l.default)(t);"string"==typeof e.body?o.find(".modal-body").append("".concat(e.body,"")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(m),s=(0,l.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),(0,l.default)(n).click(function(){e.success()}),o.modal("show"),o}function h(e){if(e.target){var t=(0,l.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=i.format(e.width),n=a.format(e.title),s=(0,l.default)(n);return s.find(".modal-body").append((0,l.default)(o)),(0,l.default)("main").append(s),s.modal("show")}function _(e){var t={success:d,error:s}[e.type].format(e.body);return(0,l.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:h,ezBadge:_};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var a=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,a(e,t)}},"./CTFd/themes/core/assets/js/pages/challenges.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js"),o("./node_modules/bootstrap/js/dist/tab.js");var i=a(o("./node_modules/nunjucks/browser/nunjucks.js")),n=o("./CTFd/themes/core/assets/js/ezq.js"),r=o("./CTFd/themes/core/assets/js/utils.js"),d=a(o("./node_modules/moment/moment.js")),_=a(o("./node_modules/jquery/dist/jquery.js")),l=a(o("./CTFd/themes/core/assets/js/CTFd.js")),s=a(o("./CTFd/themes/core/assets/js/config.js"));function a(e){return e&&e.__esModule?e:{default:e}}var c={teams:function(e){return l.default.api.get_team_solves({teamId:e})},users:function(e){return l.default.api.get_user_solves({userId:e})}},u=l.default.lib.markdown();l.default._internal.challenge={};var v=[],g=[],y=function(t){var e=_.default.grep(v,function(e){return e.id==t})[0];"hidden"!==e.type?m(e):(0,n.ezAlert)({title:"Challenge Hidden!",body:"You haven't unlocked this challenge yet!",button:"Got it!"})},m=function(a){return Promise.all([l.default.api.get_challenge({challengeId:a.id}),_.default.getScript(s.default.urlRoot+a.script),_.default.get(s.default.urlRoot+a.template)]).then(function(e){var t=e[0].data,o=e[2],n=l.default._internal.challenge;(0,_.default)("#challenge-window").empty();var s=i.default.compile(o);n.data=t,n.preRender(),t.description=n.render(t.description),t.script_root=l.default.config.urlRoot,(0,_.default)("#challenge-window").append(s.render(t)),(0,_.default)(".challenge-solves").click(function(e){b((0,_.default)("#challenge-id").val())}),(0,_.default)(".nav-tabs a").click(function(e){e.preventDefault(),(0,_.default)(this).tab("show")}),(0,_.default)("#challenge-window").on("hide.bs.modal",function(e){(0,_.default)("#submission-input").removeClass("wrong"),(0,_.default)("#submission-input").removeClass("correct"),(0,_.default)("#incorrect-key").slideUp(),(0,_.default)("#correct-key").slideUp(),(0,_.default)("#already-solved").slideUp(),(0,_.default)("#too-fast").slideUp()}),(0,_.default)(".load-hint").on("click",function(e){w((0,_.default)(this).data("hint-id"))}),(0,_.default)("#submit-key").click(function(e){e.preventDefault(),(0,_.default)("#submit-key").addClass("disabled-button"),(0,_.default)("#submit-key").prop("disabled",!0),l.default._internal.challenge.submit().then(p).then(j).then(f)}),(0,_.default)("#submission-input").keyup(function(e){13==e.keyCode&&(0,_.default)("#submit-key").click()}),(0,_.default)(".input-field").bind({focus:function(){(0,_.default)(this).parent().addClass("input--filled")},blur:function(){var e=(0,_.default)(this);""===e.val()&&(e.parent().removeClass("input--filled"),e.siblings(".input-label").removeClass("input--hide"))}}),n.postRender(),window.location.replace(window.location.href.split("#")[0]+"#"+a.name),(0,_.default)("#challenge-window").modal()})};function p(e){var t=e.data,o=(0,_.default)("#result-message"),n=(0,_.default)("#result-notification"),s=(0,_.default)("#submission-input");n.removeClass(),o.text(t.message),"authentication_required"!==t.status?("incorrect"===t.status?(n.addClass("alert alert-danger alert-dismissable text-center"),n.slideDown(),s.removeClass("correct"),s.addClass("wrong"),setTimeout(function(){s.removeClass("wrong")},3e3)):"correct"===t.status?(n.addClass("alert alert-success alert-dismissable text-center"),n.slideDown(),(0,_.default)(".challenge-solves").text(parseInt((0,_.default)(".challenge-solves").text().split(" ")[0])+1+" Solves"),s.val(""),s.removeClass("wrong"),s.addClass("correct")):"already_solved"===t.status?(n.addClass("alert alert-info alert-dismissable text-center"),n.slideDown(),s.addClass("correct")):"paused"===t.status?(n.addClass("alert alert-warning alert-dismissable text-center"),n.slideDown()):"ratelimited"===t.status&&(n.addClass("alert alert-warning alert-dismissable text-center"),n.slideDown(),s.addClass("too-fast"),setTimeout(function(){s.removeClass("too-fast")},3e3)),setTimeout(function(){(0,_.default)(".alert").slideUp(),(0,_.default)("#submit-key").removeClass("disabled-button"),(0,_.default)("#submit-key").prop("disabled",!1)},3e3)):window.location=l.default.config.urlRoot+"/login?next="+l.default.config.urlRoot+window.location.pathname+window.location.hash}function f(){return c[l.default.config.userMode]("me").then(function(e){for(var t=e.data,o=t.length-1;0<=o;o--){var n=(0,_.default)('button[value="'+t[o].challenge_id+'"]');n.addClass("solved-challenge"),n.prepend("")}})}function b(e){return l.default.api.get_challenge_solves({challengeId:e}).then(function(e){var t=e.data;(0,_.default)(".challenge-solves").text(parseInt(t.length)+" Solves");var o=(0,_.default)("#challenge-solves-names");o.empty();for(var n=0;n{2}{3}'.format(l,s,(0,r.htmlEntities)(a),i))}})}function j(){return l.default.api.get_challenge_list().then(function(e){var t=[],o=(0,_.default)("#challenges-board");v=e.data,o.empty();for(var n=v.length-1;0<=n;n--)if(v[n].solves=0,-1==_.default.inArray(v[n].category,t)){var s=v[n].category;t.push(s);var a=s.replace(/ /g,"-").hashCode(),i=(0,_.default)(''.format(a)+'');i.find(".category-header").append((0,_.default)(""+s+"")),o.append(i)}for(var l=0;l<=v.length-1;l++){var r=v[l],d=r.name.replace(/ /g,"-").hashCode(),c=r.category.replace(/ /g,"-").hashCode(),u=(0,_.default)("".format(d)),m=void 0;m=-1==g.indexOf(r.id)?(0,_.default)("".format(r.id)):(0,_.default)("".format(r.id));for(var p=(0,_.default)("{0}".format(r.name)),f=(0,_.default)("{0}".format(r.value)),j=0;j .challenges-row").append(u)}(0,_.default)(".challenge-button").click(function(e){y(this.value),b(this.value)})})}function h(){return(0==l.default.user.id?Promise.resolve():c[l.default.config.userMode]("me").then(function(e){for(var t=e.data,o=t.length-1;0<=o;o--){var n=t[o].challenge_id;t.push(n)}})).then(j).then(f)}(0,_.default)(function(){h().then(function(){0>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,i.default)("").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,i.default)("th.sort-col").click(function(){var e=(0,i.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=a(e,s),n=a(t,s);return i.default.isNumeric(o)&&i.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,i.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o {0} × {1}',i=' ',s='\n Error:\n {0}\n ×\n',d='\n Success!\n {0}\n ×\n',c='{0}',u='No',m='Yes';function p(e){var t=a.format(e.title),o=(0,l.default)(t);"string"==typeof e.body?o.find(".modal-body").append("".concat(e.body,"")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(c.format(e.button));return e.success&&(0,l.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),o.modal("show"),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),o}function f(e){(0,l.default)("#ezq--notifications-toast-container").length||(0,l.default)("body").append((0,l.default)("").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=r.format(e.title,e.body),o=(0,l.default)(t);if(e.onclose&&(0,l.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,l.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,a=!1!==e.animation,i=e.delay||1e4;return(0,l.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:i,animation:a}),o.toast("show"),o}function j(e){var t=a.format(e.title),o=(0,l.default)(t);"string"==typeof e.body?o.find(".modal-body").append("".concat(e.body,"")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(m),s=(0,l.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),(0,l.default)(n).click(function(){e.success()}),o.modal("show"),o}function h(e){if(e.target){var t=(0,l.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=i.format(e.width),n=a.format(e.title),s=(0,l.default)(n);return s.find(".modal-body").append((0,l.default)(o)),(0,l.default)("main").append(s),s.modal("show")}function _(e){var t={success:d,error:s}[e.type].format(e.body);return(0,l.default)(t)}var g={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:h,ezBadge:_};t.default=g},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var a=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,a(e,t)}},"./CTFd/themes/core/assets/js/pages/challenges.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js"),o("./node_modules/bootstrap/js/dist/tab.js");var l=a(o("./node_modules/nunjucks/browser/nunjucks.js")),n=o("./CTFd/themes/core/assets/js/ezq.js"),r=o("./CTFd/themes/core/assets/js/utils.js"),d=a(o("./node_modules/moment/moment.js")),_=a(o("./node_modules/jquery/dist/jquery.js")),c=a(o("./CTFd/themes/core/assets/js/CTFd.js")),s=a(o("./CTFd/themes/core/assets/js/config.js"));function a(e){return e&&e.__esModule?e:{default:e}}var i={teams:function(e){return c.default.api.get_team_solves({teamId:e})},users:function(e){return c.default.api.get_user_solves({userId:e})}},u=c.default.lib.markdown();c.default._internal.challenge={};var g=[],v=[],y=function(t){var e=_.default.grep(g,function(e){return e.id==t})[0];"hidden"!==e.type?m(e):(0,n.ezAlert)({title:"Challenge Hidden!",body:"You haven't unlocked this challenge yet!",button:"Got it!"})},m=function(i){return Promise.all([c.default.api.get_challenge({challengeId:i.id}),_.default.getScript(s.default.urlRoot+i.script),_.default.get(s.default.urlRoot+i.template)]).then(function(e){var t=e[0].data,o=e[2],n=c.default._internal.challenge;(0,_.default)("#challenge-window").empty();var s=l.default.compile(o);n.data=t,n.preRender(),t.description=n.render(t.description),t.script_root=c.default.config.urlRoot,(0,_.default)("#challenge-window").append(s.render(t));var a=(0,_.default)("#challenge-window").find(".modal-dialog");if(window.init.theme_settings&&window.init.theme_settings.challenge_window_size)switch(window.init.theme_settings.challenge_window_size){case"sm":a.addClass("modal-sm");break;case"lg":a.addClass("modal-lg");break;case"xl":a.addClass("modal-xl")}(0,_.default)(".challenge-solves").click(function(e){b((0,_.default)("#challenge-id").val())}),(0,_.default)(".nav-tabs a").click(function(e){e.preventDefault(),(0,_.default)(this).tab("show")}),(0,_.default)("#challenge-window").on("hide.bs.modal",function(e){(0,_.default)("#submission-input").removeClass("wrong"),(0,_.default)("#submission-input").removeClass("correct"),(0,_.default)("#incorrect-key").slideUp(),(0,_.default)("#correct-key").slideUp(),(0,_.default)("#already-solved").slideUp(),(0,_.default)("#too-fast").slideUp()}),(0,_.default)(".load-hint").on("click",function(e){w((0,_.default)(this).data("hint-id"))}),(0,_.default)("#submit-key").click(function(e){e.preventDefault(),(0,_.default)("#submit-key").addClass("disabled-button"),(0,_.default)("#submit-key").prop("disabled",!0),c.default._internal.challenge.submit().then(p).then(j).then(f)}),(0,_.default)("#submission-input").keyup(function(e){13==e.keyCode&&(0,_.default)("#submit-key").click()}),(0,_.default)(".input-field").bind({focus:function(){(0,_.default)(this).parent().addClass("input--filled")},blur:function(){var e=(0,_.default)(this);""===e.val()&&(e.parent().removeClass("input--filled"),e.siblings(".input-label").removeClass("input--hide"))}}),n.postRender(),window.location.replace(window.location.href.split("#")[0]+"#"+i.name),(0,_.default)("#challenge-window").modal()})};function p(e){var t=e.data,o=(0,_.default)("#result-message"),n=(0,_.default)("#result-notification"),s=(0,_.default)("#submission-input");n.removeClass(),o.text(t.message),"authentication_required"!==t.status?("incorrect"===t.status?(n.addClass("alert alert-danger alert-dismissable text-center"),n.slideDown(),s.removeClass("correct"),s.addClass("wrong"),setTimeout(function(){s.removeClass("wrong")},3e3)):"correct"===t.status?(n.addClass("alert alert-success alert-dismissable text-center"),n.slideDown(),(0,_.default)(".challenge-solves").text(parseInt((0,_.default)(".challenge-solves").text().split(" ")[0])+1+" Solves"),s.val(""),s.removeClass("wrong"),s.addClass("correct")):"already_solved"===t.status?(n.addClass("alert alert-info alert-dismissable text-center"),n.slideDown(),s.addClass("correct")):"paused"===t.status?(n.addClass("alert alert-warning alert-dismissable text-center"),n.slideDown()):"ratelimited"===t.status&&(n.addClass("alert alert-warning alert-dismissable text-center"),n.slideDown(),s.addClass("too-fast"),setTimeout(function(){s.removeClass("too-fast")},3e3)),setTimeout(function(){(0,_.default)(".alert").slideUp(),(0,_.default)("#submit-key").removeClass("disabled-button"),(0,_.default)("#submit-key").prop("disabled",!1)},3e3)):window.location=c.default.config.urlRoot+"/login?next="+c.default.config.urlRoot+window.location.pathname+window.location.hash}function f(){return i[c.default.config.userMode]("me").then(function(e){for(var t=e.data,o=t.length-1;0<=o;o--){var n=(0,_.default)('button[value="'+t[o].challenge_id+'"]');n.addClass("solved-challenge"),n.prepend("")}})}function b(e){return c.default.api.get_challenge_solves({challengeId:e}).then(function(e){var t=e.data;(0,_.default)(".challenge-solves").text(parseInt(t.length)+" Solves");var o=(0,_.default)("#challenge-solves-names");o.empty();for(var n=0;n{2}{3}'.format(l,s,(0,r.htmlEntities)(a),i))}})}function j(){return c.default.api.get_challenge_list().then(function(e){var t=[],o=(0,_.default)("#challenges-board");g=e.data,o.empty();for(var n=g.length-1;0<=n;n--)if(g[n].solves=0,-1==_.default.inArray(g[n].category,t)){var s=g[n].category;t.push(s);var a=s.replace(/ /g,"-").hashCode(),i=(0,_.default)(''.format(a)+'');i.find(".category-header").append((0,_.default)(""+s+"")),o.append(i)}for(var l=0;l<=g.length-1;l++){var r=g[l],d=r.name.replace(/ /g,"-").hashCode(),c=r.category.replace(/ /g,"-").hashCode(),u=(0,_.default)("".format(d)),m=void 0;m=-1==v.indexOf(r.id)?(0,_.default)("".format(r.id)):(0,_.default)("".format(r.id));for(var p=(0,_.default)("{0}".format(r.name)),f=(0,_.default)("{0}".format(r.value)),j=0;j .challenges-row").append(u)}(0,_.default)(".challenge-button").click(function(e){y(this.value),b(this.value)})})}function h(){return(0==c.default.user.id?Promise.resolve():i[c.default.config.userMode]("me").then(function(e){for(var t=e.data,o=t.length-1;0<=o;o--){var n=t[o].challenge_id;t.push(n)}})).then(j).then(f)}(0,_.default)(function(){h().then(function(){0>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,i.default)("").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,i.default)("th.sort-col").click(function(){var e=(0,i.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=a(e,s),n=a(t,s);return i.default.isNumeric(o)&&i.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,i.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o {{ Configs.theme_header }} diff --git a/CTFd/themes/core/templates/config.html b/CTFd/themes/core/templates/config.html new file mode 100644 index 00000000..cca828ad --- /dev/null +++ b/CTFd/themes/core/templates/config.html @@ -0,0 +1,12 @@ + + + Challenge Window Size + + Small + Normal + Large + Extra Large + + + Update + \ No newline at end of file
".concat(e.body,"
</head>
</body>
{0}