NG Stream
248 subscribers
85 photos
4 videos
2 files
465 links
Авторский канал об Angular и новостях фронтенда. Мы рассказываем о том, с чем сталкиваемся в процессе разработки, делимся полезными, на наш взгляд, статьями.

Made by devs for 🅰️ devs

Авторы:
- @antoonG
- @basters

Чат: https://t.me/+JYGeE7HekO04Y2My
Download Telegram
В субботу посетил Сезон кода.
Сам фестиваль проходил в офисе ТБанка - у ребят очень уютно! И солнечная Питерская погода добавила красок;)

В программе 3 секции докладов, всякие активности на стендах, зоны чилла, несколько кофеен. За счет геймификации нас ненавязчиво подталкивали к общению, чтобы сообщество тусовалось не только в своих компаниях, а знакомилось! Мне понравилось! Вообще было много классных ребят! Для себя отметил выступление с дашбордами для мониторинга и реагирования на инциденты, поскольку сам недавно с этим работал. Запомнилась активность, где нужно было разобраться с решениями, предложенными AI. Я кайфанул! Узнал кое-что новое в демозоне с графовой аналитикой, пообщался с командой на тему SDLC.

В общем, самые положительные впечатления и спасибо организаторам, ребятам на стендах! Вам удалось сделать это максимально круто💪🏻

NgStream
🔥9👎1
В Angular 22 была улучшена обработка null и undefined, которую многие не заметили. Поведение ?. в шаблонах теперь точно соответствует семантике JavaScript: если цепочка обрывается на позиции со значением null или undefined, результатом будет undefined. При этом сохранена обратная совместимость - если нужно старое поведение, специфичное для Angular, можно обернуть выражение в $null(…).

Наверное, одно из самых мощных нововведений, с точки зрения DX, это полноценная поддержка сужения типов (Type Narrowing) в шаблонах. Раньше, даже если вы проверили свойство в @if, компилятор часто требовал повторного использования ?. при обращении к вложенным полям, что сильно раздражало. Теперь после проверки на истинность (truthiness check) тип сужается, как в обычном коде TypeScript, так что последующий доступ без ?. является типобезопасным.

@if (user?.isMember) {
{{ user.isMember }}
}


Angular продолжает движение в сторону более корректной типизации и прозрачности, полностью синхронизируя работу с типами в шаблонах со стандартами JavaScript и TypeScript.

#angular

NgStream
🔥142
Будущее JS инструментов

На прошлой неделе Vite+ перешел в статус Beta. Это не просто очередная библиотека, а попытка создать единую, монолитную и невероятно быструю платформу (набор инструментов), которая возьмет на себя управление всем циклом разработки. Что важно, проект полностью открыт и распространяется под лицензией MIT. В состав входят следующие инструменты:

Vite 8 - ядро для разработки и сборки;
Vitest - для тестирования (теперь с поддержкой ARIA-снапшотов);
Rolldown - новый "blazing fast" сборщик на Rust;
Oxlint и Oxfmt - линтер и форматировщик из семейства Oxc;
tsdown - bundler с нативной поддержкой CSS-модулей.

В Vite 8 важным изменением является переход на Rolldown по умолчанию. Раньше использование разных сборщиков в dev и prod режимах приводило к трудноуловимым багам. В этом же решении предлагается использовать Rolldown, чем обеспечить консистентность на всех этапах. Технически это стало возможным, благодаря глубокой интеграции с экосистемой Oxc. Использование Rust это не только про скорость, а про общее AST. Команда работает над тем, чтобы парсер, линтер и сборщик работали с одним деревом в памяти, минимизируя дорогостоящую сериализацию данных.

Забавно, что при генерации нового проекта через vp create, автоматически добавляются файл agent.md и инструкции для агентов Cursor, Copilot, Claude. Теперь AI сразу понимает контекст проекта, знает о правилах линтинга и специфике архитектуры.

Одной из самых обсуждаемых функций Vite 8.1 стал Experimental Bundled Dev Mode. Это переименованный Full Bundle Mode. Изначально Vite отдавал файлы по одному, но на больших проектах это стало бутылочным горлышком. Когда браузер пытается одновременно загрузить 10K модулей, его сетевой стек и DevTools просто вешаются. И сейчас опять возвращается к идее бандлинга в dev-режиме, объединяя модули в крупные chunks. Это позволяет сохранить мгновенный старт, не перегружая браузер бесконечными HTTP-запросами.
Еще для Enterprise добавили поддержку прокси, custom CA-сертификатов, а также organization templates для стандартизации сетапа во всех отделах компании.

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

