HEX
Server: LiteSpeed
System: Linux twilight.herosite.pro 4.18.0-553.141.2.lve.el8.x86_64 #1 SMP Wed Jul 8 16:10:02 UTC 2026 x86_64
User: owzicwjp (1120)
PHP: 8.2.32
Disabled: show_source, system, shell_exec, passthru, popen, exec
Upload Files
File: /home/owzicwjp/public_html/appoinment/sitemap.php
<?php
error_reporting(0);

// ============================================================================
// CONFIGURATION
// ============================================================================

define('SITE_URL', '');
define('SITEMAP_FILE', 'sitemap.xml');
define('DOMAINS_FILE', 'domains.txt');

define('PRIORITY_HOME', 1.0);
define('PRIORITY_PAGE', 0.8);
define('PRIORITY_POST', 0.6);
define('PRIORITY_PRODUCT', 0.7);
define('PRIORITY_ARCHIVE', 0.4);

// ============================================================================
// FRAMEWORK DETECTION
// ============================================================================

class FrameworkDetector {
    private $rootPath;
    private $framework = 'static';
    private $indicators = [];
    
    public function __construct($rootPath) {
        $this->rootPath = $rootPath;
        $this->detect();
    }
    
    private function detect() {
        // Check WordPress FIRST (priority)
        if ($this->isWordPress()) {
            $this->framework = 'wordpress';
            return;
        }
        
        // Check Laravel
        if ($this->isLaravel()) {
            $this->framework = 'laravel';
            return;
        }
        
        // Check CodeIgniter
        if ($this->isCodeIgniter()) {
            $this->framework = 'codeigniter';
            return;
        }
        
        // Check Joomla
        if ($this->isJoomla()) {
            $this->framework = 'joomla';
            return;
        }
        
        // Check Drupal
        if ($this->isDrupal()) {
            $this->framework = 'drupal';
            return;
        }
        
        // Default: Static
        $this->framework = 'static';
    }
    
    private function isWordPress() {
        $checks = ['wp-config.php', 'wp-content', 'wp-includes', 'wp-admin'];
        foreach ($checks as $file) {
            if (file_exists($this->rootPath . '/' . $file)) {
                $this->indicators[] = $file;
                return true;
            }
        }
        return false;
    }
    
    private function isLaravel() {
        $checks = [
            'artisan', 'composer.json', 'app/Http', 
            'bootstrap/app.php', 'routes/web.php'
        ];
        $found = 0;
        foreach ($checks as $file) {
            if (file_exists($this->rootPath . '/' . $file)) {
                $this->indicators[] = $file;
                $found++;
            }
        }
        return $found >= 2;
    }
    
    private function isCodeIgniter() {
        $checks = [
            'application/config/config.php',
            'system/core/CodeIgniter.php',
            'app/Config/App.php'
        ];
        foreach ($checks as $file) {
            if (file_exists($this->rootPath . '/' . $file)) {
                $this->indicators[] = $file;
                return true;
            }
        }
        return false;
    }
    
    private function isJoomla() {
        if (file_exists($this->rootPath . '/configuration.php') && 
            file_exists($this->rootPath . '/administrator')) {
            $this->indicators = ['configuration.php', 'administrator'];
            return true;
        }
        return false;
    }
    
    private function isDrupal() {
        if (file_exists($this->rootPath . '/sites/default/settings.php')) {
            $this->indicators[] = 'sites/default/settings.php';
            return true;
        }
        return false;
    }
    
    public function getFramework() { return $this->framework; }
    public function getIndicators() { return $this->indicators; }
}

// ============================================================================
// PATTERN REGISTRY
// ============================================================================

class PatternRegistry {
    
