csharpproglib | Unsorted

Telegram-канал csharpproglib - Библиотека шарписта | C#, F#, .NET, ASP.NET

23284

Все самое полезное для C#-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/b60af5a4 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead

Subscribe to a channel

Библиотека шарписта | C#, F#, .NET, ASP.NET

♟ Регулярные шахматы

Как думаете, сколько нужно регулярных выражений для игры в шахматы?
1? 2? А вот и нет! Для этого понадобилось 84 688 регулярных выражений.

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

📖 Подробнее о безумной идее

#новость

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤨🛠Простое руководство по работе с Base64 в C#

❗️Base64 – это удобный метод преобразования данных в текстовый формат, который часто используется для передачи двоичных данных, таких как изображения, через текстовые протоколы

✏️В статье объясняется, как использовать встроенные методы C# для кодирования и декодирования данных в формате Base64. С помощью Convert.ToBase64String можно легко преобразовать строку или массив байтов в Base64, а методом Convert.FromBase64String – вернуть их обратно.

🤩 Статья также демонстрирует, как вставлять Base64-строки в другие строки с использованием интерполяции или string.Format. Она рассматривает плюсы и минусы Base64: формат удобен и поддерживается в большинстве языков программирования, но увеличивает размер данных на 33%. Рекомендуется использовать Base64 только там, где это оправдано, например, для передачи данных через API или сериализации.

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🎮 CODE-DMG - эмулятор Game Boy на С#!

CODE-DMG — это эмулятор классической консоли Nintendo Game Boy, написанный на C#. Он позволяет запускать любимые ретро-игры на вашем компьютере, включая такие хиты, как Pokémon и Tetris.
🎮Эмулятор полностью открыт для сообщества, что делает его идеальным для разработчиков и энтузиастов. Вы можете скачать проект, внести изменения или просто насладиться его функционалом, погружаясь в атмосферу 90-х.

🕹 Управление в игре
Перемещение (D-Pad): W, A, S, D
Кнопки A и B: J, K
Старт: Enter
Select: Shift

🤩 Установите CODE-DMG и погрузитесь в ностальгические приключения Game Boy!

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🔥🍊 Подборка лучших статей «Библиотеки шарписта» за декабрь: сохраняй в заметки, чтобы не пропустить #самыйсок

💡 Многопоточность в C#: освежаем основы и работаем быстрее
🚀 HybridCache в .NET 9 — гибридное кэширование на новом уровне
🎯 Полный гайд по тестированию с NUnit в C# 13 и .NET 9
🌍 Как и просили.. Get запрос разными языками
🚀 .NET 9 отказывается от встроенного Swagger

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

⚙️🛠️ WinGet — вместо тысячи кликов

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

Основные возможности WinGet:

Поиск приложений: команда winget search позволяет находить программы по названию или категории.
Установка приложений: с помощью команды winget install <имя_программы> можно быстро установить нужное приложение.
Обновление приложений: команда winget upgrade --all обновляет все установленные программы до актуальных версий.
Удаление приложений: для удаления используется команда winget uninstall <имя_программы>.

WinGet работает с проверенными репозиториями пакетов, что снижает риск загрузки вредоносного или нежелательного ПО. Для пользователей Windows 11 WinGet уже предустановлен, а владельцы Windows 10 могут бесплатно скачать его из Microsoft Store.

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Привет, C# сообщество!

Мы хотели бы поближе с вами познакомиться! Будем очень признательны за ваши ответы на следующие вопросы!

(Технические шоколадки с постами, отвечайте на вопросы, не стесняйтесь!)

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🏗️ Зачем нужен паттерн Factory в C#?
Factory (Фабрика) — это паттерн проектирования, который упрощает создание объектов, отделяя логику их создания от основного кода.