#js

NgStream
🔥5👍3
Пару недель назад в репозитории Angular появился любопытный MR, направленный на улучшение работы Router и его более глубокую интеграцию с resource.

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

During navigation, the state of the resource (value, status, error, and loading signals) is frozen so the application state and UI do not eagerly change/flash during an in-progress navigation.


При отмене навигации, например, когда, canActivate вернул false, предполагается откат. Ресурс удерживает замороженный snapshot состояния и будет показывать старые данные, пока не закончится фоновая перезагрузка текущего состояния. Если замороженное состояние не было валидным (например, ресурс находился в состоянии ошибки), фаза восстановления пропускается. Ресурс размораживается, что позволяет ему сразу перейти в новое состояние. Кроме того, работает логика New Navigation Preemption: если в процессе отката пользователь инициирует новую навигацию, система мгновенно отменяет восстановление и переключается на новую цель. Это и делает механизм по-настоящему транзакционным.
Для обеспечения транзакционности Angular накладывает жесткие ограничения на API обертки - скрыты методы для прямой записи состояния ( set/ update), его невозможно случайно перевести в невалидное состояние.

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

#angular

NgStream
👍8🔥2
История с исчезновением ngneat пакетов получила продолжение!

Если вы пропустили эту новость, то все репозитории ngneat в прошлом месяце были удалены/скрыты. Это стало неожиданностью для команд разработчиков, использующих привычные инструменты. На reddit есть обсуждение на эту тему, можно почитать. Конечно сами npm пакеты никто не удалил, но вопрос дальнейшей поддержки оставался открытым.

И вот, пару дней назад, я увидел новость о том, что была создана организация OpenNG, которая будет координировать работу над форками проектов, включая elf, query и spectator! И уже вышел первый релиз.

Один из организаторов сообщества - Gerome Grignon, довольно известный Angular Certified Expert, open source contributor, создатель Angular CanIUse. Команда планирует поддерживать работу проектов и, в первую очередь, сделать ревью МР от сообщества. Как пишут у себя на странице, организация OpenNG планирует поддерживать и совместно разрабатывать и другие open-source проекты на Angular, помогать подбирать для проектов мэйнтейнеров, готовых развивать их дальше.

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

#angular

NgStream
🔥12👍2
На прошлой неделе вышел TypeScript 7

И у меня только сейчас дошли руки написать об этом.

Это релиз нативной версии TypeScript, которая работает в 10 раз быстрее текущей, о чем было заявлено в прошлом году. Цель была в том, чтобы максимально эффективно использовать современное железо и сделать перенос близко к оригиналу с сохранением структуры и логики исходной кодовой базы, обеспечивая совместимость между двумя компиляторами. В результате мы получили скорость нативного кода, многопоточность с общей памятью и ряд новых оптимизаций, которые обычно дают ускорение от 8 до 12 раз при полной сборке.

⚡️ На практике обещают прирост скорости на каждом этапе - загрузка проекта, поиск всех ссылок, автодополнение и более короткий цикл обратной связи при запуске в режиме --watch.
👀 Режим --watch полностью переработан и работает на базе file-watcher из бандлера Parcel, обеспечивает эффективное и стабильное отслеживание изменений файлов на разных платформах.
🧵Новый компилятор теперь выполняет многие шаги параллельно: парсинг, type checking и генерацию кода. Некоторые из них, например парсинг и генерация, выполняются практически независимо для каждого файла - параллелизация автоматически хорошо масштабируется на больших кодовых базах с минимальными накладными расходами.

Были введены экспериментальные флаги --checkers и --builders для настройки параллелизации таких шагов, как проверка типов и сборка ссылок на проекты. И добавлен флаг --singleThreaded для полного отключения параллелизации, который полезен при отладке или в средах с ограниченными ресурсами.

⚠️ Важное замечание для Angular разработчиков! Angular не перейдёт на TypeScript 7 сразу, поскольку новый API компилятора ещё не готов. Команда планирует выпустить стабильную версию API в следующем релизе - 7.1, после чего Angular и другие фреймворки и инструменты, такие как Vue, MDX, Astro, Svelte начнут интеграцию.

Звучит масштабно, ожидаем примерно такой же график релизов, как и до TypeScript 7.0: новые версии с полноценными возможностями будут выходить каждые 3–4 месяца.

Оригинал в блоге.

#typescript

NgStream
👍7🔥3
This media is not supported in your browser
VIEW IN TELEGRAM
Selectel Day Off возвращается 💚

