violawww

«Виола»: тег TB

Всё это время я программировал с нейросетями, в основном с использованием самых мощных моделей, которые только доступны, но некоторое время назад решил изменить вектор. Теперь я, напротив, хочу посмотреть, на что способны более простые модели, в частности «Композер» (это дообученная открытая модель «Кими»), который входит в подписку «Курсора».

Для этого я использую свой любимый полигон — браузер «Виола». Я подыскал несколько несложных задач из разряда «найти бы место, а поправить можно за полчаса», то есть такие, где важно понять, где поправить; сама правка сложной не выглядит.

Сравнение HTML-кода и его отображения: тег сохраняет пробелы и переносы, а теги и формируют курсив и жирный шрифт соответственно.

Одна из задач — дописать нестандартный тег TB, который автор так и не завершил. Судя по иллюстрациям в его недописанной книге о браузере, этот тег предназначался для разрыва таблицы: на рисунке он стоит между строкой «HTML Source / Output» и последующими. Вероятнее всего, TB расшифровывается как Table Bar.

Модель «Композер 2.0» справилась с задачей, в принципе, на «отлично» — лучше и желать нельзя. Моментально нашла место и поправила всё как надо с первой попытки. Я-то её считал совсем негодной, но нет, надо увеличить сложность задачи, посмотрим, где предел.

Интересно, кстати, что иллюстрации в книге не совпадают с реальным поведением браузера. Такое ощущение, что автор браузера их либо дорисовывал потом в редакторе, либо всё-таки был какой-то чуть более дописанный браузер, исходный код которого не сохранился.

2 комментария

Чтение образов NeXTSTEP

Если вам (ну вдруг) когда-нибудь понадобится читать образы операционной системы NeXTSTEP, вам поможет утилита iso2next. Она умеет всё необходимое: просматривать листинг, открывать файлы и копировать их наружу.

Мне пришлось заняться этим вопросом, потому что я надеялся, что внутри одного из найденных образов этой системы меня могут ждать новые открытия, связанные с браузером «Виола».

Пользоваться утилитой не очень удобно, особенно если не вполне ясно что ищешь, но её довольно просто подключить к известному файловому менеджеру mc (Midnight Commander).

Скриншот файлового менеджера: две панели с директориями /me/Apps/viola940323 и /mosaic-personal-annotations, файлы, даты 1994, строка bash-3.2$.

Достаточно написать обёртку, которая принимает на вход две команды — list (выдача списка файлов в директории) и copyout (копирование указанного файла в указанный путь), — и всё заработает.

Правда у исходной утилиты в листинге отсутствуют некоторые необходимые поля (в частности — дата), поэтому мне пришлось добавить заглушки на эти позиции. Я уже отправил автору утилиты патч, который устраняет этот недостаток (заодно я пару багов нашёл и исправил).

К сожалению, ничего полезного внутри образа я не нашёл, но опыт интересный.

20 комментариев

«Виола»: нейросеть «Опус 4.6»

Недавно компания «Антропик» выпустила новую нейросеть для программирования — «Опус 4.6». Я с большим интересом слежу за тем, что они выпускают, потому что, по моему опыту, их сетки программируют лучше любых других.

У меня в загашнике есть несколько сложных задач и с каждым обновлением программирующих нейросетей этот список потихоньку убывает — те задачи, которые ещё недавно были им не по зубам, постепенно поддаются.

«Опус 4.6» я тестировал на задаче реализации типа нумерации для списков в «Виоле» — в найденных мной материалах упоминается, что такая возможность должна быть, но она так и осталась нереализованной.

Скриншот веб-страницы «numStyle Test - List Numbering Styles» с примерами вложенных списков: римские цифры, арабские числа и буквы, включая раздел «Long Roman Numeral List».

До выхода «Опуса 4.6» нейросети с этой задачей не справлялись — либо ломали код, либо делали довольно кривую реализацию. «4.6» с задачей справилась. Рабочую реализацию она написала примерно с третьего раза, но я считаю, что это очень хороший результат, учитывая скорость её работы. Правда было два неприятных момента.

Во-первых, она самовольно ограничила вложенность списков шестью уровнями. Я нашёл это место на ревью кода, попросил убрать, и сеть довольно легко избавилась от ограничения. То есть никакой реальной необходимости в этом не было.

Во-вторых, в оригинальном коде есть баг — он рисует нумерацию графикой на элементе определённой ширины. Если числа очень большие, они начинают обрезаться, на римских числах это очень быстро становится проблемой.

С этим багом мы боролись очень долго. Конечно, это ожидаемо — «Курсор», — среда разработки, которую я использую, почему-то до сих пор не умеет самостоятельно скриншотить разрабатываемые приложения. Там где нейросеть не может быстро получить обратную связь, всё сильно замедляется, потому что мне приходится вмешиваться — делать скриншот, добавлять его в окно чата и описывать что не так.

2 комментария

«Виола»: формулы и стилизация

Долго же я прикидывал правда ли автор «Виолы» задумывал, чтобы математические формулы у него выводились на красном фоне. С одной стороны в коде именно так, да и мне это кажется даже в чём-то логичным, с другой стороны комментарий одного из читателей посеял во мне сомнения.

Действительно, есть ли в этом смысл? Почему именно формулы на странице должны быть как-то по-особенному выделены? Мои метания разрешил скриншот оригинального браузера, на который я наткнулся, пока рылся в различных папках одного из первых сайтов, посвящённых этому браузеру.

На скриншоте красного фона нет. Видимо всё-таки автор в какой-то момент добавил его для отладки. Браузер, который я дописываю, достался мне в бета-версии и некоторые вещи там были в полусыром состоянии. Возможно и в математических формулах автор что-то собирался переделать или починить, поэтому добавил специальный фон.

Скриншот браузера Viola WWW с примерами математических формул: x²+y², интеграл, сумма a₁+...+aₙ, Σi, x/y, x²+2x+1=0, с цветными рамками и фоном.

В общем, от красного фона я избавился и сделал возможность стилизовать формулы в соответствие с закомментированным кодом, который автор не дописал — у формул должна была появиться возможность устанавливать цвет фона, шрифта и бордюра. Всё это заработал в последнем коммите.

