Разработка на javascript или как я до этого докатился.

Внимание! Много буков. А еще MODX будет представлен не в самом лучшем виде, но я обещаю быть объективным. Тем не менее, особо чувствительным не рекомендуется к прочтению.

Данный топик — ответ на этот комментарий.

Два года назад, почти одновременно, я начал три довольно сложных проекта. Конечно же я писал их на MODX. Но в процессе я столкнулся с некоторыми сложностями, которые на мелких и средних проектах не так сильно себя проявляли, но здесь они грели голову весьма и весьма. Что это за проблемы?

1. Работа с моделью данных.
Как много здесь тех, кто умеет программно средствами MODX редактировать таблицы? Создавать новые, редактировать имеющиеся (добавлять/удалять колонки и индексы) и т.п.? Думаю не много. И не воспринимайте это как очередное издевательство с моей стороны. Статистика говорит, что тема не очень популярная modx.pro/search?query=createObjectContainer
А не популярная она, потому что слишком сложная. Вот немного объяснения. Если вы руками подправите свои мап-файлы, вы сможете внести изменения в таблицу. И можно делать это без перегенерации схемы. Вот здесь обсуждали не очень активно добавление колонки. Жаль, что в подобных топиках желающих помочь советом знатоков не так много, как ко мне заглядывает…
Если кто-то все еще не уверен, что это сложная тема, советую к прочтению.

Так к чему я это? Проект развивался, и вместе с этим приходилось вносить изменения в базу данных. Для этого конечно же приходилось править модель. И вот ты правишь модель ручками, прописываешь связи с другими объектами, думаешь как их назвать, чтобы не возникло нигде конфликтов, потом деплоишь схему… И вот тут хорошо, если это просто добавление новых сущностей. А если надо переименовать таблицы/колонки, в которых уже есть данные?
Кстати, про конфликты имен я тоже не просто так упомянул. Что делать, если ты решил создать таблицу, которая уже используется другим компонентом? Помните, как из-за подобных конфликтов Василий поубирал свои исходники? Согласитесь, неприятно.

Есть и у меня своя «история успеха», которая очень запомнилась. Вроде никто и не виноват, но все же. Кто помнит Шона МакКормика? Если кто и не знал про него, то имеет смысл заполнить этот пробел. Когда из MODX LLC неожиданно возникло SiphonLabs, Шон ушел из MODX. Я до сих пор сожалею об этом и считаю, что именно из-за этого мы так долго ждем (или уже не ждем) MODX3. Ведь всем известный Джейсон Ковард — ярковыроженный бэкенд-разработчик. А вот ту часть админки, которую все видят, заходя в manager/ — это творение Шона. И хотя в последние несколько лет ее пытаются как-то переоформить, сделать типа лучше, на самом деле там ничего толком не меняется, потому что сама JS-логика, написанная им, до сих пор юзается как есть, и по большей части не трогается годами


Ну поменяли цвета и иконки, а что толку? се то же самое, только целлофане. Обидно на самом деле. За эти годы он много что мог полезного сделать для развития MODX, но… Замену так и не нашли.
Сорри, это небольшое лирическое отступление было, просто вспомнилось. А суть: оставил он и мне наследие :) Есть у меня один компонент, modRedirect называется. Я его особо не пиарил, так что наверняка многие не слышали, но это совсем не беда. А вот немного беда была, когда на сайте он как-то сильно забарахлил. То есть вроде есть и работает, но как-то совсем уж плохо. Пациент больше мертв, чем жив. И никаких четких признаков. Просто редиректы не срабатывают и все. Стал разбираться, и выяснилось интересное: оказывается, на сайте еще стоял Redirector от Шона. Казалось бы, стоит и стоит, верно? Компоненту несколько лет и вроде как временем проверенный. А оказалось, что хоть компонент и называется Redirector, Шон класс таблицы назвал не Redirector, а modRedirect :) Забавно, да?:) А у меня тоже modRedirect. И что получается. Вроде как везде все хорошо, но только вместо моего класса, срабатывает его. Вот и проблемка. При чем пакость в том, что не было никаких логов, технической ошибки не было, была коварная логическая ошибка.

И когда вот все это пройдешь, когда день убьешь на то, чтобы скорректировать модель, начинается следующий квест: скорректировать программный код. Запросы поменялись, параметры поменялись, короче все поменялось. А главное, смотришь такой на свой же код, который писал день/неделю/месяц назад и думаешь, а что в нем после корректировки модели можно поменять, а что нельзя. Так-то выглядит лишним, а так-то может потом где вылезет скрытой ошибкой, и ищи потом где что не так. И вот программный код растет, все это нагромождается, усложняется, и в какой-то момент начинаешь уже осознавать, что тратишь все время на корректировки имеющегося не очень хорошо работающего, вместо того, чтобы писать уже новый функционал. Просто потому что на это уже не хватает времени. Какую-то мелочь скорректировать — и понимаешь, что зацепит много всего и потом опять бесконечные корректировки…

Что же я имею на сегодня в противовес этому?
Есть вот компонент пользователя и в нем прописана структура модели этого самого пользователя (уверен, понять примерно назначение этой структуры по силу многим). Вот я себе хочу создать базу данных с таблицей на основании этой модели. Я выполняю несколько команд:
mkdir test
cd test
git clone https://github.com/prisma-cms/user-module
cd user-module/
yarn
endpoint=http://test-endpoint.modxclub.ru/user-module/test yarn deploy
И все. Вот у меня есть готовая база данных с таблицами и полями, а плюс к этому уже почти на все случаи жизни методы для работы с этими данными. youtu.be/lA0ynX0-ZsY
И готовая документация есть, какие сущности, какие поля, какие методы доступны.


Зайдите сами посмотрите test-endpoint.modxclub.ru/user-module/test и пощелкайте.

Да, это админское API, а не ограниченное, так что приведенный выше код можете самостоятельно протестировать, создав для себя свою базу и API. Просто замените test-endpoint.modxclub.ru/user-module/test на какое-нибудь свое, к примеру test-endpoint.modxclub.ru/my-user-module/my-stage

