RevolveR Contents Management Framework v.1.9.1 -2


AliExpress RU&CIS

Лет 10 назад мне нужна была какая-то система, чтобы вести блог о web-разработке и я использовал сильно хакнутый Drupal, который со временем стало невозможно обновить из-за груды костылей и постоянной нужде рыться под капотом после каждого update. За 10 лет накопилось порядка 300 статей по верстке и front-end программированию, а также куча полезных сниппетов кода, которые я в последующем использовал для создания RevolveR Contents Management Framework на фирменной архитектуре KMV(Kernel<-Model<-View).

RevolveR CMF logotype

С Drupal была стянута идея использовать узлы(nodes) и я применил весь комплект опыта оставшегося от хакинга ядра решившись начать писать свою систему. Сейчас RevolveR уже достиг версии 1.9 и из его отличительных особенностей можно выделить подход к программированию. Все создано на чистом PHP SPL и не использована даже jQuery для frontend(ее роль выполняет созданный на ES7 движок front-end с поддержкой всех функций, которые могут пригодится при разработке; от поддержки CSS3 анимаций до автоматических HTML форм на fetch).

RevolveR CMF setup

Поскольку Windows теперь использует Chromium для встроенного в систему Fetch — я могу считать, что framework созрел для публики. Из новенького, что мешало сделать нормальный релиз была не полная поддержка CSS4 variables, которые у меня в паре с View Port Unit формирует хитрый в 10 строчек кода алгоритм для масштабирования HTML элементов сайта под мобильные устройства, а также по примеру приложения может получить, но не отображает в строке URL GET запросы.

Трекер посетителей

С помощью JS я определяю браузер пользователя и формирую scale factor являющийся множителем, чтобы отмасштабировать ссылки, кнопки, параграфы и другие элементы требующие увеличенного размера для смартфонов, чтобы пользователю было удобнее. Я подошел к реализации Front-end с той же стороны, что и подходят разработчики приложений операционной системы: никаких Media Queries не используется вообще, а сайты выглядят крупнее или мельче в зависимости от размера окна браузера без всяких прокруток.

Я еще полирую SPAx(Single Pages Application eXtended) интерфейс на VPU и могу сказать, что сэкономил себе два три дня тестирования верстки для мобильных устройств за счет scale-factor, который работает через CSS calc.

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

Что есть в системе сейчас?


Создана поддержка инсталлятора для хостинга (можно использовать Open Server минимальный). Поскольку это не совсем набор классов и futures для создания и нужды много программировать, CMF из коробки предлагает поддержку кабинета пользователя и ролей групп пользователей.

RevolveR CMF authorization

Contents Management Framework подразумевает также поддержку создания пользователем страниц и категоризация их включена в функционал. Фреймворк многоязычный (сейчас два языка интерфейса доступны Russian & English).

RevolveR Contents Management Framework каптча

Реализована простая, но очень надежная captcha, которая работает для любых POST данных путем получения ключа и паттерна из набора рисунков независимо на каждый ROUTE специальным сервисом secure route через javascript fetch и https cookie. Рисунок создается в canvas и обвешан рядом isTrusted проверок.

RevolveR CMF create njew page

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

RevolveR CMF SEO statistics

Все формы и элементы навигации сайтов на RevolveR CMF работают в автоматическом Fetch режиме из последних релизов ECMA Script. API подразумевает удобный сборщик HTML форм и центральный валидатор данных, который связан с типом input указанном в HTML формы. Загружаемые пользователем файлы проходят на UNIX системах дополнительную проверку маски через xxd.

Вообще, если в RevolveR добавить комплекс поискового оснащения(переход по ссылкам и запись контента в базу данных) можно написать за пару дней простенький поисковик(все функции парсинга и поиска по БД уже реализованы). Нужно только указать модели в каких таблицах и каких столбцах осуществлять поиск по MySQL RegExp или тупо по статических кэшам запросов БД чтобы не грузить сервер сильно(сниппет сделан по мотивам поисковой выдачи Google), также вся система поддерживает BigInt данные.