Вот, кстати, как выглядело недописанное место, где можно подсмотреть что планировалось сделать:

tagPtr = STG_tagPtr("MATH");
i = STG_attr(tagPtr, "BGColor");
if (i) set("BGColor", i);
i = STG_attr(tagPtr, "FGColor");
if (i) set("FGColor", i);
i = STG_attr(tagPtr, "BDColor");
if (i) set("BDColor", i);

А то некоторые читатели недоумевают, наверное, откуда я вообще знаю что задумывал автор.

Этот кусочек выше был закомментирован и не дописан, зато из него видно, что автор собирался стилизовать задний фон (BGColor), цвет шрифта (FGColor) и цвет бордюра (BDColor).

Нередко такие места содержат в себе достаточно понятные намёки на то как это было задумано, в других же случаях помогают комментарии, главы из недописанной книги автора или его редкие письма в различные группы рассылок, куда он редкий раз писал свои мысли в самом начале 90-х.

6 комментариев

«Виола» и безопасность

Когда я только начинал заниматься восстановлением браузера «Виола», меня поразило как много он себе позволяет делать в системе. Если бы браузер с такими возможностями и с полным отсутствием защиты от несанкционированного их применения дожил до конца девяностых, хакеры бы от его репутации камня на камне не оставили.

Конечно, в 1991-м году, когда «Виола» только появился, об этом было рано думать. Всё-таки программист-одиночка не мог заниматься сразу всем, а работы и без того хватало — столько всего надо было реализовать, я хорошо это понимаю.

В 1995-м году, когда вышла последняя версия браузера, защита уже была необходима и, как оказалось, автор «Виолы» это тоже понимал. В частности в тринадцатой главе своей недописанной книги, он пишет:

At this point you’re probably thinking how great this this, but how do I know that the applets I run won’t delete my files, smuggle info out of my system, and do other mischiffs?

The answer is that these imported objects can’t (or shouldn’t be able to).

The current security policy is pretty straightforward and somewhat limiting for the objects. It basically goes this way: all imported objects are marked as untrusted, and as such these imported objects have no system priviledges, have no access to sub interpreters, and can not coarse other objects to execute scripts arbitrarily.

Видимо эта работа так и не была завершена, но, что радует, была начата. Я изучил всё то, что автор писал по этому поводу у себя на сайте, в группах рассылок и коде браузера и тщательно описал что именно было сделано. Потом я определил, что нужно доделать в коде, чтобы обеспечить минимальную защиту компьютера пользователя от вредоносных сайтов, и приступил к работе.

Скриншот окна «Privilege Elevation Request» в Viola WWW Browser: запрос полного доступа для TCP-соединения с pebble.ebay.gnn.com:7777, кнопки Trust/Don’t Trust.

Конечная реализация вышла довольно прямолинейной. Браузер может работать в одном из двух режимов: защищённом и нет. Когда браузер переходит на какую-либо страницу, он смотрит откуда она загружена, если из интернета, то режим переключается в защищённый, если с файловой системы, то она запускается в доверенном режиме.

В популярном приложении одно э́то было бы проблемой, но я не вижу смысла спрашивать разрешение и для локальных страниц, так как это осложнит мне тестирование браузера. Так что я себе проделал небольшую брешь в защите.

Из защищённого режима браузер переключается в режим без защиты только с разрешения пользователя, переключение инициируется, если во время интерпретации скрипта встречается вызов, требующий переключения в доверенный режим (например, работа с файловой системой или открытие сокета), а так же, если на странице установлен тег SECURITY с атрибутом LEVEL=0.

Оказывается, автор браузера предосмотрел такой тег, но не успел реализовать. Название атрибута в коде уже было, а вот его значение — это моё обоснованное предположение. В коде есть центральный флаг securityMode, принимающий два значения — 0 (система безопасности отключена) и 1. Я предположил, что атрибут LEVEL должен влиять на значение этой переменной.

Если пользователь не согласился на переход в доверенный режим, вызов, запросивший повышение привилегий, завершается с нефатальной ошибкой — там, где можно вернуть флаг того, что произошла ошибка, я это делаю. Как только браузер встретит следующий такой вызов, он опять попросит разрешения сменить режим. Тут, опять же, слабое место, — можно заспамить пользователя такими запросами. Собственно, эта проблема была в любом браузере девяностых годов.

Решается она просто. Например, можно добавить в диалог галочку «больше не спрашивать» и не позволять его вызывать до перехода на другую страницу, но это настолько не в духе браузеров тех годов, что я тоже не стал этого делать. По-честному, от кого защищаться?

Если мы перешли в доверенный режим, то он сбросится на следующей же странице, загруженной из интернета.

Я потратил так много усилий и токенов нейросетей, чтобы сначала понять замысел автора, потом придумать в её рамках реализацию, закрывающую все белые пятна, а потом реализовать, что немного выдохся и пока больше таких больших доработок не делал, да и токены надо бы поэкономить. Поэтому пока что я доделываю всякие мелочи и дописываю документацию.

Но не будь нейросетей… Я уже не раз повторял это в частных разговорах, но, кажется, ни разу не писал у себя в блоге: без нейросетей я бы этим заниматься не стал. Усилие от реализации этих доработок без нейросетей во много раз перекрывает удовольствие от этой работы.

2 комментария

«Виола»: тег CHANGED

Если верить «Википедии», веб появился в 1989 году. Его ранний период очень плохо сохранился, даже проект «Веб-архив» тут не помощник — ссылки времён начала интернета в нём не открываются. Поэтому если интересует информация тех времён, приходится заниматься археологией — выискивать обрывки информации в других источниках и собирать воедино.

В «Виоле» я часто нахожу начатые и неоконченные части реализации какой-нибудь неизвестной сейчас спецификации. Если каким-то образом становится понятно как это должно работать, я стараюсь эти места дописать.

Так случилось и с тегом CHANGED. Я давно заметил его в коде, но не понимал как он должен работать. По коду про него было известно, что он должен был выделять часть текста оттенком жёлтого (точнее — цветом LemonChiffon1), имел два атрибута ID и IDREF и при этом был не блочным.