Почему нужно использовать этот паттерн?
1️⃣ Слабое связывание — код не зависит от конкретных реализаций, работая только с интерфейсами или абстрактными классами.
2️⃣ Гибкость — легко добавлять новые типы объектов без изменения клиентского кода.
3️⃣ Чистота кода — детали создания объектов скрыты в фабрике, упрощая логику приложения.

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

📎 Для подробного кода и примеров читайте статью.

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

⚙️ Подпишись на нашу еженедельную email-рассылку, чтобы быть в курсе последних открытий и тенденций в мире бэкенда.

В еженедельных письмах ты найдешь:
● Языки программирования и фреймворки для бэкенда
● Архитектура и проектирование серверных приложений
● Базы данных и управление данными
● Безопасность и защита данных
● Облачные технологии и DevOps
● API и интеграции
● Тестирование и отладка
● Инструменты и утилиты для бэкенд-разработчиков
● Лучшие практики и паттерны проектирования

👉Подписаться👈

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Вот и новый год! 🎆 Давайте погадаем что там нас ждёт?
Делайте скриншот и присылайте в комментарии!⬇️

#интерактив

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🧑‍💻 Статьи для IT: как объяснять и распространять значимые идеи

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

Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.

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

👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Бесплатный курс по фулстек-разработке — реальность 🔥

Под Новый год Дед Мороз приносит подарки, а наши подписчики — собственные курсы! Сергей Дмитриев, который занимается коммерческой разработкой уже 15 лет, поделился с нами своим обучением по созданию веб-сервиса с нуля. В курс входит 141 урок, 28 часов видео, исходный код и чат поддержки для участников.

Подробнее о курсе читайте на Хабре или в телеграм-канале Сергея

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🌍✈️ 6 идей, как ускорить поиск работы за рубежом

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

👉 Читать статью

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🚀 Testcontainers в .NET с PostgreSQL и pgvector

💡 Мы нашли статью о том, как использовать Testcontainers в .NET для работы с PostgreSQL и расширением pgvector. Если вы хотите сделать тестирование интеграции удобнее и мощнее, то это именно то, что вам нужно!

📌 Что такое Testcontainers?
Это библиотека, которая позволяет запускать Docker-контейнеры прямо из тестов, создавая временные окружения для тестирования. Это упрощает интеграционное тестирование, минимизируя необходимость ручной настройки баз данных, брокеров сообщений и других сервисов.

📌 Что такое pgvector?
pgvector — это расширение PostgreSQL, добавляющее поддержку работы с векторными данными. Это крайне полезно для приложений, которые используют эмбеддинги (например, из OpenAI или Hugging Face) для поиска, машинного обучения или рекомендательных систем.

📌 О чём статья?
Как настроить Testcontainers для работы с PostgreSQL в .NET.
Как подключить расширение pgvector в тестовой базе данных.
Пошаговое руководство по созданию контейнера с PostgreSQL, выполнению миграций и настройке данных для тестов.
Примеры использования pgvector для хранения и поиска векторных данных.

Автор показывает, как использовать Testcontainers для запуска PostgreSQL с уже установленным pgvector. Это позволяет тестировать функции работы с векторами (например, поиск ближайших соседей) без необходимости настраивать базу данных вручную.

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🔗 Что такое паттерн «Цепочка»?

В основе паттерна «цепочка» лежит идея последовательной обработки запроса через несколько микросервисов. Клиент делает запрос, который обрабатывается первым сервисом (A). Этот сервис передает результат следующему (B), затем — следующему (C) и так далее, пока не будет получен финальный результат, возвращаемый клиенту.

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

Преимущества паттерна
Модульность: каждый сервис отвечает за свою часть работы. Это делает систему более понятной и легкой в поддержке.
Повторное использование: сервисы можно использовать в других бизнес-процессах, объединяя их в новые цепочки.
Простота реализации: логика каждого микросервиса изолирована, что упрощает проектирование и тестирование.