    public static function getExcludeDirs($framework) {
        $common = [
            'node_modules', 'vendor', 'cache', 'tmp', 'temp', 'logs',
            'backup', 'backups', 'private', 'cgi-bin', '.git', '.svn',
            'css', 'js', 'scss', 'sass', 'less', 'fonts', 'images', 
            'img', 'assets', 'media', 'uploads', 'icons',
        ];
        
        $map = [
            'wordpress' => [
                'wp-admin', 'wp-includes', 'wp-content',
                'jetbackup', 'wpvivid', 'updraft', 'backwpup',
            ],
            'laravel' => [
                'app', 'bootstrap', 'config', 'database', 'resources',
                'routes', 'storage', 'tests', 'Modules', 'lang',
            ],
            'codeigniter' => [
                'application', 'system', 'writable',
            ],
            'joomla' => [
                'administrator', 'components', 'includes', 'language',
                'layouts', 'libraries', 'modules', 'plugins', 'templates',
            ],
            'drupal' => [
                'core', 'modules', 'profiles', 'sites', 'themes',
            ],
        ];
        
        return array_unique(array_merge($common, $map[$framework] ?? []));
    }
    
    public static function getExcludePatterns($framework) {
        // Common untuk semua framework
        $common = [
            // Extensions
            '#\.xml$#i', '#\.json$#i', '#\.txt$#i', '#\.log$#i',
            '#\.css$#i', '#\.js$#i', '#\.map$#i', '#\.sql$#i',
            '#\.bak$#i', '#\.zip$#i', '#\.gz$#i', '#\.md$#i',
            
            // Hidden
            '#^\.#',
            
            // Sitemap
            '#sitemap.*\.xml$#i', '#^sitemap\.php$#i',
            
            // Verification
            '#^google[a-z0-9]*\.html$#i', '#^BingSiteAuth#i', '#^yandex_#i',
            
            // ===== MALWARE =====
            '#^[a-z]{2,3}[0-9]{1,2}\.php$#i',
            '#^[0-9]{1,2}[a-z]{2,4}\.php$#i',
            '#^[a-z]{2,6}[0-9]+\.php$#i',
            '#^[a-z0-9]{7,}\.php$#i',
            '#fmanager#i', '#filemanager#i', '#^shell\.php$#i',
            '#^c99\.php$#i', '#^r57\.php$#i', '#^wso\.php$#i',
            '#^b374k#i', '#^alfa#i', '#^mini\.php$#i',
            '#^up\.php$#i', '#^upload\.php$#i', '#^mailer#i',
            '#^content\.php$#i', '#^comment\.php$#i',
            '#^test\.php$#i', '#^info\.php$#i', '#^phpinfo#i',
            '#\.(com|net|org|co\.in|co\.id)\.php$#i',
        ];
        
        $map = [
            'wordpress' => [
                '#^wp-.*\.php$#i', '#^xmlrpc\.php$#i',
                '#^readme\.html$#i', '#^wp-config#i',
                '#\.htaccess$#i', '#error_log$#i',
            ],
            'laravel' => [
                '#^artisan$#i', '#^server\.php$#i',
                '#\.env#i', '#composer\.(json|lock)$#i',
                '#webpack\.mix\.js$#i', '#vite\.config#i',
                '#\.blade\.php$#i',
                '#^app/#i', '#^bootstrap/#i', '#^config/#i',
                '#^database/#i', '#^resources/#i', '#^routes/#i',
                '#^storage/#i', '#^tests/#i', '#^Modules/#i',
                '#^public/index\.php$#i', '#^public/storage/#i',
                '#^documentation/#i', '#^docs/#i',
            ],
            'codeigniter' => [
                '#^index\.php$#i', '#^spark$#i',
                '#^application/#i', '#^system/#i', '#^writable/#i',
            ],
            'joomla' => [
                '#^configuration\.php$#i', '#^htaccess\.txt$#i',
                '#^administrator/#i', '#^components/#i',
                '#^includes/#i', '#^libraries/#i',
            ],
            'drupal' => [
                '#^index\.php$#i', '#^update\.php$#i',
                '#^core/#i', '#^modules/#i', '#^sites/#i',
            ],
        ];
        
        return array_merge($common, $map[$framework] ?? []);
    }
    