Конечно, мне было непонятно что у него за атрибуты, но последнее всё ещё сильнее усложняло. Когда я начал читать код, то подумал, что это какой-то тег, который нужен, чтобы выделять текст светло-жёлтым, так как мы это делаем маркером. Но тогда он должен образовывать блок, а в коде написано иначе!

Тогда я решил, что это просто ошибка в коде и реализовал тег так как я его понимаю. Но было непонятно что делать с атрибутами, особенно с IDREF. По имени понятно, что это какая-то ссылка на ID, но как это должно работать? В общем, реализацию я просто выкинул, так как она точно не соответствовала тому как это задумывалось.

Я записал себе в список дел когда-нибудь разобраться с этим тегом и пошёл дальше. Прошло несколько недель и на днях мне повезло.

В архивах начала 90-х почтовой рассылки WWW-Talk, я неожиданно обнаружил ссылки на DTD (это специальный формат в котором описывается как браузер должен парсить теги) стандарта HTML+. Я знал, что это название одного из ранних стандартов HTML и подумал, что там могло оказаться упоминание CHANGED с, чем чёрт не шутит, каким-то подробностями.

Ни одна ссылка не работала, зато по имени htmlplus.dtd нашлось несколько уцелевших спецификаций, где, как я и надеялся, упоминался искомый тег с небольшим описанием:

<!-- change bars defined by a matched pair of CHANGED elements:

        <changed id=z34> changed text <changed idref=z34>

 This tag can't act as a container, since changes don't respect
 the nesting implied by paragraphs, headers, lists etc.
-->

<!ELEMENT CHANGED - O EMPTY>

<!ATTLIST CHANGED -- one of id and idref is always required --
    id      ID      #IMPLIED -- signals start of changes --
    idref   IDREF   #IMPLIED -- signals end of changes -->

Собственно, из этого кусочка всё стало ясно. Тег задуман таким образом, чтобы как бы «выпадать» из обычной логики вложенности тегов — так как выделение текста может пересекать границы других тегов.

Вместо открывающего и закрывающих тегов тут применяется тег с атрибутом ID для обозначения начала участка и тег с тем же значением в атрибуте IDREF для определения места, где участок заканчивается.

Этот тег не дожил до нашего времени, потому что его было предложено заменить на два других — ADDED и REMOVED, которые позже превратились в более привычные нам INS и DEL.

Несмотря на то, что найденная спецификация оказалась сложнее первоначальной моей реализации, в этот раз получилось всё запрограммировать даже быстрее, видимо при частом программировании с нейросетями нарабатываются какие-то приёмы, которые позволяют эффективнее с ними взаимодействовать.

Один из таких способов, кстати, — банальное документирование. В процессе реставрации «Виолы», у меня набралось довольно много документации, благо при помощи нейросети это делать очень просто — даёшь команду что ещё учесть и она сама вписывает новые знания в подходящее место.

Скриншот веб-страницы «Test CHANGED Tag - HTML+ Change Bars» с примерами выделения изменённых фрагментов текста жёлтым фоном и заголовками разделов.

3 комментария

«Виола»: растягивание окна

В последнее время мало что дорабатываю в «Виоле», чаще борюсь с багами, а их там предостаточно. Сегодня ночью пал один из самых сложных в исправлении.

Дело в том, что у меня окно «Виолы» нормально не тянулось — если попробовать изменить размеры, то в окне появлялись чёрные полосы, положение элементов плыло, в общем пользоваться этим было невозможно. Я, понадеявшись на то, что оригинальная «Виола» просто не умела растягиваться, заблокировал во всех окнах такую возможность.

Но позже в видеоролике, где видно оригинальную «Виолу», запущенную в виртуальной машине, я увидел, что она прекрасно растягивается безо всяких проблем.

Видимо проблема в каких-то особенностях работы X11 на «МакОСи», возможно он работает не в точности так же, как в 90-е, когда этот браузер писали.

К проблеме растягивания я уже пытался подступиться, но, потратив несколько часов, отступил. На этот раз я попробовал новый подход. В прошлый раз нейросети пробовали какие-то гипотезы, добавляя всё новые и новые правки и запутывая код, но ничего не помогало. Часть проблем мы смогли победить, но последняя — появляющаяся при изменении размеров рамка вокруг заголовка и урла страницы всё никак не давалась.

Я сообразил, что проект, видимо, просто слишком огромный. У нейросети «глаза разбегаются» в попытке сгенерировать фиксы, так как дело может оказаться в чём угодно.

Поэтому я попросил нейросеть сгенерировать небольшое приложение, которое компактно повторило бы проблему, чтобы там её править. Удивительно, но мой любимый «Опус 4.5» с задачей не справился — он слепил какого-то уродца из случайных компонентов, а потом всё пытался переключиться на основное приложение.

Выручил «ГПТ-5.2». Он собрал хороший прототип, где мы воспроизвели проблему и в конечном счёте её победили. Дальше я опять переключился на «Опус» и мы благополучно перенесли решение в основной код.

К тому времени, когда всё заработало, в коде было полно каких-то правок, только часть из которых решала проблему. Помятуя как нейросеть однажды легко уничтожила наш совместный многочасовой труд, я закоммитил всё как есть, а потом стал по одному откатывать все изменения, чтобы понять что имеет значения для исправления проблемы, а что нет.

Судя по логам, работу я закончил в третьем часу ночи.

Скриншот окна с заголовком «test_title_component» и текстом: «The World Wide Web project%http://info.cern.ch/hypertext/WWW/TheProject.html
Прототип, который помог компактно воспроизвести проблему и победить её

Оставить комментарий

«Виола»: тянущееся окно

Отложил пока в сторону свой проект до дописыванию браузера «Виола», поскольку исчерпал все токены на своём тарифе в «Курсоре». Там, конечно, остались бесплатные модели («Грок», например), но они годятся только для чего-то очень простого, а я таких задач пока не вижу.

Зато случилось интересное — поиск в интернете принёс видео «Viola www y Erwise dos de los navegadores web pioneros», где какой-то исследователь истории запускает оригинальную «Виолу» в виртуальной машине. Этот видеоролик, наконец, дал мне ответ на вопрос — тянулось окно «Виолы» или нет. Оказывается, тянулось.

