private function chunk($text, $width)
    {
        $chunks = [];
        $current = '';
        $currentLength = 0;
        $styleStack = [];

        $bufferLength = mb_strwidth($text);
        for ($i = 0; $i < $bufferLength; ++$i) {
            if ($text[$i] === "\033") { // start of formatting?
                // Add to current and skip length.
                $length = strpos($text, 'm', $i) - $i;
                $style = substr($text, $i, $length + 1);
                $current .= $style;
                $i += $length;

                $codes = explode(';', substr($style, 2, -1));
                $start = (bool) array_diff($codes, [22, 24, 25, 27, 28, 39, 49]);
                if ($start) {
                    $styleStack[] = $codes;
                } else {
                    array_pop($styleStack);
                }
            } else {
                $current .= $text[$i];
                ++$currentLength;
            }

            if ($currentLength >= $width || $i + 1 === $bufferLength) {
                foreach (array_reverse($styleStack) as $startStyleCodes) {
                    $endStyleCodes = [];
                    foreach ($startStyleCodes as $code) {
                        if (strlen($code) === 1) {
                            $endStyleCodes[] = '2' . $code;
                        } elseif ($code[0] === '3') {
                            $endStyleCodes[] = '39';
                        } elseif ($code[0] === '4') {
                            $endStyleCodes[] = '49';
                        }
                    }
                    $current .= sprintf("\033[%sm", implode(';', $endStyleCodes));
                }
                $chunks[] = $current;
                $current = '';
                $currentLength = 0;

                foreach ($styleStack as $startStyleCodes) {
                    $current .= sprintf("\033[%sm", implode(';', $startStyleCodes));
                }
            }
        }

        return $chunks;
    }