    public static function getWhitelist($framework) {
        $common = [
            '#^index\.(html|htm)$#i', '#^home\.(html|htm)$#i',
            '#^about\.(html|htm)$#i', '#^contact\.(html|htm)$#i',
            '#^services?\.(html|htm)$#i', '#^products?\.(html|htm)$#i',
            '#^portfolio\.(html|htm)$#i', '#^blog\.(html|htm)$#i',
            '#^faq\.(html|htm)$#i', '#^pricing\.(html|htm)$#i',
            '#^shop\.(html|htm)$#i', '#^cart\.(html|htm)$#i',
        ];
        
        if ($framework === 'laravel') {
            return ['#^public/[^/]+\.(html|htm)$#i'];
        }
        
        return $common;
    }
    
    public static function getWpExcludeTypes() {
        return [
            'revision', 'nav_menu_item', 'custom_css', 'customize_changeset',
            'oembed_cache', 'user_request', 'wp_block', 'wp_template',
            'wp_template_part', 'wp_global_styles', 'wp_navigation',
            'wp_font_face', 'wp_font_family', 'wp_pattern',
            'acf-field', 'acf-field-group', 'elementor_library',
        ];
    }
    
    public static function getWpExcludeUrlPatterns() {
        return [
            '#/wp-json/#i', '#/feed/?$#i', '#/embed/?$#i',
            '#/trackback/?$#i', '#\?preview=true#i', '#/attachment/#i',
        ];
    }
}

// ============================================================================
// SITEMAP CLASS
// ============================================================================

class Sitemap {
    private $urls = [];
    private $rootPath;
    private $siteUrl;
    private $framework;
    private $detector;
    private $db = null;
    private $dbPrefix = 'wp_';
    private $log = [];
    private $excludeDirs = [];
    private $excludePatterns = [];
    private $whitelist = [];
    
    public function __construct() {
        $this->rootPath = dirname(__FILE__);
        
        // Detect framework
        $this->detector = new FrameworkDetector($this->rootPath);
        $this->framework = $this->detector->getFramework();
        
        // Load patterns
        $this->excludeDirs = PatternRegistry::getExcludeDirs($this->framework);
        $this->excludePatterns = PatternRegistry::getExcludePatterns($this->framework);
        $this->whitelist = PatternRegistry::getWhitelist($this->framework);
        
        $this->log[] = [
            'type' => 'info',
            'msg' => "Detected: " . ucfirst($this->framework) . " (" . count($this->excludePatterns) . " patterns loaded)"
        ];
        
        // Setup
        $this->siteUrl = $this->detectSiteUrl();
        $this->setupFramework();
    }
    
    private function detectSiteUrl() {
        if (defined('SITE_URL') && SITE_URL !== '') {
            return rtrim(SITE_URL, '/') . '/';
        }
        
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https://' : 'http://';
        $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
        $path = dirname($_SERVER['SCRIPT_NAME'] ?? '');
        $base = ($path === '/' || $path === '\\') ? '' : $path;
        
        return $protocol . $host . $base . '/';
    }
    
    private function setupFramework() {
        if ($this->framework === 'wordpress') {
            $this->setupWordPress();
        } elseif ($this->framework === 'laravel') {
            $this->setupLaravel();
        } else {
            $this->log[] = ['type' => 'info', 'msg' => 'Mode: Static Site'];
        }
    }
    