Недостатки паттерна
Высокие задержки: каждый вызов в цепочке требует времени, а синхронное взаимодействие увеличивает общее время отклика для клиента.
Уязвимость к сбоям: Если один из сервисов выйдет из строя, вся цепочка перестанет работать, что может нарушить работу приложения.
Сложности мониторинга: С ростом длины цепочки становится сложнее отслеживать метрики производительности и отладку.

Когда использовать паттерн «Цепочка»?
Необходимо последовательное выполнение задач (например, обработка платежей или подготовка данных для аналитики).
Задачи строго зависят друг от друга.
Длина цепочки невелика, а задержки допустимы.
Если же время отклика критично или система должна быть устойчива к сбоям, стоит рассмотреть альтернативы, такие как асинхронное взаимодействие или паттерн оркестрации.

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Что такое паттерн «Цепочка»?
В основе паттерна «цепочка» лежит идея последовательной обработки запроса через несколько микросервисов. Клиент делает запрос, который обрабатывается первым сервисом (A). Этот сервис передает результат следующему (B), затем — следующему (C) и так далее, пока не будет получен финальный результат, возвращаемый клиенту.

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

Преимущества паттерна
Модульность: Каждый сервис отвечает за свою часть работы. Это делает систему более понятной и легкой в поддержке.
Повторное использование: Сервисы можно использовать в других бизнес-процессах, объединяя их в новые цепочки.
Простота реализации: Логика каждого микросервиса изолирована, что упрощает проектирование и тестирование.
Недостатки паттерна
Высокие задержки: Каждый вызов в цепочке требует времени, а синхронное взаимодействие увеличивает общее время отклика для клиента.
Уязвимость к сбоям: Если один из сервисов выйдет из строя, вся цепочка перестанет работать, что может нарушить работу приложения.
Сложности мониторинга: С ростом длины цепочки становится сложнее отслеживать метрики производительности и отладку.
Когда использовать паттерн «Цепочка»?
Этот паттерн хорошо подходит для сценариев, где:

Необходимо последовательное выполнение задач (например, обработка платежей или подготовка данных для аналитики).
Задачи строго зависят друг от друга.
Длина цепочки невелика, а задержки допустимы.
Если же время отклика критично или система должна быть устойчива к сбоям, стоит рассмотреть альтернативы, такие как асинхронное взаимодействие или паттерн оркестрации.

Пример работы цепочки
Представьте систему интернет-магазина:

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

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👨‍💻🛠 UUID (GUID) vs ULID: Примеры и различия

UUID (GUID) — это уникальный идентификатор, состоящий из 128 бит и представленный в виде строки из 36 символов. Пример UUID:

f47ac10b-58cc-4372-a567-0e02b2c3d479


ULID — уникальный идентификатор длиной 26 символов, который сортируется по времени. Пример ULID:
01F8G4E0D8HR7X0G9WG9M3FWVZ


Основные различия:
Сортируемость: ULID сортируется по времени, UUID — нет.
Длина: UUID длиннее (36 символов), ULID — 26 символов.
Использование: UUID подходит для генерации уникальных идентификаторов, ULID — для систем с необходимостью упорядочивания по времени.

Когда что использовать:
UUID: Если важна глобальная уникальность, а порядок не имеет значения.
ULID: Когда необходимо сортировать идентификаторы по времени и иметь компактный формат.

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Что такое ValueTask в C#?

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

Особенности использования ValueTask:

1️⃣Повторное ожидание запрещено: вызывать await несколько раз для одного и того же ValueTask нельзя, так как это может привести к неожиданным результатам.
❌ Так делать нельзя:

ValueTask<int> task = GetValueAsync();
int value1 = await task;
int value2 = await task; // Ошибка


2️⃣Конвертация в Task: если требуется передать ValueTask в API, которое ожидает Task, можно вызвать метод .AsTask():
Task<int> task = GetValueAsync().AsTask();


