1126 lines
40 KiB
HTML
1126 lines
40 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title id="webtitle"></title>
|
||
<link href="css/styles.css" rel="stylesheet" media="screen">
|
||
<script src="js/auth.js"></script>
|
||
<script src="js/jquery.js"></script>
|
||
<script src="js/dashboard.js"></script>
|
||
<script>
|
||
var lastTime = new Date().getTime();
|
||
var currentTime = new Date().getTime();
|
||
var timeOut = 20 * 60 * 1000; // 20 min timeout
|
||
|
||
// Arrays for mapping RF Power indices to values (matching sys_rf.html)
|
||
var arry_p = ["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "95"];
|
||
|
||
$(function(){
|
||
// Listen to multiple types of user activity to prevent timeout
|
||
$(document).on('mousemove keydown click scroll touchstart', function(){
|
||
lastTime = new Date().getTime();
|
||
});
|
||
});
|
||
|
||
function testTime(){
|
||
currentTime = new Date().getTime();
|
||
if(currentTime - lastTime > timeOut){
|
||
window.location.href="login.cgi?logout=1"
|
||
}
|
||
}
|
||
|
||
// Timer check (1s)
|
||
window.setInterval(testTime, 1000);
|
||
// Refresh data (2s)
|
||
setInterval(SetFormDefaults, 2000);
|
||
|
||
function get_remote_local_ctrl() {
|
||
var queryData = "sys_cfg=&";
|
||
$.get("atsc_status_cfg.cgi?"+queryData, function(data, status) {
|
||
var table = data.split("|");
|
||
// Logic for remote/local control if needed
|
||
// g_remot_local_ctrl = Number(table[0].split("#")[5]);
|
||
document.title = table[0].split("#")[11];
|
||
});
|
||
}
|
||
|
||
function refresh_show(){
|
||
get_remote_local_ctrl();
|
||
SetFormDefaults();
|
||
}
|
||
|
||
function SetFormDefaults() {
|
||
var queryData = "State_SysState=&tuner_status=&pac_status=&gps_status=&State_SysVer=&mac_sn_status=&sys_rf=&web_title=&"
|
||
$.get("atsc_status_cfg.cgi?"+queryData, function(data, status) {
|
||
var temp_unit=1;
|
||
var agc_err_code=0;
|
||
var table = data.split("|");
|
||
|
||
// --- 1. SYSTEM STATUS (Form 0) ---
|
||
var form = table[0].split("#");
|
||
var cf = document.getElementById("iostatus"); // iostatus
|
||
var ab_modenum = Number(form[25]);
|
||
temp_unit = Number(form[26]);
|
||
|
||
// Input Source Map
|
||
var i = Number(form[1]);
|
||
var s_str = (i==0)?"ASI1":(i==1)?"ASI2":(i==2)?"EAS":(i==3)?"Tuner":(i==4)?"TSoIP":(i==5)?"SMPTE":"None";
|
||
cf.asi_input.value = s_str;
|
||
|
||
// Input Status
|
||
cf.asi_status.value = (Number(form[2])==0) ? "OK" : "Err";
|
||
|
||
// AGC
|
||
cf.agc0.value = (Number(form[3])==0) ? "Off" : "On";
|
||
|
||
cf.ts_rate.value = form[4]; // TS Rate
|
||
|
||
// Temperature
|
||
if(temp_unit==0){
|
||
cf.temp1.value = form[5];
|
||
cf.temp1_c.value = ((cf.temp1.value - 32)/1.8).toFixed(2);
|
||
} else {
|
||
cf.temp1.value = (form[5]*1.8+32).toFixed(2);
|
||
cf.temp1_c.value = form[5];
|
||
}
|
||
|
||
// System Error
|
||
cf.syserr.value = (Number(form[6])==0) ? "OK" : "Err";
|
||
|
||
// Frequency Logic
|
||
i = Number(form[7]);
|
||
var freqVal = 0;
|
||
if((i>=2)&&(i<=6)){
|
||
freqVal = (i-2)*6+57; if(freqVal>69) freqVal+=4;
|
||
} else if((i>=7)&&(i<=13)){
|
||
freqVal = 177+6*(i-7);
|
||
} else if((i>=14)&&(i<=83)){
|
||
freqVal = 473+(i-14)*6;
|
||
}
|
||
cf.cha.value = freqVal; // Just the number for display
|
||
|
||
// Offset
|
||
i = Number(form[8]);
|
||
s_str = (i==0) ? "+" : "-";
|
||
cf.hz1.value = s_str + form[9];
|
||
|
||
// FWD Power & SNR
|
||
var rawFwd = Number(form[10]);
|
||
cf.fwd.value = (ab_modenum==1) ? "N/A" : (rawFwd + " %");
|
||
|
||
// SNR. Half-dB from the app, plus the fixed +10 dB display offset.
|
||
var tmpdata = Number(form[11]);
|
||
var snrStr = (tmpdata/2 + 10).toFixed(1);
|
||
cf.tsnr.value = (ab_modenum==1) ? "N/A" : snrStr;
|
||
|
||
// IMD. Half-dB from the app, plus the fixed +11 dB display offset.
|
||
// (Do not Math.round() the sum and then paste on the half: for an odd
|
||
// half-dB value that rounds x.5 up and reports 1 dB too much.)
|
||
tmpdata = Number(form[12]);
|
||
cf.l_imd.value = (ab_modenum==1) ? "N/A" : (tmpdata/2 + 11).toFixed(1);
|
||
|
||
tmpdata = Number(form[13]);
|
||
cf.u_imd.value = (ab_modenum==1) ? "N/A" : (tmpdata/2 + 11).toFixed(1);
|
||
|
||
// Control & Amp
|
||
cf.f1ctrl.value = (Number(form[14])==0) ? "Remote" : "Local";
|
||
|
||
i = Number(form[15]);
|
||
if(i>1){
|
||
// Hide if invalid
|
||
document.getElementById("amp").style.visibility="hidden";
|
||
document.getElementById("amp+").style.visibility="hidden";
|
||
} else {
|
||
document.getElementById("amp").style.visibility="visible";
|
||
document.getElementById("amp+").style.visibility="visible";
|
||
cf.amp.value = (i==0) ? "OK" : "FLT";
|
||
}
|
||
|
||
// FSSI
|
||
cf.a_fssi.value = Number(form[16]) + " %";
|
||
cf.b_fssi.value = (ab_modenum==1) ? (Number(form[17]) + " %") : "N/A";
|
||
|
||
// AGC State
|
||
agc_err_code = Number(form[27]);
|
||
var agc_adj = Number(form[28]);
|
||
if(agc_err_code==1) s_str="Down Limit!";
|
||
else if(agc_err_code==2) s_str="Up Limit!";
|
||
else {
|
||
if(Number(form[3])==1) { // AGC ON
|
||
s_str = (agc_adj>0) ? ("+"+(agc_adj/100)) : (agc_adj/100).toString();
|
||
} else {
|
||
s_str="OK";
|
||
}
|
||
}
|
||
cf.agc_state.value = s_str;
|
||
|
||
// --- 2. PARSE SYS_RF FOR DASHBOARD ---
|
||
var rfStat = 0;
|
||
var finalPower = '--';
|
||
if(table[6]) {
|
||
var rf_form = table[6].split("#");
|
||
rfStat = Number(rf_form[4]); // RFY index
|
||
var p_sign = (Number(rf_form[1]) == 0) ? "+" : "-";
|
||
var p_int = Number(rf_form[2]);
|
||
var p_dec = arry_p[Number(rf_form[3])];
|
||
finalPower = p_sign + p_int + "." + p_dec;
|
||
}
|
||
|
||
// --- 3. UPDATE DASHBOARD USING SHARED MODULE ---
|
||
if (typeof updateDashboardCards === 'function') {
|
||
updateDashboardCards({
|
||
freqVal: freqVal,
|
||
snr: cf.tsnr.value,
|
||
limd: cf.l_imd.value,
|
||
uimd: cf.u_imd.value,
|
||
inputSrc: cf.asi_input.value,
|
||
inputStatus: cf.asi_status.value,
|
||
bitrate: cf.ts_rate.value,
|
||
temp: cf.temp1.value,
|
||
agc: cf.agc0.value,
|
||
ctrl: cf.f1ctrl.value,
|
||
rfStat: rfStat,
|
||
finalPower: finalPower
|
||
});
|
||
}
|
||
|
||
// --- 4. PARSE OTHER FORMS ---
|
||
|
||
// Form 1: Tuner
|
||
var form1 = table[1].split("#");
|
||
var cf1 = document.getElementById("tuner");
|
||
cf1.rx_freq.value = Number(form1[1]);
|
||
cf1.rssi.value = Number(form1[2]);
|
||
cf1.rsnr.value = Number(form1[3]);
|
||
cf1.lock.selectedIndex = Number(form1[4]);
|
||
|
||
// Form 2: PAC Status
|
||
var form2 = table[2].split("#");
|
||
var cf2 = document.getElementById("pac_status");
|
||
cf2.v9v.value = (Number(form2[1])*0.1).toFixed(2);
|
||
cf2.v12v.value = (Number(form2[2])*0.1).toFixed(2);
|
||
cf2.v50v.value = (Number(form2[3])*0.1).toFixed(2);
|
||
cf2.pac_fwd.value = (Number(form2[4])*0.1).toFixed(2);
|
||
cf2.ref.value = (Number(form2[5])*0.1).toFixed(2);
|
||
cf2.vswr.value = (Number(form2[6])*0.1).toFixed(2);
|
||
|
||
// PAC Temp
|
||
if(temp_unit==0){
|
||
cf2.temp.value = (Number(form2[7])*0.1).toFixed(2);
|
||
cf2.temp_c.value = (cf2.temp.value < 32) ? 0 : ((cf2.temp.value - 32)/1.8).toFixed(2);
|
||
} else {
|
||
cf2.temp.value = (Number(form2[7])*0.1*1.8+32).toFixed(2);
|
||
cf2.temp_c.value = (Number(form2[7])*0.1).toFixed(2);
|
||
}
|
||
|
||
cf2.pain.value = Number(form2[8]); // This is PA_IN
|
||
|
||
cf2.c50v1.value = (Number(form2[9])*0.1).toFixed(2);
|
||
cf2.c50v2.value = (Number(form2[10])*0.1).toFixed(2);
|
||
cf2.c50v3.value = (Number(form2[11])*0.1).toFixed(2);
|
||
cf2.c50v4.value = (Number(form2[12])*0.1).toFixed(2);
|
||
cf2.gv.value = (Number(form2[13])*0.1).toFixed(2);
|
||
cf2.lvl.selectedIndex = Number(form2[14]);
|
||
|
||
// Form 3: GPS
|
||
var form3 = table[3].split("#");
|
||
var cf3 = document.getElementById("gps_form");
|
||
cf3.gps.value = (Number(form3[1])==0)?"NoGPS":(Number(form3[1])==1)?"Unlock":"Lock";
|
||
cf3.gps_in.value = (Number(form3[2])==0)?"External":"Internal";
|
||
cf3.gps_date.value = form3[3];
|
||
cf3.gps_time.value = form3[4];
|
||
cf3.gps_sv.value = form3[5];
|
||
cf3.gps_status.value = form3[6];
|
||
cf3.gps_freq.value = form3[7];
|
||
|
||
// Form 5: Version
|
||
var form5 = table[4].split("#");
|
||
var cf5 = document.getElementById("version");
|
||
cf5.atsc_ver.value = form5[1];
|
||
cf5.fpga_ver.value = form5[2];
|
||
cf5.mcu_ver.value = form5[3];
|
||
cf5.plc_ver.value = form5[4];
|
||
|
||
// Form 6: MAC/SN
|
||
var form6 = table[5].split("#");
|
||
var cf6 = document.getElementById("macsn");
|
||
cf6.mac.value = form6[1];
|
||
cf6.sn.value = form6[2];
|
||
|
||
if (table[7]) {
|
||
var title = table[7].split("#");
|
||
var titleStr = (title[1] != null) ? title[1] : "";
|
||
document.getElementById('webtitle').textContent = titleStr;
|
||
document.getElementById('webtitle_header').textContent = titleStr;
|
||
}
|
||
|
||
// Update Status Colors and UI helpers
|
||
updateStatusColors();
|
||
updateStatusAlertStrip();
|
||
highlightProblemTableRows();
|
||
updateBoxHeaderErrorState();
|
||
get_license();
|
||
});
|
||
}
|
||
|
||
function updateStatusAlertStrip() {
|
||
var strip = document.getElementById('status-alert-strip');
|
||
var textEl = strip ? strip.querySelector('.status-alert-text') : null;
|
||
var detailEl = document.getElementById('status-alert-detail');
|
||
if (!strip || !textEl) return;
|
||
var cards = document.querySelectorAll('.summary-card');
|
||
var errLabels = [], warnLabels = [];
|
||
cards.forEach(function(card) {
|
||
var val = card.querySelector('.summary-value');
|
||
var label = card.querySelector('.summary-label');
|
||
var name = label ? label.textContent.trim() : '';
|
||
if (val && val.classList.contains('value-err')) errLabels.push(name);
|
||
else if (val && val.classList.contains('value-warn')) warnLabels.push(name);
|
||
});
|
||
strip.classList.remove('status-alert-ok', 'status-alert-warn', 'status-alert-err');
|
||
if (errLabels.length > 0) {
|
||
strip.classList.add('status-alert-err');
|
||
textEl.textContent = errLabels.length + ' issue(s) detected';
|
||
if (detailEl) detailEl.textContent = ' - e.g. ' + errLabels.slice(0, 2).join(', ');
|
||
} else if (warnLabels.length > 0) {
|
||
strip.classList.add('status-alert-warn');
|
||
textEl.textContent = warnLabels.length + ' warning(s)';
|
||
if (detailEl) detailEl.textContent = ' - e.g. ' + warnLabels.slice(0, 2).join(', ');
|
||
} else {
|
||
strip.classList.add('status-alert-ok');
|
||
textEl.textContent = 'System OK';
|
||
if (detailEl) detailEl.textContent = '';
|
||
}
|
||
updateSummaryCardTooltips();
|
||
}
|
||
|
||
function updateSummaryCardTooltips() {
|
||
document.querySelectorAll('.summary-card').forEach(function(card) {
|
||
var label = card.querySelector('.summary-label');
|
||
var value = card.querySelector('.summary-value');
|
||
var status = value && value.classList.contains('value-err') ? 'Error' : (value && value.classList.contains('value-warn') ? 'Warning' : (value && value.classList.contains('value-ok') ? 'OK' : ''));
|
||
var name = label ? label.textContent.trim() : '';
|
||
var val = value ? value.textContent.trim() : '--';
|
||
card.title = name + ': ' + val + (status ? ' (' + status + ')' : '');
|
||
});
|
||
}
|
||
|
||
function highlightProblemTableRows() {
|
||
var tables = document.querySelectorAll('.app-main .box table');
|
||
tables.forEach(function(table) {
|
||
var rows = table.querySelectorAll('tr');
|
||
rows.forEach(function(tr) {
|
||
tr.classList.remove('row-has-error');
|
||
var inputs = tr.querySelectorAll('input[readonly], select');
|
||
for (var i = 0; i < inputs.length; i++) {
|
||
var inp = inputs[i];
|
||
var v = '';
|
||
if (inp.tagName === 'SELECT') {
|
||
var opt = inp.options[inp.selectedIndex];
|
||
v = opt ? opt.text.trim() : '';
|
||
} else {
|
||
v = inp.value || '';
|
||
}
|
||
// Literal error values (case-insensitive: values may be "Err", "Unlock", etc.)
|
||
if ((v && v.toUpperCase() === 'ERR') || v === 'FLT' || (v && v.toUpperCase() === 'UNLOCK')) {
|
||
tr.classList.add('row-has-error');
|
||
break;
|
||
}
|
||
// SNR, LIMD, UIMD: same error thresholds as summary cards / updateStatusColors
|
||
var id = inp.id || '';
|
||
if (id === 'tsnr' && v !== '' && v !== 'N/A') {
|
||
var snrNum = parseFloat(v); // carries the +10 dB display offset
|
||
if (snrNum < 25) { tr.classList.add('row-has-error'); break; }
|
||
}
|
||
if (id === 'l_imd' && v !== '' && v !== 'N/A') {
|
||
if (parseFloat(v) < 47) { tr.classList.add('row-has-error'); break; }
|
||
}
|
||
if (id === 'u_imd' && v !== '' && v !== 'N/A') {
|
||
if (parseFloat(v) < 47) { tr.classList.add('row-has-error'); break; }
|
||
}
|
||
// License fields: INACTIVE is an error
|
||
if (id === 'pisp_editing_lc' || id === 'eas_lc') {
|
||
if (v === 'INACTIVE') {
|
||
tr.classList.add('row-has-error');
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
function updateBoxHeaderErrorState() {
|
||
document.querySelectorAll('.box-header').forEach(function(boxHeader) {
|
||
var box = boxHeader.parentElement;
|
||
if (!box || !box.classList.contains('box')) return;
|
||
var content = box.querySelector('.box-content');
|
||
var hasError = content && content.querySelector('tr.row-has-error');
|
||
if (hasError) boxHeader.classList.add('has-error');
|
||
else boxHeader.classList.remove('has-error');
|
||
});
|
||
}
|
||
|
||
// Color Logic: Main Status details (OK/ERR, LIMD/UIMD/SNR ranges) + Tuner Lock/Unlock
|
||
function updateStatusColors() {
|
||
var color_ok = getComputedStyle(document.documentElement).getPropertyValue('--accent-green').trim();
|
||
var color_err = getComputedStyle(document.documentElement).getPropertyValue('--status-err').trim();
|
||
var color_warn = getComputedStyle(document.documentElement).getPropertyValue('--status-warn').trim();
|
||
var inputs = document.getElementsByTagName("input");
|
||
for(var i=0; i<inputs.length; i++) {
|
||
// Skip inputs inside the account modal to prevent flicker
|
||
var inModal = inputs[i].closest('#accountModal');
|
||
if(inModal) continue;
|
||
|
||
if(inputs[i].value.toUpperCase() === "OK" || inputs[i].value.toUpperCase() === "LOCK") inputs[i].style.color = color_ok;
|
||
else if(inputs[i].value.toUpperCase() === "ERR" || inputs[i].value.toUpperCase() === "UNLOCK") inputs[i].style.color = color_err;
|
||
else inputs[i].style.color = "";
|
||
}
|
||
|
||
// Main Status details: LIMD, UIMD, SNR – same rules as summary cards (green/red/warn by range)
|
||
var tsnrEl = document.getElementById("tsnr");
|
||
if(tsnrEl && tsnrEl.value !== "" && tsnrEl.value !== "N/A") {
|
||
var snrVal = parseFloat(tsnrEl.value); // already carries the +10 dB display offset
|
||
if(snrVal >= 37) tsnrEl.style.color = color_ok;
|
||
else if(snrVal >= 30) tsnrEl.style.color = color_warn;
|
||
else tsnrEl.style.color = color_err;
|
||
} else if(tsnrEl) tsnrEl.style.color = "";
|
||
|
||
var limdEl = document.getElementById("l_imd");
|
||
if(limdEl && limdEl.value !== "" && limdEl.value !== "N/A") {
|
||
limdEl.style.color = parseFloat(limdEl.value) >= 47 ? color_ok : color_err;
|
||
} else if(limdEl) limdEl.style.color = "";
|
||
|
||
var uimdEl = document.getElementById("u_imd");
|
||
if(uimdEl && uimdEl.value !== "" && uimdEl.value !== "N/A") {
|
||
uimdEl.style.color = parseFloat(uimdEl.value) >= 47 ? color_ok : color_err;
|
||
} else if(uimdEl) uimdEl.style.color = "";
|
||
|
||
// Tuner section only: Lock (green) / Unlock (red). PAC section PA Level (#lvl) is power level 0/160/310/610 W – never color it.
|
||
var selects = document.getElementsByTagName("select");
|
||
for(var j=0; j<selects.length; j++) {
|
||
var sel = selects[j];
|
||
// Skip selects inside the account modal to prevent flicker
|
||
var inModal = sel.closest('#accountModal');
|
||
if(inModal) continue;
|
||
|
||
if(sel.id !== "lock" && sel.name !== "lock") {
|
||
sel.style.color = "";
|
||
continue;
|
||
}
|
||
var opt = sel.options[sel.selectedIndex];
|
||
var text = opt ? opt.text.trim() : "";
|
||
var val = opt ? opt.value : "";
|
||
sel.classList.remove("state-error", "state-ok");
|
||
if(text === "Lock" || val === "1") {
|
||
sel.style.color = color_ok;
|
||
sel.style.fontWeight = "bold";
|
||
sel.classList.add("state-ok");
|
||
}
|
||
else if(text === "Unlock" || val === "0") {
|
||
sel.style.color = color_err;
|
||
sel.style.fontWeight = "bold";
|
||
sel.classList.add("state-error");
|
||
}
|
||
else {
|
||
sel.style.color = "";
|
||
sel.style.fontWeight = "normal";
|
||
}
|
||
}
|
||
// License fields
|
||
var licenseFields = ["pisp_editing_lc", "eas_lc"];
|
||
for (var k = 0; k < licenseFields.length; k++) {
|
||
var field = document.getElementById(licenseFields[k]);
|
||
if (field) {
|
||
if (field.value.toUpperCase() === "ACTIVE") {
|
||
field.style.color = color_ok;
|
||
} else if (field.value.toUpperCase() === "INACTIVE") {
|
||
field.style.color = color_err;
|
||
} else {
|
||
field.style.color = "";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Modal Logic - Open and close account modal
|
||
function openAccountModal() {
|
||
// Fetch current username from server
|
||
$.get("login.cgi?action=get_user", function(data) {
|
||
var trimmedData = (data || "").trim();
|
||
if (trimmedData && trimmedData !== "UNAUTHORIZED") {
|
||
document.getElementById('current_user').value = trimmedData;
|
||
}
|
||
document.getElementById('accountModal').style.display = 'block';
|
||
setTimeout(function() { document.getElementById('current_pwd').focus(); }, 100);
|
||
}).fail(function() {
|
||
// On error, modal still opens but current_user remains empty
|
||
document.getElementById('accountModal').style.display = 'block';
|
||
setTimeout(function() { document.getElementById('current_pwd').focus(); }, 100);
|
||
});
|
||
}
|
||
|
||
function closeAccountModal() {
|
||
document.getElementById('accountModal').style.display = 'none';
|
||
// Clear sensitive fields
|
||
document.getElementById('current_pwd').value = '';
|
||
document.getElementById('new_pwd').value = '';
|
||
document.getElementById('confirm_pwd').value = '';
|
||
}
|
||
|
||
// Validates that a string contains only printable characters (excluding space)
|
||
function isValidPrintableString(str) {
|
||
// Regular expression to check for printable characters (ASCII 33-126), excluding space
|
||
// Space is ASCII 32, and we want to exclude it
|
||
var printableCharRegex = /^[!-~]+$/; // ! is ASCII 33, ~ is ASCII 126
|
||
return printableCharRegex.test(str);
|
||
}
|
||
|
||
// Validate Account Form - All required fields must be filled
|
||
function validateAccountForm() {
|
||
var currentUser = document.getElementById('current_user').value;
|
||
var currentPwd = document.getElementById('current_pwd').value;
|
||
var newUsername = document.getElementById('new_user').value;
|
||
var newPwd = document.getElementById('new_pwd').value;
|
||
var confirmPwd = document.getElementById('confirm_pwd').value;
|
||
|
||
// Current password is required (cannot be empty)
|
||
if (!currentPwd || currentPwd.trim() === "") {
|
||
alert("Current password is required");
|
||
return false;
|
||
}
|
||
|
||
// Validate current password contains only printable characters
|
||
if (!isValidPrintableString(currentPwd)) {
|
||
alert("Current password contains invalid characters. Only printable characters (excluding space) are allowed.");
|
||
return false;
|
||
}
|
||
|
||
// New password is required (cannot be empty)
|
||
if (!newPwd || newPwd.trim() === "") {
|
||
alert("New password is required");
|
||
return false;
|
||
}
|
||
|
||
// Validate new password contains only printable characters
|
||
if (!isValidPrintableString(newPwd)) {
|
||
alert("New password contains invalid characters. Only printable characters (excluding space) are allowed.");
|
||
return false;
|
||
}
|
||
|
||
// Validate new password length (max 16 chars)
|
||
if (newPwd.length > 16) {
|
||
alert("New password must be no more than 16 characters");
|
||
return false;
|
||
}
|
||
|
||
// Validate new password length
|
||
if (newPwd.length < 6) {
|
||
alert("New password must be at least 6 characters");
|
||
return false;
|
||
}
|
||
|
||
// Confirm password must match new password
|
||
if (newPwd !== confirmPwd) {
|
||
alert("New passwords do not match");
|
||
return false;
|
||
}
|
||
|
||
// Validate confirm password contains only printable characters
|
||
if (!isValidPrintableString(confirmPwd)) {
|
||
alert("Confirm password contains invalid characters. Only printable characters (excluding space) are allowed.");
|
||
return false;
|
||
}
|
||
|
||
// Validate confirm password length (max 16 chars)
|
||
if (confirmPwd.length > 16) {
|
||
alert("Confirm password must be no more than 16 characters");
|
||
return false;
|
||
}
|
||
|
||
// Validate new username if provided
|
||
if (newUsername && newUsername.trim() !== "") {
|
||
// Validate new username contains only printable characters
|
||
if (!isValidPrintableString(newUsername)) {
|
||
alert("New username contains invalid characters. Only printable characters (excluding space) are allowed.");
|
||
return false;
|
||
}
|
||
|
||
// Validate new username length (max 16 chars)
|
||
if (newUsername.length > 16) {
|
||
alert("New username must be no more than 16 characters");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true; // Allows the form to submit
|
||
}
|
||
|
||
// Form submission handler using fetch API
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
var accountForm = document.getElementById('accountForm');
|
||
if (accountForm) {
|
||
accountForm.addEventListener('submit', function(e) {
|
||
e.preventDefault();
|
||
|
||
if (!validateAccountForm()) return;
|
||
|
||
var formData = new URLSearchParams({
|
||
Username: document.getElementById('current_user').value,
|
||
OldPassword: document.getElementById('current_pwd').value,
|
||
NewUsername: document.getElementById('new_user').value,
|
||
NewPassword: document.getElementById('new_pwd').value,
|
||
ConfirmPassword: document.getElementById('confirm_pwd').value
|
||
});
|
||
|
||
fetch('login.cgi?action=change_account', {
|
||
method: 'POST',
|
||
body: formData
|
||
})
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
alert("Update successful! Please login again.");
|
||
closeAccountModal();
|
||
// Redirect to login page after 1.5 seconds
|
||
setTimeout(function() {
|
||
window.location.href = 'login.cgi?logout=1';
|
||
}, 1500);
|
||
} else {
|
||
alert(data.error || "Update failed");
|
||
}
|
||
})
|
||
.catch(function(err) {
|
||
alert("Network error: " + err);
|
||
});
|
||
});
|
||
}
|
||
});
|
||
|
||
// Collapsible Tables - MAIN STATUS, PAC STATUS, GPS STATUS
|
||
function initCollapsibleTables() {
|
||
var headers = document.querySelectorAll('.app-main h2');
|
||
for (var i = 0; i < headers.length; i++) {
|
||
var header = headers[i];
|
||
var headerText = header.innerText.trim();
|
||
|
||
if (headerText === "Main Status" || headerText === "Tuner Status" || headerText === "PAC Status" || headerText === "GPS Status") {
|
||
|
||
// Smart Search for the box
|
||
var nextEl = header.nextElementSibling;
|
||
var box = null;
|
||
while (nextEl) {
|
||
if (nextEl.className && nextEl.className.indexOf("box") !== -1) {
|
||
box = nextEl;
|
||
break;
|
||
}
|
||
if (nextEl.tagName === "H2") break;
|
||
nextEl = nextEl.nextElementSibling;
|
||
}
|
||
|
||
if (box) {
|
||
var boxHeader = document.createElement('div');
|
||
boxHeader.className = "box-header collapsed";
|
||
var titleSpan = document.createElement('span');
|
||
titleSpan.innerText = headerText + " Details";
|
||
var toggleSpan = document.createElement('span');
|
||
toggleSpan.className = "toggle-text";
|
||
toggleSpan.innerText = "View Details";
|
||
|
||
boxHeader.appendChild(titleSpan);
|
||
boxHeader.appendChild(toggleSpan);
|
||
|
||
var contentDiv = document.createElement('div');
|
||
contentDiv.className = "box-content";
|
||
contentDiv.style.display = "none";
|
||
|
||
while (box.firstChild) {
|
||
contentDiv.appendChild(box.firstChild);
|
||
}
|
||
|
||
box.appendChild(boxHeader);
|
||
box.appendChild(contentDiv);
|
||
|
||
boxHeader.onclick = function() {
|
||
this.classList.toggle("collapsed");
|
||
var content = this.nextElementSibling;
|
||
var badge = this.querySelector('.toggle-text');
|
||
if (content.style.display === "none") {
|
||
content.style.display = "block";
|
||
badge.innerText = "Hide Details";
|
||
} else {
|
||
content.style.display = "none";
|
||
badge.innerText = "View Details";
|
||
}
|
||
};
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function get_license() {
|
||
var queryData = "sn_license=&";
|
||
$.get("atsc_status_cfg.cgi?" + queryData, function(data, status) {
|
||
var table = data.split("|");
|
||
var licence_para = table[0].split("#");
|
||
var cf = document.getElementById("license");
|
||
if (cf) {
|
||
cf.pisp_editing_lc.value = (licence_para[2] == "1") ? "ACTIVE" : "INACTIVE";
|
||
cf.eas_lc.value = (licence_para[4] == "1") ? "ACTIVE" : "INACTIVE";
|
||
updateStatusColors();
|
||
highlightProblemTableRows();
|
||
updateBoxHeaderErrorState();
|
||
updateStatusAlertStrip();
|
||
}
|
||
});
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
initCollapsibleTables();
|
||
});
|
||
</script>
|
||
</head>
|
||
|
||
<body onload="refresh_show()">
|
||
<body onload="refresh_show()">
|
||
<div class="app-layout">
|
||
<aside class="app-sidebar">
|
||
<ul class="items">
|
||
<li class="active"><a href="status_info.html" title="Status">Status</a></li>
|
||
<li><a href="sys_set.html" title="Settings">Settings</a></li>
|
||
<li><a href="sys_rf.html" title="RF Control">RF Control</a></li>
|
||
<li><a href="sys_psip.html" title="TSID&PSIP">TSID&PSIP</a></li>
|
||
<li><a href="sys_ts.html" title="TSoIP">TSoIP</a></li>
|
||
<li><a href="sys_spectrum.html" title="Spectrum">Spectrum</a></li>
|
||
<li><a href="log_output.html" title="Log">Log</a></li>
|
||
</ul>
|
||
<div class="sidebar-footer">
|
||
<h4>Anywave Broadcast Inc.</h4>
|
||
<p>Copyright 2026<br><br><span class="redbox-label">Technical Support</span><br>+1 847 415 2258<br><a href="mailto:support@anywaveus.com">support@anywaveus.com</a></p>
|
||
</div>
|
||
</aside>
|
||
<div class="sidebar-overlay" onclick="toggleSidebar()"></div>
|
||
|
||
<header class="app-header">
|
||
<button class="menu-toggle" onclick="toggleSidebar()" aria-label="Toggle menu">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<line x1="3" y1="12" x2="21" y2="12"></line>
|
||
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||
<line x1="3" y1="18" x2="21" y2="18"></line>
|
||
</svg>
|
||
</button>
|
||
<h1><a href="https://anywavecom.net/" class="logo-bg" title="Anywave Broadcast Inc."></a></h1>
|
||
<h2 id="webtitle_header"><span></span></h2>
|
||
<h3>
|
||
<div class="dropdown">
|
||
<button class="dropbtn-modern">Admin ▾</button>
|
||
<div class="dropdown-content">
|
||
<a href="#" onclick="openAccountModal(); return false;">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="3"></circle>
|
||
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
|
||
</svg>
|
||
Account Settings
|
||
</a>
|
||
<a href="login.cgi?logout=1">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
|
||
<polyline points="16 17 21 12 16 7"></polyline>
|
||
<line x1="21" y1="12" x2="9" y2="12"></line>
|
||
</svg>
|
||
Logout
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</h3>
|
||
</header>
|
||
|
||
<!-- Fixed Dashboard Summary - Top of page, under header -->
|
||
<div class="dashboard-fixed">
|
||
<div class="summary-dashboard">
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-neutral" id="dot_freq" aria-hidden="true"></span>
|
||
<span class="summary-label">Frequency</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-neutral" id="sum_freq">--</span>
|
||
<span class="summary-unit">MHz</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-ok" id="dot_snr" aria-hidden="true"></span>
|
||
<span class="summary-label">SNR</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-ok" id="sum_snr">--</span>
|
||
<span class="summary-unit">dB</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-ok" id="dot_uimd" aria-hidden="true"></span>
|
||
<span class="summary-label">UIMD</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-ok" id="sum_uimd">--</span>
|
||
<span class="summary-unit">dBc</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-ok" id="dot_limd" aria-hidden="true"></span>
|
||
<span class="summary-label">LIMD</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-ok" id="sum_limd">--</span>
|
||
<span class="summary-unit">dBc</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-off" id="dot_rf" aria-hidden="true"></span>
|
||
<span class="summary-label">RF Switch</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-muted" id="sum_rf">--</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-ok" id="dot_outpow" aria-hidden="true"></span>
|
||
<span class="summary-label">Output Power</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-ok" id="sum_outpow">--</span>
|
||
<span class="summary-unit">dBm</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-neutral" id="dot_input" aria-hidden="true"></span>
|
||
<span class="summary-label">Input Source</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-neutral" id="sum_input">--</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-neutral" id="dot_input_status" aria-hidden="true"></span>
|
||
<span class="summary-label">Input Status</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-neutral" id="sum_input_status">--</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-neutral" id="dot_bitrate" aria-hidden="true"></span>
|
||
<span class="summary-label">Bitrate</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-neutral" id="sum_bitrate">--</span>
|
||
<span class="summary-unit">Mbps</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-ok" id="dot_temp" aria-hidden="true"></span>
|
||
<span class="summary-label">Temperature</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-ok" id="sum_temp">--</span>
|
||
<span class="summary-unit">°F</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-off" id="dot_agc" aria-hidden="true"></span>
|
||
<span class="summary-label">AGC</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-muted" id="sum_agc">--</span>
|
||
</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="summary-label-row">
|
||
<span class="status-dot status-neutral" id="dot_control" aria-hidden="true"></span>
|
||
<span class="summary-label">Control</span>
|
||
</div>
|
||
<div class="summary-value-wrapper">
|
||
<span class="summary-value value-neutral" id="sum_control">--</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<main class="app-main">
|
||
<div id="status-alert-strip" class="status-alert status-alert-ok" role="status" aria-live="polite">
|
||
<span class="status-alert-icon" aria-hidden="true"></span>
|
||
<span class="status-alert-text">System OK</span>
|
||
<span class="status-alert-detail" id="status-alert-detail"></span>
|
||
</div>
|
||
|
||
<h2>Main Status</h2>
|
||
<div class="box">
|
||
<form name="iostatus" id="iostatus">
|
||
<table>
|
||
<tr>
|
||
<td>Input</td>
|
||
<td><input type="text" readonly name="asi_input" id="asi_input" value=""></td>
|
||
<td>Status</td>
|
||
<td><input type="text" readonly name="asi_status" id="asi_status" value=""></td>
|
||
</tr>
|
||
<tr>
|
||
<td>AGC</td>
|
||
<td>
|
||
<input type="text" readonly name="agc0" id="agc0" value="">
|
||
<input type="text" readonly name="agc_state" id="agc_state" style="margin-top: 4px;" value="">
|
||
</td>
|
||
<td>TS Bitrate</td>
|
||
<td><input type="text" readonly name="ts_rate" id="ts_rate" value=""> Mbps</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Temperature</td>
|
||
<td>
|
||
<fieldset>
|
||
<input type="text" readonly name="temp1" id="temp1" value="">°F
|
||
<input type="text" readonly name="temp1_c" id="temp1_c" value="">°C
|
||
</fieldset>
|
||
</td>
|
||
<td>SYSERR</td>
|
||
<td><input type="text" readonly name="syserr" id="syserr" value=""></td>
|
||
</tr>
|
||
<tr>
|
||
<td>TX Frequency</td>
|
||
<td><input type="text" readonly name="cha" id="cha" value=""> MHz</td>
|
||
<td>Hz(+/-50000Hz)</td>
|
||
<td><fieldset>
|
||
<input type="text" readonly name="hz1" id="hz1" value="">
|
||
</fieldset></td>
|
||
</tr>
|
||
<tr>
|
||
<td>FWD</td>
|
||
<td><input type="text" readonly name="fwd" id="fwd" value=""></td>
|
||
<td>SNR</td>
|
||
<td><input type="text" readonly name="tsnr" id="tsnr" value=""> dB</td>
|
||
</tr>
|
||
<tr>
|
||
<td>LIMD</td>
|
||
<td><input type="text" readonly name="l_imd" id="l_imd" value=""> dBc</td>
|
||
<td>UIMD</td>
|
||
<td><input type="text" readonly name="u_imd" id="u_imd" value=""> dBc</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Control</td>
|
||
<td><input type="text" readonly name="f1ctrl" id="f1ctrl" value=""></td>
|
||
<td id="amp+">AMP</td>
|
||
<td id="amp">
|
||
<input type="text" readonly name="amp" value="">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td>A FSSI</td>
|
||
<td><input type="text" readonly name="a_fssi" id="a_fssi" value=""></td>
|
||
<td>B FSSI</td>
|
||
<td><input type="text" readonly name="b_fssi" id="b_fssi" value=""></td>
|
||
</tr>
|
||
</table>
|
||
</form>
|
||
</div>
|
||
|
||
<h2>Tuner Status</h2>
|
||
<div class="box">
|
||
<form name="tuner" id="tuner">
|
||
<table>
|
||
<tr>
|
||
<td>Rx Frequency</td>
|
||
<td><input type="text" readonly name="rx_freq" id="rx_freq" value="">MHz</td>
|
||
<td>RSSI</td>
|
||
<td><input type="text" readonly name="rssi" id="rssi" value="">dBm</td>
|
||
</tr>
|
||
<tr>
|
||
<td>RSNR</td>
|
||
<td><input type="text" readonly name="rsnr" id="rsnr" value="">dB</td>
|
||
<td>Lock</td>
|
||
<td>
|
||
<select class="display-only-select" disabled name="lock" id="lock">
|
||
<option value="0">Unlock</option>
|
||
<option value="1">Lock</option>
|
||
</select>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</form>
|
||
</div>
|
||
|
||
<h2>PAC Status</h2>
|
||
<div class="box">
|
||
<form name="pac" id="pac_status">
|
||
<table>
|
||
<tr>
|
||
<td>Vol 9V</td><td><input type="text" readonly name="v9v" id="v9v" value="">V</td>
|
||
<td>Vol 12V</td><td><input type="text" readonly name="v12v" id="v12v" value="">V</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Vol 50V</td><td><input type="text" readonly name="v50v" id="v50v" value="">V</td>
|
||
<td>PA FWD</td><td><input type="text" readonly name="pac_fwd" id="pac_fwd" value="">W</td>
|
||
</tr>
|
||
<tr>
|
||
<td>PA REF</td><td><input type="text" readonly name="ref" id="ref" value="">W</td>
|
||
<td>VSWR</td><td><input type="text" readonly name="vswr" id="vswr" value=""></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Temperature</td>
|
||
<td>
|
||
<fieldset>
|
||
<input type="text" readonly name="temp" id="temp" value="">°F
|
||
<input type="text" readonly name="temp_c" id="temp_c" value="">°C
|
||
</fieldset>
|
||
</td>
|
||
<td>PA IN</td><td><input type="text" readonly name="pain" id="pain" value="">dBm</td>
|
||
</tr>
|
||
<tr>
|
||
<td>GV</td><td><input type="text" readonly name="gv" id="gv" value="">mV</td>
|
||
<td>PA Level</td>
|
||
<td>
|
||
<select class="display-only-select" disabled name="lvl" id="lvl">
|
||
<option value="0">0</option>
|
||
<option value="1">160</option>
|
||
<option value="2">310</option>
|
||
<option value="3">610</option>
|
||
</select>W
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td>50V Cur1</td><td><input type="text" readonly name="c50v1" id="c50v1" value="">A</td>
|
||
<td>50V Cur2</td><td><input type="text" readonly name="c50v2" id="c50v2" value="">A</td>
|
||
</tr>
|
||
<tr>
|
||
<td>50V Cur3</td><td><input type="text" readonly name="c50v3" id="c50v3" value="">A</td>
|
||
<td>50V Cur4</td><td><input type="text" readonly name="c50v4" id="c50v4" value="">A</td>
|
||
</tr>
|
||
</table>
|
||
</form>
|
||
</div>
|
||
|
||
<h2>GPS Status</h2>
|
||
<div class="box">
|
||
<form name="gps_form" id="gps_form">
|
||
<table>
|
||
<tr>
|
||
<td>GPS Lock</td><td><input type="text" readonly name="gps" id="gps" value=""></td>
|
||
<td>GPS</td><td><input type="text" readonly name="gps_in" id="gps_in" value=""></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Date</td><td><input type="text" readonly name="gps_date" id="gps_date" value=""></td>
|
||
<td>Time</td><td><input type="text" readonly name="gps_time" id="gps_time" value=""></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Satellite</td><td><input type="text" readonly name="gps_sv" id="gps_sv" value=""></td>
|
||
<td>Status</td><td><input type="text" readonly name="gps_status" id="gps_status" value=""></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Frequency</td><td><input type="text" readonly name="gps_freq" id="gps_freq" value=""></td>
|
||
</tr>
|
||
</table>
|
||
</form>
|
||
</div>
|
||
|
||
<h2>Version</h2>
|
||
<div class="box">
|
||
<form name="ver" id="version">
|
||
<table>
|
||
<tr>
|
||
<td>ATSC</td><td><input type="text" style="max-width: 150px;" readonly name="atsc_ver" id="atsc_ver" value=""></td>
|
||
<td>FPGA</td><td><input type="text" style="max-width: 150px;" readonly name="fpga_ver" id="fpga_ver" value=""></td>
|
||
</tr>
|
||
<tr>
|
||
<td>MCU</td><td><input type="text" style="max-width: 150px;" readonly name="mcu_ver" id="mcu_ver" value=""></td>
|
||
<td>DryLoop</td><td><input type="text" style="max-width: 150px;" readonly name="plc_ver" id="plc_ver" value=""></td>
|
||
</tr>
|
||
</table>
|
||
</form>
|
||
</div>
|
||
|
||
<h2>MAC&SN</h2>
|
||
<div class="box">
|
||
<form name="macsn" id="macsn">
|
||
<table>
|
||
<tr>
|
||
<td>MAC</td><td><input type="text" style="max-width: 150px;" readonly name="mac" id="mac" value=""></td>
|
||
<td>SN</td><td><input type="text" style="max-width: 150px;" readonly name="sn" id="sn" value=""></td>
|
||
</tr>
|
||
</table>
|
||
</form>
|
||
</div>
|
||
|
||
<h2>License</h2>
|
||
<div class="box">
|
||
<form name="license" id="license">
|
||
<table>
|
||
<tr>
|
||
<td>PSIP Editing</td>
|
||
<td><input type="text" style="max-width: 150px;" readonly name="pisp_editing_lc" id="pisp_editing_lc" value=""></td>
|
||
<td>EAS</td>
|
||
<td><input type="text" style="max-width: 150px;" readonly name="eas_lc" id="eas_lc" value=""></td>
|
||
</tr>
|
||
</table>
|
||
</form>
|
||
</div>
|
||
|
||
<br><br><br>
|
||
</main>
|
||
</div>
|
||
|
||
<div id="accountModal" class="modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3>Account Settings</h3>
|
||
<span class="close" onclick="closeAccountModal()">×</span>
|
||
</div>
|
||
<div class="modal-body">
|
||
<form id="accountForm" method="post" action="login.cgi?action=change_account" onsubmit="return validateAccountForm()">
|
||
<table class="modal-table">
|
||
<tr>
|
||
<td>Current Username</td>
|
||
<td><input type="text" id="current_user" name="current_user" readonly></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Current Password</td>
|
||
<td><input type="password" id="current_pwd" name="current_pwd" required></td>
|
||
</tr>
|
||
<tr>
|
||
<td>New Username</td>
|
||
<td><input type="text" id="new_user" name="new_user"></td>
|
||
</tr>
|
||
<tr>
|
||
<td>New Password</td>
|
||
<td><input type="password" id="new_pwd" name="new_pwd"></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Confirm Password</td>
|
||
<td><input type="password" id="confirm_pwd" name="confirm_pwd"></td>
|
||
</tr>
|
||
</table>
|
||
<div class="modal-footer">
|
||
<input type="button" class="btn-modern" style="background-color: #64748b;" value="Cancel" onclick="closeAccountModal()">
|
||
<input type="submit" class="btn-modern" value="Save Changes">
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
function toggleSidebar(){
|
||
document.querySelector('.app-sidebar').classList.toggle('sidebar-open');
|
||
document.querySelector('.sidebar-overlay').classList.toggle('active');
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|