'); } render("
{$str}
"); } public function info(string $str, bool $newline = false): void { if ($newline) { render('
'); } render("
{$str}
"); } public function notice(string $str, bool $newline = false): void { if ($newline) { render('
'); } render("
{$str}
"); } public function warning(string $str, bool $newline = false): void { if ($newline) { render('
'); } render("
{$str}
"); } public function error(string $str, bool $newline = false): void { if ($newline) { render('
'); } render("
{$str}
"); } public function primary(string $str, bool $newline = false): void { if ($newline) { render('
'); } render("
{$str}
"); } public function header(string $str, bool $newline = false): void { if ($newline) { render('
'); } render("
{$str}
"); } public function alternate(string $str, bool $newline = false): void { if ($newline) { render('
'); } render("
{$str}
"); } public function tmuxOrange(string $str, bool $newline = false): void { if ($newline) { render('
'); } render("
{$str}
"); } public function primaryOver(string $str): void { echo "\033[32m{$str}\033[0m"; } public function headerOver(string $str): void { echo "\033[33m{$str}\033[0m"; } public function alternateOver(string $str): void { echo "\033[1;35m{$str}\033[0m"; } public function warningOver(string $str): void { echo "\033[31m{$str}\033[0m"; } public function progress(): object { return new class { private int $total = 0; private int $current = 0; private string $label = ''; public function total(int $total): self { $this->total = $total; return $this; } public function current(int $current, ?string $label = null): void { $this->current = $current; if ($label !== null) { $this->label = $label; } $this->display(); } public function advance(int $step = 1, ?string $label = null): void { $this->current += $step; if ($label !== null) { $this->label = $label; } $this->display(); } private function display(): void { $percentage = $this->total > 0 ? (int) (($this->current / $this->total) * 100) : 0; $bar = str_repeat('=', (int) ($percentage / 2)); $spaces = str_repeat(' ', 50 - (int) ($percentage / 2)); $label = $this->label ? " {$this->label}" : ''; echo "\r[{$bar}{$spaces}] {$percentage}%{$label}"; if ($this->current >= $this->total) { echo "\n"; } } }; } /** * Apply ANSI color code to a string and return it (does not render) * * @param string $string The string to colorize * @param string $color The color name * @return string The colored string with ANSI codes */ public function ansiString(string $string, string $color): string { $colors = [ 'black' => '0;30', 'red' => '0;31', 'green' => '0;32', 'yellow' => '0;33', 'blue' => '0;34', 'magenta' => '0;35', 'cyan' => '0;36', 'white' => '0;37', ]; $code = $colors[$color] ?? '0;37'; return "\033[{$code}m{$string}\033[0m"; } }