3️⃣Когда использовать ValueTask:
Операция часто завершается синхронно.
Создание объекта Task может быть слишком накладным.
Вы пишете библиотеку с высокой производительностью.

4️⃣Когда НЕ использовать ValueTask:
Операция всегда асинхронна.
Производительность не является критически важной.
Приложение не оптимизировано под работу с ValueTask.

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🔍 Что такое source.dot.net?

Source.dot.net — это официальный сайт от Microsoft, предоставляющий доступ к исходному коду стандартных библиотек .NET. Здесь вы можете исследовать, как реализованы классы, структуры и методы, которые вы используете ежедневно в своих проектах на C#. Этот инструмент позволяет заглянуть «под капот» .NET и увидеть внутреннюю работу фреймворка.

⚙️ Сайт предлагает удобную навигацию по исходному коду с возможностью переключаться между версиями .NET (например, .NET 6, .NET 7, .NET 8). Помимо исходного кода, ресурс интегрирован с официальной документацией, что делает его полезным для изучения, отладки и глубокого понимания работы фреймворка.

✨ Незаменимый инструмент для разработчиков, стремящихся понять, как работают стандартные библиотеки и применять лучшие практики в своих проектах!

Попробуйте прочитать url сайта по-английски!

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🎄 Начни 2025-й с апгрейдом навыков,
которые откроют двери в мир IT!

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

🔗 Собери свой план и начни путь в IT

Почему это выгодно?

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

💾 Бессрочный доступ — все материалы всегда под рукой, чтобы учиться в своём темпе.

💸 Знания, которые окупятся — навыки, востребованные в любой точке мира.
Какие навыки ты можешь прокачать?

💡 Математика для Data Science + Алгоритмы и структуры данных
— Подготовка к собеседованиям в FAANG и поступлению в ШАД. Решай сложные задачи, работай с данными и моделями на профессиональном уровне.

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

💡 Frontend Basic + Базовые модели ML
— Построй свою первую веб-страницу и погрузись в мир ML: от нейросетей до ML-бустинга.

💡 Архитектуры и шаблоны проектирования + Математика для Data Science
— Развивай аналитическое мышление и учись проектировать устойчивые системы.

💡 Алгоритмы и структуры данных + Frontend Basic
— Получи полный набор навыков: от оптимизации алгоритмов до создания современных веб-приложений.

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

🔗 Составь свой IT-маршрут сейчас или выбери курс по новогодней скидке

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🙏 Спасибо вам за ответы! Мы стараемся для вас! 🤩

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤔👨‍💻 Что такое MapGroup в минимальных API?

MapGroup — это функция в минимальных API ASP.NET Core, позволяющая группировать связанные конечные точки под общим префиксом маршрута и общей конфигурацией. Это улучшает организацию кода, делая его более читаемым и поддерживаемым.

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

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

Логическая организация: группировка связанных конечных точек (например, /users, /orders) помогает структурировать код по функциональным областям.

Пример использования MapGroup:


var app = builder.Build();

var usersGroup = app.MapGroup("/users");

usersGroup.MapGet("/", () => "Список пользователей");
usersGroup.MapGet("/{id}", (int id) => $"Детали пользователя с ID {id}");
usersGroup.MapPost("/", () => "Создать нового пользователя");

app.Run();

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

Когда использовать MapGroup:

При наличии нескольких конечных точек с общим префиксом маршрута.
Когда требуется применить одинаковый middleware к группе конечных точек.
Для улучшения читаемости и организации кода в проектах с большим количеством маршрутов.

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤩 Быстрый переход к строке кода в Visual Studio 2022

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

Как это работает?
Переход в текущем файле
Введите в поле поиска кода : и номер строки (например, :42), чтобы сразу открыть нужную строку в активном документе.

Переход в другом файле
Укажите название файла, затем двоеточие и номер строки (например, Order:43). Visual Studio найдёт файл и сразу покажет нужный участок кода.

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

