mirror of
https://github.com/pi-hole/web.git
synced 2025-12-24 04:38:28 +00:00
@@ -7,7 +7,7 @@
|
||||
|
||||
/* global moment:false, apiFailure: false, updateFtlInfo: false, NProgress:false, WaitMe:false */
|
||||
|
||||
$(function () {
|
||||
$(() => {
|
||||
// CSRF protection for AJAX requests, this has to be configured globally
|
||||
// because we are using the jQuery $.ajax() function directly in some cases
|
||||
// Furthermore, has this to be done before any AJAX request is made so that
|
||||
@@ -19,7 +19,7 @@ $(function () {
|
||||
|
||||
// Credit: https://stackoverflow.com/a/4835406
|
||||
function escapeHtml(text) {
|
||||
var map = {
|
||||
const map = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
@@ -30,13 +30,13 @@ function escapeHtml(text) {
|
||||
// Return early when text is not a string
|
||||
if (typeof text !== "string") return text;
|
||||
|
||||
return text.replaceAll(/[&<>"']/g, function (m) {
|
||||
return text.replaceAll(/[&<>"']/g, m => {
|
||||
return map[m];
|
||||
});
|
||||
}
|
||||
|
||||
function unescapeHtml(text) {
|
||||
var map = {
|
||||
const map = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
@@ -53,27 +53,24 @@ function unescapeHtml(text) {
|
||||
|
||||
if (text === null) return null;
|
||||
|
||||
return text.replaceAll(
|
||||
/&(?:amp|lt|gt|quot|#039|Uuml|uuml|Auml|auml|Ouml|ouml|szlig);/g,
|
||||
function (m) {
|
||||
return map[m];
|
||||
}
|
||||
);
|
||||
return text.replaceAll(/&(?:amp|lt|gt|quot|#039|Uuml|uuml|Auml|auml|Ouml|ouml|szlig);/g, m => {
|
||||
return map[m];
|
||||
});
|
||||
}
|
||||
|
||||
// Helper function for converting Objects to Arrays after sorting the keys
|
||||
function objectToArray(obj) {
|
||||
var arr = [];
|
||||
var idx = [];
|
||||
var keys = Object.keys(obj);
|
||||
const arr = [];
|
||||
const idx = [];
|
||||
const keys = Object.keys(obj);
|
||||
|
||||
keys.sort(function (a, b) {
|
||||
keys.sort((a, b) => {
|
||||
return a - b;
|
||||
});
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
arr.push(obj[keys[i]]);
|
||||
idx.push(keys[i]);
|
||||
for (const key of keys) {
|
||||
arr.push(obj[key]);
|
||||
idx.push(key);
|
||||
}
|
||||
|
||||
return [idx, arr];
|
||||
@@ -83,22 +80,22 @@ function padNumber(num) {
|
||||
return ("00" + num).substr(-2, 2);
|
||||
}
|
||||
|
||||
var showAlertBox = null;
|
||||
let showAlertBox = null;
|
||||
function showAlert(type, icon, title, message, toast) {
|
||||
const options = {
|
||||
title: " <strong>" + escapeHtml(title) + "</strong><br>",
|
||||
message: escapeHtml(message),
|
||||
icon: icon,
|
||||
title: " <strong>" + escapeHtml(title) + "</strong><br>",
|
||||
message: escapeHtml(message),
|
||||
icon,
|
||||
};
|
||||
const settings = {
|
||||
type,
|
||||
delay: 5000, // default value
|
||||
mouse_over: "pause",
|
||||
animate: {
|
||||
enter: "animate__animated animate__fadeInDown",
|
||||
exit: "animate__animated animate__fadeOutUp",
|
||||
},
|
||||
settings = {
|
||||
type: type,
|
||||
delay: 5000, // default value
|
||||
mouse_over: "pause",
|
||||
animate: {
|
||||
enter: "animate__animated animate__fadeInDown",
|
||||
exit: "animate__animated animate__fadeOutUp",
|
||||
},
|
||||
};
|
||||
};
|
||||
switch (type) {
|
||||
case "info":
|
||||
options.icon = icon !== null && icon.length > 0 ? icon : "fas fa-clock";
|
||||
@@ -120,7 +117,7 @@ function showAlert(type, icon, title, message, toast) {
|
||||
// If the message is an API object, nicely format the error message
|
||||
// Try to parse message as JSON
|
||||
try {
|
||||
var data = JSON.parse(message);
|
||||
const data = JSON.parse(message);
|
||||
console.log(data); // eslint-disable-line no-console
|
||||
if (data.error !== undefined) {
|
||||
options.title = " <strong>" + escapeHtml(data.error.message) + "</strong><br>";
|
||||
@@ -143,24 +140,28 @@ function showAlert(type, icon, title, message, toast) {
|
||||
// Create a new notification for info boxes
|
||||
showAlertBox = $.notify(options, settings);
|
||||
return showAlertBox;
|
||||
} else if (showAlertBox !== null) {
|
||||
}
|
||||
|
||||
if (showAlertBox !== null) {
|
||||
// Update existing notification for other boxes (if available)
|
||||
showAlertBox.update(options);
|
||||
showAlertBox.update(settings);
|
||||
return showAlertBox;
|
||||
} else {
|
||||
// Create a new notification for other boxes if no previous info box exists
|
||||
return $.notify(options, settings);
|
||||
}
|
||||
} else if (toast === null) {
|
||||
|
||||
// Create a new notification for other boxes if no previous info box exists
|
||||
return $.notify(options, settings);
|
||||
}
|
||||
|
||||
if (toast === null) {
|
||||
// Always create a new toast
|
||||
return $.notify(options, settings);
|
||||
} else {
|
||||
// Update existing toast
|
||||
toast.update(options);
|
||||
toast.update(settings);
|
||||
return toast;
|
||||
}
|
||||
|
||||
// Update existing toast
|
||||
toast.update(options);
|
||||
toast.update(settings);
|
||||
return toast;
|
||||
}
|
||||
|
||||
function datetime(date, html, humanReadable) {
|
||||
@@ -168,8 +169,9 @@ function datetime(date, html, humanReadable) {
|
||||
return "Never";
|
||||
}
|
||||
|
||||
var format = html === false ? "Y-MM-DD HH:mm:ss z" : "Y-MM-DD [<br class='hidden-lg'>]HH:mm:ss z";
|
||||
var timestr = moment.unix(Math.floor(date)).format(format).trim();
|
||||
const format =
|
||||
html === false ? "Y-MM-DD HH:mm:ss z" : "Y-MM-DD [<br class='hidden-lg'>]HH:mm:ss z";
|
||||
const timestr = moment.unix(Math.floor(date)).format(format).trim();
|
||||
return humanReadable
|
||||
? '<span title="' + timestr + '">' + moment.unix(Math.floor(date)).fromNow() + "</span>"
|
||||
: timestr;
|
||||
@@ -193,7 +195,7 @@ function enableAll() {
|
||||
$("textarea").prop("disabled", false);
|
||||
|
||||
// Enable custom input field only if applicable
|
||||
var ip = $("#select") ? $("#select").val() : null;
|
||||
const ip = $("#select") ? $("#select").val() : null;
|
||||
if (ip !== null && ip !== "custom") {
|
||||
$("#ip-custom").prop("disabled", true);
|
||||
}
|
||||
@@ -202,10 +204,10 @@ function enableAll() {
|
||||
// Pi-hole IPv4/CIDR validator by DL6ER, see regexr.com/50csh
|
||||
function validateIPv4CIDR(ip) {
|
||||
// One IPv4 element is 8bit: 0 - 256
|
||||
var ipv4elem = "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)";
|
||||
const ipv4elem = "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)";
|
||||
// CIDR for IPv4 is 1 - 32 bit
|
||||
var v4cidr = "(\\/([1-9]|[1-2][0-9]|3[0-2])){0,1}";
|
||||
var ipv4validator = new RegExp(
|
||||
const v4cidr = "(\\/([1-9]|[1-2][0-9]|3[0-2])){0,1}";
|
||||
const ipv4validator = new RegExp(
|
||||
"^" + ipv4elem + "\\." + ipv4elem + "\\." + ipv4elem + "\\." + ipv4elem + v4cidr + "$"
|
||||
);
|
||||
return ipv4validator.test(ip);
|
||||
@@ -214,10 +216,10 @@ function validateIPv4CIDR(ip) {
|
||||
// Pi-hole IPv6/CIDR validator by DL6ER, see regexr.com/50csn
|
||||
function validateIPv6CIDR(ip) {
|
||||
// One IPv6 element is 16bit: 0000 - FFFF
|
||||
var ipv6elem = "[0-9A-Fa-f]{1,4}";
|
||||
const ipv6elem = "[0-9A-Fa-f]{1,4}";
|
||||
// CIDR for IPv6 is 1- 128 bit
|
||||
var v6cidr = "(\\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])){0,1}";
|
||||
var ipv6validator = new RegExp(
|
||||
const v6cidr = "(\\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])){0,1}";
|
||||
const ipv6validator = new RegExp(
|
||||
"^(((?:" +
|
||||
ipv6elem +
|
||||
"))*((?::" +
|
||||
@@ -238,18 +240,18 @@ function validateIPv6CIDR(ip) {
|
||||
}
|
||||
|
||||
function validateMAC(mac) {
|
||||
var macvalidator = /^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$/;
|
||||
const macvalidator = /^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$/;
|
||||
return macvalidator.test(mac);
|
||||
}
|
||||
|
||||
function validateHostname(name) {
|
||||
var namevalidator = /[^<>;"]/;
|
||||
const namevalidator = /[^<>;"]/;
|
||||
return namevalidator.test(name);
|
||||
}
|
||||
|
||||
// set bootstrap-select defaults
|
||||
function setBsSelectDefaults() {
|
||||
var bsSelectDefaults = $.fn.selectpicker.Constructor.DEFAULTS;
|
||||
const bsSelectDefaults = $.fn.selectpicker.Constructor.DEFAULTS;
|
||||
bsSelectDefaults.noneSelectedText = "none selected";
|
||||
bsSelectDefaults.selectedTextFormat = "count > 1";
|
||||
bsSelectDefaults.actionsBox = true;
|
||||
@@ -267,7 +269,7 @@ function setBsSelectDefaults() {
|
||||
};
|
||||
}
|
||||
|
||||
var backupStorage = {};
|
||||
const backupStorage = {};
|
||||
function stateSaveCallback(itemName, data) {
|
||||
if (localStorage === null) {
|
||||
backupStorage[itemName] = JSON.stringify(data);
|
||||
@@ -277,10 +279,10 @@ function stateSaveCallback(itemName, data) {
|
||||
}
|
||||
|
||||
function stateLoadCallback(itemName) {
|
||||
var data;
|
||||
let data;
|
||||
// Receive previous state from client's local storage area
|
||||
if (localStorage === null) {
|
||||
var item = backupStorage[itemName];
|
||||
const item = backupStorage[itemName];
|
||||
data = item === "undefined" ? null : item;
|
||||
} else {
|
||||
data = localStorage.getItem(itemName);
|
||||
@@ -295,9 +297,9 @@ function stateLoadCallback(itemName) {
|
||||
data = JSON.parse(data);
|
||||
|
||||
// Clear possible filtering settings
|
||||
data.columns.forEach(function (value, index) {
|
||||
for (const [index, value] of data.columns.entries()) {
|
||||
data.columns[index].search.search = "";
|
||||
});
|
||||
}
|
||||
|
||||
// Always start on the first page to show most recent queries
|
||||
data.start = 0;
|
||||
@@ -308,28 +310,28 @@ function stateLoadCallback(itemName) {
|
||||
}
|
||||
|
||||
function addFromQueryLog(domain, list) {
|
||||
var alertModal = $("#alertModal");
|
||||
var alProcessing = alertModal.find(".alProcessing");
|
||||
var alSuccess = alertModal.find(".alSuccess");
|
||||
var alFailure = alertModal.find(".alFailure");
|
||||
var alNetworkErr = alertModal.find(".alFailure #alNetErr");
|
||||
var alCustomErr = alertModal.find(".alFailure #alCustomErr");
|
||||
var alList = "#alList";
|
||||
var alDomain = "#alDomain";
|
||||
const alertModal = $("#alertModal");
|
||||
const alProcessing = alertModal.find(".alProcessing");
|
||||
const alSuccess = alertModal.find(".alSuccess");
|
||||
const alFailure = alertModal.find(".alFailure");
|
||||
const alNetworkErr = alertModal.find(".alFailure #alNetErr");
|
||||
const alCustomErr = alertModal.find(".alFailure #alCustomErr");
|
||||
const alList = "#alList";
|
||||
const alDomain = "#alDomain";
|
||||
|
||||
// Exit the function here if the Modal is already shown (multiple running interlock)
|
||||
if (alertModal.css("display") !== "none") {
|
||||
return;
|
||||
}
|
||||
|
||||
var listtype = list === "allow" ? "Allowlist" : "Denylist";
|
||||
const listtype = list === "allow" ? "Allowlist" : "Denylist";
|
||||
|
||||
alProcessing.children(alDomain).text(domain);
|
||||
alProcessing.children(alList).text(listtype);
|
||||
alertModal.modal("show");
|
||||
|
||||
// add Domain to List after Modal has faded in
|
||||
alertModal.one("shown.bs.modal", function () {
|
||||
alertModal.one("shown.bs.modal", () => {
|
||||
$.ajax({
|
||||
url: document.body.dataset.apiurl + "/domains/" + list + "/exact",
|
||||
method: "post",
|
||||
@@ -337,12 +339,12 @@ function addFromQueryLog(domain, list) {
|
||||
processData: false,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
data: JSON.stringify({
|
||||
domain: domain,
|
||||
domain,
|
||||
comment: "Added from Query Log",
|
||||
type: list,
|
||||
kind: "exact",
|
||||
}),
|
||||
success: function (response) {
|
||||
success(response) {
|
||||
alProcessing.hide();
|
||||
if ("domains" in response && response.domains.length > 0) {
|
||||
// Success
|
||||
@@ -351,7 +353,7 @@ function addFromQueryLog(domain, list) {
|
||||
alSuccess.fadeIn(1000);
|
||||
// Update domains counter in the menu
|
||||
updateFtlInfo();
|
||||
setTimeout(function () {
|
||||
setTimeout(() => {
|
||||
alertModal.modal("hide");
|
||||
}, 2000);
|
||||
} else {
|
||||
@@ -359,17 +361,17 @@ function addFromQueryLog(domain, list) {
|
||||
alNetworkErr.hide();
|
||||
alCustomErr.html(response.message);
|
||||
alFailure.fadeIn(1000);
|
||||
setTimeout(function () {
|
||||
setTimeout(() => {
|
||||
alertModal.modal("hide");
|
||||
}, 10000);
|
||||
}, 10_000);
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
error() {
|
||||
// Network Error
|
||||
alProcessing.hide();
|
||||
alNetworkErr.show();
|
||||
alFailure.fadeIn(1000);
|
||||
setTimeout(function () {
|
||||
setTimeout(() => {
|
||||
alertModal.modal("hide");
|
||||
}, 8000);
|
||||
},
|
||||
@@ -377,7 +379,7 @@ function addFromQueryLog(domain, list) {
|
||||
});
|
||||
|
||||
// Reset Modal after it has faded out
|
||||
alertModal.one("hidden.bs.modal", function () {
|
||||
alertModal.one("hidden.bs.modal", () => {
|
||||
alProcessing.show();
|
||||
alSuccess.add(alFailure).hide();
|
||||
alProcessing.add(alSuccess).children(alDomain).html("").end().children(alList).html("");
|
||||
@@ -407,7 +409,7 @@ function colorBar(percentage, total, cssClass) {
|
||||
}
|
||||
|
||||
function checkMessages() {
|
||||
var ignoreNonfatal = localStorage
|
||||
const ignoreNonfatal = localStorage
|
||||
? localStorage.getItem("hideNonfatalDnsmasqWarnings_chkbox") === "true"
|
||||
: false;
|
||||
$.ajax({
|
||||
@@ -418,10 +420,10 @@ function checkMessages() {
|
||||
method: "GET",
|
||||
dataType: "json",
|
||||
})
|
||||
.done(function (data) {
|
||||
.done(data => {
|
||||
if (data.count > 0) {
|
||||
var more = '\nAccess "Tools/Pi-hole diagnosis" for further details.';
|
||||
var title =
|
||||
const more = '\nAccess "Tools/Pi-hole diagnosis" for further details.';
|
||||
const title =
|
||||
data.count > 1
|
||||
? "There are " + data.count + " warnings." + more
|
||||
: "There is one warning." + more;
|
||||
@@ -433,7 +435,7 @@ function checkMessages() {
|
||||
$(".warning-count").addClass("hidden");
|
||||
}
|
||||
})
|
||||
.fail(function (data) {
|
||||
.fail(data => {
|
||||
$(".warning-count").addClass("hidden");
|
||||
apiFailure(data);
|
||||
});
|
||||
@@ -441,9 +443,9 @@ function checkMessages() {
|
||||
|
||||
// Show only the appropriate delete buttons in datatables
|
||||
function changeBulkDeleteStates(table) {
|
||||
var allRows = table.rows({ filter: "applied" }).data().length;
|
||||
var pageLength = table.page.len();
|
||||
var selectedRows = table.rows(".selected").data().length;
|
||||
const allRows = table.rows({ filter: "applied" }).data().length;
|
||||
const pageLength = table.page.len();
|
||||
const selectedRows = table.rows(".selected").data().length;
|
||||
|
||||
if (selectedRows === 0) {
|
||||
// Nothing selected
|
||||
@@ -470,7 +472,7 @@ function doLogout(url) {
|
||||
$.ajax({
|
||||
url: document.body.dataset.apiurl + "/auth",
|
||||
method: "DELETE",
|
||||
}).always(function () {
|
||||
}).always(() => {
|
||||
globalThis.location = url;
|
||||
});
|
||||
}
|
||||
@@ -501,9 +503,9 @@ function htmlPass(data, _type) {
|
||||
|
||||
// Show only the appropriate buttons
|
||||
function changeTableButtonStates(table) {
|
||||
var allRows = table.rows({ filter: "applied" }).data().length;
|
||||
var pageLength = table.page.len();
|
||||
var selectedRows = table.rows(".selected").data().length;
|
||||
const allRows = table.rows({ filter: "applied" }).data().length;
|
||||
const pageLength = table.page.len();
|
||||
const selectedRows = table.rows(".selected").data().length;
|
||||
|
||||
if (selectedRows === 0) {
|
||||
// Nothing selected
|
||||
@@ -527,8 +529,8 @@ function changeTableButtonStates(table) {
|
||||
}
|
||||
|
||||
function getCSSval(cssclass, cssproperty) {
|
||||
var elem = $("<div class='" + cssclass + "'></div>"),
|
||||
val = elem.appendTo("body").css(cssproperty);
|
||||
const elem = $("<div class='" + cssclass + "'></div>");
|
||||
const val = elem.appendTo("body").css(cssproperty);
|
||||
elem.remove();
|
||||
return val;
|
||||
}
|
||||
@@ -540,9 +542,10 @@ function parseQueryString() {
|
||||
|
||||
// https://stackoverflow.com/q/21647928
|
||||
function hexEncode(string) {
|
||||
var hex, i;
|
||||
let hex;
|
||||
let i;
|
||||
|
||||
var result = "";
|
||||
let result = "";
|
||||
for (i = 0; i < string.length; i++) {
|
||||
hex = string.codePointAt(i).toString(16);
|
||||
result += ("000" + hex).slice(-4);
|
||||
@@ -553,11 +556,11 @@ function hexEncode(string) {
|
||||
|
||||
// https://stackoverflow.com/q/21647928
|
||||
function hexDecode(string) {
|
||||
var j;
|
||||
var hexes = string.match(/.{1,4}/g) || [];
|
||||
var back = "";
|
||||
let j;
|
||||
const hexes = string.match(/.{1,4}/g) || [];
|
||||
let back = "";
|
||||
for (j = 0; j < hexes.length; j++) {
|
||||
back += String.fromCodePoint(parseInt(hexes[j], 16));
|
||||
back += String.fromCodePoint(Number.parseInt(hexes[j], 16));
|
||||
}
|
||||
|
||||
return back;
|
||||
@@ -592,7 +595,7 @@ function listAlert(type, items, data) {
|
||||
|
||||
// Loop over data.processed.success and print "item"
|
||||
for (const item in data.processed.success) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.processed.success, item)) {
|
||||
if (Object.hasOwn(data.processed.success, item)) {
|
||||
message += "\n- " + data.processed.success[item].item;
|
||||
}
|
||||
}
|
||||
@@ -615,10 +618,10 @@ function listAlert(type, items, data) {
|
||||
|
||||
// Loop over data.processed.errors and print "item: error"
|
||||
for (const item in data.processed.errors) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.processed.errors, item)) {
|
||||
if (Object.hasOwn(data.processed.errors, item)) {
|
||||
let error = data.processed.errors[item].error;
|
||||
// Replace some error messages with a more user-friendly text
|
||||
if (error.indexOf("UNIQUE constraint failed") > -1) {
|
||||
if (error.includes("UNIQUE constraint failed")) {
|
||||
error = "Already present";
|
||||
}
|
||||
|
||||
@@ -648,7 +651,7 @@ function loadingOverlayTimeoutCallback(reloadAfterTimeout) {
|
||||
cache: false,
|
||||
dataType: "json",
|
||||
})
|
||||
.done(function () {
|
||||
.done(() => {
|
||||
// FTL is running again, hide loading overlay
|
||||
NProgress.done();
|
||||
if (reloadAfterTimeout) {
|
||||
@@ -657,7 +660,7 @@ function loadingOverlayTimeoutCallback(reloadAfterTimeout) {
|
||||
waitMe.hideAll();
|
||||
}
|
||||
})
|
||||
.fail(function () {
|
||||
.fail(() => {
|
||||
// FTL is not running yet, try again in 500ms
|
||||
setTimeout(loadingOverlayTimeoutCallback, 500, reloadAfterTimeout);
|
||||
});
|
||||
@@ -717,40 +720,40 @@ function setInter(func, interval) {
|
||||
|
||||
globalThis.utils = (function () {
|
||||
return {
|
||||
escapeHtml: escapeHtml,
|
||||
unescapeHtml: unescapeHtml,
|
||||
objectToArray: objectToArray,
|
||||
padNumber: padNumber,
|
||||
showAlert: showAlert,
|
||||
datetime: datetime,
|
||||
datetimeRelative: datetimeRelative,
|
||||
disableAll: disableAll,
|
||||
enableAll: enableAll,
|
||||
validateIPv4CIDR: validateIPv4CIDR,
|
||||
validateIPv6CIDR: validateIPv6CIDR,
|
||||
setBsSelectDefaults: setBsSelectDefaults,
|
||||
stateSaveCallback: stateSaveCallback,
|
||||
stateLoadCallback: stateLoadCallback,
|
||||
validateMAC: validateMAC,
|
||||
validateHostname: validateHostname,
|
||||
addFromQueryLog: addFromQueryLog,
|
||||
addTD: addTD,
|
||||
toPercent: toPercent,
|
||||
colorBar: colorBar,
|
||||
checkMessages: checkMessages,
|
||||
changeBulkDeleteStates: changeBulkDeleteStates,
|
||||
doLogout: doLogout,
|
||||
renderTimestamp: renderTimestamp,
|
||||
renderTimespan: renderTimespan,
|
||||
htmlPass: htmlPass,
|
||||
changeTableButtonStates: changeTableButtonStates,
|
||||
getCSSval: getCSSval,
|
||||
parseQueryString: parseQueryString,
|
||||
hexEncode: hexEncode,
|
||||
hexDecode: hexDecode,
|
||||
escapeHtml,
|
||||
unescapeHtml,
|
||||
objectToArray,
|
||||
padNumber,
|
||||
showAlert,
|
||||
datetime,
|
||||
datetimeRelative,
|
||||
disableAll,
|
||||
enableAll,
|
||||
validateIPv4CIDR,
|
||||
validateIPv6CIDR,
|
||||
setBsSelectDefaults,
|
||||
stateSaveCallback,
|
||||
stateLoadCallback,
|
||||
validateMAC,
|
||||
validateHostname,
|
||||
addFromQueryLog,
|
||||
addTD,
|
||||
toPercent,
|
||||
colorBar,
|
||||
checkMessages,
|
||||
changeBulkDeleteStates,
|
||||
doLogout,
|
||||
renderTimestamp,
|
||||
renderTimespan,
|
||||
htmlPass,
|
||||
changeTableButtonStates,
|
||||
getCSSval,
|
||||
parseQueryString,
|
||||
hexEncode,
|
||||
hexDecode,
|
||||
listsAlert: listAlert,
|
||||
loadingOverlay: loadingOverlay,
|
||||
setTimer: setTimer,
|
||||
setInter: setInter,
|
||||
loadingOverlay,
|
||||
setTimer,
|
||||
setInter,
|
||||
};
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user