ИТ-фестиваль пройдет 25 июля в музее Эрарта! Если разбираться с будущим, то там, где его уже нарисовали😉

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

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

Присоединяйся - вживую или онлайн. Места есть, но лучше не тянуть: прошлый раз показал, что они тают быстрее, чем аргументы противников нейросетей.
🔥6👎3
В пятницу вышла новость об изменении релизного цикла Angular. Теперь major release планируется выпускать каждые 12 месяцев и 4-6 minor releases между ними. Изменение продиктовано просьбами сообщества из-за влияния критических изменений и обновлений на их проекты, а также на корпоративных клиентов.

Примерный план релизов ниже и ссылка на МР.

v22.2 | ~ September 2026
v22.3 | ~ November 2026
v22.4 | ~ January 2027
v22.5 | ~ March 2027
v23.0 | ~ June 2027

#angular

NgStream
🔥10👍2
Для крупных enterprise проектов время сборки - не просто техническая метрика, а вопрос эффективности бизнеса. При каждом ожидании разработчиком завершения CI/CD или локального билда, происходит разрушение когнитивного потока и падение "developer velocity". На масштабе нескольких команд это замедляет вывод фич на рынок.

Долгое время Angular CLI, несмотря на переход на esbuild и Vite, сохранял зависимость от Babel. Сейчас, как видим, решено отказаться от legacy в пользу сверхбыстрых инструментов нового поколения Oxc и Magic String. Ранее каждый плагин требовал повторной сериализации и десериализации AST, что создавало огромные накладные расходы. Теперь будет использоваться oxc-parser для более быстрого анализа кода и magic-string для его модификации.

📌 Oxc (Rust-based parser) берет на себя часть с построением структуры и понимания семантики.
📌 MagicString вносит корректировки в исходный код без дорогостоящей регенерации всего AST на каждом этапе.

Новое решение на базе Oxc выполняет ряд низкоуровневых преобразований
- Оптимизация TypeScript. Стандартный вывод Enums часто генерирует IIFE, которые инструменты вроде Terser или esbuild не всегда могут эффективно подвергнуть tree-shaking. А новый трансформер оборачивает их, чтобы гарантировать чистоту кода для минимизатора.
- Оптимизация статических членов классов.
- Удаление setClassMetadata и других отладочных данных. Это не только уменьшает размер файла, но и снижает вычислительную нагрузку при обработке.
- Аннотирование для Tree Shaking. Автоматическое добавление комментариев /* @__PURE__ */ к вызовам функций и конструкторов. Это явное указание сборщику, что данный код можно безопасно удалить, если он не используется.

Наибольший выигрыш от перехода получат проекты с огромной кодовой базой. В монорепах, содержащих сотни библиотек, даже 10% экономии времени на трансформации каждого файла суммируются в минуты сэкономленного времени на критическом пути CI/CD.
Переход на Oxc - логическое продолжение стратегии по улучшению инфраструктуры, перехода от неповоротливости к тому, чтобы задавать стандарты производительных инструментов для сборки. А для нас улучшение DX и повышение скорости доставки кода.

#angular

NgStream
👍3🔥2🤔2
Знаменательный день

Сегодня оказывается уже 5 лет как существует этот канал! Уже 5 лет каждую неделю (за исключением, например, отпусков) здесь выходят новости, мысли и просто важные заметки!

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

NgStream
🎉20🔥103
В индустрии от многих звучит фраза: "Нам запрещено использовать ИИ". Объяснимо - страх перед утечкой интеллектуальной собственности и конфиденциальных данных заставляет компании возводить цифровые стены. Разберем, что на самом деле происходит с кодом при использовании ИИ-инструментов.

Первое, что важно отметить - не используется для обучения ≠ не сохраняется. Многие разработчики успокаивают себя настройкой "не использовать мои данные для обучения". Однако, важно понимать фундаментальную разницу между обучением (Training) и хранением (Retention). Даже если провайдер гарантирует, что код не станет частью следующей версии нейросети, данные всё равно могут сохраняться. Провайдеры удерживают информацию для мониторинга нарушений, отладки систем и выполнения юридических обязательств.

Следующий важный пункт - риски, связанные с агентами, т.к. они, в отличие от чат-ботов, обладают полномочиями.
- чтение файлов репозитория. Исследования показывают, что Codex или Cursor, способны обходить .gitignore и считывать файлы .env, содержащие секреты.
- контакт с недоверенным контентом. Агент может анализировать сторонние зависимости или вредоносные issue в репозитории.
- Возможность отправки данных. Агент может быть "обманут" (через инъекцию промпта) и принужден к отправке кода. Причем, "Песочница - это забор, а не закон физики" и может быть преодолен при определенных условиях.