В моём проекте с этим сложности — при изменении размеров окна, всё очень некрасиво едет и красится чёрным, видимо что-то не перерисовывается так как должно. Победить это пока не удалось, да я и не особо старался. Пока убрал только из всех окон уголок, за который можно было тянуть и зафиксировал размер, надеясь, что оригинальный браузер так и был устроен.

Раз это не так, то после перерыва надо будет вернуться к этой задаче. Попытаюсь решить её с «Опусом 4.5», пока это умнейшая сеть для программирования.

Скриншот веб-страницы «Montage of the 1991 Vintage Viola» с описанием первой версии Viola (0.8) и вставкой «Tiny Play» с анимацией персонажа на сцене.
Кадр из ролика «Viola www y Erwise dos de los navegadores web pioneros» («ViolaWWW и Erwise — два браузера-пионера»)

3 комментария

«Виола»: протокол NNTP

Из всей той экзотики раннего интернета, которую сейчас уже прочно забыло большинство, — IRC, Gopher, Finger, WAIS и прочего — я больше всего пользовался сетью «Юзнет», работавшей по протоколу NNTP. Это был аналог электронной почты, только сообщения доходили сразу до всех участников выбранной «группы» — что-то вроде общего почтового ящика.

Для тех скоростей, которые тогда были доступны, это был удобный инструмент. Я состоял в нескольких группах; сейчас уже не вспомню каких, но отлично помню наши бесконечные баталии в одной из локальных групп моей альма-матер, где мы спорили с оппонентом о том, что же такое бесконечность — число или понятие. Точку в споре поставил мой научный руководитель, Александр Михайлович Елизаров, заметив, что ответ зависит от того, какой раздел математики мы имеем в виду.

В общем, в 2025-м году, как ни удивительно, этот протокол ещё жив, что я с удивлением обнаружил, начав чинить его поддержку в «Виоле». На скриншоте, например, довольно свежее сообщение в группе comp.sys.mac.misc cервера news.neodome.net.

Почитать группу теперь можно и через «Виолу», запустив её следующим образом:

NNTPSERVER=news.neodome.net ./src/vw/vw news:comp.sys.mac.misc

Указывать сервер таким образом не слишком удобно, но в те годы, видимо, способа лучше ещё не придумали. Позже придумали схему урлов, где можно указать сервер и, по-хорошему, следовало бы её реализовать. Займусь этим в ближайшее время.

Учитывая, сколько мне пришлось исправить багов за это время, я думаю — не в их ли количестве была причина того, что «Виола» проиграла своим конкурентам? Возможно автор, учитывая заложенные, но не реализованные тут возможности, просто не имел сил заниматься всем — и править баги, и дописывать всё что нужно?

Скриншот письма в Viola WWW: тема «Re: [RUMOUR] R.I.P. Mac Pro ??», отправитель Jörg Lorenz, дата 19 ноя 2025, обсуждение неактуальности Mac Pro в эпоху Apple Silicon.

2 комментария

«Виола»: предок VRML ★

Недавно завершил в «Виоле» большую работу: реализацию раннего черновика стандарта VRML. VRML когда-то широко использовался в вебе для создания трёхмерных игр, да и просто для того, чтобы рассматривать с разных сторон какие-либо объекты в объёме.

Началось всё с того, что я заметил в браузере едва начатую реализацию тегов, помеченную комментариями как /* vr exp */. В исходном коде нашлась целая группа таких тегов. Назначение некоторых из них, например OVAL или LINE, было вполне очевидным, тогда как то, что в точности могли бы делать некоторые другие теги, например ACTION или BUTTON, было не вполне ясно.

Можно было бы реализовать только понятные части, но я тогда просто отложил эту задачу в сторону, тем более что она казалась пугающе сложной.

Шло время, и вдруг, копаясь в каталогах старого сайта, посвящённого «Виоле», я неожиданно нашёл черновик письма, в котором автор «Виолы» описывал своё видение того, как должен выглядеть VRML.

Скриншот веб-страницы «Proto-VRML Graphics Demo» с примерами: жёлтые фигуры на розовом фоне, треугольник и пятиугольник, простая красная домик с солнцем.
Готовая реализация графики, которая сейчас работает в браузере

Там раскрывалось значение всех ключевых тегов из вышеуказанной группы, их атрибутов, а также интерактивная часть — причём в двух вариантах: декларативном (через теги) и скриптовом (через язык «Виолы»).

Вкратце суть такова: теги описывают графические примитивы и их вид на странице. С некоторыми из них через активные элементы можно взаимодействовать, меняя их атрибуты.

Вот, например, как на этом языке рисуется синий квадрат с тёмно-синим бордюром на светло-сером фоне в координатах x=10, y=20, повёрнутый на 45°:

<GRAPHICS WIDTH=400 HEIGHT=120>
<BGCOLOR NAME="lightgray"></BGCOLOR>
<RECT ID="rect1">
<POS X=10 Y=20></POS>
<SIZE X=70 Y=70></SIZE>
<FGCOLOR NAME="blue"></FGCOLOR>
<BDCOLOR NAME="navy"></BDCOLOR>
<ROT Z=45>
</RECT>

Особенно меня почему-то зацепил атрибут SC о роли которого я бы никогда самостоятельно не догадался. Автор описывал его так:

The SC attribute says that whenever the attributes in this object changes, relay the change to a server that broadcasts the change to all other browsers looking at this object… Have to think about this more…

Я сразу понял как хотел бы чтобы он работал: если на странице есть такой атрибут, считаем хеш урла, где находится сейчас наш браузер и, при любых изменениях тегов, связанных с этим атрибутом, рассылаем по локальной сети сообщение с закодированной командой. Одновременно мы слушаем сеть, принимаем команды, отфильтровываем те, в которых содержится хеш текущей страницы и только их и исполняем.

В итоге эту часть я сначала пытался сделать через маковский сервис «Бонжур», но позже переделал на мультикастовый UDP — так работало гораздо быстрее и надёжнее.