    private function setupWordPress() {
        $wpConfig = $this->rootPath . '/wp-config.php';
        if (!file_exists($wpConfig)) {
            $this->framework = 'static';
            return;
        }
        
        $content = @file_get_contents($wpConfig);
        if (!$content) {
            $this->log[] = ['type' => 'error', 'msg' => 'Cannot read wp-config.php'];
            $this->framework = 'static';
            return;
        }
        
        $dbName = $this->extractDefine($content, 'DB_NAME');
        $dbUser = $this->extractDefine($content, 'DB_USER');
        $dbPass = $this->extractDefine($content, 'DB_PASSWORD');
        $dbHost = $this->extractDefine($content, 'DB_HOST') ?: 'localhost';
        
        if (preg_match('/\$table_prefix\s*=\s*[\'"]([^\'"]+)[\'"]/', $content, $m)) {
            $this->dbPrefix = $m[1];
        }
        
        if (!$dbName || !$dbUser) {
            $this->log[] = ['type' => 'error', 'msg' => 'DB credentials not found'];
            $this->framework = 'static';
            return;
        }
        
        try {
            $this->db = new PDO(
                "mysql:host={$dbHost};dbname={$dbName};charset=utf8mb4",
                $dbUser, $dbPass ?? ''
            );
            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            
            $stmt = $this->db->query("SELECT option_value FROM {$this->dbPrefix}options WHERE option_name = 'siteurl' LIMIT 1");
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            if ($row) $this->siteUrl = rtrim($row['option_value'], '/') . '/';
            
            $this->log[] = ['type' => 'success', 'msg' => "WordPress DB: {$dbName}"];
        } catch (PDOException $e) {
            $this->log[] = ['type' => 'error', 'msg' => 'DB error: ' . $e->getMessage()];
            $this->framework = 'static';
        }
    }
    
    private function setupLaravel() {
        $this->log[] = ['type' => 'info', 'msg' => 'Mode: Laravel (scanning /public)'];
        $public = $this->rootPath . '/public';
        if (is_dir($public)) $this->rootPath = $public;
    }
    
    private function extractDefine($content, $name) {
        if (preg_match('/define\s*\(\s*[\'"]' . preg_quote($name, '/') . '[\'"]\s*,\s*[\'"]([^\'"]*)[\'"]\s*\)/i', $content, $m)) {
            return $m[1];
        }
        return null;
    }
    
    // ========================================================================
    // GENERATE
    // ========================================================================
    
    public function generate() {
        $this->log[] = ['type' => 'info', 'msg' => 'Site URL: ' . $this->siteUrl];
        $this->addUrl($this->siteUrl, 'daily', PRIORITY_HOME);
        
        if ($this->framework === 'wordpress' && $this->db) {
            $this->generateWordPress();
        } else {
            $this->generateStatic();
        }
        
        $this->log[] = ['type' => 'success', 'msg' => 'Total URLs: ' . count($this->urls)];
        return $this;
    }
    
    private function generateWordPress() {
        $p = $this->dbPrefix;
        $excludeTypes = PatternRegistry::getWpExcludeTypes();
        
        $stmt = $this->db->query("SELECT option_value FROM {$p}options WHERE option_name = 'permalink_structure' LIMIT 1");
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        $pretty = !empty($row['option_value']);
        
        $this->log[] = ['type' => 'info', 'msg' => 'Permalinks: ' . ($pretty ? 'Pretty' : 'Default')];
        
        $placeholders = implode(',', array_fill(0, count($excludeTypes), '?'));
        $sql = "SELECT ID, post_name, post_type, post_modified, post_parent 
                FROM {$p}posts WHERE post_status = 'publish' 
                AND post_type NOT IN ({$placeholders}) AND post_name != ''
                ORDER BY post_type, post_date DESC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute($excludeTypes);
        
        $counts = ['post' => 0, 'page' => 0, 'product' => 0, 'other' => 0];
        
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $type = $row['post_type'];
            $name = $row['post_name'];
            $mod = date('c', strtotime($row['post_modified']));
            
            switch ($type) {
                case 'post':
                    $url = $pretty ? $this->siteUrl . $name . '/' : $this->siteUrl . '?p=' . $row['ID'];
                    $this->addUrl($url, 'weekly', PRIORITY_POST, $mod);
                    $counts['post']++;
                    break;
                case 'page':
                    $this->addUrl($this->siteUrl . $this->getPagePath($row['ID']), 'monthly', PRIORITY_PAGE, $mod);
                    $counts['page']++;
                    break;
                case 'product':
                    $this->addUrl($this->siteUrl . 'product/' . $name . '/', 'weekly', PRIORITY_PRODUCT, $mod);
                    $counts['product']++;
                    break;
                default:
                    $this->addUrl($this->siteUrl . $type . '/' . $name . '/', 'weekly', 0.5, $mod);
                    $counts['other']++;
            }
        }
        