А теперь, если вы у себя все это проделали, выполните вместо endpoint=http://test-endpoint.modxclub.ru/user-module/test yarn deploy вот эту команду:
endpoint=http://test-endpoint.modxclub.ru/user-module/test yarn start
Теперь у вас запустится локально пользовательский API-сервер, по умолчанию адрес localhost:4000
Он будет сильно похож на админский, но все же отличаться. В случае с этим модулем, у вас появится не только голая модель пользователя, но и более пользовательские методы с дополнительной валидацией, такие как регистрация (signup), авторизация (signin) и получение текущего авторизованного пользователя (me).


Уже есть с чего начинать строить свою маленькую социальную сеть :) (а может и не маленькую).

А теперь выполняем все то же самое, но уже с другим модулем: github.com/prisma-cms/upload-module
Возвращаемся в тестовую папку, куда клонировали пользователей и выполняем чуть другие команды.
git clone https://github.com/prisma-cms/upload-module
cd upload-module/
yarn
endpoint=http://test-endpoint.modxclub.ru/upload-module/test yarn deploy
PORT=4001 endpoint=http://test-endpoint.modxclub.ru/upload-module/test yarn start
Я в конце добавить PORT=4001, чтобы запустить этот модуль локально на другом порту, так как сейчас порт 4000 занят модулем пользователей, и при попытке запуска будет ошибка. Error: listen EADDRINUSE :::4000
А так у меня один модуль работает на одном порту, а другой на другом. И таких сервером запустить можно много, на сколько портов хватает.


И вот у нас еще один API-сервис.

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

Файлы вы из этого интерфейса просто так не загрузите, но ниже я покажу как это работает. Пока же условимся на том, что у нас есть один сервис под пользователей, а другой под файлы. Еще есть модули логов, почты, ресурсов, проектов-задач-таймеров и т.п., но мы не будем их сейчас все устанавливать, нам же двух для примера хватит, верно? :)

И вот сейчас самое интересное: у нас есть два отдельных сервиса. Но нам не надо два, нам надо один, и чтобы там были и пользователи, и файлы, и чтобы загрузка только для авторизованных пользователей была, и чтобы связи Пользователи-Файлы были. Короче, все хотим!

Хорошо. Хотим — значит сделаем. Мы же такие? :)

Мы сейчас находимся в модуле файлов, так давайте его и отредактируем.
1. установим user-module как зависимость yarn add @prisma-cms/user-module
2. Открываем src/modules/index.mjs и в шапке файла дописываем зависимость import UserModule from "@prisma-cms/user-module";
А в constructor в конце дописываем
this.mergeModules([
  UserModule,
]);
Выполним деплой, только в новую базу (оставим оригинал для сравнения).
endpoint=http://test-endpoint.modxclub.ru/upload-module/test2 yarn deploy

Вот теперь у нас есть и пользователи, и файлы


Единственное, нам сейчас не хватает связей Пользователи-Файлы.

Идем в папку src/modules/schema/database. Там уже есть file.graphql с описанием модели файла и мы могли бы дописать в него, но не будем так делать, а просто создадим еще один файл extended.graphql и запишем в него:
type File{
  CreatedBy: User
}

type User{
  Files: [File!]!
}
и выполним опять деплой схемы в ту же базу.
endpoint=http://test-endpoint.modxclub.ru/upload-module/test2 yarn deploy

Этот результат выполнения я процитирую здесь:
$ endpoint=http://test-endpoint.modxclub.ru/upload-module/test2 yarn deploy
✔ 
Changes:

  User (Type)
  + Created field `Files` of type `[Relation!]!`

  File (Type)
  + Created field `CreatedBy` of type `Relation`

  FileToUser (Relation)
  + Created relation between File and User


Your Prisma GraphQL database endpoint is live:

  HTTP:  http://test-endpoint.modxclub.ru/upload-module/test2
  WS:    ws://test-endpoint.modxclub.ru/upload-module/test2


⠋ Get schemaHandlerObject.flags { 'env-file': undefined }
Schema file was updated: src/schema/generated/prisma.graphql
⠋ Generating fragments for project app...src/schema/generated/api.graphql
✔ Fragments for project app written to src/schema/generated/api.fragments.js
Done in 4.39s.
После этого посмотрите изменения в схеме:


Теперь и запросы можно строить со связками:


При этом у нас не только модель, но и контроль за целостностью данных. Не даст он мне привязать к пользователю запись файла, которой не существует.


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

А вот еще фишка: я сейчас удалю схему пользователя и попробую задеплоить ее.
✖ Exited with code: 1
✔ 
Warnings:

  User
    ! You already have nodes for this model. This change will result in data loss.

If you want to ignore the warnings, please deploy with the --force flag: $ prisma deploy --force
Read more about deployment warnings here: https://bit.ly/prisma-force-flag
Ой, у меня оказывается есть данные в базе, которые будут затронуты данным изменением, поэтому прерывается. Но говорит, что если все-таки хотите удалить, выполните эту команду с флагом --force, и будет вам счастье (если бэкапы есть).


Есть в MODX что-то близкое к этому?

Ну да ладно, едем дальше. API-то у нас есть, но что делать дальше?


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

Но в нашем повествовании это еще не конец. Не зря же я вверху поставил 1. Едем дальше… Хотя вторая часть будет короче.

2. Бэк и фронт живут своей жизнью.
Вот даже не знаю, что меня больше достало, то ли модель постоянно корректировать, то ли фронт потом под изменения догонять… С каждой новой «фишкой» на странице, кошмар рос в геометрической прогрессии. Эта жучка с ее глобальной областью видимости… несвязанные друг с другом отдельные компоненты страницы, когда одно редактируешь, а другое вроде должно обновиться, но не обновляется… лишние повторные запросы на сервер… 100500 JS/CCS файлов (85% из которых уже давно не актуальна, но когда удаляешь, выясняется, что 1% оттуда все-таки использовался и именно из-за этого на всю страницу появилась большая желтая полоса)… Как вспомню… Стар я стал для всего этого дерьма…