Скриншот веб-страницы «ACTION Script Demo - Clickable Shapes» с цветными геометрическими фигурами и описанием их интерактивных свойств (вращение, масштабирование, смена цвета).
Активные объекты, содержащие атрибут SC рассылают свои изменения по локальной сети

Поскольку я тестировал у себя на ноутбуке, запуская два экземпляра браузера, столкнулся и с другой проблемой — стоило убрать курсор с одного из окон, и оно переставало перерисовываться. Оказалось, это особенность оконного фреймворка, на котором построено приложение: так сделано для экономии процессорного времени.

Пришлось делать специальный таймер, который будит приложение, если ему адресованы интерактивные UDP-пакеты.

Работу я разбил на три части: реализацию графических примитивов, реализацию интерактивного взаимодействия и сетевое взаимодействие.

На всё ушло несколько дней интенсивной работы с нейросетью «Опус 4.5». Пришлось даже немного переделать парсер тегов внутри браузера. Несмотря на то, что работа двигалась трудно, отчаяния я не испытывал — было видно, что при работе в паре с «Опусом» эта задача вполне мне по силам.

На настоящий момент всё работает, так, на мой взгляд, как и задумывалось, за исключением декларативной части предлагаемого черновика.

Во-первых, она, при наличии скриптового языка, избыточна, во-вторых, в коде браузера видно, что автор её реализовывать и не собирался.

Скриншот окна браузера ViolaWWW с заголовком «Geometric Art - ViolaWWW Graphics Demo» и геометрической композицией из разноцветных фигур на сером фоне.
Пример с узорами, нарисованный при помощи реализованных графических примитивов

2 комментария

Инсталлятор «Виолы»

Вчера я хотел кое-что потестировать в «Виоле» на другом ноутбуке и понял, что я понятия не имею как её нормально там запустить. Причина в том, что «Виола» требует несколько внешних утилит для работы, плюс библиотеки,.. в общем, я решил, что пора сделать инсталлятор.

Так как с собой пришлось тащить ещё и «Кварц» (XQuartz), то лучшим выбором был dmg — файл с монтируемой файловой системой. Хорош он тем, что просто делается и легко стилизуется. Я, например, сделал внутри обои, вдохновлённые внешним видом браузера и поместил портрет автора с его старой домашней странички.

По-моему, вышло очень симпатично.

Скриншот окна установки ViolaWWW Hypermedia Browser: иконки XQuartz-2.8.5.pkg и ViolaWWW.app, папка Applications, инструкция по установке и фото автора Pei-Yuan Wei.

Для сборки сделал две новые цели — make app для сборки самого приложения и make dmg для сборки инсталлятора.

Больше всего, конечно, пришлось помучаться с приложением — чтобы пользователь потом не ставил сторонний софт, я перенёс все бинарные зависимости внутрь, переписав пути. Вообще, весь инструментарий для этого уже существует, но в случае утилиты magick из пакета ImageMagick пришлось делать отдельную компиляцию, чтобы сделать бинарник перемещаемым.

Нейросеть, которая мне это всё готовила, в этом месте зациклилась, пытаясь разобраться как готовый бинарник унести внутрь так, чтобы он заработал, хорошо что я быстро увидел, а то бы мне это обошлось в копеечку.

Добавлено позднее: код собран по процессоры АРМ и под «МакОС» 26.

8 комментариев

«Виола» или «ВиолаВеВеВе»?

Как вы уже заметили, я упоролся по браузеру «Виола» и, похоже, перемкнуло меня надолго. Тем лучше! Давно у меня не было хобби из-за которого я бы несколько недель не спал по ночам.

Вопрос, который меня интересовал — правильно ли я вообще называю эту программу? Для меня это важно.

Дело в том, что «Виола» — это язык программирования, а не сам браузер. Например, вся обработка тегов внутри написана на этом языке. Его название расшифровывается как «Visually Interactive Object-oriented Language and Application».

Браузер же правильно называется «ViolaWWW». Но называть его так очень неудобно, на редкость неуклюжее название, поэтому я почти всегда называю его «Виола». И мне подумалось, что неплохо бы выяснить как его называли в прессе во времена, когда он ещё не стал частью истории.

В общем, не мне одному было жалко ломать язык — например, в журнале «Internet World Magazine» за апрель 1995 года он тоже называется «Виола», значит всё в порядке.

Статья о раннем браузере Viola, разработанном Пе Вэй в Калифорнийском университете в Беркли, с упоминанием его функций и сравнения с Mosaic и X/Window.
Заметка из журнала «Internet World Magazine» за апрель 1995 года, страница 36

Оставить комментарий

«Виола» и самолёты: коррективы

Надо бы мне ещё вернуться к теме отображения «Виолой» самолётов. Пока я поправил только масштаб — заметил, что на старых скриншотах, снятых автором этого браузера в 90-е, модели как будто бы в два раза больше. Сообразил, что дело, видимо, в повышенном разрешении экрана моего «Макбука» — в так называемой «ретине». В итоге, я теперь обнаруживаю такие экраны и масштабирую изображение под них.

Но всплыла и ещё одна проблема — иногда «крутилки» как будто меняют ось, вокруг которой они крутят объект, при этом в терминале я вижу многочисленные ошибки следующего вида:

violaIdleEvent(): select() error: : Bad file descriptor

Как будто браузер теряет соединение со своим бэкендом для отрисовки моделей и вращение рассинхронизируется. Как только научусь стабильно повторять эту проблему, попробую поправить.

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs» и демонстрацией 3D-модели ракеты в желтом каркасе, отображаемой через XPlot.

Оставить комментарий

«Виола» и моя мечта: как ИИ снова мне помог ★

Вступление

Я, как вы знаете, довольно давно уже реставрирую браузер «Виола» из недописанных исходников. И была у одна мечта, связанная с ним: увидеть как в нём работает вращение трёхмерной модели самолёта.

Узнал я об этом из статей о судебной тяжбе компаний «Микрософт» и «Иолас» (Eolas), начавшейся в 1999-м году.