И еще один немаловажный пункт - защита и правила обработки данных, которые кардинально меняются в зависимости от подписки. Разрыв между персональными и бизнес-аккаунтами в 2026 году стал критическим.
- Личные подписки: В марте 2026 года GitHub Copilot обновил правила, согласно которым данные пользователей индивидуальных планов по умолчанию могут использоваться для обучения (opt-out модель). Аналогичный подход у OpenAI и Anthropic для персональных аккаунтов.
- Корпоративные планы: Здесь стандарты выше. По умолчанию данные не используются для обучения моделей, а условия хранения (retention) более жесткие и регулируемые.

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

Некоторые компании используют модель светофора для принятия решения об использовании ИИ.
- Зеленая зона: Публичные проекты, документация, Open Source. Использование любых ИИ-инструментов разрешено и поощряется.
- Желтая зона: Внутренний проприетарный код. Допускается работа только через одобренные Enterprise-версии инструментов с отключенным обучением. Обязательное условие: каждый сгенерированный diff должен проходить ревью человеком.
- Красная зона: Секреты (API-ключи, пароли), персональные данные клиентов, критическая инфраструктура. Использование облачных ИИ категорически запрещено.

Безопасность в эпоху ИИ - это не вопрос "использовать или нет". Это вопрос управления рисками. На мой взгляд, не стоит запрещать ИИ, а по возможности создавать безопасные коридоры для его использования.

#нетехзаметки

NgStream
👍41🔥1
Вчера релизнули Angular22.1.

Обновили возможности управления кэшированием при использовании SSR. Стали доступны две настройки для withHttpTransferCacheOptions.

- includeRequestsWithCredentials. Позволяет явно разрешить или запретить кеширование запросов с учетными данными.
- includeNonCacheableRequests - инструмент, когда нужно принудительно передать данные от сервера к клиенту, даже если API возвращает Cache-Control: no-store или no-cache. Это позволяет избежать повторного запроса в браузере сразу после загрузки страницы.

По умолчанию оба параметра false, однозначно дают понять, что стандартные механизмы кеширования останутся нетронутыми, пока вы сами сознательно не разрешите их обойти.
В общем, предоставили более гранулярный контроль над механизмом Transfer Cache в SSR.

#angular

NgStream
👍4
На неделе смотрел, что нового было добавлено в предыдущих версиях Angular и кое-какое изменение прошло незамеченным.

В 21.1 представили более чистый способ управления программной фокусировкой в формах с помощью Signal Forms и нового API focusBoundControl(). Этот метод доступен на уровне fieldState и избавляет нас от необходимости вручную манипулировать DOM-деревом и использовать прямые ссылки на элементы через @ViewChild только для того, чтобы поставить курсор в поле. Если поле связано с нативным HTML-элементом (например, <input>), вызов focusBoundControl() автоматически передает ему фокус. Это база, которая радикально упрощает код: теперь состояние формы само знает, как "достучаться" до UI. Работает только в том случае, если FormControl уже отрисован в DOM.

При работе с формами особенно важен позитивный user experience, а данный метод существенно упрощает жизнь. Вместо навешивания disabled состояния кнопки submit, что является плохой практикой, мы оставляем кнопку активной и при возникновении ошибок мгновенно переносим фокус. Особенно важно для сложных/вложенных форм. Например, в DatePicker вы можете решить, что при ошибке фокус должен всегда падать на выпадающий список Месяц (select), а не на текстовое поле Год. Теперь это реализуется парой строк кода внутри компонента, не ломая абстракцию формы.

Благодаря новой структуре errorSummary, реализация выглядит максимально технично и в декларативном стиле:

1. Сбор ошибок. Мы получаем массив всех текущих ошибок из состояния формы через сигнал errorSummary.
2. Извлечение ссылки. Каждый объект в этом массиве содержит свойство field - это сигнал, который возвращает прямую ссылку на состояние поля формы.
3. Точечный фокус. Берем первую ошибку из списка и вызываем firstError.field().state.focusBoundControl().

Angular Signal Forms продолжают обрастать инструментами, которые делают разработку сложных интерфейсов проще. Я нашел репозиторий, где наглядно показан пример работы, можно ознакомиться.

#angular

NgStream
🔥62👍1
Найм в эпоху AI