Поисковый сниппет RevolveR CMF

В систему добавлен терминал, позволяющий выполнять bash команды операционной системы или консоли Windows(в планах научиться использовать Power Shell из PHP).

Terminal

Оптимизация


Поскольку весь код писался на низкоуровневых функциях без сторонних библиотек и великолепно оптимизирован с участием кэша трех уровней:

  1. Сжатые CSS и JavaScript;
  2. Кэш шаблонизатора (свой шаблонизатор на Cache Conclude);
  3. Кэш запросов базы данных (если RevolveR не пишет статистику посетителей, то framework работает в режиме partial Kernel run и к базе для анонимного посетителя происходит 0 запросов).

Мне удалось достичь просто отличных цифр оптимизации: все ядром с шаблонами выполняется за доли секунды при этом тратиться памяти на сайт из 10 страниц порядка 3х мегабайт. Кроме того, front-end оптимизирован так, что позволяет в 240кб упакованного трансфера кода уместить и скрипты и рендер c бэкенда и даже остается место для иконок флагов всех стран на SVG и картинок интерфейса(подходит быстрой загрузки и отдачи в условиях с плохим интернетом).

RevolveR CMF performance

Что в заключение?


Я написал пока только одно расширение для системы — модуль обратной связи, который прописывается в системные URL и позволяет отправлять feedback гостям с вложениями файлов, но планирую также создать модули форума и интернет магазина.

Privacy Policy

Если не учитывать базы данных IP адресов, которые используются для ведения статистики посещаемости сайта от Max Mind(БД весят 60Mb), то весь код весит 1.93 мегабайта(сравните с Drupal или Wordpress при схожем функционале). Писать на strict PHP SPL для меня было как вызов по супероптимизации кода.

Размер дистрибутива RevolveR CMF

Еще 2 мегабайта и я создам модули каталогизации страниц на подобие Wikipedia, форум и модуль интернет магазина.

Не спрашивайте почему я не использую composer и объекты в качестве сущностей для доставки данных к front-end. Я не могу объяснить мою ненависть к ООП, когда объекты жрут в 4 раза больше памяти и процессора, чем ассоциативные массивы. Возможно, они появятся позже в более высокоуровневых классах, а пока мой код выполняется за тысячные доли секунды даже на самом дешевом Linux хостинге и мне это поднимает самооценку.

Setup extension

Скорее всего данная система превратиться в CRM для магазина дверей и окон c модулем интернет магазина, где я работаю (уж очень мне не нравится 1C).

Прощу пощупать мою систему и высказаться по поводу программирования для себя, Open Source, простых людей людей, который нужен интерфейс и продвинутым, которые захотят программировать сами.

Стоит ли продолжать писать CRM на базе RevolveR CMF и сколько мне понадобится разработчиков через 5 лет (сейчас все тяну один)?

Ссылка репозитория на GitHub.

Для установки просто распакуйте последний release на хостинг или localhost и заполните данные админа, а также подключения к базе данных. При использовании Open Server достаточно создать базу данных с именем revolver и ввести в форму инсталлятора данные аккаунта администратора. RevolveR CMF поддерживает только PHP 7.4 и выше.

Будущие обновления до версии 2.0 подразумевают ручной alter таблиц базы данных если структуры базы данных будет расширена каким-то опциями (Чекбокс dashboard -> performance -> auto alter DB tables).

В версии 2.0 планируются визуальный конструктор структуры БД c созданием пользовательских HTML форм, которые будут автоматически связаны с моделями (там будет больше объектов для использования в шаблонизаторе), а пока применен свой паттерн псевдо-объектов на ассоциативных массивах и генераторах для получения максимальной производительности.

Об обновлениях можно будет узнать в группе Facebook так как пока до версии 2.0 самостоятельный update через админку не доступен (в 2.0 будет также вмонтирована документация по созданию своих расширений и использованию API моделей в админку).