Компания «Иолас» утверждала, что первой разработала и внедрила технологию «встроенных объектов и плагинов» для веб-браузеров, и «Микрософт», по их мнению, нарушала права, используя схожий механизм. В этой связи автора «Виолы» вызывали в суд, где рассказал, что придумал эту технологию ещё в начале 90-х годов, тогда как «Иолас» получила на неё патент только в 1998-м.

Тема широко освещалась в прессе и в некоторых из статей есть статичный скриншот того как это выглядело. Кроме того, сохранился код страницы с программой на языке «Виола». Казалось бы — почти всё что нужно!

Скриншот ViolaWWW: заголовок «Front-Ending External Programs», описание встраивания front-end для XPlot, жёлтый каркасный самолёт на синем фоне.
Скриншот того как это выглядело в первой половине 1990-х

Что мешало

Но оказалось, что исполнению моей мечты мешало несколько обстоятельств.

Во-первых, на самом деле модель вращала утилита V-Plot, написанная Скоттом Силви, который учился вместе с автором «Виолы». Её исходники не сохранились.

Во-вторых, судя по сохранившимся исходникам веб-страницы, вращались две модели, которые назывались TomCat и x29.geom, которые ещё нужно было найти.

В-третьих, как оказалось, часть, которая должна взаимодейстовать с V-Plot не работала.

Вопрос №1: где взять V-Plot?

По всей видимости, в открытых источниках его не найти — сколько не запускал я невод глубокого поиска нейросетями, ничего не вышло. Тогда я решил пойти от обратного — у нас есть скрипт на «Виоле», который должен слать этой программе какие-то команды, так может нейросеть, отталкиваясь от них, мне её просто напишет?

Без особой надежды я дал нейросети такое задание и пошёл заниматься делами. Через какое-то время у меня был на руках исходник, в который я даже не заглядывал. Решил просто всё запустить и посмотреть что будет. Ожидаемо ничего не заработало сразу. Я пожаловался на этой нейросети и мы пошли смотреть в чём причина.

Оказалось, что специальный «объект» TTY «Виолы» для взаимодействия с программами, которые могут выводить графику в окно браузера, реализован только для «Линукса», а для «МакОСи» (в «Виоле» встречаются куски для очень старой версии этой операционной системы) код реализован не был.

Я как можно тщательнее, как зловредному джину, описал что именно хочу получить и опять переключился на свои дела. И вот тут, когда я без особой надежды вернулся через какое-то время посмотреть на то как нейросеть провалила задачу, меня ждало маленькое чудо: в окне, где должны выводиться модели, появилась жёлтая сетка — самодельный V-Plot делал что-то полезное!

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs» и описанием демонстрации встраивания объекта viola для связи с процессом построения графиков XPlot.
Сетка — признак того, что взаимодействие с V-Plot работает!

Здо́рово! Но где же мои самолётики?

Настал момент узнать откуда же брались самолёты. Оказалось, что «Виола» передаёт на вход V-Plot одну из моделей, которые выберет пользователь — там на выбор несколько графиков и две модели в формате OFF (Object File Format). Моделей в комплекте с исходниками браузера не оказалось.

Ориентируясь на приметное имя x29.geom, я решил поискать эту модель, вдруг это что-то известное. А параллельно зарядил ChatGPT глубоким поиском.

Модель действительно оказалось известной — её когда-то изготовила компания «Эванс энд Сазерлэнд», а потом использовали на европейской выставке 1987 года, электронные материалы которой каким-то чудом уцелели и доступны для скачивания.

ChatGPT оказался полезен тем, что правильно идентифицировал модель и рассказал её историю, но сам файл нашёлся банальным поиском по интернету.

Дальше нейросети меня опять удивили — посмотрев на мой найденный файл, сеть для программирования «Опус 4.5», не моргнув глазом, написала мне за каких-то несколько десятков секунд код для парсинга и отображения этого формата. И вот я уже вращал свой первый самолёт!

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs», описанием демонстрации встраивания объекта и желтым 3D-графиком XPlot на синем фоне.
Браузер «Виола», вращающий модель самолёта Grumman X-29 в трёх измерениях

Отлично! А что со второй моделью?

Со второй моделью так гладко не вышло — как я ни старался, ничего путного по слову TomCat на нашёл. Решил смириться и найти хоть какую-нибудь модель того же самолёта — ChatGPT определила, что на картинке нарисован Grumman F-14 Tomcat.

Тут наконец пригодился глубокий поиск — нашёлся архив внутри которого лежала модель самолёта F-14, но, вот неприятность, в формате IOB (Imagine object). Формат давно мёртвый и единственный конвертор, который я нашёл — бинарный файл под операционную систему «Амига».

Я, было загрустил, но тут решил попробовать уже совсем безумную штуку — натурально попросить нейросеть написать мне конвертор из формата IOB в OFF, причём без описания самих форматов. Самое смешное, что это сработало, причём с первого раза! Получившаяся модель сразу появилась в окне и заработала!

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs» и демонстрацией 3D-модели самолёта XPlot в виде жёлтой проволочной сетки на синем фоне.
Модель Grumman F-14 Tomcat, сконвертированная из формата IOB

Выводы, или Что меня удивило

Лёгкость к которой нейросеть провела обратную разработку команд, написала интерпретатор команд для V-Plot и конвертор, просто поражает! Честно сказать, я на такое совсем не надеялся. Максимум, который я ожидал — полуживой прототип, который придётся отлаживать не один день.

Конечно, у меня осталось ещё много задач даже в этом проекте, которые нейросети либо не могут решить самостоятельно, либо даже с моей помощью.

Тем не менее, та работа, которую я проделал над браузером при помощи нейросетей, совершенно неподъёмна для человека в такие короткие сроки.

8 комментариев

Звуки в «Виоле»

Как я уже писал, анимацию в «Виоле» можно получить, задействовав скриптовый язык, а что же со звуком?

Из скриптового языка доступны только две функции — bell() издаёт системный «бип» и bellVolume(), позволяющая задавать или получать громкость этого «бипа» в процентах. Функций немного, но и их пришлось чинить — они обе используют вызов XBell(), который на «МакОСи» не работает испокон веков.