С перестроением рабочих процессов перестраиваются и механизмы найма. Компаниям приходится видоизменять процесс собеседований в сторону оценки реальных навыков работы с ИИ.
Я наткнулся на любопытную публикацию компании Coinbase (точнее, спасибо @Basters за рекомендацию), в которой они приходят к мысли, что написание кода с нуля больше не создает основной ценности. Когда ИИ генерирует реализацию за секунды, инженерный труд перемещается в область спецификаций, глубокого ревью и исправления "уверенных" архитектурных галлюцинаций моделей.
Действительно, в мире, где, код сам по себе, обесценивается, самым дорогим ресурсом становятся проверка, верификация и принятие решений в точках неопределенности. Инженер превращается из исполнителя в контролера качества и системного архитектора.
И в Coinbase теперь оценивают не объем знаний, а используют новый стандарт оценки, который стал обязательным для всех уровней - от джунов до топ-менеджмента. Они вывели три принципа «AI Fluency». Или грамотности, если угодно.

1. Usage. Насколько эффективно и ответственно кандидат применяет инструменты? Умеет ли он выбирать правильную модель для конкретной задачи и интегрировать её в свой рабочий процесс?
2. Application. Способен ли инженер проектировать процессы, где ИИ создает реальную бизнес-ценность, а не просто автоматизирует рутину?
3. Understanding Limits. Видит ли человек, где ИИ ошибается? Понимает ли он риски безопасности и приватности? Это о способности находить тонкие ошибки в работе моделей.

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

Поскольку нейросети умнеют ежемесячно, задача, которая была сложной в январе, может стать тривиальной для новой модели в марте. Поэтому процесс найма в Coinbase теперь пересматривается ежеквартально. Даже поведенческие интервью изменились: теперь кандидатам задают вопросы об использовании ИИ в своей повседневной работе.

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

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

#нетехзаметки

NgStream
👍5
В Angular 22.1 добавили еще одну фичушку. Это CSS variable namespacing.

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

Этап компиляции. Компилятор находит все CSS-переменные и заменяет их на внутреннее представление с заглушкой. Например, --foo превращается в --%NS%foo. Это касается как файлов стилей (styles, styleUrls), так и динамических привязок в шаблонах (например, [style.--foo]="val").

Runtime. Здесь заменяется %NS% на реальное имя пространства имен, заданное при конфигурации (например, --my-app_foo).

DOM больше не является «источником истины» для имен переменных. Привычный вызов getComputedStyle(el).getPropertyValue('--foo') теперь официально считается опасным паттерном, так как реальное имя переменной в runtime будет содержать префикс.
Для решения этой проблемы представлен сервис CssVarNamespacer. Его использование становится критически важным, особенно для авторов библиотек компонентов. Если ваша библиотека работает с CSS-переменными через JS и не поддерживает этот сервис, она фактически становится несовместимой с современными enterprise-стандартами Angular.
export const appConfig: ApplicationConfig = {
providers: [
{ provide: APP_ID, useValue: 'crm-app' },
// Использование разделителя для чистоты имен
provideCssVarNamespacing('crm-app_'),
],
};


Поскольку процесс автоматизирован, разработчик продолжает писать чистый CSS, а Angular берет на себя всю рутину по обеспечению уникальности.

#angular

NgStream
🔥5
ИТ-пикник удался!

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

Отдельно для себя отметил выступление Анны Громовой об оценке эффективности AI в SDLC, потому что содержало больше конкретики, чем у коллег. Краткий вывод, что при внедрении нового подхода процессы надо перестраивать комплексно. Если CI/CD или Code Review не оптимизированы, общее время поставки (Lead Time) не изменится - узкое место просто переместится на следующий этап. Вроде база, только не все этому следуют. Также существует риск генерации «тестов ради тестов», которые легко проходят, но не повышают реальную надежность. Для контроля этого риска используются метрики инцидентов, откатов (rollbacks) и доля падающих пайплайнов. Кроме того, рекомендуется проводить (и проходить) опросы (SPACE метрики) для отслеживания отношения к изменениям. Примеры пересказывать не буду, если интересно, стоит посмотреть запись. Могу порекомендовать послушать об эволюции метрик, в целом, если еще не сылшали.

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

Что касается всего мероприятия, то расстроили огромные очереди на стендах, но без этого никуда на подобного масштаба ивентах. Даже мерч достать не получилось. Те, кто лутали по 5 сумок от одной компании, расскажите, как вы это делаете;) Стенд с авто.ру я вообще не понял:) Но это не важно, потому что фишкой и клевым завершением стало выступление The LAB и Антона Беляева! Они сделали этот вечер!🤟🏻
В общем, было полезно сгонять, пообщаться и узнать что-то новое!

NgStream
🔥3