3. На каком языке я сейчас пишу?
Заключительная причина, совсем сжатая.
Со временем начинаешь в php писать console.log(), в JS print_r()… Блин, в какой-то момент это уже начинало бесить. При чем самый треш происходит, когда какую-то часть логики с фронта нужно было перенести на бэк, а там php… Приходилось переписывать. А эти языки не только синтаксисом отличаются… Сейчас я хоть с фронта на сервер переношу, хоть наоборот во фронт. А нет, что я такое говорю?! Для меня же сейчас вообще практически нет такой разницы:) Это называется «изоморфные приложения».

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

Вот, собственно, так я и докатился до этого. 8 лет плотно работал с MODX, но столкнулся с задачами, которые мне сказали «Парень, ты не осилишь нас этой мотыгой, пора хотя бы мотоблок в руки взять...». Первый год было очень больно. Не буду перечислять всего, но в ту бытность даже webpack приходилось самому конфигурировать, и graphql-схемы я вручную писал, и много еще всего интересного было. Но где-то с полгода назад я уже почувствовал, что у меня в руках уже весьма хорошие наработки, и с ними я сейчас не редко за один-два дня делаю столько, сколько до этого на MODX делал месяц, а то и не один. И вот как-то привыкаешь к хорошему и назад уже не хочется. Но каждый выбирает для себя свой путь сам, и рабочие инструменты тоже.

UPD: Забыл еще один немаловажный момент отметить: безопасность. А-я-яй! Кому-то больно стало? Да, это лето у нас жарким было. К слову, по статистике запросов вижу, что тема все еще не закрыта, до сих пор ломают MODX-сайты. Запилил свежий топик с процедурой восстановления.

Так к чему я про эту безопасность? А к тому, что в моем случае есть только одна точка активного взаимодействия с сайтом — вот это вот самое API. Другой точки просто нет. Все остальное — это на чтение только. И самая соль в том, что именно схема определяет что и в каком виде можно отправлять в API-запросах. Если сказано, что на обновление пользователя можно отправлять только fullname типа Строка, то отправить можно только строку. В последних версиях graphql вообще, если указан тип Int, а ты пытаешься отправить '10', а не 10, такое не пройдет, будет возвращена ошибка. Хотя явно '10' легко конвертируется в 10 и еще недавно graphql позволял такое пропустить, сейчас уже не позволяет.
Fi1osof
11 декабря 2018, 23:10
modx.pro
3
1 624
+17

Комментарии: 52

Дмитрий Ломакин
12 декабря 2018, 05:46
0
С нетерпением ждем открытия jsclub.ru!