Пришлось примотать небольшой код на Objective-C, который вызывает фреймворк AVFoundation, через который я теперь проигрываю системный звук Tink.aiff с заданной громкостью.

Что касается HTML, отдельного тега нет, но небольшими ухищрениями можно заставить проиграть браузер любой файл, имя которого кончается на .au — этот файл передаётся маковской утилите afplay, а она умеет играть файл в целой куче аудиоформатов.

Каноничнее, конечно, использовать именно формат au, тем более, что в него аудио можно преобразовать большинством современных утилит, той же ffmpeg, например.

Так как же проиграть звук из HTML?

Самый простой способ — поставить на аудиофайл ссылку. При переходе на неё файл проигрывается, а не скачивается. Способ позанятнее — использование тега INSERT, аналога современного IFRAME. Он проиграет файл при открытии страницы, а если использовать атрибут AFTER, то ещё и зациклит его с указанной в миллисекундах задержкой.

Скриншот окна браузера Viola WWW с заголовком «Audio Player» и HTML-кодом, содержащим тег `` для вставки аудиофайла.

Так как звук играется асинхронно, в теории, можно было писать игры или делать сайты с фоновой музыкой, для этого уже всё было готово. А если учесть, что скриптовый язык позволяет запускать что угодно (с безопасностью у этого браузера явные проблемы), то можно, запуская ту же утилиту afplay, организовать звуковые эффекты.

Оставить комментарий

«Виола» и организация закладок

«Виола», конечно, глубже любой кроличьей норы — со временем всё больше и больше похороненных идей удаётся находить в её внутренностях. Вчера ночью, просматривая код незавершённых и закомментированных пунктов меню, я заметил интересное место — недописанный интерфейс каталога закладок.

Степень готовности там оказалась очень высокой, поэтому я решил оживить этот фрагмент. В «Виоле» уже есть его конкурент — «Hot List», позволяющий хранить закладки плоским списком. Но «Hot List» куда проще и примитивнее. В отличие от него, каталог позволяет создавать папки и перетаскивать закладки, визуально организуя их так, как больше нравится пользователю.

Несмотря на то, что кажется логичным перетаскивать закладку в папку, чтобы туда её перенести, такого автор, к сожалению, не задумывал — в комментариях к незавершённым кускам достаточно подробно описана логика перетаскивания. Чтобы не нарушать аутентичность, я тоже это не реализовывал.

Я вообще стараюсь придерживаться авторского замысла, но есть тут два места, где мне пришлось придумывать что-то самостоятельно.

Скриншот окна программы Personal URL Catalog с меню File, Edit, Organize, Help; в папке Root отображены файлы Demos, The World Wide Web project и Viola Central.

Во-первых, иконки — автор хоть и оставил для них место, но не нарисовал, поэтому пришлось натащить их из других мест. Иконку документа я взял из интерфейса браузера, из кнопки клонирования. А в качестве папки приспособил иконку раскрываемых списков.

Во-вторых, формат сохранения списка каталога закладок. Этой части тоже не было, поэтому пришлось придумывать свой.

12 комментариев

Внешний вид браузера «Виола»

Если вы приглядывались к браузеру «Виола» на моих многочисленных скриншотах, могли заметить, что он выглядит каким-то недоделанным — адресная строка и заголовок страницы небрежно брошены в интерфейс.

На деле всё обстояло даже хуже — в нулевом состоянии в этих местах были прописаны заглушки, по которым сразу становилось понятно, что это не интерфейс, а нечто временное.

Мне от этого делалось грустно — я люблю красивый дизайн, а тут такое уродство. Но оказалось, что внутри кода браузера есть закомментированные недописанные куски, в которых можно подглядеть, как на самом деле должен был выглядеть браузер!

Мы с нейросетью посмотрели на этот код, отряхнули его, дописали и выкинули оттуда очевидно лишние вещи (внизу были невзрачные кнопки, дублирующие меню, думаю, это остатки технического интерфейса). Теперь в свежей сборке можно увидеть, каким именно браузер должен был получиться. По-моему, стало гораздо лучше.

Скриншот веб-страницы проекта World Wide Web (W3) в браузере Viola, содержащий описание инициативы, ссылки на разделы и информацию о проекте.

Кстати, пока мы с нейросетью занимались интерфейсом, я решил заняться некрасивым уголком справа внизу. Снял скриншот, чтобы меньше объяснять — многие нейросети довольно неплохо по ним всё понимают и написал в промпте:

Посмотри на out.png, справа внизу светлый угол, за который тянуть надо, не совпадающий по цвету с остальным окном. надо бы поправить цвет, сделать в цвет остального окна.

Вот иллюстрация того как это ещё недавно выглядело:

Кнопки интерфейса: Back Up, Previous, Next, Show Source, Clone Page; надпись «Click to visit the previous document.
Неприятный уголок и технические кнопки, которые я потом убрал

Нейронка, так сказать «взяла под козырек» и начала что-то бодро писать на «Пайтоне». Что странно, кстати, — программа-то на Си. Через какое-то время я вернулся посмотреть что получилось.

Оказалось, она написала мне программу, которая покрасила краешек моего скриншота в правильный цвет!

В итоге я вообще убрал этот уголок: масштабирование всё равно нормально не работает, остаются артефакты, да и в оригинальной программе окно было фиксированного размера.

Оставить комментарий

«Виола»: ИИ и отображение PostScript

Когда я в очередной раз думаю, что понял какие задачи может, а какие не может решить нейросеть быстро и с минимальным моим участием, нейросети подкладывают мне свинью.

Случайно, изучая заголовки, которые отправляет «Виола», я обнаружил, что этот браузер каким-то образом работать с «ПостСкриптом» — это язык описания страниц, который используется, например, принтерами. Для этого, как оказалось, нужно использовать отдельный тег FIGURE.

Непонятно для этого понадобился отдельный тег, ну вот так сделано. Для наглядности вот пример его использования:

<FIGURE TYPE="application/postscript" SRC="test_figure_ps.ps"
WIDTH="100" HEIGHT="100" MAYDELAY="2000" ISMAP></FIGURE>

У него больше атрибутов, чем я использовал в примере, в минимуме ему нужен только TYPE и SRC, а остальные атрибуты у меня тут используются как ненужные подробности в моём рассказе, но так уж мне захотелось.