Комментарии (18):

  1. NikitchenkoSergey
    /#21986050 / +3

    Ну если вам нужна обратная связь, держите немного критики:

    • не использовать composer в 2020, из этого вытекает следующий пункт
    • велосипедить все на свете место использования готовых компонентов. Вы просто игнорируете опыт всего PHP сообщества не используя готовые, хорошо отлаженные компоненты. У вас даже QueryBuilder свой, если это вообще можно так назвать. 90% вашей CMS можно собрать из готовых пакетов, и это будет в 100 раз полезнее и удобнее.
      Сейчас в вашем велосипеде никто не сможет никогда разобраться, да и не захочет.
      Почему вы не взяли тот же Laravel и не сделали CMS на нем? Если бы вы реализовали крутую админку с готовыми модулями, может кому-то бы и пригодилось.
    • смотря на ваш код, начал ностальгировать по 2010 году — никаких тебе PSR, никакого автолоада, куча непонятных массивов, магия. Действительно похоже на Drupal 7. Только ничего хорошего в этом нет.

    Я вам крайне рекомендую прекратить ненавидеть ОПП, ознакомиться с PSR, попробовать какой-нибудь хороший фреймворк типа Laravel, иначе вы так и останетесь в 2010 году.
    Простите, если грубо написал.

    • Full-R
      /#21986094 / -6

      А вы бы с проститутками сели кушать за один стол? Мне кажется ваша непритязательность и тяга к халяве лишь намекает о квалификации.

      • NikitchenkoSergey
        /#21986148 / +1

        Ну-ка, раскройте мысль про проституток. Мне даже интересно стало, как это все связано.

        • Full-R
          /#21986614 / -3

          Раскрываю.

          > не использовать composer в 2020, из этого вытекает следующий пункт

          Чтобы в ядро не толкали код не соответствующий стандарту и не нарушали концепцию минимализма я не допускаю использование сомнительного парсера namespace и последующего шаринга по папкам. Код ваших автолоадов зачастую полное говно и не поддерживает strict types, что не допустимо в RevolveR.

          В следующей версии появится API сборщика ядра. Это будет разбор config файла циклом и проход по указанным путям для регистрации частей Kernel c require. Это никогда не будет autoload в силу причин, которые я указал выше.

          > Вы просто игнорируете опыт всего PHP сообщества не используя готовые, хорошо отлаженные компоненты. У вас даже QueryBuilder свой, если это вообще можно так назвать. 90% вашей CMS можно собрать из готовых пакетов, и это будет в 100 раз полезнее и удобнее.

          Я также лишил framework ошибок всего сообщества PHP.

          > У вас даже QueryBuilder

          А это хорошо или плохо? Я использую модели для получения из базы и они кэшируют вместе с DataBaseX. Я вообще позволил разработчикам не писать SQL так как это решает модель на 100%.

          > Почему вы не взяли тот же Laravel и не сделали CMS на нем?

          Вы бы сели кушать с проститутками за один стол?

          > смотря на ваш код, начал ностальгировать по 2010 году — никаких тебе PSR, никакого автолоада, куча непонятных массивов, магия. Действительно похоже на Drupal 7. Только ничего хорошего в этом нет.

          Мой код новее, чем в D7 и в Laravel. Привыкайте. На носу 2020, а вы гнобите своих отечественных разработчиков по привычке, что они работать не умеют. Это вы живете в чужих парадигмах и работаете по чужой записке сами ни чего мне создавая.

          Документация будет интегрирована с такой опцией, как визуальный конструктор моделей, который будет создавать и модель для доступа к данным и структуру базы данных и даже связывать с формами HTML. То есть вы сможете создать ноду, сервис к ней и просто создать трансфер необходимых данных с готовым интерфейсом в пару кликов по гайду. Документация в данном случае не пишется сразу из-за того, что Kernel меняется. Справка будет прямо в админке.

          По поводу вашей квалификации уточняю:

          > никаких тебе PSR, никакого автолоада, куча непонятных массивов, магия.

          Если для вас 2 мегабайта оптимизированного под OpCode(RevolveR CMF реально не ускоряется опкодами потому что создан почти на опкодах) программирования магия — мне вас жаль. Продолжайте жрать память и процессор вместе с деньгами потребителя.

          Я могу и на RPI запустится и в отпуске с NetBook на Intel Atom работать и мне все что нужно — это Sublime Text 3 и Open Server.

          Так вот я вас спрашиваю — почему вы унижаете меня словами про Laravel. Вы просто как тролль залезли и хотели испортить мне настроение, а после этого еще сказали, что есть Французское но лучше и надо работать на нем. Я написал что создаю новый contents management framework, а не беру готовое у кого либо.

          • grayfolk
            /#21986626 / +1

            Я также лишил framework ошибок всего сообщества PHP.

            Наконец-то.
            Наконец-то, появился разработчик, пишущий идеальный код, для которого даже не нужны тесты, подтверждающие это. Теперь заживем!
            Я написал что создаю новый contents management framework, а не беру готовое у кого либо.

            Странно, почему вы тогда берете готовый ЯП, а не пишете свой? Тяга к халяве?

          • grayfolk
            /#21986628

            Код ваших автолоадов зачастую полное говно

            ПИСАТЕЛЬ: Я писатель!
            ЧИТАТЕЛЬ: А по-моему, ты говно!
            (Писатель стоит несколько минут, потря-
            сенный этой новой идеей и падает замерт-
            во. Его выносят.)

            Простите, не удержался.

            • Full-R
              /#21986634 / -3

              И что вы со мной сделаете, когда будет в 20 раз круче чем у вас, но проще и новее? (: Будете шаблонные вопли про PSR, объекты, тесты и восхваления Laravel использовать?

              • grayfolk
                /#21986642

                Вопли пока что только у вас. Круче? Удачи вам. Я только за, чтобы создавалось что-либо, более крутое, чем есть.
                P.S. Да, «Простите, не удержался.» — не вам, Full-R, адресовалось.

  2. pqbd
    /#21986282 / +1

    Допустим… но

    считать, что framework созрел для публики

    Где документация, Карл? Ну хоть какая-нибудь?
    Где ну хоть какие-то тесты?
    Где хоть какие-то замеры производительности (в сравнении с)?

    PS: почему 1.9.1? В коде же ясно написано
    // Kernel version
    define('rr_version', '1.9.0');

    или вот
      * RevolveR Cipher Class
      *
      * v.1.8.0

  3. Aios
    /#21986976 / +1

    Забавная ситуация, в посте велоспиед, в коментах д'артаньян.
    пошел за попкорном.

    • Full-R
      /#21987046 / -4

      Смузи не забудьте и трубочку после шлюх протрите.

  4. Full-R
    /#21987682 / -2

    В общем вот что я натворил. Поскольку у меня приложение с одной точкой входа(любые URL пути обрабатывает index.php) я решил сделать компиляцию ядра в автоматическом режиме.

    Набросок следующий. Тут будет более подробная описаловка файлов ядра и комментарии по API в дескрипшнах:

    <?php
    
     /*
      *
      * RevolveR 
      *
      * Contents Management Framework
      *
      * v.1.9.2
      * 
      *
      *
      *
      *
      *                   ^
      *                  | |
      *                @#####@
      *              (###   ###)-.
      *            .(###     ###)   *           /  (###   ###)   )
      *          (=-  .@#####@|_--"
      *          /\    \_|l|_/ (  *         (=-\     |l|    /
      *          \  \.___|l|___/
      *          /\      |_|   /
      *         (=-\._________/  *          \             /
      *            \._________/
      *              #  ----  #
      *              #   __   #
      *              \########/
      *
      *
      *
      * Developer: Dmitry Maltsev
      *
      * License: Apache 2.0
      *
      */
    
    #
    # Allow strict
    #
    # To run framework with developers
    # use strict_types = 1 bellow
    #
    
    declare( ticks = 0, strict_types = 1 );
    
    define('StartTime', microtime(true));
    
    define('MemoryStart', memory_get_usage());
    
    if( is_readable('./kernel.php') ) {
    
      require_once('./kernel.php');
    
    }
    
    define('KERNEL_CONFIG', [
    
      'Parts' => [
    
        'Kernel#0' => [
    
          'Countries list' => [
    
            'directory' => './private/',
            'file'    => 'Countries',
    
          ],
    
          'Translations of interface' => [
    
            'directory' => './private/',
            'file'    => 'Translations',
    
          ],
    
          'Structures of DataBase' => [
    
            'directory' => './Kernel/Structures/',
            'file'    => 'DataBase',
    
          ],
    
          'Kernel HTML Forms API' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'HTMLFormBuilder',
    
          ],
    
          'Kernel Calendar' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Calendar',
    
          ],
    
          'Kernel User Agent Detection' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'DetectUserAgent',
    
          ],
    
          'Kernel Notifications' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Notifications',
    
          ],
    
          'Kernel Parser' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Parse',
    
          ],
    
          'Kernel Markup' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Markup',
    
          ],
    
          'Kernel Optimizers' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Minifier',
    
          ],
    
          'Kernel Language' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Language',
    
          ],
    
          'Kernel Captcha' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Captcha',
    
          ],
    
          'Kernel Data Base API' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'DataBaseX',
    
          ],
    
          'Kernel Cipher' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Cipher',
    
          ],
    
          'Kernel Auth' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Auth',
    
          ],
    
          'Kernel Menu' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Menu',
    
          ],
    
          'Kernel Route' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Route',
    
          ],
    
          'Kernel Node' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Node',
    
          ],
    
          'Kernel Variables' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Vars',
    
          ],
    
          'Kernel Mail' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Mail',
    
          ],
    
          'Kernel Models' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Model',
    
          ],
    
          'Kernel Statistics' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Statistics',
    
          ],
    
          'Kernel Extra MMDB Decoder' => [
    
            'directory' => './Kernel/Modules/Extra/',
            'file'    => 'MMDBDecoder',
    
          ],
    
          'Kernel Extra MMDB Reader' => [
    
            'directory' => './Kernel/Modules/Extra/',
            'file'    => 'MMDBReader',
    
          ],
    
          'Kernel Resolve' => [
    
            'directory' => './Kernel/Modules/',
            'file'    => 'Conclude',
    
          ],
    
          'Kernel Core' => [
    
            'directory' => './Kernel/',
            'file'    => 'Kernel',
    
          ],
    
        ]
    
      ]
    
    ]);
    
    
    # READ KERNEL CONFIG
    
    $src = '';
    
    foreach( KERNEL_CONFIG['Parts']['Kernel#0'] as $KPart ) {
    
      $src .= str_replace(['<?php', '?>'], ['', ''], file_get_contents( $KPart['directory'] . $KPart['file'] .'.php' ));
    
    }
    
    file_put_contents('./kernel.php', '<?php'. $src .'?>');
    
    ?>
    
    


    Я хочу добавить вычистку комментариев из кода и убрать переносы строк, но для этого надо парсер дорабатывать и думать над RegExp.

    Мы в общем описали части kernel и прохреначили их в один файл. Далее при перезапуске проверили, что kernel.php существует(кстати, в Windows нельзя через put_contents создать файлы с именами Kernel.php и kernel) и выполнили его.

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

    Далее такой ворпос: я хочу автоматически собрать все ядро в компилят. Мне нужно сделать это один раз и в админку я добавлю кнопочку для перекомпиляции без участия кэш, когда разработчик добавил какие-то фичи и хочет перезапустить систему на продакшн. Сейчас вроде никто в сиджик не компиляет, но мне хочется погонять тесты без JIT пока его нет и потом с ним. Есть у нас еще FAST CGI. Есть ли какая-то терминальная команда типа shell_exec('complile fcgi ./kernel.php'), которую я могу использовать, чтобы потом запускаться со скомпилированного ядра.

    Это позволит мне запатентовать систему, как полноценное приложение согласно РосПатентовским правилам, а не использовать ее как скрипт, который патентовать нельзя.

    Подскажите есть ли смысл компилять и как скомпилять kernel.php. Код я пока не выкладываю потому, что хочу минификатор и патчер дописать, чтобы все файлы ядра склеивало максимально компактно.

  5. SerafimArts
    /#21987802 / +2

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

    Объекты "жрут" в полтора-два раза меньше оперативы, нежели идентичные по количеству полей хеш-мапы (массивы). Единственное преимущество массивов — это скорость инициализации на выделенной памяти (т.е. там где не требуется дополнительная аллокация), которая примерно на 20%-30% выше по сравнению с объектами. Что, в свою очередь, даёт преимущество при передачи таких данных в больших количествах (с коротким жизненным циклом, что б GC подчищал это сразу): Например, отдача миллионов тьюплов из итератора, вместо DTO. Но естественно — это вообще копейки.


    Не спрашивайте почему я не использую composer и объекты

    Использование композера и как следствие ленивой подгрузки позволит на порядки сократить использование оперативной памяти и на такой же порядок ускорить ПО. Очевидно, просто за счёт того, что код, который не нужен в какой-то определённый промежуток времени — даже не будет считываться. Более того — декларативные структуры (классы/функции) лишь попадают в таблицу символов, но не исполняются. Что, очевидно, быстрее, нежели любой императивный код (ваш капитан очевидность).


    Помимо этого, архитектура PHP устроена таким образом, что всё состояние хранится, если я ничего не путаю, в структурах _zend_executor_globalsи _zend_compiler_globals (в нормальном ZTS): https://github.com/php/php-src/blob/2dd2dcaf9c8bcdda9c687660da887c5fddeb7448/Zend/zend_globals_macros.h#L45 Внутри которой есть хешмапы с подключёнными файлами, классами, функциями и рантаймом: дефайнами и переменными в т.ч. Это говорит о том, что чем больше стейт приложения (больше переменных, больше констант, больше классов) — тем дольше производится поиск подходящих символов (так устроен поиск по хешмапам). Это понимание позволит понять, что использование стейтлесс объектов и ООП в частности в перспективе выльется в намного более производительное приложение, нежели процедурное или класс-ориентированное программирование, где одна переменная инициализируется и живёт в течении всей жизни приложения.




    Остальное расписывать довольно скучно и тривиально. Очередная реинкарнация "мегапроекта Sky" =))

    • Full-R
      /#21988828

      Ладно. Пока меня сливают откровенно можно полюбопытствовать. Вот вы пишете что zend напрямую участвует в работе PHP, но zend представляет из себя дополнительную обвязку и его кажется можно тупо отключить от SPL и ничего не сломается. Так ли это? И это вообще попытка пропиарить zend или я ошибаюсь? Я даже mb string не использую :)

      www.facebook.com/100312451429651/videos/452806098761578

      p.s.: хочу запустить индийский генератор бесплатного электричества на магнитах из акустики и подключить к Raspberi Pi, используя слабый канал интернет, чтобы продемонстрировать возможность работы RevolveR CMF без ущерба комфорта пользователя. Я создавал систему с низким энергопотреблением и для работы в медленных сетях на новейших методиках. Например спутниковый интернет на полярном круге, джунглях или в пустыне. Пришлось отключать не только расширения почти все расширения PHP и программировать аккуратно, но и думать над железом и образом Linux.

      • NikitchenkoSergey
        /#21990726 / +1

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

        • grayfolk
          /#21991916 / +1

          Индийский генератор кода уже явно запущен =)

  6. Full-R
    /#21989160 / -1

    А есть кнопка «пожаловаться на преследование»? Дело в том, что я на одном форуме написал татарам, которые так любят брать французские имена типа Рафаэль(и Ларавэль они тоже любят), что они были когда-то русскими, которые попами меряли письки монголов и стали татарами, марийцами, башкирами, видимо еще и бурятами. Но не смотря на иго мы справились и живем в России, а на изнасилованных не обижаемся. С тех пор они меня прямо преследуют всюду в интернете :) Я конечно обнулю карму, когда волна схлынет, но, я считаю, что хабру нужна опция как у Facebook «Пожаловаться на травлю».

    • grayfolk
      /#21992346

      А есть кнопка «пожаловаться на преследование»?

      Есть. Профиль - Reset:
      image