#новость

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🔍 Новое обновление в Visual Studio 2022: закрепляем окно поиска

Работаете в Visual Studio 2022? Тогда у нас для вас отличные новости! Теперь окно поиска кода и функций можно закрепить в интерфейсе как полноценную панель инструментов. Это обновление делает рабочий процесс ещё удобнее и эффективнее.

Что нового?
1️⃣ Закрепление окна поиска
Раньше окно поиска появлялось поверх других окон, что могло мешать. Теперь его можно закрепить в любом месте интерфейса Visual Studio — например, рядом с «Обозревателем решений». Чтобы сделать это, нажмите на значок в правом верхнем углу окна поиска. 🎯

2️⃣ Упрощённый предварительный просмотр
Добавлена кнопка для включения/выключения панели предварительного просмотра (иконка глаза). Если панель включена, она автоматически адаптируется под размеры окна поиска, предоставляя удобный просмотр найденного кода. 👁

3️⃣ Повышение продуктивности
Эти изменения помогают лучше организовать рабочее пространство, особенно если вы часто пользуетесь поиском кода (Ctrl + T) или функций (Ctrl + Q).

#новость

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Давайте признавайтесь в комментариях — что вам подарили? 👇

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

С наступающим, С# сообщество! Или уже наступившим!🎆🎆

Уже придумали чем заняться в новом году? 😉
Если нет, то предлагаем вам подборку фильмов и сериалов к просмотру:

🔠 Остановись и гори (2014)
🅰️ The IT Crowd (2006-2013)
🔠 Revolution OS (2001)
©️ Разрабы (2020)
🔠 Игра в имитацию (2014)

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👋 Привет, мир: несколько креативных способов написать классический код на C#

Иногда самые простые вещи могут быть невероятно увлекательными. В этой статье автор собрал разнообразные способы написать легендарное 'Hello, World!' на C#. Это не просто базовые примеры, а настоящая коллекция техник и подходов, которая понравится как новичкам, так и опытным разработчикам.

📎 Узнайте, как добавить немного креатива даже в такие тривиальные задачи!

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

💻📈 Итоги года Proglib: 2024 год в цифрах и достижениях

Как оставаться в курсе самых актуальных тенденций, не теряя времени на поиск информации? Итоги года Proglib покажут, как платформа объединила разработчиков, помогая им оставаться впереди.

Загляните в цифры, достижения и материалы, которые сделали этот год ярким!

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🎨 Новый канал для вдохновения — UX in GIF

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

📌 Чем полезен канал?

→ Идеи для дизайна интерфейсов.
→ Анимации, которые можно повторить или адаптировать.
→ Лёгкий способ искать вдохновение перед новым проектом.

👉 Подписывайтесь и вдохновляйтесь: UX in GIF

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

☁️ Размышления про абстракции

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

Основные мысли:
💭 Хорошая абстракция упрощает работу, скрывая сложные детали;
💭 Плохая абстракция лишь увеличивает количество слоев и усложняет понимание системы;
💭 Абстракции стоят дорого: они могут снижать производительность и усложнять сопровождение;
💭 Со временем даже хорошие абстракции могут начать «протекать», требуя знания внутренних механизмов.

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

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📘 SkunkHTML: Генератор статичных сайтов

SkunkHTML — это инструмент, который позволяет легко и быстро создавать статичные веб-сайты из файлов Markdown, автоматизируя процесс генерации и развертывания. Он разработан на F#, что делает его не только функциональным, но и интересным примером использования этого языка.

🛠️ Как это работает?
1. Форкните репозиторий: SkunkHTML на GitHub.
2. Добавьте контент: создайте свои файлы Markdown в соответствующей папке.
3. Настройте GitHub Pages: включите автоматическое развертывание через GitHub Actions.
4. Наслаждайтесь готовым сайтом!

📎 Попробуйте сами!

#новость

Читать полностью…
Subscribe to a channel