Когда я сделал тестовую страничку с этим тегом, оказалось, что ISMAP и MAYDELAY с «ПостСкриптом» не работали, как и, собственно, само отображение «ПостСкрипта».

С отображением я справился быстро. Секрет в том, что «Виола» на самом деле этот язык сама по себе не понимала, до моего вмешательства она использовала довольно неряшливый код, который использовал кучу временных файлов и две утилиты, — gs и ppmtogif, при помощи которых она получала GIF, который на самом деле и отображался.

Я весь этот код просто выкинул и заменил на вызов утилиты magick, которая умеет конвертировать «ПостСкрипт» в GIF напрямую безо всяких посредников. Пришлось только учесть, что по-умолчанию она создаёт GIF с прозрачностью, тогда как предыдущий набор использовал белый фон.

Довольно быстро я починил и реализацию атрибута ISMAP — просто скопировал его из обработчика формата XBM, где он работал, а починку MAYDELAY отдал нейросети.

Вроде ничего сложного, опять же — этот атрибут работал у XBM, я предполагал, что сеть быстро разберётся в чём там дело, передрав рабочий код и наложив его на особенность — XBM отображается напрямую внутренней библиотекой браузера, а «ПостСкрипт» конвертируется.

Примерно спустя час я сдался. Ни ChatGPT 5.1 Codex, ни Gemini 3 Pro, ни моя любимая Sonnet 4.5 с задачей не справились — каждая из них писала мне огромную простыню кода, которая задачу не решала.

Кусок кода, который надо было поправить, выглядел следующим образом. Если атрибут MAYDELAY не указывался, то вызывалась конвертация «ПостСкрипта» в GIF и он показывался, в противном случае запускался таймер, который вызывал loadData — другой… э… метод, назовём это так, программы на внутреннем языке «Виолы», в котором конвертации не было.

Модели это видели и просто копировали конвертацию в этот метод, но к моменту срабатывания таймера файл, с которым нужно было работать, уже пропадал. Думаю, его удалял сборщик временных файлов, встроенный в «Виолу». В итоге ничего толком не работало: модели ходили по кругу и, пытаясь исправить ситуацию, писали всё больше кода.

Исправление, которое сделал я, работает очень просто: я сначала делаю конвертацию, потом смотрю, есть ли параметр MAYDELAY, если нет, отдаю сконвертированную в GIF картинку в отрисовку, если есть, откладываю отрисовку, передавая в метод loadData уже сконвертированную картинку.

По сути, я передвинул несколько строк кода чуть ниже, это всё моё исправление. Я как-то очень разочарован, что умнейшие из нейросетей до этого не додумались. Можно посмотреть в моём коммите, но там сразу несколько вещей исправляются.

Скриншот браузера Viola WWW с заголовком «PostScript FIGURE Test» и графиком: три надписи «text» (красный с зелёной обводкой, сплошной красный, красный контур).
Пример изображения PostScript взят из чужого репозитория

Оставить комментарий

«Виола», математика и скобки

Два дня занимался математическим модулем в «Виоле».

Поручил нейросети посмотреть, есть ли что-то, что автор начинал делать, но не доделал. Оказалось — есть! В коде есть недоделанная реализация пропорциональных скобок: сделаны токены и логика, но код не соединён с парсером, и некоторые сложные случаи не обрабатываются.

С наскоку задачу решить не удалось — она оказалась сложной. Сначала мы сделали отдельные теги для разных видов скобок, дописали обработку и поправили все баги, а на следующий день убрали теги и научили парсер генерировать нужные токены на скобки.

Звучит, вроде, несложно, но на деле коммит оказался очень объёмным. Зато сейчас всё работает очень хорошо.

Ещё в комментариях к коду есть указание на то, что ширина скобки должна, по задумке автора, меняться динамически в зависимости от её высоты. Но я попробовал — смотрится плохо, фиксированная выглядит намного лучше, поэтому реализовывать это не стал.

Скриншот веб-страницы с примерами вложенных скобок и формул: a+(b+c), [x]+y, дробь с вложенными скобками, сумма и интеграл с круглыми и квадратными скобками.

5 комментариев

«Виола»: математический модуль

Наверное, можно подумать, что я забросил заниматься браузером «Виола» — первым графическим браузером с потрясающими для своего времени возможностями. На самом деле — ничего подобного: почти каждый день, с редкими пропусками, я что-то в нём правлю.

Тот исходный код, который мне достался, был в статусе беты, но даже для беты тут очень много вполне очевидных багов, которые нужно исправить. А ещё — много впечатляющих вещей, которые автор, по всей видимости, не успел доделать. Часть из них я нашёл чисто случайно, как, например, модуль для отображения математических формул.

Нашёлся он совершенно случайно, когда я чинил баг с отображением символьных сущностей HTML — плёвая ошибка: дело было в том, что char у меня в компиляторе — тип со знаком, а в компиляторе автора, видимо, был без него. Из-за этого часть функций, работающих с символами, работала неверно.

Скриншот веб-страницы «Complex Mathematical Formulas Test» с формулами: e^(iπ)+1=0, x=(-b±c)/2a, интеграл e^(-x), сумма квадратов и e^x².

В общем, обнаружив модуль для отображения математических функций, я занялся им. Основное поправил, но кое-что до сих пор работает неправильно, буду позже править, думаю на это уйдёт ещё много сил.

Вот как выглядят формулы:

<math>&integral;<sup>&infin;</sup><sub>0</sub> e<sup>-x</sup> = <box>&sigma;<over>2</box></math>

Это третья формула на моём скриншоте, можно посмотреть чему соответствуют отдельные элементы. Как можно убедиться, реализованное в «Виоле» почти в точности совпадает со стандартом HTML Math, разрабатываемым когда-то Консорциумом Всемирной паутины, который так и остался в стадии черновика. Правда в браузере реализована только малая часть.

Синтаксис довольно простой, но, в принципе, несложные формулы записать можно. Вся математика отображается красным, я думал это какой-то баг, но нет, это такая особенность.

4 комментария

← 1 2 →