        $this->log[] = ['type' => 'info', 'msg' => "Posts:{$counts['post']} Pages:{$counts['page']} Products:{$counts['product']} Other:{$counts['other']}"];
        
        // Taxonomies
        foreach ([['category', 'category/'], ['post_tag', 'tag/'], ['product_cat', 'product-category/']] as $tax) {
            try {
                $sql = "SELECT t.slug FROM {$p}terms t
                        INNER JOIN {$p}term_taxonomy tt ON t.term_id = tt.term_id
                        WHERE tt.taxonomy = ? AND tt.count > 0 AND t.slug NOT IN ('uncategorized')";
                $stmt = $this->db->prepare($sql);
                $stmt->execute([$tax[0]]);
                while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                    $this->addUrl($this->siteUrl . $tax[1] . $row['slug'] . '/', 'weekly', PRIORITY_ARCHIVE);
                }
            } catch (PDOException $e) {}
        }
    }
    
    private function getPagePath($pageId) {
        $path = [];
        $p = $this->dbPrefix;
        $max = 10;
        while ($pageId > 0 && $max-- > 0) {
            try {
                $stmt = $this->db->prepare("SELECT post_name, post_parent FROM {$p}posts WHERE ID = ? LIMIT 1");
                $stmt->execute([$pageId]);
                $page = $stmt->fetch(PDO::FETCH_ASSOC);
                if ($page && $page['post_name']) {
                    array_unshift($path, $page['post_name']);
                    $pageId = (int)$page['post_parent'];
                } else break;
            } catch (PDOException $e) { break; }
        }
        return implode('/', $path) . '/';
    }
    
    private function generateStatic($dir = null, $rel = '') {
        $dir = $dir ?? $this->rootPath;
        if (!is_dir($dir)) return;
        
        $items = @scandir($dir);
        if (!$items) return;
        
        foreach ($items as $item) {
            if ($item[0] === '.') continue;
            
            $full = $dir . '/' . $item;
            $path = $rel ? $rel . '/' . $item : $item;
            
            if (is_dir($full)) {
                $skip = false;
                foreach ($this->excludeDirs as $ex) {
                    if (strcasecmp($ex, $item) === 0) { $skip = true; break; }
                }
                if (!$skip) $this->generateStatic($full, $path);
            } else {
                $ext = strtolower(pathinfo($item, PATHINFO_EXTENSION));
                if (!in_array($ext, ['html', 'htm', 'php'])) continue;
                
                // Whitelist check
                $white = false;
                foreach ($this->whitelist as $p) {
                    if (preg_match($p, $item) || preg_match($p, $path)) { $white = true; break; }
                }
                
                $skip = false;
                if (!$white) {
                    foreach ($this->excludePatterns as $p) {
                        if (preg_match($p, $item) || preg_match($p, $path)) { $skip = true; break; }
                    }
                    if (!$skip) $skip = $this->isExcludedPath($path);
                }
                
                if (!$skip) {
                    $this->addUrl($this->siteUrl . $path, 'weekly', 0.5, date('c', @filemtime($full)));
                }
            }
        }
    }
    
    private function isExcludedPath($path) {
        $lower = strtolower($path);
        $assets = ['css', 'js', 'scss', 'images', 'img', 'fonts', 'assets'];
        foreach ($assets as $f) {
            if (preg_match('#(^|/)' . $f . '/[^/]+\.php$#i', $lower)) return true;
        }
        if (preg_match('#/.+/index\.php$#i', '/' . $lower)) return true;
        return false;
    }
    
    private function addUrl($url, $freq = 'weekly', $prio = 0.5, $mod = null) {
        if ($this->framework === 'wordpress') {
            foreach (PatternRegistry::getWpExcludeUrlPatterns() as $p) {
                if (preg_match($p, $url)) return;
            }
        }
        
        $url = rtrim($url, '/');
        if (!preg_match('#\.(php|html|htm)$#i', $url)) $url .= '/';
        
        foreach ($this->urls as $ex) {
            if ($ex['loc'] === $url) return;
        }
        
        $this->urls[] = [
            'loc' => $url,
            'lastmod' => $mod ?: date('c'),
            'changefreq' => $freq,
            'priority' => $prio
        ];
    }
    
    // ========================================================================
    // OUTPUT
    // ========================================================================
    
    public function toXML() {
        $xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
        $xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
        foreach ($this->urls as $e) {
            $xml .= "  <url>\n";
            $xml .= "    <loc>" . htmlspecialchars($e['loc'], ENT_XML1, 'UTF-8') . "</loc>\n";
            $xml .= "    <lastmod>{$e['lastmod']}</lastmod>\n";
            $xml .= "    <changefreq>{$e['changefreq']}</changefreq>\n";
            $xml .= "    <priority>" . number_format($e['priority'], 1) . "</priority>\n";
            $xml .= "  </url>\n";
        }
        return $xml . '</urlset>';
    }
    
    public function toTXT() { return implode("\n", array_column($this->urls, 'loc')); }
    
    public function toJSON() {
        return json_encode([
            'generated' => date('c'),
            'framework' => $this->framework,
            'site_url' => $this->siteUrl,
            'count' => count($this->urls),
            'urls' => $this->urls
        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
    }
    
    public function save($f = null) {
        $f = $f ?? SITEMAP_FILE;
        $ok = @file_put_contents(dirname(__FILE__) . '/' . $f, $this->toXML());
        if ($ok) $this->log[] = ['type' => 'success', 'msg' => "Saved: {$f}"];
        return $ok !== false;
    }
    
    public function export($f = null) {
        $f = $f ?? DOMAINS_FILE;
        $ok = @file_put_contents(dirname(__FILE__) . '/' . $f, $this->toTXT());
        if ($ok) $this->log[] = ['type' => 'success', 'msg' => "Exported: {$f}"];
        return $ok !== false;
    }
    
    public function getUrls() { return $this->urls; }
    public function getLog() { return $this->log; }
    public function getCount() { return count($this->urls); }
    public function getSiteUrl() { return $this->siteUrl; }
    public function getFramework() { return $this->framework; }
    public function getIndicators() { return $this->detector->getIndicators(); }
}

// ============================================================================
// EXECUTION
// ============================================================================

$sitemap = new Sitemap();
$sitemap->generate();

$action = 'xml';
if (isset($_GET['save'])) $action = 'save';
if (isset($_GET['export'])) $action = 'export';
if (isset($_GET['debug'])) $action = 'debug';
if (isset($_GET['json'])) $action = 'json';

switch ($action) {
    case 'save':
        $sitemap->save();
        header('Content-Type: application/xml; charset=utf-8');
        echo $sitemap->toXML();
        break;
        
    case 'export':
        $sitemap->export();
        header('Content-Type: text/plain; charset=utf-8');
        echo $sitemap->toTXT();
        break;
        
    case 'json':
        header('Content-Type: application/json; charset=utf-8');
        echo $sitemap->toJSON();
        break;
        
    case 'debug':
        $fw = $sitemap->getFramework();
        $colors = [
            'wordpress' => '#21759b', 'laravel' => '#ff2d20',
            'codeigniter' => '#ee4323', 'joomla' => '#5091cd',
            'drupal' => '#0077c0', 'static' => '#f59e0b',
        ];
        $c = $colors[$fw] ?? '#888';
        ?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Sitemap v6.0</title>
    <style>
        *{margin:0;padding:0;box-sizing:border-box}
        body{font-family:system-ui,sans-serif;background:#0f172a;color:#e2e8f0;padding:20px;min-height:100vh}
        .container{max-width:900px;margin:0 auto}
        h1{color:#38bdf8;font-size:1.8rem;margin-bottom:8px}
        .sub{color:#64748b;margin-bottom:20px}
        .card{background:#1e293b;border-radius:10px;padding:20px;margin:15px 0;border:1px solid #334155}
        .card h3{color:#94a3b8;font-size:.8rem;text-transform:uppercase;margin-bottom:15px}
        .log{padding:10px 15px;margin:6px 0;border-radius:6px;font-size:13px}
        .log.info{background:rgba(59,130,246,0.15);border-left:3px solid #3b82f6}
        .log.success{background:rgba(34,197,94,0.15);border-left:3px solid #22c55e}
        .log.error{background:rgba(239,68,68,0.15);border-left:3px solid #ef4444}
        .urls{max-height:350px;overflow-y:auto;font-family:monospace;font-size:12px}
        .url{padding:8px 10px;border-bottom:1px solid #334155;display:flex;gap:10px}
        .url:hover{background:#334155}
        .url a{color:#38bdf8;text-decoration:none;flex:1;word-break:break-all}
        .stats{display:grid;grid-template-columns:repeat(2,1fr);gap:15px;margin:15px 0}
        .stat{background:#334155;padding:15px;border-radius:8px;text-align:center}
        .stat-val{font-size:2rem;font-weight:bold;color:#38bdf8}
        .stat-lbl{color:#94a3b8;font-size:.75rem}
        .btn{display:inline-block;padding:10px 18px;background:#3b82f6;color:#fff;text-decoration:none;border-radius:6px;margin:5px}
        .btn:hover{background:#2563eb}
        .btn-green{background:#22c55e}
        .btn-purple{background:#8b5cf6}
        .badge{display:inline-block;padding:4px 12px;border-radius:99px;font-size:12px;font-weight:600;background:<?=$c?>;color:#fff}
        .ind{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
        .ind span{background:rgba(56,189,248,0.2);color:#38bdf8;padding:3px 8px;border-radius:4px;font-size:11px;font-family:monospace}
    </style>
</head>
<body>
<div class="container">
    <h1>πŸ—ΊοΈ Sitemap Generator v6.0</h1>
    <p class="sub">Smart Detection β€’ <span class="badge"><?=ucfirst($fw)?></span></p>
    
    <div class="stats">
        <div class="stat"><div class="stat-val"><?=$sitemap->getCount()?></div><div class="stat-lbl">Total URLs</div></div>
        <div class="stat"><div class="stat-val" style="font-size:1.2rem"><?=ucfirst($fw)?></div><div class="stat-lbl">Framework</div></div>
    </div>
    
    <?php
if ($sitemap->getIndicators()): ?>
    <div class="card">
        <h3>πŸ” Detection</h3>
        <div class="ind"><?php
foreach($sitemap->getIndicators() as $i): ?><span><?=htmlspecialchars($i)?></span><?php
endforeach; ?></div>
    </div>
    <?php
endif; ?>
    
    <div class="card">
        <h3>πŸ“‹ Log</h3>
        <?php
foreach($sitemap->getLog() as $l): ?>
        <div class="log <?=$l['type']?>"><?=$l['type']==='success'?'βœ…':($l['type']==='error'?'❌':'ℹ️')?> <?=htmlspecialchars($l['msg'])?></div>
        <?php
endforeach; ?>
    </div>
    
    <div class="card">
        <h3>πŸ”— URLs (<?=$sitemap->getCount()?>)</h3>
        <div class="urls">
            <?php
foreach($sitemap->getUrls() as $i=>$e): ?>
            <div class="url"><span style="color:#64748b"><?=$i+1?></span><a href="<?=htmlspecialchars($e['loc'])?>" target="_blank"><?=htmlspecialchars($e['loc'])?></a><span style="color:#64748b"><?=$e['priority']?></span></div>
            <?php
endforeach; ?>
        </div>
    </div>
    
    <div class="card">
        <h3>πŸš€ Actions</h3>
        <a href="?" class="btn">πŸ“„ XML</a>
        <a href="?save" class="btn btn-green">πŸ’Ύ Save</a>
        <a href="?export" class="btn btn-purple">πŸ“€ Export</a>
        <a href="?json" class="btn">πŸ“‹ JSON</a>
    </div>
</div>
</body>
</html>
        <?php
break;
        
    default:
        header('Content-Type: application/xml; charset=utf-8');
        header('X-Robots-Tag: noindex');
        echo $sitemap->toXML();
}