ps просто шутка, без обид.
    Fi1osof
    12 декабря 2018, 08:29
    0
    Да, modxclub.ru будет скоро переименован :) Но статьи никуда не пропадут. И это не шутка, простите))
    Павел Гвоздь
    12 декабря 2018, 07:56
    +1
    Вот читаешь Николая и в каждом его слове видишь «подковырку», стёб, самолюбование, даже если это не так! Репутация дело такое…
    Статья классная, я заинтересован! Благодарю!
      Fi1osof
      12 декабря 2018, 08:29
      +1
      Сорян, настрой с прошлой статьи остался. Но я сдерживался)
      Николай
      12 декабря 2018, 09:02
      0
      Правильный ли я вывод сделал, что MODX не годится для более менее крупных проектов, что многое в нём устарело? И что приведённое API это некий костыль, чтобы MODX кое-как хромая на одну ногу, продолжал идти дальше?
        Павел Гвоздь
        12 декабря 2018, 09:11
        0
        Статья вообще не о MODX. Он там фигурирует только, как прошлое Николая.
          Fi1osof
          12 декабря 2018, 09:18
          0
          Ну, отчасти, все-таки этот комментарий не лишен смысла.
            Павел Гвоздь
            12 декабря 2018, 09:22
            0
            Я про текущую статью. В ней нет ни слова о том, что ты пытался скрестить Призму с MODX.
          Николай
          12 декабря 2018, 09:20
          0
          Ну так для Николая MODX в прошлом по причинам, что я указал?) Дескать нельзя на нём сложные вещи писать, поэтому он пробует другие технологии и фишки, типа приведённого API.
            Fi1osof
            12 декабря 2018, 09:47
            0
            Да, так и есть. Хотя когда-то он мне очень нравился. Но в то «когда-то» MODX был очень современной платформой, и это было не раз отмечено наградами. Но проблема в том, что он был тогда, а время идет, и технологии развиваются, а он практически стоит на месте. По мне, так это из серии «Оставьте старичка в покое».

            К слову, php мне теперь тоже ппц не нравится :) Но это уже совсем другая история.
          Fi1osof
          12 декабря 2018, 09:18
          0
          Не совсем так. На самом деле это вообще не MODX. Это самостоятельный JS-движок (кажется я забыл об этом упомянуть в прошлой и этой статье, видимо, потому что думал, что @prisma-cms как бы намекает...). А вот попытка сделать костыль под MODX была, и предыдущая версия modxclub.ru где-то с недельку поработала на таком костыле. Вот здесь почитайте. Честно сказать, у меня нет особо желания развивать эту задумку для MODX, хотя на самом деле она вполне себя так проявила, и вот сейчас ее применяю на другом сайте клиента, где тоже функционал весьма серьезный (система пропусков в бизнес-центре, да есть с мобайл-приложением), и вот надо прогресс двигать, а просто так за раз не перекинуть это все на JS, приходится костыли использовать. И вот хоть и с костылями, но теперь у меня там есть API:) Если заинтересованность будет и после прочтения той статьи останутся еще вопросы, могу запилить еще одну статью на счет того решения.
            Николай
            12 декабря 2018, 09:30
            0
            А фреймворки не рассматривали, типа Laravel? Есть даже OctoberCMS, написанная на нём. По ней много восторженных отзывов. Если статья появилась как ответ на комментарий Сергея Шлокова:

            Я выбрал Laravel. Ты ноду. Я в свое время тоже хотел погружаться в неё, но одумался :)
            то, что-то я не услышал в чём выгода вашей prisma-cms перед тем же Laravel, или OctoberCMS, написанной на нём. Иначе холивар какой-то слабый получится)) Мне правда пока сложно оценить внутреннюю кухню, нужно будет погрузиться в то и другое. Но может есть какие-то основные моменты по пунктам.
              shtyrman
              12 декабря 2018, 09:42
              +1
              Мне кажется что это получится сравнение Personal Home Page и js, со всем вытекающим)
                Fi1osof
                12 декабря 2018, 09:48
                0
                Смотрите п. 3 в статье. Ларка на php написана, а фронт пишется на JS. Я не хочу в одном проекте юзать разные языки.
                Николай
                12 декабря 2018, 10:52
                +1
                В общем, думал думал к чему это всё, зачем API, и вроде дошло. Поправьте если не так. Если упростить, то суть в том, что раньше была БД, и был PHP, который брал данные с помощью чистых запросов. Потом появилась PDO для более удобной работы с БД. В MODX даже xPDO, как надстройка над PDO. Но, всё это в рамках одного сайта. Если у меня 20 поддоменов, или есть мобильное приложение, то возникает куча костылей для получения данных из БД, привязанной к одному сайту. Сайт работает на какой-либо CMS, а их пруд пруди, везде свои нюансы, своё API и т.д. Если мне надо множить данные в другие источники, то придётся городить костыли под каждую конкретную CMS. И, собственно, @prisma-cms это универсальный инструмент. который позволяет подключаться к БД из разных источников, посредством универсального API. Там есть private-методы, и есть public-методы для общественности. С помощью них может подключаться куча других сайтов, или приложений, как мобильных так и десктопных. И таким образом контент будет синхронизироваться во множестве мест одновременно. А как вывести контент не суть важно. Можно в мобильном приложении, а можно хоть с помощью какой-либо CMS. По сути универсальную API не придумать, т.к. задачи могут быть совершенно разные. Но, для решения определённого круга задач можно придумать отдельную API, скажем, для организации блогов. Т.е. раньше был Wordpress как CMS для блогов, а мы, к примеру, придумаем специальную CMS с API для этих же задач. И тогда контент построенный на базе этой CMS будет синхронизироваться в куче мест. Т.е. пишу коммент в одном месте, и одновременно он появляется на других сайтах где был продублирован определённый топик. Безо всяких парсингов, выгрузок в xml и других костылей. Я верно понял?)
                  Николай
                  12 декабря 2018, 11:00
                  +1
                  Да и собственно «проблема» большинства CMS заключается в том, что БД жёстко привязана к интерфейсу, или каким-то другим ограничением системы, там множество зависимостей. Т.е. я не могу без костылей наладить связь между сайтом на MODX, и, например, Wordpress, т.к. в каждой системе свои нюансы. Придётся изобретать универсальный костыль подходящий как для MODX, так и для Wordpress. Причём каждой системе по костылю как минимум. Грубо говоря, получится что MODX связывается через костыль с костылём от Wordpress. А уже для Битрикса эти костыли не прокатят. Нужно городить 3-ий костыль как минимум. А если делаем облачную CMS, то тупо все данные получаем через одно API. А как получить неважно, может php-страничка запрос сделать, а может js-скрипт через ajax. Т.е. я могу тупо сделать простенькую страничку у себя на сайте, скажем, для вывода только лишь статей из определённого раздела, допустим, modx.pro. Подключился по API, несколько запросов, и готово. Безо всякой CMS. Верно?
                    Fi1osof
                    12 декабря 2018, 12:35
                    0
                    И здесь вы абсолютно верно все говорите. Более того, попробуйте набрать в поисковике «wordpress headless». У них уже полно решений на этот счет. И на тостере целевой вопрос как битриксу headless добавить. Короче, пока здесь сидят и кричат «Это мое! Не трогай!» и «MODX — устоявшееся офигенное сообщество, которому ничего не требуется, поди прочь!», другие устоявшиеся системы думают как шагнуть в ногу со временем. А ведь естьgraphql для php, к примеру, и внутри MODX очень даже можно читать запросы из @prisma-cms, или стать источником данных для призмы.
                      Николай
                      13 декабря 2018, 09:09
                      0
                      Тогда надо признать, что это довольно перспективное направление развития) Правда для блогов не думаю, что это сильно актуально. Мало кто захочет иметь дубли своего контента на других сайтах. Всё-таки информация это можно сказать «актив» для информационного сайта, благодаря которому он зарабатывает и как-то развивается. Авторитет ресурса привязан к одному домену. Да и поисковики не любят дубли. Разве что всякие мобильные приложения могут использовать API… Ну или в случае когда информация продаётся, как, например, база TecDoc для автозапчастей. Но бОльшая актуальность мне кажется для чисто коммерческих ресурсов. Допустим, какой-то поставщик даёт возможность торговать своими товарами с подключением к своему API. Или речь идёт о сетевых структурах, чтобы единая база была. В более частных случаях, наверное, ещё долго люди не поймут необходимости зачем им переходить с любимых CMS к каким-то сервисам. Если только сами сервисы не придут к ним, и не объяснят все выгоды)
                        Fi1osof
                        13 декабря 2018, 13:11
                        0
                        Николай, сейчас много чего и кому не понятно, в том числе и мне. Вы не видите, что интернет современный меняется? Сейчас ресурсов и информации слишком много, и многое из того, что работало раньше, не работает больше. Посмотрите на medium.com — полным-полно классных статей, оформлено все нормально, да и вообще. И что? Где комментарии? Только что и делают, что хлопают. А посмотрите на qaru.site/ или issuehub.io/ Угадайте, что это?
                        А недавно зашел на какой-то ресурс, типа медиума, то есть оформлено так хорошо, читаю вроде как статью с полезной информацией, но не терзает меня ощущение, что я это уже читал. Вспомнил! Я это читал на гитхабе в одном тикете.

                        И вот эти сайты частенько лезут в ТОП, хотя контент у них не уникальный.

                        А сейчас вот мне для одного проекта понадобится много справочной информации, в основном просто как структура каталогов. Где мне ее искать? Да википедия вся бесплатно распространяется. И программы есть специальные для ее парсинга и чтения. Пойду-ка скачаю свежую версию википедии себе.

                        Короче, пока большинство думают как себе создать свои медийные ресурсы с «ценнейшей и уникальной информацией», идет такая волна, что всех накроет и смоет, они и не поймут ничего. И вот же незадача, поисковики совсем с этим не борятся! Какие плохие. Но вы тут держитесь.
                          Николай
                          13 декабря 2018, 18:27
                          0
                          У википедии и ей подобных сайтов «траст» перекрывает другие сайты, которые её копируют) Бороться то с другими сайтами никто не борется в плане копипаста, просто в выдаче они будут за пределами топа. Ну то есть алгоритм поиска один для всех. И допустим по какому-то запросу нашлось множество ресурсов, которые с точки зрения релевантности практически одинаковы. Предпочтение получит наиболее авторитетный источник. И даже если википедия «сворует» мою статью с моего же сайта, то она будет по-любому выше. А вообще я согласен, информация обесценивается с каждым разом. Держать какие-то статейные сайты со своими умными мыслями не особо выгодно. Но давать возможность легко копировать эти мысли всем кому непопадя, без обратных ссылок, это вообще чистый альтруизм выходит) Если статья уникальная, она хоть как-то всплывёт по ключам. А если в сети множество копий этой статьи, то шансы мизерные. Ну при условии, что ресурс не особо популярный. Если хабрахабр, то с него не убудет) Просто представьте, что будет какой-либо портал, который как спрут будет качать инфу с кучи сайтов и собирать её в одном месте. Он станет монополистом. А для поисковиков, кстати, уникальность всё-такие играет роль. Если сайт постоянно радует их новыми текстами, да ещё показывает хорошие поведенческие показатели, то его авторитет будет расти. Сайт основанный на копипасте тоже может вырасти, но больше за счёт поведенческих.
                            Николай
                            13 декабря 2018, 18:58
                            0
                            Как пример. Если мою крутую статью расхватают все кому не лень, включая известные сайты, то это равносильно как если бы мою какую-то крутую разработку украли, присвоили авторство себе, а меня бы даже никто и не вспомнил.

                            А вообще эпопея с уникальным контентом длится со времен появления яндекса. У любого сеошника спросить, и я думаю они подтвердят, что уник по любому нужен и лучше неуника. Сколько фильтров всяких уже было, когда тысячи сайтов яндекс выкашивал за копипаст и бесполезность для юзеров. Обычно жалобные истории начинаются со слов, дескать, у меня был хороший сайт с полностью уникальными статьями, и… его забанили. Я не спорю, что копипасты полно в интернете, но если сайт успел завоевать популярность, его не забанят. В остальных случаях «молодняк» проходит кучу проверок, в том числе и на уникальность. Если робот сайта при обходе выясняет, что сайт на 100% состоит из копипасты, то зачем он вообще?
                              Fi1osof
                              13 декабря 2018, 19:03
                              +1
                              Если мою крутую статью расхватают все кому не лень, включая известные сайты, то это равносильно как если бы мою какую-то крутую разработку украли, присвоили авторство себе, а меня бы даже никто и не вспомнил.
                              Как раз сейчас мир к этому и идет. И что уж ваша крутая статья, люди и компании выкладывают готовые крутые решения в открытый доступ и дают в безлимитное пользование и даже право всяко редактировать и даже говорить, что это ваше. Не инструкции, а готовые решения. А вы тут со своими статьями. Не работает это больше.
                                Николай
                                13 декабря 2018, 19:43
                                0
                                Выкладывают, но это же конечном счёте 100%-ый коммерческий интерес) Они просто повышают свою популярность, цитируемость, узнаваемость, и в конечном счёте растёт траст в поисковиках. Как там, персональных бренд это вроде называется. А уже потом заработав пузомерки, монетизируют их. Так сказать игра в долгую. А те кто пытаются денюжку сразу заработать, у тех просто более мелкий бизнес.

                                stackoverflow.com/, github.com/
                                Пожалуйста, копируйте.
                                Ну так они уже бренд) Мой копипаст не подвинет их первоисточник в поиске. И к тому же зарабатывают они не на информации, а на сервисе. Я то пытаюсь доказать, что мелким «лавочникам» в массе своей это невыгодно. Тем более, чтобы кто-то копировал их статьи по-тихому, без обратных ссылок. Если со ссылками, то совсем другой расклад. Наоборот писательство может стать возможностью прославиться.

                                Это вряд ли. Рамблер тоже о таком местал, но у него не получилось. Хотя мордокнига тоже пытается к этому прийти.
                                Вы наверное не в курсе, что есть такие дорвейщики с которыми яндекс со времён своего существования борется) Это такие люди, которые ничего нового не несут в интернет, а тупо генерируют террабайты инфо-мусора, в том числе копипаста. За счёт которого нагоняют трафик, а потом монетизируют его разными способами. Если бы яндекс с ними не боролся, то количество информации в сети было бы существенно больше чем сейчас. Один дорвейщик это как вирус, который может производить сотни сайтов если это выгодно. А яндекс сделал так что это не выгодно, сделав кучу фильтров, в том числе и на копипаст.
                                Fi1osof
                                13 декабря 2018, 19:54
                                0
                                Ладно, все это дикий оффтоп. Предлагаю закруглиться.
                                Сергей Шлоков
                                13 декабря 2018, 20:06
                                0
                                Как раз сейчас мир к этому и идет.
                                Здесь как обычно — широкий выбор. Где-то такое же отношение как у тебя, где-то обратное. Всё зависит от подходов. Попробуй какую-нибудь авторскую песню добавить в своё видео на ютубе. У последнего есть библиотека бесплатных треков. Так что это не весь мир к этому идёт, а определённая часть сообщества. Другая свято чтит неприкосновенность авторского права.
                                Fi1osof
                                14 декабря 2018, 16:27
                                0
                                Есть подозрение, что другая часть проиграет.
                                Сергей Шлоков
                                14 декабря 2018, 19:34
                                0
                                Ага, как только Windows станет бесплатной Open Source :)
                                Fi1osof
                                14 декабря 2018, 20:25
                                0
                                Смех-смехом, а github.com/Microsoft/vscode и microsoft.github.io/monaco-editor/ — openSource
                            Fi1osof
                            13 декабря 2018, 19:00
                            0
                            Но давать возможность легко копировать эти мысли всем кому непопадя, без обратных ссылок, это вообще чистый альтруизм выходит)
                            stackoverflow.com/, github.com/
                            Пожалуйста, копируйте.

                            Просто представьте, что будет какой-либо портал, который как спрут будет качать инфу с кучи сайтов и собирать её в одном месте. Он станет монополистом.
                            Это вряд ли. Рамблер тоже о таком местал, но у него не получилось. Хотя мордокнига тоже пытается к этому прийти.

                            но больше за счёт поведенческих
                            Именно так. Я современный тренд вижу в том, чтобы брать информацию там, где она есть, но представлена не в лучшем виде, и выводить так, чтобы пользователю было эффективней с ней работать.
                    Fi1osof
                    12 декабря 2018, 12:29
                    0
                    Николай, вы сразу скакнули на первое место в адекватности комментариев в моих последних двух топиках. По сути это как раз то, что я и пытался донести до общественности, но, видимо, не так это делал. Вы сейчас коротко описали современную тенденцию — «безголовые ЦМС». Подробнее я об этом писал здесь.
                shtyrman
                12 декабря 2018, 09:45
                1
                0
                Это все понятно, я про бэк.
                Николай пилите лучше дальше статьи по фронту и бэку. Я читал их у вас. А сейчас не понятно, что у вас на ресурсе. Получается типа доска объявлений.
                И касательно фронта.
                Имея продолжительный опыт с реактом, думали уйти от этого кривого конструктора в сторону angular или vue?
                  Fi1osof
                  12 декабря 2018, 09:53
                  0
                  Вы видимо не уловили, что в статье рассматривался и бэк, и фронт. Но я писал там, что сейчас грани в этом сильно размыты, поэтому и кажется, что все это только фронт. Хотя на самом деле все это работает в том числе и на бэке. К примеру, ту нас же запросы летят, с записью в БД, и чтение информации, и работа с таблицами базы.

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

                  Для расширения кругозора советую к прочтению.

                  И не пытайтесь здесь доказать сейчас обратное. Лучше запилите отдельную статью подробную с примерами.
                    shtyrman
                    12 декабря 2018, 10:05
                    0
                    Да где же тут размытые грани? Вроде все вполне очевидно. Есть front end, есть back end, есть full stack.

                    Да кому мне что доказывать? Я не использую graphql, но я понимаю для чего он. Видимо мне просто хватает rest и тихонечко себе пилю на angular)

                    Но я больше интересовался статьями от вас. Типа с житейскими трудностями и реализацией их решения.
                      Fi1osof
                      12 декабря 2018, 10:13
                      0
                      Есть front end, есть back end, есть full stack.
                      Middle еще забыли…

                      Говорю же, вы меряете классическими рамками. Сейчас, еще раз, грани размываются.
                        shtyrman
                        12 декабря 2018, 10:27
                        0
                        Николай, дайте знать касательно статей)

                        Что значит размываются грани? Т.е. мальчик\девочка, имеющий опыт только на клиенте, спокойно может лесть и в серверную часть? Ведь везде js.
                          Fi1osof
                          12 декабря 2018, 11:03
                          0
                          По большому счету все именно так. Настоятельно советую к прочтению. Очень полезная статья для корректировки сознания.
                            shtyrman
                            12 декабря 2018, 12:35
                            0
                            Николай, вы же понимаете что это очередное описание очередного стэка? Я не очень понимаю что должен вынести для себя из этой статьи.
                            Я же говорил про статьи, ну реально мало статей в интернетах с бытовыми проблемами, а не статей с поверхностным описанием стэка) И потом вы сказали что мол все едино.
                            Позвольте с вами не согласиться. Если человек не знает что использовать — реляционную или нереляционную бд, то на выходе будет боль. И тем более как можно использовать туже postgresql не зная ее?
                            Я читал про graphql когда он появился. И если мне не изменяет память, он нужен для взаимодействия со всеми rest сервисами (причем на разных языках сделанные), которые используются, из одного места. Разве не так? А это по умолчанию много чего нужно уже знать, что бы все работало.
                            И кроме того знание js не означает что человек знает все области, если там есть js. Нынешний JavaScript — это в первую очередь инструмент. Который позволяет взаимодействовать с кучей чего — зная лишь один язык программирования.
                              Fi1osof
                              12 декабря 2018, 12:52
                              0
                              Позвольте с вами не согласиться. Если человек не знает что использовать — реляционную или нереляционную бд, то на выходе будет боль. И тем более как можно использовать туже postgresql не зная ее?
                              Позвольте и мне с вами не согласиться. Вы видели примеры выше? Вы пробовали сами их выполнить? Там хоть слово есть о том, как вам базу данных настроить? Реляционная вообще или нет? Там я вообще говорил, какая база используется? Вы удивитесь, если я скажу, что там даже не MySQL?..
                              На уже на сегодня призма позволяет использовать MySQL, PostgreSQL, Amazon RDS и MongoDB, а так же скоро будет Эластик, кассандра и другие (частично уже они поддерживаются). Если бы я поменял настройку и использовал, к примеру, эластик, мои примеры выше бы не поменялись ни на байт. Все было бы то же самое. И не пугайте людей словами типа «реляционная»…

                              Я читал про graphql когда он появился. И если мне не изменяет память, он нужен для взаимодействия со всеми rest сервисами (причем на разных языках сделанные), которые используются, из одного места. Разве не так? А это по умолчанию много чего нужно уже знать, что бы все работало.
                              Чуть-чуть не так. Он позволяет взаимодействовать с чем угодно, и не только с REST-сервисами, но и отдавать данные из памяти, из файлов, из других graphql-сервисов и т.п. Можно создать очень широкую сеть из таких микросервисов, на конце которых будет куча различных непонятных технологий, которые совсем никак не беспокоят конечных клиентов. Те взаимодействуют с единым интерфейсом на единой технологии. Своего рода API-ORM.

                              И кроме того знание js не означает что человек знает все области, если там есть js. Нынешний JavaScript — это в первую очередь инструмент. Который позволяет взаимодействовать с кучей чего — зная лишь один язык программирования.
                              Это по большому счету верно. Но в последнее время все менее и менее напрягает, как раз за счет унификации и развития микросервисов. К примеру, основная часть призмы (именно отдельного модуля, используемого в моей @prisma-cms), написана вообще на скала, и спрятана глубоко в докер-контейнере. Я там ни строчки не знаю. Я не знаю как она работает с БД (к слову, которая спрятана в другом докере, но не обязана быть именно там). А призма в целом использует кучу сторонних компонентов, включая graphql и apollo, и там намешано столько всего, что всех концов и не найдешь. Но их и не надо искать. Есть конечный продукт, написано как им пользоваться. Use as is и не лезь глубоко. Что-то работает не так — пиши багрепорт. К слову, призма очень оперативно работают с багрепортами.
                              Я бы сказал, что в чем-то, используя их, надо знать меньше, чем в MODX. Вот вам инструкция выше, в несколько строк, и у вас свое API готово. А теперь сравните с быстрым стартом в MODX.
                                shtyrman
                                12 декабря 2018, 13:16
                                +1
                                Позвольте и мне с вами не согласиться. Вы видели примеры выше? Вы пробовали сами их выполнить? Там хоть слово есть о том, как вам базу данных настроить? Реляционная вообще или нет? Там я вообще говорил, какая база используется? Вы удивитесь, если я скажу, что там даже не MySQL?..
                                Боже упаси меня лесть в чужой код) Да и тем более я вообще не имел в виду и не говорил, касательно вашей статьи, абсолютно ничего)
                                Я лишь поинтересовался статьями, мнением по фронту. А потом вы такой — все едино!
                                А то получается, что так же и не плохо бы про масштабирование, кластеризацию знать, виртуализации там всякие, тестирование, оптимизация, unix системы, а пусть еще haproxy, nginx, балансировка трафика, vlan, сетевое оборудование — кстати уже и сис админ выходит. А всем известно что сис админы ничего не делают, посему и завхоз позицию может совмещать. Еще полы мыть и после выходить в ночную смену сторожем.

                                Кстати, только сейчас понял, prisma-cms это ваш продукт?

                                Ну а что касается очередной ORM. Ну я хз, призму не использую. Все как то sequalize да sequalize.
                                  Fi1osof
                                  12 декабря 2018, 13:23
                                  +1
                                  Я лишь поинтересовался статьями, мнением по фронту. А потом вы такой — все едино!
                                  и далее.

                                  Я понял ваш намек:) Давайте так, чтобы было более конструктивно, я на днях напишу статью с примером изоморфного приложения, и там мы уже разберемся предметно, где грани стираются, а где непреодолимые стены.
                                    Fi1osof
                                    12 декабря 2018, 13:25
                                    0
                                    Кстати, только сейчас понял, prisma-cms это ваш продукт?
                                    Да. Но на базе сторонних решений, в основе которых www.prisma.io/

                                    Ну а что касается очередной ORM. Ну я хз, призму не использую. Все как то sequalize да sequalize.
                                    Я knex юзаю, но это не совсем относится к делу.
                                srs
                                srs
                                12 декабря 2018, 12:50
                                0
                                Справедливости ради таких статей как в одну, так и в другую сторону (а иногда даже и в три стороны сразу) тонны. Можно открыть хабр и зачитаться такими статьями. Сознание в таком случае будет как метроном колебаться)
                                  Fi1osof
                                  12 декабря 2018, 12:53
                                  0
                                  Согласен. Потому и выделяю, что в первую очередь полезней будет прочитать, где боле менее продуктивная информация, а не читать тонны низкосортного материала.
                      iWatchYouFromAfar
                      12 декабря 2018, 10:10
                      +4
                      Ну оставлю и свой не авторитетный фидбек. Статья очень интересная и уровень навыка автора классный. Но вот вопрос, а зачем это тут? Давайте бросим взгляд на экосистему modx.pro

                      1. Быстрый и классный магазин дополнений, куда каждый может загрузить свой компонент modstore.pro.
                      2. Мега удобный и быстрый хостинг modhost.pro
                      3. Свободная и обновляемая документация docs.modx.pro
                      4. Кладезь полезной инфы (при условии навыка использования поиска) modx.pro

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

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

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

                      Ну а пока что, повторюсь, экосистема modx.pro живее всех живых.

                      P.S.
                      Скорость модкс-клаба действительно впечатляет!
                        Fi1osof
                        12 декабря 2018, 11:00
                        +1
                        А я и не говорил, что всем срочно надо покидать MODX. Это было мое ИМХО, моя история, почему я, не просто пользователь MODX, а в свое время один из самых активных ее пользователей, оставивших в свое время определенный вклад в развитие этой экосистемы, а не просто смотрел на нее со стороны и смотрел кто делает вклад больше или меньше, покидаю ее. У каждого свой путь. Хотите в MODX — вообще не вопрос, это ваш выбор.
                        Alex
                        13 декабря 2018, 12:47
                        0
                        Николай, здравствуйте. Недавно начал интересоваться нодой. Не подскажете более менее внятные туториалы по Node.js, а не как вывести Hello World? В русскоязычном интернете с этим явно проблемы.
                        Возникла одна задачка, которую я никак не могу преодолеть. При обращении по УРЛ в массив notes заносятся данные, скажем ИД и время +30 мин после обращения (скажем сейчас 12:00, тогда в массив пишем 12:30). Далее я запускаю setInterval и каждую секунду перебираю массив notes. Примерно так:

                        setInterval(function(){
                                for (var i = 0; i < notes.length; i++){
                                    var curDate = new Date().getHours() + ':' + new Date().getMinutes();
                                    if ( notes[i]['time'] == curDate ) {
                                        fs.writeFileSync("log1.txt", "OK")
                                    }
                                }
                        },1000)
                        Если время сейчас и время в массиве совпадает, то выполняем действие. И вот тут как раз проблема — если действие нужно выполнить через 1-5 мин после обращения, то действие выполняется, а если через 30 или 60 мин, то нет. Хотя очень редко бывает, что и выполняется, но 1 из 20 раз, примерно. Уже перегуглил все что можно. Не подскажете куда копать по данному вопросу?
                        Нигде не могу найти ответа по поводу данного поведения — хочет срабатывает, хочет не срабатывает.
                          Fi1osof
                          13 декабря 2018, 13:32
                          +1
                          У меня два основных источника: developer.mozilla.org/ru/docs/Web/JavaScript и github.com. Хотя для начинающего скорее всего больше подойдет learn.javascript.ru/
                          JS — это совсем не быстро. Даже я, когда уже плотно занялся им, только через год минимум почувствовал себя боле менее уверенным в нем. Но и до сих пор очень много белых пятен. JS слишком объемный и не однозначный, это вам не php.

                          И особенно тем, кто привык в php, с ним очень сложно по началу. Дело в том, что в php у нас все последовательно выполняется, а в JS по умолчанию многие вещи параллельно выполняются. Даже попытка понять что из этого sync, а что async (то есть параллельное или последовательное) — это причина появления множества разъясняющих и спорных статей.

                          В вашем случае, я бы советовал, во-первых, заюзать momentjs и вот почему:
                          Давайте выполним вот такой код:
                          console.log(new Date("2018-09-12 12:01:11").getMinutes())
                          Что мы здесь получим? 01? Неправильно. Получим 1. А вы случаем, не ожидаете «12:01:11»? Я вот не вижу у вас каких-либо попыток преобразовать данные.
                          В случае с момент вы получите console.log(new moment(«2018-09-12 12:01:11»).format(«HH:mm:ss»)) === «12:01:11».

                          Во-вторых, я бы не интервал ставил бы на перебор массива, а перебрал бы сразу массив и задал нужные тайминги.
                          notes.map(n => {
                              const a = new moment(n.time);
                              const diff = a - new moment();
                              if(a > 0){
                                  setTimeout(action, diff)
                              }
                          })
                            Alex
                            13 декабря 2018, 14:17
                            0
                            Спасибо за ответ. Попробую и ваш вариант. Да, после php, node.js кажется совсем не очевидным и порой непредсказуемым, это вы верно подметили.
                            Время для выполнения действия я получаю вот так:
                            var currentTime = new Date()
                                var newTime = currentTime.setMinutes(currentTime.getMinutes() + 1)
                                var sendTime = (currentTime.getHours()+":"+currentTime.getMinutes())
                            Конечно если сейчас 12:01, мы добавляем минуту, то выходит вот так 12:2. Но действие все равно выполняется, если интервал небольшой (что странно). Я грешил на этот момент, но как выяснилось приведя время в формат 12:02, то есть с 0, все равно таймер не отрабатывает. Даже если попадаем через 30 мин на 12:45 все равно не работает. Кстати, дело не в формате времени, так как при использовании функции setTimeout() все равно не работает если поставить интервал в 30-60 мин.
                            Может у меня просто «жизненный цикл» ноды умирает? Сколько вообще живет нода после обращения к ней? Вот описания «поведения» node.js я пока не нашел. То есть в пыхе все понятно, сделал запрос, код отработал и умер, а в ноде как? Сколько живет «процесс» или он вообще не умирает, а в каких случаях умирает, а как сделать чтобы работал постоянно и тд, а что влияет на жизненный цикл процесса. Это все для меня пока загадка.
                              Fi1osof
                              13 декабря 2018, 15:32
                              +1
                              Время для выполнения действия я получаю вот так:
                              var currentTime = new Date()
                              var newTime = currentTime.setMinutes(currentTime.getMinutes() + 1)
                              var sendTime = (currentTime.getHours()+":"+currentTime.getMinutes())
                              Для отладки, в том числе отслеживания времени выполнения, советую debug.

                              Конечно если сейчас 12:01, мы добавляем минуту, то выходит вот так 12:2. Но действие все равно выполняется, если интервал небольшой (что странно). Я грешил на этот момент, но как выяснилось приведя время в формат 12:02, то есть с 0, все равно таймер не отрабатывает.
                              Не занимайтесь магией и лишней арифметикой. Абсолютно точно, что строковое «01:1» не равно «01:01». Если у вас срабатывает, значит у вас с той стороны прилетает «01:1», а не «01:01». Это еще один аргумент в пользу того, чтобы использовать moment, потому что даже в случае таких расхождений в форматах, он приведет вам к единому формату.

                              И попробуйте у себя в цикле, где сравнение происходит, вывести
                              console.log("compare dates", notes[i]['time'], curDate, notes[i]['time'] === curDate);
                              И попутный совет: старайтесь избегать неточных сравнений ==, используйте === и следите за форматами данных, это очень важно в JS. Прям через силу себя заставляйте. Иначе намучаетесь.

                              Про жизненный цикл: если node-процесс умер, то он умер. И такого не должно быть, если процесс изначально планировался, что будет работать постоянно. К примеру, если говорим про работу сервера express или типа того, то процесс должен работать. Вот как раз в прошлом топике был пример, что сайт разваливался. С тех пор он не разваливался, uptime 2 дня.

                              App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
                              ├───────────────┼────┼─────────┼──────┼───────┼─────────┼─────────┼────────┼─────┼───────────┼─────────┼──────────┤
                              │ front │ 0 │ N/A │ fork │ 14248 │ online │ 0 │ 2D │ 0% │ 25.1 MB │ fi1osof │ disabled │
                              │ server │ 7 │ N/A │ fork │ 17570 │ online │ 42 │ 2D │ 0% │ 25.3 MB │ fi1osof │ disabled

                              На городских банях у меня процесс месяцами висел.

                              Вот эти таблицы — это используется pm2
                              В целом у него все просто с запуском, например pm2 --name myProcessName start js-script
                              С запуском npm с параметрами чуть сложнее, но ненамного, к примеру, был npm run myScript, pm2 это
                              pm2 start npm — run myScript
                                Alex
                                13 декабря 2018, 16:21
                                0
                                У меня koa. То есть я так понимаю процесс умирать не должен и надо искать косяк с таймером? pm2 немного юзал, прикольная штука. Там еще походу монитор навороченный есть, но до него пока руки не дошли.
                                Спасибо вам за советы.
                                  Fi1osof
                                  13 декабря 2018, 16:58
                                  0
                                  Да, коа тоже должна постоянно работать.

                                  Не за что.
                          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                          52