diff --git a/.gitignore b/.gitignore index e52e823..44033d3 100644 --- a/.gitignore +++ b/.gitignore @@ -57,9 +57,6 @@ coverage.xml .hypothesis/ .pytest_cache/ -# Translations -*.mo -*.pot # Django stuff: *.log diff --git a/CHANGELOG.md b/CHANGELOG.md index 939c8ba..70c6d7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ Changelog ========= +## Version 1.4.2 + +### Enhancements and Bugfixes: + +* Upgraded editor to use CVSS4 calculator +* Minor upgrades and enhancement + ## Version 1.4.1 ### Enhancements and Bugfixes: diff --git a/app/locale/es/LC_MESSAGES/django.mo b/app/locale/es/LC_MESSAGES/django.mo new file mode 100755 index 0000000..4bc7ded Binary files /dev/null and b/app/locale/es/LC_MESSAGES/django.mo differ diff --git a/app/locale/fr/LC_MESSAGES/django.mo b/app/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 0000000..01d213e Binary files /dev/null and b/app/locale/fr/LC_MESSAGES/django.mo differ diff --git a/app/petereport/static/cvss-v4-calculator/LICENSE b/app/petereport/static/cvss-v4-calculator/LICENSE new file mode 100644 index 0000000..2414303 --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2023 FIRST.ORG, Inc., Red Hat, and contributors + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/app/petereport/static/cvss-v4-calculator/README.md b/app/petereport/static/cvss-v4-calculator/README.md new file mode 100644 index 0000000..f9ce75b --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/README.md @@ -0,0 +1,3 @@ +# CVSS v4.0 calculator + +Deployed: https://redhatproductsecurity.github.io/cvss-v4-calculator/ \ No newline at end of file diff --git a/app/petereport/static/cvss-v4-calculator/app.js b/app/petereport/static/cvss-v4-calculator/app.js new file mode 100644 index 0000000..cee7332 --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/app.js @@ -0,0 +1,602 @@ +// Copyright FIRST, Red Hat, and contributors +// SPDX-License-Identifier: BSD-2-Clause + +const app = Vue.createApp({ + data() { + return { + cvssConfigData: cvssConfig, + maxComposedData: maxComposed, + maxSeverityData: maxSeverity, + expectedMetricOrder: expectedMetricOrder, + cvssMacroVectorDetailsData: cvssMacroVectorDetails, + cvssMacroVectorValuesData: cvssMacroVectorValues, + showDetails: false, + cvssSelected: null, + header_height: 0, + lookup: cvssLookup_global, + } + }, + methods: { + getEQMaxes(lookup, eq) { + return maxComposed["eq" + eq][lookup[eq - 1]] + }, + extractValueMetric(metric, str) { + // indexOf gives first index of the metric, we then need to go over its size + extracted = str.slice(str.indexOf(metric) + metric.length + 1) + // remove what follow + if (extracted.indexOf('/') > 0) { + metric_val = extracted.substring(0, extracted.indexOf('/')); + } + else { + // case where it is the last metric so no ending / + metric_val = extracted + } + return metric_val + }, + buttonClass(isPrimary, big = false) { + result = "cvss-btn cvss-btn-m" + if (isPrimary) { + result += " cvss-btn-primary" + } + if (!big) { + result += " cvss-btn-sm" + } + + return result + }, + scoreClass(qualScore) { + if (qualScore == "Low") { + return "c-hand text-success" + } + else if (qualScore == "Medium") { + return "c-hand text-warning" + } + else if (qualScore == "High") { + return "c-hand text-error" + } + else if (qualScore == "Critical") { + return "c-hand text-error text-bold" + } + else { + return "c-hand text-gray" + } + }, + copyVector() { + navigator.clipboard.writeText(this.vector) + window.location.hash = this.vector + }, + onButton(metric, value) { + this.cvssSelected[metric] = value + //window.location.hash = this.vector + }, + setButtonsToVector(vector) { + this.resetSelected() + metrics = vector.split("/") + // Remove hash + CVSS v4.0 prefix + prefix = metrics[0].slice(1); + if (prefix != "CVSS:4.0") { + console.log("Error invalid vector, missing CVSS v4.0 prefix") + return + } + metrics.shift() + + // Ensure compliance first + toSelect = {} + oi = 0 + for (index in metrics) { + [key, value] = metrics[index].split(":") + + expected = Object.entries(this.expectedMetricOrder)[oi++] + while (true) { + // If out of possible metrics ordering, it not a valid value thus + // the vector is invalid + if (expected == undefined) { + console.log("Error invalid vector, too many metric values") + return + } + if (key != expected[0]) { + // If not this metric but is mandatory, the vector is invalid + // As the only mandatory ones are from the Base group, 11 is the + // number of metrics part of it. + if (oi <= 11) { + console.log("Error invalid vector, missing mandatory metrics") + return + } + // If a non-mandatory, retry + expected = Object.entries(this.expectedMetricOrder)[oi++] + continue + } + break + } + // The value MUST be part of the metric's values, case insensitive + if (!expected[1].includes(value)) { + console.log("Error invalid vector, for key " + key + ", value " + value + " is not in " + expected[1]) + return + } + if (key in this.cvssSelected) { + toSelect[key] = value + } + } + + // Apply iff is compliant + for (key in toSelect) { + this.cvssSelected[key] = toSelect[key] + } + }, + m(metric) { + selected = this.cvssSelected[metric] + + // If E=X it will default to the worst case i.e. E=A + if (metric == "E" && selected == "X") { + return "A" + } + // If CR=X, IR=X or AR=X they will default to the worst case i.e. CR=H, IR=H and AR=H + if (metric == "CR" && selected == "X") { + return "H"; + } + // IR:X is the same as IR:H + if (metric == "IR" && selected == "X") { + return "H" + } + // AR:X is the same as AR:H + if (metric == "AR" && selected == "X") { + return "H" + } + + // All other environmental metrics just overwrite base score values, + // so if they’re not defined just use the base score value. + if (Object.keys(this.cvssSelected).includes("M" + metric)) { + modified_selected = this.cvssSelected["M" + metric] + if (modified_selected != "X") { + return modified_selected + } + } + + return selected + }, + //onReset() { + // window.location.hash = "" + //}, + resetSelected() { + this.cvssSelected = {} + for ([metricType, metricTypeData] of Object.entries(this.cvssConfigData)) { + for ([metricGroup, metricGroupData] of Object.entries(metricTypeData.metric_groups)) { + for ([metric, metricData] of Object.entries(metricGroupData)) { + this.cvssSelected[metricData.short] = metricData.selected + } + } + } + }, + splitObjectEntries(object, chunkSize) { + arr = Object.entries(object) + res = []; + for (let i = 0; i < arr.length; i += chunkSize) { + chunk = arr.slice(i, i + chunkSize) + res.push(chunk) + } + return res + } + }, + computed: { + vector() { + value = "CVSS:4.0" + for (metric in this.expectedMetricOrder) { + selected = this.cvssSelected[metric] + if (selected != "X") { + value = value.concat("/" + metric + ":" + selected) + } + } + + // Instead of use v-model for qualScore, vector and score update the form due the edit function + console.log("vector value: " + value) + const inputElement = document.getElementById('id_cvss_vector'); + + if (inputElement) { + inputElement.value = value; + } + + return value + + }, + macroVector() { + // EQ1: 0-AV:N and PR:N and UI:N + // 1-(AV:N or PR:N or UI:N) and not (AV:N and PR:N and UI:N) and not AV:P + // 2-AV:P or not(AV:N or PR:N or UI:N) + + if (this.m("AV") == "N" && this.m("PR") == "N" && this.m("UI") == "N") { + eq1 = "0" + } + else if ((this.m("AV") == "N" || this.m("PR") == "N" || this.m("UI") == "N") + && !(this.m("AV") == "N" && this.m("PR") == "N" && this.m("UI") == "N") + && !(this.m("AV") == "P")) { + eq1 = "1" + } + else if (this.m("AV") == "P" + || !(this.m("AV") == "N" || this.m("PR") == "N" || this.m("UI") == "N")) { + eq1 = "2" + } + + // EQ2: 0-(AC:L and AT:N) + // 1-(not(AC:L and AT:N)) + + if (this.m("AC") == "L" && this.m("AT") == "N") { + eq2 = "0" + } + else if (!(this.m("AC") == "L" && this.m("AT") == "N")) { + eq2 = "1" + } + + // EQ3: 0-(VC:H and VI:H) + // 1-(not(VC:H and VI:H) and (VC:H or VI:H or VA:H)) + // 2-not (VC:H or VI:H or VA:H) + if (this.m("VC") == "H" && this.m("VI") == "H") { + eq3 = 0 + } + else if (!(this.m("VC") == "H" && this.m("VI") == "H") + && (this.m("VC") == "H" || this.m("VI") == "H" || this.m("VA") == "H")) { + eq3 = 1 + } + else if (!(this.m("VC") == "H" || this.m("VI") == "H" || this.m("VA") == "H")) { + eq3 = 2 + } + + // EQ4: 0-(MSI:S or MSA:S) + // 1-not (MSI:S or MSA:S) and (SC:H or SI:H or SA:H) + // 2-not (MSI:S or MSA:S) and not (SC:H or SI:H or SA:H) + + if (this.m("MSI") == "S" || this.m("MSA") == "S") { + eq4 = 0 + } + else if (!(this.m("MSI") == "S" || this.m("MSA") == "S") && + (this.m("SC") == "H" || this.m("SI") == "H" || this.m("SA") == "H")) { + eq4 = 1 + } + else if (!(this.m("MSI") == "S" || this.m("MSA") == "S") && + !((this.m("SC") == "H" || this.m("SI") == "H" || this.m("SA") == "H"))) { + eq4 = 2 + } + + // EQ5: 0-E:A + // 1-E:P + // 2-E:U + + if (this.m("E") == "A") { + eq5 = 0 + } + else if (this.m("E") == "P") { + eq5 = 1 + } + else if (this.m("E") == "U") { + eq5 = 2 + } + + // EQ6: 0-(CR:H and VC:H) or (IR:H and VI:H) or (AR:H and VA:H) + // 1-not[(CR:H and VC:H) or (IR:H and VI:H) or (AR:H and VA:H)] + + if ((this.m("CR") == "H" && this.m("VC") == "H") + || (this.m("IR") == "H" && this.m("VI") == "H") + || (this.m("AR") == "H" && this.m("VA") == "H")) { + eq6 = 0 + } + else if (!((this.m("CR") == "H" && this.m("VC") == "H") + || (this.m("IR") == "H" && this.m("VI") == "H") + || (this.m("AR") == "H" && this.m("VA") == "H"))) { + eq6 = 1 + } + + macroVector_final = eq1 + eq2 + eq3 + eq4 + eq5 + eq6 + + // Instead of use v-model for qualScore, vector and score update the form due the edit function + const inputElement = document.getElementById('id_macroVector'); + + if (inputElement) { + inputElement.value = macroVector_final; + } + return macroVector_final + }, + score() { + // The following defines the index of each metric's values. + // It is used when looking for the highest vector part of the + // combinations produced by the MacroVector respective highest vectors. + AV_levels = { "N": 0.0, "A": 0.1, "L": 0.2, "P": 0.3 } + PR_levels = { "N": 0.0, "L": 0.1, "H": 0.2 } + UI_levels = { "N": 0.0, "P": 0.1, "A": 0.2 } + + AC_levels = { 'L': 0.0, 'H': 0.1 } + AT_levels = { 'N': 0.0, 'P': 0.1 } + + VC_levels = { 'H': 0.0, 'L': 0.1, 'N': 0.2 } + VI_levels = { 'H': 0.0, 'L': 0.1, 'N': 0.2 } + VA_levels = { 'H': 0.0, 'L': 0.1, 'N': 0.2 } + + SC_levels = { 'H': 0.1, 'L': 0.2, 'N': 0.3 } + SI_levels = { 'S': 0.0, 'H': 0.1, 'L': 0.2, 'N': 0.3 } + SA_levels = { 'S': 0.0, 'H': 0.1, 'L': 0.2, 'N': 0.3 } + + CR_levels = { 'H': 0.0, 'M': 0.1, 'L': 0.2 } + IR_levels = { 'H': 0.0, 'M': 0.1, 'L': 0.2 } + AR_levels = { 'H': 0.0, 'M': 0.1, 'L': 0.2 } + + E_levels = { 'U': 0.2, 'P': 0.1, 'A': 0 } + + + + macroVector = this.macroVector + + // Exception for no impact on system (shortcut) + if (["VC", "VI", "VA", "SC", "SI", "SA"].every((metric) => this.m(metric) == "N")) { + return 0.0 + } + value = this.lookup[macroVector] + + // 1. For each of the EQs: + // a. The maximal scoring difference is determined as the difference + // between the current MacroVector and the lower MacroVector. + // i. If there is no lower MacroVector the available distance is + // set to NaN and then ignored in the further calculations. + eq1_val = parseInt(macroVector[0]) + eq2_val = parseInt(macroVector[1]) + eq3_val = parseInt(macroVector[2]) + eq4_val = parseInt(macroVector[3]) + eq5_val = parseInt(macroVector[4]) + eq6_val = parseInt(macroVector[5]) + + // compute next lower macro, it can also not exist + eq1_next_lower_macro = "".concat(eq1_val + 1, eq2_val, eq3_val, eq4_val, eq5_val, eq6_val) + eq2_next_lower_macro = "".concat(eq1_val, eq2_val + 1, eq3_val, eq4_val, eq5_val, eq6_val) + + // eq3 and eq6 are related + if (eq3 == 1 && eq6 == 1) { + // 11 --> 21 + eq3eq6_next_lower_macro = "".concat(eq1_val, eq2_val, eq3_val + 1, eq4_val, eq5_val, eq6_val) + } + else if (eq3 == 0 && eq6 == 1) { + // 01 --> 11 + eq3eq6_next_lower_macro = "".concat(eq1_val, eq2_val, eq3_val + 1, eq4_val, eq5_val, eq6_val) + } + else if (eq3 == 1 && eq6 == 0) { + // 10 --> 11 + eq3eq6_next_lower_macro = "".concat(eq1_val, eq2_val, eq3_val, eq4_val, eq5_val, eq6_val + 1) + } + else if (eq3 == 0 && eq6 == 0) { + // 00 --> 01 + // 00 --> 10 + eq3eq6_next_lower_macro_left = "".concat(eq1_val, eq2_val, eq3_val, eq4_val, eq5_val, eq6_val + 1) + eq3eq6_next_lower_macro_right = "".concat(eq1_val, eq2_val, eq3_val + 1, eq4_val, eq5_val, eq6_val) + } + else { + // 21 --> 32 (do not exist) + eq3eq6_next_lower_macro = "".concat(eq1_val, eq2_val, eq3_val + 1, eq4_val, eq5_val, eq6_val + 1) + } + + + eq4_next_lower_macro = "".concat(eq1_val, eq2_val, eq3_val, eq4_val + 1, eq5_val, eq6_val) + eq5_next_lower_macro = "".concat(eq1_val, eq2_val, eq3_val, eq4_val, eq5_val + 1, eq6_val) + + + // get their score, if the next lower macro score do not exist the result is NaN + score_eq1_next_lower_macro = this.lookup[eq1_next_lower_macro] + score_eq2_next_lower_macro = this.lookup[eq2_next_lower_macro] + + if (eq3 == 0 && eq6 == 0) { + // multiple path take the one with higher score + score_eq3eq6_next_lower_macro_left = this.lookup[eq3eq6_next_lower_macro_left] + score_eq3eq6_next_lower_macro_right = this.lookup[eq3eq6_next_lower_macro_right] + + if (score_eq3eq6_next_lower_macro_left > score_eq3eq6_next_lower_macro_right) { + score_eq3eq6_next_lower_macro = score_eq3eq6_next_lower_macro_left + } + else { + score_eq3eq6_next_lower_macro = score_eq3eq6_next_lower_macro_right + } + } + else { + score_eq3eq6_next_lower_macro = this.lookup[eq3eq6_next_lower_macro] + } + + + score_eq4_next_lower_macro = this.lookup[eq4_next_lower_macro] + score_eq5_next_lower_macro = this.lookup[eq5_next_lower_macro] + + // b. The severity distance of the to-be scored vector from a + // highest severity vector in the same MacroVector is determined. + eq1_maxes = this.getEQMaxes(macroVector, 1) + eq2_maxes = this.getEQMaxes(macroVector, 2) + eq3_eq6_maxes = this.getEQMaxes(macroVector, 3)[macroVector[5]] + eq4_maxes = this.getEQMaxes(macroVector, 4) + eq5_maxes = this.getEQMaxes(macroVector, 5) + + // compose them + max_vectors = [] + for (eq1_max of eq1_maxes) { + for (eq2_max of eq2_maxes) { + for (eq3_eq6_max of eq3_eq6_maxes) { + for (eq4_max of eq4_maxes) { + for (eq5max of eq5_maxes) { + max_vectors.push(eq1_max + eq2_max + eq3_eq6_max + eq4_max + eq5max) + } + } + } + } + } + + // Find the max vector to use i.e. one in the combination of all the highests + // that is greater or equal (severity distance) than the to-be scored vector. + for (let i = 0; i < max_vectors.length; i++) { + max_vector = max_vectors[i] + severity_distance_AV = AV_levels[this.m("AV")] - AV_levels[this.extractValueMetric("AV", max_vector)] + severity_distance_PR = PR_levels[this.m("PR")] - PR_levels[this.extractValueMetric("PR", max_vector)] + severity_distance_UI = UI_levels[this.m("UI")] - UI_levels[this.extractValueMetric("UI", max_vector)] + + severity_distance_AC = AC_levels[this.m("AC")] - AC_levels[this.extractValueMetric("AC", max_vector)] + severity_distance_AT = AT_levels[this.m("AT")] - AT_levels[this.extractValueMetric("AT", max_vector)] + + severity_distance_VC = VC_levels[this.m("VC")] - VC_levels[this.extractValueMetric("VC", max_vector)] + severity_distance_VI = VI_levels[this.m("VI")] - VI_levels[this.extractValueMetric("VI", max_vector)] + severity_distance_VA = VA_levels[this.m("VA")] - VA_levels[this.extractValueMetric("VA", max_vector)] + + severity_distance_SC = SC_levels[this.m("SC")] - SC_levels[this.extractValueMetric("SC", max_vector)] + severity_distance_SI = SI_levels[this.m("SI")] - SI_levels[this.extractValueMetric("SI", max_vector)] + severity_distance_SA = SA_levels[this.m("SA")] - SA_levels[this.extractValueMetric("SA", max_vector)] + + severity_distance_CR = CR_levels[this.m("CR")] - CR_levels[this.extractValueMetric("CR", max_vector)] + severity_distance_IR = IR_levels[this.m("IR")] - IR_levels[this.extractValueMetric("IR", max_vector)] + severity_distance_AR = AR_levels[this.m("AR")] - AR_levels[this.extractValueMetric("AR", max_vector)] + + + // if any is less than zero this is not the right max + if ([severity_distance_AV, severity_distance_PR, severity_distance_UI, severity_distance_AC, severity_distance_AT, severity_distance_VC, severity_distance_VI, severity_distance_VA, severity_distance_SC, severity_distance_SI, severity_distance_SA, severity_distance_CR, severity_distance_IR, severity_distance_AR].some((met) => met < 0)) { + continue + } + // if multiple maxes exist to reach it it is enough the first one + break + } + + current_severity_distance_eq1 = severity_distance_AV + severity_distance_PR + severity_distance_UI + current_severity_distance_eq2 = severity_distance_AC + severity_distance_AT + current_severity_distance_eq3eq6 = severity_distance_VC + severity_distance_VI + severity_distance_VA + severity_distance_CR + severity_distance_IR + severity_distance_AR + current_severity_distance_eq4 = severity_distance_SC + severity_distance_SI + severity_distance_SA + current_severity_distance_eq5 = 0 + + step = 0.1 + + // if the next lower macro score do not exist the result is Nan + // Rename to maximal scoring difference (aka MSD) + available_distance_eq1 = value - score_eq1_next_lower_macro + available_distance_eq2 = value - score_eq2_next_lower_macro + available_distance_eq3eq6 = value - score_eq3eq6_next_lower_macro + available_distance_eq4 = value - score_eq4_next_lower_macro + available_distance_eq5 = value - score_eq5_next_lower_macro + + percent_to_next_eq1_severity = 0 + percent_to_next_eq2_severity = 0 + percent_to_next_eq3eq6_severity = 0 + percent_to_next_eq4_severity = 0 + percent_to_next_eq5_severity = 0 + + // some of them do not exist, we will find them by retrieving the score. If score null then do not exist + n_existing_lower = 0 + + normalized_severity_eq1 = 0 + normalized_severity_eq2 = 0 + normalized_severity_eq3eq6 = 0 + normalized_severity_eq4 = 0 + normalized_severity_eq5 = 0 + + // multiply by step because distance is pure + maxSeverity_eq1 = this.maxSeverityData["eq1"][eq1_val] * step + maxSeverity_eq2 = this.maxSeverityData["eq2"][eq2_val] * step + maxSeverity_eq3eq6 = this.maxSeverityData["eq3eq6"][eq3_val][eq6_val] * step + maxSeverity_eq4 = this.maxSeverityData["eq4"][eq4_val] * step + + // c. The proportion of the distance is determined by dividing + // the severity distance of the to-be-scored vector by the depth + // of the MacroVector. + // d. The maximal scoring difference is multiplied by the proportion of + // distance. + if (!isNaN(available_distance_eq1)) { + n_existing_lower = n_existing_lower + 1 + percent_to_next_eq1_severity = (current_severity_distance_eq1) / maxSeverity_eq1 + normalized_severity_eq1 = available_distance_eq1 * percent_to_next_eq1_severity + } + + if (!isNaN(available_distance_eq2)) { + n_existing_lower = n_existing_lower + 1 + percent_to_next_eq2_severity = (current_severity_distance_eq2) / maxSeverity_eq2 + normalized_severity_eq2 = available_distance_eq2 * percent_to_next_eq2_severity + } + + if (!isNaN(available_distance_eq3eq6)) { + n_existing_lower = n_existing_lower + 1 + percent_to_next_eq3eq6_severity = (current_severity_distance_eq3eq6) / maxSeverity_eq3eq6 + normalized_severity_eq3eq6 = available_distance_eq3eq6 * percent_to_next_eq3eq6_severity + } + + if (!isNaN(available_distance_eq4)) { + n_existing_lower = n_existing_lower + 1 + percent_to_next_eq4_severity = (current_severity_distance_eq4) / maxSeverity_eq4 + normalized_severity_eq4 = available_distance_eq4 * percent_to_next_eq4_severity + } + + if (!isNaN(available_distance_eq5)) { + // for eq5 is always 0 the percentage + n_existing_lower = n_existing_lower + 1 + percent_to_next_eq5_severity = 0 + normalized_severity_eq5 = available_distance_eq5 * percent_to_next_eq5_severity + } + + // 2. The mean of the above computed proportional distances is computed. + if (n_existing_lower == 0) { + mean_distance = 0 + } else { // sometimes we need to go up but there is nothing there, or down but there is nothing there so it's a change of 0. + mean_distance = (normalized_severity_eq1 + normalized_severity_eq2 + normalized_severity_eq3eq6 + normalized_severity_eq4 + normalized_severity_eq5) / n_existing_lower + } + + // 3. The score of the vector is the score of the MacroVector + // (i.e. the score of the highest severity vector) minus the mean + // distance so computed. This score is rounded to one decimal place. + value -= mean_distance; + if (value < 0) { + value = 0.0 + } + if (value > 10) { + value = 10.0 + } + + + // Instead of use v-model for qualScore, vector and score update the form due the edit function + const inputElement = document.getElementById('id_cvss_score'); + + if (inputElement) { + inputElement.value = value.toFixed(1); + } + + return value.toFixed(1) + }, + qualScore() { + qualScore_data = null + if (this.score == 0) { + qualScore_data = "None" + } + else if (this.score < 4.0) { + qualScore_data = "Low" + } + else if (this.score < 7.0) { + qualScore_data = "Medium" + } + else if (this.score < 9.0) { + qualScore_data = "High" + } + else { + qualScore_data = "Critical" + } + + // Instead of use v-model for qualScore, vector and score update the form due the edit function + const inputElement = document.getElementById('id_severity'); + + if (inputElement) { + inputElement.value = qualScore_data; + } + + return qualScore_data + + }, + }, + beforeMount() { + this.resetSelected() + }, + mounted() { + //this.setButtonsToVector(window.location.hash) + window.addEventListener("hashchange", () => { + this.setButtonsToVector(window.location.hash) + }) + + const resizeObserver = new ResizeObserver(() => { + this.header_height = document.getElementById('header').clientHeight + }) + + //resizeObserver.observe(document.getElementById('header')) + } +}) + +app.mount("#appCVSS") diff --git a/app/petereport/static/cvss-v4-calculator/cvss_config.js b/app/petereport/static/cvss-v4-calculator/cvss_config.js new file mode 100644 index 0000000..ee36e96 --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/cvss_config.js @@ -0,0 +1,734 @@ +// Copyright FIRST, Red Hat, and contributors +// SPDX-License-Identifier: BSD-2-Clause + +cvssConfig = { + "Base Metrics": { + "fill": "supplier", + "metric_groups": { + "Exploitability Metrics": { + "Attack Vector (AV)": { + "tooltip": "This metric reflects the context by which vulnerability exploitation is possible. This metric value (and consequently the resulting severity) will be larger the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable system. The assumption is that the number of potential attackers for a vulnerability that could be exploited from across a network is larger than the number of potential attackers that could exploit a vulnerability requiring physical access to a device, and therefore warrants a greater severity.", + "short": "AV", + "options": { + "Network (N)": { + "tooltip": "The vulnerable system is bound to the network stack and the set of possible attackers extends beyond the other options listed below, up to and including the entire Internet. Such a vulnerability is often termed “remotely exploitable” and can be thought of as an attack being exploitable at the protocol level one or more network hops away (e.g., across one or more routers).", + "value": "N" + }, + "Adjacent (A)": { + "tooltip": "The vulnerable system is bound to a protocol stack, but the attack is limited at the protocol level to a logically adjacent topology. This can mean an attack must be launched from the same shared proximity (e.g., Bluetooth, NFC, or IEEE 802.11) or logical network (e.g., local IP subnet), or from within a secure or otherwise limited administrative domain (e.g., MPLS, secure VPN within an administrative network zone).", + "value": "A" + }, + "Local (L)": { + "tooltip": "The vulnerable system is not bound to the network stack and the attacker’s path is via read/write/execute capabilities. Either the attacker exploits the vulnerability by accessing the target system locally (e.g., keyboard, console), or through terminal emulation (e.g., SSH); or the attacker relies on User Interaction by another person to perform actions required to exploit the vulnerability (e.g., using social engineering techniques to trick a legitimate user into opening a malicious document).", + "value": "L" + }, + "Physical (P)": { + "tooltip": "The attack requires the attacker to physically touch or manipulate the vulnerable system. Physical interaction may be brief (e.g., evil maid attack) or persistent.", + "value": "P" + } + }, + "selected": "N" + }, + "Attack Complexity (AC)": { + "tooltip": "This metric captures measurable actions that must be taken by the attacker to actively evade or circumvent existing built-in security-enhancing conditions in order to obtain a working exploit. These are conditions whose primary purpose is to increase security and/or increase exploit engineering complexity. A vulnerability exploitable without a target-specific variable has a lower complexity than a vulnerability that would require non-trivial customization. This metric is meant to capture security mechanisms utilized by the vulnerable system.", + "short": "AC", + "options": { + "Low (L)": { + "tooltip": "The attacker must take no measurable action to exploit the vulnerability. The attack requires no target-specific circumvention to exploit the vulnerability. An attacker can expect repeatable success against the vulnerable system.", + "value": "L" + }, + "High (H)": { + "tooltip": "The successful attack depends on the evasion or circumvention of security-enhancing techniques in place that would otherwise hinder the attack. These include: Evasion of exploit mitigation techniques, for example, circumvention of address space randomization (ASLR) or data execution prevention (DEP) must be performed for the attack to be successful; Obtaining target-specific secrets. The attacker must gather some target-specific secret before the attack can be successful. A secret is any piece of information that cannot be obtained through any amount of reconnaissance. To obtain the secret the attacker must perform additional attacks or break otherwise secure measures (e.g. knowledge of a secret key may be needed to break a crypto channel). This operation must be performed for each attacked target.", + "value": "H" + } + }, + "selected": "L" + }, + "Attack Requirements (AT)": { + "tooltip": "This metric captures the prerequisite deployment and execution conditions or variables of the vulnerable system that enable the attack. These differ from security-enhancing techniques/technologies (ref Attack Complexity) as the primary purpose of these conditions is not to explicitly mitigate attacks, but rather, emerge naturally as a consequence of the deployment and execution of the vulnerable system.", + "short": "AT", + "options": { + "None (N)": { + "tooltip": "The successful attack does not depend on the deployment and execution conditions of the vulnerable system. The attacker can expect to be able to reach the vulnerability and execute the exploit under all or most instances of the vulnerability.", + "value": "N" + }, + "Present (P)": { + "tooltip": "The successful attack depends on the presence of specific deployment and execution conditions of the vulnerable system that enable the attack. These include: a race condition must be won to successfully exploit the vulnerability (the successfulness of the attack is conditioned on execution conditions that are not under full control of the attacker, or the attack may need to be launched multiple times against a single target before being successful); the attacker must inject themselves into the logical network path between the target and the resource requested by the victim (e.g. vulnerabilities requiring an on-path attacker).", + "value": "P" + } + }, + "selected": "N" + }, + "Privileges Required (PR)": { + "tooltip": "This metric describes the level of privileges an attacker must possess prior to successfully exploiting the vulnerability. The method by which the attacker obtains privileged credentials prior to the attack (e.g., free trial accounts), is outside the scope of this metric. Generally, self-service provisioned accounts do not constitute a privilege requirement if the attacker can grant themselves privileges as part of the attack.", + "short": "PR", + "options": { + "None (N)": { + "tooltip": "The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack.", + "value": "N" + }, + "Low (L)": { + "tooltip": "The attacker requires privileges that provide basic capabilities that are typically limited to settings and resources owned by a single low-privileged user. Alternatively, an attacker with Low privileges has the ability to access only non-sensitive resources.", + "value": "L" + }, + "High (H)": { + "tooltip": "The attacker requires privileges that provide significant (e.g., administrative) control over the vulnerable system allowing full access to the vulnerable system’s settings and files.", + "value": "H" + } + }, + "selected": "N" + }, + "User Interaction (UI)": { + "tooltip": "This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable system. This metric determines whether the vulnerability can be exploited solely at the will of the attacker, or whether a separate user (or user-initiated process) must participate in some manner.", + "short": "UI", + "options": { + "None (N)": { + "tooltip": "The vulnerable system can be exploited without interaction from any human user, other than the attacker.", + "value": "N" + }, + "Passive (P)": { + "tooltip": "Successful exploitation of this vulnerability requires limited interaction by the targeted user with the vulnerable system and the attacker’s payload. These interactions would be considered involuntary and do not require that the user actively subvert protections built into the vulnerable system.", + "value": "P" + }, + "Active (A)": { + "tooltip": "Successful exploitation of this vulnerability requires a targeted user to perform specific, conscious interactions with the vulnerable system and the attacker’s payload, or the user’s interactions would actively subvert protection mechanisms which would lead to exploitation of the vulnerability.", + "value": "A" + } + }, + "selected": "N" + } + }, + "Vulnerable System Impact Metrics": { + "Confidentiality (VC)": { + "tooltip": "This metric measures the impact to the confidentiality of the information managed by the VULNERABLE SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.", + "short": "VC", + "options": { + "High (H)": { + "tooltip": "There is a total loss of confidentiality, resulting in all information within the Vulnerable System being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact. For example, an attacker steals the administrator's password, or private encryption keys of a web server.", + "value": "H" + }, + "Low (L)": { + "tooltip": "There is some loss of confidentiality. Access to some restricted information is obtained, but the attacker does not have control over what information is obtained, or the amount or kind of loss is limited. The information disclosure does not cause a direct, serious loss to the Vulnerable System.", + "value": "L" + }, + "None (N)": { + "tooltip": "There is no loss of confidentiality within the Vulnerable System.", + "value": "N" + } + }, + "selected": "N" + }, + "Integrity (VI)": { + "tooltip": "This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the VULNERABLE SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).", + "short": "VI", + "options": { + "High (H)": { + "tooltip": "There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the vulnerable system. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the vulnerable system.", + "value": "H" + }, + "Low (L)": { + "tooltip": "Modification of data is possible, but the attacker does not have control over the consequence of a modification, or the amount of modification is limited. The data modification does not have a direct, serious impact to the Vulnerable System.", + "value": "L" + }, + "None (N)": { + "tooltip": "There is no loss of integrity within the Vulnerable System.", + "value": "N" + } + }, + "selected": "N" + }, + "Availability (VA)": { + "tooltip": "This metric measures the impact to the availability of the VULNERABLE SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.", + "short": "VA", + "options": { + "High (H)": { + "tooltip": "There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the Vulnerable System; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the Vulnerable System (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable).", + "value": "H" + }, + "Low (L)": { + "tooltip": "Performance is reduced or there are interruptions in resource availability. Even if repeated exploitation of the vulnerability is possible, the attacker does not have the ability to completely deny service to legitimate users. The resources in the Vulnerable System are either partially available all of the time, or fully available only some of the time, but overall there is no direct, serious consequence to the Vulnerable System.", + "value": "L" + }, + "None (N)": { + "tooltip": "There is no impact to availability within the Vulnerable System.", + "value": "N" + } + }, + "selected": "N" + } + }, + "Subsequent System Impact Metrics": { + "Confidentiality (SC)": { + "tooltip": "This metric measures the impact to the confidentiality of the information managed by the SUBSEQUENT SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.", + "short": "SC", + "options": { + "High (H)": { + "tooltip": "There is a total loss of confidentiality, resulting in all resources within the Subsequent System being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact. For example, an attacker steals the administrator's password, or private encryption keys of a web server.", + "value": "H" + }, + "Low (L)": { + "tooltip": "There is some loss of confidentiality. Access to some restricted information is obtained, but the attacker does not have control over what information is obtained, or the amount or kind of loss is limited. The information disclosure does not cause a direct, serious loss to the Subsequent System.", + "value": "L" + }, + "None (N)": { + "tooltip": "There is no loss of confidentiality within the Subsequent System or all confidentiality impact is constrained to the Vulnerable System.", + "value": "N" + } + }, + "selected": "N" + }, + "Integrity (SI)": { + "tooltip": "This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the SUBSEQUENT SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).", + "short": "SI", + "options": { + "High (H)": { + "tooltip": "There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the Subsequent System. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the Subsequent System.", + "value": "H" + }, + "Low (L)": { + "tooltip": "Modification of data is possible, but the attacker does not have control over the consequence of a modification, or the amount of modification is limited. The data modification does not have a direct, serious impact to the Subsequent System.", + "value": "L" + }, + "None (N)": { + "tooltip": "There is no loss of integrity within the Subsequent System or all integrity impact is constrained to the Vulnerable System.", + "value": "N" + } + }, + "selected": "N" + }, + "Availability (SA)": { + "tooltip": "This metric measures the impact to the availability of the SUBSEQUENT SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.", + "short": "SA", + "options": { + "High (H)": { + "tooltip": "There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the Subsequent System; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the Subsequent System (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable).", + "value": "H" + }, + "Low (L)": { + "tooltip": "Performance is reduced or there are interruptions in resource availability. Even if repeated exploitation of the vulnerability is possible, the attacker does not have the ability to completely deny service to legitimate users. The resources in the Subsequent System are either partially available all of the time, or fully available only some of the time, but overall there is no direct, serious consequence to the Subsequent System.", + "value": "L" + }, + "None (N)": { + "tooltip": "There is no impact to availability within the Subsequent System or all availability impact is constrained to the Vulnerable System.", + "value": "N" + } + }, + "selected": "N" + } + } + } + }, + "Supplemental Metrics": { + "fill": "supplier", + "metric_groups": { + "": { + "Safety (S)": { + "tooltip": "When a system does have an intended use or fitness of purpose aligned to safety, it is possible that exploiting a vulnerability within that system may have Safety impact which can be represented in the Supplemental Metrics group. Lack of a Safety metric value being supplied does NOT mean that there may not be any Safety-related impacts.", + "short": "S", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "Negligible (N)": { + "tooltip": "Consequences of the vulnerability meet definition of IEC 61508 consequence category \"negligible.\"", + "value": "N" + }, + "Present (P)": { + "tooltip": "Consequences of the vulnerability meet definition of IEC 61508 consequence categories of \"marginal,\" \"critical,\" or \"catastrophic.\"", + "value": "P" + } + }, + "selected": "X" + }, + "Automatable (AU)": { + "tooltip": "The “ The “Automatable” metric captures the answer to the question ”Can an attacker automate exploitation events for this vulnerability across multiple targets?” based on steps 1-4 of the kill chain [Hutchins et al., 2011]. These steps are reconnaissance, weaponization, delivery, and exploitation.", + "short": "AU", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "No (N)": { + "tooltip": "Attackers cannot reliably automate all 4 steps of the kill chain for this vulnerability for some reason. These steps are reconnaissance, weaponization, delivery, and exploitation.", + "value": "N" + }, + "Yes (Y)": { + "tooltip": "Attackers can reliably automate all 4 steps of the kill chain. These steps are reconnaissance, weaponization, delivery, and exploitation (e.g., the vulnerability is “wormable”).", + "value": "Y" + } + }, + "selected": "X" + }, + "Recovery (R)": { + "tooltip": "Recovery describes the resilience of a system to recover services, in terms of performance and availability, after an attack has been performed.", + "short": "R", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "Automatic (A)": { + "tooltip": "The system recovers services automatically after an attack has been performed.", + "value": "A" + }, + "User (U)": { + "tooltip": "The system requires manual intervention by the user to recover services, after an attack has been performed.", + "value": "U" + }, + "Irrecoverable (I)": { + "tooltip": "The system services are irrecoverable by the user, after an attack has been performed.", + "value": "I" + } + }, + "selected": "X" + }, + "Value Density (V)": { + "tooltip": "Value Density describes the resources that the attacker will gain control over with a single exploitation event.", + "short": "V", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "Diffuse (D)": { + "tooltip": "The vulnerable system has limited resources. That is, the resources that the attacker will gain control over with a single exploitation event are relatively small. An example of Diffuse (think: limited) Value Density would be an attack on a single email client vulnerability.", + "value": "D" + }, + "Concentrated (C)": { + "tooltip": "The vulnerable system is rich in resources. Heuristically, such systems are often the direct responsibility of \“system operators\” rather than users. An example of Concentrated (think: broad) Value Density would be an attack on a central email server.", + "value": "C" + } + }, + "selected": "X" + }, + "Vulnerability Response Effort (RE)": { + "tooltip": "The intention of the Vulnerability Response Effort metric is to provide supplemental information on how difficult it is for consumers to provide an initial response to the impact of vulnerabilities for deployed products and services in their infrastructure. The consumer can then take this additional information on effort required into consideration when applying mitigations and/or scheduling remediation.", + "short": "RE", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "Low (L)": { + "tooltip": "The effort required to respond to a vulnerability is low/trivial. Examples include: communication on better documentation, configuration workarounds, or guidance from the vendor that does not require an immediate update, upgrade, or replacement by the consuming entity, such as firewall filter configuration.", + "value": "L" + }, + "Moderate (M)": { + "tooltip": "The actions required to respond to a vulnerability require some effort on behalf of the consumer and could cause minimal service impact to implement. Examples include: simple remote update, disabling of a subsystem, or a low-touch software upgrade such as a driver update.", + "value": "M" + }, + "High (H)": { + "tooltip": "The actions required to respond to a vulnerability are significant and/or difficult, and may possibly lead to an extended, scheduled service impact. This would need to be considered for scheduling purposes including honoring any embargo on deployment of the selected response. Alternatively, response to the vulnerability in the field is not possible remotely. The only resolution to the vulnerability involves physical replacement (e.g. units deployed would have to be recalled for a depot level repair or replacement). Examples include: a highly privileged driver update, microcode or UEFI BIOS updates, or software upgrades requiring careful analysis and understanding of any potential infrastructure impact before implementation. A UEFI BIOS update that impacts Trusted Platform Module (TPM) attestation without impacting disk encryption software such as Bit locker is a good recent example. Irreparable failures such as non-bootable flash subsystems, failed disks or solid-state drives (SSD), bad memory modules, network devices, or other non-recoverable under warranty hardware, should also be scored as having a High effort.", + "value": "H" + } + }, + "selected": "X" + }, + "Provider Urgency (U)": { + "tooltip": "To facilitate a standardized method to incorporate additional provider-supplied assessment, an optional “pass-through” Supplemental Metric called Provider Urgency is available. Note: While any assessment provider along the product supply chain may provide a Provider Urgency rating. The Penultimate Product Provider (PPP) is best positioned to provide a direct assessment of Provider Urgency.", + "short": "U", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "Clear": { + "tooltip": "Provider has assessed the impact of this vulnerability as having no urgency (Informational).", + "value": "Clear" + }, + "Green": { + "tooltip": "Provider has assessed the impact of this vulnerability as having a reduced urgency.", + "value": "Green" + }, + "Amber": { + "tooltip": "Provider has assessed the impact of this vulnerability as having a moderate urgency.", + "value": "Amber" + }, + "Red": { + "tooltip": "Provider has assessed the impact of this vulnerability as having the highest urgency.", + "value": "Red" + } + }, + "selected": "X" + } + } + } + }, + "Environmental (Modified Base Metrics)": { + "fill": "consumer", + "metric_groups": { + "Exploitability Metrics": { + "Attack Vector (MAV)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric reflects the context by which vulnerability exploitation is possible. This metric value (and consequently the resulting severity) will be larger the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable system. The assumption is that the number of potential attackers for a vulnerability that could be exploited from across a network is larger than the number of potential attackers that could exploit a vulnerability requiring physical access to a device, and therefore warrants a greater severity.", + "short": "MAV", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "Network (N)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "N" + }, + "Adjacent (A)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "A" + }, + "Local (L)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "L" + }, + "Physical (P)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "P" + } + }, + "selected": "X" + }, + "Attack Complexity (MAC)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric captures measurable actions that must be taken by the attacker to actively evade or circumvent existing built-in security-enhancing conditions in order to obtain a working exploit. These are conditions whose primary purpose is to increase security and/or increase exploit engineering complexity. A vulnerability exploitable without a target-specific variable has a lower complexity than a vulnerability that would require non-trivial customization. This metric is meant to capture security mechanisms utilized by the vulnerable system.", + "short": "MAC", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "Low (L)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "L" + }, + "High (H)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "H" + } + }, + "selected": "X" + }, + "Attack Requirements (MAT)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric captures the prerequisite deployment and execution conditions or variables of the vulnerable system that enable the attack. These differ from security-enhancing techniques/technologies (ref Attack Complexity) as the primary purpose of these conditions is not to explicitly mitigate attacks, but rather, emerge naturally as a consequence of the deployment and execution of the vulnerable system.", + "short": "MAT", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "None (N)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "N" + }, + "Present (P)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "P" + } + }, + "selected": "X" + }, + "Privileges Required (MPR)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric describes the level of privileges an attacker must possess prior to successfully exploiting the vulnerability. The method by which the attacker obtains privileged credentials prior to the attack (e.g., free trial accounts), is outside the scope of this metric. Generally, self-service provisioned accounts do not constitute a privilege requirement if the attacker can grant themselves privileges as part of the attack.", + "short": "MPR", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "None (N)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "N" + }, + "Low (L)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "L" + }, + "High (H)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "H" + } + }, + "selected": "X" + }, + "User Interaction (MUI)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable system. This metric determines whether the vulnerability can be exploited solely at the will of the attacker, or whether a separate user (or user-initiated process) must participate in some manner.", + "short": "MUI", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "None (N)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "N" + }, + "Passive (P)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "P" + }, + "Active (A)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "A" + } + }, + "selected": "X" + } + }, + "Vulnerable System Impact Metrics": { + "Confidentiality (MVC)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric measures the impact to the confidentiality of the information managed by the VULNERABLE SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.", + "short": "MVC", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "High (H)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "H" + }, + "Low (L)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "L" + }, + "None (N)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "N" + } + }, + "selected": "X" + }, + "Integrity (MVI)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the VULNERABLE SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).", + "short": "MVI", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "High (H)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "H" + }, + "Low (L)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "L" + }, + "None (N)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "N" + } + }, + "selected": "X" + }, + "Availability (MVA)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric measures the impact to the availability of the VULNERABLE SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.", + "short": "MVA", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "High (H)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "H" + }, + "Low (L)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "L" + }, + "None (N)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "N" + } + }, + "selected": "X" + } + }, + "Subsequent System Impact Metrics": { + "Confidentiality (MSC)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric measures the impact to the confidentiality of the information managed by the SUBSEQUENT SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.", + "short": "MSC", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "": { + }, + "High (H)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "H" + }, + "Low (L)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "L" + }, + "Negligible (N)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "N" + }, + }, + "selected": "X" + }, + "Integrity (MSI)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the SUBSEQUENT SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging). In addition to the logical systems defined for System of Interest, Subsequent Systems can also include impacts to humans.", + "short": "MSI", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "Safety (S)": { + "tooltip": "The exploited vulnerability will result in integrity impacts that could cause serious injury or worse (categories of \"Marginal\" or worse as described in IEC 61508) to a human actor or participant.", + "value": "S" + }, + "High (H)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "H" + }, + "Low (L)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "L" + }, + "Negligible (N)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "N" + } + }, + "selected": "X" + }, + "Availability (MSA)": { + "tooltip": "These metrics enable the consumer analyst to override individual Base metric values based on specific characteristics of a user’s environment. This metric measures the impact to the availability of the SUBSEQUENT SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system. In addition to the logical systems defined for System of Interest, Subsequent Systems can also include impacts to humans.", + "short": "MSA", + "options": { + "Not Defined (X)": { + "tooltip": "The metric has not been evaluated.", + "value": "X" + }, + "Safety (S)": { + "tooltip": "The exploited vulnerability will result in availability impacts that could cause serious injury or worse (categories of \"Marginal\" or worse as described in IEC 61508) to a human actor or participant.", + "value": "S" + }, + "High (H)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "H" + }, + "Low (L)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "L" + }, + "Negligible (N)": { + "tooltip": "This metric values has the same definition as the Base Metric value defined above.", + "value": "N" + } + }, + "selected": "X" + } + } + } + }, + "Environmental (Security Requirements)": { + "fill": "consumer", + "metric_groups": { + "": { + "Confidentiality Requirements (CR)": { + "tooltip": "This metric enables the consumer to customize the assessment depending on the importance of the affected IT asset to the analyst’s organization, measured in terms of Confidentiality. That is, if an IT asset supports a business function for which Confidentiality is most important, the analyst can assign a greater value to Confidentiality metrics relative to Integrity and Availability.", + "short": "CR", + "options": { + "Not Defined (X)": { + "tooltip": "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Environmental Score", + "value": "X" + }, + "High (H)": { + "tooltip": "Loss of Confidentiality is likely to have a catastrophic adverse effect on the organization or individuals associated with the organization.", + "value": "H" + }, + "Medium (M)": { + "tooltip": "Loss of Confidentiality is likely to have a serious adverse effect on the organization or individuals associated with the organization.", + "value": "M" + }, + "Low (L)": { + "tooltip": "Loss of Confidentiality is likely to have only a limited adverse effect on the organization or individuals associated with the organization.", + "value": "L" + } + }, + "selected": "X" + }, + "Integrity Requirements (IR)": { + "tooltip": "This metric enables the consumer to customize the assessment depending on the importance of the affected IT asset to the analyst’s organization, measured in terms of Integrity. That is, if an IT asset supports a business function for which Integrity is most important, the analyst can assign a greater value to Integrity metrics relative to Confidentiality and Availability.", + "short": "IR", + "options": { + "Not Defined (X)": { + "tooltip": "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Environmental Score", + "value": "X" + }, + "High (H)": { + "tooltip": "Loss of Integrity is likely to have a catastrophic adverse effect on the organization or individuals associated with the organization.", + "value": "H" + }, + "Medium (M)": { + "tooltip": "Loss of Integrity is likely to have a serious adverse effect on the organization or individuals associated with the organization.", + "value": "M" + }, + "Low (L)": { + "tooltip": "Loss of Integrity is likely to have only a limited adverse effect on the organization or individuals associated with the organization.", + "value": "L" + } + }, + "selected": "X" + }, + "Availability Requirements (AR)": { + "tooltip": "This metric enables the consumer to customize the assessment depending on the importance of the affected IT asset to the analyst’s organization, measured in terms of Availability. That is, if an IT asset supports a business function for which Availability is most important, the analyst can assign a greater value to Availability metrics relative to Confidentiality and Integrity.", + "short": "AR", + "options": { + "Not Defined (X)": { + "tooltip": "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Environmental Score", + "value": "X" + }, + "High (H)": { + "tooltip": "Loss of Availability is likely to have a catastrophic adverse effect on the organization or individuals associated with the organization.", + "value": "H" + }, + "Medium (M)": { + "tooltip": "Loss of Availability is likely to have a serious adverse effect on the organization or individuals associated with the organization.", + "value": "M" + }, + "Low (L)": { + "tooltip": "Loss of Availability is likely to have only a limited adverse effect on the organization or individuals associated with the organization.", + "value": "L" + } + }, + "selected": "X" + } + } + } + }, + "Threat Metrics": { + "fill": "consumer", + "metric_groups": { + "": { + "Exploit Maturity (E)": { + "tooltip": "This metric measures the likelihood of the vulnerability being attacked, and is typically based on the current state of exploit techniques, exploit code availability, or active, \"in-the-wild\" exploitation. It is the responsibility of the CVSS consumer to populate the values of Exploit Maturity (E) based on information regarding the availability of exploitation code/processes and the state of exploitation techniques. This information will be referred to as \"threat intelligence\".", + "short": "E", + "options": { + "Not Defined (X)": { + "tooltip": "The Exploit Maturity metric is not being used. Reliable threat intelligence is not available to determine Exploit Maturity characteristics.", + "value": "X" + }, + "Attacked (A)": { + "tooltip": "Based on threat intelligence sources either of the following must apply:\n· Attacks targeting this vulnerability (attempted or successful) have been reported\n· Solutions to simplify attempts to exploit the vulnerability are publicly or privately available (such as exploit toolkits)", + "value": "A" + }, + "POC (P)": { + "tooltip": "Based on threat intelligence sources each of the following must apply:\n· Proof-of-concept is publicly available\n· No knowledge of reported attempts to exploit this vulnerability\n· No knowledge of publicly available solutions used to simplify attempts to exploit the vulnerability", + "value": "P" + }, + "Unreported (U)": { + "tooltip": "Based on threat intelligence sources each of the following must apply:\n· No knowledge of publicly available proof-of-concept\n· No knowledge of reported attempts to exploit this vulnerability\n· No knowledge of publicly available solutions used to simplify attempts to exploit the vulnerability", + "value": "U" + } + }, + "selected": "X" + } + } + } + } +} diff --git a/app/petereport/static/cvss-v4-calculator/cvss_details.js b/app/petereport/static/cvss-v4-calculator/cvss_details.js new file mode 100644 index 0000000..3b68bc7 --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/cvss_details.js @@ -0,0 +1,18 @@ +// Copyright FIRST, Red Hat, and contributors +// SPDX-License-Identifier: BSD-2-Clause + +cvssMacroVectorDetails = { + "Exploitability": 0, + "Complexity": 1, + "Vulnerable system": 2, + "Subsequent system": 3, + "Exploitation": 4, + "Security requirements": 5 +} + +cvssMacroVectorValues = { + "0": "High", + "1": "Medium", + "2": "Low", + "3": "None", +} diff --git a/app/petereport/static/cvss-v4-calculator/cvss_lookup.js b/app/petereport/static/cvss-v4-calculator/cvss_lookup.js new file mode 100644 index 0000000..aecacfc --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/cvss_lookup.js @@ -0,0 +1,275 @@ +// Copyright FIRST, Red Hat, and contributors +// SPDX-License-Identifier: BSD-2-Clause + +cvssLookup_global = { + "000000": 10, + "000001": 9.9, + "000010": 9.8, + "000011": 9.5, + "000020": 9.5, + "000021": 9.2, + "000100": 10, + "000101": 9.6, + "000110": 9.3, + "000111": 8.7, + "000120": 9.1, + "000121": 8.1, + "000200": 9.3, + "000201": 9, + "000210": 8.9, + "000211": 8, + "000220": 8.1, + "000221": 6.8, + "001000": 9.8, + "001001": 9.5, + "001010": 9.5, + "001011": 9.2, + "001020": 9, + "001021": 8.4, + "001100": 9.3, + "001101": 9.2, + "001110": 8.9, + "001111": 8.1, + "001120": 8.1, + "001121": 6.5, + "001200": 8.8, + "001201": 8, + "001210": 7.8, + "001211": 7, + "001220": 6.9, + "001221": 4.8, + "002001": 9.2, + "002011": 8.2, + "002021": 7.2, + "002101": 7.9, + "002111": 6.9, + "002121": 5, + "002201": 6.9, + "002211": 5.5, + "002221": 2.7, + "010000": 9.9, + "010001": 9.7, + "010010": 9.5, + "010011": 9.2, + "010020": 9.2, + "010021": 8.5, + "010100": 9.5, + "010101": 9.1, + "010110": 9, + "010111": 8.3, + "010120": 8.4, + "010121": 7.1, + "010200": 9.2, + "010201": 8.1, + "010210": 8.2, + "010211": 7.1, + "010220": 7.2, + "010221": 5.3, + "011000": 9.5, + "011001": 9.3, + "011010": 9.2, + "011011": 8.5, + "011020": 8.5, + "011021": 7.3, + "011100": 9.2, + "011101": 8.2, + "011110": 8, + "011111": 7.2, + "011120": 7, + "011121": 5.9, + "011200": 8.4, + "011201": 7, + "011210": 7.1, + "011211": 5.2, + "011220": 5, + "011221": 3, + "012001": 8.6, + "012011": 7.5, + "012021": 5.2, + "012101": 7.1, + "012111": 5.2, + "012121": 2.9, + "012201": 6.3, + "012211": 2.9, + "012221": 1.7, + "100000": 9.8, + "100001": 9.5, + "100010": 9.4, + "100011": 8.7, + "100020": 9.1, + "100021": 8.1, + "100100": 9.4, + "100101": 8.9, + "100110": 8.6, + "100111": 7.4, + "100120": 7.7, + "100121": 6.4, + "100200": 8.7, + "100201": 7.5, + "100210": 7.4, + "100211": 6.3, + "100220": 6.3, + "100221": 4.9, + "101000": 9.4, + "101001": 8.9, + "101010": 8.8, + "101011": 7.7, + "101020": 7.6, + "101021": 6.7, + "101100": 8.6, + "101101": 7.6, + "101110": 7.4, + "101111": 5.8, + "101120": 5.9, + "101121": 5, + "101200": 7.2, + "101201": 5.7, + "101210": 5.7, + "101211": 5.2, + "101220": 5.2, + "101221": 2.5, + "102001": 8.3, + "102011": 7, + "102021": 5.4, + "102101": 6.5, + "102111": 5.8, + "102121": 2.6, + "102201": 5.3, + "102211": 2.1, + "102221": 1.3, + "110000": 9.5, + "110001": 9, + "110010": 8.8, + "110011": 7.6, + "110020": 7.6, + "110021": 7, + "110100": 9, + "110101": 7.7, + "110110": 7.5, + "110111": 6.2, + "110120": 6.1, + "110121": 5.3, + "110200": 7.7, + "110201": 6.6, + "110210": 6.8, + "110211": 5.9, + "110220": 5.2, + "110221": 3, + "111000": 8.9, + "111001": 7.8, + "111010": 7.6, + "111011": 6.7, + "111020": 6.2, + "111021": 5.8, + "111100": 7.4, + "111101": 5.9, + "111110": 5.7, + "111111": 5.7, + "111120": 4.7, + "111121": 2.3, + "111200": 6.1, + "111201": 5.2, + "111210": 5.7, + "111211": 2.9, + "111220": 2.4, + "111221": 1.6, + "112001": 7.1, + "112011": 5.9, + "112021": 3, + "112101": 5.8, + "112111": 2.6, + "112121": 1.5, + "112201": 2.3, + "112211": 1.3, + "112221": 0.6, + "200000": 9.3, + "200001": 8.7, + "200010": 8.6, + "200011": 7.2, + "200020": 7.5, + "200021": 5.8, + "200100": 8.6, + "200101": 7.4, + "200110": 7.4, + "200111": 6.1, + "200120": 5.6, + "200121": 3.4, + "200200": 7, + "200201": 5.4, + "200210": 5.2, + "200211": 4, + "200220": 4, + "200221": 2.2, + "201000": 8.5, + "201001": 7.5, + "201010": 7.4, + "201011": 5.5, + "201020": 6.2, + "201021": 5.1, + "201100": 7.2, + "201101": 5.7, + "201110": 5.5, + "201111": 4.1, + "201120": 4.6, + "201121": 1.9, + "201200": 5.3, + "201201": 3.6, + "201210": 3.4, + "201211": 1.9, + "201220": 1.9, + "201221": 0.8, + "202001": 6.4, + "202011": 5.1, + "202021": 2, + "202101": 4.7, + "202111": 2.1, + "202121": 1.1, + "202201": 2.4, + "202211": 0.9, + "202221": 0.4, + "210000": 8.8, + "210001": 7.5, + "210010": 7.3, + "210011": 5.3, + "210020": 6, + "210021": 5, + "210100": 7.3, + "210101": 5.5, + "210110": 5.9, + "210111": 4, + "210120": 4.1, + "210121": 2, + "210200": 5.4, + "210201": 4.3, + "210210": 4.5, + "210211": 2.2, + "210220": 2, + "210221": 1.1, + "211000": 7.5, + "211001": 5.5, + "211010": 5.8, + "211011": 4.5, + "211020": 4, + "211021": 2.1, + "211100": 6.1, + "211101": 5.1, + "211110": 4.8, + "211111": 1.8, + "211120": 2, + "211121": 0.9, + "211200": 4.6, + "211201": 1.8, + "211210": 1.7, + "211211": 0.7, + "211220": 0.8, + "211221": 0.2, + "212001": 5.3, + "212011": 2.4, + "212021": 1.4, + "212101": 2.4, + "212111": 1.2, + "212121": 0.5, + "212201": 1, + "212211": 0.3, + "212221": 0.1, +} diff --git a/app/petereport/static/cvss-v4-calculator/max_composed.js b/app/petereport/static/cvss-v4-calculator/max_composed.js new file mode 100644 index 0000000..fc62609 --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/max_composed.js @@ -0,0 +1,35 @@ +// Copyright FIRST, Red Hat, and contributors +// SPDX-License-Identifier: BSD-2-Clause + +maxComposed = { + // EQ1 + "eq1": { + 0: ["AV:N/PR:N/UI:N/"], + 1: ["AV:A/PR:N/UI:N/", "AV:N/PR:L/UI:N/", "AV:N/PR:N/UI:P/"], + 2: ["AV:P/PR:N/UI:N/", "AV:A/PR:L/UI:P/"] + }, + // EQ2 + "eq2": { + 0: ["AC:L/AT:N/"], + 1: ["AC:H/AT:N/", "AC:L/AT:P/"] + }, + // EQ3+EQ6 + "eq3": { + 0: { "0": ["VC:H/VI:H/VA:H/CR:H/IR:H/AR:H/"], "1": ["VC:H/VI:H/VA:L/CR:M/IR:M/AR:H/", "VC:H/VI:H/VA:H/CR:M/IR:M/AR:M/"] }, + 1: { "0": ["VC:L/VI:H/VA:H/CR:H/IR:H/AR:H/", "VC:H/VI:L/VA:H/CR:H/IR:H/AR:H/"], "1": ["VC:L/VI:H/VA:L/CR:H/IR:M/AR:H/", "VC:L/VI:H/VA:H/CR:H/IR:M/AR:M/", "VC:H/VI:L/VA:H/CR:M/IR:H/AR:M/", "VC:H/VI:L/VA:L/CR:M/IR:H/AR:H/", "VC:L/VI:L/VA:H/CR:H/IR:H/AR:M/"] }, + 2: { "1": ["VC:L/VI:L/VA:L/CR:H/IR:H/AR:H/"] }, + }, + // EQ4 + "eq4": { + 0: ["SC:H/SI:S/SA:S/"], + 1: ["SC:H/SI:H/SA:H/"], + 2: ["SC:L/SI:L/SA:L/"] + + }, + // EQ5 + "eq5": { + 0: ["E:A/"], + 1: ["E:P/"], + 2: ["E:U/"], + }, +} diff --git a/app/petereport/static/cvss-v4-calculator/max_severity.js b/app/petereport/static/cvss-v4-calculator/max_severity.js new file mode 100644 index 0000000..f96f407 --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/max_severity.js @@ -0,0 +1,30 @@ +// Copyright FIRST, Red Hat, and contributors +// SPDX-License-Identifier: BSD-2-Clause + +// max severity distances in EQs MacroVectors (+1) +maxSeverity = { + "eq1": { + 0: 1, + 1: 4, + 2: 5 + }, + "eq2": { + 0: 1, + 1: 2 + }, + "eq3eq6": { + 0: { 0: 7, 1: 6 }, + 1: { 0: 8, 1: 8 }, + 2: { 1: 10 } + }, + "eq4": { + 0: 6, + 1: 5, + 2: 4 + }, + "eq5": { + 0: 1, + 1: 1, + 2: 1 + }, +} diff --git a/app/petereport/static/cvss-v4-calculator/metrics.js b/app/petereport/static/cvss-v4-calculator/metrics.js new file mode 100644 index 0000000..2c0f237 --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/metrics.js @@ -0,0 +1,42 @@ +// Copyright FIRST, Red Hat, and contributors +// SPDX-License-Identifier: BSD-2-Clause + +// CVSS v4.0 metrics ordering and valid values +expectedMetricOrder = { + // Base (11 metrics) + "AV": ["N", "A", "L", "P"], + "AC": ["L", "H"], + "AT": ["N", "P"], + "PR": ["N", "L", "H"], + "UI": ["N", "P", "A"], + "VC": ["H", "L", "N"], + "VI": ["H", "L", "N"], + "VA": ["H", "L", "N"], + "SC": ["H", "L", "N"], + "SI": ["H", "L", "N"], + "SA": ["H", "L", "N"], + // Threat (1 metric) + "E": ["X", "A", "P", "U"], + // Environmental (14 metrics) + "CR": ["X", "H", "M", "L"], + "IR": ["X", "H", "M", "L"], + "AR": ["X", "H", "M", "L"], + "MAV": ["X", "N", "A", "L", "P"], + "MAC": ["X", "L", "H"], + "MAT": ["X", "N", "P"], + "MPR": ["X", "N", "L", "H"], + "MUI": ["X", "N", "P", "A"], + "MVC": ["X", "H", "L", "N"], + "MVI": ["X", "H", "L", "N"], + "MVA": ["X", "H", "L", "N"], + "MSC": ["X", "H", "L", "N"], + "MSI": ["X", "S", "H", "L", "N"], + "MSA": ["X", "S", "H", "L", "N"], + // Supplemental (6 metrics) + "S": ["X", "N", "P"], + "AU": ["X", "N", "Y"], + "R": ["X", "A", "U", "I"], + "V": ["X", "D", "C"], + "RE": ["X", "L", "M", "H"], + "U": ["X", "Clear", "Green", "Amber", "Red"], +} diff --git a/app/petereport/static/cvss-v4-calculator/spectre_petereport.css b/app/petereport/static/cvss-v4-calculator/spectre_petereport.css new file mode 100644 index 0000000..988299b --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/spectre_petereport.css @@ -0,0 +1,463 @@ +/*! Spectre.css v0.5.9 | MIT License | github.com/picturepan2/spectre */ +/* Manually forked from Normalize.css */ +/* normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */ +/** 1. Change the default font family in all browsers (opinionated). 2. Correct the line height in all browsers. 3. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS. */ +/* Document ========================================================================== */ + +.cvss-btn { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: #fff; + border: .05rem solid #5755d9; + border-radius: .1rem; + color: #5755d9; + cursor: pointer; + display: inline-block; + font-size: .9rem; + height: 1.8rem; + line-height: 1.2rem; + outline: none; + padding: .25rem .4rem; + text-align: center; + text-decoration: none; + transition: background .2s, border .2s, box-shadow .2s, color .2s; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + vertical-align: middle; + white-space: nowrap; +} + +.cvss-btn:focus { + box-shadow: 0 0 0 .1rem rgba(87, 85, 217, .2); +} + +.cvss-btn:focus, +.cvss-btn:hover { + background: #f1f1fc; + border-color: #4b48d6; + text-decoration: none; +} + +.cvss-btn:active, +.cvss-btn.active { + background: #4b48d6; + border-color: #3634d2; + color: #fff; + text-decoration: none; +} + +.cvss-btn:active.loading::after, +.cvss-btn.active.loading::after { + border-bottom-color: #fff; + border-left-color: #fff; +} + +.cvss-btn[disabled], +.cvss-btn:disabled, +.cvss-btn.disabled { + cursor: default; + opacity: .5; + pointer-events: none; +} + +.cvss-btn.cvss-btn-primary { + background: #5755d9; + border-color: #4b48d6; + color: #fff; +} + +.cvss-btn.cvss-btn-primary:focus, +.cvss-btn.cvss-btn-primary:hover { + background: #4240d4; + border-color: #3634d2; + color: #fff; +} + +.cvss-btn.cvss-btn-primary:active, +.cvss-btn.cvss-btn-primary.active { + background: #3a38d2; + border-color: #302ecd; + color: #fff; +} + +.cvss-btn.cvss-btn-primary.loading::after { + border-bottom-color: #fff; + border-left-color: #fff; +} + +.cvss-btn.cvss-btn-success { + background: #32b643; + border-color: #2faa3f; + color: #fff; +} + +.cvss-btn.cvss-btn-success:focus { + box-shadow: 0 0 0 .1rem rgba(50, 182, 67, .2); +} + +.cvss-btn.cvss-btn-success:focus, +.cvss-btn.cvss-btn-success:hover { + background: #30ae40; + border-color: #2da23c; + color: #fff; +} + +.cvss-btn.cvss-btn-success:active, +.cvss-btn.cvss-btn-success.active { + background: #2a9a39; + border-color: #278e34; + color: #fff; +} + +.cvss-btn.cvss-btn-success.loading::after { + border-bottom-color: #fff; + border-left-color: #fff; +} + +.cvss-btn.cvss-btn-error { + background: #e85600; + border-color: #d95000; + color: #fff; +} + +.cvss-btn.cvss-btn-error:focus { + box-shadow: 0 0 0 .1rem rgba(232, 86, 0, .2); +} + +.cvss-btn.cvss-btn-error:focus, +.cvss-btn.cvss-btn-error:hover { + background: #de5200; + border-color: #cf4d00; + color: #fff; +} + +.cvss-btn.cvss-btn-error:active, +.cvss-btn.cvss-btn-error.active { + background: #c44900; + border-color: #b54300; + color: #fff; +} + +.cvss-btn.cvss-btn-error.loading::after { + border-bottom-color: #fff; + border-left-color: #fff; +} + +.cvss-btn.cvss-btn-link { + background: transparent; + border-color: transparent; + color: #5755d9; +} + +.cvss-btn.cvss-btn-link:focus, +.cvss-btn.cvss-btn-link:hover, +.cvss-btn.cvss-btn-link:active, +.cvss-btn.cvss-btn-link.active { + color: #302ecd; +} + +.cvss-btn.cvss-btn-sm { + font-size: .9rem; + height: 1.4rem; + padding: .05rem .3rem; +} + +.cvss-btn.cvss-btn-lg { + font-size: .9rem; + height: 2rem; + padding: .35rem .6rem; +} + +.cvss-btn.cvss-btn-block { + display: block; + width: 100%; +} + +.cvss-btn.cvss-btn-action { + padding-left: 0; + padding-right: 0; + width: 1.8rem; +} + +.cvss-btn.cvss-btn-action.cvss-btn-sm { + width: 1.4rem; +} + +.cvss-btn.cvss-btn-action.cvss-btn-lg { + width: 2rem; +} + +.cvss-btn.cvss-btn-clear { + background: transparent; + border: 0; + color: currentColor; + height: 1rem; + line-height: .8rem; + margin-left: .2rem; + margin-right: -2px; + opacity: 1; + padding: .1rem; + text-decoration: none; + width: 1rem; +} + +.cvss-btn.cvss-btn-clear:focus, +.cvss-btn.cvss-btn-clear:hover { + background: rgba(247, 248, 249, .5); + opacity: .95; +} + +.cvss-btn.cvss-btn-clear::before { + content: "\2715"; +} + +.cvss-btn-group { + display: -ms-inline-flexbox; + display: inline-flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.cvss-btn-group .cvss-btn { + -ms-flex: 1 0 auto; + flex: 1 0 auto; +} + +.cvss-btn-group .cvss-btn:first-child:not(:last-child) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} + +.cvss-btn-group .cvss-btn:not(:first-child):not(:last-child) { + border-radius: 0; + margin-left: -.05rem; +} + +.cvss-btn-group .cvss-btn:last-child:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + margin-left: -.05rem; +} + +.cvss-btn-group .cvss-btn:focus, +.cvss-btn-group .cvss-btn:hover, +.cvss-btn-group .cvss-btn:active, +.cvss-btn-group .cvss-btn.active { + z-index: 1; +} + +.cvss-btn-group.cvss-btn-group-block { + display: -ms-flexbox; + display: flex; +} + +.cvss-btn-group.cvss-btn-group-block .cvss-btn { + -ms-flex: 1 0 0; + flex: 1 0 0; +} + + +.show-xs, +.show-sm, +.show-md, +.show-lg, +.show-xl { + display: none !important; +} + +.cols, +.columns { + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-left: -.4rem; + margin-right: -.4rem; +} + +.cols.col-gapless, +.columns.col-gapless { + margin-left: 0; + margin-right: 0; +} + +.cols.col-gapless > .column, +.columns.col-gapless > .column { + padding-left: 0; + padding-right: 0; +} + +.cols.col-oneline, +.columns.col-oneline { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + overflow-x: auto; +} + +[class~="col-"], +.column { + -ms-flex: 1; + flex: 1; + max-width: 100%; + padding-left: .4rem; + padding-right: .4rem; +} + +[class~="col-"].col-12, +[class~="col-"].col-11, +[class~="col-"].col-10, +[class~="col-"].col-9, +[class~="col-"].col-8, +[class~="col-"].col-7, +[class~="col-"].col-6, +[class~="col-"].col-5, +[class~="col-"].col-4, +[class~="col-"].col-3, +[class~="col-"].col-2, +[class~="col-"].col-1, +[class~="col-"].col-auto, +.column.col-12, +.column.col-11, +.column.col-10, +.column.col-9, +.column.col-8, +.column.col-7, +.column.col-6, +.column.col-5, +.column.col-4, +.column.col-3, +.column.col-2, +.column.col-1, +.column.col-auto { + -ms-flex: none; + flex: none; +} + +.col-12 { + width: 100%; +} + +.col-11 { + width: 91.66666667%; +} + +.col-10 { + width: 83.33333333%; +} + +.col-9 { + width: 75%; +} + +.col-8 { + width: 66.66666667%; +} + +.col-7 { + width: 58.33333333%; +} + +.col-6 { + width: 50%; +} + +.col-5 { + width: 41.66666667%; +} + +.col-4 { + width: 33.33333333%; +} + +.col-3 { + width: 25%; +} + +.col-2 { + width: 16.66666667%; +} + +.col-1 { + width: 8.33333333%; +} + +.col-auto { + -ms-flex: 0 0 auto; + flex: 0 0 auto; + max-width: none; + width: auto; +} + +.col-mx-auto { + margin-left: auto; + margin-right: auto; +} + +.col-ml-auto { + margin-left: auto; +} + +.col-mr-auto { + margin-right: auto; +} + +.bg-primary { + background: #5755d9 !important; + color: #fff; +} + +.bg-secondary { + background: #f1f1fc !important; +} + +.bg-dark { + background: #303742 !important; + color: #fff; +} + +.bg-gray { + background: #f7f8f9 !important; +} + +.bg-success { + background: #32b643 !important; + color: #fff; +} + +.bg-warning { + background: #ffb700 !important; + color: #fff; +} + +.bg-error { + background: #e85600 !important; + color: #fff; +} + +.c-hand { + cursor: pointer; +} + +.c-move { + cursor: move; +} + +.c-zoom-in { + cursor: zoom-in; +} + +.c-zoom-out { + cursor: zoom-out; +} + +.c-not-allowed { + cursor: not-allowed; +} + +.c-auto { + cursor: auto; +} + diff --git a/app/petereport/static/cvss-v4-calculator/styles.css b/app/petereport/static/cvss-v4-calculator/styles.css new file mode 100644 index 0000000..0560b1c --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/styles.css @@ -0,0 +1,129 @@ +/* +Copyright FIRST, Red Hat, and contributors +SPDX-License-Identifier: BSD-2-Clause +*/ + +h1, h2, h3, h4, h5, h6 { + margin-top: 0.4rem; +} + +h5.text-center { + padding-bottom: 0.2rem; +} + +h4.text-center { + background: #666666; + color: #ffffff; + padding: 0.2rem; + margin-bottom: 0.3rem; + border-radius: 0.3rem; +} + +h5.score-line { + padding-top: 0.5rem; +} + +h4.page-title { + color: #00400d; + padding: 0 0 0.5rem 0; +} + +mark { + overflow-wrap: break-word; + background: #090; + border: 0.05rem solid #090; + border-radius: 0.5rem; + color: #ffffff; + font-size: large; + padding: 0.5rem 0.5rem 0.5rem 0.5rem; +} + +#header { + position: fixed; + top: 0; + left: 0; + padding-left: 0.4rem; + padding-right: 0.4rem; + width: 100%; + background-color: white; + z-index: 1; + border-bottom: 1px solid lightgray; +} + +.metric-type { + background-color: #f2f2f2; + border-radius: 0.3rem; + padding: 0rem 0rem 0rem 0rem; + margin: 0rem 0rem 1rem 0rem; + border-bottom: 0.05rem solid #666666; + border-right: 0.05rem solid #666666; + border-left: 0.05rem solid #666666; +} + +.metric-group { + background-color: #f2f2f2; + padding: 10px; + padding-top: 2px; + border-radius: 0.3rem; +} + +.cvss-btn-m { + width:100%; + display:block; + border-radius: 0.3rem; +} + +/* +If we want to edit buttons, there are two options: +1) We have to override these class colors, or build our own version + of Spectre.css framework by modifying + https://github.com/picturepan2/spectre/blob/master/src/_variables.scss +2) We can override class colors below, they are copy/paste from Spectre.css framework + +Useful tools: + https://sassme.jim-nielsen.com/ + https://www.rapidtables.com/convert/color/hex-to-rgb.html +*/ + +.cvss-btn { + background: #f2f2f2; + border:.05rem solid #999999; + border-radius: 0.2rem; + color: #666666; +} + +.cvss-btn:focus, +.cvss-btn:hover { + background: #666666; + border-color: #666666; + color: #ffffff; +} + +.cvss-btn.active, +.cvss-btn:active { + background: #060; + border-color: #060; + color: #fff; +} + +.cvss-btn.cvss-btn-primary { + background: #090; + border-color: #090; + border: 0.05rem solid #060; + border-radius: 0.2rem; + color: #fff +} + +.cvss-btn.cvss-btn-primary:focus, +.cvss-btn.cvss-btn-primary:hover { + background: #060; + border-color: #060; + color: #fff +} + +.cvss-btn.cvss-btn-primary.active, +.cvss-btn.cvss-btn-primary:active { + background:#060; + border-color:#060; + color:#fff +} diff --git a/app/petereport/static/cvss-v4-calculator/vue.global.prod.js b/app/petereport/static/cvss-v4-calculator/vue.global.prod.js new file mode 100644 index 0000000..b74173c --- /dev/null +++ b/app/petereport/static/cvss-v4-calculator/vue.global.prod.js @@ -0,0 +1 @@ +var Vue=function(e){"use strict";function t(e,t){const n=Object.create(null),o=e.split(",");for(let r=0;r!!n[e.toLowerCase()]:e=>!!n[e]}const n=t("Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt");function o(e){if(E(e)){const t={};for(let n=0;n{if(e){const n=e.split(s);n.length>1&&(t[n[0].trim()]=n[1].trim())}})),t}function c(e){let t="";if(R(e))t=e;else if(E(e))for(let n=0;nh(e,t)))}const g=(e,t)=>t&&t.__v_isRef?g(e,t.value):O(t)?{[`Map(${t.size})`]:[...t.entries()].reduce(((e,[t,n])=>(e[`${t} =>`]=n,e)),{})}:A(t)?{[`Set(${t.size})`]:[...t.values()]}:!M(t)||E(t)||L(t)?t:String(t),v={},y=[],b=()=>{},_=()=>!1,S=/^on[^a-z]/,x=e=>S.test(e),C=e=>e.startsWith("onUpdate:"),k=Object.assign,w=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},T=Object.prototype.hasOwnProperty,N=(e,t)=>T.call(e,t),E=Array.isArray,O=e=>"[object Map]"===B(e),A=e=>"[object Set]"===B(e),F=e=>"[object Date]"===B(e),P=e=>"function"==typeof e,R=e=>"string"==typeof e,$=e=>"symbol"==typeof e,M=e=>null!==e&&"object"==typeof e,V=e=>M(e)&&P(e.then)&&P(e.catch),I=Object.prototype.toString,B=e=>I.call(e),L=e=>"[object Object]"===B(e),j=e=>R(e)&&"NaN"!==e&&"-"!==e[0]&&""+parseInt(e,10)===e,U=t(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),D=t("bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo"),H=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},W=/-(\w)/g,z=H((e=>e.replace(W,((e,t)=>t?t.toUpperCase():"")))),K=/\B([A-Z])/g,G=H((e=>e.replace(K,"-$1").toLowerCase())),q=H((e=>e.charAt(0).toUpperCase()+e.slice(1))),J=H((e=>e?`on${q(e)}`:"")),Z=(e,t)=>!Object.is(e,t),Y=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},X=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let ee;let te;class ne{constructor(e=!1){this.detached=e,this.active=!0,this.effects=[],this.cleanups=[],this.parent=te,!e&&te&&(this.index=(te.scopes||(te.scopes=[])).push(this)-1)}run(e){if(this.active){const t=te;try{return te=this,e()}finally{te=t}}}on(){te=this}off(){te=this.parent}stop(e){if(this.active){let t,n;for(t=0,n=this.effects.length;t{const t=new Set(e);return t.w=0,t.n=0,t},se=e=>(e.w&ae)>0,ie=e=>(e.n&ae)>0,le=new WeakMap;let ce=0,ae=1;let ue;const pe=Symbol(""),fe=Symbol("");class de{constructor(e,t=null,n){this.fn=e,this.scheduler=t,this.active=!0,this.deps=[],this.parent=void 0,oe(this,n)}run(){if(!this.active)return this.fn();let e=ue,t=me;for(;e;){if(e===this)return;e=e.parent}try{return this.parent=ue,ue=this,me=!0,ae=1<<++ce,ce<=30?(({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let o=0;o{("length"===n||n>=e)&&l.push(t)}))}else switch(void 0!==n&&l.push(i.get(n)),t){case"add":E(e)?j(n)&&l.push(i.get("length")):(l.push(i.get(pe)),O(e)&&l.push(i.get(fe)));break;case"delete":E(e)||(l.push(i.get(pe)),O(e)&&l.push(i.get(fe)));break;case"set":O(e)&&l.push(i.get(pe))}if(1===l.length)l[0]&&xe(l[0]);else{const e=[];for(const t of l)t&&e.push(...t);xe(re(e))}}function xe(e,t){const n=E(e)?e:[...e];for(const o of n)o.computed&&Ce(o);for(const o of n)o.computed||Ce(o)}function Ce(e,t){(e!==ue||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}const ke=t("__proto__,__v_isRef,__isVue"),we=new Set(Object.getOwnPropertyNames(Symbol).filter((e=>"arguments"!==e&&"caller"!==e)).map((e=>Symbol[e])).filter($)),Te=Pe(),Ne=Pe(!1,!0),Ee=Pe(!0),Oe=Pe(!0,!0),Ae=Fe();function Fe(){const e={};return["includes","indexOf","lastIndexOf"].forEach((t=>{e[t]=function(...e){const n=bt(this);for(let t=0,r=this.length;t{e[t]=function(...e){ve();const n=bt(this)[t].apply(this,e);return ye(),n}})),e}function Pe(e=!1,t=!1){return function(n,o,r){if("__v_isReactive"===o)return!e;if("__v_isReadonly"===o)return e;if("__v_isShallow"===o)return t;if("__v_raw"===o&&r===(e?t?at:ct:t?lt:it).get(n))return n;const s=E(n);if(!e&&s&&N(Ae,o))return Reflect.get(Ae,o,r);const i=Reflect.get(n,o,r);return($(o)?we.has(o):ke(o))?i:(e||be(n,0,o),t?i:wt(i)?s&&j(o)?i:i.value:M(i)?e?dt(i):pt(i):i)}}function Re(e=!1){return function(t,n,o,r){let s=t[n];if(gt(s)&&wt(s)&&!wt(o))return!1;if(!e&&(vt(o)||gt(o)||(s=bt(s),o=bt(o)),!E(t)&&wt(s)&&!wt(o)))return s.value=o,!0;const i=E(t)&&j(n)?Number(n)!0,deleteProperty:(e,t)=>!0},Ve=k({},$e,{get:Ne,set:Re(!0)}),Ie=k({},Me,{get:Oe}),Be=e=>e,Le=e=>Reflect.getPrototypeOf(e);function je(e,t,n=!1,o=!1){const r=bt(e=e.__v_raw),s=bt(t);n||(t!==s&&be(r,0,t),be(r,0,s));const{has:i}=Le(r),l=o?Be:n?xt:St;return i.call(r,t)?l(e.get(t)):i.call(r,s)?l(e.get(s)):void(e!==r&&e.get(t))}function Ue(e,t=!1){const n=this.__v_raw,o=bt(n),r=bt(e);return t||(e!==r&&be(o,0,e),be(o,0,r)),e===r?n.has(e):n.has(e)||n.has(r)}function De(e,t=!1){return e=e.__v_raw,!t&&be(bt(e),0,pe),Reflect.get(e,"size",e)}function He(e){e=bt(e);const t=bt(this);return Le(t).has.call(t,e)||(t.add(e),Se(t,"add",e,e)),this}function We(e,t){t=bt(t);const n=bt(this),{has:o,get:r}=Le(n);let s=o.call(n,e);s||(e=bt(e),s=o.call(n,e));const i=r.call(n,e);return n.set(e,t),s?Z(t,i)&&Se(n,"set",e,t):Se(n,"add",e,t),this}function ze(e){const t=bt(this),{has:n,get:o}=Le(t);let r=n.call(t,e);r||(e=bt(e),r=n.call(t,e)),o&&o.call(t,e);const s=t.delete(e);return r&&Se(t,"delete",e,void 0),s}function Ke(){const e=bt(this),t=0!==e.size,n=e.clear();return t&&Se(e,"clear",void 0,void 0),n}function Ge(e,t){return function(n,o){const r=this,s=r.__v_raw,i=bt(s),l=t?Be:e?xt:St;return!e&&be(i,0,pe),s.forEach(((e,t)=>n.call(o,l(e),l(t),r)))}}function qe(e,t,n){return function(...o){const r=this.__v_raw,s=bt(r),i=O(s),l="entries"===e||e===Symbol.iterator&&i,c="keys"===e&&i,a=r[e](...o),u=n?Be:t?xt:St;return!t&&be(s,0,c?fe:pe),{next(){const{value:e,done:t}=a.next();return t?{value:e,done:t}:{value:l?[u(e[0]),u(e[1])]:u(e),done:t}},[Symbol.iterator](){return this}}}}function Je(e){return function(...t){return"delete"!==e&&this}}function Ze(){const e={get(e){return je(this,e)},get size(){return De(this)},has:Ue,add:He,set:We,delete:ze,clear:Ke,forEach:Ge(!1,!1)},t={get(e){return je(this,e,!1,!0)},get size(){return De(this)},has:Ue,add:He,set:We,delete:ze,clear:Ke,forEach:Ge(!1,!0)},n={get(e){return je(this,e,!0)},get size(){return De(this,!0)},has(e){return Ue.call(this,e,!0)},add:Je("add"),set:Je("set"),delete:Je("delete"),clear:Je("clear"),forEach:Ge(!0,!1)},o={get(e){return je(this,e,!0,!0)},get size(){return De(this,!0)},has(e){return Ue.call(this,e,!0)},add:Je("add"),set:Je("set"),delete:Je("delete"),clear:Je("clear"),forEach:Ge(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach((r=>{e[r]=qe(r,!1,!1),n[r]=qe(r,!0,!1),t[r]=qe(r,!1,!0),o[r]=qe(r,!0,!0)})),[e,n,t,o]}const[Ye,Qe,Xe,et]=Ze();function tt(e,t){const n=t?e?et:Xe:e?Qe:Ye;return(t,o,r)=>"__v_isReactive"===o?!e:"__v_isReadonly"===o?e:"__v_raw"===o?t:Reflect.get(N(n,o)&&o in t?n:t,o,r)}const nt={get:tt(!1,!1)},ot={get:tt(!1,!0)},rt={get:tt(!0,!1)},st={get:tt(!0,!0)},it=new WeakMap,lt=new WeakMap,ct=new WeakMap,at=new WeakMap;function ut(e){return e.__v_skip||!Object.isExtensible(e)?0:function(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}((e=>B(e).slice(8,-1))(e))}function pt(e){return gt(e)?e:ht(e,!1,$e,nt,it)}function ft(e){return ht(e,!1,Ve,ot,lt)}function dt(e){return ht(e,!0,Me,rt,ct)}function ht(e,t,n,o,r){if(!M(e))return e;if(e.__v_raw&&(!t||!e.__v_isReactive))return e;const s=r.get(e);if(s)return s;const i=ut(e);if(0===i)return e;const l=new Proxy(e,2===i?o:n);return r.set(e,l),l}function mt(e){return gt(e)?mt(e.__v_raw):!(!e||!e.__v_isReactive)}function gt(e){return!(!e||!e.__v_isReadonly)}function vt(e){return!(!e||!e.__v_isShallow)}function yt(e){return mt(e)||gt(e)}function bt(e){const t=e&&e.__v_raw;return t?bt(t):e}function _t(e){return Q(e,"__v_skip",!0),e}const St=e=>M(e)?pt(e):e,xt=e=>M(e)?dt(e):e;function Ct(e){me&&ue&&_e((e=bt(e)).dep||(e.dep=re()))}function kt(e,t){(e=bt(e)).dep&&xe(e.dep)}function wt(e){return!(!e||!0!==e.__v_isRef)}function Tt(e){return Nt(e,!1)}function Nt(e,t){return wt(e)?e:new Et(e,t)}class Et{constructor(e,t){this.__v_isShallow=t,this.dep=void 0,this.__v_isRef=!0,this._rawValue=t?e:bt(e),this._value=t?e:St(e)}get value(){return Ct(this),this._value}set value(e){const t=this.__v_isShallow||vt(e)||gt(e);e=t?e:bt(e),Z(e,this._rawValue)&&(this._rawValue=e,this._value=t?e:St(e),kt(this))}}function Ot(e){return wt(e)?e.value:e}const At={get:(e,t,n)=>Ot(Reflect.get(e,t,n)),set:(e,t,n,o)=>{const r=e[t];return wt(r)&&!wt(n)?(r.value=n,!0):Reflect.set(e,t,n,o)}};function Ft(e){return mt(e)?e:new Proxy(e,At)}class Pt{constructor(e){this.dep=void 0,this.__v_isRef=!0;const{get:t,set:n}=e((()=>Ct(this)),(()=>kt(this)));this._get=t,this._set=n}get value(){return this._get()}set value(e){this._set(e)}}class Rt{constructor(e,t,n){this._object=e,this._key=t,this._defaultValue=n,this.__v_isRef=!0}get value(){const e=this._object[this._key];return void 0===e?this._defaultValue:e}set value(e){this._object[this._key]=e}}function $t(e,t,n){const o=e[t];return wt(o)?o:new Rt(e,t,n)}var Mt;class Vt{constructor(e,t,n,o){this._setter=t,this.dep=void 0,this.__v_isRef=!0,this[Mt]=!1,this._dirty=!0,this.effect=new de(e,(()=>{this._dirty||(this._dirty=!0,kt(this))})),this.effect.computed=this,this.effect.active=this._cacheable=!o,this.__v_isReadonly=n}get value(){const e=bt(this);return Ct(e),!e._dirty&&e._cacheable||(e._dirty=!1,e._value=e.effect.run()),e._value}set value(e){this._setter(e)}}function It(e,t,n,o){let r;try{r=o?e(...o):e()}catch(s){Lt(s,t,n)}return r}function Bt(e,t,n,o){if(P(e)){const r=It(e,t,n,o);return r&&V(r)&&r.catch((e=>{Lt(e,t,n)})),r}const r=[];for(let s=0;s>>1;tn(Dt[o])tn(e)-tn(t))),Kt=0;Ktnull==e.id?1/0:e.id,nn=(e,t)=>{const n=tn(e)-tn(t);if(0===n){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function on(e){Ut=!1,jt=!0,Dt.sort(nn);try{for(Ht=0;HtR(e)?e.trim():e))),t&&(r=n.map(X))}let l,c=o[l=J(t)]||o[l=J(z(t))];!c&&s&&(c=o[l=J(G(t))]),c&&Bt(c,e,6,r);const a=o[l+"Once"];if(a){if(e.emitted){if(e.emitted[l])return}else e.emitted={};e.emitted[l]=!0,Bt(a,e,6,r)}}function ln(e,t,n=!1){const o=t.emitsCache,r=o.get(e);if(void 0!==r)return r;const s=e.emits;let i={},l=!1;if(!P(e)){const o=e=>{const n=ln(e,t,!0);n&&(l=!0,k(i,n))};!n&&t.mixins.length&&t.mixins.forEach(o),e.extends&&o(e.extends),e.mixins&&e.mixins.forEach(o)}return s||l?(E(s)?s.forEach((e=>i[e]=null)):k(i,s),M(e)&&o.set(e,i),i):(M(e)&&o.set(e,null),null)}function cn(e,t){return!(!e||!x(t))&&(t=t.slice(2).replace(/Once$/,""),N(e,t[0].toLowerCase()+t.slice(1))||N(e,G(t))||N(e,t))}let an=null,un=null;function pn(e){const t=an;return an=e,un=e&&e.type.__scopeId||null,t}function fn(e,t=an,n){if(!t)return e;if(e._n)return e;const o=(...n)=>{o._d&&Cr(-1);const r=pn(t);let s;try{s=e(...n)}finally{pn(r),o._d&&Cr(1)}return s};return o._n=!0,o._c=!0,o._d=!0,o}function dn(e){const{type:t,vnode:n,proxy:o,withProxy:r,props:s,propsOptions:[i],slots:l,attrs:c,emit:a,render:u,renderCache:p,data:f,setupState:d,ctx:h,inheritAttrs:m}=e;let g,v;const y=pn(e);try{if(4&n.shapeFlag){const e=r||o;g=Vr(u.call(e,e,p,s,d,f,h)),v=c}else{const e=t;0,g=Vr(e(s,e.length>1?{attrs:c,slots:l,emit:a}:null)),v=t.props?c:hn(c)}}catch(_){yr.length=0,Lt(_,e,1),g=Pr(gr)}let b=g;if(v&&!1!==m){const e=Object.keys(v),{shapeFlag:t}=b;e.length&&7&t&&(i&&e.some(C)&&(v=mn(v,i)),b=$r(b,v))}return n.dirs&&(b=$r(b),b.dirs=b.dirs?b.dirs.concat(n.dirs):n.dirs),n.transition&&(b.transition=n.transition),g=b,pn(y),g}const hn=e=>{let t;for(const n in e)("class"===n||"style"===n||x(n))&&((t||(t={}))[n]=e[n]);return t},mn=(e,t)=>{const n={};for(const o in e)C(o)&&o.slice(9)in t||(n[o]=e[o]);return n};function gn(e,t,n){const o=Object.keys(t);if(o.length!==Object.keys(e).length)return!0;for(let r=0;re.__isSuspense,bn={name:"Suspense",__isSuspense:!0,process(e,t,n,o,r,s,i,l,c,a){null==e?function(e,t,n,o,r,s,i,l,c){const{p:a,o:{createElement:u}}=c,p=u("div"),f=e.suspense=Sn(e,r,o,t,p,n,s,i,l,c);a(null,f.pendingBranch=e.ssContent,p,null,o,f,s,i),f.deps>0?(_n(e,"onPending"),_n(e,"onFallback"),a(null,e.ssFallback,t,n,o,null,s,i),kn(f,e.ssFallback)):f.resolve()}(t,n,o,r,s,i,l,c,a):function(e,t,n,o,r,s,i,l,{p:c,um:a,o:{createElement:u}}){const p=t.suspense=e.suspense;p.vnode=t,t.el=e.el;const f=t.ssContent,d=t.ssFallback,{activeBranch:h,pendingBranch:m,isInFallback:g,isHydrating:v}=p;if(m)p.pendingBranch=f,Nr(f,m)?(c(m,f,p.hiddenContainer,null,r,p,s,i,l),p.deps<=0?p.resolve():g&&(c(h,d,n,o,r,null,s,i,l),kn(p,d))):(p.pendingId++,v?(p.isHydrating=!1,p.activeBranch=m):a(m,r,p),p.deps=0,p.effects.length=0,p.hiddenContainer=u("div"),g?(c(null,f,p.hiddenContainer,null,r,p,s,i,l),p.deps<=0?p.resolve():(c(h,d,n,o,r,null,s,i,l),kn(p,d))):h&&Nr(f,h)?(c(h,f,n,o,r,p,s,i,l),p.resolve(!0)):(c(null,f,p.hiddenContainer,null,r,p,s,i,l),p.deps<=0&&p.resolve()));else if(h&&Nr(f,h))c(h,f,n,o,r,p,s,i,l),kn(p,f);else if(_n(t,"onPending"),p.pendingBranch=f,p.pendingId++,c(null,f,p.hiddenContainer,null,r,p,s,i,l),p.deps<=0)p.resolve();else{const{timeout:e,pendingId:t}=p;e>0?setTimeout((()=>{p.pendingId===t&&p.fallback(d)}),e):0===e&&p.fallback(d)}}(e,t,n,o,r,i,l,c,a)},hydrate:function(e,t,n,o,r,s,i,l,c){const a=t.suspense=Sn(t,o,n,e.parentNode,document.createElement("div"),null,r,s,i,l,!0),u=c(e,a.pendingBranch=t.ssContent,n,a,s,i);0===a.deps&&a.resolve();return u},create:Sn,normalize:function(e){const{shapeFlag:t,children:n}=e,o=32&t;e.ssContent=xn(o?n.default:n),e.ssFallback=o?xn(n.fallback):Pr(gr)}};function _n(e,t){const n=e.props&&e.props[t];P(n)&&n()}function Sn(e,t,n,o,r,s,i,l,c,a,u=!1){const{p:p,m:f,um:d,n:h,o:{parentNode:m,remove:g}}=a,v=X(e.props&&e.props.timeout),y={vnode:e,parent:t,parentComponent:n,isSVG:i,container:o,hiddenContainer:r,anchor:s,deps:0,pendingId:0,timeout:"number"==typeof v?v:-1,activeBranch:null,pendingBranch:null,isInFallback:!0,isHydrating:u,isUnmounted:!1,effects:[],resolve(e=!1){const{vnode:t,activeBranch:n,pendingBranch:o,pendingId:r,effects:s,parentComponent:i,container:l}=y;if(y.isHydrating)y.isHydrating=!1;else if(!e){const e=n&&o.transition&&"out-in"===o.transition.mode;e&&(n.transition.afterLeave=()=>{r===y.pendingId&&f(o,l,t,0)});let{anchor:t}=y;n&&(t=h(n),d(n,i,y,!0)),e||f(o,l,t,0)}kn(y,o),y.pendingBranch=null,y.isInFallback=!1;let c=y.parent,a=!1;for(;c;){if(c.pendingBranch){c.effects.push(...s),a=!0;break}c=c.parent}a||Qt(s),y.effects=[],_n(t,"onResolve")},fallback(e){if(!y.pendingBranch)return;const{vnode:t,activeBranch:n,parentComponent:o,container:r,isSVG:s}=y;_n(t,"onFallback");const i=h(n),a=()=>{y.isInFallback&&(p(null,e,r,i,o,null,s,l,c),kn(y,e))},u=e.transition&&"out-in"===e.transition.mode;u&&(n.transition.afterLeave=a),y.isInFallback=!0,d(n,o,null,!0),u||a()},move(e,t,n){y.activeBranch&&f(y.activeBranch,e,t,n),y.container=e},next:()=>y.activeBranch&&h(y.activeBranch),registerDep(e,t){const n=!!y.pendingBranch;n&&y.deps++;const o=e.vnode.el;e.asyncDep.catch((t=>{Lt(t,e,0)})).then((r=>{if(e.isUnmounted||y.isUnmounted||y.pendingId!==e.suspenseId)return;e.asyncResolved=!0;const{vnode:s}=e;Yr(e,r,!1),o&&(s.el=o);const l=!o&&e.subTree.el;t(e,s,m(o||e.subTree.el),o?null:h(e.subTree),y,i,c),l&&g(l),vn(e,s.el),n&&0==--y.deps&&y.resolve()}))},unmount(e,t){y.isUnmounted=!0,y.activeBranch&&d(y.activeBranch,n,e,t),y.pendingBranch&&d(y.pendingBranch,n,e,t)}};return y}function xn(e){let t;if(P(e)){const n=xr&&e._c;n&&(e._d=!1,_r()),e=e(),n&&(e._d=!0,t=br,Sr())}if(E(e)){const t=function(e){let t;for(let n=0;nt!==e))),e}function Cn(e,t){t&&t.pendingBranch?E(e)?t.effects.push(...e):t.effects.push(e):Qt(e)}function kn(e,t){e.activeBranch=t;const{vnode:n,parentComponent:o}=e,r=n.el=t.el;o&&o.subTree===n&&(o.vnode.el=r,vn(o,r))}function wn(e,t){if(Hr){let n=Hr.provides;const o=Hr.parent&&Hr.parent.provides;o===n&&(n=Hr.provides=Object.create(o)),n[e]=t}else;}function Tn(e,t,n=!1){const o=Hr||an;if(o){const r=null==o.parent?o.vnode.appContext&&o.vnode.appContext.provides:o.parent.provides;if(r&&e in r)return r[e];if(arguments.length>1)return n&&P(t)?t.call(o.proxy):t}}function Nn(e,t){return An(e,null,{flush:"post"})}const En={};function On(e,t,n){return An(e,t,n)}function An(e,t,{immediate:n,deep:o,flush:r}=v){const s=Hr;let i,l,c=!1,a=!1;if(wt(e)?(i=()=>e.value,c=vt(e)):mt(e)?(i=()=>e,o=!0):E(e)?(a=!0,c=e.some((e=>mt(e)||vt(e))),i=()=>e.map((e=>wt(e)?e.value:mt(e)?Rn(e):P(e)?It(e,s,2):void 0))):i=P(e)?t?()=>It(e,s,2):()=>{if(!s||!s.isUnmounted)return l&&l(),Bt(e,s,3,[u])}:b,t&&o){const e=i;i=()=>Rn(e())}let u=e=>{l=h.onStop=()=>{It(e,s,4)}},p=a?new Array(e.length).fill(En):En;const f=()=>{if(h.active)if(t){const e=h.run();(o||c||(a?e.some(((e,t)=>Z(e,p[t]))):Z(e,p)))&&(l&&l(),Bt(t,s,3,[e,p===En?void 0:a&&p[0]===En?[]:p,u]),p=e)}else h.run()};let d;f.allowRecurse=!!t,"sync"===r?d=f:"post"===r?d=()=>nr(f,s&&s.suspense):(f.pre=!0,s&&(f.id=s.uid),d=()=>Zt(f));const h=new de(i,d);t?n?f():p=h.run():"post"===r?nr(h.run.bind(h),s&&s.suspense):h.run();return()=>{h.stop(),s&&s.scope&&w(s.scope.effects,h)}}function Fn(e,t,n){const o=this.proxy,r=R(e)?e.includes(".")?Pn(o,e):()=>o[e]:e.bind(o,o);let s;P(t)?s=t:(s=t.handler,n=t);const i=Hr;zr(this);const l=An(r,s.bind(o),n);return i?zr(i):Kr(),l}function Pn(e,t){const n=t.split(".");return()=>{let t=e;for(let e=0;e{Rn(e,t)}));else if(L(e))for(const n in e)Rn(e[n],t);return e}function $n(){const e={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return ro((()=>{e.isMounted=!0})),lo((()=>{e.isUnmounting=!0})),e}const Mn=[Function,Array],Vn={name:"BaseTransition",props:{mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Mn,onEnter:Mn,onAfterEnter:Mn,onEnterCancelled:Mn,onBeforeLeave:Mn,onLeave:Mn,onAfterLeave:Mn,onLeaveCancelled:Mn,onBeforeAppear:Mn,onAppear:Mn,onAfterAppear:Mn,onAppearCancelled:Mn},setup(e,{slots:t}){const n=Wr(),o=$n();let r;return()=>{const s=t.default&&Dn(t.default(),!0);if(!s||!s.length)return;let i=s[0];if(s.length>1)for(const e of s)if(e.type!==gr){i=e;break}const l=bt(e),{mode:c}=l;if(o.isLeaving)return Ln(i);const a=jn(i);if(!a)return Ln(i);const u=Bn(a,l,o,n);Un(a,u);const p=n.subTree,f=p&&jn(p);let d=!1;const{getTransitionKey:h}=a.type;if(h){const e=h();void 0===r?r=e:e!==r&&(r=e,d=!0)}if(f&&f.type!==gr&&(!Nr(a,f)||d)){const e=Bn(f,l,o,n);if(Un(f,e),"out-in"===c)return o.isLeaving=!0,e.afterLeave=()=>{o.isLeaving=!1,!1!==n.update.active&&n.update()},Ln(i);"in-out"===c&&a.type!==gr&&(e.delayLeave=(e,t,n)=>{In(o,f)[String(f.key)]=f,e._leaveCb=()=>{t(),e._leaveCb=void 0,delete u.delayedLeave},u.delayedLeave=n})}return i}}};function In(e,t){const{leavingVNodes:n}=e;let o=n.get(t.type);return o||(o=Object.create(null),n.set(t.type,o)),o}function Bn(e,t,n,o){const{appear:r,mode:s,persisted:i=!1,onBeforeEnter:l,onEnter:c,onAfterEnter:a,onEnterCancelled:u,onBeforeLeave:p,onLeave:f,onAfterLeave:d,onLeaveCancelled:h,onBeforeAppear:m,onAppear:g,onAfterAppear:v,onAppearCancelled:y}=t,b=String(e.key),_=In(n,e),S=(e,t)=>{e&&Bt(e,o,9,t)},x=(e,t)=>{const n=t[1];S(e,t),E(e)?e.every((e=>e.length<=1))&&n():e.length<=1&&n()},C={mode:s,persisted:i,beforeEnter(t){let o=l;if(!n.isMounted){if(!r)return;o=m||l}t._leaveCb&&t._leaveCb(!0);const s=_[b];s&&Nr(e,s)&&s.el._leaveCb&&s.el._leaveCb(),S(o,[t])},enter(e){let t=c,o=a,s=u;if(!n.isMounted){if(!r)return;t=g||c,o=v||a,s=y||u}let i=!1;const l=e._enterCb=t=>{i||(i=!0,S(t?s:o,[e]),C.delayedLeave&&C.delayedLeave(),e._enterCb=void 0)};t?x(t,[e,l]):l()},leave(t,o){const r=String(e.key);if(t._enterCb&&t._enterCb(!0),n.isUnmounting)return o();S(p,[t]);let s=!1;const i=t._leaveCb=n=>{s||(s=!0,o(),S(n?h:d,[t]),t._leaveCb=void 0,_[r]===e&&delete _[r])};_[r]=e,f?x(f,[t,i]):i()},clone:e=>Bn(e,t,n,o)};return C}function Ln(e){if(Kn(e))return(e=$r(e)).children=null,e}function jn(e){return Kn(e)?e.children?e.children[0]:void 0:e}function Un(e,t){6&e.shapeFlag&&e.component?Un(e.component.subTree,t):128&e.shapeFlag?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Dn(e,t=!1,n){let o=[],r=0;for(let s=0;s1)for(let s=0;s!!e.type.__asyncLoader;function zn(e,t){const{ref:n,props:o,children:r,ce:s}=t.vnode,i=Pr(e,o,r);return i.ref=n,i.ce=s,delete t.vnode.ce,i}const Kn=e=>e.type.__isKeepAlive,Gn={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(e,{slots:t}){const n=Wr(),o=n.ctx,r=new Map,s=new Set;let i=null;const l=n.suspense,{renderer:{p:c,m:a,um:u,o:{createElement:p}}}=o,f=p("div");function d(e){Xn(e),u(e,n,l,!0)}function h(e){r.forEach(((t,n)=>{const o=ns(t.type);!o||e&&e(o)||m(n)}))}function m(e){const t=r.get(e);i&&t.type===i.type?i&&Xn(i):d(t),r.delete(e),s.delete(e)}o.activate=(e,t,n,o,r)=>{const s=e.component;a(e,t,n,0,l),c(s.vnode,e,t,n,s,l,o,e.slotScopeIds,r),nr((()=>{s.isDeactivated=!1,s.a&&Y(s.a);const t=e.props&&e.props.onVnodeMounted;t&&jr(t,s.parent,e)}),l)},o.deactivate=e=>{const t=e.component;a(e,f,null,1,l),nr((()=>{t.da&&Y(t.da);const n=e.props&&e.props.onVnodeUnmounted;n&&jr(n,t.parent,e),t.isDeactivated=!0}),l)},On((()=>[e.include,e.exclude]),(([e,t])=>{e&&h((t=>qn(e,t))),t&&h((e=>!qn(t,e)))}),{flush:"post",deep:!0});let g=null;const v=()=>{null!=g&&r.set(g,eo(n.subTree))};return ro(v),io(v),lo((()=>{r.forEach((e=>{const{subTree:t,suspense:o}=n,r=eo(t);if(e.type!==r.type)d(e);else{Xn(r);const e=r.component.da;e&&nr(e,o)}}))})),()=>{if(g=null,!t.default)return null;const n=t.default(),o=n[0];if(n.length>1)return i=null,n;if(!(Tr(o)&&(4&o.shapeFlag||128&o.shapeFlag)))return i=null,o;let l=eo(o);const c=l.type,a=ns(Wn(l)?l.type.__asyncResolved||{}:c),{include:u,exclude:p,max:f}=e;if(u&&(!a||!qn(u,a))||p&&a&&qn(p,a))return i=l,o;const d=null==l.key?c:l.key,h=r.get(d);return l.el&&(l=$r(l),128&o.shapeFlag&&(o.ssContent=l)),g=d,h?(l.el=h.el,l.component=h.component,l.transition&&Un(l,l.transition),l.shapeFlag|=512,s.delete(d),s.add(d)):(s.add(d),f&&s.size>parseInt(f,10)&&m(s.values().next().value)),l.shapeFlag|=256,i=l,yn(o.type)?o:l}}};function qn(e,t){return E(e)?e.some((e=>qn(e,t))):R(e)?e.split(",").includes(t):!!e.test&&e.test(t)}function Jn(e,t){Yn(e,"a",t)}function Zn(e,t){Yn(e,"da",t)}function Yn(e,t,n=Hr){const o=e.__wdc||(e.__wdc=()=>{let t=n;for(;t;){if(t.isDeactivated)return;t=t.parent}return e()});if(to(t,o,n),n){let e=n.parent;for(;e&&e.parent;)Kn(e.parent.vnode)&&Qn(o,t,n,e),e=e.parent}}function Qn(e,t,n,o){const r=to(t,e,o,!0);co((()=>{w(o[t],r)}),n)}function Xn(e){e.shapeFlag&=-257,e.shapeFlag&=-513}function eo(e){return 128&e.shapeFlag?e.ssContent:e}function to(e,t,n=Hr,o=!1){if(n){const r=n[e]||(n[e]=[]),s=t.__weh||(t.__weh=(...o)=>{if(n.isUnmounted)return;ve(),zr(n);const r=Bt(t,n,e,o);return Kr(),ye(),r});return o?r.unshift(s):r.push(s),s}}const no=e=>(t,n=Hr)=>(!Zr||"sp"===e)&&to(e,((...e)=>t(...e)),n),oo=no("bm"),ro=no("m"),so=no("bu"),io=no("u"),lo=no("bum"),co=no("um"),ao=no("sp"),uo=no("rtg"),po=no("rtc");function fo(e,t=Hr){to("ec",e,t)}function ho(e,t,n,o){const r=e.dirs,s=t&&t.dirs;for(let i=0;i!Tr(e)||e.type!==gr&&!(e.type===hr&&!bo(e.children))))?e:null}const _o=e=>e?Gr(e)?ts(e)||e.proxy:_o(e.parent):null,So=k(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>_o(e.parent),$root:e=>_o(e.root),$emit:e=>e.emit,$options:e=>Oo(e),$forceUpdate:e=>e.f||(e.f=()=>Zt(e.update)),$nextTick:e=>e.n||(e.n=Jt.bind(e.proxy)),$watch:e=>Fn.bind(e)}),xo=(e,t)=>e!==v&&!e.__isScriptSetup&&N(e,t),Co={get({_:e},t){const{ctx:n,setupState:o,data:r,props:s,accessCache:i,type:l,appContext:c}=e;let a;if("$"!==t[0]){const l=i[t];if(void 0!==l)switch(l){case 1:return o[t];case 2:return r[t];case 4:return n[t];case 3:return s[t]}else{if(xo(o,t))return i[t]=1,o[t];if(r!==v&&N(r,t))return i[t]=2,r[t];if((a=e.propsOptions[0])&&N(a,t))return i[t]=3,s[t];if(n!==v&&N(n,t))return i[t]=4,n[t];wo&&(i[t]=0)}}const u=So[t];let p,f;return u?("$attrs"===t&&be(e,0,t),u(e)):(p=l.__cssModules)&&(p=p[t])?p:n!==v&&N(n,t)?(i[t]=4,n[t]):(f=c.config.globalProperties,N(f,t)?f[t]:void 0)},set({_:e},t,n){const{data:o,setupState:r,ctx:s}=e;return xo(r,t)?(r[t]=n,!0):o!==v&&N(o,t)?(o[t]=n,!0):!N(e.props,t)&&(("$"!==t[0]||!(t.slice(1)in e))&&(s[t]=n,!0))},has({_:{data:e,setupState:t,accessCache:n,ctx:o,appContext:r,propsOptions:s}},i){let l;return!!n[i]||e!==v&&N(e,i)||xo(t,i)||(l=s[0])&&N(l,i)||N(o,i)||N(So,i)||N(r.config.globalProperties,i)},defineProperty(e,t,n){return null!=n.get?e._.accessCache[t]=0:N(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}},ko=k({},Co,{get(e,t){if(t!==Symbol.unscopables)return Co.get(e,t,e)},has:(e,t)=>"_"!==t[0]&&!n(t)});let wo=!0;function To(e){const t=Oo(e),n=e.proxy,o=e.ctx;wo=!1,t.beforeCreate&&No(t.beforeCreate,e,"bc");const{data:r,computed:s,methods:i,watch:l,provide:c,inject:a,created:u,beforeMount:p,mounted:f,beforeUpdate:d,updated:h,activated:m,deactivated:g,beforeUnmount:v,unmounted:y,render:_,renderTracked:S,renderTriggered:x,errorCaptured:C,serverPrefetch:k,expose:w,inheritAttrs:T,components:N,directives:O}=t;if(a&&function(e,t,n=b,o=!1){E(e)&&(e=Ro(e));for(const r in e){const n=e[r];let s;s=M(n)?"default"in n?Tn(n.from||r,n.default,!0):Tn(n.from||r):Tn(n),wt(s)&&o?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>s.value,set:e=>s.value=e}):t[r]=s}}(a,o,null,e.appContext.config.unwrapInjectedRef),i)for(const b in i){const e=i[b];P(e)&&(o[b]=e.bind(n))}if(r){const t=r.call(n,n);M(t)&&(e.data=pt(t))}if(wo=!0,s)for(const E in s){const e=s[E],t=P(e)?e.bind(n,n):P(e.get)?e.get.bind(n,n):b,r=!P(e)&&P(e.set)?e.set.bind(n):b,i=os({get:t,set:r});Object.defineProperty(o,E,{enumerable:!0,configurable:!0,get:()=>i.value,set:e=>i.value=e})}if(l)for(const b in l)Eo(l[b],o,n,b);if(c){const e=P(c)?c.call(n):c;Reflect.ownKeys(e).forEach((t=>{wn(t,e[t])}))}function A(e,t){E(t)?t.forEach((t=>e(t.bind(n)))):t&&e(t.bind(n))}if(u&&No(u,e,"c"),A(oo,p),A(ro,f),A(so,d),A(io,h),A(Jn,m),A(Zn,g),A(fo,C),A(po,S),A(uo,x),A(lo,v),A(co,y),A(ao,k),E(w))if(w.length){const t=e.exposed||(e.exposed={});w.forEach((e=>{Object.defineProperty(t,e,{get:()=>n[e],set:t=>n[e]=t})}))}else e.exposed||(e.exposed={});_&&e.render===b&&(e.render=_),null!=T&&(e.inheritAttrs=T),N&&(e.components=N),O&&(e.directives=O)}function No(e,t,n){Bt(E(e)?e.map((e=>e.bind(t.proxy))):e.bind(t.proxy),t,n)}function Eo(e,t,n,o){const r=o.includes(".")?Pn(n,o):()=>n[o];if(R(e)){const n=t[e];P(n)&&On(r,n)}else if(P(e))On(r,e.bind(n));else if(M(e))if(E(e))e.forEach((e=>Eo(e,t,n,o)));else{const o=P(e.handler)?e.handler.bind(n):t[e.handler];P(o)&&On(r,o,e)}}function Oo(e){const t=e.type,{mixins:n,extends:o}=t,{mixins:r,optionsCache:s,config:{optionMergeStrategies:i}}=e.appContext,l=s.get(t);let c;return l?c=l:r.length||n||o?(c={},r.length&&r.forEach((e=>Ao(c,e,i,!0))),Ao(c,t,i)):c=t,M(t)&&s.set(t,c),c}function Ao(e,t,n,o=!1){const{mixins:r,extends:s}=t;s&&Ao(e,s,n,!0),r&&r.forEach((t=>Ao(e,t,n,!0)));for(const i in t)if(o&&"expose"===i);else{const o=Fo[i]||n&&n[i];e[i]=o?o(e[i],t[i]):t[i]}return e}const Fo={data:Po,props:Mo,emits:Mo,methods:Mo,computed:Mo,beforeCreate:$o,created:$o,beforeMount:$o,mounted:$o,beforeUpdate:$o,updated:$o,beforeDestroy:$o,beforeUnmount:$o,destroyed:$o,unmounted:$o,activated:$o,deactivated:$o,errorCaptured:$o,serverPrefetch:$o,components:Mo,directives:Mo,watch:function(e,t){if(!e)return t;if(!t)return e;const n=k(Object.create(null),e);for(const o in t)n[o]=$o(e[o],t[o]);return n},provide:Po,inject:function(e,t){return Mo(Ro(e),Ro(t))}};function Po(e,t){return t?e?function(){return k(P(e)?e.call(this,this):e,P(t)?t.call(this,this):t)}:t:e}function Ro(e){if(E(e)){const t={};for(let n=0;n{c=!0;const[n,o]=Bo(e,t,!0);k(i,n),o&&l.push(...o)};!n&&t.mixins.length&&t.mixins.forEach(o),e.extends&&o(e.extends),e.mixins&&e.mixins.forEach(o)}if(!s&&!c)return M(e)&&o.set(e,y),y;if(E(s))for(let u=0;u-1,n[1]=o<0||t-1||N(n,"default"))&&l.push(e)}}}const a=[i,l];return M(e)&&o.set(e,a),a}function Lo(e){return"$"!==e[0]}function jo(e){const t=e&&e.toString().match(/^\s*function (\w+)/);return t?t[1]:null===e?"null":""}function Uo(e,t){return jo(e)===jo(t)}function Do(e,t){return E(t)?t.findIndex((t=>Uo(t,e))):P(t)&&Uo(t,e)?0:-1}const Ho=e=>"_"===e[0]||"$stable"===e,Wo=e=>E(e)?e.map(Vr):[Vr(e)],zo=(e,t,n)=>{if(t._n)return t;const o=fn(((...e)=>Wo(t(...e))),n);return o._c=!1,o},Ko=(e,t,n)=>{const o=e._ctx;for(const r in e){if(Ho(r))continue;const n=e[r];if(P(n))t[r]=zo(0,n,o);else if(null!=n){const e=Wo(n);t[r]=()=>e}}},Go=(e,t)=>{const n=Wo(t);e.slots.default=()=>n};function qo(){return{app:null,config:{isNativeTag:_,performance:!1,globalProperties:{},optionMergeStrategies:{},errorHandler:void 0,warnHandler:void 0,compilerOptions:{}},mixins:[],components:{},directives:{},provides:Object.create(null),optionsCache:new WeakMap,propsCache:new WeakMap,emitsCache:new WeakMap}}let Jo=0;function Zo(e,t){return function(n,o=null){P(n)||(n=Object.assign({},n)),null==o||M(o)||(o=null);const r=qo(),s=new Set;let i=!1;const l=r.app={_uid:Jo++,_component:n,_props:o,_container:null,_context:r,_instance:null,version:cs,get config(){return r.config},set config(e){},use:(e,...t)=>(s.has(e)||(e&&P(e.install)?(s.add(e),e.install(l,...t)):P(e)&&(s.add(e),e(l,...t))),l),mixin:e=>(r.mixins.includes(e)||r.mixins.push(e),l),component:(e,t)=>t?(r.components[e]=t,l):r.components[e],directive:(e,t)=>t?(r.directives[e]=t,l):r.directives[e],mount(s,c,a){if(!i){const u=Pr(n,o);return u.appContext=r,c&&t?t(u,s):e(u,s,a),i=!0,l._container=s,s.__vue_app__=l,ts(u.component)||u.component.proxy}},unmount(){i&&(e(null,l._container),delete l._container.__vue_app__)},provide:(e,t)=>(r.provides[e]=t,l)};return l}}function Yo(e,t,n,o,r=!1){if(E(e))return void e.forEach(((e,s)=>Yo(e,t&&(E(t)?t[s]:t),n,o,r)));if(Wn(o)&&!r)return;const s=4&o.shapeFlag?ts(o.component)||o.component.proxy:o.el,i=r?null:s,{i:l,r:c}=e,a=t&&t.r,u=l.refs===v?l.refs={}:l.refs,p=l.setupState;if(null!=a&&a!==c&&(R(a)?(u[a]=null,N(p,a)&&(p[a]=null)):wt(a)&&(a.value=null)),P(c))It(c,l,12,[i,u]);else{const t=R(c),o=wt(c);if(t||o){const l=()=>{if(e.f){const n=t?N(p,c)?p[c]:u[c]:c.value;r?E(n)&&w(n,s):E(n)?n.includes(s)||n.push(s):t?(u[c]=[s],N(p,c)&&(p[c]=u[c])):(c.value=[s],e.k&&(u[e.k]=c.value))}else t?(u[c]=i,N(p,c)&&(p[c]=i)):o&&(c.value=i,e.k&&(u[e.k]=i))};i?(l.id=-1,nr(l,n)):l()}}}let Qo=!1;const Xo=e=>/svg/.test(e.namespaceURI)&&"foreignObject"!==e.tagName,er=e=>8===e.nodeType;function tr(e){const{mt:t,p:n,o:{patchProp:o,createText:r,nextSibling:s,parentNode:i,remove:l,insert:c,createComment:a}}=e,u=(n,o,l,a,g,v=!1)=>{const y=er(n)&&"["===n.data,b=()=>h(n,o,l,a,g,y),{type:_,ref:S,shapeFlag:x,patchFlag:C}=o;let k=n.nodeType;o.el=n,-2===C&&(v=!1,o.dynamicChildren=null);let w=null;switch(_){case mr:3!==k?""===o.children?(c(o.el=r(""),i(n),n),w=n):w=b():(n.data!==o.children&&(Qo=!0,n.data=o.children),w=s(n));break;case gr:w=8!==k||y?b():s(n);break;case vr:if(y&&(k=(n=s(n)).nodeType),1===k||3===k){w=n;const e=!o.children.length;for(let t=0;t{i=i||!!t.dynamicChildren;const{type:c,props:a,patchFlag:u,shapeFlag:p,dirs:d}=t,h="input"===c&&d||"option"===c;if(h||-1!==u){if(d&&ho(t,null,n,"created"),a)if(h||!i||48&u)for(const t in a)(h&&t.endsWith("value")||x(t)&&!U(t))&&o(e,t,null,a[t],!1,void 0,n);else a.onClick&&o(e,"onClick",null,a.onClick,!1,void 0,n);let c;if((c=a&&a.onVnodeBeforeMount)&&jr(c,n,t),d&&ho(t,null,n,"beforeMount"),((c=a&&a.onVnodeMounted)||d)&&Cn((()=>{c&&jr(c,n,t),d&&ho(t,null,n,"mounted")}),r),16&p&&(!a||!a.innerHTML&&!a.textContent)){let o=f(e.firstChild,t,e,n,r,s,i);for(;o;){Qo=!0;const e=o;o=o.nextSibling,l(e)}}else 8&p&&e.textContent!==t.children&&(Qo=!0,e.textContent=t.children)}return e.nextSibling},f=(e,t,o,r,s,i,l)=>{l=l||!!t.dynamicChildren;const c=t.children,a=c.length;for(let p=0;p{const{slotScopeIds:u}=t;u&&(r=r?r.concat(u):u);const p=i(e),d=f(s(e),t,p,n,o,r,l);return d&&er(d)&&"]"===d.data?s(t.anchor=d):(Qo=!0,c(t.anchor=a("]"),p,d),d)},h=(e,t,o,r,c,a)=>{if(Qo=!0,t.el=null,a){const t=m(e);for(;;){const n=s(e);if(!n||n===t)break;l(n)}}const u=s(e),p=i(e);return l(e),n(null,t,p,u,o,r,Xo(p),c),u},m=e=>{let t=0;for(;e;)if((e=s(e))&&er(e)&&("["===e.data&&t++,"]"===e.data)){if(0===t)return s(e);t--}return e};return[(e,t)=>{if(!t.hasChildNodes())return n(null,e,t),en(),void(t._vnode=e);Qo=!1,u(t.firstChild,e,null,null,null),en(),t._vnode=e,Qo&&console.error("Hydration completed but contains mismatches.")},u]}const nr=Cn;function or(e){return sr(e)}function rr(e){return sr(e,tr)}function sr(e,t){(ee||(ee="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{})).__VUE__=!0;const{insert:n,remove:o,patchProp:r,createElement:s,createText:i,createComment:l,setText:c,setElementText:a,parentNode:u,nextSibling:p,setScopeId:f=b,insertStaticContent:d}=e,h=(e,t,n,o=null,r=null,s=null,i=!1,l=null,c=!!t.dynamicChildren)=>{if(e===t)return;e&&!Nr(e,t)&&(o=J(e),D(e,r,s,!0),e=null),-2===t.patchFlag&&(c=!1,t.dynamicChildren=null);const{type:a,ref:u,shapeFlag:p}=t;switch(a){case mr:m(e,t,n,o);break;case gr:g(e,t,n,o);break;case vr:null==e&&_(t,n,o,i);break;case hr:A(e,t,n,o,r,s,i,l,c);break;default:1&p?S(e,t,n,o,r,s,i,l,c):6&p?F(e,t,n,o,r,s,i,l,c):(64&p||128&p)&&a.process(e,t,n,o,r,s,i,l,c,X)}null!=u&&r&&Yo(u,e&&e.ref,s,t||e,!t)},m=(e,t,o,r)=>{if(null==e)n(t.el=i(t.children),o,r);else{const n=t.el=e.el;t.children!==e.children&&c(n,t.children)}},g=(e,t,o,r)=>{null==e?n(t.el=l(t.children||""),o,r):t.el=e.el},_=(e,t,n,o)=>{[e.el,e.anchor]=d(e.children,t,n,o,e.el,e.anchor)},S=(e,t,n,o,r,s,i,l,c)=>{i=i||"svg"===t.type,null==e?x(t,n,o,r,s,i,l,c):T(e,t,r,s,i,l,c)},x=(e,t,o,i,l,c,u,p)=>{let f,d;const{type:h,props:m,shapeFlag:g,transition:v,dirs:y}=e;if(f=e.el=s(e.type,c,m&&m.is,m),8&g?a(f,e.children):16&g&&w(e.children,f,null,i,l,c&&"foreignObject"!==h,u,p),y&&ho(e,null,i,"created"),m){for(const t in m)"value"===t||U(t)||r(f,t,null,m[t],c,e.children,i,l,q);"value"in m&&r(f,"value",null,m.value),(d=m.onVnodeBeforeMount)&&jr(d,i,e)}C(f,e,e.scopeId,u,i),y&&ho(e,null,i,"beforeMount");const b=(!l||l&&!l.pendingBranch)&&v&&!v.persisted;b&&v.beforeEnter(f),n(f,t,o),((d=m&&m.onVnodeMounted)||b||y)&&nr((()=>{d&&jr(d,i,e),b&&v.enter(f),y&&ho(e,null,i,"mounted")}),l)},C=(e,t,n,o,r)=>{if(n&&f(e,n),o)for(let s=0;s{for(let a=c;a{const c=t.el=e.el;let{patchFlag:u,dynamicChildren:p,dirs:f}=t;u|=16&e.patchFlag;const d=e.props||v,h=t.props||v;let m;n&&ir(n,!1),(m=h.onVnodeBeforeUpdate)&&jr(m,n,t,e),f&&ho(t,e,n,"beforeUpdate"),n&&ir(n,!0);const g=s&&"foreignObject"!==t.type;if(p?E(e.dynamicChildren,p,c,n,o,g,i):l||I(e,t,c,null,n,o,g,i,!1),u>0){if(16&u)O(c,t,d,h,n,o,s);else if(2&u&&d.class!==h.class&&r(c,"class",null,h.class,s),4&u&&r(c,"style",d.style,h.style,s),8&u){const i=t.dynamicProps;for(let t=0;t{m&&jr(m,n,t,e),f&&ho(t,e,n,"updated")}),o)},E=(e,t,n,o,r,s,i)=>{for(let l=0;l{if(n!==o){if(n!==v)for(const c in n)U(c)||c in o||r(e,c,n[c],null,l,t.children,s,i,q);for(const c in o){if(U(c))continue;const a=o[c],u=n[c];a!==u&&"value"!==c&&r(e,c,u,a,l,t.children,s,i,q)}"value"in o&&r(e,"value",n.value,o.value)}},A=(e,t,o,r,s,l,c,a,u)=>{const p=t.el=e?e.el:i(""),f=t.anchor=e?e.anchor:i("");let{patchFlag:d,dynamicChildren:h,slotScopeIds:m}=t;m&&(a=a?a.concat(m):m),null==e?(n(p,o,r),n(f,o,r),w(t.children,o,f,s,l,c,a,u)):d>0&&64&d&&h&&e.dynamicChildren?(E(e.dynamicChildren,h,o,s,l,c,a),(null!=t.key||s&&t===s.subTree)&&lr(e,t,!0)):I(e,t,o,f,s,l,c,a,u)},F=(e,t,n,o,r,s,i,l,c)=>{t.slotScopeIds=l,null==e?512&t.shapeFlag?r.ctx.activate(t,n,o,i,c):P(t,n,o,r,s,i,c):R(e,t,c)},P=(e,t,n,o,r,s,i)=>{const l=e.component=function(e,t,n){const o=e.type,r=(t?t.appContext:e.appContext)||Ur,s={uid:Dr++,vnode:e,type:o,parent:t,appContext:r,root:null,next:null,subTree:null,effect:null,update:null,scope:new ne(!0),render:null,proxy:null,exposed:null,exposeProxy:null,withProxy:null,provides:t?t.provides:Object.create(r.provides),accessCache:null,renderCache:[],components:null,directives:null,propsOptions:Bo(o,r),emitsOptions:ln(o,r),emit:null,emitted:null,propsDefaults:v,inheritAttrs:o.inheritAttrs,ctx:v,data:v,props:v,attrs:v,slots:v,refs:v,setupState:v,setupContext:null,suspense:n,suspenseId:n?n.pendingId:0,asyncDep:null,asyncResolved:!1,isMounted:!1,isUnmounted:!1,isDeactivated:!1,bc:null,c:null,bm:null,m:null,bu:null,u:null,um:null,bum:null,da:null,a:null,rtg:null,rtc:null,ec:null,sp:null};s.ctx={_:s},s.root=t?t.root:s,s.emit=sn.bind(null,s),e.ce&&e.ce(s);return s}(e,o,r);if(Kn(e)&&(l.ctx.renderer=X),function(e,t=!1){Zr=t;const{props:n,children:o}=e.vnode,r=Gr(e);(function(e,t,n,o=!1){const r={},s={};Q(s,Er,1),e.propsDefaults=Object.create(null),Vo(e,t,r,s);for(const i in e.propsOptions[0])i in r||(r[i]=void 0);e.props=n?o?r:ft(r):e.type.props?r:s,e.attrs=s})(e,n,r,t),((e,t)=>{if(32&e.vnode.shapeFlag){const n=t._;n?(e.slots=bt(t),Q(t,"_",n)):Ko(t,e.slots={})}else e.slots={},t&&Go(e,t);Q(e.slots,Er,1)})(e,o);const s=r?function(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=_t(new Proxy(e.ctx,Co));const{setup:o}=n;if(o){const n=e.setupContext=o.length>1?es(e):null;zr(e),ve();const r=It(o,e,0,[e.props,n]);if(ye(),Kr(),V(r)){if(r.then(Kr,Kr),t)return r.then((n=>{Yr(e,n,t)})).catch((t=>{Lt(t,e,0)}));e.asyncDep=r}else Yr(e,r,t)}else Xr(e,t)}(e,t):void 0;Zr=!1}(l),l.asyncDep){if(r&&r.registerDep(l,$),!e.el){const e=l.subTree=Pr(gr);g(null,e,t,n)}}else $(l,e,t,n,r,s,i)},R=(e,t,n)=>{const o=t.component=e.component;if(function(e,t,n){const{props:o,children:r,component:s}=e,{props:i,children:l,patchFlag:c}=t,a=s.emitsOptions;if(t.dirs||t.transition)return!0;if(!(n&&c>=0))return!(!r&&!l||l&&l.$stable)||o!==i&&(o?!i||gn(o,i,a):!!i);if(1024&c)return!0;if(16&c)return o?gn(o,i,a):!!i;if(8&c){const e=t.dynamicProps;for(let t=0;tHt&&Dt.splice(t,1)}(o.update),o.update()}else t.el=e.el,o.vnode=t},$=(e,t,n,o,r,s,i)=>{const l=e.effect=new de((()=>{if(e.isMounted){let t,{next:n,bu:o,u:l,parent:c,vnode:a}=e,p=n;ir(e,!1),n?(n.el=a.el,M(e,n,i)):n=a,o&&Y(o),(t=n.props&&n.props.onVnodeBeforeUpdate)&&jr(t,c,n,a),ir(e,!0);const f=dn(e),d=e.subTree;e.subTree=f,h(d,f,u(d.el),J(d),e,r,s),n.el=f.el,null===p&&vn(e,f.el),l&&nr(l,r),(t=n.props&&n.props.onVnodeUpdated)&&nr((()=>jr(t,c,n,a)),r)}else{let i;const{el:l,props:c}=t,{bm:a,m:u,parent:p}=e,f=Wn(t);if(ir(e,!1),a&&Y(a),!f&&(i=c&&c.onVnodeBeforeMount)&&jr(i,p,t),ir(e,!0),l&&oe){const n=()=>{e.subTree=dn(e),oe(l,e.subTree,e,r,null)};f?t.type.__asyncLoader().then((()=>!e.isUnmounted&&n())):n()}else{const i=e.subTree=dn(e);h(null,i,n,o,e,r,s),t.el=i.el}if(u&&nr(u,r),!f&&(i=c&&c.onVnodeMounted)){const e=t;nr((()=>jr(i,p,e)),r)}(256&t.shapeFlag||p&&Wn(p.vnode)&&256&p.vnode.shapeFlag)&&e.a&&nr(e.a,r),e.isMounted=!0,t=n=o=null}}),(()=>Zt(c)),e.scope),c=e.update=()=>l.run();c.id=e.uid,ir(e,!0),c()},M=(e,t,n)=>{t.component=e;const o=e.vnode.props;e.vnode=t,e.next=null,function(e,t,n,o){const{props:r,attrs:s,vnode:{patchFlag:i}}=e,l=bt(r),[c]=e.propsOptions;let a=!1;if(!(o||i>0)||16&i){let o;Vo(e,t,r,s)&&(a=!0);for(const s in l)t&&(N(t,s)||(o=G(s))!==s&&N(t,o))||(c?!n||void 0===n[s]&&void 0===n[o]||(r[s]=Io(c,l,s,void 0,e,!0)):delete r[s]);if(s!==l)for(const e in s)t&&N(t,e)||(delete s[e],a=!0)}else if(8&i){const n=e.vnode.dynamicProps;for(let o=0;o{const{vnode:o,slots:r}=e;let s=!0,i=v;if(32&o.shapeFlag){const e=t._;e?n&&1===e?s=!1:(k(r,t),n||1!==e||delete r._):(s=!t.$stable,Ko(t,r)),i=t}else t&&(Go(e,t),i={default:1});if(s)for(const l in r)Ho(l)||l in i||delete r[l]})(e,t.children,n),ve(),Xt(),ye()},I=(e,t,n,o,r,s,i,l,c=!1)=>{const u=e&&e.children,p=e?e.shapeFlag:0,f=t.children,{patchFlag:d,shapeFlag:h}=t;if(d>0){if(128&d)return void L(u,f,n,o,r,s,i,l,c);if(256&d)return void B(u,f,n,o,r,s,i,l,c)}8&h?(16&p&&q(u,r,s),f!==u&&a(n,f)):16&p?16&h?L(u,f,n,o,r,s,i,l,c):q(u,r,s,!0):(8&p&&a(n,""),16&h&&w(f,n,o,r,s,i,l,c))},B=(e,t,n,o,r,s,i,l,c)=>{const a=(e=e||y).length,u=(t=t||y).length,p=Math.min(a,u);let f;for(f=0;fu?q(e,r,s,!0,!1,p):w(t,n,o,r,s,i,l,c,p)},L=(e,t,n,o,r,s,i,l,c)=>{let a=0;const u=t.length;let p=e.length-1,f=u-1;for(;a<=p&&a<=f;){const o=e[a],u=t[a]=c?Ir(t[a]):Vr(t[a]);if(!Nr(o,u))break;h(o,u,n,null,r,s,i,l,c),a++}for(;a<=p&&a<=f;){const o=e[p],a=t[f]=c?Ir(t[f]):Vr(t[f]);if(!Nr(o,a))break;h(o,a,n,null,r,s,i,l,c),p--,f--}if(a>p){if(a<=f){const e=f+1,p=ef)for(;a<=p;)D(e[a],r,s,!0),a++;else{const d=a,m=a,g=new Map;for(a=m;a<=f;a++){const e=t[a]=c?Ir(t[a]):Vr(t[a]);null!=e.key&&g.set(e.key,a)}let v,b=0;const _=f-m+1;let S=!1,x=0;const C=new Array(_);for(a=0;a<_;a++)C[a]=0;for(a=d;a<=p;a++){const o=e[a];if(b>=_){D(o,r,s,!0);continue}let u;if(null!=o.key)u=g.get(o.key);else for(v=m;v<=f;v++)if(0===C[v-m]&&Nr(o,t[v])){u=v;break}void 0===u?D(o,r,s,!0):(C[u-m]=a+1,u>=x?x=u:S=!0,h(o,t[u],n,null,r,s,i,l,c),b++)}const k=S?function(e){const t=e.slice(),n=[0];let o,r,s,i,l;const c=e.length;for(o=0;o>1,e[n[l]]0&&(t[o]=n[s-1]),n[s]=o)}}s=n.length,i=n[s-1];for(;s-- >0;)n[s]=i,i=t[i];return n}(C):y;for(v=k.length-1,a=_-1;a>=0;a--){const e=m+a,p=t[e],f=e+1{const{el:i,type:l,transition:c,children:a,shapeFlag:u}=e;if(6&u)return void j(e.component.subTree,t,o,r);if(128&u)return void e.suspense.move(t,o,r);if(64&u)return void l.move(e,t,o,X);if(l===hr){n(i,t,o);for(let e=0;e{let s;for(;e&&e!==t;)s=p(e),n(e,o,r),e=s;n(t,o,r)})(e,t,o);if(2!==r&&1&u&&c)if(0===r)c.beforeEnter(i),n(i,t,o),nr((()=>c.enter(i)),s);else{const{leave:e,delayLeave:r,afterLeave:s}=c,l=()=>n(i,t,o),a=()=>{e(i,(()=>{l(),s&&s()}))};r?r(i,l,a):a()}else n(i,t,o)},D=(e,t,n,o=!1,r=!1)=>{const{type:s,props:i,ref:l,children:c,dynamicChildren:a,shapeFlag:u,patchFlag:p,dirs:f}=e;if(null!=l&&Yo(l,null,n,e,!0),256&u)return void t.ctx.deactivate(e);const d=1&u&&f,h=!Wn(e);let m;if(h&&(m=i&&i.onVnodeBeforeUnmount)&&jr(m,t,e),6&u)K(e.component,n,o);else{if(128&u)return void e.suspense.unmount(n,o);d&&ho(e,null,t,"beforeUnmount"),64&u?e.type.remove(e,t,n,r,X,o):a&&(s!==hr||p>0&&64&p)?q(a,t,n,!1,!0):(s===hr&&384&p||!r&&16&u)&&q(c,t,n),o&&H(e)}(h&&(m=i&&i.onVnodeUnmounted)||d)&&nr((()=>{m&&jr(m,t,e),d&&ho(e,null,t,"unmounted")}),n)},H=e=>{const{type:t,el:n,anchor:r,transition:s}=e;if(t===hr)return void W(n,r);if(t===vr)return void(({el:e,anchor:t})=>{let n;for(;e&&e!==t;)n=p(e),o(e),e=n;o(t)})(e);const i=()=>{o(n),s&&!s.persisted&&s.afterLeave&&s.afterLeave()};if(1&e.shapeFlag&&s&&!s.persisted){const{leave:t,delayLeave:o}=s,r=()=>t(n,i);o?o(e.el,i,r):r()}else i()},W=(e,t)=>{let n;for(;e!==t;)n=p(e),o(e),e=n;o(t)},K=(e,t,n)=>{const{bum:o,scope:r,update:s,subTree:i,um:l}=e;o&&Y(o),r.stop(),s&&(s.active=!1,D(i,e,t,n)),l&&nr(l,t),nr((()=>{e.isUnmounted=!0}),t),t&&t.pendingBranch&&!t.isUnmounted&&e.asyncDep&&!e.asyncResolved&&e.suspenseId===t.pendingId&&(t.deps--,0===t.deps&&t.resolve())},q=(e,t,n,o=!1,r=!1,s=0)=>{for(let i=s;i6&e.shapeFlag?J(e.component.subTree):128&e.shapeFlag?e.suspense.next():p(e.anchor||e.el),Z=(e,t,n)=>{null==e?t._vnode&&D(t._vnode,null,null,!0):h(t._vnode||null,e,t,null,null,null,n),Xt(),en(),t._vnode=e},X={p:h,um:D,m:j,r:H,mt:P,mc:w,pc:I,pbc:E,n:J,o:e};let te,oe;return t&&([te,oe]=t(X)),{render:Z,hydrate:te,createApp:Zo(Z,te)}}function ir({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function lr(e,t,n=!1){const o=e.children,r=t.children;if(E(o)&&E(r))for(let s=0;se&&(e.disabled||""===e.disabled),ar=e=>"undefined"!=typeof SVGElement&&e instanceof SVGElement,ur=(e,t)=>{const n=e&&e.to;if(R(n)){if(t){return t(n)}return null}return n};function pr(e,t,n,{o:{insert:o},m:r},s=2){0===s&&o(e.targetAnchor,t,n);const{el:i,anchor:l,shapeFlag:c,children:a,props:u}=e,p=2===s;if(p&&o(i,t,n),(!p||cr(u))&&16&c)for(let f=0;f{16&v&&u(y,e,t,r,s,i,l,c)};g?b(n,a):p&&b(p,f)}else{t.el=e.el;const o=t.anchor=e.anchor,u=t.target=e.target,d=t.targetAnchor=e.targetAnchor,m=cr(e.props),v=m?n:u,y=m?o:d;if(i=i||ar(u),b?(f(e.dynamicChildren,b,v,r,s,i,l),lr(e,t,!0)):c||p(e,t,v,y,r,s,i,l,!1),g)m||pr(t,n,o,a,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const e=t.target=ur(t.props,h);e&&pr(t,e,null,a,0)}else m&&pr(t,u,d,a,1)}dr(t)},remove(e,t,n,o,{um:r,o:{remove:s}},i){const{shapeFlag:l,children:c,anchor:a,targetAnchor:u,target:p,props:f}=e;if(p&&s(u),(i||!cr(f))&&(s(a),16&l))for(let d=0;d0?br||y:null,Sr(),xr>0&&br&&br.push(e),e}function wr(e,t,n,o,r){return kr(Pr(e,t,n,o,r,!0))}function Tr(e){return!!e&&!0===e.__v_isVNode}function Nr(e,t){return e.type===t.type&&e.key===t.key}const Er="__vInternal",Or=({key:e})=>null!=e?e:null,Ar=({ref:e,ref_key:t,ref_for:n})=>null!=e?R(e)||wt(e)||P(e)?{i:an,r:e,k:t,f:!!n}:e:null;function Fr(e,t=null,n=null,o=0,r=null,s=(e===hr?0:1),i=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Or(t),ref:t&&Ar(t),scopeId:un,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:s,patchFlag:o,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:an};return l?(Br(c,n),128&s&&e.normalize(c)):n&&(c.shapeFlag|=R(n)?8:16),xr>0&&!i&&br&&(c.patchFlag>0||6&s)&&32!==c.patchFlag&&br.push(c),c}const Pr=function(e,t=null,n=null,r=0,s=null,i=!1){e&&e!==go||(e=gr);if(Tr(e)){const o=$r(e,t,!0);return n&&Br(o,n),xr>0&&!i&&br&&(6&o.shapeFlag?br[br.indexOf(e)]=o:br.push(o)),o.patchFlag|=-2,o}l=e,P(l)&&"__vccOpts"in l&&(e=e.__vccOpts);var l;if(t){t=Rr(t);let{class:e,style:n}=t;e&&!R(e)&&(t.class=c(e)),M(n)&&(yt(n)&&!E(n)&&(n=k({},n)),t.style=o(n))}const a=R(e)?1:yn(e)?128:(e=>e.__isTeleport)(e)?64:M(e)?4:P(e)?2:0;return Fr(e,t,n,r,s,a,i,!0)};function Rr(e){return e?yt(e)||Er in e?k({},e):e:null}function $r(e,t,n=!1){const{props:o,ref:r,patchFlag:s,children:i}=e,l=t?Lr(o||{},t):o;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Or(l),ref:t&&t.ref?n&&r?E(r)?r.concat(Ar(t)):[r,Ar(t)]:Ar(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==hr?-1===s?16:16|s:s,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&$r(e.ssContent),ssFallback:e.ssFallback&&$r(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx}}function Mr(e=" ",t=0){return Pr(mr,null,e,t)}function Vr(e){return null==e||"boolean"==typeof e?Pr(gr):E(e)?Pr(hr,null,e.slice()):"object"==typeof e?Ir(e):Pr(mr,null,String(e))}function Ir(e){return null===e.el&&-1!==e.patchFlag||e.memo?e:$r(e)}function Br(e,t){let n=0;const{shapeFlag:o}=e;if(null==t)t=null;else if(E(t))n=16;else if("object"==typeof t){if(65&o){const n=t.default;return void(n&&(n._c&&(n._d=!1),Br(e,n()),n._c&&(n._d=!0)))}{n=32;const o=t._;o||Er in t?3===o&&an&&(1===an.slots._?t._=1:(t._=2,e.patchFlag|=1024)):t._ctx=an}}else P(t)?(t={default:t,_ctx:an},n=32):(t=String(t),64&o?(n=16,t=[Mr(t)]):n=8);e.children=t,e.shapeFlag|=n}function Lr(...e){const t={};for(let n=0;nHr||an,zr=e=>{Hr=e,e.scope.on()},Kr=()=>{Hr&&Hr.scope.off(),Hr=null};function Gr(e){return 4&e.vnode.shapeFlag}let qr,Jr,Zr=!1;function Yr(e,t,n){P(t)?e.render=t:M(t)&&(e.setupState=Ft(t)),Xr(e,n)}function Qr(e){qr=e,Jr=e=>{e.render._rc&&(e.withProxy=new Proxy(e.ctx,ko))}}function Xr(e,t,n){const o=e.type;if(!e.render){if(!t&&qr&&!o.render){const t=o.template||Oo(e).template;if(t){const{isCustomElement:n,compilerOptions:r}=e.appContext.config,{delimiters:s,compilerOptions:i}=o,l=k(k({isCustomElement:n,delimiters:s},r),i);o.render=qr(t,l)}}e.render=o.render||b,Jr&&Jr(e)}zr(e),ve(),To(e),ye(),Kr()}function es(e){const t=t=>{e.exposed=t||{}};let n;return{get attrs(){return n||(n=function(e){return new Proxy(e.attrs,{get:(t,n)=>(be(e,0,"$attrs"),t[n])})}(e))},slots:e.slots,emit:e.emit,expose:t}}function ts(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(Ft(_t(e.exposed)),{get:(t,n)=>n in t?t[n]:n in So?So[n](e):void 0,has:(e,t)=>t in e||t in So}))}function ns(e,t=!0){return P(e)?e.displayName||e.name:e.name||t&&e.__name}const os=(e,t)=>function(e,t,n=!1){let o,r;const s=P(e);return s?(o=e,r=b):(o=e.get,r=e.set),new Vt(o,r,s||!r,n)}(e,0,Zr);function rs(){const e=Wr();return e.setupContext||(e.setupContext=es(e))}function ss(e,t,n){const o=arguments.length;return 2===o?M(t)&&!E(t)?Tr(t)?Pr(e,null,[t]):Pr(e,t):Pr(e,null,t):(o>3?n=Array.prototype.slice.call(arguments,2):3===o&&Tr(n)&&(n=[n]),Pr(e,t,n))}const is=Symbol("");function ls(e,t){const n=e.memo;if(n.length!=t.length)return!1;for(let o=0;o0&&br&&br.push(e),!0}const cs="3.2.45",as="undefined"!=typeof document?document:null,us=as&&as.createElement("template"),ps={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,o)=>{const r=t?as.createElementNS("http://www.w3.org/2000/svg",e):as.createElement(e,n?{is:n}:void 0);return"select"===e&&o&&null!=o.multiple&&r.setAttribute("multiple",o.multiple),r},createText:e=>as.createTextNode(e),createComment:e=>as.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>as.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,o,r,s){const i=n?n.previousSibling:t.lastChild;if(r&&(r===s||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),r!==s&&(r=r.nextSibling););else{us.innerHTML=o?`${e}`:e;const r=us.content;if(o){const e=r.firstChild;for(;e.firstChild;)r.appendChild(e.firstChild);r.removeChild(e)}t.insertBefore(r,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}};const fs=/\s*!important$/;function ds(e,t,n){if(E(n))n.forEach((n=>ds(e,t,n)));else if(null==n&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const o=function(e,t){const n=ms[t];if(n)return n;let o=z(t);if("filter"!==o&&o in e)return ms[t]=o;o=q(o);for(let r=0;r{if(e._vts){if(e._vts<=n.attached)return}else e._vts=Date.now();Bt(function(e,t){if(E(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map((e=>t=>!t._stopped&&e&&e(t)))}return t}(e,n.value),t,5,[e])};return n.value=e,n.attached=(()=>_s||(Ss.then((()=>_s=0)),_s=Date.now()))(),n}(o,r);vs(e,n,i,l)}else i&&(!function(e,t,n,o){e.removeEventListener(t,n,o)}(e,n,i,l),s[t]=void 0)}}const bs=/(?:Once|Passive|Capture)$/;let _s=0;const Ss=Promise.resolve();const xs=/^on[a-z]/;function Cs(e,t){const n=Hn(e);class o extends ws{constructor(e){super(n,e,t)}}return o.def=n,o}const ks="undefined"!=typeof HTMLElement?HTMLElement:class{};class ws extends ks{constructor(e,t={},n){super(),this._def=e,this._props=t,this._instance=null,this._connected=!1,this._resolved=!1,this._numberProps=null,this.shadowRoot&&n?n(this._createVNode(),this.shadowRoot):(this.attachShadow({mode:"open"}),this._def.__asyncLoader||this._resolveProps(this._def))}connectedCallback(){this._connected=!0,this._instance||(this._resolved?this._update():this._resolveDef())}disconnectedCallback(){this._connected=!1,Jt((()=>{this._connected||(Si(null,this.shadowRoot),this._instance=null)}))}_resolveDef(){this._resolved=!0;for(let n=0;n{for(const t of e)this._setAttr(t.attributeName)})).observe(this,{attributes:!0});const e=(e,t=!1)=>{const{props:n,styles:o}=e;let r;if(n&&!E(n))for(const s in n){const e=n[s];(e===Number||e&&e.type===Number)&&(s in this._props&&(this._props[s]=X(this._props[s])),(r||(r=Object.create(null)))[z(s)]=!0)}this._numberProps=r,t&&this._resolveProps(e),this._applyStyles(o),this._update()},t=this._def.__asyncLoader;t?t().then((t=>e(t,!0))):e(this._def)}_resolveProps(e){const{props:t}=e,n=E(t)?t:Object.keys(t||{});for(const o of Object.keys(this))"_"!==o[0]&&n.includes(o)&&this._setProp(o,this[o],!0,!1);for(const o of n.map(z))Object.defineProperty(this,o,{get(){return this._getProp(o)},set(e){this._setProp(o,e)}})}_setAttr(e){let t=this.getAttribute(e);const n=z(e);this._numberProps&&this._numberProps[n]&&(t=X(t)),this._setProp(n,t,!1)}_getProp(e){return this._props[e]}_setProp(e,t,n=!0,o=!0){t!==this._props[e]&&(this._props[e]=t,o&&this._instance&&this._update(),n&&(!0===t?this.setAttribute(G(e),""):"string"==typeof t||"number"==typeof t?this.setAttribute(G(e),t+""):t||this.removeAttribute(G(e))))}_update(){Si(this._createVNode(),this.shadowRoot)}_createVNode(){const e=Pr(this._def,k({},this._props));return this._instance||(e.ce=e=>{this._instance=e,e.isCE=!0;const t=(e,t)=>{this.dispatchEvent(new CustomEvent(e,{detail:t}))};e.emit=(e,...n)=>{t(e,n),G(e)!==e&&t(G(e),n)};let n=this;for(;n=n&&(n.parentNode||n.host);)if(n instanceof ws){e.parent=n._instance,e.provides=n._instance.provides;break}}),e}_applyStyles(e){e&&e.forEach((e=>{const t=document.createElement("style");t.textContent=e,this.shadowRoot.appendChild(t)}))}}function Ts(e,t){if(128&e.shapeFlag){const n=e.suspense;e=n.activeBranch,n.pendingBranch&&!n.isHydrating&&n.effects.push((()=>{Ts(n.activeBranch,t)}))}for(;e.component;)e=e.component.subTree;if(1&e.shapeFlag&&e.el)Ns(e.el,t);else if(e.type===hr)e.children.forEach((e=>Ts(e,t)));else if(e.type===vr){let{el:n,anchor:o}=e;for(;n&&(Ns(n,t),n!==o);)n=n.nextSibling}}function Ns(e,t){if(1===e.nodeType){const n=e.style;for(const e in t)n.setProperty(`--${e}`,t[e])}}const Es="transition",Os="animation",As=(e,{slots:t})=>ss(Vn,Ms(e),t);As.displayName="Transition";const Fs={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Ps=As.props=k({},Vn.props,Fs),Rs=(e,t=[])=>{E(e)?e.forEach((e=>e(...t))):e&&e(...t)},$s=e=>!!e&&(E(e)?e.some((e=>e.length>1)):e.length>1);function Ms(e){const t={};for(const k in e)k in Fs||(t[k]=e[k]);if(!1===e.css)return t;const{name:n="v",type:o,duration:r,enterFromClass:s=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=s,appearActiveClass:a=i,appearToClass:u=l,leaveFromClass:p=`${n}-leave-from`,leaveActiveClass:f=`${n}-leave-active`,leaveToClass:d=`${n}-leave-to`}=e,h=function(e){if(null==e)return null;if(M(e))return[Vs(e.enter),Vs(e.leave)];{const t=Vs(e);return[t,t]}}(r),m=h&&h[0],g=h&&h[1],{onBeforeEnter:v,onEnter:y,onEnterCancelled:b,onLeave:_,onLeaveCancelled:S,onBeforeAppear:x=v,onAppear:C=y,onAppearCancelled:w=b}=t,T=(e,t,n)=>{Bs(e,t?u:l),Bs(e,t?a:i),n&&n()},N=(e,t)=>{e._isLeaving=!1,Bs(e,p),Bs(e,d),Bs(e,f),t&&t()},E=e=>(t,n)=>{const r=e?C:y,i=()=>T(t,e,n);Rs(r,[t,i]),Ls((()=>{Bs(t,e?c:s),Is(t,e?u:l),$s(r)||Us(t,o,m,i)}))};return k(t,{onBeforeEnter(e){Rs(v,[e]),Is(e,s),Is(e,i)},onBeforeAppear(e){Rs(x,[e]),Is(e,c),Is(e,a)},onEnter:E(!1),onAppear:E(!0),onLeave(e,t){e._isLeaving=!0;const n=()=>N(e,t);Is(e,p),zs(),Is(e,f),Ls((()=>{e._isLeaving&&(Bs(e,p),Is(e,d),$s(_)||Us(e,o,g,n))})),Rs(_,[e,n])},onEnterCancelled(e){T(e,!1),Rs(b,[e])},onAppearCancelled(e){T(e,!0),Rs(w,[e])},onLeaveCancelled(e){N(e),Rs(S,[e])}})}function Vs(e){return X(e)}function Is(e,t){t.split(/\s+/).forEach((t=>t&&e.classList.add(t))),(e._vtc||(e._vtc=new Set)).add(t)}function Bs(e,t){t.split(/\s+/).forEach((t=>t&&e.classList.remove(t)));const{_vtc:n}=e;n&&(n.delete(t),n.size||(e._vtc=void 0))}function Ls(e){requestAnimationFrame((()=>{requestAnimationFrame(e)}))}let js=0;function Us(e,t,n,o){const r=e._endId=++js,s=()=>{r===e._endId&&o()};if(n)return setTimeout(s,n);const{type:i,timeout:l,propCount:c}=Ds(e,t);if(!i)return o();const a=i+"end";let u=0;const p=()=>{e.removeEventListener(a,f),s()},f=t=>{t.target===e&&++u>=c&&p()};setTimeout((()=>{u(n[e]||"").split(", "),r=o("transitionDelay"),s=o("transitionDuration"),i=Hs(r,s),l=o("animationDelay"),c=o("animationDuration"),a=Hs(l,c);let u=null,p=0,f=0;t===Es?i>0&&(u=Es,p=i,f=s.length):t===Os?a>0&&(u=Os,p=a,f=c.length):(p=Math.max(i,a),u=p>0?i>a?Es:Os:null,f=u?u===Es?s.length:c.length:0);return{type:u,timeout:p,propCount:f,hasTransform:u===Es&&/\b(transform|all)(,|$)/.test(o("transitionProperty").toString())}}function Hs(e,t){for(;e.lengthWs(t)+Ws(e[n]))))}function Ws(e){return 1e3*Number(e.slice(0,-1).replace(",","."))}function zs(){return document.body.offsetHeight}const Ks=new WeakMap,Gs=new WeakMap,qs={name:"TransitionGroup",props:k({},Ps,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=Wr(),o=$n();let r,s;return io((()=>{if(!r.length)return;const t=e.moveClass||`${e.name||"v"}-move`;if(!function(e,t,n){const o=e.cloneNode();e._vtc&&e._vtc.forEach((e=>{e.split(/\s+/).forEach((e=>e&&o.classList.remove(e)))}));n.split(/\s+/).forEach((e=>e&&o.classList.add(e))),o.style.display="none";const r=1===t.nodeType?t:t.parentNode;r.appendChild(o);const{hasTransform:s}=Ds(o);return r.removeChild(o),s}(r[0].el,n.vnode.el,t))return;r.forEach(Js),r.forEach(Zs);const o=r.filter(Ys);zs(),o.forEach((e=>{const n=e.el,o=n.style;Is(n,t),o.transform=o.webkitTransform=o.transitionDuration="";const r=n._moveCb=e=>{e&&e.target!==n||e&&!/transform$/.test(e.propertyName)||(n.removeEventListener("transitionend",r),n._moveCb=null,Bs(n,t))};n.addEventListener("transitionend",r)}))})),()=>{const i=bt(e),l=Ms(i);let c=i.tag||hr;r=s,s=t.default?Dn(t.default()):[];for(let e=0;e{const t=e.props["onUpdate:modelValue"]||!1;return E(t)?e=>Y(t,e):t};function Xs(e){e.target.composing=!0}function ei(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const ti={created(e,{modifiers:{lazy:t,trim:n,number:o}},r){e._assign=Qs(r);const s=o||r.props&&"number"===r.props.type;vs(e,t?"change":"input",(t=>{if(t.target.composing)return;let o=e.value;n&&(o=o.trim()),s&&(o=X(o)),e._assign(o)})),n&&vs(e,"change",(()=>{e.value=e.value.trim()})),t||(vs(e,"compositionstart",Xs),vs(e,"compositionend",ei),vs(e,"change",ei))},mounted(e,{value:t}){e.value=null==t?"":t},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:o,number:r}},s){if(e._assign=Qs(s),e.composing)return;if(document.activeElement===e&&"range"!==e.type){if(n)return;if(o&&e.value.trim()===t)return;if((r||"number"===e.type)&&X(e.value)===t)return}const i=null==t?"":t;e.value!==i&&(e.value=i)}},ni={deep:!0,created(e,t,n){e._assign=Qs(n),vs(e,"change",(()=>{const t=e._modelValue,n=li(e),o=e.checked,r=e._assign;if(E(t)){const e=m(t,n),s=-1!==e;if(o&&!s)r(t.concat(n));else if(!o&&s){const n=[...t];n.splice(e,1),r(n)}}else if(A(t)){const e=new Set(t);o?e.add(n):e.delete(n),r(e)}else r(ci(e,o))}))},mounted:oi,beforeUpdate(e,t,n){e._assign=Qs(n),oi(e,t,n)}};function oi(e,{value:t,oldValue:n},o){e._modelValue=t,E(t)?e.checked=m(t,o.props.value)>-1:A(t)?e.checked=t.has(o.props.value):t!==n&&(e.checked=h(t,ci(e,!0)))}const ri={created(e,{value:t},n){e.checked=h(t,n.props.value),e._assign=Qs(n),vs(e,"change",(()=>{e._assign(li(e))}))},beforeUpdate(e,{value:t,oldValue:n},o){e._assign=Qs(o),t!==n&&(e.checked=h(t,o.props.value))}},si={deep:!0,created(e,{value:t,modifiers:{number:n}},o){const r=A(t);vs(e,"change",(()=>{const t=Array.prototype.filter.call(e.options,(e=>e.selected)).map((e=>n?X(li(e)):li(e)));e._assign(e.multiple?r?new Set(t):t:t[0])})),e._assign=Qs(o)},mounted(e,{value:t}){ii(e,t)},beforeUpdate(e,t,n){e._assign=Qs(n)},updated(e,{value:t}){ii(e,t)}};function ii(e,t){const n=e.multiple;if(!n||E(t)||A(t)){for(let o=0,r=e.options.length;o-1:t.has(s);else if(h(li(r),t))return void(e.selectedIndex!==o&&(e.selectedIndex=o))}n||-1===e.selectedIndex||(e.selectedIndex=-1)}}function li(e){return"_value"in e?e._value:e.value}function ci(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const ai={created(e,t,n){ui(e,t,n,null,"created")},mounted(e,t,n){ui(e,t,n,null,"mounted")},beforeUpdate(e,t,n,o){ui(e,t,n,o,"beforeUpdate")},updated(e,t,n,o){ui(e,t,n,o,"updated")}};function ui(e,t,n,o,r){const s=function(e,t){switch(e){case"SELECT":return si;case"TEXTAREA":return ti;default:switch(t){case"checkbox":return ni;case"radio":return ri;default:return ti}}}(e.tagName,n.props&&n.props.type)[r];s&&s(e,t,n,o)}const pi=["ctrl","shift","alt","meta"],fi={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&0!==e.button,middle:e=>"button"in e&&1!==e.button,right:e=>"button"in e&&2!==e.button,exact:(e,t)=>pi.some((n=>e[`${n}Key`]&&!t.includes(n)))},di={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},hi={beforeMount(e,{value:t},{transition:n}){e._vod="none"===e.style.display?"":e.style.display,n&&t?n.beforeEnter(e):mi(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:o}){!t!=!n&&(o?t?(o.beforeEnter(e),mi(e,!0),o.enter(e)):o.leave(e,(()=>{mi(e,!1)})):mi(e,t))},beforeUnmount(e,{value:t}){mi(e,t)}};function mi(e,t){e.style.display=t?e._vod:"none"}const gi=k({patchProp:(e,t,n,o,r=!1,s,i,l,c)=>{"class"===t?function(e,t,n){const o=e._vtc;o&&(t=(t?[t,...o]:[...o]).join(" ")),null==t?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}(e,o,r):"style"===t?function(e,t,n){const o=e.style,r=R(n);if(n&&!r){for(const e in n)ds(o,e,n[e]);if(t&&!R(t))for(const e in t)null==n[e]&&ds(o,e,"")}else{const s=o.display;r?t!==n&&(o.cssText=n):t&&e.removeAttribute("style"),"_vod"in e&&(o.display=s)}}(e,n,o):x(t)?C(t)||ys(e,t,0,o,i):("."===t[0]?(t=t.slice(1),1):"^"===t[0]?(t=t.slice(1),0):function(e,t,n,o){if(o)return"innerHTML"===t||"textContent"===t||!!(t in e&&xs.test(t)&&P(n));if("spellcheck"===t||"draggable"===t||"translate"===t)return!1;if("form"===t)return!1;if("list"===t&&"INPUT"===e.tagName)return!1;if("type"===t&&"TEXTAREA"===e.tagName)return!1;if(xs.test(t)&&R(n))return!1;return t in e}(e,t,o,r))?function(e,t,n,o,r,s,i){if("innerHTML"===t||"textContent"===t)return o&&i(o,r,s),void(e[t]=null==n?"":n);if("value"===t&&"PROGRESS"!==e.tagName&&!e.tagName.includes("-")){e._value=n;const o=null==n?"":n;return e.value===o&&"OPTION"!==e.tagName||(e.value=o),void(null==n&&e.removeAttribute(t))}let l=!1;if(""===n||null==n){const o=typeof e[t];"boolean"===o?n=d(n):null==n&&"string"===o?(n="",l=!0):"number"===o&&(n=0,l=!0)}try{e[t]=n}catch(c){}l&&e.removeAttribute(t)}(e,t,o,s,i,l,c):("true-value"===t?e._trueValue=o:"false-value"===t&&(e._falseValue=o),function(e,t,n,o,r){if(o&&t.startsWith("xlink:"))null==n?e.removeAttributeNS(gs,t.slice(6,t.length)):e.setAttributeNS(gs,t,n);else{const o=f(t);null==n||o&&!d(n)?e.removeAttribute(t):e.setAttribute(t,o?"":n)}}(e,t,o,r))}},ps);let vi,yi=!1;function bi(){return vi||(vi=or(gi))}function _i(){return vi=yi?vi:rr(gi),yi=!0,vi}const Si=(...e)=>{bi().render(...e)},xi=(...e)=>{_i().hydrate(...e)};function Ci(e){if(R(e)){return document.querySelector(e)}return e}const ki=b;function wi(e){throw e}function Ti(e){}function Ni(e,t,n,o){const r=new SyntaxError(String(e));return r.code=e,r.loc=t,r}const Ei=Symbol(""),Oi=Symbol(""),Ai=Symbol(""),Fi=Symbol(""),Pi=Symbol(""),Ri=Symbol(""),$i=Symbol(""),Mi=Symbol(""),Vi=Symbol(""),Ii=Symbol(""),Bi=Symbol(""),Li=Symbol(""),ji=Symbol(""),Ui=Symbol(""),Di=Symbol(""),Hi=Symbol(""),Wi=Symbol(""),zi=Symbol(""),Ki=Symbol(""),Gi=Symbol(""),qi=Symbol(""),Ji=Symbol(""),Zi=Symbol(""),Yi=Symbol(""),Qi=Symbol(""),Xi=Symbol(""),el=Symbol(""),tl=Symbol(""),nl=Symbol(""),ol=Symbol(""),rl=Symbol(""),sl=Symbol(""),il=Symbol(""),ll=Symbol(""),cl=Symbol(""),al=Symbol(""),ul=Symbol(""),pl=Symbol(""),fl=Symbol(""),dl={[Ei]:"Fragment",[Oi]:"Teleport",[Ai]:"Suspense",[Fi]:"KeepAlive",[Pi]:"BaseTransition",[Ri]:"openBlock",[$i]:"createBlock",[Mi]:"createElementBlock",[Vi]:"createVNode",[Ii]:"createElementVNode",[Bi]:"createCommentVNode",[Li]:"createTextVNode",[ji]:"createStaticVNode",[Ui]:"resolveComponent",[Di]:"resolveDynamicComponent",[Hi]:"resolveDirective",[Wi]:"resolveFilter",[zi]:"withDirectives",[Ki]:"renderList",[Gi]:"renderSlot",[qi]:"createSlots",[Ji]:"toDisplayString",[Zi]:"mergeProps",[Yi]:"normalizeClass",[Qi]:"normalizeStyle",[Xi]:"normalizeProps",[el]:"guardReactiveProps",[tl]:"toHandlers",[nl]:"camelize",[ol]:"capitalize",[rl]:"toHandlerKey",[sl]:"setBlockTracking",[il]:"pushScopeId",[ll]:"popScopeId",[cl]:"withCtx",[al]:"unref",[ul]:"isRef",[pl]:"withMemo",[fl]:"isMemoSame"};const hl={source:"",start:{line:1,column:1,offset:0},end:{line:1,column:1,offset:0}};function ml(e,t,n,o,r,s,i,l=!1,c=!1,a=!1,u=hl){return e&&(l?(e.helper(Ri),e.helper(Wl(e.inSSR,a))):e.helper(Hl(e.inSSR,a)),i&&e.helper(zi)),{type:13,tag:t,props:n,children:o,patchFlag:r,dynamicProps:s,directives:i,isBlock:l,disableTracking:c,isComponent:a,loc:u}}function gl(e,t=hl){return{type:17,loc:t,elements:e}}function vl(e,t=hl){return{type:15,loc:t,properties:e}}function yl(e,t){return{type:16,loc:hl,key:R(e)?bl(e,!0):e,value:t}}function bl(e,t=!1,n=hl,o=0){return{type:4,loc:n,content:e,isStatic:t,constType:t?3:o}}function _l(e,t=hl){return{type:8,loc:t,children:e}}function Sl(e,t=[],n=hl){return{type:14,loc:n,callee:e,arguments:t}}function xl(e,t,n=!1,o=!1,r=hl){return{type:18,params:e,returns:t,newline:n,isSlot:o,loc:r}}function Cl(e,t,n,o=!0){return{type:19,test:e,consequent:t,alternate:n,newline:o,loc:hl}}const kl=e=>4===e.type&&e.isStatic,wl=(e,t)=>e===t||e===G(t);function Tl(e){return wl(e,"Teleport")?Oi:wl(e,"Suspense")?Ai:wl(e,"KeepAlive")?Fi:wl(e,"BaseTransition")?Pi:void 0}const Nl=/^\d|[^\$\w]/,El=e=>!Nl.test(e),Ol=/[A-Za-z_$\xA0-\uFFFF]/,Al=/[\.\?\w$\xA0-\uFFFF]/,Fl=/\s+[.[]\s*|\s*[.[]\s+/g,Pl=e=>{e=e.trim().replace(Fl,(e=>e.trim()));let t=0,n=[],o=0,r=0,s=null;for(let i=0;i4===e.key.type&&e.key.content===o))}return n}function Jl(e,t){return`_${t}_${e.replace(/[^\w]/g,((t,n)=>"-"===t?"_":e.charCodeAt(n).toString()))}`}function Zl(e,{helper:t,removeHelper:n,inSSR:o}){e.isBlock||(e.isBlock=!0,n(Hl(o,e.isComponent)),t(Ri),t(Wl(o,e.isComponent)))}const Yl=/&(gt|lt|amp|apos|quot);/g,Ql={gt:">",lt:"<",amp:"&",apos:"'",quot:'"'},Xl={delimiters:["{{","}}"],getNamespace:()=>0,getTextMode:()=>0,isVoidTag:_,isPreTag:_,isCustomElement:_,decodeEntities:e=>e.replace(Yl,((e,t)=>Ql[t])),onError:wi,onWarn:Ti,comments:!1};function ec(e,t={}){const n=function(e,t){const n=k({},Xl);let o;for(o in t)n[o]=void 0===t[o]?Xl[o]:t[o];return{options:n,column:1,line:1,offset:0,originalSource:e,source:e,inPre:!1,inVPre:!1,onWarn:n.onWarn}}(e,t),o=hc(n);return function(e,t=hl){return{type:0,children:e,helpers:[],components:[],directives:[],hoists:[],imports:[],cached:0,temps:0,codegenNode:void 0,loc:t}}(tc(n,0,[]),mc(n,o))}function tc(e,t,n){const o=gc(n),r=o?o.ns:0,s=[];for(;!Sc(e,t,n);){const i=e.source;let l;if(0===t||1===t)if(!e.inVPre&&vc(i,e.options.delimiters[0]))l=pc(e,t);else if(0===t&&"<"===i[0])if(1===i.length);else if("!"===i[1])l=vc(i,"\x3c!--")?rc(e):vc(i,""===i[2]){yc(e,3);continue}if(/[a-z]/i.test(i[2])){cc(e,1,o);continue}l=sc(e)}else/[a-z]/i.test(i[1])?l=ic(e,n):"?"===i[1]&&(l=sc(e));if(l||(l=fc(e,t)),E(l))for(let e=0;e/.exec(e.source);if(o){n=e.source.slice(4,o.index);const t=e.source.slice(0,o.index);let r=1,s=0;for(;-1!==(s=t.indexOf("\x3c!--",r));)yc(e,s-r+1),r=s+1;yc(e,o.index+o[0].length-r+1)}else n=e.source.slice(4),yc(e,e.source.length);return{type:3,content:n,loc:mc(e,t)}}function sc(e){const t=hc(e),n="?"===e.source[1]?1:2;let o;const r=e.source.indexOf(">");return-1===r?(o=e.source.slice(n),yc(e,e.source.length)):(o=e.source.slice(n,r),yc(e,r+1)),{type:3,content:o,loc:mc(e,t)}}function ic(e,t){const n=e.inPre,o=e.inVPre,r=gc(t),s=cc(e,0,r),i=e.inPre&&!n,l=e.inVPre&&!o;if(s.isSelfClosing||e.options.isVoidTag(s.tag))return i&&(e.inPre=!1),l&&(e.inVPre=!1),s;t.push(s);const c=e.options.getTextMode(s,r),a=tc(e,c,t);if(t.pop(),s.children=a,xc(e.source,s.tag))cc(e,1,r);else if(0===e.source.length&&"script"===s.tag.toLowerCase()){const e=a[0];e&&vc(e.loc.source,"\x3c!--")}return s.loc=mc(e,s.loc.start),i&&(e.inPre=!1),l&&(e.inVPre=!1),s}const lc=t("if,else,else-if,for,slot");function cc(e,t,n){const o=hc(e),r=/^<\/?([a-z][^\t\r\n\f />]*)/i.exec(e.source),s=r[1],i=e.options.getNamespace(s,n);yc(e,r[0].length),bc(e);const l=hc(e),c=e.source;e.options.isPreTag(s)&&(e.inPre=!0);let a=ac(e,t);0===t&&!e.inVPre&&a.some((e=>7===e.type&&"pre"===e.name))&&(e.inVPre=!0,k(e,l),e.source=c,a=ac(e,t).filter((e=>"v-pre"!==e.name)));let u=!1;if(0===e.source.length||(u=vc(e.source,"/>"),yc(e,u?2:1)),1===t)return;let p=0;return e.inVPre||("slot"===s?p=2:"template"===s?a.some((e=>7===e.type&&lc(e.name)))&&(p=3):function(e,t,n){const o=n.options;if(o.isCustomElement(e))return!1;if("component"===e||/^[A-Z]/.test(e)||Tl(e)||o.isBuiltInComponent&&o.isBuiltInComponent(e)||o.isNativeTag&&!o.isNativeTag(e))return!0;for(let r=0;r0&&!vc(e.source,">")&&!vc(e.source,"/>");){if(vc(e.source,"/")){yc(e,1),bc(e);continue}const r=uc(e,o);6===r.type&&r.value&&"class"===r.name&&(r.value.content=r.value.content.replace(/\s+/g," ").trim()),0===t&&n.push(r),/^[^\t\r\n\f />]/.test(e.source),bc(e)}return n}function uc(e,t){const n=hc(e),o=/^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(e.source)[0];t.has(o),t.add(o);{const e=/["'<]/g;let t;for(;t=e.exec(o););}let r;yc(e,o.length),/^[\t\r\n\f ]*=/.test(e.source)&&(bc(e),yc(e,1),bc(e),r=function(e){const t=hc(e);let n;const o=e.source[0],r='"'===o||"'"===o;if(r){yc(e,1);const t=e.source.indexOf(o);-1===t?n=dc(e,e.source.length,4):(n=dc(e,t,4),yc(e,1))}else{const t=/^[^\t\r\n\f >]+/.exec(e.source);if(!t)return;const o=/["'<=`]/g;let r;for(;r=o.exec(t[0]););n=dc(e,t[0].length,4)}return{content:n,isQuoted:r,loc:mc(e,t)}}(e));const s=mc(e,n);if(!e.inVPre&&/^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(o)){const t=/(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(o);let i,l=vc(o,"."),c=t[1]||(l||vc(o,":")?"bind":vc(o,"@")?"on":"slot");if(t[2]){const r="slot"===c,s=o.lastIndexOf(t[2]),l=mc(e,_c(e,n,s),_c(e,n,s+t[2].length+(r&&t[3]||"").length));let a=t[2],u=!0;a.startsWith("[")?(u=!1,a=a.endsWith("]")?a.slice(1,a.length-1):a.slice(1)):r&&(a+=t[3]||""),i={type:4,content:a,isStatic:u,constType:u?3:0,loc:l}}if(r&&r.isQuoted){const e=r.loc;e.start.offset++,e.start.column++,e.end=$l(e.start,r.content),e.source=e.source.slice(1,-1)}const a=t[3]?t[3].slice(1).split("."):[];return l&&a.push("prop"),{type:7,name:c,exp:r&&{type:4,content:r.content,isStatic:!1,constType:0,loc:r.loc},arg:i,modifiers:a,loc:s}}return!e.inVPre&&vc(o,"v-"),{type:6,name:o,value:r&&{type:2,content:r.content,loc:r.loc},loc:s}}function pc(e,t){const[n,o]=e.options.delimiters,r=e.source.indexOf(o,n.length);if(-1===r)return;const s=hc(e);yc(e,n.length);const i=hc(e),l=hc(e),c=r-n.length,a=e.source.slice(0,c),u=dc(e,c,t),p=u.trim(),f=u.indexOf(p);f>0&&Ml(i,a,f);return Ml(l,a,c-(u.length-p.length-f)),yc(e,o.length),{type:5,content:{type:4,isStatic:!1,constType:0,content:p,loc:mc(e,i,l)},loc:mc(e,s)}}function fc(e,t){const n=3===t?["]]>"]:["<",e.options.delimiters[0]];let o=e.source.length;for(let s=0;st&&(o=t)}const r=hc(e);return{type:2,content:dc(e,o,t),loc:mc(e,r)}}function dc(e,t,n){const o=e.source.slice(0,t);return yc(e,t),2!==n&&3!==n&&o.includes("&")?e.options.decodeEntities(o,4===n):o}function hc(e){const{column:t,line:n,offset:o}=e;return{column:t,line:n,offset:o}}function mc(e,t,n){return{start:t,end:n=n||hc(e),source:e.originalSource.slice(t.offset,n.offset)}}function gc(e){return e[e.length-1]}function vc(e,t){return e.startsWith(t)}function yc(e,t){const{source:n}=e;Ml(e,n,t),e.source=n.slice(t)}function bc(e){const t=/^[\t\r\n\f ]+/.exec(e.source);t&&yc(e,t[0].length)}function _c(e,t,n){return $l(t,e.originalSource.slice(t.offset,n),n)}function Sc(e,t,n){const o=e.source;switch(t){case 0:if(vc(o,"=0;--e)if(xc(o,n[e].tag))return!0;break;case 1:case 2:{const e=gc(n);if(e&&xc(o,e.tag))return!0;break}case 3:if(vc(o,"]]>"))return!0}return!o}function xc(e,t){return vc(e,"]/.test(e[2+t.length]||">")}function Cc(e,t){wc(e,t,kc(e,e.children[0]))}function kc(e,t){const{children:n}=e;return 1===n.length&&1===t.type&&!Dl(t)}function wc(e,t,n=!1){const{children:o}=e,r=o.length;let s=0;for(let i=0;i0){if(o>=2){e.codegenNode.patchFlag="-1",e.codegenNode=t.hoist(e.codegenNode),s++;continue}}else{const n=e.codegenNode;if(13===n.type){const o=Fc(n);if((!o||512===o||1===o)&&Oc(e,t)>=2){const o=Ac(e);o&&(n.props=t.hoist(o))}n.dynamicProps&&(n.dynamicProps=t.hoist(n.dynamicProps))}}}if(1===e.type){const n=1===e.tagType;n&&t.scopes.vSlot++,wc(e,t),n&&t.scopes.vSlot--}else if(11===e.type)wc(e,t,1===e.children.length);else if(9===e.type)for(let n=0;n1)for(let r=0;r`_${dl[w.helper(e)]}`,replaceNode(e){w.parent.children[w.childIndex]=w.currentNode=e},removeNode(e){const t=e?w.parent.children.indexOf(e):w.currentNode?w.childIndex:-1;e&&e!==w.currentNode?w.childIndex>t&&(w.childIndex--,w.onNodeRemoved()):(w.currentNode=null,w.onNodeRemoved()),w.parent.children.splice(t,1)},onNodeRemoved:()=>{},addIdentifiers(e){},removeIdentifiers(e){},hoist(e){R(e)&&(e=bl(e)),w.hoists.push(e);const t=bl(`_hoisted_${w.hoists.length}`,!1,e.loc,2);return t.hoisted=e,t},cache:(e,t=!1)=>function(e,t,n=!1){return{type:20,index:e,value:t,isVNode:n,loc:hl}}(w.cached++,e,t)};return w}function Rc(e,t){const n=Pc(e,t);$c(e,n),t.hoistStatic&&Cc(e,n),t.ssr||function(e,t){const{helper:n}=t,{children:o}=e;if(1===o.length){const n=o[0];if(kc(e,n)&&n.codegenNode){const o=n.codegenNode;13===o.type&&Zl(o,t),e.codegenNode=o}else e.codegenNode=n}else if(o.length>1){let o=64;e.codegenNode=ml(t,n(Ei),void 0,e.children,o+"",void 0,void 0,!0,void 0,!1)}}(e,n),e.helpers=[...n.helpers.keys()],e.components=[...n.components],e.directives=[...n.directives],e.imports=n.imports,e.hoists=n.hoists,e.temps=n.temps,e.cached=n.cached}function $c(e,t){t.currentNode=e;const{nodeTransforms:n}=t,o=[];for(let s=0;s{n--};for(;nt===e:t=>e.test(t);return(e,o)=>{if(1===e.type){const{props:r}=e;if(3===e.tagType&&r.some(jl))return;const s=[];for(let i=0;i`${dl[e]}: _${dl[e]}`;function Bc(e,t={}){const n=function(e,{mode:t="function",prefixIdentifiers:n="module"===t,sourceMap:o=!1,filename:r="template.vue.html",scopeId:s=null,optimizeImports:i=!1,runtimeGlobalName:l="Vue",runtimeModuleName:c="vue",ssrRuntimeModuleName:a="vue/server-renderer",ssr:u=!1,isTS:p=!1,inSSR:f=!1}){const d={mode:t,prefixIdentifiers:n,sourceMap:o,filename:r,scopeId:s,optimizeImports:i,runtimeGlobalName:l,runtimeModuleName:c,ssrRuntimeModuleName:a,ssr:u,isTS:p,inSSR:f,source:e.loc.source,code:"",column:1,line:1,offset:0,indentLevel:0,pure:!1,map:void 0,helper:e=>`_${dl[e]}`,push(e,t){d.code+=e},indent(){h(++d.indentLevel)},deindent(e=!1){e?--d.indentLevel:h(--d.indentLevel)},newline(){h(d.indentLevel)}};function h(e){d.push("\n"+" ".repeat(e))}return d}(e,t);t.onContextCreated&&t.onContextCreated(n);const{mode:o,push:r,prefixIdentifiers:s,indent:i,deindent:l,newline:c,ssr:a}=n,u=e.helpers.length>0,p=!s&&"module"!==o;!function(e,t){const{push:n,newline:o,runtimeGlobalName:r}=t,s=r;if(e.helpers.length>0&&(n(`const _Vue = ${s}\n`),e.hoists.length)){n(`const { ${[Vi,Ii,Bi,Li,ji].filter((t=>e.helpers.includes(t))).map(Ic).join(", ")} } = _Vue\n`)}(function(e,t){if(!e.length)return;t.pure=!0;const{push:n,newline:o}=t;o();for(let r=0;r0)&&c()),e.directives.length&&(Lc(e.directives,"directive",n),e.temps>0&&c()),e.temps>0){r("let ");for(let t=0;t0?", ":""}_temp${t}`)}return(e.components.length||e.directives.length||e.temps)&&(r("\n"),c()),a||r("return "),e.codegenNode?Dc(e.codegenNode,n):r("null"),p&&(l(),r("}")),l(),r("}"),{ast:e,code:n.code,preamble:"",map:n.map?n.map.toJSON():void 0}}function Lc(e,t,{helper:n,push:o,newline:r,isTS:s}){const i=n("component"===t?Ui:Hi);for(let l=0;l3||!1;t.push("["),n&&t.indent(),Uc(e,t,n),n&&t.deindent(),t.push("]")}function Uc(e,t,n=!1,o=!0){const{push:r,newline:s}=t;for(let i=0;ie||"null"))}([s,i,l,c,a]),t),n(")"),p&&n(")");u&&(n(", "),Dc(u,t),n(")"))}(e,t);break;case 14:!function(e,t){const{push:n,helper:o,pure:r}=t,s=R(e.callee)?e.callee:o(e.callee);r&&n(Vc);n(s+"(",e),Uc(e.arguments,t),n(")")}(e,t);break;case 15:!function(e,t){const{push:n,indent:o,deindent:r,newline:s}=t,{properties:i}=e;if(!i.length)return void n("{}",e);const l=i.length>1||!1;n(l?"{":"{ "),l&&o();for(let c=0;c "),(c||l)&&(n("{"),o());i?(c&&n("return "),E(i)?jc(i,t):Dc(i,t)):l&&Dc(l,t);(c||l)&&(r(),n("}"));a&&n(")")}(e,t);break;case 19:!function(e,t){const{test:n,consequent:o,alternate:r,newline:s}=e,{push:i,indent:l,deindent:c,newline:a}=t;if(4===n.type){const e=!El(n.content);e&&i("("),Hc(n,t),e&&i(")")}else i("("),Dc(n,t),i(")");s&&l(),t.indentLevel++,s||i(" "),i("? "),Dc(o,t),t.indentLevel--,s&&a(),s||i(" "),i(": ");const u=19===r.type;u||t.indentLevel++;Dc(r,t),u||t.indentLevel--;s&&c(!0)}(e,t);break;case 20:!function(e,t){const{push:n,helper:o,indent:r,deindent:s,newline:i}=t;n(`_cache[${e.index}] || (`),e.isVNode&&(r(),n(`${o(sl)}(-1),`),i());n(`_cache[${e.index}] = `),Dc(e.value,t),e.isVNode&&(n(","),i(),n(`${o(sl)}(1),`),i(),n(`_cache[${e.index}]`),s());n(")")}(e,t);break;case 21:Uc(e.body,t,!0,!1)}}function Hc(e,t){const{content:n,isStatic:o}=e;t.push(o?JSON.stringify(n):n,e)}function Wc(e,t){for(let n=0;nfunction(e,t,n,o){if(!("else"===t.name||t.exp&&t.exp.content.trim())){t.exp=bl("true",!1,t.exp?t.exp.loc:e.loc)}if("if"===t.name){const r=Gc(e,t),s={type:9,loc:e.loc,branches:[r]};if(n.replaceNode(s),o)return o(s,r,!0)}else{const r=n.parent.children;let s=r.indexOf(e);for(;s-- >=-1;){const i=r[s];if(i&&3===i.type)n.removeNode(i);else{if(!i||2!==i.type||i.content.trim().length){if(i&&9===i.type){n.removeNode();const r=Gc(e,t);i.branches.push(r);const s=o&&o(i,r,!1);$c(r,n),s&&s(),n.currentNode=null}break}n.removeNode(i)}}}}(e,t,n,((e,t,o)=>{const r=n.parent.children;let s=r.indexOf(e),i=0;for(;s-- >=0;){const e=r[s];e&&9===e.type&&(i+=e.branches.length)}return()=>{if(o)e.codegenNode=qc(t,i,n);else{const o=function(e){for(;;)if(19===e.type){if(19!==e.alternate.type)return e;e=e.alternate}else 20===e.type&&(e=e.value)}(e.codegenNode);o.alternate=qc(t,i+e.branches.length-1,n)}}}))));function Gc(e,t){const n=3===e.tagType;return{type:10,loc:e.loc,condition:"else"===t.name?void 0:t.exp,children:n&&!Vl(e,"for")?e.children:[e],userKey:Il(e,"key"),isTemplateIf:n}}function qc(e,t,n){return e.condition?Cl(e.condition,Jc(e,t,n),Sl(n.helper(Bi),['""',"true"])):Jc(e,t,n)}function Jc(e,t,n){const{helper:o}=n,r=yl("key",bl(`${t}`,!1,hl,2)),{children:s}=e,i=s[0];if(1!==s.length||1!==i.type){if(1===s.length&&11===i.type){const e=i.codegenNode;return Gl(e,r,n),e}{let t=64;return ml(n,o(Ei),vl([r]),s,t+"",void 0,void 0,!0,!1,!1,e.loc)}}{const e=i.codegenNode,t=14===(l=e).type&&l.callee===pl?l.arguments[1].returns:l;return 13===t.type&&Zl(t,n),Gl(t,r,n),e}var l}const Zc=Mc("for",((e,t,n)=>{const{helper:o,removeHelper:r}=n;return function(e,t,n,o){if(!t.exp)return;const r=ea(t.exp);if(!r)return;const{scopes:s}=n,{source:i,value:l,key:c,index:a}=r,u={type:11,loc:t.loc,source:i,valueAlias:l,keyAlias:c,objectIndexAlias:a,parseResult:r,children:Ul(e)?e.children:[e]};n.replaceNode(u),s.vFor++;const p=o&&o(u);return()=>{s.vFor--,p&&p()}}(e,t,n,(t=>{const s=Sl(o(Ki),[t.source]),i=Ul(e),l=Vl(e,"memo"),c=Il(e,"key"),a=c&&(6===c.type?bl(c.value.content,!0):c.exp),u=c?yl("key",a):null,p=4===t.source.type&&t.source.constType>0,f=p?64:c?128:256;return t.codegenNode=ml(n,o(Ei),void 0,s,f+"",void 0,void 0,!0,!p,!1,e.loc),()=>{let c;const{children:f}=t,d=1!==f.length||1!==f[0].type,h=Dl(e)?e:i&&1===e.children.length&&Dl(e.children[0])?e.children[0]:null;if(h?(c=h.codegenNode,i&&u&&Gl(c,u,n)):d?c=ml(n,o(Ei),u?vl([u]):void 0,e.children,"64",void 0,void 0,!0,void 0,!1):(c=f[0].codegenNode,i&&u&&Gl(c,u,n),c.isBlock!==!p&&(c.isBlock?(r(Ri),r(Wl(n.inSSR,c.isComponent))):r(Hl(n.inSSR,c.isComponent))),c.isBlock=!p,c.isBlock?(o(Ri),o(Wl(n.inSSR,c.isComponent))):o(Hl(n.inSSR,c.isComponent))),l){const e=xl(na(t.parseResult,[bl("_cached")]));e.body={type:21,body:[_l(["const _memo = (",l.exp,")"]),_l(["if (_cached",...a?[" && _cached.key === ",a]:[],` && ${n.helperString(fl)}(_cached, _memo)) return _cached`]),_l(["const _item = ",c]),bl("_item.memo = _memo"),bl("return _item")],loc:hl},s.arguments.push(e,bl("_cache"),bl(String(n.cached++)))}else s.arguments.push(xl(na(t.parseResult),c,!0))}}))}));const Yc=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,Qc=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,Xc=/^\(|\)$/g;function ea(e,t){const n=e.loc,o=e.content,r=o.match(Yc);if(!r)return;const[,s,i]=r,l={source:ta(n,i.trim(),o.indexOf(i,s.length)),value:void 0,key:void 0,index:void 0};let c=s.trim().replace(Xc,"").trim();const a=s.indexOf(c),u=c.match(Qc);if(u){c=c.replace(Qc,"").trim();const e=u[1].trim();let t;if(e&&(t=o.indexOf(e,a+c.length),l.key=ta(n,e,t)),u[2]){const r=u[2].trim();r&&(l.index=ta(n,r,o.indexOf(r,l.key?t+e.length:a+c.length)))}}return c&&(l.value=ta(n,c,a)),l}function ta(e,t,n){return bl(t,!1,Rl(e,n,t.length))}function na({value:e,key:t,index:n},o=[]){return function(e){let t=e.length;for(;t--&&!e[t];);return e.slice(0,t+1).map(((e,t)=>e||bl("_".repeat(t+1),!1)))}([e,t,n,...o])}const oa=bl("undefined",!1),ra=(e,t)=>{if(1===e.type&&(1===e.tagType||3===e.tagType)){const n=Vl(e,"slot");if(n)return t.scopes.vSlot++,()=>{t.scopes.vSlot--}}},sa=(e,t,n)=>xl(e,t,!1,!0,t.length?t[0].loc:n);function ia(e,t,n=sa){t.helper(cl);const{children:o,loc:r}=e,s=[],i=[];let l=t.scopes.vSlot>0||t.scopes.vFor>0;const c=Vl(e,"slot",!0);if(c){const{arg:e,exp:t}=c;e&&!kl(e)&&(l=!0),s.push(yl(e||bl("default",!0),n(t,o,r)))}let a=!1,u=!1;const p=[],f=new Set;let d=0;for(let g=0;gyl("default",n(e,t,r));a?p.length&&p.some((e=>aa(e)))&&(u||s.push(e(void 0,p))):s.push(e(void 0,o))}const h=l?2:ca(e.children)?3:1;let m=vl(s.concat(yl("_",bl(h+"",!1))),r);return i.length&&(m=Sl(t.helper(qi),[m,gl(i)])),{slots:m,hasDynamicSlots:l}}function la(e,t,n){const o=[yl("name",e),yl("fn",t)];return null!=n&&o.push(yl("key",bl(String(n),!0))),vl(o)}function ca(e){for(let t=0;tfunction(){if(1!==(e=t.currentNode).type||0!==e.tagType&&1!==e.tagType)return;const{tag:n,props:o}=e,r=1===e.tagType;let s=r?function(e,t,n=!1){let{tag:o}=e;const r=ma(o),s=Il(e,"is");if(s)if(r){const e=6===s.type?s.value&&bl(s.value.content,!0):s.exp;if(e)return Sl(t.helper(Di),[e])}else 6===s.type&&s.value.content.startsWith("vue:")&&(o=s.value.content.slice(4));const i=!r&&Vl(e,"is");if(i&&i.exp)return Sl(t.helper(Di),[i.exp]);const l=Tl(o)||t.isBuiltInComponent(o);if(l)return n||t.helper(l),l;return t.helper(Ui),t.components.add(o),Jl(o,"component")}(e,t):`"${n}"`;const i=M(s)&&s.callee===Di;let l,c,a,u,p,f,d=0,h=i||s===Oi||s===Ai||!r&&("svg"===n||"foreignObject"===n);if(o.length>0){const n=fa(e,t,void 0,r,i);l=n.props,d=n.patchFlag,p=n.dynamicPropNames;const o=n.directives;f=o&&o.length?gl(o.map((e=>function(e,t){const n=[],o=ua.get(e);o?n.push(t.helperString(o)):(t.helper(Hi),t.directives.add(e.name),n.push(Jl(e.name,"directive")));const{loc:r}=e;e.exp&&n.push(e.exp);e.arg&&(e.exp||n.push("void 0"),n.push(e.arg));if(Object.keys(e.modifiers).length){e.arg||(e.exp||n.push("void 0"),n.push("void 0"));const t=bl("true",!1,r);n.push(vl(e.modifiers.map((e=>yl(e,t))),r))}return gl(n,e.loc)}(e,t)))):void 0,n.shouldUseBlock&&(h=!0)}if(e.children.length>0){s===Fi&&(h=!0,d|=1024);if(r&&s!==Oi&&s!==Fi){const{slots:n,hasDynamicSlots:o}=ia(e,t);c=n,o&&(d|=1024)}else if(1===e.children.length&&s!==Oi){const n=e.children[0],o=n.type,r=5===o||8===o;r&&0===Tc(n,t)&&(d|=1),c=r||2===o?n:e.children}else c=e.children}0!==d&&(a=String(d),p&&p.length&&(u=function(e){let t="[";for(let n=0,o=e.length;n0;let d=!1,h=0,m=!1,g=!1,v=!1,y=!1,b=!1,_=!1;const S=[],C=e=>{a.length&&(u.push(vl(da(a),l)),a=[]),e&&u.push(e)},k=({key:e,value:n})=>{if(kl(e)){const s=e.content,i=x(s);if(!i||o&&!r||"onclick"===s.toLowerCase()||"onUpdate:modelValue"===s||U(s)||(y=!0),i&&U(s)&&(_=!0),20===n.type||(4===n.type||8===n.type)&&Tc(n,t)>0)return;"ref"===s?m=!0:"class"===s?g=!0:"style"===s?v=!0:"key"===s||S.includes(s)||S.push(s),!o||"class"!==s&&"style"!==s||S.includes(s)||S.push(s)}else b=!0};for(let x=0;x0&&a.push(yl(bl("ref_for",!0),bl("true")))),"is"===n&&(ma(i)||o&&o.content.startsWith("vue:")))continue;a.push(yl(bl(n,!0,Rl(e,0,n.length)),bl(o?o.content:"",s,o?o.loc:e)))}else{const{name:n,arg:c,exp:h,loc:m}=r,g="bind"===n,v="on"===n;if("slot"===n)continue;if("once"===n||"memo"===n)continue;if("is"===n||g&&Bl(c,"is")&&ma(i))continue;if(v&&s)continue;if((g&&Bl(c,"key")||v&&f&&Bl(c,"vue:before-update"))&&(d=!0),g&&Bl(c,"ref")&&t.scopes.vFor>0&&a.push(yl(bl("ref_for",!0),bl("true"))),!c&&(g||v)){b=!0,h&&(g?(C(),u.push(h)):C({type:14,loc:m,callee:t.helper(tl),arguments:o?[h]:[h,"true"]}));continue}const y=t.directiveTransforms[n];if(y){const{props:n,needRuntime:o}=y(r,e,t);!s&&n.forEach(k),v&&c&&!kl(c)?C(vl(n,l)):a.push(...n),o&&(p.push(r),$(o)&&ua.set(r,o))}else D(n)||(p.push(r),f&&(d=!0))}}let w;if(u.length?(C(),w=u.length>1?Sl(t.helper(Zi),u,l):u[0]):a.length&&(w=vl(da(a),l)),b?h|=16:(g&&!o&&(h|=2),v&&!o&&(h|=4),S.length&&(h|=8),y&&(h|=32)),d||0!==h&&32!==h||!(m||_||p.length>0)||(h|=512),!t.inSSR&&w)switch(w.type){case 15:let e=-1,n=-1,o=!1;for(let t=0;t{if(Dl(e)){const{children:n,loc:o}=e,{slotName:r,slotProps:s}=function(e,t){let n,o='"default"';const r=[];for(let s=0;s0){const{props:o,directives:s}=fa(e,t,r,!1,!1);n=o}return{slotName:o,slotProps:n}}(e,t),i=[t.prefixIdentifiers?"_ctx.$slots":"$slots",r,"{}","undefined","true"];let l=2;s&&(i[2]=s,l=3),n.length&&(i[3]=xl([],n,!1,!1,o),l=4),t.scopeId&&!t.slotted&&(l=5),i.splice(l),e.codegenNode=Sl(t.helper(Gi),i,o)}};const va=/^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/,ya=(e,t,n,o)=>{const{loc:r,modifiers:s,arg:i}=e;let l;if(4===i.type)if(i.isStatic){let e=i.content;e.startsWith("vue:")&&(e=`vnode-${e.slice(4)}`);l=bl(0!==t.tagType||e.startsWith("vnode")||!/[A-Z]/.test(e)?J(z(e)):`on:${e}`,!0,i.loc)}else l=_l([`${n.helperString(rl)}(`,i,")"]);else l=i,l.children.unshift(`${n.helperString(rl)}(`),l.children.push(")");let c=e.exp;c&&!c.content.trim()&&(c=void 0);let a=n.cacheHandlers&&!c&&!n.inVOnce;if(c){const e=Pl(c.content),t=!(e||va.test(c.content)),n=c.content.includes(";");(t||a&&e)&&(c=_l([`${t?"$event":"(...args)"} => ${n?"{":"("}`,c,n?"}":")"]))}let u={props:[yl(l,c||bl("() => {}",!1,r))]};return o&&(u=o(u)),a&&(u.props[0].value=n.cache(u.props[0].value)),u.props.forEach((e=>e.key.isHandlerKey=!0)),u},ba=(e,t,n)=>{const{exp:o,modifiers:r,loc:s}=e,i=e.arg;return 4!==i.type?(i.children.unshift("("),i.children.push(') || ""')):i.isStatic||(i.content=`${i.content} || ""`),r.includes("camel")&&(4===i.type?i.content=i.isStatic?z(i.content):`${n.helperString(nl)}(${i.content})`:(i.children.unshift(`${n.helperString(nl)}(`),i.children.push(")"))),n.inSSR||(r.includes("prop")&&_a(i,"."),r.includes("attr")&&_a(i,"^")),!o||4===o.type&&!o.content.trim()?{props:[yl(i,bl("",!0,s))]}:{props:[yl(i,o)]}},_a=(e,t)=>{4===e.type?e.content=e.isStatic?t+e.content:`\`${t}\${${e.content}}\``:(e.children.unshift(`'${t}' + (`),e.children.push(")"))},Sa=(e,t)=>{if(0===e.type||1===e.type||11===e.type||10===e.type)return()=>{const n=e.children;let o,r=!1;for(let e=0;e7===e.type&&!t.directiveTransforms[e.name])))))for(let e=0;e{if(1===e.type&&Vl(e,"once",!0)){if(xa.has(e)||t.inVOnce)return;return xa.add(e),t.inVOnce=!0,t.helper(sl),()=>{t.inVOnce=!1;const e=t.currentNode;e.codegenNode&&(e.codegenNode=t.cache(e.codegenNode,!0))}}},ka=(e,t,n)=>{const{exp:o,arg:r}=e;if(!o)return wa();const s=o.loc.source,i=4===o.type?o.content:s,l=n.bindingMetadata[s];if("props"===l||"props-aliased"===l)return wa();if(!i.trim()||!Pl(i))return wa();const c=r||bl("modelValue",!0),a=r?kl(r)?`onUpdate:${r.content}`:_l(['"onUpdate:" + ',r]):"onUpdate:modelValue";let u;u=_l([`${n.isTS?"($event: any)":"$event"} => ((`,o,") = $event)"]);const p=[yl(c,e.exp),yl(a,u)];if(e.modifiers.length&&1===t.tagType){const t=e.modifiers.map((e=>(El(e)?e:JSON.stringify(e))+": true")).join(", "),n=r?kl(r)?`${r.content}Modifiers`:_l([r,' + "Modifiers"']):"modelModifiers";p.push(yl(n,bl(`{ ${t} }`,!1,e.loc,2)))}return wa(p)};function wa(e=[]){return{props:e}}const Ta=new WeakSet,Na=(e,t)=>{if(1===e.type){const n=Vl(e,"memo");if(!n||Ta.has(e))return;return Ta.add(e),()=>{const o=e.codegenNode||t.currentNode.codegenNode;o&&13===o.type&&(1!==e.tagType&&Zl(o,t),e.codegenNode=Sl(t.helper(pl),[n.exp,xl(void 0,o),"_cache",String(t.cached++)]))}}};function Ea(e,t={}){const n=t.onError||wi,o="module"===t.mode;!0===t.prefixIdentifiers?n(Ni(47)):o&&n(Ni(48));t.cacheHandlers&&n(Ni(49)),t.scopeId&&!o&&n(Ni(50));const r=R(e)?ec(e,t):e,[s,i]=[[Ca,Kc,Na,Zc,ga,pa,ra,Sa],{on:ya,bind:ba,model:ka}];return Rc(r,k({},t,{prefixIdentifiers:false,nodeTransforms:[...s,...t.nodeTransforms||[]],directiveTransforms:k({},i,t.directiveTransforms||{})})),Bc(r,k({},t,{prefixIdentifiers:false}))}const Oa=Symbol(""),Aa=Symbol(""),Fa=Symbol(""),Pa=Symbol(""),Ra=Symbol(""),$a=Symbol(""),Ma=Symbol(""),Va=Symbol(""),Ia=Symbol(""),Ba=Symbol("");var La;let ja;La={[Oa]:"vModelRadio",[Aa]:"vModelCheckbox",[Fa]:"vModelText",[Pa]:"vModelSelect",[Ra]:"vModelDynamic",[$a]:"withModifiers",[Ma]:"withKeys",[Va]:"vShow",[Ia]:"Transition",[Ba]:"TransitionGroup"},Object.getOwnPropertySymbols(La).forEach((e=>{dl[e]=La[e]}));const Ua=t("style,iframe,script,noscript",!0),Da={isVoidTag:p,isNativeTag:e=>a(e)||u(e),isPreTag:e=>"pre"===e,decodeEntities:function(e,t=!1){return ja||(ja=document.createElement("div")),t?(ja.innerHTML=`
`,ja.children[0].getAttribute("foo")):(ja.innerHTML=e,ja.textContent)},isBuiltInComponent:e=>wl(e,"Transition")?Ia:wl(e,"TransitionGroup")?Ba:void 0,getNamespace(e,t){let n=t?t.ns:0;if(t&&2===n)if("annotation-xml"===t.tag){if("svg"===e)return 1;t.props.some((e=>6===e.type&&"encoding"===e.name&&null!=e.value&&("text/html"===e.value.content||"application/xhtml+xml"===e.value.content)))&&(n=0)}else/^m(?:[ions]|text)$/.test(t.tag)&&"mglyph"!==e&&"malignmark"!==e&&(n=0);else t&&1===n&&("foreignObject"!==t.tag&&"desc"!==t.tag&&"title"!==t.tag||(n=0));if(0===n){if("svg"===e)return 1;if("math"===e)return 2}return n},getTextMode({tag:e,ns:t}){if(0===t){if("textarea"===e||"title"===e)return 1;if(Ua(e))return 2}return 0}},Ha=(e,t)=>{const n=l(e);return bl(JSON.stringify(n),!1,t,3)};const Wa=t("passive,once,capture"),za=t("stop,prevent,self,ctrl,shift,alt,meta,exact,middle"),Ka=t("left,right"),Ga=t("onkeyup,onkeydown,onkeypress",!0),qa=(e,t)=>kl(e)&&"onclick"===e.content.toLowerCase()?bl(t,!0):4!==e.type?_l(["(",e,`) === "onClick" ? "${t}" : (`,e,")"]):e,Ja=(e,t)=>{1!==e.type||0!==e.tagType||"script"!==e.tag&&"style"!==e.tag||t.removeNode()},Za=[e=>{1===e.type&&e.props.forEach(((t,n)=>{6===t.type&&"style"===t.name&&t.value&&(e.props[n]={type:7,name:"bind",arg:bl("style",!0,t.loc),exp:Ha(t.value.content,t.loc),modifiers:[],loc:t.loc})}))}],Ya={cloak:()=>({props:[]}),html:(e,t,n)=>{const{exp:o,loc:r}=e;return t.children.length&&(t.children.length=0),{props:[yl(bl("innerHTML",!0,r),o||bl("",!0))]}},text:(e,t,n)=>{const{exp:o,loc:r}=e;return t.children.length&&(t.children.length=0),{props:[yl(bl("textContent",!0),o?Tc(o,n)>0?o:Sl(n.helperString(Ji),[o],r):bl("",!0))]}},model:(e,t,n)=>{const o=ka(e,t,n);if(!o.props.length||1===t.tagType)return o;const{tag:r}=t,s=n.isCustomElement(r);if("input"===r||"textarea"===r||"select"===r||s){let e=Fa,i=!1;if("input"===r||s){const n=Il(t,"type");if(n){if(7===n.type)e=Ra;else if(n.value)switch(n.value.content){case"radio":e=Oa;break;case"checkbox":e=Aa;break;case"file":i=!0}}else(function(e){return e.props.some((e=>!(7!==e.type||"bind"!==e.name||e.arg&&4===e.arg.type&&e.arg.isStatic)))})(t)&&(e=Ra)}else"select"===r&&(e=Pa);i||(o.needRuntime=n.helper(e))}return o.props=o.props.filter((e=>!(4===e.key.type&&"modelValue"===e.key.content))),o},on:(e,t,n)=>ya(e,t,n,(t=>{const{modifiers:o}=e;if(!o.length)return t;let{key:r,value:s}=t.props[0];const{keyModifiers:i,nonKeyModifiers:l,eventOptionModifiers:c}=((e,t,n,o)=>{const r=[],s=[],i=[];for(let l=0;l({props:[],needRuntime:n.helper(Va)})};const Qa=Object.create(null);function Xa(e,t){if(!R(e)){if(!e.nodeType)return b;e=e.innerHTML}const n=e,o=Qa[n];if(o)return o;if("#"===e[0]){const t=document.querySelector(e);e=t?t.innerHTML:""}const r=k({hoistStatic:!0,onError:void 0,onWarn:b},t);r.isCustomElement||"undefined"==typeof customElements||(r.isCustomElement=e=>!!customElements.get(e));const{code:s}=function(e,t={}){return Ea(e,k({},Da,t,{nodeTransforms:[Ja,...Za,...t.nodeTransforms||[]],directiveTransforms:k({},Ya,t.directiveTransforms||{}),transformHoist:null}))}(e,r),i=new Function(s)();return i._rc=!0,Qa[n]=i}return Qr(Xa),e.BaseTransition=Vn,e.Comment=gr,e.EffectScope=ne,e.Fragment=hr,e.KeepAlive=Gn,e.ReactiveEffect=de,e.Static=vr,e.Suspense=bn,e.Teleport=fr,e.Text=mr,e.Transition=As,e.TransitionGroup=qs,e.VueElement=ws,e.callWithAsyncErrorHandling=Bt,e.callWithErrorHandling=It,e.camelize=z,e.capitalize=q,e.cloneVNode=$r,e.compatUtils=null,e.compile=Xa,e.computed=os,e.createApp=(...e)=>{const t=bi().createApp(...e),{mount:n}=t;return t.mount=e=>{const o=Ci(e);if(!o)return;const r=t._component;P(r)||r.render||r.template||(r.template=o.innerHTML),o.innerHTML="";const s=n(o,!1,o instanceof SVGElement);return o instanceof Element&&(o.removeAttribute("v-cloak"),o.setAttribute("data-v-app","")),s},t},e.createBlock=wr,e.createCommentVNode=function(e="",t=!1){return t?(_r(),wr(gr,null,e)):Pr(gr,null,e)},e.createElementBlock=function(e,t,n,o,r,s){return kr(Fr(e,t,n,o,r,s,!0))},e.createElementVNode=Fr,e.createHydrationRenderer=rr,e.createPropsRestProxy=function(e,t){const n={};for(const o in e)t.includes(o)||Object.defineProperty(n,o,{enumerable:!0,get:()=>e[o]});return n},e.createRenderer=or,e.createSSRApp=(...e)=>{const t=_i().createApp(...e),{mount:n}=t;return t.mount=e=>{const t=Ci(e);if(t)return n(t,!0,t instanceof SVGElement)},t},e.createSlots=function(e,t){for(let n=0;n{const t=o.fn(...e);return t&&(t.key=o.key),t}:o.fn)}return e},e.createStaticVNode=function(e,t){const n=Pr(vr,null,e);return n.staticCount=t,n},e.createTextVNode=Mr,e.createVNode=Pr,e.customRef=function(e){return new Pt(e)},e.defineAsyncComponent=function(e){P(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:o,delay:r=200,timeout:s,suspensible:i=!0,onError:l}=e;let c,a=null,u=0;const p=()=>{let e;return a||(e=a=t().catch((e=>{if(e=e instanceof Error?e:new Error(String(e)),l)return new Promise(((t,n)=>{l(e,(()=>t((u++,a=null,p()))),(()=>n(e)),u+1)}));throw e})).then((t=>e!==a&&a?a:(t&&(t.__esModule||"Module"===t[Symbol.toStringTag])&&(t=t.default),c=t,t))))};return Hn({name:"AsyncComponentWrapper",__asyncLoader:p,get __asyncResolved(){return c},setup(){const e=Hr;if(c)return()=>zn(c,e);const t=t=>{a=null,Lt(t,e,13,!o)};if(i&&e.suspense)return p().then((t=>()=>zn(t,e))).catch((e=>(t(e),()=>o?Pr(o,{error:e}):null)));const l=Tt(!1),u=Tt(),f=Tt(!!r);return r&&setTimeout((()=>{f.value=!1}),r),null!=s&&setTimeout((()=>{if(!l.value&&!u.value){const e=new Error(`Async component timed out after ${s}ms.`);t(e),u.value=e}}),s),p().then((()=>{l.value=!0,e.parent&&Kn(e.parent.vnode)&&Zt(e.parent.update)})).catch((e=>{t(e),u.value=e})),()=>l.value&&c?zn(c,e):u.value&&o?Pr(o,{error:u.value}):n&&!f.value?Pr(n):void 0}})},e.defineComponent=Hn,e.defineCustomElement=Cs,e.defineEmits=function(){return null},e.defineExpose=function(e){},e.defineProps=function(){return null},e.defineSSRCustomElement=e=>Cs(e,xi),e.effect=function(e,t){e.effect&&(e=e.effect.fn);const n=new de(e);t&&(k(n,t),t.scope&&oe(n,t.scope)),t&&t.lazy||n.run();const o=n.run.bind(n);return o.effect=n,o},e.effectScope=function(e){return new ne(e)},e.getCurrentInstance=Wr,e.getCurrentScope=function(){return te},e.getTransitionRawChildren=Dn,e.guardReactiveProps=Rr,e.h=ss,e.handleError=Lt,e.hydrate=xi,e.initCustomFormatter=function(){},e.initDirectivesForSSR=ki,e.inject=Tn,e.isMemoSame=ls,e.isProxy=yt,e.isReactive=mt,e.isReadonly=gt,e.isRef=wt,e.isRuntimeOnly=()=>!qr,e.isShallow=vt,e.isVNode=Tr,e.markRaw=_t,e.mergeDefaults=function(e,t){const n=E(e)?e.reduce(((e,t)=>(e[t]={},e)),{}):e;for(const o in t){const e=n[o];e?E(e)||P(e)?n[o]={type:e,default:t[o]}:e.default=t[o]:null===e&&(n[o]={default:t[o]})}return n},e.mergeProps=Lr,e.nextTick=Jt,e.normalizeClass=c,e.normalizeProps=function(e){if(!e)return null;let{class:t,style:n}=e;return t&&!R(t)&&(e.class=c(t)),n&&(e.style=o(n)),e},e.normalizeStyle=o,e.onActivated=Jn,e.onBeforeMount=oo,e.onBeforeUnmount=lo,e.onBeforeUpdate=so,e.onDeactivated=Zn,e.onErrorCaptured=fo,e.onMounted=ro,e.onRenderTracked=po,e.onRenderTriggered=uo,e.onScopeDispose=function(e){te&&te.cleanups.push(e)},e.onServerPrefetch=ao,e.onUnmounted=co,e.onUpdated=io,e.openBlock=_r,e.popScopeId=function(){un=null},e.provide=wn,e.proxyRefs=Ft,e.pushScopeId=function(e){un=e},e.queuePostFlushCb=Qt,e.reactive=pt,e.readonly=dt,e.ref=Tt,e.registerRuntimeCompiler=Qr,e.render=Si,e.renderList=function(e,t,n,o){let r;const s=n&&n[o];if(E(e)||R(e)){r=new Array(e.length);for(let n=0,o=e.length;nt(e,n,void 0,s&&s[n])));else{const n=Object.keys(e);r=new Array(n.length);for(let o=0,i=n.length;oe.devtools.emit(t,...n))),rn=[];else if("undefined"!=typeof window&&window.HTMLElement&&!(null===(s=null===(r=window.navigator)||void 0===r?void 0:r.userAgent)||void 0===s?void 0:s.includes("jsdom"))){(o.__VUE_DEVTOOLS_HOOK_REPLAY__=o.__VUE_DEVTOOLS_HOOK_REPLAY__||[]).push((e=>{t(e,o)})),setTimeout((()=>{e.devtools||(o.__VUE_DEVTOOLS_HOOK_REPLAY__=null,rn=[])}),3e3)}else rn=[]},e.setTransitionHooks=Un,e.shallowReactive=ft,e.shallowReadonly=function(e){return ht(e,!0,Ie,st,at)},e.shallowRef=function(e){return Nt(e,!0)},e.ssrContextKey=is,e.ssrUtils=null,e.stop=function(e){e.effect.stop()},e.toDisplayString=e=>R(e)?e:null==e?"":E(e)||M(e)&&(e.toString===I||!P(e.toString))?JSON.stringify(e,g,2):String(e),e.toHandlerKey=J,e.toHandlers=function(e,t){const n={};for(const o in e)n[t&&/[A-Z]/.test(o)?`on:${o}`:J(o)]=e[o];return n},e.toRaw=bt,e.toRef=$t,e.toRefs=function(e){const t=E(e)?new Array(e.length):{};for(const n in e)t[n]=$t(e,n);return t},e.transformVNodeArgs=function(e){},e.triggerRef=function(e){kt(e)},e.unref=Ot,e.useAttrs=function(){return rs().attrs},e.useCssModule=function(e="$style"){return v},e.useCssVars=function(e){const t=Wr();if(!t)return;const n=t.ut=(n=e(t.proxy))=>{Array.from(document.querySelectorAll(`[data-v-owner="${t.uid}"]`)).forEach((e=>Ns(e,n)))},o=()=>{const o=e(t.proxy);Ts(t.subTree,o),n(o)};Nn(o),ro((()=>{const e=new MutationObserver(o);e.observe(t.subTree.el.parentNode,{childList:!0}),co((()=>e.disconnect()))}))},e.useSSRContext=()=>{},e.useSlots=function(){return rs().slots},e.useTransitionState=$n,e.vModelCheckbox=ni,e.vModelDynamic=ai,e.vModelRadio=ri,e.vModelSelect=si,e.vModelText=ti,e.vShow=hi,e.version=cs,e.warn=function(e,...t){},e.watch=On,e.watchEffect=function(e,t){return An(e,null,t)},e.watchPostEffect=Nn,e.watchSyncEffect=function(e,t){return An(e,null,{flush:"sync"})},e.withAsyncContext=function(e){const t=Wr();let n=e();return Kr(),V(n)&&(n=n.catch((e=>{throw zr(t),e}))),[n,()=>zr(t)]},e.withCtx=fn,e.withDefaults=function(e,t){return null},e.withDirectives=function(e,t){const n=an;if(null===n)return e;const o=ts(n)||n.proxy,r=e.dirs||(e.dirs=[]);for(let s=0;sn=>{if(!("key"in n))return;const o=G(n.key);return t.some((e=>e===o||di[e]===o))?e(n):void 0},e.withMemo=function(e,t,n,o){const r=n[o];if(r&&ls(r,e))return r;const s=t();return s.memo=e.slice(),n[o]=s},e.withModifiers=(e,t)=>(n,...o)=>{for(let e=0;efn,Object.defineProperty(e,"__esModule",{value:!0}),e}({}); diff --git a/app/preport/forms.py b/app/preport/forms.py index c3a0563..a22fde1 100644 --- a/app/preport/forms.py +++ b/app/preport/forms.py @@ -41,12 +41,9 @@ def label_from_instance(self, obj: Model) -> str: class NewReportForm(forms.ModelForm): product_placeholder = _('(Select a product)') - product = CustomModelChoiceField(queryset=DB_Product.objects.all(), empty_label=product_placeholder, widget=forms.Select(attrs={'class': 'form-control'})) - audit = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'class': 'form-control float-right', 'data-toggle': 'datetimepicker', 'data-target': '#audit', 'data-date-format': 'YYYY-MM-DD', 'id': "audit"})) - class Meta: today = datetime.date.today().strftime('%Y-%m-%d') nowformat = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') @@ -60,7 +57,6 @@ class Meta: } - class CWEModelChoiceField(ModelChoiceField): def label_from_instance(self, obj): return "%s - %s" % (obj.cwe_id, obj.cwe_name) @@ -94,15 +90,15 @@ class NewFindingForm(forms.ModelForm): class Meta: model = DB_Finding - fields = ('title', 'status', 'severity', 'cvss_score', 'cvss_base_score', 'description', 'location', 'poc', 'impact', 'recommendation', 'references', 'cwe', 'owasp') + fields = ('title', 'status', 'severity', 'cvss_score', 'cvss_vector', 'description', 'location', 'poc', 'impact', 'recommendation', 'references', 'cwe', 'owasp') widgets = { 'title': TextInput(attrs={'class': 'form-control', 'type': "text", 'required': "required", 'placeholder': _("Finding title")}), - 'cvss_base_score': TextInput(attrs={'class': 'form-control', 'type': "text", 'required': "required", 'placeholder': _("CVSS Base Score")}), + 'cvss_vector': TextInput(attrs={'class': 'form-control', 'type': "text", 'required': "required", 'placeholder': _("CVSS Vector")}), + 'cvss_score': TextInput(attrs={'class': 'form-control', 'type': "text", 'required': "required", 'placeholder': _("CVSS Score"),}), } - class NewFindingTemplateForm(forms.ModelForm): severity_choices = ( @@ -115,8 +111,6 @@ class NewFindingTemplateForm(forms.ModelForm): ('None', _('None')), ) - - severity = forms.ChoiceField(choices=severity_choices, required=True, widget=forms.Select(attrs={'class': 'form-control', 'type': "text", 'required': "required", 'placeholder': _("Critical/High/Medium/Low/Info/None")})) cwe = CWEModelChoiceField(queryset=DB_CWE.objects.all(), empty_label=_("(Select a CWE)"), widget=forms.Select(attrs={'class': 'form-control select2CWE'})) @@ -124,16 +118,15 @@ class NewFindingTemplateForm(forms.ModelForm): class Meta: model = DB_Finding_Template - fields = ('title', 'severity', 'cvss_score', 'cvss_base_score', 'description', 'location', 'impact', 'recommendation', 'references', 'cwe', 'owasp') + fields = ('title', 'severity', 'cvss_score', 'cvss_vector', 'description', 'location', 'impact', 'recommendation', 'references', 'cwe', 'owasp') widgets = { 'title': TextInput(attrs={'class': 'form-control', 'type': "text", 'required': "required", 'placeholder': _("Finding title")}), - 'cvss_base_score': TextInput(attrs={'class': 'form-control', 'type': "text", 'required': "required", 'placeholder': _("CVSS Base Score")}), - } + 'cvss_vector': TextInput(attrs={'class': 'form-control', 'type': "text", 'required': "required", 'placeholder': _("CVSS Vector")}), + 'cvss_score': TextInput(attrs={'class': 'form-control', 'type': "text", 'required': "required", 'placeholder': _("CVSS Score"),}), + } - - class FindingModelChoiceField(ModelChoiceField): def label_from_instance(self, obj): return f"({obj.report.title}) - {obj.title}" @@ -158,8 +151,6 @@ class Meta: } - - class AddUserForm(UserCreationForm): group = ModelChoiceField(queryset=Group.objects.all(), empty_label=_("(Select a group)"), widget=forms.Select(attrs={'class': 'form-control'})) @@ -184,7 +175,6 @@ def __init__(self, *args, **kwargs): self.fields['password2'].widget.attrs.update({'class': 'form-control', 'placeholder': 'Secret P@ssW0rd'}) - class NewAttackTreeForm(forms.ModelForm): def __init__(self, *args, **kwargs): @@ -257,7 +247,6 @@ class Meta: } - class NewCustomerForm(forms.ModelForm): class Meta: diff --git a/app/preport/migrations/0006_rename_cvss_base_score_db_finding_cvss_vector_and_more.py b/app/preport/migrations/0006_rename_cvss_base_score_db_finding_cvss_vector_and_more.py new file mode 100644 index 0000000..f61617e --- /dev/null +++ b/app/preport/migrations/0006_rename_cvss_base_score_db_finding_cvss_vector_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.5 on 2023-12-11 09:04 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('preport', '0005_db_customer_db_owasp_db_settings_db_shareconnection_and_more'), + ] + + operations = [ + migrations.RenameField( + model_name='db_finding', + old_name='cvss_base_score', + new_name='cvss_vector', + ), + migrations.RenameField( + model_name='db_finding_template', + old_name='cvss_base_score', + new_name='cvss_vector', + ), + ] diff --git a/app/preport/models.py b/app/preport/models.py index ead67fc..ebefa4f 100644 --- a/app/preport/models.py +++ b/app/preport/models.py @@ -133,7 +133,7 @@ class DB_Finding(models.Model): closed_at = models.DateTimeField(blank=True, null=True) title = models.CharField(blank=True, max_length=200) severity = models.CharField(blank=True, max_length=200) - cvss_base_score = models.CharField(blank=True, max_length=200) + cvss_vector = models.CharField(blank=True, max_length=200) cvss_score = models.DecimalField(max_digits=3, decimal_places=1, default=0) description = MartorField(blank=True) location = MartorField(blank=True) @@ -155,7 +155,7 @@ def save(self, *args, **kwargs): super().save(*args, **kwargs) def get_cvss_score_anchor(self): - m = cvss_regex.search(self.cvss_base_score) + m = cvss_regex.search(self.cvss_vector) if m: return m.group(1) class Meta: @@ -168,7 +168,7 @@ class DB_Finding_Template(models.Model): finding_id = models.CharField(blank=False, max_length=200) title = models.CharField(blank=False, max_length=200) severity = models.CharField(blank=True, max_length=200) - cvss_base_score = models.CharField(blank=True, max_length=200) + cvss_vector = models.CharField(blank=True, max_length=200) cvss_score = models.DecimalField(max_digits=3, decimal_places=1, default=0) description = MartorField(blank=True) location = MartorField(blank=True) @@ -183,7 +183,7 @@ def get_label (self): return self.title def get_cvss_score_anchor(self): - m = cvss_regex.search(self.cvss_base_score) + m = cvss_regex.search(self.cvss_vector) if m: return m.group(1) diff --git a/app/preport/templates/findings/finding_add.html b/app/preport/templates/findings/finding_add.html index da4c10f..5699ffc 100644 --- a/app/preport/templates/findings/finding_add.html +++ b/app/preport/templates/findings/finding_add.html @@ -6,11 +6,12 @@ {% block stylesheets %} {{ block.super }} + + {% endblock stylesheets %} {% block content %} -
@@ -61,216 +62,175 @@

{% translate "Finding" %}

-
- -
- {{ form.severity }} -
-
- -
- -
- {{ form.cvss_base_score }} -
- - - -
- - - - -
- - - - - -
- Base Score -
- -
-

Attack Vector (AV)

- - - - -
- -
-

Attack Complexity (AC)

- - -
- -
-

Privileges Required (PR)

- - - -
- -
-

User Interaction (UI)

- - -
+{% verbatim %} +
+
+ {% endverbatim %} + +
+ {{ form.severity }} +
+ {% verbatim %}
+
+ {% endverbatim %} + +
+ {{ form.cvss_vector }} +
+ + {% verbatim %} +
-
- -
-

Scope (S)

- - -
- -
-

Confidentiality (C)

- - - -
- -
-

Integrity (I)

- - - -
-
-

Availability (A)

- - - +
+ {% endverbatim %} + +
+ {{ form.cvss_score }}
- + {% verbatim %}
+ + +

{{ vector }} {{ score }} {{ qualScore }} {{ macroVector }}

+ +
+ {% endverbatim %} + + {% verbatim %} + +
+
+
+

+ {{ metricType }} + +

-
-

Select values for all base metrics to generate score

- - -
-
-
+ +
+
{{ metricGroup }}
+
+ +
+ + +
+
{{ metric }}:
+
{{metric}}:
+ +
+
+ + {{ option }} + {{ option }} + +
+
+
-
+
+
{{ metric }}:
+
{{metric}}:
+ +
+
+ + {{ option }} + {{ option }} + +
+
+
+
+
{{ metric }}:
+
{{metric}}:
+ +
+
+ + {{ option }} + {{ option }} + +
+
+
+
+
{{ metric }}:
+
{{metric}}:
+ +
+
+ + {{ option }} + {{ option }} + +
+
+
+
+
{{ metric }}:
+
{{metric}}:
+ +
+
+ + {{ option }} + {{ option }} + +
+
+
- +
-
+
+
+
+
+ + +{% endverbatim %} -
-
- {{ form.cvss_score.as_hidden }} -
-
@@ -368,257 +328,6 @@
Error
{% block javascripts %} {{ block.super}} - - - - - - + + + + + + + + + + {% endblock javascripts %} diff --git a/app/preport/templates/findings/finding_view.html b/app/preport/templates/findings/finding_view.html index 07fd285..a7ace80 100644 --- a/app/preport/templates/findings/finding_view.html +++ b/app/preport/templates/findings/finding_view.html @@ -79,11 +79,33 @@

{% translate "Finding ID" %} - {{ finding.finding_id | safe_markdown | bleach}} + {{ finding.finding_id | safe | bleach}}

+
+
+ {% translate "Status" %} + {{ finding.status | safe | bleach}} +
+
+
+ +
+
+
+ {% translate "Date" %} + {{ finding.creation_date | date:"d-m-Y H:m:s" | safe | bleach}} +
+
+
+ + + +
+ +
{% translate "Product" %} @@ -91,16 +113,15 @@

-
+
{% translate "Report" %} {{ DB_report.title | safe_markdown | bleach}} -
+
-
- +
@@ -116,37 +137,34 @@

- {% translate "CVSS Score" %} - {{ finding.cvss_base_score | safe | bleach}} - -
+ {% translate "OWASP" %} + {{ finding.owasp.owasp_id | safe | bleach}} - {{finding.owasp.owasp_name |safe| bleach}} +

-
- -
+
- {% translate "OWASP" %} - {{ finding.owasp.owasp_id | safe | bleach}} - {{finding.owasp.owasp_name |safe| bleach}} -
+ {% translate "CVSS Vector" %} + {{ finding.cvss_vector | safe | bleach}} +
-
+
- {% translate "Status" %} - {{ finding.status | safe | bleach}} + {% translate "CVSS Score" %} + {{ finding.cvss_score | safe | bleach}}
-
+
{% translate "Severity" %} @@ -162,7 +180,7 @@

{% elif finding.severity == "Info" %} {{finding.severity| safe | bleach}} {% else %} - {{finding.severity}} ({% translate "will not appear in the report" %}) + {{ finding.cvss_score | safe | bleach}} - {{finding.severity | safe | bleach}} ({% translate "will not appear in the report" %}) {% endif %}

diff --git a/app/preport/templates/findings/template_add.html b/app/preport/templates/findings/template_add.html index 0926c36..b63862f 100644 --- a/app/preport/templates/findings/template_add.html +++ b/app/preport/templates/findings/template_add.html @@ -7,6 +7,8 @@ {% block stylesheets %} {{ block.super }} + + {% endblock stylesheets %} {% block content %} @@ -53,216 +55,181 @@

{% translate "Finding Template" %}

-
- -
- {{ form.severity }} -
-
- -
- -
- {{ form.cvss_base_score }} -
- - - -
- - - - -
- - - - -
- Base Score -
-
-

Attack Vector (AV)

- - - - -
- -
-

Attack Complexity (AC)

- - -
- -
-

Privileges Required (PR)

- - - -
+{% verbatim %} +
-
-

User Interaction (UI)

- - -
+
+ {% endverbatim %} + +
+ {{ form.severity }} +
+ {% verbatim %}
+
+ {% endverbatim %} + +
+ {{ form.cvss_vector }} +
+ + {% verbatim %} +
-
-
-

Scope (S)

- - +
+ {% endverbatim %} + +
+ {{ form.cvss_score }}
+ {% verbatim %} +
-
-

Confidentiality (C)

- - - -
+ + +

{{ vector }} {{ score }} {{ qualScore }} {{ macroVector }}

+ +
+ {% endverbatim %} + + {% verbatim %} + +
+
+
+

+ {{ metricType }} + +

-
-

Integrity (I)

- - - -
+ +
+
{{ metricGroup }}
+
+ +
+ + +
+
{{ metric }}:
+
{{metric}}:
+ +
+
+ + {{ option }} + {{ option }} + +
+
+
-
-

Availability (A)

- - - -
+
+
{{ metric }}:
+
{{metric}}:
+ +
+
+ + {{ option }} + {{ option }} + +
+
+
-
+
+
{{ metric }}:
+
{{metric}}:
+ +
+
+ + {{ option }} + {{ option }} + +
+
+
+
+
{{ metric }}:
+
{{metric}}:
+ +
+
+ + {{ option }} + {{ option }} + +
+
+
-
-

Select values for all base metrics to generate score

- - -
-
-
+
+
{{ metric }}:
+
{{metric}}:
+ +
+
+ + {{ option }} + {{ option }} + +
+
+
-
+
+
+
+
+ + + - +{% endverbatim %}
- -
-
- {{ form.cvss_score.as_hidden }} -
-
-
@@ -355,264 +322,21 @@
Error
{% block javascripts %} {{ block.super}} - - - - - - - - -{% endblock javascripts %} + + + + + + + + + +{% endblock javascripts %} \ No newline at end of file diff --git a/app/preport/templates/findings/template_list.html b/app/preport/templates/findings/template_list.html index bbfd7d9..18cc5c0 100644 --- a/app/preport/templates/findings/template_list.html +++ b/app/preport/templates/findings/template_list.html @@ -46,9 +46,9 @@

{{ DB_findings_query.count }} {% translate "Templates" %} - - - + + + @@ -79,7 +79,7 @@

{{ DB_findings_query.count }} {% translate "Templates" %}

+ + + + + + + + + + {% if finding.description %} diff --git a/app/preport/templates/tpl/html/html_finding.md b/app/preport/templates/tpl/html/html_finding.md deleted file mode 100644 index bf0c2c6..0000000 --- a/app/preport/templates/tpl/html/html_finding.md +++ /dev/null @@ -1,74 +0,0 @@ -{% load martortags %} -{% load bleach_tags %} -{% load i18n %} -## {{finding.title | safe | bleach}} - -
{% translate "Finding title" %}{% translate "Severity" %}{% translate "CVSS Score" %}{% translate "Finding title" %}{% translate "Severity" %}{% translate "CVSS Score" %} {% translate "CWE" %} {% translate "OWASP" %} {% translate "Actions" %} - {{template.cvss_base_score}} + {{template.cvss_score}} diff --git a/app/preport/templates/findings/template_view.html b/app/preport/templates/findings/template_view.html index 93f8038..0889013 100644 --- a/app/preport/templates/findings/template_view.html +++ b/app/preport/templates/findings/template_view.html @@ -68,9 +68,9 @@

- {% translate "CVSS Score" %} - {{ DB_Template.cvss_base_score }} -
+ {% translate "Title" %} + {{ DB_Template.title | safe | bleach}} +
@@ -80,24 +80,41 @@

- -
+
+
+
+ {% translate "CVSS Vector" %} + {{ DB_Template.cvss_vector | safe | bleach}} +
+
+
+ +
+
+
+ {% translate "CVSS Score" %} + {{ DB_Template.cvss_score | safe | bleach}} +
+
+
+ +
{% translate "Severity" %} {% if DB_Template.severity == "Critical" %} - {{DB_Template.severity}} + {{DB_Template.severity| safe | bleach}} {% elif DB_Template.severity == "High" %} - {{DB_Template.severity}} + {{DB_Template.severity| safe | bleach}} {% elif DB_Template.severity == "Medium" %} - {{DB_Template.severity}} + {{DB_Template.severity| safe | bleach}} {% elif DB_Template.severity == "Low" %} - {{DB_Template.severity}} + {{DB_Template.severity| safe | bleach}} {% elif DB_Template.severity == "Info" %} - {{DB_Template.severity}} + {{DB_Template.severity| safe | bleach}} {% else %} - {{DB_Template.severity}} + {{ DB_Template.cvss_score | safe | bleach}} - {{DB_Template.severity | safe | bleach}} ({% translate "will not appear in the report" %}) {% endif %}
@@ -105,26 +122,35 @@

+
+ + -
+
+
{% translate "CWE" %} - {{ DB_Template.cwe.cwe_id }} - {{DB_Template.cwe.cwe_name }} + {{ DB_Template.cwe.cwe_id | safe | bleach}} - {{DB_Template.cwe.cwe_name |safe| bleach}}
+
+
+ +
+
{% translate "OWASP" %} - {{ DB_Template.owasp.owasp_id }} - {{DB_Template.owasp.owasp_name }} + {{ DB_Template.owasp.owasp_id | safe | bleach}} - {{DB_Template.owasp.owasp_name |safe| bleach}}
-
+
-
+
diff --git a/app/preport/templates/findings/templateaddfinding.html b/app/preport/templates/findings/templateaddfinding.html index 7b35af9..b0ec88b 100644 --- a/app/preport/templates/findings/templateaddfinding.html +++ b/app/preport/templates/findings/templateaddfinding.html @@ -85,7 +85,7 @@

{% translate "Templates" %}

- {{template.cvss_base_score}} + {{template.cvss_vector}} diff --git a/app/preport/templates/findings/uploadfindings.html b/app/preport/templates/findings/uploadfindings.html index 5273fa5..2e90f2d 100644 --- a/app/preport/templates/findings/uploadfindings.html +++ b/app/preport/templates/findings/uploadfindings.html @@ -61,7 +61,7 @@

{% translate "Findings CSV Document" %}

 // {% translate "Comma-separated values (CSV) file format" %}
                         
-"ID","Status","Title","Severity","CVSS Base Score","CVSS Score","CWE","Description","Location","Impact","Recommendation","References","Appendix","Appendix Description"
+"ID", "Status", "Title", "Severity", "CVSS Vector", "CVSS Score", "CWE", "CWE ID", "OWASP", "OWASP ID", "Description", "POC", "Location", "Impact", "Recommendation", "References", "Appendix", "Appendix Description"
 
 "2834q345-b24e-4ghf-r86d-ftue38af5480","Open","Finding 1","Low","3.7 (CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N)","3.7","73","Description","127.0.0.1","Impact","Recommendation","References","Appendix","Appendix Description"
 
diff --git a/app/preport/templates/home/footer.html b/app/preport/templates/home/footer.html index 570e626..6cf9974 100644 --- a/app/preport/templates/home/footer.html +++ b/app/preport/templates/home/footer.html @@ -1,7 +1,7 @@ {% load i18n%}
- Version 1.4.1 + Version 1.4.2
BSD 3-Clause Copyright © {% now "Y" %} PeTeReport {% translate "All rights reserved." %}
diff --git a/app/preport/templates/home/template.html b/app/preport/templates/home/template.html index 67ca2a5..8676fa9 100644 --- a/app/preport/templates/home/template.html +++ b/app/preport/templates/home/template.html @@ -121,18 +121,12 @@ - - - + + diff --git a/app/preport/templates/tpl/eisvogel.latex b/app/preport/templates/tpl/eisvogel.latex deleted file mode 100644 index 525b192..0000000 --- a/app/preport/templates/tpl/eisvogel.latex +++ /dev/null @@ -1,1034 +0,0 @@ -%% -% Copyright (c) 2017 - 2020, Pascal Wagler; -% Copyright (c) 2014 - 2020, John MacFarlane -% -% All rights reserved. -% -% Redistribution and use in source and binary forms, with or without -% modification, are permitted provided that the following conditions -% are met: -% -% - Redistributions of source code must retain the above copyright -% notice, this list of conditions and the following disclaimer. -% -% - Redistributions in binary form must reproduce the above copyright -% notice, this list of conditions and the following disclaimer in the -% documentation and/or other materials provided with the distribution. -% -% - Neither the name of John MacFarlane nor the names of other -% contributors may be used to endorse or promote products derived -% from this software without specific prior written permission. -% -% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -% FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -% COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -% INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -% ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -% POSSIBILITY OF SUCH DAMAGE. -%% - -%% -% This is the Eisvogel pandoc LaTeX template. -% -% For usage information and examples visit the official GitHub page: -% https://github.com/Wandmalfarbe/pandoc-latex-template -%% - -% Options for packages loaded elsewhere -\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref} -\PassOptionsToPackage{hyphens}{url} -\PassOptionsToPackage{dvipsnames,svgnames*,x11names*,table}{xcolor} -$if(dir)$ -$if(latex-dir-rtl)$ -\PassOptionsToPackage{RTLdocument}{bidi} -$endif$ -$endif$ -% -\documentclass[ -$if(fontsize)$ - $fontsize$, -$endif$ -$if(lang)$ - $babel-lang$, -$endif$ -$if(papersize)$ - $papersize$paper, -$else$ - paper=a4, -$endif$ -$if(beamer)$ - ignorenonframetext, -$if(handout)$ - handout, -$endif$ -$if(aspectratio)$ - aspectratio=$aspectratio$, -$endif$ -$endif$ -$for(classoption)$ - $classoption$$sep$, -$endfor$ -,captions=tableheading -]{$if(beamer)$$documentclass$$else$$if(book)$scrbook$else$scrartcl$endif$$endif$} -$if(beamer)$ -$if(background-image)$ -\usebackgroundtemplate{% - \includegraphics[width=\paperwidth]{$background-image$}% -} -$endif$ -\usepackage{pgfpages} -\setbeamertemplate{caption}[numbered] -\setbeamertemplate{caption label separator}{: } -\setbeamercolor{caption name}{fg=normal text.fg} -\beamertemplatenavigationsymbols$if(navigation)$$navigation$$else$empty$endif$ -$for(beameroption)$ -\setbeameroption{$beameroption$} -$endfor$ -% Prevent slide breaks in the middle of a paragraph -\widowpenalties 1 10000 -\raggedbottom -$if(section-titles)$ -\setbeamertemplate{part page}{ - \centering - \begin{beamercolorbox}[sep=16pt,center]{part title} - \usebeamerfont{part title}\insertpart\par - \end{beamercolorbox} -} -\setbeamertemplate{section page}{ - \centering - \begin{beamercolorbox}[sep=12pt,center]{part title} - \usebeamerfont{section title}\insertsection\par - \end{beamercolorbox} -} -\setbeamertemplate{subsection page}{ - \centering - \begin{beamercolorbox}[sep=8pt,center]{part title} - \usebeamerfont{subsection title}\insertsubsection\par - \end{beamercolorbox} -} -\AtBeginPart{ - \frame{\partpage} -} -\AtBeginSection{ - \ifbibliography - \else - \frame{\sectionpage} - \fi -} -\AtBeginSubsection{ - \frame{\subsectionpage} -} -$endif$ -$endif$ -$if(beamerarticle)$ -\usepackage{beamerarticle} % needs to be loaded first -$endif$ -$if(fontfamily)$ -\usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$} -$else$ -\usepackage{lmodern} -$endif$ -$if(linestretch)$ -\usepackage{setspace} -\setstretch{$linestretch$} -$else$ -\usepackage{setspace} -\setstretch{1.2} -$endif$ -\usepackage{amssymb,amsmath} -\usepackage{ifxetex,ifluatex} -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc} - \usepackage[utf8]{inputenc} - \usepackage{textcomp} % provide euro and other symbols -\else % if luatex or xetex -$if(mathspec)$ - \ifxetex - \usepackage{mathspec} - \else - \usepackage{unicode-math} - \fi -$else$ - \usepackage{unicode-math} -$endif$ - \defaultfontfeatures{Scale=MatchLowercase} - \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} -$if(mainfont)$ - \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$} -$endif$ -$if(sansfont)$ - \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$} -$endif$ -$if(monofont)$ - \setmonofont[$for(monofontoptions)$$monofontoptions$$sep$,$endfor$]{$monofont$} -$endif$ -$for(fontfamilies)$ - \newfontfamily{$fontfamilies.name$}[$for(fontfamilies.options)$$fontfamilies.options$$sep$,$endfor$]{$fontfamilies.font$} -$endfor$ -$if(mathfont)$ -$if(mathspec)$ - \ifxetex - \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} - \else - \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} - \fi -$else$ - \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} -$endif$ -$endif$ -$if(CJKmainfont)$ - \ifxetex - \usepackage{xeCJK} - \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} - \fi -$endif$ -$if(luatexjapresetoptions)$ - \ifluatex - \usepackage[$for(luatexjapresetoptions)$$luatexjapresetoptions$$sep$,$endfor$]{luatexja-preset} - \fi -$endif$ -$if(CJKmainfont)$ - \ifluatex - \usepackage[$for(luatexjafontspecoptions)$$luatexjafontspecoptions$$sep$,$endfor$]{luatexja-fontspec} - \setmainjfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} - \fi -$endif$ -\fi -$if(beamer)$ -$if(theme)$ -\usetheme[$for(themeoptions)$$themeoptions$$sep$,$endfor$]{$theme$} -$endif$ -$if(colortheme)$ -\usecolortheme{$colortheme$} -$endif$ -$if(fonttheme)$ -\usefonttheme{$fonttheme$} -$endif$ -$if(mainfont)$ -\usefonttheme{serif} % use mainfont rather than sansfont for slide text -$endif$ -$if(innertheme)$ -\useinnertheme{$innertheme$} -$endif$ -$if(outertheme)$ -\useoutertheme{$outertheme$} -$endif$ -$endif$ -% Use upquote if available, for straight quotes in verbatim environments -\IfFileExists{upquote.sty}{\usepackage{upquote}}{} -\IfFileExists{microtype.sty}{% use microtype if available - \usepackage[$for(microtypeoptions)$$microtypeoptions$$sep$,$endfor$]{microtype} - \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts -}{} -$if(indent)$ -$else$ -\makeatletter -\@ifundefined{KOMAClassName}{% if non-KOMA class - \IfFileExists{parskip.sty}{% - \usepackage{parskip} - }{% else - \setlength{\parindent}{0pt} - \setlength{\parskip}{6pt plus 2pt minus 1pt}} -}{% if KOMA class - \KOMAoptions{parskip=half}} -\makeatother -$endif$ -$if(verbatim-in-note)$ -\usepackage{fancyvrb} -$endif$ -\usepackage{xcolor} -\definecolor{default-linkcolor}{HTML}{A50000} -\definecolor{default-filecolor}{HTML}{A50000} -\definecolor{default-citecolor}{HTML}{4077C0} -\definecolor{default-urlcolor}{HTML}{4077C0} -\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available -$if(footnotes-pretty)$ -% load footmisc in order to customize footnotes (footmisc has to be loaded before hyperref, cf. https://tex.stackexchange.com/a/169124/144087) -\usepackage[hang,flushmargin,bottom,multiple]{footmisc} -\setlength{\footnotemargin}{0.8em} % set space between footnote nr and text -\setlength{\footnotesep}{\baselineskip} % set space between multiple footnotes -\setlength{\skip\footins}{0.3cm} % set space between page content and footnote -\setlength{\footskip}{0.9cm} % set space between footnote and page bottom -$endif$ -\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} -\hypersetup{ -$if(title-meta)$ - pdftitle={$title-meta$}, -$endif$ -$if(author-meta)$ - pdfauthor={$author-meta$}, -$endif$ -$if(lang)$ - pdflang={$lang$}, -$endif$ -$if(subject)$ - pdfsubject={$subject$}, -$endif$ -$if(keywords)$ - pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$}, -$endif$ -$if(colorlinks)$ - colorlinks=true, - linkcolor=$if(linkcolor)$$linkcolor$$else$default-linkcolor$endif$, - filecolor=$if(filecolor)$$filecolor$$else$default-filecolor$endif$, - citecolor=$if(citecolor)$$citecolor$$else$default-citecolor$endif$, - urlcolor=$if(urlcolor)$$urlcolor$$else$default-urlcolor$endif$, -$else$ - hidelinks, -$endif$ - breaklinks=true, - pdfcreator={LaTeX via pandoc with the Eisvogel template}} -\urlstyle{same} % disable monospaced font for URLs -$if(verbatim-in-note)$ -\VerbatimFootnotes % allow verbatim text in footnotes -$endif$ -$if(geometry)$ -$if(beamer)$ -\geometry{$for(geometry)$$geometry$$sep$,$endfor$} -$else$ -\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} -$endif$ -$else$ -$if(beamer)$ -$else$ -\usepackage[margin=2.5cm,includehead=true,includefoot=true,centering,$for(geometry)$$geometry$$sep$,$endfor$]{geometry} -$endif$ -$endif$ -$if(logo)$ -\usepackage[export]{adjustbox} -\usepackage{graphicx} -$endif$ -$if(beamer)$ -\newif\ifbibliography -$endif$ -$if(listings)$ -\usepackage{listings} -\newcommand{\passthrough}[1]{#1} -\lstset{defaultdialect=[5.3]Lua} -\lstset{defaultdialect=[x86masm]Assembler} -$endif$ -$if(listings-no-page-break)$ -\usepackage{etoolbox} -\BeforeBeginEnvironment{lstlisting}{\par\noindent\begin{minipage}{\linewidth}} -\AfterEndEnvironment{lstlisting}{\end{minipage}\par\addvspace{\topskip}} -$endif$ -$if(lhs)$ -\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} -$endif$ -$if(highlighting-macros)$ -$highlighting-macros$ - -% Workaround/bugfix from jannick0. -% See https://github.com/jgm/pandoc/issues/4302#issuecomment-360669013) -% or https://github.com/Wandmalfarbe/pandoc-latex-template/issues/2 -% -% Redefine the verbatim environment 'Highlighting' to break long lines (with -% the help of fvextra). Redefinition is necessary because it is unlikely that -% pandoc includes fvextra in the default template. -\usepackage{fvextra} -\DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines,fontsize=$if(code-block-font-size)$$code-block-font-size$$else$\small$endif$,commandchars=\\\{\}} - -$endif$ -$if(tables)$ -\usepackage{longtable,booktabs} -$if(beamer)$ -\usepackage{caption} -% Make caption package work with longtable -\makeatletter -\def\fnum@table{\tablename~\thetable} -\makeatother -$else$ -% Correct order of tables after \paragraph or \subparagraph -\usepackage{etoolbox} -\makeatletter -\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} -\makeatother -% Allow footnotes in longtable head/foot -\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} -\makesavenoteenv{longtable} -$endif$ -$endif$ -% add backlinks to footnote references, cf. https://tex.stackexchange.com/questions/302266/make-footnote-clickable-both-ways -$if(footnotes-disable-backlinks)$ -$else$ -\usepackage{footnotebackref} -$endif$ -$if(graphics)$ -\usepackage{graphicx} -\makeatletter -\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} -\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} -\makeatother -% Scale images if necessary, so that they will not overflow the page -% margins by default, and it is still possible to overwrite the defaults -% using explicit options in \includegraphics[width, height, ...]{} -\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} -$endif$ -$if(links-as-notes)$ -% Make links footnotes instead of hotlinks: -\DeclareRobustCommand{\href}[2]{#2\footnote{\url{#1}}} -$endif$ -$if(strikeout)$ -\usepackage[normalem]{ulem} -% Avoid problems with \sout in headers with hyperref -\pdfstringdefDisableCommands{\renewcommand{\sout}{}} -$endif$ -\setlength{\emergencystretch}{3em} % prevent overfull lines -\providecommand{\tightlist}{% - \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} -$if(numbersections)$ -\setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$3$endif$} -$else$ -\setcounter{secnumdepth}{-\maxdimen} % remove section numbering -$endif$ -$if(beamer)$ -$else$ -$if(block-headings)$ -% Make \paragraph and \subparagraph free-standing -\ifx\paragraph\undefined\else - \let\oldparagraph\paragraph - \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}} -\fi -\ifx\subparagraph\undefined\else - \let\oldsubparagraph\subparagraph - \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}} -\fi -$endif$ -$endif$ -$if(pagestyle)$ -\pagestyle{$pagestyle$} -$endif$ - -% Make use of float-package and set default placement for figures to H. -% The option H means 'PUT IT HERE' (as opposed to the standard h option which means 'You may put it here if you like'). -\usepackage{float} -\floatplacement{figure}{$if(float-placement-figure)$$float-placement-figure$$else$H$endif$} - -$for(header-includes)$ -$header-includes$ -$endfor$ -$if(lang)$ -\ifxetex - $if(mainfont)$ - $else$ - % See issue https://github.com/reutenauer/polyglossia/issues/127 - \renewcommand*\familydefault{\sfdefault} - $endif$ - % Load polyglossia as late as possible: uses bidi with RTL langages (e.g. Hebrew, Arabic) - \usepackage{polyglossia} - \setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$} -$for(polyglossia-otherlangs)$ - \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$} -$endfor$ -\else - \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} -$if(babel-newcommands)$ - $babel-newcommands$ -$endif$ -\fi -$endif$ -$if(dir)$ -\ifxetex - % Load bidi as late as possible as it modifies e.g. graphicx - \usepackage{bidi} -\fi -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \TeXXeTstate=1 - \newcommand{\RL}[1]{\beginR #1\endR} - \newcommand{\LR}[1]{\beginL #1\endL} - \newenvironment{RTL}{\beginR}{\endR} - \newenvironment{LTR}{\beginL}{\endL} -\fi -$endif$ -$if(natbib)$ -\usepackage[$natbiboptions$]{natbib} -\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$} -$endif$ -$if(biblatex)$ -\usepackage[$if(biblio-style)$style=$biblio-style$,$endif$$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$]{biblatex} -$for(bibliography)$ -\addbibresource{$bibliography$} -$endfor$ -$endif$ -$if(csl-refs)$ -\newlength{\cslhangindent} -\setlength{\cslhangindent}{1.5em} -\newenvironment{cslreferences}% - {$if(csl-hanging-indent)$\setlength{\parindent}{0pt}% - \everypar{\setlength{\hangindent}{\cslhangindent}}\ignorespaces$endif$}% - {\par} -$endif$ - -$if(title)$ -\title{$title$$if(thanks)$\thanks{$thanks$}$endif$} -$endif$ -$if(subtitle)$ -$if(beamer)$ -$else$ -\usepackage{etoolbox} -\makeatletter -\providecommand{\subtitle}[1]{% add subtitle to \maketitle - \apptocmd{\@title}{\par {\large #1 \par}}{}{} -} -\makeatother -$endif$ -\subtitle{$subtitle$} -$endif$ -$if(author)$ -\author{$for(author)$$author$$sep$ \and $endfor$} -$endif$ -\date{$date$} -$if(beamer)$ -$if(institute)$ -\institute{$for(institute)$$institute$$sep$ \and $endfor$} -$endif$ -$if(titlegraphic)$ -\titlegraphic{\includegraphics{$titlegraphic$}} -$endif$ -$if(logo)$ -\logo{\includegraphics{$logo$}} -$endif$ -$endif$ - - - -%% -%% added -%% - -% -% language specification -% -% If no language is specified, use English as the default main document language. -% -$if(lang)$$else$ -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=english]{babel} -$if(babel-newcommands)$ - $babel-newcommands$ -$endif$ -\else - $if(mainfont)$ - $else$ - % Workaround for bug in Polyglossia that breaks `\familydefault` when `\setmainlanguage` is used. - % See https://github.com/Wandmalfarbe/pandoc-latex-template/issues/8 - % See https://github.com/reutenauer/polyglossia/issues/186 - % See https://github.com/reutenauer/polyglossia/issues/127 - \renewcommand*\familydefault{\sfdefault} - $endif$ - % load polyglossia as late as possible as it *could* call bidi if RTL lang (e.g. Hebrew or Arabic) - \usepackage{polyglossia} - \setmainlanguage[]{english} -$for(polyglossia-otherlangs)$ - \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$} -$endfor$ -\fi -$endif$ - -$if(page-background)$ -\usepackage[pages=all]{background} -$endif$ - -% -% for the background color of the title page -% -$if(titlepage)$ -\usepackage{pagecolor} -\usepackage{afterpage} -$if(titlepage-background)$ -\usepackage{tikz} -$endif$ -$if(geometry)$ -$else$ -\usepackage[margin=2.5cm,includehead=true,includefoot=true,centering]{geometry} -$endif$ -$endif$ - -% -% break urls -% -\PassOptionsToPackage{hyphens}{url} - -% -% When using babel or polyglossia with biblatex, loading csquotes is recommended -% to ensure that quoted texts are typeset according to the rules of your main language. -% -\usepackage{csquotes} - -% -% captions -% -\definecolor{caption-color}{HTML}{777777} -$if(beamer)$ -$else$ -\usepackage[font={stretch=1.2}, textfont={color=caption-color}, position=top, skip=4mm, labelfont=bf, singlelinecheck=false, justification=$if(caption-justification)$$caption-justification$$else$raggedright$endif$]{caption} -\setcapindent{0em} -$endif$ - -% -% blockquote -% -\definecolor{blockquote-border}{RGB}{221,221,221} -\definecolor{blockquote-text}{RGB}{119,119,119} -\usepackage{mdframed} -\newmdenv[rightline=false,bottomline=false,topline=false,linewidth=3pt,linecolor=blockquote-border,skipabove=\parskip]{customblockquote} -\renewenvironment{quote}{\begin{customblockquote}\list{}{\rightmargin=0em\leftmargin=0em}% -\item\relax\color{blockquote-text}\ignorespaces}{\unskip\unskip\endlist\end{customblockquote}} - -% -% Source Sans Pro as the de­fault font fam­ily -% Source Code Pro for monospace text -% -% 'default' option sets the default -% font family to Source Sans Pro, not \sfdefault. -% -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - $if(fontfamily)$ - $else$ - \usepackage[default]{sourcesanspro} - \usepackage{sourcecodepro} - $endif$ -\else % if not pdftex - $if(mainfont)$ - $else$ - \usepackage[default]{sourcesanspro} - \usepackage{sourcecodepro} - - % XeLaTeX specific adjustments for straight quotes: https://tex.stackexchange.com/a/354887 - % This issue is already fixed (see https://github.com/silkeh/latex-sourcecodepro/pull/5) but the - % fix is still unreleased. - % TODO: Remove this workaround when the new version of sourcecodepro is released on CTAN. - \ifxetex - \makeatletter - \defaultfontfeatures[\ttfamily] - { Numbers = \sourcecodepro@figurestyle, - Scale = \SourceCodePro@scale, - Extension = .otf } - \setmonofont - [ UprightFont = *-\sourcecodepro@regstyle, - ItalicFont = *-\sourcecodepro@regstyle It, - BoldFont = *-\sourcecodepro@boldstyle, - BoldItalicFont = *-\sourcecodepro@boldstyle It ] - {SourceCodePro} - \makeatother - \fi - $endif$ -\fi - -% -% heading color -% -\definecolor{heading-color}{RGB}{40,40,40} -$if(beamer)$ -$else$ -\addtokomafont{section}{\color{heading-color}} -$endif$ -% When using the classes report, scrreprt, book, -% scrbook or memoir, uncomment the following line. -%\addtokomafont{chapter}{\color{heading-color}} - -% -% variables for title and author -% -$if(beamer)$ -$else$ -\usepackage{titling} -\title{$title$} -\author{$for(author)$$author$$sep$, $endfor$} -$endif$ - -% -% tables -% -$if(tables)$ - -\definecolor{table-row-color}{HTML}{F5F5F5} -\definecolor{table-rule-color}{HTML}{999999} - -%\arrayrulecolor{black!40} -\arrayrulecolor{table-rule-color} % color of \toprule, \midrule, \bottomrule -\setlength\heavyrulewidth{0.3ex} % thickness of \toprule, \bottomrule -\renewcommand{\arraystretch}{1.3} % spacing (padding) - -$if(table-use-row-colors)$ -% TODO: This doesn't work anymore. I don't know why. -% Reset rownum counter so that each table -% starts with the same row colors. -% https://tex.stackexchange.com/questions/170637/restarting-rowcolors -% -% Unfortunately the colored cells extend beyond the edge of the -% table because pandoc uses @-expressions (@{}) like so: -% -% \begin{longtable}[]{@{}ll@{}} -% \end{longtable} -% -% https://en.wikibooks.org/wiki/LaTeX/Tables#.40-expressions -\let\oldlongtable\longtable -\let\endoldlongtable\endlongtable -\renewenvironment{longtable}{ -\rowcolors{3}{}{table-row-color!100} % row color -\oldlongtable} { -\endoldlongtable -\global\rownum=0\relax} -$endif$ -$endif$ - -% -% remove paragraph indention -% -\setlength{\parindent}{0pt} -\setlength{\parskip}{6pt plus 2pt minus 1pt} -\setlength{\emergencystretch}{3em} % prevent overfull lines - -% -% -% Listings -% -% - -$if(listings)$ - -% -% general listing colors -% -\definecolor{listing-background}{HTML}{F7F7F7} -\definecolor{listing-rule}{HTML}{B3B2B3} -\definecolor{listing-numbers}{HTML}{B3B2B3} -\definecolor{listing-text-color}{HTML}{000000} -\definecolor{listing-keyword}{HTML}{435489} -\definecolor{listing-keyword-2}{HTML}{1284CA} % additional keywords -\definecolor{listing-keyword-3}{HTML}{9137CB} % additional keywords -\definecolor{listing-identifier}{HTML}{435489} -\definecolor{listing-string}{HTML}{00999A} -\definecolor{listing-comment}{HTML}{8E8E8E} - -\lstdefinestyle{eisvogel_listing_style}{ - language = java, -$if(listings-disable-line-numbers)$ - xleftmargin = 0.6em, - framexleftmargin = 0.4em, -$else$ - numbers = left, - xleftmargin = 2.7em, - framexleftmargin = 2.5em, -$endif$ - backgroundcolor = \color{listing-background}, - basicstyle = \color{listing-text-color}\linespread{1.0}$if(code-block-font-size)$$code-block-font-size$$else$\small$endif$\ttfamily{}, - breaklines = true, - frame = single, - framesep = 0.19em, - rulecolor = \color{listing-rule}, - frameround = ffff, - tabsize = 4, - numberstyle = \color{listing-numbers}, - aboveskip = 1.0em, - belowskip = 0.1em, - abovecaptionskip = 0em, - belowcaptionskip = 1.0em, - keywordstyle = {\color{listing-keyword}\bfseries}, - keywordstyle = {[2]\color{listing-keyword-2}\bfseries}, - keywordstyle = {[3]\color{listing-keyword-3}\bfseries\itshape}, - sensitive = true, - identifierstyle = \color{listing-identifier}, - commentstyle = \color{listing-comment}, - stringstyle = \color{listing-string}, - showstringspaces = false, - escapeinside = {/*@}{@*/}, % Allow LaTeX inside these special comments - literate = - {á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1 - {Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1 - {à}{{\`a}}1 {è}{{\'e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1 - {À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1 - {ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1 - {Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1 - {â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1 - {Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1 - {œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1 - {ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1 - {€}{{\EUR}}1 {£}{{\pounds}}1 {«}{{\guillemotleft}}1 - {»}{{\guillemotright}}1 {ñ}{{\~n}}1 {Ñ}{{\~N}}1 {¿}{{?`}}1 - {…}{{\ldots}}1 {≥}{{>=}}1 {≤}{{<=}}1 {„}{{\glqq}}1 {“}{{\grqq}}1 - {”}{{''}}1 -} -\lstset{style=eisvogel_listing_style} - -% -% Java (Java SE 12, 2019-06-22) -% -\lstdefinelanguage{Java}{ - morekeywords={ - % normal keywords (without data types) - abstract,assert,break,case,catch,class,continue,default, - do,else,enum,exports,extends,final,finally,for,if,implements, - import,instanceof,interface,module,native,new,package,private, - protected,public,requires,return,static,strictfp,super,switch, - synchronized,this,throw,throws,transient,try,volatile,while, - % var is an identifier - var - }, - morekeywords={[2] % data types - % primitive data types - boolean,byte,char,double,float,int,long,short, - % String - String, - % primitive wrapper types - Boolean,Byte,Character,Double,Float,Integer,Long,Short - % number types - Number,AtomicInteger,AtomicLong,BigDecimal,BigInteger,DoubleAccumulator,DoubleAdder,LongAccumulator,LongAdder,Short, - % other - Object,Void,void - }, - morekeywords={[3] % literals - % reserved words for literal values - null,true,false, - }, - sensitive, - morecomment = [l]//, - morecomment = [s]{/*}{*/}, - morecomment = [s]{/**}{*/}, - morestring = [b]", - morestring = [b]', -} - -\lstdefinelanguage{XML}{ - morestring = [b]", - moredelim = [s][\bfseries\color{listing-keyword}]{<}{\ }, - moredelim = [s][\bfseries\color{listing-keyword}]{}, - moredelim = [l][\bfseries\color{listing-keyword}]{/>}, - moredelim = [l][\bfseries\color{listing-keyword}]{>}, - morecomment = [s]{}, - morecomment = [s]{}, - commentstyle = \color{listing-comment}, - stringstyle = \color{listing-string}, - identifierstyle = \color{listing-identifier} -} -$endif$ - -% -% header and footer -% -$if(beamer)$ -$else$ -$if(disable-header-and-footer)$ -$else$ -\usepackage{fancyhdr} - -\fancypagestyle{eisvogel-header-footer}{ - \fancyhead{} - \fancyfoot{} - \lhead[$if(header-right)$$header-right$$else$$date$$endif$]{$if(header-left)$$header-left$$else$$title$$endif$} - \chead[$if(header-center)$$header-center$$else$$endif$]{$if(header-center)$$header-center$$else$$endif$} - \rhead[$if(header-left)$$header-left$$else$$title$$endif$]{$if(header-right)$$header-right$$else$$date$$endif$} - \lfoot[$if(footer-right)$$footer-right$$else$\thepage$endif$]{$if(footer-left)$$footer-left$$else$$for(author)$$author$$sep$, $endfor$$endif$} - \cfoot[$if(footer-center)$$footer-center$$else$$endif$]{$if(footer-center)$$footer-center$$else$$endif$} - \rfoot[$if(footer-left)$$footer-left$$else$$for(author)$$author$$sep$, $endfor$$endif$]{$if(footer-right)$$footer-right$$else$\thepage$endif$} - \renewcommand{\headrulewidth}{0.4pt} - \renewcommand{\footrulewidth}{0.4pt} -} -\pagestyle{eisvogel-header-footer} -$if(page-background)$ -\backgroundsetup{ -scale=1, -color=black, -opacity=$if(page-background-opacity)$$page-background-opacity$$else$0.2$endif$, -angle=0, -contents={% - \includegraphics[width=\paperwidth,height=\paperheight]{$page-background$} - }% -} -$endif$ -$endif$ -$endif$ - -%% -%% end added -%% - -\begin{document} - -%% -%% begin titlepage -%% -$if(beamer)$ -$else$ -$if(titlepage)$ -\begin{titlepage} -$if(titlepage-background)$ -\newgeometry{top=2cm, right=4cm, bottom=3cm, left=4cm} -$else$ -\newgeometry{left=6cm} -$endif$ -$if(titlepage-color)$ -\definecolor{titlepage-color}{HTML}{$titlepage-color$} -\newpagecolor{titlepage-color}\afterpage{\restorepagecolor} -$endif$ -$if(titlepage-background)$ -\tikz[remember picture,overlay] \node[inner sep=0pt] at (current page.center){\includegraphics[width=\paperwidth,height=\paperheight]{$titlepage-background$}}; -$endif$ -\newcommand{\colorRule}[3][black]{\textcolor[HTML]{#1}{\rule{#2}{#3}}} -\begin{flushleft} -\noindent -\\[-1em] -\color[HTML]{$if(titlepage-text-color)$$titlepage-text-color$$else$5F5F5F$endif$} -\makebox[0pt][l]{\colorRule[$if(titlepage-rule-color)$$titlepage-rule-color$$else$435488$endif$]{1.3\textwidth}{$if(titlepage-rule-height)$$titlepage-rule-height$$else$4$endif$pt}} -\par -\noindent - -$if(titlepage-background)$ -% The titlepage with a background image has other text spacing and text size -{ - \setstretch{2} - \vfill - \vskip -8em - \noindent {\huge \textbf{\textsf{$title$}}} - $if(subtitle)$ - \vskip 1em - {\Large \textsf{$subtitle$}} - $endif$ - \vskip 2em - \noindent {\Large \textsf{$for(author)$$author$$sep$, $endfor$} \vskip 0.6em \textsf{$date$}} - \vfill -} -$else$ -{ - \setstretch{1.4} - \vfill - \noindent {\huge \textbf{\textsf{$title$}}} - $if(subtitle)$ - \vskip 1em - {\Large \textsf{$subtitle$}} - $endif$ - \vskip 2em - \noindent {\Large \textsf{$for(author)$$author$$sep$, $endfor$}} - \vfill -} -$endif$ - -$if(logo)$ -\noindent -\includegraphics[width=$if(logo-width)$$logo-width$$else$100$endif$pt, left]{$logo$} -$endif$ - -$if(titlepage-background)$ -$else$ -\textsf{$date$} -$endif$ -\end{flushleft} -\end{titlepage} -\restoregeometry -$endif$ -$endif$ - -%% -%% end titlepage -%% - -$if(has-frontmatter)$ -\frontmatter -$endif$ -$if(title)$ -$if(beamer)$ -\frame{\titlepage} -$endif$ -$if(abstract)$ -\begin{abstract} -$abstract$ -\end{abstract} -$endif$ -$endif$ - -$if(first-chapter)$ -\setcounter{chapter}{$first-chapter$} -\addtocounter{chapter}{-1} -$endif$ - -$for(include-before)$ -$include-before$ - -$endfor$ -$if(toc)$ -$if(toc-title)$ -\renewcommand*\contentsname{$toc-title$} -$endif$ -$if(beamer)$ -\begin{frame} -$if(toc-title)$ - \frametitle{$toc-title$} -$endif$ - \tableofcontents[hideallsubsections] -\end{frame} -$if(toc-own-page)$ -\newpage -$endif$ -$else$ -{ -$if(colorlinks)$ -\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$$endif$} -$endif$ -\setcounter{tocdepth}{$if(toc-depth)$$toc-depth$$else$3$endif$} -\tableofcontents -$if(toc-own-page)$ -\newpage -$endif$ -} -$endif$ -$endif$ -$if(lot)$ -\listoftables -$endif$ -$if(lof)$ -\listoffigures -$endif$ -$if(linestretch)$ -\setstretch{$linestretch$} -$endif$ -$if(has-frontmatter)$ -\mainmatter -$endif$ -$body$ - -$if(has-frontmatter)$ -\backmatter -$endif$ -$if(natbib)$ -$if(bibliography)$ -$if(biblio-title)$ -$if(has-chapters)$ -\renewcommand\bibname{$biblio-title$} -$else$ -\renewcommand\refname{$biblio-title$} -$endif$ -$endif$ -$if(beamer)$ -\begin{frame}[allowframebreaks]{$biblio-title$} - \bibliographytrue -$endif$ - \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} -$if(beamer)$ -\end{frame} -$endif$ - -$endif$ -$endif$ -$if(biblatex)$ -$if(beamer)$ -\begin{frame}[allowframebreaks]{$biblio-title$} - \bibliographytrue - \printbibliography[heading=none] -\end{frame} -$else$ -\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ -$endif$ - -$endif$ -$for(include-after)$ -$include-after$ - -$endfor$ -\end{document} diff --git a/app/preport/templates/tpl/html/default/html_finding.md b/app/preport/templates/tpl/html/default/html_finding.md index 1adf425..95c0deb 100644 --- a/app/preport/templates/tpl/html/default/html_finding.md +++ b/app/preport/templates/tpl/html/default/html_finding.md @@ -17,11 +17,21 @@
**{{finding.cvss_score | safe | bleach}} **
**{% translate "CVSS Vector" %}****{{finding.cvss_vector | safe | bleach}} **
**CWE** {{finding.cwe.cwe_id}} - {{finding.cwe.cwe_name | safe | bleach}}
**OWASP**{{finding.owasp.owasp_id|safe}} - {{finding.owasp.owasp_name|safe}}
**{% translate "Description" %}**
- - - - - - - - - - - - - - - - - - -{% if finding.description %} - - - - -{% endif %} - -{% if finding.location %} - - - - -{% endif %} - -{% if finding.impact %} - - - - -{% endif %} - -{% if finding.recommendation %} - - - - -{% endif %} - -{% if finding.references %} - - - - -{% endif %} - -{% if template_custom_fields %} -{{template_custom_fields | safe}} -{% endif %} - -{% if template_attackflow_in_finding %} - -{{template_attackflow_in_finding | safe }} - -{% endif %} - -
**{% translate "Severity" %}****{{finding.severity | safe | bleach}} **
**{% translate "CVSS Score" %}****{{finding.cvss_score | safe | bleach}} **
**CWE**{{finding.cwe.cwe_id}} - {{finding.cwe.cwe_name | safe | bleach}}
**{% translate "Description" %}** - -{{finding.description | safe_markdown | bleach}} - -
**{% translate "Location" %}**{{finding.location | safe_markdown | bleach}}
**{% translate "Impact" %}**{{finding.impact | safe_markdown | bleach}}
**{% translate "Recommendation" %}**{{finding.recommendation | safe_markdown | bleach}}
**{% translate "References" %}**{{finding.references | safe_markdown | bleach}}
\ No newline at end of file diff --git a/app/preport/templates/tpl/html/html_finding_end_table.html b/app/preport/templates/tpl/html/html_finding_end_table.html deleted file mode 100644 index 6944a91..0000000 --- a/app/preport/templates/tpl/html/html_finding_end_table.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/app/preport/templates/tpl/html/html_finding_summary.html b/app/preport/templates/tpl/html/html_finding_summary.html deleted file mode 100644 index e558719..0000000 --- a/app/preport/templates/tpl/html/html_finding_summary.html +++ /dev/null @@ -1,7 +0,0 @@ -{% load martortags %} -{% load bleach_tags %} - - {{counter_finding}} - {{finding.title|safe| bleach}} - **{{finding.severity|safe| bleach}} ** - \ No newline at end of file diff --git a/app/preport/templates/tpl/html/html_finding_summary_table.html b/app/preport/templates/tpl/html/html_finding_summary_table.html deleted file mode 100644 index c9ec980..0000000 --- a/app/preport/templates/tpl/html/html_finding_summary_table.html +++ /dev/null @@ -1,10 +0,0 @@ -{% load i18n %} - - - - - - - - - \ No newline at end of file diff --git a/app/preport/templates/tpl/html/html_report.md b/app/preport/templates/tpl/html/html_report.md deleted file mode 100644 index 85e3455..0000000 --- a/app/preport/templates/tpl/html/html_report.md +++ /dev/null @@ -1,63 +0,0 @@ -{% load martortags %} -{% load bleach_tags %} -{% load i18n %} ---- -title: "{{DB_report_query.title| safe | bleach}}" -product: "{{DB_report_query.product.name| safe | bleach}}" -author: ["{{md_author}}", "Report ID: {{DB_report_query.report_id| safe | bleach}}"] -date: "{{report_date}}" -subject: "{{md_subject}}" -subtitle: "{{DB_report_query.report_id}}" -website: {{md_website}} -counter_finding_critical: "{{counter_finding_critical}}" -counter_finding_high: "{{counter_finding_high}}" -counter_finding_medium: "{{counter_finding_medium}}" -counter_finding_low: "{{counter_finding_low}}" -counter_finding_info: "{{counter_finding_info}}" -lang: "en" -colorlinks: true ---- - -# {% translate "Project Overview" %} - -## {% translate "Description" %} - -{{DB_report_query.product.description | safe_markdown | bleach}} - -# {% translate "Executive Summary" %} - -{{DB_report_query.executive_summary | safe_markdown | bleach}} - -## {% translate "Summary of Findings Identified" %} - -
-
-
-
-
- -{{finding_summary_table}} - -## {% translate "Scope" %} - -### {% translate "In Scope" %} - -{{DB_report_query.scope | safe_markdown | bleach}} - -### {% translate "Out of Scope" %} - -{{DB_report_query.outofscope | safe_markdown | bleach}} - -## {% translate "Methodology" %} - -{{DB_report_query.methodology | safe_markdown | bleach}} - -## {% translate "Recommendations" %} - -{{DB_report_query.recommendation | safe_markdown | bleach}} - -# {% translate "Findings and Risk Analysis" %} - -{{template_findings}} - -{{template_appendix}} diff --git a/app/preport/templates/tpl/html/md_appendix.md b/app/preport/templates/tpl/html/md_appendix.md deleted file mode 100644 index f9c0aab..0000000 --- a/app/preport/templates/tpl/html/md_appendix.md +++ /dev/null @@ -1,5 +0,0 @@ -{% load martortags %} -{% load bleach_tags %} -## {{appendix_in_finding.title | safe | bleach}} - -{{appendix_in_finding.description | safe_markdown | bleach}} diff --git a/app/preport/templates/tpl/html/md_attackflow.md b/app/preport/templates/tpl/html/md_attackflow.md deleted file mode 100644 index a72f09a..0000000 --- a/app/preport/templates/tpl/html/md_attackflow.md +++ /dev/null @@ -1,7 +0,0 @@ -{% load martortags %} -{% load bleach_tags %} -{{attackflow_in_finding.title | safe | bleach}} - -
-![{{attackflow_in_finding.title | safe | bleach}}]({{attackflow_in_finding.attackflow_png | safe | bleach}}){style="max-height:1000px;max-width:900px;height:auto;width:auto;"} -
diff --git a/app/preport/templates/tpl/jupyter/NA.ipynb b/app/preport/templates/tpl/jupyter/NA.ipynb deleted file mode 100644 index 93a6f1f..0000000 --- a/app/preport/templates/tpl/jupyter/NA.ipynb +++ /dev/null @@ -1,8 +0,0 @@ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "N/A\n", - "\n" - ] - }, \ No newline at end of file diff --git a/app/preport/templates/tpl/jupyter/additional_notes.ipynb b/app/preport/templates/tpl/jupyter/additional_notes.ipynb deleted file mode 100644 index 1c9afd5..0000000 --- a/app/preport/templates/tpl/jupyter/additional_notes.ipynb +++ /dev/null @@ -1,9 +0,0 @@ - {% load i18n %} - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# {% translate "Additional Notes" %}\n\n", - "\n" - ] - }, \ No newline at end of file diff --git a/app/preport/templates/tpl/jupyter/appendix.ipynb b/app/preport/templates/tpl/jupyter/appendix.ipynb deleted file mode 100644 index de621d5..0000000 --- a/app/preport/templates/tpl/jupyter/appendix.ipynb +++ /dev/null @@ -1,11 +0,0 @@ -{% load app_filters %} - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## {{appendix_in_finding.title}}\n\n", - "{{ appendix_in_finding.description|jupyter_format }}\n", - "\n\n" - ] - }, \ No newline at end of file diff --git a/app/preport/templates/tpl/jupyter/appendix_in_finding.ipynb b/app/preport/templates/tpl/jupyter/appendix_in_finding.ipynb deleted file mode 100644 index 75f16ff..0000000 --- a/app/preport/templates/tpl/jupyter/appendix_in_finding.ipynb +++ /dev/null @@ -1,8 +0,0 @@ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "{{appendix_in_finding.title}}\n", - "\n" - ] - }, \ No newline at end of file diff --git a/app/preport/templates/tpl/jupyter/attackflow.ipynb b/app/preport/templates/tpl/jupyter/attackflow.ipynb deleted file mode 100644 index f31e986..0000000 --- a/app/preport/templates/tpl/jupyter/attackflow.ipynb +++ /dev/null @@ -1,10 +0,0 @@ - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## {{attackflow_in_finding.title}}\n\n", - "![{{attackflow_in_finding.title}}]({{attackflow_in_finding.attackflow_png}})\n", - "\n\n" - ] - }, \ No newline at end of file diff --git a/app/preport/templates/tpl/jupyter/attackflow_in_finding.ipynb b/app/preport/templates/tpl/jupyter/attackflow_in_finding.ipynb deleted file mode 100644 index 4eef7e5..0000000 --- a/app/preport/templates/tpl/jupyter/attackflow_in_finding.ipynb +++ /dev/null @@ -1,9 +0,0 @@ - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "{{ attackflow_in_finding.title }}\n\n", - "\n" - ] - }, \ No newline at end of file diff --git a/app/preport/templates/tpl/jupyter/attackflows.ipynb b/app/preport/templates/tpl/jupyter/attackflows.ipynb deleted file mode 100644 index f6897b2..0000000 --- a/app/preport/templates/tpl/jupyter/attackflows.ipynb +++ /dev/null @@ -1,8 +0,0 @@ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Attack Flows\n\n", - "\n" - ] - }, \ No newline at end of file diff --git a/app/preport/templates/tpl/jupyter/custom_field.ipynb b/app/preport/templates/tpl/jupyter/custom_field.ipynb deleted file mode 100644 index de621d5..0000000 --- a/app/preport/templates/tpl/jupyter/custom_field.ipynb +++ /dev/null @@ -1,11 +0,0 @@ -{% load app_filters %} - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## {{appendix_in_finding.title}}\n\n", - "{{ appendix_in_finding.description|jupyter_format }}\n", - "\n\n" - ] - }, \ No newline at end of file diff --git a/app/preport/templates/tpl/jupyter/default/finding.ipynb b/app/preport/templates/tpl/jupyter/default/finding.ipynb index 4fd7e8d..dde5cbf 100644 --- a/app/preport/templates/tpl/jupyter/default/finding.ipynb +++ b/app/preport/templates/tpl/jupyter/default/finding.ipynb @@ -7,8 +7,10 @@ "source": [ "## {{ finding.title }}\n", "**{% translate "Severity" %}:** {{ finding.severity }}\n\n", - "**{% translate "CVSS Score" %}:** {{ finding.cvss_base_score }}\n\n", + "**{% translate "CVSS Score" %}:** {{ finding.cvss_score }}\n\n", + "**{% translate "CVSS Vector" %}:** {{ finding.cvss_vector }}\n\n", "**{% translate "CWE" %}:** {{ finding.cwe.cwe_id }} - {{ finding.cwe.cwe_name }}\n\n", + "**{% translate "OWASP" %}:** {{finding.owasp.owasp_id|safe}} - {{finding.owasp.owasp_name|safe}}\n\n", {% if finding.description %} "**{% translate "Description" %}**\n\n", "{{ finding.description|jupyter_format }}\n\n", diff --git a/app/preport/templates/tpl/jupyter/finding.ipynb b/app/preport/templates/tpl/jupyter/finding.ipynb deleted file mode 100644 index 0d6951c..0000000 --- a/app/preport/templates/tpl/jupyter/finding.ipynb +++ /dev/null @@ -1,41 +0,0 @@ -{% load app_filters %} -{% load i18n %} - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## {{ finding.title }}\n", - "**{% translate "Severity" %}:** {{ finding.severity }}\n\n", - "**{% translate "CVSS Score" %}:** {{ finding.cvss_base_score }}\n\n", - "**{% translate "CWE" %}:** {{ finding.cwe.cwe_id }} - {{ finding.cwe.cwe_name }}\n\n", - {% if finding.description %} - "**{% translate "Description" %}**\n\n", - "{{ finding.description|jupyter_format }}\n\n", - {% endif %} - {% if finding.location %} - "**{% translate "Location" %}**\n\n", - "{{finding.location|jupyter_format }}\n\n", - {% endif %} - {% if finding.impact %} - "**{% translate "Impact" %}**\n\n", - "{{ finding.impact|jupyter_format }}\n\n", - {% endif %} - {% if finding.recommendation %} - "**{% translate "Recommendation" %}**\n\n", - "{{ finding.recommendation|jupyter_format }}\n\n", - {% endif %} - {% if finding.references %} - "**{% translate "References" %}**\n\n", - "{{ finding.references|jupyter_format }}\n\n", - {% endif %} - {% if finding.custom_field_finding %} - {% for field_in_finding in finding.custom_field_finding.all %} - "**{{field_in_finding.title}}**\n\n", - "{{ field_in_finding.description|jupyter_format }}\n\n", - {% endfor %} - {% endif %} - "**{% translate "Additional notes" %}**\n", - "\n" - ] - }, \ No newline at end of file diff --git a/app/preport/templates/tpl/jupyter/finding_summary.ipynb b/app/preport/templates/tpl/jupyter/finding_summary.ipynb deleted file mode 100644 index 826f802..0000000 --- a/app/preport/templates/tpl/jupyter/finding_summary.ipynb +++ /dev/null @@ -1,7 +0,0 @@ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**# {{counter_finding}} {{finding.severity}}** {{finding.title}}" - ] - }, \ No newline at end of file diff --git a/app/preport/templates/tpl/jupyter/report.ipynb b/app/preport/templates/tpl/jupyter/report.ipynb deleted file mode 100644 index 69cb4ce..0000000 --- a/app/preport/templates/tpl/jupyter/report.ipynb +++ /dev/null @@ -1,149 +0,0 @@ -{% load app_filters %} -{% load i18n %} -{ - "cells": [ - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# {% translate "Project Overview" %}\n", - "## {% translate "Description" %}\n", - "{{ DB_report_query.product.description|jupyter_format }}\n\n" - ] - }, - - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# {% translate "Executive Summary" %}\n", - "{{ DB_report_query.executive_summary|jupyter_format }}\n\n", - "## {% translate "Summary of Findings Identified" %}\n", - "\n" - ] - }, - - - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "fig = plt.figure(figsize = (10, 5))\n", - "ax = fig.add_axes([0,0,1,1])\n", - "width = 0.80\n", - "\n", - "severity = ['{% translate "Critical" %}', '{% translate "High" %}', '{% translate "Medium" %}', '{% translate "Low" %}', '{% translate "Informational" %}']\n", - "value = [{{counter_finding_critical}},{{counter_finding_high}},{{counter_finding_medium}},{{counter_finding_low}},{{counter_finding_info}}]\n", - "\n", - "plt.title('{% translate "Breakdown by Severity" %}')\n", - "\n", - "ax.bar(severity[0], value[0], color='#CC0000', width=width)\n", - "ax.bar(severity[1], value[1], color='#FF0000', width=width)\n", - "ax.bar(severity[2], value[2], color='#FC7F03', width=width)\n", - "ax.bar(severity[3], value[3], color='#05B04F', width=width)\n", - "ax.bar(severity[4], value[4], color='#002060', width=width)\n", - "\n", - "plt.show()\n" - ] - }, - -{{ finding_summary|safe }} - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## {% translate "Scope" %}\n", - "### {% translate "In Scope" %}\n", - "{{ DB_report_query.scope|jupyter_format }}\n\n", - "### {% translate "Out of Scope" %}\n", - "{{ DB_report_query.outofscope|jupyter_format }}\n\n", - "\n" - ] - }, - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## {% translate "Methodology" %}\n", - "{{ DB_report_query.methodology|jupyter_format }}\n\n", - "\n" - ] - }, - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## {% translate "Recommendations" %}\n", - "{{ DB_report_query.recommendation|jupyter_format }}\n\n", - "\n" - ] - }, - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# {% translate "Findings and Risk Analysis" %}\n\n", - "\n" - ] - }, - -{{ template_findings|safe }} - -{{ template_appendix|safe }} - -{{ template_attackflow|safe }} - - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---\n", - "title: \"{{DB_report_query.title}}\"\n\n", - "product: \"{{DB_report_query.product.name}}\"\n\n", - "author: [\"{{md_author}}\", \"Report ID: {{DB_report_query.report_id}}\"]\n\n", - "date: \"{{report_date}}\"\n\n", - "subject: \"{{md_subject}}\"\n\n", - "subtitle: \"{{DB_report_query.report_id}}\"\n\n", - "website: {{md_website}}\n\n", - "---\n" - ] - } - - - - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} - - - diff --git a/app/preport/templates/tpl/markdown/default/md_finding.md b/app/preport/templates/tpl/markdown/default/md_finding.md index c2b6858..13edfeb 100644 --- a/app/preport/templates/tpl/markdown/default/md_finding.md +++ b/app/preport/templates/tpl/markdown/default/md_finding.md @@ -3,12 +3,19 @@ **{% translate "Severity" %}:** {{finding.severity|safe}} -{% if finding.cvss_base_score != "0" %} -**{% translate "CVSS Score" %}:** {{finding.cvss_base_score|safe}} +{% if finding.cvss_vector != "0" %} +**{% translate "CVSS Vector" %}:** {{finding.cvss_vector|safe}} +{% endif %} + +{% if finding.cvss_score != "0" %} +**{% translate "CVSS Score" %}:** {{finding.cvss_score|safe}} {% endif %} **{% translate "CWE" %}:** {{finding.cwe.cwe_id|safe}} - {{finding.cwe.cwe_name|safe}} +**{% translate "OWASP" %}:** {{finding.owasp.owasp_id|safe}} - {{finding.owasp.owasp_name|safe}} + + {% if finding.description %} **{% translate "Description" %}** diff --git a/app/preport/templates/tpl/markdown/md_appendix.md b/app/preport/templates/tpl/markdown/md_appendix.md deleted file mode 100644 index 8694913..0000000 --- a/app/preport/templates/tpl/markdown/md_appendix.md +++ /dev/null @@ -1,4 +0,0 @@ -## {{appendix_in_finding.title|safe}} - -{{appendix_in_finding.description|safe}} - diff --git a/app/preport/templates/tpl/markdown/md_attackflow.md b/app/preport/templates/tpl/markdown/md_attackflow.md deleted file mode 100644 index ca02ae4..0000000 --- a/app/preport/templates/tpl/markdown/md_attackflow.md +++ /dev/null @@ -1,3 +0,0 @@ -{{attackflow_in_finding.title}} - -![{{attackflow_in_finding.title|safe}}]({{attackflow_in_finding.attackflow_png|safe}}) diff --git a/app/preport/templates/tpl/markdown/md_finding.md b/app/preport/templates/tpl/markdown/md_finding.md deleted file mode 100644 index 5bfb1a5..0000000 --- a/app/preport/templates/tpl/markdown/md_finding.md +++ /dev/null @@ -1,53 +0,0 @@ -{% load i18n %} -## {{finding.title|safe}} - -**{% translate "Severity" %}:** {{finding.severity|safe}} - -{% if finding.cvss_base_score != "0" %} -**{% translate "CVSS Score" %}:** {{finding.cvss_base_score|safe}} -{% endif %} - -**{% translate "CWE" %}:** {{finding.cwe.cwe_id|safe}} - {{finding.cwe.cwe_name|safe}} - -{% if finding.description %} -**{% translate "Description" %}** - -{{finding.description|safe}} -{% endif %} - -{% if finding.location %} -**{% translate "Location" %}** - -{{finding.location|safe}} -{% endif %} - -{% if finding.impact %} -**{% translate "Impact" %}** - -{{finding.impact|safe}} -{% endif %} - -{% if finding.recommendation %} -**{% translate "Recommendation" %}** - -{{finding.recommendation|safe}} -{% endif %} - -{% if finding.references %} -**{% translate "References" %}** - -{{finding.references|safe}} -{% endif %} - -{% if template_custom_fields %} -{{template_custom_fields | safe}} -{% endif %} - -{% if template_appendix_in_finding %} -{{template_appendix_in_finding|safe}} -{% endif %} - - -{% if template_attackflow_in_finding %} -{{template_attackflow_in_finding|safe}} -{% endif %} \ No newline at end of file diff --git a/app/preport/templates/tpl/markdown/md_finding_summary.md b/app/preport/templates/tpl/markdown/md_finding_summary.md deleted file mode 100644 index 51a757a..0000000 --- a/app/preport/templates/tpl/markdown/md_finding_summary.md +++ /dev/null @@ -1 +0,0 @@ -**# {{counter_finding}} {{finding.severity}}** {{finding.title}} diff --git a/app/preport/templates/tpl/markdown/md_report.md b/app/preport/templates/tpl/markdown/md_report.md deleted file mode 100644 index 569085c..0000000 --- a/app/preport/templates/tpl/markdown/md_report.md +++ /dev/null @@ -1,52 +0,0 @@ -{% load i18n %} ---- -title: "{{DB_report_query.title}}" -product: "{{DB_report_query.product.name}}" -author: ["{{md_author}}", "Report ID: {{DB_report_query.report_id}}"] -date: "{{report_date}}" -subject: "{{md_subject}}" -subtitle: "{{DB_report_query.report_id}}" -website: {{md_website}} ---- - -# {% translate "Project Overview" %} - -## {% translate "Description" %} - -{{DB_report_query.product.description | safe}} - -# {% translate "Executive Summary" %} - -{{DB_report_query.executive_summary | safe}} - -## {% translate "Summary of Findings Identified" %} - -![Breakdown by Severity]({{report_executive_summary_image}}) - -![Breakdown by Categories]({{report_executive_categories_image}}) - -{{finding_summary}} - -## {% translate "Scope" %} - -### {% translate "In Scope" %} - -{{DB_report_query.scope | safe}} - -### {% translate "Out of Scope" %} - -{{DB_report_query.outofscope | safe}} - -## {% translate "Methodology" %} - -{{DB_report_query.methodology | safe}} - -## {% translate "Recommendations" %} - -{{DB_report_query.recommendation | safe}} - -# {% translate "Findings and Risk Analysis" %} - -{{template_findings}} - -{{template_appendix}} \ No newline at end of file diff --git a/app/preport/templates/tpl/pdf/background_example/pdf_finding.md b/app/preport/templates/tpl/pdf/background_example/pdf_finding.md index 54836cf..b67bea8 100644 --- a/app/preport/templates/tpl/pdf/background_example/pdf_finding.md +++ b/app/preport/templates/tpl/pdf/background_example/pdf_finding.md @@ -5,14 +5,26 @@ ::: {{icon_finding}} **{% translate "Severity" %}:** {{severity_color_finding}} -{% if finding.cvss_base_score != "0" %} -**{% translate "CVSS Score" %}:** {{finding.cvss_base_score|safe}} +{% if finding.cvss_score != "0" %} +**{% translate "CVSS Score" %}:** {{finding.cvss_score|safe}} +{% endif %} + +{% if finding.cvss_vector != "0" %} +**{% translate "CVSS Vector" %}:** {{finding.cvss_vector|safe}} {% endif %} ::: +{% if finding.cwe %} **{% translate "CWE" %}** {{finding.cwe.cwe_id}} - {{finding.cwe.cwe_name|safe}} +{% endif %} + +{% if finding.owasp %} +**{% translate "OWASP" %}** + +{{finding.owasp.owasp_id|safe}} - {{finding.owasp.owasp_name|safe}} +{% endif %} {% if finding.description %} **{% translate "Description" %}** diff --git a/app/preport/templates/tpl/pdf/blank.png b/app/preport/templates/tpl/pdf/blank.png deleted file mode 100644 index ef73ff7..0000000 Binary files a/app/preport/templates/tpl/pdf/blank.png and /dev/null differ diff --git a/app/preport/templates/tpl/pdf/default/pdf_finding.md b/app/preport/templates/tpl/pdf/default/pdf_finding.md index 54836cf..b67bea8 100644 --- a/app/preport/templates/tpl/pdf/default/pdf_finding.md +++ b/app/preport/templates/tpl/pdf/default/pdf_finding.md @@ -5,14 +5,26 @@ ::: {{icon_finding}} **{% translate "Severity" %}:** {{severity_color_finding}} -{% if finding.cvss_base_score != "0" %} -**{% translate "CVSS Score" %}:** {{finding.cvss_base_score|safe}} +{% if finding.cvss_score != "0" %} +**{% translate "CVSS Score" %}:** {{finding.cvss_score|safe}} +{% endif %} + +{% if finding.cvss_vector != "0" %} +**{% translate "CVSS Vector" %}:** {{finding.cvss_vector|safe}} {% endif %} ::: +{% if finding.cwe %} **{% translate "CWE" %}** {{finding.cwe.cwe_id}} - {{finding.cwe.cwe_name|safe}} +{% endif %} + +{% if finding.owasp %} +**{% translate "OWASP" %}** + +{{finding.owasp.owasp_id|safe}} - {{finding.owasp.owasp_name|safe}} +{% endif %} {% if finding.description %} **{% translate "Description" %}** diff --git a/app/preport/templates/tpl/pdf/pdf_appendix.md b/app/preport/templates/tpl/pdf/pdf_appendix.md deleted file mode 100644 index 8694913..0000000 --- a/app/preport/templates/tpl/pdf/pdf_appendix.md +++ /dev/null @@ -1,4 +0,0 @@ -## {{appendix_in_finding.title|safe}} - -{{appendix_in_finding.description|safe}} - diff --git a/app/preport/templates/tpl/pdf/pdf_attackflow.md b/app/preport/templates/tpl/pdf/pdf_attackflow.md deleted file mode 100644 index ca02ae4..0000000 --- a/app/preport/templates/tpl/pdf/pdf_attackflow.md +++ /dev/null @@ -1,3 +0,0 @@ -{{attackflow_in_finding.title}} - -![{{attackflow_in_finding.title|safe}}]({{attackflow_in_finding.attackflow_png|safe}}) diff --git a/app/preport/templates/tpl/pdf/pdf_finding.md b/app/preport/templates/tpl/pdf/pdf_finding.md deleted file mode 100644 index 4916c2b..0000000 --- a/app/preport/templates/tpl/pdf/pdf_finding.md +++ /dev/null @@ -1,57 +0,0 @@ -{% load i18n %} - -## {{finding.title|safe}} - -::: {{icon_finding}} -**{% translate "Severity" %}:** {{severity_color_finding}} - -{% if finding.cvss_base_score != "0" %} -**{% translate "CVSS Score" %}:** {{finding.cvss_base_score|safe}} -{% endif %} -::: - -**{% translate "CWE" %}** - -{{finding.cwe.cwe_id}} - {{finding.cwe.cwe_name|safe}} - -{% if finding.description %} -**{% translate "Description" %}** - -{{finding.description|safe}} -{% endif %} - -{% if finding.location %} -**{% translate "Location" %}** - -{{finding.location|safe}} -{% endif %} - -{% if finding.impact %} -**{% translate "Impact" %}** - -{{finding.impact|safe}} -{% endif %} - -{% if finding.recommendation %} -**{% translate "Recommendation" %}** - -{{finding.recommendation|safe}} -{% endif %} - -{% if finding.references %} -**{% translate "References" %}** - -{{finding.references|safe}} -{% endif %} - -{% if template_custom_fields %} -{{template_custom_fields | safe}} -{% endif %} - -{% if template_appendix_in_finding %} -{{template_appendix_in_finding|safe}} -{% endif %} - -{% if template_attackflow_in_finding %} -{{template_attackflow_in_finding|safe}} -{% endif %} diff --git a/app/preport/templates/tpl/pdf/pdf_finding_summary.md b/app/preport/templates/tpl/pdf/pdf_finding_summary.md deleted file mode 100644 index 03a784b..0000000 --- a/app/preport/templates/tpl/pdf/pdf_finding_summary.md +++ /dev/null @@ -1,5 +0,0 @@ - -::: {{severity_box}} -**# {{counter_finding}} {{finding.severity}}** {{finding.title|safe}} - -::: diff --git a/app/preport/templates/tpl/pdf/pdf_header.tex b/app/preport/templates/tpl/pdf/pdf_header.tex deleted file mode 100644 index d8fed93..0000000 --- a/app/preport/templates/tpl/pdf/pdf_header.tex +++ /dev/null @@ -1,77 +0,0 @@ - -\usepackage{awesomebox} -\usepackage{tcolorbox} -% tcolorbox % -\newtcolorbox{info-box}{colback=cyan!5!white,arc=0pt,outer arc=0pt,colframe=cyan!60!black} -\newtcolorbox{warning-box}{colback=orange!5!white,arc=0pt,outer arc=0pt,colframe=orange!80!black} -\newtcolorbox{low-box}{colback=green!5!white,arc=0pt,outer arc=0pt,colframe=green!75!black} -\newtcolorbox{error-box}{colback=red!5!white,arc=0pt,outer arc=0pt,colframe=red!75!black} -\newtcolorbox{critical-box}{colback=purple!5!white,arc=0pt,outer arc=0pt,colframe=purple!75!black} - - -\usepackage{xcolor} -% Colors for Severity % -\definecolor{criticalcolor}{HTML}{CC0000} -\definecolor{highcolor}{HTML}{F20000} -\definecolor{mediumcolor}{HTML}{FC7F03} -\definecolor{lowcolor}{HTML}{05B04F} -\definecolor{infocolor}{HTML}{002060} -\definecolor{debugcolor}{HTML}{45A7F7} -% custom awesomebox for Severity, icons https://www.ctan.org/pkg/fontawesome5% - -% high awesomebox -\newenvironment{highblock} - {\begin{awesomeblock}[highcolor]{\aweboxrulewidth}{\faExclamationTriangle}{highcolor}} - {\end{awesomeblock}} - -% medium awesomebox -\newenvironment{mediumblock} - {\begin{awesomeblock}[mediumcolor]{\aweboxrulewidth}{\faExclamationTriangle}{mediumcolor}} - {\end{awesomeblock}} - -% low awesomebox -\newenvironment{lowblock} - {\begin{awesomeblock}[lowcolor]{\aweboxrulewidth}{\faExclamationTriangle}{lowcolor}} - {\end{awesomeblock}} - -% info awesomebox -\newenvironment{infoblock} - {\begin{awesomeblock}[infocolor]{\aweboxrulewidth}{\faExclamationTriangle}{infocolor}} - {\end{awesomeblock}} - -% debug awesomebox -\newenvironment{debugblock} - {\begin{awesomeblock}[debugcolor]{\aweboxrulewidth}{\faBug}{debugcolor}} - {\end{awesomeblock}} - -% custom awesomebox other sections, icons https://www.ctan.org/pkg/fontawesome5% - -% Description awesomebox -\newenvironment{descriptionblock} - {\begin{awesomeblock}[infocolor][\abLongLine][\textbf{Description}]{0pt}{\faFile*}{abnote}} - {\end{awesomeblock}} - -% Location awesomebox -\newenvironment{locationblock} - {\begin{awesomeblock}[infocolor][\abLongLine][\textbf{Location}]{0pt}{\faLink}{infocolor}} - {\end{awesomeblock}} - -% Impact awesomebox -\newenvironment{impactblock} - {\begin{awesomeblock}[abcaution][\abLongLine][\textbf{Impact}]{0pt}{\faBomb}{abcaution}} - {\end{awesomeblock}} - -% Recommendation awesomebox -\newenvironment{recommendationblock} - {\begin{awesomeblock}[black][\abLongLine][\textbf{Recommendation}]{0pt}{\faLightbulb[regular]}{black}} - {\end{awesomeblock}} - -% References awesomebox -\newenvironment{referencesblock} - {\begin{awesomeblock}[black][\abLongLine][\textbf{References}]{0pt}{\faRocket}{black}} - {\end{awesomeblock}} - -% Additional Notes awesomebox -\newenvironment{additional_notesblock} - {\begin{awesomeblock}[black][\abLongLine][\textbf{Additional Notes}]{0pt}{\faCogs}{black}} - {\end{awesomeblock}} diff --git a/app/preport/templates/tpl/pdf/pdf_header.yaml b/app/preport/templates/tpl/pdf/pdf_header.yaml deleted file mode 100644 index 1be719b..0000000 --- a/app/preport/templates/tpl/pdf/pdf_header.yaml +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "{{DB_report_query.title}}" -product: "{{DB_report_query.product.name}}" -author: ["{{md_author}}", "{{md_website}}"] -date: "{{report_date}}" -subject: "{{md_subject}}" -subtitle: "{{DB_report_query.report_id}}" -lang: "{{report_pdf_language}}" -titlepage: true -titlepage-color: "{{titlepagecolor}}" -titlepage-text-color: "{{titlepagetextcolor}}" -titlepage-rule-color: "{{titlerulecolor}}" -titlepage-rule-height: "{{titlepageruleheight}}" -titlepage-background: "{{title_background}}" -page-background: "{{pages_background}}" -book: false -toc-own-page: true -code-block-font-size: \scriptsize -colorlinks: true - -pandoc-latex-environment: - noteblock: [note] - tipblock: [tip] - warningblock: [warning] - cautionblock: [caution] - importantblock: [important] - tcolorbox: [box] - info-box: [infobox] - low-box: [lowbox] - warning-box: [mediumbox] - error-box: [highbox] - critical-box: [criticalbox] - highblock: [highnote] - mediumblock: [mediumnote] - lowblock: [lownote] - infoblock: [infonote] - debugblock: [debugnote] - descriptionblock: [descriptionnote] - locationblock: [locationnote] - impactblock: [impactnote] - recommendationblock: [recommendationnote] - referencesblock: [referencesnote] - additional_notesblock: [additional_notesnote] - ---- - diff --git a/app/preport/templates/tpl/pdf/pdf_report.md b/app/preport/templates/tpl/pdf/pdf_report.md deleted file mode 100644 index 15a6f8a..0000000 --- a/app/preport/templates/tpl/pdf/pdf_report.md +++ /dev/null @@ -1,49 +0,0 @@ -{% load i18n %} -# {% translate "Project Overview" %} - -## {% translate "Description" %} - -{{DB_report_query.product.description | safe}} - -\pagebreak -# {% translate "Executive Summary" %} - -{{DB_report_query.executive_summary | safe}} - -## {% translate "Summary of Findings Identified" %} - -![Executive Summary]({{report_executive_summary_image}}) - -![Breakdown by Categories]({{report_executive_categories_image}}) - -{{pdf_finding_summary}} - -## {% translate "Scope" %} - -### {% translate "In Scope" %} - -{{DB_report_query.scope | safe}} - -### {% translate "Out of Scope" %} - -{{DB_report_query.outofscope | safe}} - -\pagebreak -## {% translate "Methodology" %} - -{{DB_report_query.methodology | safe}} - -\pagebreak -## {% translate "Recommendations" %} - -{{DB_report_query.recommendation | safe}} - -\pagebreak -# {% translate "Findings and Risk Analysis" %} - -{{template_findings}} - -\pagebreak -{{template_appendix}} - -\pagebreak diff --git a/app/preport/templates/tpl/pdf/title.png b/app/preport/templates/tpl/pdf/title.png deleted file mode 100644 index b125b23..0000000 Binary files a/app/preport/templates/tpl/pdf/title.png and /dev/null differ diff --git a/app/preport/templates/tpl/petereport.latex b/app/preport/templates/tpl/petereport.latex deleted file mode 100644 index 341b463..0000000 --- a/app/preport/templates/tpl/petereport.latex +++ /dev/null @@ -1,1036 +0,0 @@ -%% -% Copyright (c) 2017 - 2020, Pascal Wagler; -% Copyright (c) 2014 - 2020, John MacFarlane -% -% All rights reserved. -% -% Redistribution and use in source and binary forms, with or without -% modification, are permitted provided that the following conditions -% are met: -% -% - Redistributions of source code must retain the above copyright -% notice, this list of conditions and the following disclaimer. -% -% - Redistributions in binary form must reproduce the above copyright -% notice, this list of conditions and the following disclaimer in the -% documentation and/or other materials provided with the distribution. -% -% - Neither the name of John MacFarlane nor the names of other -% contributors may be used to endorse or promote products derived -% from this software without specific prior written permission. -% -% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -% FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -% COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -% INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -% ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -% POSSIBILITY OF SUCH DAMAGE. -%% - -%% -% This is the Eisvogel pandoc LaTeX template. -% -% For usage information and examples visit the official GitHub page: -% https://github.com/Wandmalfarbe/pandoc-latex-template -%% - -% Options for packages loaded elsewhere -\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref} -\PassOptionsToPackage{hyphens}{url} -\PassOptionsToPackage{dvipsnames,svgnames*,x11names*,table}{xcolor} -$if(dir)$ -$if(latex-dir-rtl)$ -\PassOptionsToPackage{RTLdocument}{bidi} -$endif$ -$endif$ -% -\documentclass[ -$if(fontsize)$ - $fontsize$, -$endif$ -$if(lang)$ - $babel-lang$, -$endif$ -$if(papersize)$ - $papersize$paper, -$else$ - paper=a4, -$endif$ -$if(beamer)$ - ignorenonframetext, -$if(handout)$ - handout, -$endif$ -$if(aspectratio)$ - aspectratio=$aspectratio$, -$endif$ -$endif$ -$for(classoption)$ - $classoption$$sep$, -$endfor$ -,captions=tableheading -]{$if(beamer)$$documentclass$$else$$if(book)$scrbook$else$scrartcl$endif$$endif$} -$if(beamer)$ -$if(background-image)$ -\usebackgroundtemplate{% - \includegraphics[width=\paperwidth]{$background-image$}% -} -$endif$ -\usepackage{pgfpages} -\setbeamertemplate{caption}[numbered] -\setbeamertemplate{caption label separator}{: } -\setbeamercolor{caption name}{fg=normal text.fg} -\beamertemplatenavigationsymbols$if(navigation)$$navigation$$else$empty$endif$ -$for(beameroption)$ -\setbeameroption{$beameroption$} -$endfor$ -% Prevent slide breaks in the middle of a paragraph -\widowpenalties 1 10000 -\raggedbottom -$if(section-titles)$ -\setbeamertemplate{part page}{ - \centering - \begin{beamercolorbox}[sep=16pt,center]{part title} - \usebeamerfont{part title}\insertpart\par - \end{beamercolorbox} -} -\setbeamertemplate{section page}{ - \centering - \begin{beamercolorbox}[sep=12pt,center]{part title} - \usebeamerfont{section title}\insertsection\par - \end{beamercolorbox} -} -\setbeamertemplate{subsection page}{ - \centering - \begin{beamercolorbox}[sep=8pt,center]{part title} - \usebeamerfont{subsection title}\insertsubsection\par - \end{beamercolorbox} -} -\AtBeginPart{ - \frame{\partpage} -} -\AtBeginSection{ - \ifbibliography - \else - \frame{\sectionpage} - \fi -} -\AtBeginSubsection{ - \frame{\subsectionpage} -} -$endif$ -$endif$ -$if(beamerarticle)$ -\usepackage{beamerarticle} % needs to be loaded first -$endif$ -$if(fontfamily)$ -\usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$} -$else$ -\usepackage{lmodern} -$endif$ -$if(linestretch)$ -\usepackage{setspace} -\setstretch{$linestretch$} -$else$ -\usepackage{setspace} -\setstretch{1.2} -$endif$ -\usepackage{amssymb,amsmath} -\usepackage{ifxetex,ifluatex} -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc} - \usepackage[utf8]{inputenc} - \usepackage{textcomp} % provide euro and other symbols -\else % if luatex or xetex -$if(mathspec)$ - \ifxetex - \usepackage{mathspec} - \else - \usepackage{unicode-math} - \fi -$else$ - \usepackage{unicode-math} -$endif$ - \defaultfontfeatures{Scale=MatchLowercase} - \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} -$if(mainfont)$ - \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$} -$endif$ -$if(sansfont)$ - \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$} -$endif$ -$if(monofont)$ - \setmonofont[$for(monofontoptions)$$monofontoptions$$sep$,$endfor$]{$monofont$} -$endif$ -$for(fontfamilies)$ - \newfontfamily{$fontfamilies.name$}[$for(fontfamilies.options)$$fontfamilies.options$$sep$,$endfor$]{$fontfamilies.font$} -$endfor$ -$if(mathfont)$ -$if(mathspec)$ - \ifxetex - \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} - \else - \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} - \fi -$else$ - \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} -$endif$ -$endif$ -$if(CJKmainfont)$ - \ifxetex - \usepackage{xeCJK} - \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} - \fi -$endif$ -$if(luatexjapresetoptions)$ - \ifluatex - \usepackage[$for(luatexjapresetoptions)$$luatexjapresetoptions$$sep$,$endfor$]{luatexja-preset} - \fi -$endif$ -$if(CJKmainfont)$ - \ifluatex - \usepackage[$for(luatexjafontspecoptions)$$luatexjafontspecoptions$$sep$,$endfor$]{luatexja-fontspec} - \setmainjfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} - \fi -$endif$ -\fi -$if(beamer)$ -$if(theme)$ -\usetheme[$for(themeoptions)$$themeoptions$$sep$,$endfor$]{$theme$} -$endif$ -$if(colortheme)$ -\usecolortheme{$colortheme$} -$endif$ -$if(fonttheme)$ -\usefonttheme{$fonttheme$} -$endif$ -$if(mainfont)$ -\usefonttheme{serif} % use mainfont rather than sansfont for slide text -$endif$ -$if(innertheme)$ -\useinnertheme{$innertheme$} -$endif$ -$if(outertheme)$ -\useoutertheme{$outertheme$} -$endif$ -$endif$ -% Use upquote if available, for straight quotes in verbatim environments -\IfFileExists{upquote.sty}{\usepackage{upquote}}{} -\IfFileExists{microtype.sty}{% use microtype if available - \usepackage[$for(microtypeoptions)$$microtypeoptions$$sep$,$endfor$]{microtype} - \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts -}{} -$if(indent)$ -$else$ -\makeatletter -\@ifundefined{KOMAClassName}{% if non-KOMA class - \IfFileExists{parskip.sty}{% - \usepackage{parskip} - }{% else - \setlength{\parindent}{0pt} - \setlength{\parskip}{6pt plus 2pt minus 1pt}} -}{% if KOMA class - \KOMAoptions{parskip=half}} -\makeatother -$endif$ -$if(verbatim-in-note)$ -\usepackage{fancyvrb} -$endif$ -\usepackage{xcolor} -\definecolor{default-linkcolor}{HTML}{A50000} -\definecolor{default-filecolor}{HTML}{A50000} -\definecolor{default-citecolor}{HTML}{4077C0} -\definecolor{default-urlcolor}{HTML}{4077C0} -\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available -$if(footnotes-pretty)$ -% load footmisc in order to customize footnotes (footmisc has to be loaded before hyperref, cf. https://tex.stackexchange.com/a/169124/144087) -\usepackage[hang,flushmargin,bottom,multiple]{footmisc} -\setlength{\footnotemargin}{0.8em} % set space between footnote nr and text -\setlength{\footnotesep}{\baselineskip} % set space between multiple footnotes -\setlength{\skip\footins}{0.3cm} % set space between page content and footnote -\setlength{\footskip}{0.9cm} % set space between footnote and page bottom -$endif$ -\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} -\hypersetup{ -$if(title-meta)$ - pdftitle={$title-meta$}, -$endif$ -$if(author-meta)$ - pdfauthor={$author-meta$}, -$endif$ -$if(lang)$ - pdflang={$lang$}, -$endif$ -$if(subject)$ - pdfsubject={$subject$}, -$endif$ -$if(keywords)$ - pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$}, -$endif$ -$if(colorlinks)$ - colorlinks=true, - linkcolor=$if(linkcolor)$$linkcolor$$else$default-linkcolor$endif$, - filecolor=$if(filecolor)$$filecolor$$else$default-filecolor$endif$, - citecolor=$if(citecolor)$$citecolor$$else$default-citecolor$endif$, - urlcolor=$if(urlcolor)$$urlcolor$$else$default-urlcolor$endif$, -$else$ - hidelinks, -$endif$ - breaklinks=true, - pdfcreator={LaTeX via pandoc with the Eisvogel template}} -\urlstyle{same} % disable monospaced font for URLs -$if(verbatim-in-note)$ -\VerbatimFootnotes % allow verbatim text in footnotes -$endif$ -$if(geometry)$ -$if(beamer)$ -\geometry{$for(geometry)$$geometry$$sep$,$endfor$} -$else$ -\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} -$endif$ -$else$ -$if(beamer)$ -$else$ -\usepackage[margin=2.5cm,includehead=true,includefoot=true,centering,$for(geometry)$$geometry$$sep$,$endfor$]{geometry} -$endif$ -$endif$ -$if(logo)$ -\usepackage[export]{adjustbox} -\usepackage{graphicx} -$endif$ -$if(beamer)$ -\newif\ifbibliography -$endif$ -$if(listings)$ -\usepackage{listings} -\newcommand{\passthrough}[1]{#1} -\lstset{defaultdialect=[5.3]Lua} -\lstset{defaultdialect=[x86masm]Assembler} -$endif$ -$if(listings-no-page-break)$ -\usepackage{etoolbox} -\BeforeBeginEnvironment{lstlisting}{\par\noindent\begin{minipage}{\linewidth}} -\AfterEndEnvironment{lstlisting}{\end{minipage}\par\addvspace{\topskip}} -$endif$ -$if(lhs)$ -\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} -$endif$ -$if(highlighting-macros)$ -$highlighting-macros$ - -% Workaround/bugfix from jannick0. -% See https://github.com/jgm/pandoc/issues/4302#issuecomment-360669013) -% or https://github.com/Wandmalfarbe/pandoc-latex-template/issues/2 -% -% Redefine the verbatim environment 'Highlighting' to break long lines (with -% the help of fvextra). Redefinition is necessary because it is unlikely that -% pandoc includes fvextra in the default template. -\usepackage{fvextra} -\DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines,fontsize=$if(code-block-font-size)$$code-block-font-size$$else$\small$endif$,commandchars=\\\{\}} - -$endif$ -$if(tables)$ -\usepackage{longtable,booktabs} -$if(beamer)$ -\usepackage{caption} -% Make caption package work with longtable -\makeatletter -\def\fnum@table{\tablename~\thetable} -\makeatother -$else$ -% Correct order of tables after \paragraph or \subparagraph -\usepackage{etoolbox} -\makeatletter -\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} -\makeatother -% Allow footnotes in longtable head/foot -\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} -\makesavenoteenv{longtable} -$endif$ -$endif$ -% add backlinks to footnote references, cf. https://tex.stackexchange.com/questions/302266/make-footnote-clickable-both-ways -$if(footnotes-disable-backlinks)$ -$else$ -\usepackage{footnotebackref} -$endif$ -$if(graphics)$ -\usepackage{graphicx} -\makeatletter -\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} -\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} -\makeatother -% Scale images if necessary, so that they will not overflow the page -% margins by default, and it is still possible to overwrite the defaults -% using explicit options in \includegraphics[width, height, ...]{} -\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} -$endif$ -$if(links-as-notes)$ -% Make links footnotes instead of hotlinks: -\DeclareRobustCommand{\href}[2]{#2\footnote{\url{#1}}} -$endif$ -$if(strikeout)$ -\usepackage[normalem]{ulem} -% Avoid problems with \sout in headers with hyperref -\pdfstringdefDisableCommands{\renewcommand{\sout}{}} -$endif$ -\setlength{\emergencystretch}{3em} % prevent overfull lines -\providecommand{\tightlist}{% - \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} -$if(numbersections)$ -\setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$3$endif$} -$else$ -\setcounter{secnumdepth}{-\maxdimen} % remove section numbering -$endif$ -$if(beamer)$ -$else$ -$if(block-headings)$ -% Make \paragraph and \subparagraph free-standing -\ifx\paragraph\undefined\else - \let\oldparagraph\paragraph - \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}} -\fi -\ifx\subparagraph\undefined\else - \let\oldsubparagraph\subparagraph - \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}} -\fi -$endif$ -$endif$ -$if(pagestyle)$ -\pagestyle{$pagestyle$} -$endif$ - -% Make use of float-package and set default placement for figures to H. -% The option H means 'PUT IT HERE' (as opposed to the standard h option which means 'You may put it here if you like'). -\usepackage{float} -\floatplacement{figure}{$if(float-placement-figure)$$float-placement-figure$$else$H$endif$} - -$for(header-includes)$ -$header-includes$ -$endfor$ -$if(lang)$ -\ifxetex - $if(mainfont)$ - $else$ - % See issue https://github.com/reutenauer/polyglossia/issues/127 - \renewcommand*\familydefault{\sfdefault} - $endif$ - % Load polyglossia as late as possible: uses bidi with RTL langages (e.g. Hebrew, Arabic) - \usepackage{polyglossia} - \setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$} -$for(polyglossia-otherlangs)$ - \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$} -$endfor$ -\else - \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} -$if(babel-newcommands)$ - $babel-newcommands$ -$endif$ -\fi -$endif$ -$if(dir)$ -\ifxetex - % Load bidi as late as possible as it modifies e.g. graphicx - \usepackage{bidi} -\fi -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \TeXXeTstate=1 - \newcommand{\RL}[1]{\beginR #1\endR} - \newcommand{\LR}[1]{\beginL #1\endL} - \newenvironment{RTL}{\beginR}{\endR} - \newenvironment{LTR}{\beginL}{\endL} -\fi -$endif$ -$if(natbib)$ -\usepackage[$natbiboptions$]{natbib} -\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$} -$endif$ -$if(biblatex)$ -\usepackage[$if(biblio-style)$style=$biblio-style$,$endif$$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$]{biblatex} -$for(bibliography)$ -\addbibresource{$bibliography$} -$endfor$ -$endif$ -$if(csl-refs)$ -\newlength{\cslhangindent} -\setlength{\cslhangindent}{1.5em} -\newenvironment{cslreferences}% - {$if(csl-hanging-indent)$\setlength{\parindent}{0pt}% - \everypar{\setlength{\hangindent}{\cslhangindent}}\ignorespaces$endif$}% - {\par} -$endif$ - -$if(title)$ -\title{$title$$if(thanks)$\thanks{$thanks$}$endif$} -$endif$ -$if(subtitle)$ -$if(beamer)$ -$else$ -\usepackage{etoolbox} -\makeatletter -\providecommand{\subtitle}[1]{% add subtitle to \maketitle - \apptocmd{\@title}{\par {\large #1 \par}}{}{} -} -\makeatother -$endif$ -\subtitle{$subtitle$} -$endif$ -$if(author)$ -\author{$for(author)$$author$$sep$ \and $endfor$} -$endif$ -\date{$date$} -$if(beamer)$ -$if(institute)$ -\institute{$for(institute)$$institute$$sep$ \and $endfor$} -$endif$ -$if(titlegraphic)$ -\titlegraphic{\includegraphics{$titlegraphic$}} -$endif$ -$if(logo)$ -\logo{\includegraphics{$logo$}} -$endif$ -$endif$ - - - -%% -%% added -%% - -% -% language specification -% -% If no language is specified, use English as the default main document language. -% -$if(lang)$$else$ -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=english]{babel} -$if(babel-newcommands)$ - $babel-newcommands$ -$endif$ -\else - $if(mainfont)$ - $else$ - % Workaround for bug in Polyglossia that breaks `\familydefault` when `\setmainlanguage` is used. - % See https://github.com/Wandmalfarbe/pandoc-latex-template/issues/8 - % See https://github.com/reutenauer/polyglossia/issues/186 - % See https://github.com/reutenauer/polyglossia/issues/127 - \renewcommand*\familydefault{\sfdefault} - $endif$ - % load polyglossia as late as possible as it *could* call bidi if RTL lang (e.g. Hebrew or Arabic) - \usepackage{polyglossia} - \setmainlanguage[]{english} -$for(polyglossia-otherlangs)$ - \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$} -$endfor$ -\fi -$endif$ - -$if(page-background)$ -\usepackage[pages=all]{background} -$endif$ - -% -% for the background color of the title page -% -$if(titlepage)$ -\usepackage{pagecolor} -\usepackage{afterpage} -$if(titlepage-background)$ -\usepackage{tikz} -$endif$ -$if(geometry)$ -$else$ -\usepackage[margin=2.5cm,includehead=true,includefoot=true,centering]{geometry} -$endif$ -$endif$ - -% -% break urls -% -\PassOptionsToPackage{hyphens}{url} - -% -% When using babel or polyglossia with biblatex, loading csquotes is recommended -% to ensure that quoted texts are typeset according to the rules of your main language. -% -\usepackage{csquotes} - -% -% captions -% -\definecolor{caption-color}{HTML}{777777} -$if(beamer)$ -$else$ -\usepackage[font={stretch=1.2}, textfont={color=caption-color}, position=top, skip=4mm, labelfont=bf, singlelinecheck=false, justification=$if(caption-justification)$$caption-justification$$else$raggedright$endif$]{caption} -\setcapindent{0em} -$endif$ - -% -% blockquote -% -\definecolor{blockquote-border}{RGB}{221,221,221} -\definecolor{blockquote-text}{RGB}{119,119,119} -\usepackage{mdframed} -\newmdenv[rightline=false,bottomline=false,topline=false,linewidth=3pt,linecolor=blockquote-border,skipabove=\parskip]{customblockquote} -\renewenvironment{quote}{\begin{customblockquote}\list{}{\rightmargin=0em\leftmargin=0em}% -\item\relax\color{blockquote-text}\ignorespaces}{\unskip\unskip\endlist\end{customblockquote}} - -% -% Source Sans Pro as the de­fault font fam­ily -% Source Code Pro for monospace text -% -% 'default' option sets the default -% font family to Source Sans Pro, not \sfdefault. -% -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - $if(fontfamily)$ - $else$ - \usepackage[default]{sourcesanspro} - \usepackage{sourcecodepro} - $endif$ -\else % if not pdftex - $if(mainfont)$ - $else$ - \usepackage[default]{sourcesanspro} - \usepackage{sourcecodepro} - - % XeLaTeX specific adjustments for straight quotes: https://tex.stackexchange.com/a/354887 - % This issue is already fixed (see https://github.com/silkeh/latex-sourcecodepro/pull/5) but the - % fix is still unreleased. - % TODO: Remove this workaround when the new version of sourcecodepro is released on CTAN. - \ifxetex - \makeatletter - \defaultfontfeatures[\ttfamily] - { Numbers = \sourcecodepro@figurestyle, - Scale = \SourceCodePro@scale, - Extension = .otf } - \setmonofont - [ UprightFont = *-\sourcecodepro@regstyle, - ItalicFont = *-\sourcecodepro@regstyle It, - BoldFont = *-\sourcecodepro@boldstyle, - BoldItalicFont = *-\sourcecodepro@boldstyle It ] - {SourceCodePro} - \makeatother - \fi - $endif$ -\fi - -% -% heading color -% -\definecolor{heading-color}{RGB}{40,40,40} -$if(beamer)$ -$else$ -\addtokomafont{section}{\color{heading-color}} -$endif$ -% When using the classes report, scrreprt, book, -% scrbook or memoir, uncomment the following line. -%\addtokomafont{chapter}{\color{heading-color}} - -% -% variables for title and author -% -$if(beamer)$ -$else$ -\usepackage{titling} -\title{$title$} -\author{$for(author)$$author$$sep$, $endfor$} -$endif$ - -% -% tables -% -$if(tables)$ - -\definecolor{table-row-color}{HTML}{F5F5F5} -\definecolor{table-rule-color}{HTML}{999999} - -%\arrayrulecolor{black!40} -\arrayrulecolor{table-rule-color} % color of \toprule, \midrule, \bottomrule -\setlength\heavyrulewidth{0.3ex} % thickness of \toprule, \bottomrule -\renewcommand{\arraystretch}{1.3} % spacing (padding) - -$if(table-use-row-colors)$ -% TODO: This doesn't work anymore. I don't know why. -% Reset rownum counter so that each table -% starts with the same row colors. -% https://tex.stackexchange.com/questions/170637/restarting-rowcolors -% -% Unfortunately the colored cells extend beyond the edge of the -% table because pandoc uses @-expressions (@{}) like so: -% -% \begin{longtable}[]{@{}ll@{}} -% \end{longtable} -% -% https://en.wikibooks.org/wiki/LaTeX/Tables#.40-expressions -\let\oldlongtable\longtable -\let\endoldlongtable\endlongtable -\renewenvironment{longtable}{ -\rowcolors{3}{}{table-row-color!100} % row color -\oldlongtable} { -\endoldlongtable -\global\rownum=0\relax} -$endif$ -$endif$ - -% -% remove paragraph indention -% -\setlength{\parindent}{0pt} -\setlength{\parskip}{6pt plus 2pt minus 1pt} -\setlength{\emergencystretch}{3em} % prevent overfull lines - -% -% -% Listings -% -% - -$if(listings)$ - -% -% general listing colors -% -\definecolor{listing-background}{HTML}{F7F7F7} -\definecolor{listing-rule}{HTML}{B3B2B3} -\definecolor{listing-numbers}{HTML}{B3B2B3} -\definecolor{listing-text-color}{HTML}{000000} -\definecolor{listing-keyword}{HTML}{435489} -\definecolor{listing-keyword-2}{HTML}{1284CA} % additional keywords -\definecolor{listing-keyword-3}{HTML}{9137CB} % additional keywords -\definecolor{listing-identifier}{HTML}{435489} -\definecolor{listing-string}{HTML}{00999A} -\definecolor{listing-comment}{HTML}{8E8E8E} - -\lstdefinestyle{eisvogel_listing_style}{ - language = java, -$if(listings-disable-line-numbers)$ - xleftmargin = 0.6em, - framexleftmargin = 0.4em, -$else$ - numbers = left, - xleftmargin = 2.7em, - framexleftmargin = 2.5em, -$endif$ - backgroundcolor = \color{listing-background}, - basicstyle = \color{listing-text-color}\linespread{1.0}$if(code-block-font-size)$$code-block-font-size$$else$\small$endif$\ttfamily{}, - breaklines = true, - frame = single, - framesep = 0.19em, - rulecolor = \color{listing-rule}, - frameround = ffff, - tabsize = 4, - numberstyle = \color{listing-numbers}, - aboveskip = 1.0em, - belowskip = 0.1em, - abovecaptionskip = 0em, - belowcaptionskip = 1.0em, - keywordstyle = {\color{listing-keyword}\bfseries}, - keywordstyle = {[2]\color{listing-keyword-2}\bfseries}, - keywordstyle = {[3]\color{listing-keyword-3}\bfseries\itshape}, - sensitive = true, - identifierstyle = \color{listing-identifier}, - commentstyle = \color{listing-comment}, - stringstyle = \color{listing-string}, - showstringspaces = false, - escapeinside = {/*@}{@*/}, % Allow LaTeX inside these special comments - literate = - {á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1 - {Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1 - {à}{{\`a}}1 {è}{{\'e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1 - {À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1 - {ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1 - {Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1 - {â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1 - {Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1 - {œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1 - {ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1 - {€}{{\EUR}}1 {£}{{\pounds}}1 {«}{{\guillemotleft}}1 - {»}{{\guillemotright}}1 {ñ}{{\~n}}1 {Ñ}{{\~N}}1 {¿}{{?`}}1 - {…}{{\ldots}}1 {≥}{{>=}}1 {≤}{{<=}}1 {„}{{\glqq}}1 {“}{{\grqq}}1 - {”}{{''}}1 -} -\lstset{style=eisvogel_listing_style} - -% -% Java (Java SE 12, 2019-06-22) -% -\lstdefinelanguage{Java}{ - morekeywords={ - % normal keywords (without data types) - abstract,assert,break,case,catch,class,continue,default, - do,else,enum,exports,extends,final,finally,for,if,implements, - import,instanceof,interface,module,native,new,package,private, - protected,public,requires,return,static,strictfp,super,switch, - synchronized,this,throw,throws,transient,try,volatile,while, - % var is an identifier - var - }, - morekeywords={[2] % data types - % primitive data types - boolean,byte,char,double,float,int,long,short, - % String - String, - % primitive wrapper types - Boolean,Byte,Character,Double,Float,Integer,Long,Short - % number types - Number,AtomicInteger,AtomicLong,BigDecimal,BigInteger,DoubleAccumulator,DoubleAdder,LongAccumulator,LongAdder,Short, - % other - Object,Void,void - }, - morekeywords={[3] % literals - % reserved words for literal values - null,true,false, - }, - sensitive, - morecomment = [l]//, - morecomment = [s]{/*}{*/}, - morecomment = [s]{/**}{*/}, - morestring = [b]", - morestring = [b]', -} - -\lstdefinelanguage{XML}{ - morestring = [b]", - moredelim = [s][\bfseries\color{listing-keyword}]{<}{\ }, - moredelim = [s][\bfseries\color{listing-keyword}]{}, - moredelim = [l][\bfseries\color{listing-keyword}]{/>}, - moredelim = [l][\bfseries\color{listing-keyword}]{>}, - morecomment = [s]{}, - morecomment = [s]{}, - commentstyle = \color{listing-comment}, - stringstyle = \color{listing-string}, - identifierstyle = \color{listing-identifier} -} -$endif$ - -% -% header and footer -% -$if(beamer)$ -$else$ -$if(disable-header-and-footer)$ -$else$ -\usepackage{fancyhdr} - -\fancypagestyle{eisvogel-header-footer}{ - \fancyhead{} - \fancyfoot{} - \lhead[$if(header-right)$$header-right$$else$$date$$endif$]{$if(header-left)$$header-left$$else$$title$$endif$} - \chead[$if(header-center)$$header-center$$else$$endif$]{$if(header-center)$$header-center$$else$$endif$} - \rhead[$if(header-left)$$header-left$$else$$title$$endif$]{$if(header-right)$$header-right$$else$$date$$endif$} - \lfoot[$if(footer-right)$$footer-right$$else$\thepage$endif$]{$if(footer-left)$$footer-left$$else$$for(author)$$author$$sep$, $endfor$$endif$} - \cfoot[$if(footer-center)$$footer-center$$else$$endif$]{$if(footer-center)$$footer-center$$else$$endif$} - \rfoot[$if(footer-left)$$footer-left$$else$$for(author)$$author$$sep$, $endfor$$endif$]{$if(footer-right)$$footer-right$$else$\thepage$endif$} - \renewcommand{\headrulewidth}{0.4pt} - \renewcommand{\footrulewidth}{0.4pt} -} -\pagestyle{eisvogel-header-footer} -$if(page-background)$ -\backgroundsetup{ -scale=1, -color=black, -opacity=$if(page-background-opacity)$$page-background-opacity$$else$0.2$endif$, -angle=0, -contents={% - \includegraphics[width=\paperwidth,height=\paperheight]{$page-background$} - }% -} -$endif$ -$endif$ -$endif$ - -%% -%% end added -%% - -\begin{document} - -%% -%% begin titlepage -%% -$if(beamer)$ -$else$ -$if(titlepage)$ -\begin{titlepage} -$if(titlepage-background)$ -\newgeometry{top=2cm, right=4cm, bottom=3cm, left=4cm} -$else$ -\newgeometry{left=6cm} -$endif$ -$if(titlepage-color)$ -\definecolor{titlepage-color}{HTML}{$titlepage-color$} -\newpagecolor{titlepage-color}\afterpage{\restorepagecolor} -$endif$ -$if(titlepage-background)$ -\tikz[remember picture,overlay] \node[inner sep=0pt] at (current page.center){\includegraphics[width=\paperwidth,height=\paperheight]{$titlepage-background$}}; -$endif$ -\newcommand{\colorRule}[3][black]{\textcolor[HTML]{#1}{\rule{#2}{#3}}} -\begin{flushleft} -\noindent -\\[-1em] -\color[HTML]{$if(titlepage-text-color)$$titlepage-text-color$$else$5F5F5F$endif$} -\makebox[0pt][l]{\colorRule[$if(titlepage-rule-color)$$titlepage-rule-color$$else$435488$endif$]{1.3\textwidth}{$if(titlepage-rule-height)$$titlepage-rule-height$$else$4$endif$pt}} -\par -\noindent - -$if(titlepage-background)$ -% The titlepage with a background image has other text spacing and text size -{ - \setstretch{2} - \vfill - \vskip -8em - \noindent {\huge \textbf{\textsf{$title$}}} - $if(subtitle)$ - \vskip 1em - {\Large \textsf{$subtitle$}} - $endif$ - \vskip 2em - \noindent {\Large \textsf{$for(author)$$author$$sep$, $endfor$} \vskip 0.6em \textsf{$date$}} - \vfill -} -$else$ -{ - \setstretch{1.4} - \vfill - \noindent {\huge \textbf{\textsf{Product: $product$}}} - \newline\newline - \noindent {\huge \textbf{\textsf{Report: $title$}}} - $if(subtitle)$ - \vskip 1em - {\Large \textsf{$subtitle$}} - $endif$ - \vskip 2em - \noindent {\Large \textsf{$for(author)$$author$$sep$, $endfor$}} - \vfill -} -$endif$ - -$if(logo)$ -\noindent -\includegraphics[width=$if(logo-width)$$logo-width$$else$100$endif$pt, left]{$logo$} -$endif$ - -$if(titlepage-background)$ -$else$ -\textsf{$date$} -$endif$ -\end{flushleft} -\end{titlepage} -\restoregeometry -$endif$ -$endif$ - -%% -%% end titlepage -%% - -$if(has-frontmatter)$ -\frontmatter -$endif$ -$if(title)$ -$if(beamer)$ -\frame{\titlepage} -$endif$ -$if(abstract)$ -\begin{abstract} -$abstract$ -\end{abstract} -$endif$ -$endif$ - -$if(first-chapter)$ -\setcounter{chapter}{$first-chapter$} -\addtocounter{chapter}{-1} -$endif$ - -$for(include-before)$ -$include-before$ - -$endfor$ -$if(toc)$ -$if(toc-title)$ -\renewcommand*\contentsname{$toc-title$} -$endif$ -$if(beamer)$ -\begin{frame} -$if(toc-title)$ - \frametitle{$toc-title$} -$endif$ - \tableofcontents[hideallsubsections] -\end{frame} -$if(toc-own-page)$ -\newpage -$endif$ -$else$ -{ -$if(colorlinks)$ -\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$$endif$} -$endif$ -\setcounter{tocdepth}{$if(toc-depth)$$toc-depth$$else$3$endif$} -\tableofcontents -$if(toc-own-page)$ -\newpage -$endif$ -} -$endif$ -$endif$ -$if(lot)$ -\listoftables -$endif$ -$if(lof)$ -\listoffigures -$endif$ -$if(linestretch)$ -\setstretch{$linestretch$} -$endif$ -$if(has-frontmatter)$ -\mainmatter -$endif$ -$body$ - -$if(has-frontmatter)$ -\backmatter -$endif$ -$if(natbib)$ -$if(bibliography)$ -$if(biblio-title)$ -$if(has-chapters)$ -\renewcommand\bibname{$biblio-title$} -$else$ -\renewcommand\refname{$biblio-title$} -$endif$ -$endif$ -$if(beamer)$ -\begin{frame}[allowframebreaks]{$biblio-title$} - \bibliographytrue -$endif$ - \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} -$if(beamer)$ -\end{frame} -$endif$ - -$endif$ -$endif$ -$if(biblatex)$ -$if(beamer)$ -\begin{frame}[allowframebreaks]{$biblio-title$} - \bibliographytrue - \printbibliography[heading=none] -\end{frame} -$else$ -\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ -$endif$ - -$endif$ -$for(include-after)$ -$include-after$ - -$endfor$ -\end{document} diff --git a/app/preport/views.py b/app/preport/views.py index e9df370..b2606d3 100644 --- a/app/preport/views.py +++ b/app/preport/views.py @@ -1152,8 +1152,6 @@ def reportdownloadpdf(request, template, pk): else: template_attackflow_in_finding += ''.join("\\pagebreak") - - # finding pdf_finding = render_to_string(os.path.join(template_pdf_dir, 'pdf_finding.md'), {'finding': finding, 'icon_finding': icon_finding, 'severity_color': severity_color, 'severity_color_finding': severity_color_finding, 'template_appendix_in_finding': template_appendix_in_finding, 'template_attackflow_in_finding': template_attackflow_in_finding, 'template_custom_fields': template_custom_fields}) @@ -1172,7 +1170,6 @@ def reportdownloadpdf(request, template, pk): PDF_HEADER_FILE = os.path.join(template_pdf_dir, 'pdf_header.tex') PETEREPORT_LATEX_FILE = os.path.join(template_pdf_dir, PETEREPORT_TEMPLATES['pdf_latex_template']) - # Remove Unicode characters, not parsed by pdflatex final_markdown_output = final_markdown_output.encode(encoding="utf-8", errors="ignore").decode() @@ -1192,8 +1189,6 @@ def reportdownloadpdf(request, template, pk): '--pdf-engine', PETEREPORT_MARKDOWN['pdf_engine'], '--listings']) - - deliverable = DB_Deliverable(report=DB_report_query, filename=name_file, generation_date=now, filetemplate=template, filetype='pdf') deliverable.save() @@ -1506,7 +1501,7 @@ def downloadfindingscsv(request,pk): csv.register_dialect('MMDialect', quoting=csv.QUOTE_ALL, skipinitialspace=True) with open(csv_file_output, 'w') as fh: writer = csv.writer(fh, dialect='MMDialect') - writer.writerow(["ID", "Status", "Title", "Severity", "CVSS Base Score", "CVSS Score", "CWE", "CWE ID", "OWASP", "OWASP ID", "Description", "POC", "Location", "Impact", "Recommendation", "References", "Appendix", "Appendix Description"]) + writer.writerow(["ID", "Status", "Title", "Severity", "CVSS Vector", "CVSS Score", "CWE", "CWE ID", "OWASP", "OWASP ID", "Description", "POC", "Location", "Impact", "Recommendation", "References", "Appendix", "Appendix Description"]) for finding in DB_finding_query: if finding.cwe: cwe_title = f"CWE-{finding.cwe.cwe_id} - {finding.cwe.cwe_name}" @@ -1544,7 +1539,7 @@ def downloadfindingscsv(request,pk): writer.writerow([finding.finding_id, finding.status, finding_title_encoded, - finding.severity, finding.cvss_base_score, finding.cvss_score, + finding.severity, finding.cvss_vector, finding.cvss_score, cwe_title, cwe_id, owasp_title, owasp_id, finding_description_encoded, @@ -1591,10 +1586,10 @@ def upload_csv_findings(request,pk): f_status = header.index("Status") f_title = header.index("Title") f_severity = header.index("Severity") - f_cvss_score = header.index("CVSS Base Score") + f_cvss_score = header.index("CVSS Vector") f_cvss = header.index("CVSS Score") f_cwe = header.index("CWE ID") - f_owasp = header.index("OWASP ID") + f_owasp_id = header.index("OWASP ID") f_description = header.index("Description") f_location = header.index("Location") f_impact = header.index("Impact") @@ -1613,7 +1608,7 @@ def upload_csv_findings(request,pk): fcvss_score = row[f_cvss_score] fcvss = row[f_cvss] fcwe = row[f_cwe] - fowasp = row[f_owasp] + fowasp = row[f_owasp_id] fdescription = row[f_description] flocation = row[f_location] fimpact = row[f_impact] @@ -1625,10 +1620,10 @@ def upload_csv_findings(request,pk): List.append([fid,ftitle,fstatus,fseverity,fcvss_score,fcvss,fcwe,fowasp,fdescription,flocation,fimpact,frecommendation,fref,fappendix,fappendixdescription]) DB_cwe = get_object_or_404(DB_CWE, cwe_id=fcwe) - DB_owasp = get_object_or_404(DB_OWASP, owasp_id=fowasp) + DB_owasp = get_object_or_404(DB_OWASP, owasp_full_id=fowasp) # Save finding - finding_to_DB = DB_Finding(report=DB_report_query, finding_id=fid, title=ftitle, status=fstatus, severity=fseverity, cvss_base_score=fcvss_score, cvss_score=fcvss, description=fdescription, location=flocation, impact=fimpact, recommendation=frecommendation, references=fref, cwe=DB_cwe, owasp=DB_owasp) + finding_to_DB = DB_Finding(report=DB_report_query, finding_id=fid, title=ftitle, status=fstatus, severity=fseverity, cvss_vector=fcvss_score, cvss_score=fcvss, description=fdescription, location=flocation, impact=fimpact, recommendation=frecommendation, references=fref, cwe=DB_cwe, owasp=DB_owasp) finding_to_DB.save() # Save appendix @@ -1759,7 +1754,7 @@ def defectdojo_import(request,pk,ddpk): cweDB = DB_CWE.objects.filter(cwe_id=finding_cwe).first() or DB_CWE.objects.filter(cwe_id=0).first() #Save Finding - finding_to_DB = DB_Finding(report=DB_report_query, finding_id=finding_hash_code, status = 'Open', title=finding_title, severity=finding_severity, cvss_base_score=finding_cvssv3, cvss_score=finding_cvssv3_score, description=finding_final_description, location=finding_file_path, impact=finding_impact, recommendation=finding_mitigation, references=finding_references, cwe=cweDB) + finding_to_DB = DB_Finding(report=DB_report_query, finding_id=finding_hash_code, status = 'Open', title=finding_title, severity=finding_severity, cvss_vector=finding_cvssv3, cvss_score=finding_cvssv3_score, description=finding_final_description, location=finding_file_path, impact=finding_impact, recommendation=finding_mitigation, references=finding_references, cwe=cweDB) finding_to_DB.save() return redirect('report_view', pk=pk) @@ -1804,7 +1799,7 @@ def defectdojo_import_finding(request,pk,ddpk): cweDB = DB_CWE.objects.filter(cwe_id=finding_cwe).first() or DB_CWE.objects.filter(cwe_id=0).first() #Save Finding - finding_to_DB = DB_Finding(report=DB_report_query, finding_id=finding_hash_code, status = 'Open', title=finding_title, severity=finding_severity, cvss_base_score=finding_cvssv3, cvss_score=finding_cvssv3_score, description=finding_final_description, location=finding_file_path, impact=finding_impact, recommendation=finding_mitigation, references=finding_references, cwe=cweDB) + finding_to_DB = DB_Finding(report=DB_report_query, finding_id=finding_hash_code, status = 'Open', title=finding_title, severity=finding_severity, cvss_vector=finding_cvssv3, cvss_score=finding_cvssv3_score, description=finding_final_description, location=finding_file_path, impact=finding_impact, recommendation=finding_mitigation, references=finding_references, cwe=cweDB) finding_to_DB.save() return redirect('report_view', pk=pk) @@ -2122,7 +2117,7 @@ def templateaddreport(request,pk,reportpk): # save template in DB finding_uuid = uuid.uuid4() finding_status = "Open" - finding_to_DB = DB_Finding(report=DB_report_query, finding_id=finding_uuid, title=DB_finding_template_query.title, severity=DB_finding_template_query.severity, cvss_base_score=DB_finding_template_query.cvss_base_score, cvss_score=DB_finding_template_query.cvss_score, description=DB_finding_template_query.description, status=finding_status, location=DB_finding_template_query.location, impact=DB_finding_template_query.impact, recommendation=DB_finding_template_query.recommendation, references=DB_finding_template_query.references, cwe=DB_finding_template_query.cwe, owasp=DB_finding_template_query.owasp) + finding_to_DB = DB_Finding(report=DB_report_query, finding_id=finding_uuid, title=DB_finding_template_query.title, severity=DB_finding_template_query.severity, cvss_vector=DB_finding_template_query.cvss_vector, cvss_score=DB_finding_template_query.cvss_score, description=DB_finding_template_query.description, status=finding_status, location=DB_finding_template_query.location, impact=DB_finding_template_query.impact, recommendation=DB_finding_template_query.recommendation, references=DB_finding_template_query.references, cwe=DB_finding_template_query.cwe, owasp=DB_finding_template_query.owasp) finding_to_DB.save() diff --git a/licenses/cvss4_calculator b/licenses/cvss4_calculator new file mode 100644 index 0000000..2414303 --- /dev/null +++ b/licenses/cvss4_calculator @@ -0,0 +1,22 @@ +Copyright (c) 2023 FIRST.ORG, Inc., Red Hat, and contributors + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
#{% translate "Finding" %}{% translate "Severity" %}