13 Commits

Author SHA1 Message Date
erjemin 17d45d1c05 fix: медленный '?'-запрос в базе заменили на рандом по ip (должно не тормозить в проде) + таймауты
Build and Push Docker Image / build-and-push (push) Successful in 1m13s
2026-07-05 21:29:35 +03:00
erjemin e55ea68d05 ---: minor 2026-03-25 14:32:14 +03:00
erjemin a537bc9c37 mod: вернул борку для ARM64. Добавил очистку кеша poetry
Build and Push Docker Image / build-and-push (push) Successful in 3m18s
2026-03-21 16:51:16 +03:00
erjemin a62e02ddcb ---: убрал сборку для ARM64
Build and Push Docker Image / build-and-push (push) Successful in 1m5s
2026-03-21 16:47:16 +03:00
erjemin d294e5a951 fix: правильный map для тома с media
Build and Push Docker Image / build-and-push (push) Failing after 1m21s
2026-03-21 16:37:18 +03:00
erjemin fd5553e326 mod: обновление пакетов 2026-03-21 16:21:39 +03:00
erjemin 5b5e8dd096 ---: minor (комментарии)
Build and Push Docker Image / build-and-push (push) Successful in 39s
2026-03-21 15:53:27 +03:00
erjemin 906888ae73 mod: формирование правильного canonical для index-страницы 2026-03-21 15:52:43 +03:00
erjemin ac9109ea6e mod: Поле вкл/выкл типограф перенесено во вкладку настроек типографа 2026-03-21 15:51:49 +03:00
erjemin 9027f12792 mod: ленивое формирование тегов (чтобы в проде уменьшить нагрузку на gunicorn) 2026-03-21 15:17:12 +03:00
erjemin 4ddd787f5d ---: minor (comments) 2026-03-21 14:42:05 +03:00
erjemin a60972d70b fix: volumes for database -- /home/app/web/database 2026-03-20 19:10:24 +03:00
erjemin 8fa96cae66 fix: del SQLite files 2026-03-20 19:09:27 +03:00
24 changed files with 287 additions and 302 deletions
+1
View File
@@ -61,6 +61,7 @@ jobs:
# Собираем под текущую архитектуру (linux/amd64). # Собираем под текущую архитектуру (linux/amd64).
# Если сервер и MacMini на разных архитектурах (x86 vs ARM), добавьте нужные, например: linux/amd64,linux/arm64 # Если сервер и MacMini на разных архитектурах (x86 vs ARM), добавьте нужные, например: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
# platforms: linux/amd64
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
# ДОБАВЛЕНО: # ДОБАВЛЕНО:
+10 -1
View File
@@ -262,8 +262,17 @@ cython_debug/
public/media/* public/media/*
!public/media/README.md !public/media/README.md
# OS specific # OS specific (Synology DSM)
.DS_Store .DS_Store
# Data Backup # Data Backup
database/data.json database/data.json
# База данных SQLite
# Никогда не копировать локальную базу в образ!
db.sqlite3
db.sqlite3-journal
db.sqlite3-shm
db.sqlite3-wal
*.sqlite3
*.sqlite3-journal
+3
View File
@@ -29,6 +29,9 @@ COPY pyproject.toml poetry.lock /app/
# Устанавливаем зависимости проекта. Poetry установит их в /usr/local/lib/python3.12/site-packages # Устанавливаем зависимости проекта. Poetry установит их в /usr/local/lib/python3.12/site-packages
RUN poetry install --no-interaction --no-ansi --no-root --only main RUN poetry install --no-interaction --no-ansi --no-root --only main
# Очищаем кэш Poetry, чтобы уменьшить размер слоя
RUN poetry cache clear --all -n
# ================================================= # =================================================
# STAGE 2: Final - Создание чистого и безопасного образа # STAGE 2: Final - Создание чистого и безопасного образа
+7 -2
View File
@@ -29,7 +29,7 @@ upstream dq-django {
# 2. Конфигурируем сервер # 2. Конфигурируем сервер
server { server {
server_name dq.cube2.ru dq2.cube2.ru; # Основное доменное имя server_name dq.cube2.ru; # Основное доменное имя
# Слушаем 80 порт (Certbot потом добавит сюда редирект на 443 и настройки SSL) # Слушаем 80 порт (Certbot потом добавит сюда редирект на 443 и настройки SSL)
listen 80; listen 80;
@@ -108,7 +108,12 @@ server {
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# ВАЖНО: Явно указываем https, потому что клиент всегда приходит по HTTPS к Nginx
# Если нужно чтобы Django обрабатывал и HTTP, и HTTPS, то можно раскомментировать эту строку
# и передавать реальный протокол от клиента
# proxy_set_header X-Forwarded-Proto $scheme;
# Явно указываем https, потому что клиент всегда приходит по HTTPS к Nginx
# Даже если внутри контейнера это HTTP на 127.0.0.1:8010, для Django это должно быть HTTPS # Даже если внутри контейнера это HTTP на 127.0.0.1:8010, для Django это должно быть HTTPS
proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Proto https;
BIN
View File
Binary file not shown.
+9 -5
View File
@@ -12,12 +12,16 @@
<meta property="og:title" content="{% block OgTitle %}{{ DQ.szContent|truncatechars:85 }}{% endblock %}"/> <meta property="og:title" content="{% block OgTitle %}{{ DQ.szContent|truncatechars:85 }}{% endblock %}"/>
<meta property="og:description" content="{% block OgDescription %}{{ DQ.szIntro|default:'' }} {{ DQ.szContent }} {{ AUTHOR.szAuthor|default:'' }}{% endblock %}"/> <meta property="og:description" content="{% block OgDescription %}{{ DQ.szIntro|default:'' }} {{ DQ.szContent }} {{ AUTHOR.szAuthor|default:'' }}{% endblock %}"/>
<meta property="og:url" content="{{ request.build_absolute_uri }}"/> <meta property="og:url" content="{{ request.build_absolute_uri }}"/>
<meta property="og:site_name" content="DicQuo"/> <meta property="og:site_name" content="DicQuo"/>{% if IMAGE %}
{% if IMAGE %}<meta property="og:image" content="{{ request.scheme }}://{{ request.get_host }}{{ IMAGE.url }}"/>{% endif %} <meta property="og:image" content="{{ request.scheme }}://{{ request.get_host }}{{ IMAGE.url }}"/>{% endif %}
{# Шутка #}<meta name="generator" content="Microsoft FrontPage 1.0"/> {# Шутка #}<meta name="generator" content="Microsoft FrontPage 1.0"/>
{# Canonical #}<link rel="canonical" href="{{ request.build_absolute_uri }}"/> {# Canonical #}{% if DQ and DQ_SLUG %}<link rel="canonical" href="{{ request.scheme }}://{{ request.get_host }}/{{ DQ.id }}_{{ DQ_SLUG }}"/>{% else %}<link rel="canonical" href="{{ request.build_absolute_uri }}"/>{% endif %}
{# Favicons #}<link rel="shortcut icon" type="image/x-icon" href="{% static 'img/favicon.ico' %}"/> {# Favicons #}<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="icon" type="image/png" href="{% static 'img/favicon.png' %}"/> {# Favicons #}<link rel="icon" type="image/png" href="/favicon.png"/>
{# Favicons #}<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
{# Favicons #}<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico"/>
{# Favicons #}<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
{# Favicons #}<link rel="manifest" href="/site.webmanifest" />
{# Technical Meta #}<meta http-equiv="Last-Modified" content="{% block Last4Meta %}{% endblock %}"/> {# Technical Meta #}<meta http-equiv="Last-Modified" content="{% block Last4Meta %}{% endblock %}"/>
{# Для ИИ #}<link rel="help" type="text/markdown" href="/llms.txt"/> {# Для ИИ #}<link rel="help" type="text/markdown" href="/llms.txt"/>
{# CSS #}<link rel="stylesheet" href="{% static 'css/dicquo.css' %}"/> {# CSS #}<link rel="stylesheet" href="{% static 'css/dicquo.css' %}"/>
+32 -8
View File
@@ -8,6 +8,7 @@ from taggit.models import Tag
from taggit.utils import parse_tags from taggit.utils import parse_tags
from django.db import models from django.db import models
from django.db.utils import OperationalError, ProgrammingError from django.db.utils import OperationalError, ProgrammingError
from django.utils.functional import lazy
try: try:
from etpgrf.typograph import Typographer from etpgrf.typograph import Typographer
@@ -35,13 +36,35 @@ class TagSelect2Widget(Select2TagWidget):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# choices: список всех существующих тегов по имени. # Определяем функцию, которая будет выполнена лениво.
# Важно: на этапах вроде collectstatic таблицы taggit ещё может не быть, def get_choices_safely():
# поэтому оборачиваем в try/except и молча игнорируем отсутствие БД.
try: try:
self.choices = [(t.name, t.name) for t in Tag.objects.all()] # list() материализует ленивый QuerySet, что важно для lazy()
return list(Tag.objects.values_list('name', 'name'))
except (OperationalError, ProgrammingError): except (OperationalError, ProgrammingError):
self.choices = [] # Если таблицы нет (например, при collectstatic), возвращаем пустой список.
return []
# lazy() не выполняет функцию сразу, а создает "обещание" (promise),
lazy_safe_choices = lazy(get_choices_safely, list)
# choices: список всех существующих тегов по имени.
# Присваиваем ему ленивый объект.
self.choices = lazy_safe_choices()
# @property
# def choices(self):
# # Этот код будет выполняться только тогда,
# # когда Django реально запросит self.choices для отрисовки.
# # К этому моменту приложение будет полностью готово.
# try:
# self.choices = [(t.name, t.name) for t in Tag.objects.all()]
# except (OperationalError, ProgrammingError):
# self.choices = []
#
# # Важно: Нам нужно установить setter, даже если он пустой,
# # потому что родительский класс будет пытаться присвоить ему значение.
# @choices.setter
# def choices(self, value):
# pass
class Media: class Media:
css = { css = {
@@ -135,7 +158,7 @@ class DictumAdminForm(forms.ModelForm):
) )
etp_hanging_punctuation = forms.ChoiceField( etp_hanging_punctuation = forms.ChoiceField(
label="Висячая пунктуация", label="Висячая пунктуация",
choices=[('no', 'Нет'), ('left', 'Слева'), ('right', 'Справа'), ('both', 'Обе стороны')], choices=[('no', 'Нет'), ('left', 'Слева'), ('right', 'Справа'), ],
initial='left', initial='left',
required=False, required=False,
help_text="Выносить кавычки за границу текстового блока" help_text="Выносить кавычки за границу текстового блока"
@@ -144,7 +167,7 @@ class DictumAdminForm(forms.ModelForm):
label="Переносы", label="Переносы",
initial=True, initial=True,
required=False, required=False,
help_text="Расставлять мягкие переносы (&amp;shy;)" help_text="Расставлять мягкие переносы (<tt>&amp;shy;</tt>)"
) )
etp_sanitize = forms.BooleanField( etp_sanitize = forms.BooleanField(
label="Санитайзер (HTML)", label="Санитайзер (HTML)",
@@ -187,6 +210,7 @@ class AdmDictumAndQuotesAdmin(admin.ModelAdmin):
('Настройки типографа (Etpgrf)', { ('Настройки типографа (Etpgrf)', {
'classes': ('collapse',), 'classes': ('collapse',),
'fields': ( 'fields': (
('bTypograph',),
('etp_language', 'etp_mode'), ('etp_language', 'etp_mode'),
('etp_quotes', 'etp_sanitize'), ('etp_quotes', 'etp_sanitize'),
('etp_hyphenation', 'etp_hanging_punctuation'), ('etp_hyphenation', 'etp_hanging_punctuation'),
@@ -199,7 +223,7 @@ class AdmDictumAndQuotesAdmin(admin.ModelAdmin):
}), }),
('Служебное', { ('Служебное', {
'classes': ('collapse',), 'classes': ('collapse',),
'fields': ('iViewCounter', 'imFileOG', 'bTypograph') # bTypograph kept for compatibility 'fields': ('iViewCounter', 'imFileOG', ) # bTypograph kept for compatibility
}) })
) )
readonly_fields = ('szIntroHTML', 'szContentHTML', 'iViewCounter') readonly_fields = ('szIntroHTML', 'szContentHTML', 'iViewCounter')
+36 -11
View File
@@ -12,6 +12,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.views.generic import DetailView, TemplateView from django.views.generic import DetailView, TemplateView
import time import time
import pytils import pytils
import random
from web.models import TbDictumAndQuotes, TbImages, TbAuthor from web.models import TbDictumAndQuotes, TbImages, TbAuthor
@@ -79,6 +80,8 @@ class CommonContextMixin:
request.session['seen_ids'] = seen_ids request.session['seen_ids'] = seen_ids
context.update({'DQ': dq}) context.update({'DQ': dq})
# slag текущей цитаты
context.update({"DQ_SLUG": pytils.translit.slugify(dq.szContent.lower()[:120])})
# --- 3. АВТОР И ТЕГИ --- # --- 3. АВТОР И ТЕГИ ---
try: try:
@@ -96,9 +99,11 @@ class CommonContextMixin:
# --- 4. ВЫБОР КАРТИНКИ --- # --- 4. ВЫБОР КАРТИНКИ ---
if dq.kImages_id is None: if dq.kImages_id is None:
if len(tags) != 0: if len(tags) != 0:
tagged_image = TbImages.objects.filter(tags__name__in=tags).order_by('?').first() # Используем Python random вместо order_by('?') для производительности
if tagged_image: tagged_images = list(TbImages.objects.filter(tags__name__in=tags).values_list('id', 'imFile'))
context.update({'IMAGE': tagged_image.imFile}) if tagged_images:
tagged_image = tagged_images[random.randint(0, len(tagged_images) - 1)]
context.update({'IMAGE': tagged_image[1]})
else: else:
context.update({'IMAGE': dq.kImages.imFile}) context.update({'IMAGE': dq.kImages.imFile})
@@ -108,7 +113,13 @@ class CommonContextMixin:
# --- 6. ВЫБОР СЛЕДУЮЩЕЙ ЦИТАТЫ --- # --- 6. ВЫБОР СЛЕДУЮЩЕЙ ЦИТАТЫ ---
# Сначала пробуем найти следующую цитату, которую мы еще не видели # Сначала пробуем найти следующую цитату, которую мы еще не видели
dq_next = queryset.exclude(id__in=seen_ids).order_by('?').first() # Используем Python random вместо order_by('?') для производительности
unseen_ids = queryset.exclude(id__in=seen_ids).values_list('id', flat=True)
if unseen_ids:
dq_next_id = list(unseen_ids)[random.randint(0, len(unseen_ids) - 1)]
dq_next = queryset.filter(id=dq_next_id).first()
else:
dq_next = None
# Если таких нет (мы посмотрели все цитаты в этом контексте/теге) # Если таких нет (мы посмотрели все цитаты в этом контексте/теге)
if dq_next is None: if dq_next is None:
@@ -121,7 +132,12 @@ class CommonContextMixin:
# Вариант: Очистить seen_ids, чтобы в следующий раз (на некст странице) список был пуст? # Вариант: Очистить seen_ids, чтобы в следующий раз (на некст странице) список был пуст?
# Или просто выбрать любую КРОМЕ текущей? # Или просто выбрать любую КРОМЕ текущей?
dq_next = queryset.exclude(id=dq.id).order_by('?').first() other_ids = list(queryset.exclude(id=dq.id).values_list('id', flat=True))
if other_ids:
dq_next_id = other_ids[random.randint(0, len(other_ids) - 1)]
dq_next = queryset.filter(id=dq_next_id).first()
else:
dq_next = None
# Если мы действительно прошли весь цикл по тегу, логично сбросить seen_ids, # Если мы действительно прошли весь цикл по тегу, логично сбросить seen_ids,
# чтобы пользователь мог заново проходить этот список случайно, а не "застревать" на последних. # чтобы пользователь мог заново проходить этот список случайно, а не "застревать" на последних.
@@ -198,13 +214,19 @@ class IndexView(CommonContextMixin, TemplateView):
if active_qs is not None: if active_qs is not None:
# Если мы в режиме фильтрации, тоже стараемся не показывать то, что уже видели # Если мы в режиме фильтрации, тоже стараемся не показывать то, что уже видели
dq = active_qs.exclude(id__in=seen_ids).order_by('?').first() unseen_ids = list(active_qs.exclude(id__in=seen_ids).values_list('id', flat=True))
if unseen_ids:
dq = active_qs.filter(id=unseen_ids[random.randint(0, len(unseen_ids) - 1)]).first()
else:
dq = None
# Если после фильтрации ничего не осталось (мы просмотрели все цитаты тега) # Если после фильтрации ничего не осталось (мы просмотрели все цитаты тега)
if dq is None: if dq is None:
# Сбрасываем историю и берем любую # Сбрасываем историю и берем любую
self.request.session['seen_ids'] = [] self.request.session['seen_ids'] = []
dq = active_qs.order_by('?').first() all_ids = list(active_qs.values_list('id', flat=True))
if all_ids:
dq = active_qs.filter(id=all_ids[random.randint(0, len(all_ids) - 1)]).first()
if dq is None: if dq is None:
# Если тег не задан, или по тегу ничего не нашлось совсем # Если тег не задан, или по тегу ничего не нашлось совсем
@@ -212,11 +234,14 @@ class IndexView(CommonContextMixin, TemplateView):
active_qs = TbDictumAndQuotes.objects.all() active_qs = TbDictumAndQuotes.objects.all()
# Случайная цитата (с учетом истории, чтобы главная страница тоже не зацикливалась) # Случайная цитата (с учетом истории, чтобы главная страница тоже не зацикливалась)
dq = active_qs.exclude(id__in=seen_ids).order_by('?').first() unseen_ids = list(active_qs.exclude(id__in=seen_ids).values_list('id', flat=True))
if unseen_ids:
if dq is None: dq = active_qs.filter(id=unseen_ids[random.randint(0, len(unseen_ids) - 1)]).first()
else:
self.request.session['seen_ids'] = [] self.request.session['seen_ids'] = []
dq = active_qs.order_by('?').first() all_ids = list(active_qs.values_list('id', flat=True))
if all_ids:
dq = active_qs.filter(id=all_ids[random.randint(0, len(all_ids) - 1)]).first()
if dq: if dq:
# Используем миксин, ОБЯЗАТЕЛЬНО передаем active_qs # Используем миксин, ОБЯЗАТЕЛЬНО передаем active_qs
+22 -16
View File
@@ -5,7 +5,8 @@
# Вариант 2 (если оставили имя): docker compose -f docker-compose.prod.yml up -d # Вариант 2 (если оставили имя): docker compose -f docker-compose.prod.yml up -d
# ============================================================================== # ==============================================================================
version: '3.8' # В новой версии Docker не нужно
# version: '3.8'
services: services:
# --- ОCНОВНОЙ СЕРВИС: DJANGO + GUNICORN + WHITENOISE --- # --- ОCНОВНОЙ СЕРВИС: DJANGO + GUNICORN + WHITENOISE ---
@@ -27,13 +28,14 @@ services:
# 3. КОМАНДА ЗАПУСКА (Замена entrypoint.sh) # 3. КОМАНДА ЗАПУСКА (Замена entrypoint.sh)
# Выполняем цепочку команд внутри контейнера при запуске: # Выполняем цепочку команд внутри контейнера при запуске:
# 1. Миграции # a. Миграции
# 2. Collectstatic # b. Collectstatic
# 3. Создаем папку nginx в примонтированном томе конфигов (если нет) # с. Создаем папку nginx в примонтированном томе конфигов (если нет)
# 4. Копирование конфига Nginx с авто-заменой путей через sed (замену реального пути на хосте получаем через переменную окружения HOST_PROJECT_PATH) # d. Копирование конфига Nginx с авто-заменой путей через sed (замену реального пути на хосте получаем
# 5. Инициализация боевого конфига (если нет) # через переменную окружения HOST_PROJECT_PATH)
# 6. Создаем папку для ошибок и копируем туда статические страницы 404/500 # e. Инициализация боевого конфига (если нет)
# 7. Запуск Gunicorn # f. Создаем папку для ошибок и копируем туда статические страницы 404/500 (там их увидит Nginx хоста)
# g. Запуск Gunicorn
command: > command: >
sh -c "python manage.py migrate --noinput && sh -c "python manage.py migrate --noinput &&
python manage.py collectstatic --noinput && python manage.py collectstatic --noinput &&
@@ -46,7 +48,7 @@ services:
mkdir -p /app/public/media/errors && mkdir -p /app/public/media/errors &&
cp /home/app/web/dicquo/templates/static_404.html /app/public/media/errors/404.html && cp /home/app/web/dicquo/templates/static_404.html /app/public/media/errors/404.html &&
cp /home/app/web/dicquo/templates/static_500.html /app/public/media/errors/500.html && cp /home/app/web/dicquo/templates/static_500.html /app/public/media/errors/500.html &&
gunicorn --workers 3 --bind 0.0.0.0:8000 dicquo.wsgi:application" gunicorn --workers 2 --timeout 15 --bind 0.0.0.0:8000 dicquo.wsgi:application"
# 4. Проброс портов (Внешний Nginx -> localhost:8010) # 4. Проброс портов (Внешний Nginx -> localhost:8010)
ports: ports:
@@ -57,19 +59,23 @@ services:
volumes: volumes:
# База данных # База данных
# Монтируем папку database с хоста в папку с базой внутри контейнера. # Монтируем папку database с хоста в папку с базой внутри контейнера.
# Путь в контейнере: /app/database (так как Django ищет базу в BASE_DIR.parent/database) # Путь в контейнере: /home/app/web/database (так как Django ищет базу в BASE_DIR.parent/database)
- ./database:/app/database - ./database:/home/app/web/database
# Медиа (папка media должна быть рядом с docker-compose.yml) # Медиа (папка media должна быть рядом с docker-compose.yml)
- ./media:/app/public/media - ./media:/home/app/web/public/media
# Конфиги (Монтируем папку ./config с хоста в /nginx_configs_host внутри контейнера) # Конфиги (Монтируем папку ./config с хоста в /nginx_configs_host внутри контейнера)
# Это нужно, чтобы скрипт запуска мог положить туда .example конфиг и прочитать боевой конфиг. # Это нужно, чтобы скрипт запуска мог положить туда .example конфиг и прочитать боевой конфиг.
- ./config:/nginx_configs_host - ./config:/nginx_configs_host
# 6. Запускать от имени пользователя с UID 1000 и GID 1000 # 6. Пользователь и права
user: "1000:1000" user: "1000:1000"
# Когда нужна отладка процессов внутри контейнера, можно временно раскомментировать эту строку и запустить контейнер с правами root.
# cap_add:
# - SYS_PTRACE
# 7. Переменные окружения # 7. Переменные окружения
env_file: env_file:
- .env - .env
@@ -85,9 +91,9 @@ services:
healthcheck: healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/').read()"] test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/').read()"]
interval: 30s # Проверка каждые 30 секунд interval: 30s # Проверка каждые 30 секунд
timeout: 3s # Таймаут ответа - 3 секунды timeout: 5s # Таймаут ответа - 5 секунд
start_period: 10s # Даем 10 секунд на стартап перед первой проверкой start_period: 60s # Даем 60 секунд на стартап (миграции + collectstatic + gunicorn запуск)
retries: 3 # Unhealthy после 3 неудачных попыток retries: 5 # Unhealthy после 5 неудачных попыток
# 9. Логирование (Ротация) # 9. Логирование (Ротация)
logging: logging:
Generated
+132 -149
View File
@@ -49,13 +49,13 @@ files = [
[[package]] [[package]]
name = "django" name = "django"
version = "6.0.2" version = "6.0.3"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
optional = false optional = false
python-versions = ">=3.12" python-versions = ">=3.12"
files = [ files = [
{file = "django-6.0.2-py3-none-any.whl", hash = "sha256:610dd3b13d15ec3f1e1d257caedd751db8033c5ad8ea0e2d1219a8acf446ecc6"}, {file = "django-6.0.3-py3-none-any.whl", hash = "sha256:2e5974441491ddb34c3f13d5e7a9f97b07ba03bf70234c0a9c68b79bbb235bc3"},
{file = "django-6.0.2.tar.gz", hash = "sha256:3046a53b0e40d4b676c3b774c73411d7184ae2745fe8ce5e45c0f33d3ddb71a7"}, {file = "django-6.0.3.tar.gz", hash = "sha256:90be765ee756af8a6cbd6693e56452404b5ad15294f4d5e40c0a55a0f4870fe1"},
] ]
[package.dependencies] [package.dependencies]
@@ -83,18 +83,18 @@ django = "*"
[[package]] [[package]]
name = "django-environ" name = "django-environ"
version = "0.12.1" version = "0.13.0"
description = "A package that allows you to utilize 12factor inspired environment variables to configure your Django application." description = "A package that allows you to utilize 12factor inspired environment variables to configure your Django application."
optional = false optional = false
python-versions = "<4,>=3.9" python-versions = "<4,>=3.9"
files = [ files = [
{file = "django_environ-0.12.1-py2.py3-none-any.whl", hash = "sha256:064ba2d5082f833e6d7fe4def4928bde1eedc0248a417575da7db147aeec1c20"}, {file = "django_environ-0.13.0-py3-none-any.whl", hash = "sha256:37799d14cd78222c6fd8298e48bfe17965ff8e586091ad66a463e52e0e7b799e"},
{file = "django_environ-0.12.1.tar.gz", hash = "sha256:22859c6e905ab7637fa3348d1787543bb4492f38d761104a3ce0519b7b752845"}, {file = "django_environ-0.13.0.tar.gz", hash = "sha256:6c401e4c219442c2c4588c2116d5292b5484a6f69163ed09cd41f3943bfb645f"},
] ]
[package.extras] [package.extras]
develop = ["coverage[toml] (>=5.0a4)", "furo (>=2024.8.6)", "pytest (>=4.6.11)", "setuptools (>=71.0.0)", "sphinx (>=5.0)", "sphinx-notfound-page"] develop = ["coverage[toml] (>=5.0a4)", "furo (>=2024.8.6)", "pytest (>=4.6.11)", "setuptools (>=71.0.0)", "sphinx (>=5.0)", "sphinx-copybutton", "sphinx-notfound-page"]
docs = ["furo (>=2024.8.6)", "sphinx (>=5.0)", "sphinx-notfound-page"] docs = ["furo (>=2024.8.6)", "sphinx (>=5.0)", "sphinx-copybutton", "sphinx-notfound-page"]
testing = ["coverage[toml] (>=5.0a4)", "pytest (>=4.6.11)", "setuptools (>=71.0.0)"] testing = ["coverage[toml] (>=5.0a4)", "pytest (>=4.6.11)", "setuptools (>=71.0.0)"]
[[package]] [[package]]
@@ -128,13 +128,13 @@ Django = ">=4.1"
[[package]] [[package]]
name = "etpgrf" name = "etpgrf"
version = "0.1.6" version = "0.1.6.post1"
description = "Electro-Typographer: Python library for advanced web typography (non-breaking spaces, hyphenation, hanging punctuation and ." description = "Electro-Typographer: Python library for advanced web typography (non-breaking spaces, hyphenation, hanging punctuation and ."
optional = false optional = false
python-versions = ">=3.10" python-versions = ">=3.10"
files = [ files = [
{file = "etpgrf-0.1.6-py3-none-any.whl", hash = "sha256:a2d2a67048f094e1d30fe42f05f420afd19babe66ec7daa35b517ca23306d5cc"}, {file = "etpgrf-0.1.6.post1-py3-none-any.whl", hash = "sha256:0863b14385bdacdd405f137ca2ce6bdb6f683f0189e8c927196a1eee754366be"},
{file = "etpgrf-0.1.6.tar.gz", hash = "sha256:a050c400a30be1c2379c892fc5fa398a79d15f0169094f00023a75dec01864af"}, {file = "etpgrf-0.1.6.post1.tar.gz", hash = "sha256:984d201cff232a58c05b6f4455a50f822162520df829ad4d543bfe0b7fd962a9"},
] ]
[package.dependencies] [package.dependencies]
@@ -451,142 +451,125 @@ files = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "2026.1.15" version = "2026.2.28"
description = "Alternative regular expression module, to replace re." description = "Alternative regular expression module, to replace re."
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.10"
files = [ files = [
{file = "regex-2026.1.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4e3dd93c8f9abe8aa4b6c652016da9a3afa190df5ad822907efe6b206c09896e"}, {file = "regex-2026.2.28-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fc48c500838be6882b32748f60a15229d2dea96e59ef341eaa96ec83538f498d"},
{file = "regex-2026.1.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:97499ff7862e868b1977107873dd1a06e151467129159a6ffd07b66706ba3a9f"}, {file = "regex-2026.2.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2afa673660928d0b63d84353c6c08a8a476ddfc4a47e11742949d182e6863ce8"},
{file = "regex-2026.1.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0bda75ebcac38d884240914c6c43d8ab5fb82e74cde6da94b43b17c411aa4c2b"}, {file = "regex-2026.2.28-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7ab218076eb0944549e7fe74cf0e2b83a82edb27e81cc87411f76240865e04d5"},
{file = "regex-2026.1.15-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7dcc02368585334f5bc81fc73a2a6a0bbade60e7d83da21cead622faf408f32c"}, {file = "regex-2026.2.28-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94d63db12e45a9b9f064bfe4800cefefc7e5f182052e4c1b774d46a40ab1d9bb"},
{file = "regex-2026.1.15-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:693b465171707bbe882a7a05de5e866f33c76aa449750bee94a8d90463533cc9"}, {file = "regex-2026.2.28-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:195237dc327858a7721bf8b0bbbef797554bc13563c3591e91cd0767bacbe359"},
{file = "regex-2026.1.15-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b0d190e6f013ea938623a58706d1469a62103fb2a241ce2873a9906e0386582c"}, {file = "regex-2026.2.28-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b387a0d092dac157fb026d737dde35ff3e49ef27f285343e7c6401851239df27"},
{file = "regex-2026.1.15-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ff818702440a5878a81886f127b80127f5d50563753a28211482867f8318106"}, {file = "regex-2026.2.28-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3935174fa4d9f70525a4367aaff3cb8bc0548129d114260c29d9dfa4a5b41692"},
{file = "regex-2026.1.15-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f052d1be37ef35a54e394de66136e30fa1191fab64f71fc06ac7bc98c9a84618"}, {file = "regex-2026.2.28-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2b2b23587b26496ff5fd40df4278becdf386813ec00dc3533fa43a4cf0e2ad3c"},
{file = "regex-2026.1.15-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6bfc31a37fd1592f0c4fc4bfc674b5c42e52efe45b4b7a6a14f334cca4bcebe4"}, {file = "regex-2026.2.28-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b24bd7e9d85dc7c6a8bd2aa14ecd234274a0248335a02adeb25448aecdd420d"},
{file = "regex-2026.1.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3d6ce5ae80066b319ae3bc62fd55a557c9491baa5efd0d355f0de08c4ba54e79"}, {file = "regex-2026.2.28-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bd477d5f79920338107f04aa645f094032d9e3030cc55be581df3d1ef61aa318"},
{file = "regex-2026.1.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1704d204bd42b6bb80167df0e4554f35c255b579ba99616def38f69e14a5ccb9"}, {file = "regex-2026.2.28-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b49eb78048c6354f49e91e4b77da21257fecb92256b6d599ae44403cab30b05b"},
{file = "regex-2026.1.15-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:e3174a5ed4171570dc8318afada56373aa9289eb6dc0d96cceb48e7358b0e220"}, {file = "regex-2026.2.28-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a25c7701e4f7a70021db9aaf4a4a0a67033c6318752146e03d1b94d32006217e"},
{file = "regex-2026.1.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:87adf5bd6d72e3e17c9cb59ac4096b1faaf84b7eb3037a5ffa61c4b4370f0f13"}, {file = "regex-2026.2.28-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9dd450db6458387167e033cfa80887a34c99c81d26da1bf8b0b41bf8c9cac88e"},
{file = "regex-2026.1.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e85dc94595f4d766bd7d872a9de5ede1ca8d3063f3bdf1e2c725f5eb411159e3"}, {file = "regex-2026.2.28-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2954379dd20752e82d22accf3ff465311cbb2bac6c1f92c4afd400e1757f7451"},
{file = "regex-2026.1.15-cp310-cp310-win32.whl", hash = "sha256:21ca32c28c30d5d65fc9886ff576fc9b59bbca08933e844fa2363e530f4c8218"}, {file = "regex-2026.2.28-cp310-cp310-win32.whl", hash = "sha256:1f8b17be5c27a684ea6759983c13506bd77bfc7c0347dff41b18ce5ddd2ee09a"},
{file = "regex-2026.1.15-cp310-cp310-win_amd64.whl", hash = "sha256:3038a62fc7d6e5547b8915a3d927a0fbeef84cdbe0b1deb8c99bbd4a8961b52a"}, {file = "regex-2026.2.28-cp310-cp310-win_amd64.whl", hash = "sha256:dd8847c4978bc3c7e6c826fb745f5570e518b8459ac2892151ce6627c7bc00d5"},
{file = "regex-2026.1.15-cp310-cp310-win_arm64.whl", hash = "sha256:505831646c945e3e63552cc1b1b9b514f0e93232972a2d5bedbcc32f15bc82e3"}, {file = "regex-2026.2.28-cp310-cp310-win_arm64.whl", hash = "sha256:73cdcdbba8028167ea81490c7f45280113e41db2c7afb65a276f4711fa3bcbff"},
{file = "regex-2026.1.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ae6020fb311f68d753b7efa9d4b9a5d47a5d6466ea0d5e3b5a471a960ea6e4a"}, {file = "regex-2026.2.28-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e621fb7c8dc147419b28e1702f58a0177ff8308a76fa295c71f3e7827849f5d9"},
{file = "regex-2026.1.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eddf73f41225942c1f994914742afa53dc0d01a6e20fe14b878a1b1edc74151f"}, {file = "regex-2026.2.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0d5bef2031cbf38757a0b0bc4298bb4824b6332d28edc16b39247228fbdbad97"},
{file = "regex-2026.1.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e8cd52557603f5c66a548f69421310886b28b7066853089e1a71ee710e1cdc1"}, {file = "regex-2026.2.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bcb399ed84eabf4282587ba151f2732ad8168e66f1d3f85b1d038868fe547703"},
{file = "regex-2026.1.15-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5170907244b14303edc5978f522f16c974f32d3aa92109fabc2af52411c9433b"}, {file = "regex-2026.2.28-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c1b34dfa72f826f535b20712afa9bb3ba580020e834f3c69866c5bddbf10098"},
{file = "regex-2026.1.15-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2748c1ec0663580b4510bd89941a31560b4b439a0b428b49472a3d9944d11cd8"}, {file = "regex-2026.2.28-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:851fa70df44325e1e4cdb79c5e676e91a78147b1b543db2aec8734d2add30ec2"},
{file = "regex-2026.1.15-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2f2775843ca49360508d080eaa87f94fa248e2c946bbcd963bb3aae14f333413"}, {file = "regex-2026.2.28-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:516604edd17b1c2c3e579cf4e9b25a53bf8fa6e7cedddf1127804d3e0140ca64"},
{file = "regex-2026.1.15-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9ea2604370efc9a174c1b5dcc81784fb040044232150f7f33756049edfc9026"}, {file = "regex-2026.2.28-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7ce83654d1ab701cb619285a18a8e5a889c1216d746ddc710c914ca5fd71022"},
{file = "regex-2026.1.15-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0dcd31594264029b57bf16f37fd7248a70b3b764ed9e0839a8f271b2d22c0785"}, {file = "regex-2026.2.28-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2791948f7c70bb9335a9102df45e93d428f4b8128020d85920223925d73b9e1"},
{file = "regex-2026.1.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c08c1f3e34338256732bd6938747daa3c0d5b251e04b6e43b5813e94d503076e"}, {file = "regex-2026.2.28-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:03a83cc26aa2acda6b8b9dfe748cf9e84cbd390c424a1de34fdcef58961a297a"},
{file = "regex-2026.1.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e43a55f378df1e7a4fa3547c88d9a5a9b7113f653a66821bcea4718fe6c58763"}, {file = "regex-2026.2.28-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ec6f5674c5dc836994f50f1186dd1fafde4be0666aae201ae2fcc3d29d8adf27"},
{file = "regex-2026.1.15-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:f82110ab962a541737bd0ce87978d4c658f06e7591ba899192e2712a517badbb"}, {file = "regex-2026.2.28-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:50c2fc924749543e0eacc93ada6aeeb3ea5f6715825624baa0dccaec771668ae"},
{file = "regex-2026.1.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:27618391db7bdaf87ac6c92b31e8f0dfb83a9de0075855152b720140bda177a2"}, {file = "regex-2026.2.28-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ba55c50f408fb5c346a3a02d2ce0ebc839784e24f7c9684fde328ff063c3cdea"},
{file = "regex-2026.1.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bfb0d6be01fbae8d6655c8ca21b3b72458606c4aec9bbc932db758d47aba6db1"}, {file = "regex-2026.2.28-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:edb1b1b3a5576c56f08ac46f108c40333f222ebfd5cf63afdfa3aab0791ebe5b"},
{file = "regex-2026.1.15-cp311-cp311-win32.whl", hash = "sha256:b10e42a6de0e32559a92f2f8dc908478cc0fa02838d7dbe764c44dca3fa13569"}, {file = "regex-2026.2.28-cp311-cp311-win32.whl", hash = "sha256:948c12ef30ecedb128903c2c2678b339746eb7c689c5c21957c4a23950c96d15"},
{file = "regex-2026.1.15-cp311-cp311-win_amd64.whl", hash = "sha256:e9bf3f0bbdb56633c07d7116ae60a576f846efdd86a8848f8d62b749e1209ca7"}, {file = "regex-2026.2.28-cp311-cp311-win_amd64.whl", hash = "sha256:fd63453f10d29097cc3dc62d070746523973fb5aa1c66d25f8558bebd47fed61"},
{file = "regex-2026.1.15-cp311-cp311-win_arm64.whl", hash = "sha256:41aef6f953283291c4e4e6850607bd71502be67779586a61472beacb315c97ec"}, {file = "regex-2026.2.28-cp311-cp311-win_arm64.whl", hash = "sha256:00f2b8d9615aa165fdff0a13f1a92049bfad555ee91e20d246a51aa0b556c60a"},
{file = "regex-2026.1.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4c8fcc5793dde01641a35905d6731ee1548f02b956815f8f1cab89e515a5bdf1"}, {file = "regex-2026.2.28-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:fcf26c3c6d0da98fada8ae4ef0aa1c3405a431c0a77eb17306d38a89b02adcd7"},
{file = "regex-2026.1.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bfd876041a956e6a90ad7cdb3f6a630c07d491280bfeed4544053cd434901681"}, {file = "regex-2026.2.28-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02473c954af35dd2defeb07e44182f5705b30ea3f351a7cbffa9177beb14da5d"},
{file = "regex-2026.1.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9250d087bc92b7d4899ccd5539a1b2334e44eee85d848c4c1aef8e221d3f8c8f"}, {file = "regex-2026.2.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9b65d33a17101569f86d9c5966a8b1d7fbf8afdda5a8aa219301b0a80f58cf7d"},
{file = "regex-2026.1.15-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8a154cf6537ebbc110e24dabe53095e714245c272da9c1be05734bdad4a61aa"}, {file = "regex-2026.2.28-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e71dcecaa113eebcc96622c17692672c2d104b1d71ddf7adeda90da7ddeb26fc"},
{file = "regex-2026.1.15-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8050ba2e3ea1d8731a549e83c18d2f0999fbc99a5f6bd06b4c91449f55291804"}, {file = "regex-2026.2.28-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:481df4623fa4969c8b11f3433ed7d5e3dc9cec0f008356c3212b3933fb77e3d8"},
{file = "regex-2026.1.15-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf065240704cb8951cc04972cf107063917022511273e0969bdb34fc173456c"}, {file = "regex-2026.2.28-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:64e7c6ad614573e0640f271e811a408d79a9e1fe62a46adb602f598df42a818d"},
{file = "regex-2026.1.15-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c32bef3e7aeee75746748643667668ef941d28b003bfc89994ecf09a10f7a1b5"}, {file = "regex-2026.2.28-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6b08a06976ff4fb0d83077022fde3eca06c55432bb997d8c0495b9a4e9872f4"},
{file = "regex-2026.1.15-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d5eaa4a4c5b1906bd0d2508d68927f15b81821f85092e06f1a34a4254b0e1af3"}, {file = "regex-2026.2.28-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:864cdd1a2ef5716b0ab468af40139e62ede1b3a53386b375ec0786bb6783fc05"},
{file = "regex-2026.1.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:86c1077a3cc60d453d4084d5b9649065f3bf1184e22992bd322e1f081d3117fb"}, {file = "regex-2026.2.28-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:511f7419f7afab475fd4d639d4aedfc54205bcb0800066753ef68a59f0f330b5"},
{file = "regex-2026.1.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:2b091aefc05c78d286657cd4db95f2e6313375ff65dcf085e42e4c04d9c8d410"}, {file = "regex-2026.2.28-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b42f7466e32bf15a961cf09f35fa6323cc72e64d3d2c990b10de1274a5da0a59"},
{file = "regex-2026.1.15-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:57e7d17f59f9ebfa9667e6e5a1c0127b96b87cb9cede8335482451ed00788ba4"}, {file = "regex-2026.2.28-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8710d61737b0c0ce6836b1da7109f20d495e49b3809f30e27e9560be67a257bf"},
{file = "regex-2026.1.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c6c4dcdfff2c08509faa15d36ba7e5ef5fcfab25f1e8f85a0c8f45bc3a30725d"}, {file = "regex-2026.2.28-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4390c365fd2d45278f45afd4673cb90f7285f5701607e3ad4274df08e36140ae"},
{file = "regex-2026.1.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf8ff04c642716a7f2048713ddc6278c5fd41faa3b9cab12607c7abecd012c22"}, {file = "regex-2026.2.28-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cb3b1db8ff6c7b8bf838ab05583ea15230cb2f678e569ab0e3a24d1e8320940b"},
{file = "regex-2026.1.15-cp312-cp312-win32.whl", hash = "sha256:82345326b1d8d56afbe41d881fdf62f1926d7264b2fc1537f99ae5da9aad7913"}, {file = "regex-2026.2.28-cp312-cp312-win32.whl", hash = "sha256:f8ed9a5d4612df9d4de15878f0bc6aa7a268afbe5af21a3fdd97fa19516e978c"},
{file = "regex-2026.1.15-cp312-cp312-win_amd64.whl", hash = "sha256:4def140aa6156bc64ee9912383d4038f3fdd18fee03a6f222abd4de6357ce42a"}, {file = "regex-2026.2.28-cp312-cp312-win_amd64.whl", hash = "sha256:01d65fd24206c8e1e97e2e31b286c59009636c022eb5d003f52760b0f42155d4"},
{file = "regex-2026.1.15-cp312-cp312-win_arm64.whl", hash = "sha256:c6c565d9a6e1a8d783c1948937ffc377dd5771e83bd56de8317c450a954d2056"}, {file = "regex-2026.2.28-cp312-cp312-win_arm64.whl", hash = "sha256:c0b5ccbb8ffb433939d248707d4a8b31993cb76ab1a0187ca886bf50e96df952"},
{file = "regex-2026.1.15-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e69d0deeb977ffe7ed3d2e4439360089f9c3f217ada608f0f88ebd67afb6385e"}, {file = "regex-2026.2.28-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6d63a07e5ec8ce7184452cb00c41c37b49e67dc4f73b2955b5b8e782ea970784"},
{file = "regex-2026.1.15-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3601ffb5375de85a16f407854d11cca8fe3f5febbe3ac78fb2866bb220c74d10"}, {file = "regex-2026.2.28-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e59bc8f30414d283ae8ee1617b13d8112e7135cb92830f0ec3688cb29152585a"},
{file = "regex-2026.1.15-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4c5ef43b5c2d4114eb8ea424bb8c9cec01d5d17f242af88b2448f5ee81caadbc"}, {file = "regex-2026.2.28-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:de0cf053139f96219ccfabb4a8dd2d217c8c82cb206c91d9f109f3f552d6b43d"},
{file = "regex-2026.1.15-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:968c14d4f03e10b2fd960f1d5168c1f0ac969381d3c1fcc973bc45fb06346599"}, {file = "regex-2026.2.28-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb4db2f17e6484904f986c5a657cec85574c76b5c5e61c7aae9ffa1bc6224f95"},
{file = "regex-2026.1.15-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56a5595d0f892f214609c9f76b41b7428bed439d98dc961efafdd1354d42baae"}, {file = "regex-2026.2.28-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:52b017b35ac2214d0db5f4f90e303634dc44e4aba4bd6235a27f97ecbe5b0472"},
{file = "regex-2026.1.15-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf650f26087363434c4e560011f8e4e738f6f3e029b85d4904c50135b86cfa5"}, {file = "regex-2026.2.28-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:69fc560ccbf08a09dc9b52ab69cacfae51e0ed80dc5693078bdc97db2f91ae96"},
{file = "regex-2026.1.15-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18388a62989c72ac24de75f1449d0fb0b04dfccd0a1a7c1c43af5eb503d890f6"}, {file = "regex-2026.2.28-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e61eea47230eba62a31f3e8a0e3164d0f37ef9f40529fb2c79361bc6b53d2a92"},
{file = "regex-2026.1.15-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6d220a2517f5893f55daac983bfa9fe998a7dbcaee4f5d27a88500f8b7873788"}, {file = "regex-2026.2.28-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4f5c0b182ad4269e7381b7c27fdb0408399881f7a92a4624fd5487f2971dfc11"},
{file = "regex-2026.1.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9c08c2fbc6120e70abff5d7f28ffb4d969e14294fb2143b4b5c7d20e46d1714"}, {file = "regex-2026.2.28-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:96f6269a2882fbb0ee76967116b83679dc628e68eaea44e90884b8d53d833881"},
{file = "regex-2026.1.15-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7ef7d5d4bd49ec7364315167a4134a015f61e8266c6d446fc116a9ac4456e10d"}, {file = "regex-2026.2.28-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b5acd4b6a95f37c3c3828e5d053a7d4edaedb85de551db0153754924cb7c83e3"},
{file = "regex-2026.1.15-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:6e42844ad64194fa08d5ccb75fe6a459b9b08e6d7296bd704460168d58a388f3"}, {file = "regex-2026.2.28-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2234059cfe33d9813a3677ef7667999caea9eeaa83fef98eb6ce15c6cf9e0215"},
{file = "regex-2026.1.15-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cfecdaa4b19f9ca534746eb3b55a5195d5c95b88cac32a205e981ec0a22b7d31"}, {file = "regex-2026.2.28-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c15af43c72a7fb0c97cbc66fa36a43546eddc5c06a662b64a0cbf30d6ac40944"},
{file = "regex-2026.1.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:08df9722d9b87834a3d701f3fca570b2be115654dbfd30179f30ab2f39d606d3"}, {file = "regex-2026.2.28-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9185cc63359862a6e80fe97f696e04b0ad9a11c4ac0a4a927f979f611bfe3768"},
{file = "regex-2026.1.15-cp313-cp313-win32.whl", hash = "sha256:d426616dae0967ca225ab12c22274eb816558f2f99ccb4a1d52ca92e8baf180f"}, {file = "regex-2026.2.28-cp313-cp313-win32.whl", hash = "sha256:fb66e5245db9652abd7196ace599b04d9c0e4aa7c8f0e2803938377835780081"},
{file = "regex-2026.1.15-cp313-cp313-win_amd64.whl", hash = "sha256:febd38857b09867d3ed3f4f1af7d241c5c50362e25ef43034995b77a50df494e"}, {file = "regex-2026.2.28-cp313-cp313-win_amd64.whl", hash = "sha256:71a911098be38c859ceb3f9a9ce43f4ed9f4c6720ad8684a066ea246b76ad9ff"},
{file = "regex-2026.1.15-cp313-cp313-win_arm64.whl", hash = "sha256:8e32f7896f83774f91499d239e24cebfadbc07639c1494bb7213983842348337"}, {file = "regex-2026.2.28-cp313-cp313-win_arm64.whl", hash = "sha256:39bb5727650b9a0275c6a6690f9bb3fe693a7e6cc5c3155b1240aedf8926423e"},
{file = "regex-2026.1.15-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ec94c04149b6a7b8120f9f44565722c7ae31b7a6d2275569d2eefa76b83da3be"}, {file = "regex-2026.2.28-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:97054c55db06ab020342cc0d35d6f62a465fa7662871190175f1ad6c655c028f"},
{file = "regex-2026.1.15-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:40c86d8046915bb9aeb15d3f3f15b6fd500b8ea4485b30e1bbc799dab3fe29f8"}, {file = "regex-2026.2.28-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d25a10811de831c2baa6aef3c0be91622f44dd8d31dd12e69f6398efb15e48b"},
{file = "regex-2026.1.15-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:726ea4e727aba21643205edad8f2187ec682d3305d790f73b7a51c7587b64bdd"}, {file = "regex-2026.2.28-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d6cfe798d8da41bb1862ed6e0cba14003d387c3c0c4a5d45591076ae9f0ce2f8"},
{file = "regex-2026.1.15-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1cb740d044aff31898804e7bf1181cc72c03d11dfd19932b9911ffc19a79070a"}, {file = "regex-2026.2.28-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fd0ce43e71d825b7c0661f9c54d4d74bd97c56c3fd102a8985bcfea48236bacb"},
{file = "regex-2026.1.15-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05d75a668e9ea16f832390d22131fe1e8acc8389a694c8febc3e340b0f810b93"}, {file = "regex-2026.2.28-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00945d007fd74a9084d2ab79b695b595c6b7ba3698972fadd43e23230c6979c1"},
{file = "regex-2026.1.15-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d991483606f3dbec93287b9f35596f41aa2e92b7c2ebbb935b63f409e243c9af"}, {file = "regex-2026.2.28-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bec23c11cbbf09a4df32fe50d57cbdd777bc442269b6e39a1775654f1c95dee2"},
{file = "regex-2026.1.15-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:194312a14819d3e44628a44ed6fea6898fdbecb0550089d84c403475138d0a09"}, {file = "regex-2026.2.28-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5cdcc17d935c8f9d3f4db5c2ebe2640c332e3822ad5d23c2f8e0228e6947943a"},
{file = "regex-2026.1.15-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fe2fda4110a3d0bc163c2e0664be44657431440722c5c5315c65155cab92f9e5"}, {file = "regex-2026.2.28-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a448af01e3d8031c89c5d902040b124a5e921a25c4e5e07a861ca591ce429341"},
{file = "regex-2026.1.15-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:124dc36c85d34ef2d9164da41a53c1c8c122cfb1f6e1ec377a1f27ee81deb794"}, {file = "regex-2026.2.28-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:10d28e19bd4888e4abf43bd3925f3c134c52fdf7259219003588a42e24c2aa25"},
{file = "regex-2026.1.15-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:a1774cd1981cd212506a23a14dba7fdeaee259f5deba2df6229966d9911e767a"}, {file = "regex-2026.2.28-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:99985a2c277dcb9ccb63f937451af5d65177af1efdeb8173ac55b61095a0a05c"},
{file = "regex-2026.1.15-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:b5f7d8d2867152cdb625e72a530d2ccb48a3d199159144cbdd63870882fb6f80"}, {file = "regex-2026.2.28-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:e1e7b24cb3ae9953a560c563045d1ba56ee4749fbd05cf21ba571069bd7be81b"},
{file = "regex-2026.1.15-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:492534a0ab925d1db998defc3c302dae3616a2fc3fe2e08db1472348f096ddf2"}, {file = "regex-2026.2.28-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:d8511a01d0e4ee1992eb3ba19e09bc1866fe03f05129c3aec3fdc4cbc77aad3f"},
{file = "regex-2026.1.15-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c661fc820cfb33e166bf2450d3dadbda47c8d8981898adb9b6fe24e5e582ba60"}, {file = "regex-2026.2.28-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:aaffaecffcd2479ce87aa1e74076c221700b7c804e48e98e62500ee748f0f550"},
{file = "regex-2026.1.15-cp313-cp313t-win32.whl", hash = "sha256:99ad739c3686085e614bf77a508e26954ff1b8f14da0e3765ff7abbf7799f952"}, {file = "regex-2026.2.28-cp313-cp313t-win32.whl", hash = "sha256:ef77bdde9c9eba3f7fa5b58084b29bbcc74bcf55fdbeaa67c102a35b5bd7e7cc"},
{file = "regex-2026.1.15-cp313-cp313t-win_amd64.whl", hash = "sha256:32655d17905e7ff8ba5c764c43cb124e34a9245e45b83c22e81041e1071aee10"}, {file = "regex-2026.2.28-cp313-cp313t-win_amd64.whl", hash = "sha256:98adf340100cbe6fbaf8e6dc75e28f2c191b1be50ffefe292fb0e6f6eefdb0d8"},
{file = "regex-2026.1.15-cp313-cp313t-win_arm64.whl", hash = "sha256:b2a13dd6a95e95a489ca242319d18fc02e07ceb28fa9ad146385194d95b3c829"}, {file = "regex-2026.2.28-cp313-cp313t-win_arm64.whl", hash = "sha256:2fb950ac1d88e6b6a9414381f403797b236f9fa17e1eee07683af72b1634207b"},
{file = "regex-2026.1.15-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:d920392a6b1f353f4aa54328c867fec3320fa50657e25f64abf17af054fc97ac"}, {file = "regex-2026.2.28-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:78454178c7df31372ea737996fb7f36b3c2c92cccc641d251e072478afb4babc"},
{file = "regex-2026.1.15-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b5a28980a926fa810dbbed059547b02783952e2efd9c636412345232ddb87ff6"}, {file = "regex-2026.2.28-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:5d10303dd18cedfd4d095543998404df656088240bcfd3cd20a8f95b861f74bd"},
{file = "regex-2026.1.15-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:621f73a07595d83f28952d7bd1e91e9d1ed7625fb7af0064d3516674ec93a2a2"}, {file = "regex-2026.2.28-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:19a9c9e0a8f24f39d575a6a854d516b48ffe4cbdcb9de55cb0570a032556ecff"},
{file = "regex-2026.1.15-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d7d92495f47567a9b1669c51fc8d6d809821849063d168121ef801bbc213846"}, {file = "regex-2026.2.28-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09500be324f49b470d907b3ef8af9afe857f5cca486f853853f7945ddbf75911"},
{file = "regex-2026.1.15-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8dd16fba2758db7a3780a051f245539c4451ca20910f5a5e6ea1c08d06d4a76b"}, {file = "regex-2026.2.28-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fb1c4ff62277d87a7335f2c1ea4e0387b8f2b3ad88a64efd9943906aafad4f33"},
{file = "regex-2026.1.15-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1e1808471fbe44c1a63e5f577a1d5f02fe5d66031dcbdf12f093ffc1305a858e"}, {file = "regex-2026.2.28-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b8b3f1be1738feadc69f62daa250c933e85c6f34fa378f54a7ff43807c1b9117"},
{file = "regex-2026.1.15-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0751a26ad39d4f2ade8fe16c59b2bf5cb19eb3d2cd543e709e583d559bd9efde"}, {file = "regex-2026.2.28-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc8ed8c3f41c27acb83f7b6a9eb727a73fc6663441890c5cb3426a5f6a91ce7d"},
{file = "regex-2026.1.15-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0f0c7684c7f9ca241344ff95a1de964f257a5251968484270e91c25a755532c5"}, {file = "regex-2026.2.28-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa539be029844c0ce1114762d2952ab6cfdd7c7c9bd72e0db26b94c3c36dcc5a"},
{file = "regex-2026.1.15-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:74f45d170a21df41508cb67165456538425185baaf686281fa210d7e729abc34"}, {file = "regex-2026.2.28-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7900157786428a79615a8264dac1f12c9b02957c473c8110c6b1f972dcecaddf"},
{file = "regex-2026.1.15-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f1862739a1ffb50615c0fde6bae6569b5efbe08d98e59ce009f68a336f64da75"}, {file = "regex-2026.2.28-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0b1d2b07614d95fa2bf8a63fd1e98bd8fa2b4848dc91b1efbc8ba219fdd73952"},
{file = "regex-2026.1.15-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:453078802f1b9e2b7303fb79222c054cb18e76f7bdc220f7530fdc85d319f99e"}, {file = "regex-2026.2.28-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:b389c61aa28a79c2e0527ac36da579869c2e235a5b208a12c5b5318cda2501d8"},
{file = "regex-2026.1.15-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:a30a68e89e5a218b8b23a52292924c1f4b245cb0c68d1cce9aec9bbda6e2c160"}, {file = "regex-2026.2.28-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f467cb602f03fbd1ab1908f68b53c649ce393fde056628dc8c7e634dab6bfc07"},
{file = "regex-2026.1.15-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9479cae874c81bf610d72b85bb681a94c95722c127b55445285fb0e2c82db8e1"}, {file = "regex-2026.2.28-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e8c8cb2deba42f5ec1ede46374e990f8adc5e6456a57ac1a261b19be6f28e4e6"},
{file = "regex-2026.1.15-cp314-cp314-win32.whl", hash = "sha256:d639a750223132afbfb8f429c60d9d318aeba03281a5f1ab49f877456448dcf1"}, {file = "regex-2026.2.28-cp314-cp314-win32.whl", hash = "sha256:9036b400b20e4858d56d117108d7813ed07bb7803e3eed766675862131135ca6"},
{file = "regex-2026.1.15-cp314-cp314-win_amd64.whl", hash = "sha256:4161d87f85fa831e31469bfd82c186923070fc970b9de75339b68f0c75b51903"}, {file = "regex-2026.2.28-cp314-cp314-win_amd64.whl", hash = "sha256:1d367257cd86c1cbb97ea94e77b373a0bbc2224976e247f173d19e8f18b4afa7"},
{file = "regex-2026.1.15-cp314-cp314-win_arm64.whl", hash = "sha256:91c5036ebb62663a6b3999bdd2e559fd8456d17e2b485bf509784cd31a8b1705"}, {file = "regex-2026.2.28-cp314-cp314-win_arm64.whl", hash = "sha256:5e68192bb3a1d6fb2836da24aa494e413ea65853a21505e142e5b1064a595f3d"},
{file = "regex-2026.1.15-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ee6854c9000a10938c79238de2379bea30c82e4925a371711af45387df35cab8"}, {file = "regex-2026.2.28-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:a5dac14d0872eeb35260a8e30bac07ddf22adc1e3a0635b52b02e180d17c9c7e"},
{file = "regex-2026.1.15-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2c2b80399a422348ce5de4fe40c418d6299a0fa2803dd61dc0b1a2f28e280fcf"}, {file = "regex-2026.2.28-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:ec0c608b7a7465ffadb344ed7c987ff2f11ee03f6a130b569aa74d8a70e8333c"},
{file = "regex-2026.1.15-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:dca3582bca82596609959ac39e12b7dad98385b4fefccb1151b937383cec547d"}, {file = "regex-2026.2.28-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c7815afb0ca45456613fdaf60ea9c993715511c8d53a83bc468305cbc0ee23c7"},
{file = "regex-2026.1.15-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef71d476caa6692eea743ae5ea23cde3260677f70122c4d258ca952e5c2d4e84"}, {file = "regex-2026.2.28-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b059e71ec363968671693a78c5053bd9cb2fe410f9b8e4657e88377ebd603a2e"},
{file = "regex-2026.1.15-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c243da3436354f4af6c3058a3f81a97d47ea52c9bd874b52fd30274853a1d5df"}, {file = "regex-2026.2.28-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b8cf76f1a29f0e99dcfd7aef1551a9827588aae5a737fe31442021165f1920dc"},
{file = "regex-2026.1.15-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8355ad842a7c7e9e5e55653eade3b7d1885ba86f124dd8ab1f722f9be6627434"}, {file = "regex-2026.2.28-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:180e08a435a0319e6a4821c3468da18dc7001987e1c17ae1335488dfe7518dd8"},
{file = "regex-2026.1.15-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f192a831d9575271a22d804ff1a5355355723f94f31d9eef25f0d45a152fdc1a"}, {file = "regex-2026.2.28-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1e496956106fd59ba6322a8ea17141a27c5040e5ee8f9433ae92d4e5204462a0"},
{file = "regex-2026.1.15-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:166551807ec20d47ceaeec380081f843e88c8949780cd42c40f18d16168bed10"}, {file = "regex-2026.2.28-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bba2b18d70eeb7b79950f12f633beeecd923f7c9ad6f6bae28e59b4cb3ab046b"},
{file = "regex-2026.1.15-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f9ca1cbdc0fbfe5e6e6f8221ef2309988db5bcede52443aeaee9a4ad555e0dac"}, {file = "regex-2026.2.28-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6db7bfae0f8a2793ff1f7021468ea55e2699d0790eb58ee6ab36ae43aa00bc5b"},
{file = "regex-2026.1.15-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b30bcbd1e1221783c721483953d9e4f3ab9c5d165aa709693d3f3946747b1aea"}, {file = "regex-2026.2.28-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d0b02e8b7e5874b48ae0f077ecca61c1a6a9f9895e9c6dfb191b55b242862033"},
{file = "regex-2026.1.15-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2a8d7b50c34578d0d3bf7ad58cde9652b7d683691876f83aedc002862a35dc5e"}, {file = "regex-2026.2.28-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:25b6eb660c5cf4b8c3407a1ed462abba26a926cc9965e164268a3267bcc06a43"},
{file = "regex-2026.1.15-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:9d787e3310c6a6425eb346be4ff2ccf6eece63017916fd77fe8328c57be83521"}, {file = "regex-2026.2.28-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:5a932ea8ad5d0430351ff9c76c8db34db0d9f53c1d78f06022a21f4e290c5c18"},
{file = "regex-2026.1.15-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:619843841e220adca114118533a574a9cd183ed8a28b85627d2844c500a2b0db"}, {file = "regex-2026.2.28-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1c2c95e1a2b0f89d01e821ff4de1be4b5d73d1f4b0bf679fa27c1ad8d2327f1a"},
{file = "regex-2026.1.15-cp314-cp314t-win32.whl", hash = "sha256:e90b8db97f6f2c97eb045b51a6b2c5ed69cedd8392459e0642d4199b94fabd7e"}, {file = "regex-2026.2.28-cp314-cp314t-win32.whl", hash = "sha256:bbb882061f742eb5d46f2f1bd5304055be0a66b783576de3d7eef1bed4778a6e"},
{file = "regex-2026.1.15-cp314-cp314t-win_amd64.whl", hash = "sha256:5ef19071f4ac9f0834793af85bd04a920b4407715624e40cb7a0631a11137cdf"}, {file = "regex-2026.2.28-cp314-cp314t-win_amd64.whl", hash = "sha256:6591f281cb44dc13de9585b552cec6fc6cf47fb2fe7a48892295ee9bc4a612f9"},
{file = "regex-2026.1.15-cp314-cp314t-win_arm64.whl", hash = "sha256:ca89c5e596fc05b015f27561b3793dc2fa0917ea0d7507eebb448efd35274a70"}, {file = "regex-2026.2.28-cp314-cp314t-win_arm64.whl", hash = "sha256:dee50f1be42222f89767b64b283283ef963189da0dda4a515aa54a5563c62dec"},
{file = "regex-2026.1.15-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:55b4ea996a8e4458dd7b584a2f89863b1655dd3d17b88b46cbb9becc495a0ec5"}, {file = "regex-2026.2.28.tar.gz", hash = "sha256:a729e47d418ea11d03469f321aaf67cdee8954cde3ff2cf8403ab87951ad10f2"},
{file = "regex-2026.1.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e1e28be779884189cdd57735e997f282b64fd7ccf6e2eef3e16e57d7a34a815"},
{file = "regex-2026.1.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0057de9eaef45783ff69fa94ae9f0fd906d629d0bd4c3217048f46d1daa32e9b"},
{file = "regex-2026.1.15-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc7cd0b2be0f0269283a45c0d8b2c35e149d1319dcb4a43c9c3689fa935c1ee6"},
{file = "regex-2026.1.15-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8db052bbd981e1666f09e957f3790ed74080c2229007c1dd67afdbf0b469c48b"},
{file = "regex-2026.1.15-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:343db82cb3712c31ddf720f097ef17c11dab2f67f7a3e7be976c4f82eba4e6df"},
{file = "regex-2026.1.15-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:55e9d0118d97794367309635df398bdfd7c33b93e2fdfa0b239661cd74b4c14e"},
{file = "regex-2026.1.15-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:008b185f235acd1e53787333e5690082e4f156c44c87d894f880056089e9bc7c"},
{file = "regex-2026.1.15-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fd65af65e2aaf9474e468f9e571bd7b189e1df3a61caa59dcbabd0000e4ea839"},
{file = "regex-2026.1.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f42e68301ff4afee63e365a5fc302b81bb8ba31af625a671d7acb19d10168a8c"},
{file = "regex-2026.1.15-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:f7792f27d3ee6e0244ea4697d92b825f9a329ab5230a78c1a68bd274e64b5077"},
{file = "regex-2026.1.15-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:dbaf3c3c37ef190439981648ccbf0c02ed99ae066087dd117fcb616d80b010a4"},
{file = "regex-2026.1.15-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:adc97a9077c2696501443d8ad3fa1b4fc6d131fc8fd7dfefd1a723f89071cf0a"},
{file = "regex-2026.1.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:069f56a7bf71d286a6ff932a9e6fb878f151c998ebb2519a9f6d1cee4bffdba3"},
{file = "regex-2026.1.15-cp39-cp39-win32.whl", hash = "sha256:ea4e6b3566127fda5e007e90a8fd5a4169f0cf0619506ed426db647f19c8454a"},
{file = "regex-2026.1.15-cp39-cp39-win_amd64.whl", hash = "sha256:cda1ed70d2b264952e88adaa52eea653a33a1b98ac907ae2f86508eb44f65cdc"},
{file = "regex-2026.1.15-cp39-cp39-win_arm64.whl", hash = "sha256:b325d4714c3c48277bfea1accd94e193ad6ed42b4bad79ad64f3b8f8a31260a5"},
{file = "regex-2026.1.15.tar.gz", hash = "sha256:164759aa25575cbc0651bef59a0b18353e54300d79ace8084c818ad8ac72b7d5"},
] ]
[[package]] [[package]]
@@ -660,13 +643,13 @@ files = [
[[package]] [[package]]
name = "whitenoise" name = "whitenoise"
version = "6.11.0" version = "6.12.0"
description = "Radically simplified static file serving for WSGI applications" description = "Radically simplified static file serving for WSGI applications"
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.10"
files = [ files = [
{file = "whitenoise-6.11.0-py3-none-any.whl", hash = "sha256:b2aeb45950597236f53b5342b3121c5de69c8da0109362aee506ce88e022d258"}, {file = "whitenoise-6.12.0-py3-none-any.whl", hash = "sha256:fc5e8c572e33ebf24795b47b6a7da8da3c00cff2349f5b04c02f28d0cc5a3cc2"},
{file = "whitenoise-6.11.0.tar.gz", hash = "sha256:0f5bfce6061ae6611cd9396a8231e088722e4fc67bc13a111be74c738d99375f"}, {file = "whitenoise-6.12.0.tar.gz", hash = "sha256:f723ebb76a112e98816ff80fcea0a6c9b8ecde835f8ddda25df7a30a3c2db6ad"},
] ]
[package.extras] [package.extras]
@@ -675,4 +658,4 @@ brotli = ["brotli"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.12" python-versions = "^3.12"
content-hash = "64c804553b6314e8f8f5830637781a3179fd70f14cceb6730bfcb2cf24c91a31" content-hash = "fb71f5e7011418134e09152004d990412cf923433f675398e5e99439bf9653b9"
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+1 -53
View File
@@ -1,53 +1 @@
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="50" height="46" viewBox="0 0 1512 1386" shape-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd"><defs><linearGradient id="A" gradientUnits="userSpaceOnUse" x1="1476.52" y1="1395.4" x2="1034.86" y2="872.762"><stop offset="0" stop-color="#ef7f1a"></stop><stop offset=".349" stop-color="#ffed00"></stop><stop offset=".949" stop-color="#cc6f3c"></stop></linearGradient><linearGradient id="B" gradientUnits="userSpaceOnUse" x1="1023.98" y1="1127.45" x2="575.667" y2="596.929"><stop offset="0" stop-color="#ef7f1a"></stop><stop offset=".059" stop-color="#cc6f3c"></stop><stop offset=".671" stop-color="#ffed00"></stop><stop offset="1" stop-color="#cc6f3c"></stop></linearGradient><linearGradient id="C" href="#A" x1="1398.9" y1="1160.31" x2="613.548" y2="230.976"></linearGradient><linearGradient id="D" href="#A" x1="805.595" y1="948.571" x2="21.024" y2="20.143"></linearGradient><linearGradient id="E" gradientUnits="userSpaceOnUse" x1="381.071" y1="958.69" x2="89.071" y2="613.119"><stop offset="0" stop-color="#ef7f1a"></stop><stop offset=".831" stop-color="#ffed00"></stop><stop offset=".949" stop-color="#cc6f3c"></stop></linearGradient></defs><path d="M746 677L405 970c21-19 37-44 49-75 14-37 20-83 20-137 0-47-6-92-19-135s-32-82-58-118-57-67-95-95c-38-27-84-50-139-68L27 298c-6-2-12-2-18 1-1 0-2 1-3 2L351 5c1-1 2-2 4-2 6-3 12-3 18-1l136 44c55 18 101 41 139 68s69 59 95 95c25 36 45 75 58 118s19 88 19 135c0 54-7 100-20 137-12 34-30 60-53 79z" fill="url(#D)"></path><path d="M1005 1173c12-10 22-22 30-35 10-16 18-34 25-54 6-20 11-41 14-65 3-23 4-48 4-73 0-50-6-97-17-141-12-44-29-83-51-119-23-35-51-66-85-92s-74-47-119-62c-48-16-90-22-126-17-36 4-66 17-91 40l345-295c24-22 54-34 90-39 36-4 78 2 126 17 45 15 85 35 119 62 34 26 63 57 85 92 23 35 40 75 51 119s17 90 17 141c0 26-2 50-4 73-3 23-8 45-14 65s-15 38-25 54c-9 14-20 27-33 37l-341 292z" fill="url(#C)"></path><path d="M409 739c0-38-5-74-14-109-10-35-24-68-44-97-20-30-45-56-75-79s-69-42-116-58l-99-33v538l100 33c44 14 81 21 111 20s56-9 76-25 35-40 46-71c10-31 15-71 15-118zm65 18c0 54-7 100-20 137-14 37-34 65-60 84-27 19-59 30-98 31s-86-7-140-24L29 943c-6-2-12-6-18-13S1 914 1 902V319c0-12 3-19 10-22 6-3 12-3 18-1l136 44c55 18 101 41 139 68s69 59 95 95c25 36 45 75 58 118s19 88 19 135z" fill="#ae4a84" fill-rule="nonzero"></path><path d="M1343 884l-333 285c-3 3-7 6-10 9 26 30 49 54 68 73l48 43c13 10 22 18 29 23s12 9 15 13 5 8 6 13 2 10 2 17c0 5 0 10-1 13s-2 6-4 8l-2 2 344-294c1 0 1-1 2-2 2-2 3-5 4-8 1-4 1-8 1-13 0-7-1-12-2-17s-3-9-6-13-8-8-15-13-17-13-29-23c-13-10-29-25-48-43-20-19-42-43-68-73z" fill="url(#A)"></path><path d="M1015 931c0-38-4-75-11-111s-19-69-36-99-38-57-66-80c-27-23-61-41-102-54-40-13-74-17-101-11-28 6-50 18-67 38-17 19-29 44-37 75s-11 65-11 101c0 39 3 77 10 113s18 69 35 99c16 30 38 57 66 80 27 23 62 41 103 55 41 13 75 17 103 11s50-19 67-39 29-45 36-76 11-65 11-102zm153 430c0 5 0 10-1 13s-2 6-4 8-3 3-5 3c-2 1-3 0-5 0-4-1-12-7-26-16-13-10-29-22-48-39-19-16-39-35-61-57s-44-46-66-72c-17 6-39 9-65 9-27 0-58-6-94-18-48-16-89-37-124-63-35-27-63-57-85-93-22-35-38-75-49-119-10-44-16-91-16-142s6-95 18-132 29-67 53-88 53-34 89-38 78 2 126 17c45 15 85 35 119 62 34 26 63 57 85 92 23 35 40 75 51 119s17 90 17 141c0 26-2 50-4 73-3 23-8 45-14 65s-15 38-25 54-22 29-36 40c26 30 49 54 68 73l48 43c13 10 22 18 29 23s12 9 15 13 5 8 6 13 2 10 2 17z" fill="#ae4a84" fill-rule="nonzero"></path><path d="M1015 931c0-38-4-75-11-111s-19-69-36-99-38-57-66-80c-27-23-61-41-102-54-40-13-74-17-101-11-28 6-50 18-67 38-17 19-29 44-37 75s-11 65-11 101c0 39 3 77 10 113s18 69 35 99c16 30 38 57 66 80 27 23 62 41 103 55 41 13 75 17 103 11s50-19 67-39 29-45 36-76 11-65 11-102z" fill="url(#B)"></path><path d="M61 900l330-283c1 4 2 8 4 12 9 35 14 72 14 109 0 48-5 87-15 118s-25 55-46 71c-20 16-45 24-76 25s-67-6-111-20L61 899z" fill="url(#E)"></path><path d="M61 900l330-283c-9-31-23-59-40-85-20-30-45-56-75-79s-69-42-116-58l-99-33v538z" fill="#ffd900"></path></svg>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Creator: CorelDRAW X6 -->
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="120px" height="120px" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 1512 1386"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style type="text/css">
<![CDATA[
.fil6 {fill:#FFD900}
.fil2 {fill:#AE4A84;fill-rule:nonzero}
.fil3 {fill:url(#id0)}
.fil4 {fill:url(#id1)}
.fil1 {fill:url(#id2)}
.fil0 {fill:url(#id3)}
.fil5 {fill:url(#id4)}
]]>
</style>
<linearGradient id="id0" gradientUnits="userSpaceOnUse" x1="1476.52" y1="1395.4" x2="1034.86" y2="872.762">
<stop offset="0" style="stop-color:#EF7F1A"/>
<stop offset="0.34902" style="stop-color:#FFED00"/>
<stop offset="0.94902" style="stop-color:#CC6F3C"/>
<stop offset="1" style="stop-color:#CC6F3C"/>
</linearGradient>
<linearGradient id="id1" gradientUnits="userSpaceOnUse" x1="1023.98" y1="1127.45" x2="575.667" y2="596.929">
<stop offset="0" style="stop-color:#EF7F1A"/>
<stop offset="0.0588235" style="stop-color:#CC6F3C"/>
<stop offset="0.670588" style="stop-color:#FFED00"/>
<stop offset="1" style="stop-color:#CC6F3C"/>
</linearGradient>
<linearGradient id="id2" gradientUnits="userSpaceOnUse" xlink:href="#id0" x1="1398.9" y1="1160.31" x2="613.548" y2="230.976">
</linearGradient>
<linearGradient id="id3" gradientUnits="userSpaceOnUse" xlink:href="#id0" x1="805.595" y1="948.571" x2="21.0238" y2="20.1429">
</linearGradient>
<linearGradient id="id4" gradientUnits="userSpaceOnUse" x1="381.071" y1="958.69" x2="89.0714" y2="613.119">
<stop offset="0" style="stop-color:#EF7F1A"/>
<stop offset="0.831373" style="stop-color:#FFED00"/>
<stop offset="0.94902" style="stop-color:#CC6F3C"/>
<stop offset="1" style="stop-color:#CC6F3C"/>
</linearGradient>
</defs>
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<path class="fil0" d="M746 677l-341 293c21,-19 37,-44 49,-75 14,-37 20,-83 20,-137 0,-47 -6,-92 -19,-135 -13,-43 -32,-82 -58,-118 -26,-36 -57,-67 -95,-95 -38,-27 -84,-50 -139,-68l-136 -44c-6,-2 -12,-2 -18,1 -1,0 -2,1 -3,2l345 -296c1,-1 2,-2 4,-2 6,-3 12,-3 18,-1l136 44c55,18 101,41 139,68 38,27 69,59 95,95 25,36 45,75 58,118 13,43 19,88 19,135 0,54 -7,100 -20,137 -12,34 -30,60 -53,79z"/>
<path class="fil1" d="M1005 1173c12,-10 22,-22 30,-35 10,-16 18,-34 25,-54 6,-20 11,-41 14,-65 3,-23 4,-48 4,-73 0,-50 -6,-97 -17,-141 -12,-44 -29,-83 -51,-119 -23,-35 -51,-66 -85,-92 -34,-26 -74,-47 -119,-62 -48,-16 -90,-22 -126,-17 -36,4 -66,17 -91,40l345 -295c24,-22 54,-34 90,-39 36,-4 78,2 126,17 45,15 85,35 119,62 34,26 63,57 85,92 23,35 40,75 51,119 11,44 17,90 17,141 0,26 -2,50 -4,73 -3,23 -8,45 -14,65 -6,20 -15,38 -25,54 -9,14 -20,27 -33,37l-341 292z"/>
<path class="fil2" d="M409 739c0,-38 -5,-74 -14,-109 -10,-35 -24,-68 -44,-97 -20,-30 -45,-56 -75,-79 -30,-23 -69,-42 -116,-58l-99 -33 0 538 100 33c44,14 81,21 111,20 30,-1 56,-9 76,-25 20,-16 35,-40 46,-71 10,-31 15,-71 15,-118zm65 18c0,54 -7,100 -20,137 -14,37 -34,65 -60,84 -27,19 -59,30 -98,31 -39,1 -86,-7 -140,-24l-127 -42c-6,-2 -12,-6 -18,-13 -6,-7 -10,-16 -10,-28l0 -583c0,-12 3,-19 10,-22 6,-3 12,-3 18,-1l136 44c55,18 101,41 139,68 38,27 69,59 95,95 25,36 45,75 58,118 13,43 19,88 19,135z"/>
<path class="fil3" d="M1343 884l-333 285c-3,3 -7,6 -10,9 26,30 49,54 68,73 20,18 36,33 48,43 13,10 22,18 29,23 7,5 12,9 15,13 3,4 5,8 6,13 1,5 2,10 2,17 0,5 0,10 -1,13 -1,3 -2,6 -4,8 -1,1 -1,1 -2,2l344 -294c1,0 1,-1 2,-2 2,-2 3,-5 4,-8 1,-4 1,-8 1,-13 0,-7 -1,-12 -2,-17 -1,-5 -3,-9 -6,-13 -3,-4 -8,-8 -15,-13 -7,-5 -17,-13 -29,-23 -13,-10 -29,-25 -48,-43 -20,-19 -42,-43 -68,-73z"/>
<path class="fil2" d="M1015 931c0,-38 -4,-75 -11,-111 -7,-36 -19,-69 -36,-99 -17,-30 -38,-57 -66,-80 -27,-23 -61,-41 -102,-54 -40,-13 -74,-17 -101,-11 -28,6 -50,18 -67,38 -17,19 -29,44 -37,75 -8,31 -11,65 -11,101 0,39 3,77 10,113 7,36 18,69 35,99 16,30 38,57 66,80 27,23 62,41 103,55 41,13 75,17 103,11 28,-6 50,-19 67,-39 17,-20 29,-45 36,-76 7,-31 11,-65 11,-102zm153 430c0,5 0,10 -1,13 -1,3 -2,6 -4,8 -2,2 -3,3 -5,3 -2,1 -3,0 -5,0 -4,-1 -12,-7 -26,-16 -13,-10 -29,-22 -48,-39 -19,-16 -39,-35 -61,-57 -22,-22 -44,-46 -66,-72 -17,6 -39,9 -65,9 -27,0 -58,-6 -94,-18 -48,-16 -89,-37 -124,-63 -35,-27 -63,-57 -85,-93 -22,-35 -38,-75 -49,-119 -10,-44 -16,-91 -16,-142 0,-51 6,-95 18,-132 12,-37 29,-67 53,-88 24,-21 53,-34 89,-38 36,-4 78,2 126,17 45,15 85,35 119,62 34,26 63,57 85,92 23,35 40,75 51,119 11,44 17,90 17,141 0,26 -2,50 -4,73 -3,23 -8,45 -14,65 -6,20 -15,38 -25,54 -10,16 -22,29 -36,40 26,30 49,54 68,73 20,18 36,33 48,43 13,10 22,18 29,23 7,5 12,9 15,13 3,4 5,8 6,13 1,5 2,10 2,17z"/>
<path class="fil4" d="M1015 931c0,-38 -4,-75 -11,-111 -7,-36 -19,-69 -36,-99 -17,-30 -38,-57 -66,-80 -27,-23 -61,-41 -102,-54 -40,-13 -74,-17 -101,-11 -28,6 -50,18 -67,38 -17,19 -29,44 -37,75 -8,31 -11,65 -11,101 0,39 3,77 10,113 7,36 18,69 35,99 16,30 38,57 66,80 27,23 62,41 103,55 41,13 75,17 103,11 28,-6 50,-19 67,-39 17,-20 29,-45 36,-76 7,-31 11,-65 11,-102z"/>
<path class="fil5" d="M61 900l330 -283c1,4 2,8 4,12 9,35 14,72 14,109 0,48 -5,87 -15,118 -10,31 -25,55 -46,71 -20,16 -45,24 -76,25 -31,1 -67,-6 -111,-20l-100 -33z"/>
<path class="fil6" d="M61 900l330 -283c-9,-31 -23,-59 -40,-85 -20,-30 -45,-56 -75,-79 -30,-23 -69,-42 -116,-58l-99 -33 0 538z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

+23
View File
@@ -0,0 +1,23 @@
{
"name": "DicQuo",
"short_name": "DicQuo",
"description": "Коллекция цитат и афоризмов.",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#ffffff",
"icons": [
{
"src": "/favicon.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/web-app-manifest-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
}
+6
View File
@@ -302,6 +302,12 @@ footer button:hover {
main > article > div > div > div > img { main > article > div > div > div > img {
height: 36vmax; height: 36vmax;
} }
/* Для мобильных путь иконка будет поменьше и поскромнее */
header > #logo a > img {
width:25px;
height:23px;
}
} }
/* --- ВЫРАВНИВАНИЕ СИМВОЛОВ ВИСЯЧЕЙ ПУНКТУАЦИИ (Hanging Punctuation) ТИПОГРАФА ETPGRF --- */ /* --- ВЫРАВНИВАНИЕ СИМВОЛОВ ВИСЯЧЕЙ ПУНКТУАЦИИ (Hanging Punctuation) ТИПОГРАФА ETPGRF --- */
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

+1 -53
View File
@@ -1,53 +1 @@
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="50" height="46" viewBox="0 0 1512 1386" shape-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd"><defs><linearGradient id="A" gradientUnits="userSpaceOnUse" x1="1476.52" y1="1395.4" x2="1034.86" y2="872.762"><stop offset="0" stop-color="#ef7f1a"/><stop offset=".349" stop-color="#ffed00"/><stop offset=".949" stop-color="#cc6f3c"/></linearGradient><linearGradient id="B" gradientUnits="userSpaceOnUse" x1="1023.98" y1="1127.45" x2="575.667" y2="596.929"><stop offset="0" stop-color="#ef7f1a"/><stop offset=".059" stop-color="#cc6f3c"/><stop offset=".671" stop-color="#ffed00"/><stop offset="1" stop-color="#cc6f3c"/></linearGradient><linearGradient id="C" href="#A" x1="1398.9" y1="1160.31" x2="613.548" y2="230.976"/><linearGradient id="D" href="#A" x1="805.595" y1="948.571" x2="21.024" y2="20.143"/><linearGradient id="E" gradientUnits="userSpaceOnUse" x1="381.071" y1="958.69" x2="89.071" y2="613.119"><stop offset="0" stop-color="#ef7f1a"/><stop offset=".831" stop-color="#ffed00"/><stop offset=".949" stop-color="#cc6f3c"/></linearGradient></defs><path d="M746 677L405 970c21-19 37-44 49-75 14-37 20-83 20-137 0-47-6-92-19-135s-32-82-58-118-57-67-95-95c-38-27-84-50-139-68L27 298c-6-2-12-2-18 1-1 0-2 1-3 2L351 5c1-1 2-2 4-2 6-3 12-3 18-1l136 44c55 18 101 41 139 68s69 59 95 95c25 36 45 75 58 118s19 88 19 135c0 54-7 100-20 137-12 34-30 60-53 79z" fill="url(#D)"/><path d="M1005 1173c12-10 22-22 30-35 10-16 18-34 25-54 6-20 11-41 14-65 3-23 4-48 4-73 0-50-6-97-17-141-12-44-29-83-51-119-23-35-51-66-85-92s-74-47-119-62c-48-16-90-22-126-17-36 4-66 17-91 40l345-295c24-22 54-34 90-39 36-4 78 2 126 17 45 15 85 35 119 62 34 26 63 57 85 92 23 35 40 75 51 119s17 90 17 141c0 26-2 50-4 73-3 23-8 45-14 65s-15 38-25 54c-9 14-20 27-33 37l-341 292z" fill="url(#C)"/><path d="M409 739c0-38-5-74-14-109-10-35-24-68-44-97-20-30-45-56-75-79s-69-42-116-58l-99-33v538l100 33c44 14 81 21 111 20s56-9 76-25 35-40 46-71c10-31 15-71 15-118zm65 18c0 54-7 100-20 137-14 37-34 65-60 84-27 19-59 30-98 31s-86-7-140-24L29 943c-6-2-12-6-18-13S1 914 1 902V319c0-12 3-19 10-22 6-3 12-3 18-1l136 44c55 18 101 41 139 68s69 59 95 95c25 36 45 75 58 118s19 88 19 135z" fill="#ae4a84" fill-rule="nonzero"/><path d="M1343 884l-333 285c-3 3-7 6-10 9 26 30 49 54 68 73l48 43c13 10 22 18 29 23s12 9 15 13 5 8 6 13 2 10 2 17c0 5 0 10-1 13s-2 6-4 8l-2 2 344-294c1 0 1-1 2-2 2-2 3-5 4-8 1-4 1-8 1-13 0-7-1-12-2-17s-3-9-6-13-8-8-15-13-17-13-29-23c-13-10-29-25-48-43-20-19-42-43-68-73z" fill="url(#A)"/><path d="M1015 931c0-38-4-75-11-111s-19-69-36-99-38-57-66-80c-27-23-61-41-102-54-40-13-74-17-101-11-28 6-50 18-67 38-17 19-29 44-37 75s-11 65-11 101c0 39 3 77 10 113s18 69 35 99c16 30 38 57 66 80 27 23 62 41 103 55 41 13 75 17 103 11s50-19 67-39 29-45 36-76 11-65 11-102zm153 430c0 5 0 10-1 13s-2 6-4 8-3 3-5 3c-2 1-3 0-5 0-4-1-12-7-26-16-13-10-29-22-48-39-19-16-39-35-61-57s-44-46-66-72c-17 6-39 9-65 9-27 0-58-6-94-18-48-16-89-37-124-63-35-27-63-57-85-93-22-35-38-75-49-119-10-44-16-91-16-142s6-95 18-132 29-67 53-88 53-34 89-38 78 2 126 17c45 15 85 35 119 62 34 26 63 57 85 92 23 35 40 75 51 119s17 90 17 141c0 26-2 50-4 73-3 23-8 45-14 65s-15 38-25 54-22 29-36 40c26 30 49 54 68 73l48 43c13 10 22 18 29 23s12 9 15 13 5 8 6 13 2 10 2 17z" fill="#ae4a84" fill-rule="nonzero"/><path d="M1015 931c0-38-4-75-11-111s-19-69-36-99-38-57-66-80c-27-23-61-41-102-54-40-13-74-17-101-11-28 6-50 18-67 38-17 19-29 44-37 75s-11 65-11 101c0 39 3 77 10 113s18 69 35 99c16 30 38 57 66 80 27 23 62 41 103 55 41 13 75 17 103 11s50-19 67-39 29-45 36-76 11-65 11-102z" fill="url(#B)"/><path d="M61 900l330-283c1 4 2 8 4 12 9 35 14 72 14 109 0 48-5 87-15 118s-25 55-46 71c-20 16-45 24-76 25s-67-6-111-20L61 899z" fill="url(#E)"/><path d="M61 900l330-283c-9-31-23-59-40-85-20-30-45-56-75-79s-69-42-116-58l-99-33v538z" fill="#ffd900"/></svg>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Creator: CorelDRAW X6 -->
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="50px" height="46px" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 1512 1386"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style type="text/css">
<![CDATA[
.fil6 {fill:#FFD900}
.fil2 {fill:#AE4A84;fill-rule:nonzero}
.fil3 {fill:url(#id0)}
.fil4 {fill:url(#id1)}
.fil1 {fill:url(#id2)}
.fil0 {fill:url(#id3)}
.fil5 {fill:url(#id4)}
]]>
</style>
<linearGradient id="id0" gradientUnits="userSpaceOnUse" x1="1476.52" y1="1395.4" x2="1034.86" y2="872.762">
<stop offset="0" style="stop-color:#EF7F1A"/>
<stop offset="0.34902" style="stop-color:#FFED00"/>
<stop offset="0.94902" style="stop-color:#CC6F3C"/>
<stop offset="1" style="stop-color:#CC6F3C"/>
</linearGradient>
<linearGradient id="id1" gradientUnits="userSpaceOnUse" x1="1023.98" y1="1127.45" x2="575.667" y2="596.929">
<stop offset="0" style="stop-color:#EF7F1A"/>
<stop offset="0.0588235" style="stop-color:#CC6F3C"/>
<stop offset="0.670588" style="stop-color:#FFED00"/>
<stop offset="1" style="stop-color:#CC6F3C"/>
</linearGradient>
<linearGradient id="id2" gradientUnits="userSpaceOnUse" xlink:href="#id0" x1="1398.9" y1="1160.31" x2="613.548" y2="230.976">
</linearGradient>
<linearGradient id="id3" gradientUnits="userSpaceOnUse" xlink:href="#id0" x1="805.595" y1="948.571" x2="21.0238" y2="20.1429">
</linearGradient>
<linearGradient id="id4" gradientUnits="userSpaceOnUse" x1="381.071" y1="958.69" x2="89.0714" y2="613.119">
<stop offset="0" style="stop-color:#EF7F1A"/>
<stop offset="0.831373" style="stop-color:#FFED00"/>
<stop offset="0.94902" style="stop-color:#CC6F3C"/>
<stop offset="1" style="stop-color:#CC6F3C"/>
</linearGradient>
</defs>
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<path class="fil0" d="M746 677l-341 293c21,-19 37,-44 49,-75 14,-37 20,-83 20,-137 0,-47 -6,-92 -19,-135 -13,-43 -32,-82 -58,-118 -26,-36 -57,-67 -95,-95 -38,-27 -84,-50 -139,-68l-136 -44c-6,-2 -12,-2 -18,1 -1,0 -2,1 -3,2l345 -296c1,-1 2,-2 4,-2 6,-3 12,-3 18,-1l136 44c55,18 101,41 139,68 38,27 69,59 95,95 25,36 45,75 58,118 13,43 19,88 19,135 0,54 -7,100 -20,137 -12,34 -30,60 -53,79z"/>
<path class="fil1" d="M1005 1173c12,-10 22,-22 30,-35 10,-16 18,-34 25,-54 6,-20 11,-41 14,-65 3,-23 4,-48 4,-73 0,-50 -6,-97 -17,-141 -12,-44 -29,-83 -51,-119 -23,-35 -51,-66 -85,-92 -34,-26 -74,-47 -119,-62 -48,-16 -90,-22 -126,-17 -36,4 -66,17 -91,40l345 -295c24,-22 54,-34 90,-39 36,-4 78,2 126,17 45,15 85,35 119,62 34,26 63,57 85,92 23,35 40,75 51,119 11,44 17,90 17,141 0,26 -2,50 -4,73 -3,23 -8,45 -14,65 -6,20 -15,38 -25,54 -9,14 -20,27 -33,37l-341 292z"/>
<path class="fil2" d="M409 739c0,-38 -5,-74 -14,-109 -10,-35 -24,-68 -44,-97 -20,-30 -45,-56 -75,-79 -30,-23 -69,-42 -116,-58l-99 -33 0 538 100 33c44,14 81,21 111,20 30,-1 56,-9 76,-25 20,-16 35,-40 46,-71 10,-31 15,-71 15,-118zm65 18c0,54 -7,100 -20,137 -14,37 -34,65 -60,84 -27,19 -59,30 -98,31 -39,1 -86,-7 -140,-24l-127 -42c-6,-2 -12,-6 -18,-13 -6,-7 -10,-16 -10,-28l0 -583c0,-12 3,-19 10,-22 6,-3 12,-3 18,-1l136 44c55,18 101,41 139,68 38,27 69,59 95,95 25,36 45,75 58,118 13,43 19,88 19,135z"/>
<path class="fil3" d="M1343 884l-333 285c-3,3 -7,6 -10,9 26,30 49,54 68,73 20,18 36,33 48,43 13,10 22,18 29,23 7,5 12,9 15,13 3,4 5,8 6,13 1,5 2,10 2,17 0,5 0,10 -1,13 -1,3 -2,6 -4,8 -1,1 -1,1 -2,2l344 -294c1,0 1,-1 2,-2 2,-2 3,-5 4,-8 1,-4 1,-8 1,-13 0,-7 -1,-12 -2,-17 -1,-5 -3,-9 -6,-13 -3,-4 -8,-8 -15,-13 -7,-5 -17,-13 -29,-23 -13,-10 -29,-25 -48,-43 -20,-19 -42,-43 -68,-73z"/>
<path class="fil2" d="M1015 931c0,-38 -4,-75 -11,-111 -7,-36 -19,-69 -36,-99 -17,-30 -38,-57 -66,-80 -27,-23 -61,-41 -102,-54 -40,-13 -74,-17 -101,-11 -28,6 -50,18 -67,38 -17,19 -29,44 -37,75 -8,31 -11,65 -11,101 0,39 3,77 10,113 7,36 18,69 35,99 16,30 38,57 66,80 27,23 62,41 103,55 41,13 75,17 103,11 28,-6 50,-19 67,-39 17,-20 29,-45 36,-76 7,-31 11,-65 11,-102zm153 430c0,5 0,10 -1,13 -1,3 -2,6 -4,8 -2,2 -3,3 -5,3 -2,1 -3,0 -5,0 -4,-1 -12,-7 -26,-16 -13,-10 -29,-22 -48,-39 -19,-16 -39,-35 -61,-57 -22,-22 -44,-46 -66,-72 -17,6 -39,9 -65,9 -27,0 -58,-6 -94,-18 -48,-16 -89,-37 -124,-63 -35,-27 -63,-57 -85,-93 -22,-35 -38,-75 -49,-119 -10,-44 -16,-91 -16,-142 0,-51 6,-95 18,-132 12,-37 29,-67 53,-88 24,-21 53,-34 89,-38 36,-4 78,2 126,17 45,15 85,35 119,62 34,26 63,57 85,92 23,35 40,75 51,119 11,44 17,90 17,141 0,26 -2,50 -4,73 -3,23 -8,45 -14,65 -6,20 -15,38 -25,54 -10,16 -22,29 -36,40 26,30 49,54 68,73 20,18 36,33 48,43 13,10 22,18 29,23 7,5 12,9 15,13 3,4 5,8 6,13 1,5 2,10 2,17z"/>
<path class="fil4" d="M1015 931c0,-38 -4,-75 -11,-111 -7,-36 -19,-69 -36,-99 -17,-30 -38,-57 -66,-80 -27,-23 -61,-41 -102,-54 -40,-13 -74,-17 -101,-11 -28,6 -50,18 -67,38 -17,19 -29,44 -37,75 -8,31 -11,65 -11,101 0,39 3,77 10,113 7,36 18,69 35,99 16,30 38,57 66,80 27,23 62,41 103,55 41,13 75,17 103,11 28,-6 50,-19 67,-39 17,-20 29,-45 36,-76 7,-31 11,-65 11,-102z"/>
<path class="fil5" d="M61 900l330 -283c1,4 2,8 4,12 9,35 14,72 14,109 0,48 -5,87 -15,118 -10,31 -25,55 -46,71 -20,16 -45,24 -76,25 -31,1 -67,-6 -111,-20l-100 -33z"/>
<path class="fil6" d="M61 900l330 -283c-9,-31 -23,-59 -40,-85 -20,-30 -45,-56 -75,-79 -30,-23 -69,-42 -116,-58l-99 -33 0 538z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

+2 -2
View File
@@ -12,8 +12,8 @@ django = "^6.0.2"
django-taggit = "^6.1.0" django-taggit = "^6.1.0"
pillow = "^12.1.1" pillow = "^12.1.1"
pytils = "^0.4.4" pytils = "^0.4.4"
etpgrf = "0.1.6" etpgrf = "^0.1.6"
django-environ = "^0.12.1" django-environ = "^0.13.0"
whitenoise = "^6.11.0" whitenoise = "^6.11.0"
gunicorn = "^25.1.0" gunicorn = "^25.1.0"
tqdm = "^4.67.3" tqdm = "^4.67.3"