From 67ce2af066a6675bf4ba1b1fe4d9e26b1d9e8ed5 Mon Sep 17 00:00:00 2001
From: Madara <122021584+Dina-Tolkina@users.noreply.github.com>
Date: Wed, 21 Feb 2024 12:58:40 +0300
Subject: [PATCH 01/31] Added media file settings
Added media file settings to settings.py and urls.py.
---
settings.py | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++
urls.py | 32 +++++++++++++
2 files changed, 166 insertions(+)
create mode 100644 settings.py
create mode 100644 urls.py
diff --git a/settings.py b/settings.py
new file mode 100644
index 0000000..5c0d8ad
--- /dev/null
+++ b/settings.py
@@ -0,0 +1,134 @@
+"""
+Django settings for config project.
+
+Generated by 'django-admin startproject' using Django 5.0.1.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.0/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/5.0/ref/settings/
+"""
+
+from pathlib import Path
+import os
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'django-insecure-)uwi$ei!p$_26*lkmjlv&&kzali)nq7b1y^ptq20kqxogwng&t'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+ 'petapp',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'config.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ 'django.template.context_processors.media',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'config.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.postgresql',
+ 'NAME': 'Pet_store',
+ 'USER': 'postgres',
+ 'PASSWORD': '111',
+ 'HOST': 'localhost',
+ 'PORT': 5432,
+ }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/5.0/topics/i18n/
+
+LANGUAGE_CODE = 'ru-ru'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/5.0/howto/static-files/
+
+STATIC_URL = 'static/'
+STATIC_ROOT = os.path.join(BASE_DIR, 'static')
+MEDIA_URL = "/media/"
+MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
+STATICFILELS_DIRS = []
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
diff --git a/urls.py b/urls.py
new file mode 100644
index 0000000..cfb222d
--- /dev/null
+++ b/urls.py
@@ -0,0 +1,32 @@
+"""
+URL configuration for config project.
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/5.0/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: path('', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
+Including another URLconf
+ 1. Import the include() function: from django.urls import include, path
+ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import path
+from config import settings
+from petapp import views
+from django.conf.urls.static import static
+
+urlpatterns = [
+ path('admin/', admin.site.urls),
+ path('', views.index, name='home'),
+ path('catalog/', views.catalog, name='catalog'),
+ path('contact/', views.contact, name='contact'),
+ path('about/', views.about, name='about'),
+ path('auth/', views.auth, name='auth'),
+ path('reg/', views.reg, name='reg'),
+ path('basket/', views.basket, name='basket'),
+] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
From e2f4eace140558e70c539bda5cf7409d17f91e0c Mon Sep 17 00:00:00 2001
From: Madara <122021584+Dina-Tolkina@users.noreply.github.com>
Date: Mon, 26 Feb 2024 19:56:47 +0300
Subject: [PATCH 02/31] Added the models and set up the admin.
Added models, signals, and admin customization for Customer, Product, Animal_type, Category, Basket, Order, OrderDetail, PurchaseHistory, Rating. Implemented image size validation for product photos. Created admin views for Customer and Product with custom display fields.
---
admin.py | 56 +++++++++++++++++
models.py | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 237 insertions(+)
create mode 100644 admin.py
create mode 100644 models.py
diff --git a/admin.py b/admin.py
new file mode 100644
index 0000000..9b0ca16
--- /dev/null
+++ b/admin.py
@@ -0,0 +1,56 @@
+from django.contrib import admin
+from .models import Basket, Customer, Product, Animal_type, Category, Order, OrderDetail, PurchaseHistory, Rating, BasketProduct
+from django.utils.safestring import mark_safe
+
+
+admin.site.site_header = "Страница администратора"
+admin.site.site_title = "Зоомагазин puffball"
+admin.site.index_title = "Администрирование сайта"
+
+
+class CustomerAdmin(admin.ModelAdmin):
+ list_display = ('get_last_name', 'get_first_name', 'phone', 'get_email', 'avatar_show')
+
+ def get_last_name(self, obj):
+ return obj.user.last_name
+ get_last_name.short_description = 'Фамилия'
+
+ def get_first_name(self, obj):
+ return obj.user.first_name
+ get_first_name.short_description = 'Имя'
+
+ def get_email(self, obj):
+ return obj.user.email
+ get_first_name.short_description = 'Электронная почта'
+
+ def avatar_show(self, obj):
+ if obj.photo_avatar:
+ return mark_safe("".format(obj.photo_avatar.url))
+ return "None"
+
+ avatar_show.__name__ = "Картинка"
+
+
+class ProductAdmin(admin.ModelAdmin):
+ list_display = ("product_name", "price", "availability", "stock", "image_show")
+ readonly_fields = ['availability']
+
+ def image_show(self, obj):
+ if obj.photo_product:
+ return mark_safe("
".format(obj.photo_product.url))
+ return "None"
+
+ image_show.__name__ = "Картинка"
+
+
+admin.site.register(Customer, CustomerAdmin)
+admin.site.register(Product, ProductAdmin)
+admin.site.register(Animal_type)
+admin.site.register(Category)
+admin.site.register(Basket)
+admin.site.register(BasketProduct)
+admin.site.register(Order)
+admin.site.register(OrderDetail)
+admin.site.register(PurchaseHistory)
+admin.site.register(Rating)
+
diff --git a/models.py b/models.py
new file mode 100644
index 0000000..761ce27
--- /dev/null
+++ b/models.py
@@ -0,0 +1,181 @@
+import uuid
+from PIL import Image
+from django.db import models
+from django.forms import ValidationError
+from phonenumber_field.modelfields import PhoneNumberField
+from django.core.validators import MaxValueValidator
+from decimal import Decimal
+from django.core.validators import RegexValidator
+from django.contrib.auth.models import User
+from django.db.models.signals import post_save
+from django.dispatch import receiver
+
+
+def validate_image_size(image):
+ max_width = 300
+ max_height = 400
+ img = Image.open(image)
+ if img.width > max_width or img.height > max_height:
+ raise ValidationError("Максимальные допустимые размеры изображения - 300x400 пикселей.")
+
+class Customer(models.Model):
+ user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, verbose_name = ("Пользователь"))
+ patronymic = models.CharField(max_length=30, unique=False,verbose_name = ("Отчество"), validators=[RegexValidator(r'^[a-zA-ZА-Яа-яЁё]+$', 'Разрешены только буквы.')])
+ phone = PhoneNumberField(unique=True, blank=False, verbose_name = ("Номер телефона"))
+ address = models.CharField(max_length=255, blank=True, verbose_name = ("Адрес"))
+ photo_avatar = models.ImageField(upload_to='customer/', blank=True, null=True, verbose_name = ("Фото пользователь"))
+
+ class Meta:
+ verbose_name = "Клиент"
+ verbose_name_plural = "Клиенты"
+ ordering = ['user__date_joined']
+
+ def __str__(self):
+ return f"{self.user.last_name} {self.user.first_name}"
+
+@receiver(post_save, sender=User)
+def create_user_profile(sender, instance, created, **kwargs):
+ if created:
+ Customer.objects.create(user=instance)
+
+@receiver(post_save, sender=User)
+def save_user_profile(sender, instance, **kwargs):
+ instance.customer.save()
+
+
+class Animal_type(models.Model):
+ name = models.CharField(max_length=255, verbose_name = ("Название"), validators=[RegexValidator(r'^[a-zA-ZА-Яа-яЁё]+$', 'Разрешены только буквы.')], unique=True)
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ verbose_name = "Тип животного"
+ verbose_name_plural = "Типы животных"
+
+
+class Category(models.Model):
+ name = models.CharField(max_length=255, unique=True, verbose_name = ("Название"))
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ verbose_name = "Категория"
+ verbose_name_plural = "Категории"
+
+
+class Product(models.Model):
+ product_name = models.CharField(max_length=255, unique=True, verbose_name = ("Название продукта"),)
+ price = models.PositiveIntegerField(default=0, verbose_name = ("Цена"))
+ description = models.TextField(verbose_name = ("Описание"))
+ category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name = ("Категория"))
+ manufacturer = models.CharField(max_length=100, verbose_name = ("Производитель"))
+ origin_country = models.CharField(max_length=100, verbose_name = ("Страна производитель"))
+ photo_product = models.ImageField(upload_to='products/', validators=[validate_image_size], verbose_name = ("Фото продукта"))
+ animal_type = models.ManyToManyField(Animal_type, related_name='products', verbose_name = ("Тип животного"))
+ weight = models.DecimalField(default=Decimal('0.0'), max_digits=10, decimal_places=2, verbose_name = ("Вес"))
+ availability = models.BooleanField(verbose_name = ("Наличие"))
+ stock = models.PositiveIntegerField(default=0, verbose_name = ("Склад"))
+
+ def save(self, *args, **kwargs):
+ if self.stock > 0:
+ self.availability = True
+ else:
+ self.availability = False
+ super(Product, self).save(*args, **kwargs)
+
+ def __str__(self):
+ return f"{self.product_name} - {self.price} р"
+
+ class Meta:
+ verbose_name = "Продукт"
+ verbose_name_plural = "Продукты"
+ ordering = ['-rating']
+
+
+class Basket(models.Model):
+ user = models.ForeignKey(Customer, on_delete=models.CASCADE, verbose_name = ("Пользователь"))
+ created_at = models.DateTimeField(auto_now_add=True, verbose_name = ("Дата создания"))
+
+ def __str__(self):
+ return f"Корзина: {self.user}"
+
+ class Meta:
+ verbose_name = ("Корзину")
+ verbose_name_plural = ("Корзины")
+
+
+class BasketProduct(models.Model):
+ basket = models.ForeignKey(Basket, on_delete=models.CASCADE, verbose_name = ("Корзина пользователя"))
+ product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name = ("Продукт"))
+ quantity = models.PositiveIntegerField(verbose_name = ("Количество"))
+
+ def __str__(self):
+ return f"{self.basket}: {self.product} - {self.quantity}"
+
+ class Meta:
+ verbose_name = "Корзина продуктов"
+ verbose_name_plural = "Корзины продуктов"
+
+
+class Order(models.Model):
+ customer = models.ForeignKey(Customer, on_delete=models.CASCADE, verbose_name = ("Пользователь"))
+ order_date = models.DateField(verbose_name = ("Дата заказа"))
+ shipping_address = models.TextField(verbose_name = ("Адрес доставки"))
+
+ def __str__(self):
+ return f"Заказ {self.id} от {self.customer}"
+
+ class Meta:
+ verbose_name = "Заказ"
+ verbose_name_plural = "Заказы"
+ ordering = ['-order_date']
+
+
+class OrderDetail(models.Model):
+ STATUS_CHOICES = [
+ ('created', 'Created'),
+ ('processing', 'Processing'),
+ ('paid', 'Paid'),
+ ('cancelled', 'Cancelled'),
+ ('error', 'Error'),
+ ]
+
+ order_number = models.UUIDField(default = uuid.uuid4, verbose_name = ("Номер заказа"))
+ order = models.OneToOneField(Order, related_name='details', on_delete=models.CASCADE, verbose_name = ("Заказ"))
+ basket = models.ForeignKey(Basket, on_delete=models.CASCADE, verbose_name = ("Корзина"))
+ payment_id = models.CharField(max_length=128, blank=True, verbose_name = ("Идентификатор платежа"))
+ created_at = models.DateTimeField(auto_now_add=True, verbose_name = ("Дата создания"))
+ updated_at = models.DateTimeField(auto_now=True, verbose_name = ("Обновлённая дата "))
+ status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='created', verbose_name = ("Статус"))
+
+ def __str__(self):
+ return f"Деталь {self.id} из заказа {self.order_id}"
+
+ class Meta:
+ verbose_name = "Детали заказа"
+ verbose_name_plural = "Детали заказов"
+ ordering = ['-order']
+
+
+class PurchaseHistory(models.Model):
+ user = models.ForeignKey(Customer, on_delete=models.CASCADE, verbose_name = ("Пользователь"))
+ order_number = models.ForeignKey(OrderDetail, on_delete=models.CASCADE, verbose_name = ("Номер заказа"))
+ created_at = models.DateTimeField(auto_now_add=True, verbose_name = ("Дата создания"))
+ basket = models.ForeignKey(Basket, on_delete=models.CASCADE, verbose_name = ("Корзина"))
+
+ class Meta:
+ verbose_name = "История покупок"
+ verbose_name_plural = "История покупки"
+
+
+class Rating(models.Model):
+ user = models.ForeignKey(Customer, on_delete=models.CASCADE, verbose_name = ("Пользователь"))
+ purchase_history = models.OneToOneField(PurchaseHistory, on_delete=models.CASCADE, primary_key=True, verbose_name = ("История покупок"))
+ product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name = ("Продукт"))
+ rating = models.PositiveSmallIntegerField(validators=[MaxValueValidator(5)], default=0, verbose_name = ("Рейтинг"))
+
+ class Meta:
+ verbose_name = "Рейтинги"
+ verbose_name_plural = "Рейтинг"
\ No newline at end of file
From b02a0ce595966100046c4651f3ec272b7c77ec15 Mon Sep 17 00:00:00 2001
From: Madara <122021584+Dina-Tolkina@users.noreply.github.com>
Date: Wed, 28 Feb 2024 03:29:52 +0300
Subject: [PATCH 03/31] I connected a DB to the catalog, user registration
Added form classes createUserForm, RegForm, CombinedForm and views catalog, reg with validation and rendering functions.
---
auth.html | 41 +++++++++++++++++++
catalog.html | 50 ++++++++++++++++++++++++
forms.py | 100 +++++++++++++++++++++++++++++++++++++++++++++++
reg.html | 47 ++++++++++++++++++++++
requirements.txt | Bin 164 -> 162 bytes
settings.py | 30 +++++++++++---
urls.py | 11 ++++--
views.py | 97 +++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 367 insertions(+), 9 deletions(-)
create mode 100644 auth.html
create mode 100644 catalog.html
create mode 100644 forms.py
create mode 100644 reg.html
create mode 100644 views.py
diff --git a/auth.html b/auth.html
new file mode 100644
index 0000000..119b148
--- /dev/null
+++ b/auth.html
@@ -0,0 +1,41 @@
+{% extends 'base.html' %}
+{% load static %}
+
+{% block head %}
+
+
+
+{% endblock %}
+
+{% block title %}Страница авторизации{% endblock %}
+
+
+{% block content %}
+
+
{{ message }}
+ {% else %} +{{ product.product_name }} / {{ product.category }} для + {% for animal_type in product.animal_type.all %} + {{ animal_type.name }} + {% endfor %} + {{ product.weight }} kg
+{{ message }}
- {% else %} -{{ product.product_name }} / {{ product.category }} для - {% for animal_type in product.animal_type.all %} - {{ animal_type.name }} - {% endfor %} - {{ product.weight }} kg
-
-
-
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-
- Wagg / Корм для собак 5kg
-{{ message }}
+ {% else %} +{{ product.product_name }} / {{ product.category }} для + {% for animal_type in product.animal_type.all %} + {{ animal_type.name }} + {% endfor %} + {{ product.weight }} kg
+
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+{% endblock %}
\ No newline at end of file
diff --git a/petapp/templates/petapp/reg.html b/petapp/templates/petapp/reg.html
new file mode 100644
index 0000000..db1357d
--- /dev/null
+++ b/petapp/templates/petapp/reg.html
@@ -0,0 +1,47 @@
+{% extends 'base.html' %}
+{% load static %}
+
+{% block head %}
+
+
+
+{% endblock %}
+
+{% block title %}Страница регистрации{% endblock %}
+
+
+{% block content %}
+
+ 4 заказа
+15.866 ₽
+4 заказа
+Получите уникальную возможность порадовать своих любимцев! Зарегистрируйтесь
- и получите на первую покупку 25% скидку. Кроме того, акция PuffGift дает возможность получать
первым
- уведомления о новинках и розыгрышах.
XF7 zx@FKJF%^S;l0!LHkZ$M-=NHx>FtyL>zj)&VguYpu9P%dX&x zSOo;ICaq*mu@$_}O#~9CEYntMHmZCHPOm}F%5W#nt(elZ>#{52)Jni eE_$`ZH`xn@&{5O&>|W~%fFOM#vp!C?f66g3o0uR^*s(@ptV z^ZJq XaLC{=h68^1+~KblZ{A+0LVvoFFW$R*_r9CzdkKFM-U2DSlW&w) zmm#fu^-GIujGC)ADSrfi4y)iVufvQju5GNMucgM*cggF9r8af?DJ#JF2>kdQjBkb_ zk;p+b9TEQ`LgeheFuO01eIdIqj32~>*znf)_LWY#UGB`c=YJEYe;1Qmqg%^AuKcj_ z;;|#n;QI9Ta_2$&!R~}3UJhHMg=_6=JKs3s1>8TieSU9rx;r|(JL8BKQ8Tf OgBIk`R7nP^Y!j5%U1AUb#2cXpmQ;#^>(Guxisx$20sxXx}jJI~wCcUK(o zV_Z+Zi0zH%yW{!Y?;P=ZU|}y)=w=G9=N26C^M6#uZl?J9@)wS{^ky=hjvh=2qO_IY fld@eYySubkobMLrouSVT&ZN@|k?&J12budD2fAas delta 653 zcmbO&bc9#qG%qg~0}yy me0UN^!R40N(9T%E9ZlF3bEb4gB)bRq 3GFa3Jp{WxFs*{7NL$*If1WlnRP@w`A1I5tPi38OsVNoZ6 zP?ydXB~&S?DV12u#K6E68swvpoS&DLnZB8cxtVG5Y}U-lqHOleewxCQm$Au9bEjk_ z=B4NBl@{d`7XhP~;TBs#YDr>2K@sa@0d{d$PM}Z`C=nEKg9siF!3!cl(Okq2A_RcM zEpDIz1&JjksYQ9kD;Yimg&2OxyI92(r55BDPu|Y1Bm)XBMj$Re03<#zGcq!MWa4LJ o`KrLcs5tpIdm`s_t%+I-%&xF#O|Il{;Q1iR&Ck@xT?C2_04r8u!vFvP diff --git a/config/__pycache__/wsgi.cpython-311.pyc b/config/__pycache__/wsgi.cpython-311.pyc index d9ca2c332ddd72b6f9dea2b8aea62f1e533aabd1..afbd93d81274b0e3f5b4fd3541403c0b92fec5a3 100644 GIT binary patch delta 20 acmZ3*x{8&1IWI340}zyN adt_5!DKe3 F6acju5n=!U delta 35 pcmeyx@`{D$G%qg~0}yy ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=S5Y9x)CY?P~0^Akk V*Bm1$<3i>(gs<>-lHrYMt2o@k*_G) WHI4tte82wsp83BxSH+3_XP8)Z|J8qnUxKT5t^d>be*f!x{(o7n>T}nh*qi^g z{x8P`*4uB*t_QX*-q9JY+ jPlJhduc3(=*J$7?b`` ka)B}XKZEk!?|%#APiikJ@f29RYSX-hZI0{8uK#o2{r=Yj`$^%R z4l;AU?)p(3y=~9dpStU$Q#STBU;k6j^;&!O$2yhmo3_V)o#g+i|FHZOpi&HP-22Y} z_Q$$(*N?i><}P*3Hu6hxx~a9G&(m(}jf)O4XYQ%&*ze3YIoaCdPGujP`2EYDO_wjq zjK5iy8oT|x;$7{k`CgY7HCX)a^^(;-7Cv2^>nTsx;)IjuuKs7>+EbI5c32=f=Cpe1 wEw=jLSWywibD7u7cTHQdYu!@$DI5PYtZ4Z5-TwL7k`hGlBD;}Tw*3E_0Fc<&YXATM literal 0 HcmV?d00001 diff --git a/media/customer/1611870_avatar.jpg b/media/customer/1611870_avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f2ccd9b070156822ecd0e9ecc2387cb4ee88c988 GIT binary patch literal 1204 zcmex= ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=S5wViXt50}kqn<{!{bBy-RoR$Q3mVPgWH`&rhwtu>n`C4?R zQgz#>D}4*fkAM1;nPX#~x%{5$nc$es%L-%<%Jh`Uef2-;etPGnb<%%hiffL44F1c@ zkd+zbx^H^Us*YtjHJ>J)mjAFkt15Kc^1O>@8a(?aIoPGzKi?X+ruuhpmG$vxZR$X^{E(aaD3X_^LgI$ z3t?v&L;_vmI0WRQYN(G^Rz&}EeO RZ5j)hR=%25l~u-{^PJ^V@84^(yfKR! zEVFa7KD+fqWo?_Z>G-E57kl2x?(Ox|@6an%F~}4veqYCPiHGI;mvz&+7#1$cT)p&$ Y4#T^ma*um!vi^z$FuIbD+5g`J0H27?Q2+n{ literal 0 HcmV?d00001 diff --git a/media/customer/1909392_avatar.jpg b/media/customer/1909392_avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b26de7bdc7b7e8ef774f11e36b1ead209cdcd26a GIT binary patch literal 1224 zcmex= ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=S5Y9x)CY?P~0^Akk V*Bm1$<3i>(gs<>-lHrYMt2o@k*_G) WHI4tte82wsp83BxSH+3_XP8)Z|J8qnUxKT5t^d>be*f!x{(o7n>T}nh*qi^g z{x8P`*4uB*t_QX*-q9JY+ jPlJhduc3(=*J$7?b`` ka)B}XKZEk!?|%#APiikJ@f29RYSX-hZI0{8uK#o2{r=Yj`$^%R z4l;AU?)p(3y=~9dpStU$Q#STBU;k6j^;&!O$2yhmo3_V)o#g+i|FHZOpi&HP-22Y} z_Q$$(*N?i><}P*3Hu6hxx~a9G&(m(}jf)O4XYQ%&*ze3YIoaCdPGujP`2EYDO_wjq zjK5iy8oT|x;$7{k`CgY7HCX)a^^(;-7Cv2^>nTsx;)IjuuKs7>+EbI5c32=f=Cpe1 wEw=jLSWywibD7u7cTHQdYu!@$DI5PYtZ4Z5-TwL7k`hGlBD;}Tw*3E_0Fc<&YXATM literal 0 HcmV?d00001 diff --git a/media/customer/2142738_avatar.jpg b/media/customer/2142738_avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8f9f2697d2cb8649637f2f96174c66ef1d7ecfc2 GIT binary patch literal 1234 zcmex= ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=5t_KL?05|0tV42! zmrp#p_x|6H_ 6Ph2vgAWU&i zovr4!I`zx>s)C(z;_3`uJI+78)L^EusEYv^uUz$?;e_1pe|w+&XSm=S^kMs-?rZ-U z!hxLL*sJwV_-p?C@uNp|*3b_~EiyZBs?hY>v_1nbVTM&eHG2@FrXO$o5aSGGB}C zRH| er{SsjA69<}U=weBpSok?q+3Nk z*Vb>Cd|h_`METad>*f#p@5Q~kuKjPF=fB|Br{!O1FIm9Ur2)rWv)2D &A PCt=Qv=*p=10BBSio0Naoks3F82K25BA5lmipS7TC;B}ZmM+q z_nNP5U7&-^-fdgU7rW`2MterMe_C>}=bh}{-qicAwj0OXx%cwXTivHUD$86SRu^8E z|63gU)bwJCn|r{i!>k@Blo~WMu3h`KD}*!W;p5c1`+pz#YFam|W8(ssfK`hb7#mov LC`umo|8D{SoHgwp literal 0 HcmV?d00001 diff --git a/media/customer/2354864_avatar.jpg b/media/customer/2354864_avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8f9f2697d2cb8649637f2f96174c66ef1d7ecfc2 GIT binary patch literal 1234 zcmex= ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=5t_KL?05|0tV42! zmrp#p_x|6H_ 6Ph2vgAWU&i zovr4!I`zx>s)C(z;_3`uJI+78)L^EusEYv^uUz$?;e_1pe|w+&XSm=S^kMs-?rZ-U z!hxLL*sJwV_-p?C@uNp|*3b_~EiyZBs?hY>v_1nbVTM&eHG2@FrXO$o5aSGGB}C zRH| er{SsjA69<}U=weBpSok?q+3Nk z*Vb>Cd|h_`METad>*f#p@5Q~kuKjPF=fB|Br{!O1FIm9Ur2)rWv)2D &A PCt=Qv=*p=10BBSio0Naoks3F82K25BA5lmipS7TC;B}ZmM+q z_nNP5U7&-^-fdgU7rW`2MterMe_C>}=bh}{-qicAwj0OXx%cwXTivHUD$86SRu^8E z|63gU)bwJCn|r{i!>k@Blo~WMu3h`KD}*!W;p5c1`+pz#YFam|W8(ssfK`hb7#mov LC`umo|8D{SoHgwp literal 0 HcmV?d00001 diff --git a/media/customer/2364084_avatar.jpg b/media/customer/2364084_avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b26de7bdc7b7e8ef774f11e36b1ead209cdcd26a GIT binary patch literal 1224 zcmex= ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=S5Y9x)CY?P~0^Akk V*Bm1$<3i>(gs<>-lHrYMt2o@k*_G) WHI4tte82wsp83BxSH+3_XP8)Z|J8qnUxKT5t^d>be*f!x{(o7n>T}nh*qi^g z{x8P`*4uB*t_QX*-q9JY+ jPlJhduc3(=*J$7?b`` ka)B}XKZEk!?|%#APiikJ@f29RYSX-hZI0{8uK#o2{r=Yj`$^%R z4l;AU?)p(3y=~9dpStU$Q#STBU;k6j^;&!O$2yhmo3_V)o#g+i|FHZOpi&HP-22Y} z_Q$$(*N?i><}P*3Hu6hxx~a9G&(m(}jf)O4XYQ%&*ze3YIoaCdPGujP`2EYDO_wjq zjK5iy8oT|x;$7{k`CgY7HCX)a^^(;-7Cv2^>nTsx;)IjuuKs7>+EbI5c32=f=Cpe1 wEw=jLSWywibD7u7cTHQdYu!@$DI5PYtZ4Z5-TwL7k`hGlBD;}Tw*3E_0Fc<&YXATM literal 0 HcmV?d00001 diff --git a/media/customer/2673344_avatar.jpg b/media/customer/2673344_avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f2ccd9b070156822ecd0e9ecc2387cb4ee88c988 GIT binary patch literal 1204 zcmex= ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=S5wViXt50}kqn<{!{bBy-RoR$Q3mVPgWH`&rhwtu>n`C4?R zQgz#>D}4*fkAM1;nPX#~x%{5$nc$es%L-%<%Jh`Uef2-;etPGnb<%%hiffL44F1c@ zkd+zbx^H^Us*YtjHJ>J)mjAFkt15Kc^1O>@8a(?aIoPGzKi?X+ruuhpmG$vxZR$X^{E(aaD3X_^LgI$ z3t?v&L;_vmI0WRQYN(G^Rz&}EeO RZ5j)hR=%25l~u-{^PJ^V@84^(yfKR! zEVFa7KD+fqWo?_Z>G-E57kl2x?(Ox|@6an%F~}4veqYCPiHGI;mvz&+7#1$cT)p&$ Y4#T^ma*um!vi^z$FuIbD+5g`J0H27?Q2+n{ literal 0 HcmV?d00001 diff --git a/media/customer/3285991_avatar.jpg b/media/customer/3285991_avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f688d01f368bab24c7d09a6765ca17b47441d3a6 GIT binary patch literal 1198 zcmex= ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=S5+UCyRKeMiF;~!(23%=z`&fV_a zoXY>(@?R|f<5=0^sxZ}$b<2&4x@L2JKOz5Ha{+H|()Tw~p+_D(JoMK8dq2}olP$So z_dTx`6rKJ3esRfvhU3NIHStw#kFK5Uu1xqjsr7YV^T%VEv(|TPdF$*w?V`fYFohgd zafZIRFPPT@y(-gu!er~jhpX>z%h;G_Sy5khzuo_`=z0fMkw7>WH3fR(-hT$LKh~wY ze$<^dcd2W(kzb0_O|1oeo_1SrTy&5*b5CW*erLYP$<`isD*M>P?_d6Gx_nV)vezbU zWwv?F`@+9}S!<=iJmUi6mD1gBLl55IpDtE^eu4blk}rV{GW(|RO?@ ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGchUHQo1xUS129h`bjm@^G5!IsWTQ z8L}@%n%OB|UjI~3rB|l+(3-`P|E4Z2G`bz_ZT)0PM(oDx3~3E2i*`PIENj!J`|dx( z`_}&qk5*;Zi@uzELU5jk=X ostEdrLki7 zL%MlbikYX*bXWe9`TfMl4DrB|iW9G0Jy>M8 &Bx?{o#Z` faO~0j&!F^m|JDBtUzEf1x7?0(6YG1Vn$ssQZ}gWp z=)?9u-Piszg#Tx_(3=y$ZuxNLv!?95YGrqFXKU2oJpbuMz0`}>voCGb@BV5zc}mC) z|9uYs8E*QPOo4e1L^H;HyApTPJ1=J0*8_=H &U}-Ttv&8k_OXfIzx>(sa-f6cEVZeBr>BM9 YuK6T;Y5U4AYppaEFm;iS`TySp0ADfZl>h($ literal 0 HcmV?d00001 diff --git a/media/customer/3761615_avatar.jpg b/media/customer/3761615_avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f2ccd9b070156822ecd0e9ecc2387cb4ee88c988 GIT binary patch literal 1204 zcmex= ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=S5wViXt50}kqn<{!{bBy-RoR$Q3mVPgWH`&rhwtu>n`C4?R zQgz#>D}4*fkAM1;nPX#~x%{5$nc$es%L-%<%Jh`Uef2-;etPGnb<%%hiffL44F1c@ zkd+zbx^H^Us*YtjHJ>J)mjAFkt15Kc^1O>@8a(?aIoPGzKi?X+ruuhpmG$vxZR$X^{E(aaD3X_^LgI$ z3t?v&L;_vmI0WRQYN(G^Rz&}EeO RZ5j)hR=%25l~u-{^PJ^V@84^(yfKR! zEVFa7KD+fqWo?_Z>G-E57kl2x?(Ox|@6an%F~}4veqYCPiHGI;mvz&+7#1$cT)p&$ Y4#T^ma*um!vi^z$FuIbD+5g`J0H27?Q2+n{ literal 0 HcmV?d00001 diff --git a/media/customer/862833_avatar.jpg b/media/customer/862833_avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f688d01f368bab24c7d09a6765ca17b47441d3a6 GIT binary patch literal 1198 zcmex= ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=S5+UCyRKeMiF;~!(23%=z`&fV_a zoXY>(@?R|f<5=0^sxZ}$b<2&4x@L2JKOz5Ha{+H|()Tw~p+_D(JoMK8dq2}olP$So z_dTx`6rKJ3esRfvhU3NIHStw#kFK5Uu1xqjsr7YV^T%VEv(|TPdF$*w?V`fYFohgd zafZIRFPPT@y(-gu!er~jhpX>z%h;G_Sy5khzuo_`=z0fMkw7>WH3fR(-hT$LKh~wY ze$<^dcd2W(kzb0_O|1oeo_1SrTy&5*b5CW*erLYP$<`isD*M>P?_d6Gx_nV)vezbU zWwv?F`@+9}S!<=iJmUi6mD1gBLl55IpDtE^eu4blk}rV{GW(|RO?@ ^(PF6}rMnOeST|r4lSw=>~TvNxu(8R< c1}I=;VrF4wW9Q)H;sz?% zD!{ d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$ #!*?!?MGX{TE$hx{w{At=S5+UCyRKeMiF;~!(23%=z`&fV_a zoXY>(@?R|f<5=0^sxZ}$b<2&4x@L2JKOz5Ha{+H|()Tw~p+_D(JoMK8dq2}olP$So z_dTx`6rKJ3esRfvhU3NIHStw#kFK5Uu1xqjsr7YV^T%VEv(|TPdF$*w?V`fYFohgd zafZIRFPPT@y(-gu!er~jhpX>z%h;G_Sy5khzuo_`=z0fMkw7>WH3fR(-hT$LKh~wY ze$<^dcd2W(kzb0_O|1oeo_1SrTy&5*b5CW*erLYP$<`isD*M>P?_d6Gx_nV)vezbU zWwv?F`@+9}S!<=iJmUi6mD1gBLl55IpDtE^eu4blk}rV{GW(|RO?@ q?zzspzf}8pNHob+pb6 z5>0|^t93+)rDzbLj-Vk$#1V p`zFri(Tr4uSVlQg)4s0gO=L~oha97ygioebrn%M3 zj&Y(%D?gUyxSq5YS3_Fo*>5Frh+8Ez5NmR{pFFiSRV*|VxiHPxK!`M$Jw1{O%zmPO zM8*Yq^$=Cs=IT#}#4lK@ia^BF{*d?q#TW2)PP?%nRA_)mBM^8F5yZ_|bbA7 )bcfu5%kd!OuO&)eu~S1Bk>75=&{Xc_Qn+vc(1#nLu6 z1YavzRe4+vi#9&hvEAKEjM_Jgn`hUez5J46>bnY{OvK)oAxe%*eA2jT*_F8XdBPZ- zd4yr$3?h#Tt4>WuaT|I;w^obT^zn!mZ94Nz**<+PO=Uk^SX_!*ems8%l)V0Vkus6T z$}-!B$k|xuL$|nS4GnnWe8xubgffEtnVqPOjx_&1ZM;AuWXAbZllkvx4y$`qOnzBv zv+h2BZfR+Uq2?e-kHxwF?*1}eMKC(oN=bl5A{t-fD>QPy%gd?~k5|1%F?bgl!YW`x zbAOu q} z?DW8$K4n?)l15CfY!hitekC23`5>Mmo4KE}gyUCUjn{|^0KdZ+t*=%z9{)2x-0XC? z2BcVg7~+KB%(0DX6|DRfBCj D&k&bApSI z`8_i`u&zE_UxHWKkkYWSmmdcB$JO|B+jEr4Q&)UHf?I)?>_ojaa`iEf?wMZlzFeKH z6`|m5-#~>=#zCIG6hM_wIOQu-C$}Zc49vsxw9BIrvq|EwV&2!M=v=s*7e&658<}G+ zm AXYU(m^DOII7aWU1{x$H6f^B%=#`R}KFhXZ-=qYYGgYdD|aoOqAd zV_~^Ji#<7Dn*>*|E0%zhdM7$yNgFf0P;7~iK~pIbOz3*?&TU-C7*fTg-KOTol>}~C z{E|?S80?=MBlK@X`A8#m oFCBI$%?hs;` zyw0ub{ya9`T3%+W0Oe`V(-?o7H_@1HIq&EkZ(!*PGik12r+Ez-k1ovSggcvJ%am%L zCA?n_9F`XLM`Pvi3PEaZLd`RUikzibzsEvW^DQcTdyxC{+CR>cm$|i?BI6|0iWdyw z150vL_AWXqTLATy*LNJ`ydlJQ9}30rdkxKZBj@jaemMEYFkOma7Up6-G+1V_k-F1N z>EXdFx9L00n?5B+-TW=D>uZi5f8zm9am_c(^-Q&yXKL2RkrZnUyFUK493(bY)Y_N) z0KuQZUx3(ItB|hvXj``vxs#qNoEht_eys1sVet$wDDG)XpLQ|!H$$Z7Z1Pte*Av se{{`yyZ1#-`n>xV^AUy3m@>UnhCAR-WsgEi}NSU%M8~AXX@1J?Ug|p^!Ip zBAh6gu4Y;KK4hCbKQh&%x)|i74*Ci~wLQr5eDa_me`@0*s~W`dY>Y@)`4Zb`FaaB} zKfuN}=>PP4%t^)V?Y(OI_DJ54Nft14T35oo!NYaO+3{?IGEu3lx9i7+w^Vx?D)VS!=x|!v$U&THb9kYeKikVj#D#F|y1(=0ChdXWQ zqPU;sDy<#}Yw# )gu1pdnEA zunXovuM_!O(6Lm{>G^9Hvtx78DN*-hJqBjeX{Dja+X}M<<^7xaH+R3 EuF%Je_FKvVx0F 7g7H_6BMRp#g$YfI9>86VKW2Nr zN1Kn^kO{ qo8U}fg5WNY5gNwPpq)Q@Z zK_u@lHhYCmdPVldk32fxIp7I#eC5NNnaMq`aw9}EL~AbJ7O?P2mT~N!N*wn?K%in# z)Y2SGDlL5AUDL#OO}B`Ex?SmYr*BdMGs_ZXCZs$!zCa((<#-bQhdR_5;+rR{THjU1 zsR}hJ(#h3NN89CZE#x4vOes;HuuY!4?>X4Y?ANy2NC|5=K2oFBn~zQ!&|WrN%msl8 zM+vfj2+UBSi=lJAJN$Qvw46>%QuNPoV?L-d_YMAdn N# z8q116;m^qXXIQ|Wu|Tk5Y>OZI zFVYGcOJQHvB}dkuJ8jh2)iK&JcX{<=++a8qs@-lstn1xEApVy4y_qR5^DslQI%X1i zNT+c{eG}HcsZumgt$sUB!SF7Ff! zemxexnH`Js{AhnJtRJst(^Xe_S3UE4SbEj~wmu(OR2!_^_kM9HbgbQog7%p7B0c#< zvR>t;I8o?fPUB-~_ILT9(w?y4?Ddd5Esn{=9dWF gyw=1WUSaPi zEp27lr!5)hgTS5D^dlj!f^&}MP;s`ReciWQO~!oxcx(55@q;yL0P9;5CS5FXYGaD~ z0$dI 2 z9KPUH;r`brsTXg8#M>oKXEC;>v!30K& @^S3_n{s$*g)9zwz+HYi-C~Q))(RfpHO=fYmGFE zowBX@FzYVEvP4-c ^Kv2s!{V-AeBZU0_F@Mkp^@E82k6z)PC6TJbRaCnxJa~Hnwl|!vH(U!y`7fhL BDl-58 literal 0 HcmV?d00001 diff --git a/petapp/__pycache__/__init__.cpython-311.pyc b/petapp/__pycache__/__init__.cpython-311.pyc index 9d4752de97e3e1240378fe906f5f85374e87db8e..0b01bfa8608afd9e393a566e70302a3b9f14d71e 100644 GIT binary patch delta 19 ZcmZ3)xQLN^IWI340}zyN I _G2&Eqv5F~5EyypP7;XyygpCOD diff --git a/petapp/__pycache__/admin.cpython-311.pyc b/petapp/__pycache__/admin.cpython-311.pyc index d71960231f56c54780c9d28206bb7bab623d4b40..d0a69af56face5ce71101b9534267bf35881dcb8 100644 GIT binary patch literal 3796 zcmd5<-EZ4e6u(YvH=ivd>$ DP2Jf^xORY* z4`pZq9+24ECZ0e-LlZ)(fQd0i;ZL|mmWV7NP2y=UC{y8uC(f~xG+7XW3JGrQ<9mPi z+ t+PzJ1+60_n;+)5}3E2$){l#&8|qKjtQ8dL_MFHvD-s4Yajt=-e*9(-E| zALzkvZ{rd2B++AMi5`dfOdGuzCFE0h!=`KxxDvpX{0pw(ZV4amXs_=6Qju=I2zK}s z-mnSeZ>*B&@D^6d7X^?6?>~?dc=TTfJr{CIYznUr^D@ATY~hsrLj}0tu4{oe$aq_ z 9Z$W+VXit~IO{;mPz7w~?Cths7!X=zb2 z&2Z0ieOp|CT;z_{W!wZLenR;mo-OYs=Zu!rPw|IiopxUw6QS? L z;i}Lfz5x$;e=8?sJ7JrAgzbWlpV%}e8v~$qHg*T}8Rp#8@qT4D*Wht_wVmLx33eyI zH5mxMz_0xaT1vs)_A5Ay3Xb$E7_eiOw^Kk`mVEC`9?OQR?MBr;0~226SA&>Zhxq!I zuetB%_;(Oo?*yUH?LFw^f%llu>Gd8q?R3f!ffD**_d4JXTaUkW_ !KC8QWjn@@C7$){XAYi`apqCtL5+Qz4_$f2avk(24o%ta<^Zg$0&~fk3 z3vTv=mp$QT=Do~3Pt7-mhTnZTF!XO&`}qf8*g9Aglh{?hHk*(8F*S&1RrM39YC(QA zDfCmS`ch3ZG175lLh@8~!>*cI7&!hmh$#jbwTsNCI!2`&_$Wg^V0fNOB#;}rFaE$_ zNRsf{HjsMfuaSAN{%lheqzO1yi(KD(uzu7N_aM9n;gDRPy0<>-iIWK5fpAE!Pd(j& zqtcEh>5v2&FVvs$#GO2NLVZw+BD|f}_K}TgfNo8#B>___BuPmZsnnGuB}kI8pK6tl zc8*L{!wMCqNU6$ nm4>M;8m8euk%BT*Jmn{#fR$*F8`=FJxF>!5XD-g}0#(3+ z)1e2qP7}B=yBnrh9!XzzdH~SXk#1WQHjlR#CcC|N9KBcR^WHh{& ab$*XM z97g`5>@etoHP{}9xM)TNL1>U1?|qsPBFsdZ!1({54YHs2K24d7J|)zpvk8yvXzY9- z>e*oe%+kiNd)<9;zyGC zfn?4dxnQ|u+9T7POg9MV)54#;u;7w?9@)pqzHa;(m*l*_+TG|8mt;MX NG_?Z-(7bKxh0!dB5&`N-W04d>>@(75iJg$+B!?$rRxwGB9b0KMq z3_?YG!5^r9mHHE*N>N)>N`dyj{WudNN2eko^@~3QR7iYv=FU#y1XML@rLN`K-PxJh znb~>Rzeb}W0^{^=Yep{A5%LFaszazOp7;0(xlUA~ayl_MiQ|asQ~kQn@JoJ!mv}>v z1VfZWqfV+b0#d*TN34=!wefQKMd}hqXYtu{G68=4bh>>RJ`wK(S(u zqV5e8E2|VfvY)7dOGFI qKa7c|VWe6z4e?!^y`a8!qdXg4G%G1W1J`cl@ zf50cure*PoH@RipR<|rJ|FXCu%i; d z*wb-XesABkZ@Y*K-eK{geIJSP9msLrz7L Vee?ZcBE N=rB;#4B}R8I1%zDq>nRX^qBYW0E20XPw= zhPVJH0 <=skV6uIw74tl3!D2JIiVa k7hSk$R7+lU9wHOI zDgWSP+YZf0$4!>n+573|z45b}YK`vf-MYCqzG;`k4? !3%JNk+peZO><`;Qg- zkCpq67yFOTbex!powOq-XB(PafB%UuVSfq!Er4UOBHpp52NOXjAiL#3mYt9+8&Iru z3hRh0f1FozEF8Ggp%TlgX6AIo%Q|NTBqReIHB(H>Sz0#Z#xcW?U}(w|aqsm)9DmU; z1Y!7^I{{oGv$2l~ho14A(Dk@yYvFK-@5W8{ gK? >|MNi0|M;d z4BLy-z^I~TGx`KHE2^s|LrvIb1X%05fO;QS2)f{FVj0DN8Y&!`ZCPhG_Y{si 8s_W(#Vk4Klwzu54w%EA#1%b_rWRTl SZH? delta 146 zcmbOxvw_j~G%qg~0}yy av7r-85t^>G?`z5 zq%|3Du_mVEX6E^6GEL^^5fxm?@EIijOTon|rYN-_zj*R~RteQ#95%W6DWy57c10XO WSwIL0f#II}1 2IWI340}ym> 2IWI340}y0AX5PrXm<0ec@&xz* diff --git a/petapp/__pycache__/authentication.cpython-312.pyc b/petapp/__pycache__/authentication.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d04604b5467deef5b6ebae6af4ef4510f14724c GIT binary patch literal 1026 zcmZuwO=uHQ5T3U``DxRpuwvp*r8M;r)F6VQQiN)YAexJK=n~j&cVF8io89!i4QV7o zksdtOQ*Po>sb}w=^{dUD=wB0)Q_^UdFzH*aS4{m94=AT4}2x0I6r zz6zyJYES6iN1+2Y*u;Sv(FqZ< # >8+GLorwnm)nfgWpWuqnntX|3xu*{IUClES7K_@oo zk}ccP2GQjf$t%IwT+J*yGYx;Gm%C^wy<-A|Jd9uW1+oq#!AFd!(of$vAXfUF7_haa zH)M-Mh9_!Ut;7eMJ+UqKBbd}yA3_UqgEuAqKQRRiJ35b%O<0rXp-J*m5&NN1@t(ZO zMCC!;TdYva=YfoE3P!CJYE_N8$$8Ubc95F&C@*^c+*+CY`B MR9uMpqk@`z$Fk zB>qOns!fwE^FR^Z<}q|mgmiS{&drjT1~1+7c$rbRG)sBa_v)oO_4!JKX1!iAvCGu; z%a-YvJ-1MA1*riOeLVi}EDD2eQ4TL6TZaQlO=iDnna=d{>0K?it>s>w|ET45w9C(C z_tM&KdU88G`SSXw^u@i*na$w?8OARC{w5p~+v$m)K$6+dTIN7TJmP6g`Si*)c&p8% z zjVzpjF7dbFZFfrYbiJ@_!ZNQ-v zQ?u+;-&4%TgR^$UbeFw?<+(m9FNQBIEJo|infL{Q)5nE`Th62DYR3dHv4K$$Ss{g& zio%W()6o-dv2j$zLh>nO*abrN;p#qI*oVT87$i>a#53#4p%N$A&Gs)q2($bFbFB9e literal 0 HcmV?d00001 diff --git a/petapp/__pycache__/forms.cpython-311.pyc b/petapp/__pycache__/forms.cpython-311.pyc index d98324708d8ae5bea7ef9a66c74e9066482843c9..2c423f5a22479e74ec9f79be5e992a9d50f51de6 100644 GIT binary patch delta 504 zcmX@?G|7#3IWI340}!O|;ZD0gkynyYW1~7FBOeokJ41><3qy)vDq|M^#0}!?LMcMQ z44T55^%yV6N+g4{zyJ%B@i~lP@>)ij`V^)$%*&V<7*+!@1VphiF{CnQvBCH$EGevO z*wEClr?3Mp;JC#dkXV_UnpfhMUzA(L>zJEgnpdJwlCMyZSXl%zQIn}i5J=tP%+1V; zFH6iRO|9bbFG@)*QphXKO-e1Qe<^~biYqs T4I~;M&=E-8 z;FawNy}~QIz<)>K1zyLCypC6R9UI(k2rEr6onpU2?ts$;VfTx|?pK7}8+Pa)Rm 2FE~_ytpNbv Czj%89 delta 98 zcmbQ_cG!t`IWI340}y0AW=>O`$ScXnv{9Xrku60am_bu;a|q)FS!O>?p~=$~_9-g> rl@%$12qhr#i^C>2KczG$)vhQN$YliL;>gXlih+!i*C=tbf)xS)Y(f@n diff --git a/petapp/__pycache__/forms.cpython-312.pyc b/petapp/__pycache__/forms.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0c01e2453c0bb930104fa2463816e9d51bb7a086 GIT binary patch literal 8120 zcmdTJSx_9ub!PUyShRqIBm`?f5-XWS2SyhGOETyNUsCK9c)el V9SBJw&L3#CW`OS%C6!j0RXvL63rYmTQ8lhN bLi(`5XCSyfWDJ{pCW0FPH~Y*4H-;=>tItYsQ^@u{LsJa3k7CW|DAvN!ZMoXC zv(GC!756y^r4=Y`51`B-ly;zW0A>CxFAYoa%w#CebS2sB(~)r*FwXgaamxs0CQvSW z0Hv$L<;l8(Gk9pl&>ZE%0wDUM0>{JCwL2!ZauG4u6cB^aNG)_jYeowv`eQ)h4@X%p z1TFT!EFA~+%$jf@7{bAO0!=5m2n%iWh9>R%@M%g`re7k0<0v1^Qa%PgSl4ErOQ_;3 zO?t>inBU7XtS(4j)n5TVSgsnbFe>IVF3L^qc{FY&!YxzfJr}ZSk85t5iZAhQ) $xCI1mO?|zi!{)Io8BIJF5IGbmiZ7M{e5LoKG3hgDT>4ZRmj@L?Qz#$^ z_pB)W(qN=LCSHcU5D-OPxXdVqP~Zd?QjDj9EXX}(#PJuU&*Z_oPayg}Fu5juBKOI? z(sk)`_#2Z4-O?A*b@?s1Pa3;xN2=dIEB1dXUzoQGk}{*Fvw>=a(slu-^XXaIXXs!& zx_epkzrcHh69XQ-Vu6 @KFUc(I>Zau}^4xe-?%CmJIqhj_GI=^4B`f<<3 zLLA_BzyGyZAcP$JeqIkRpcu%8R*cO-F2o9#scC4W?rqw;vjNvnXgC-Zf;<;#c!m>B ziqZClc1{#p)n}l+y@9BYx4lEr<2&*wLfkF_F2Ol!GBdm1Fu82^fRV?Q |Gz}MniD3%ww)8YY?3cmvT(FQ42qF^e4imMbWvD5Kv^4rz6RX7SK z _{0;!VWWkVO#5wGg)>Vx6jK{v{`M5_q)+qT;N=HNS>To #s@J^JIITR8%X~`)|e) z^?teDFSSIZ_AaTpJ6`{0+}_h$GwIClj}7(=^jvyHs;nQcNmSO$mG#n(Uy)u7NyozR z%1GQ9?cM)xJ!9BIe?uWuzX4x=-e$5u1D5F<0A@GSqKfvvGATON#F|;lFLetVDKH-3 zVTj*Isjj)h?r|ul=eZW5v$%<*UxSLhC0&!xfL47VUFUIA@eTy2(mc|{a4Si_0zLZ- z2z%W?c@5Q5K1Wn@tkYjoy|ZCs_3;L_@r}(-ZtXr^+Td*v8mm3k&;kF)8%i3EH+ocp zt=*)>)6m%1b-ck_+UOzUwsw0+J2a4bc{lbVmts$6_WF(6+$Ai_dfWg?$^Uwfj=Zd5 zY6qLb@sUmo8xRAf;ec>*p8Ouh7}%3*qFMn)u>wy%8tDiJn-oKPYc#@v!l$W}V%{4Q z#Auk~d33gX0RlIISzRFdQ3`FSK`DjJMTISyudtRh?nGhvVq~`#ffqp;f`xQ$19l+D zfu9fp06M3sleB)vjj|hS|6KN`GU?@4r4te9rD%Lldwkhzs8Fl>YX<8F>ZQW!o6eht zzdQfplv>5FC~6NlKzInc1NyHi%1 `Vc-GhxNTRs5&0h9FO|JIQ_hZPx?!0 z`f2ESYmVylQ_VC>pELV(EOU+mo2&z9VD$ivq|X3-Ce{dbb3b*O_E}z_JSN4tHyS<> zjBspHSWTK_fjxy0n-hN1Q_%WzdV~^Fy`uIaR2TI&7^N;cNOdvq(eFSsCu#u$rNu)F zhY2XZE^6VvO6Yq?KFkt)7{Uk54=GE&k8TM*x<}xnUxJVR5x&c?1RujA@G&mI$B2A7 zU?bGcdaOBWfg^czO5m9dLaZIsatqYZO9vxC5qvQ&t*WKCRl(Qm1uoRA=mUI lFja^;w=-!<%!~5a`CS5!*cO~WZz-g z{KQo8#@`-D6qn1z bZS|n `0DC7&~^I14J5PNVOmyJ)ZidR6#$P^Dwf1DGFlx}^^>9F+cu z0i#9#xa-mf-pdBX-W1{jU}*g4Q4}2n zsERJcMbse5c`OhLLI<2&YIr`%dl Jv|arZ6Tnkm S2E}RAY_QqCcg_n>>vO&@SiKY>yIfr9#>Bj2u?CjAeriV&xZA#?u8{XOMxC& z6G_g>M9w-nXI&y^gPgNrv~nV6d%qP$(s{o6;&Zob`Ex`fPPk%{JvQlFDVbOPAVfj} z3?h;jQ6y<`;dd?^oNgiE%m!YI31^l9P4eRi=gkRMk7VyzOgL!wiOp-(LJ4S4%YYt2 z2(V_FbM6MK)RwYt8WjcUBF%1fGmB6#DGHs4r(aSQvVm=>kU*n?P(*h%Wf|KrT2Cw5 z`|&QY*ccY2704jywPOJUK^Wze^3d}$kPk@)SWC{IwaEN5Yn+|GBk9(O3rCIf&?MB2 zH31HXd~(2-K0@n^W*ko+V9Mn)coG?tK0*79hCO*c!RLKv6t{d9e84prB%hTBwDS%$ zUX%O0Fda@EYk9cou1g=g<+txkP+)T^K|yGin$p6T!)%x&0Z+qM0nTs222=Dz8`mU4 zK++rx!Ldd$a;Jj=)GYy)^+Qk- vjB;G#t?`=HvHv!JCz zeHY#ZfMLsuyx~*B-9PK;w@+r~B{JP|ru)*0iA)ciR?_NU+OiV1)v|4M!d58T3P*D! zTj7MQEMcpVZ546b_DOr@VBJ97#cgnaSbLDc6T>0qOPh1Ba-cF{%a?8WmySxd{0ZB} zgl&s#+Y+~x&l^(5+=U_a%vU 8? zBK6U8xWVD)vACJEd6NN?xsC+IcQE-G^8uKfG@G^R5DyWTOY#8M<-rAmB}^2cs*Ot@ zxwj+v{J`nHz;P=~H;o?o5JeL?HD*&3F`22e8FVI#X0m=kkI*!AVYwcR!uz^Y^kupZ z(!8c1g!B;8L*|h2Zc_A3kjR?rKJHm6Tet{!x}C4;+`Qmc_iL#;Z)GUj6bK1b-qeso z@D9_MSNkU_!Y$XfOYBhjNab+lNR{l`_Md6oaDA)t=-3HBmR`WLcvJofWGwqIb@_Yw zyc ma7{VAl9&&j>=c`xK&h^-^0vKnVYAI(1v zK+y#v9a_|fN5HvX1*vK@u_^I)<}bZH&{_&_1ArhrYegcfSk5X=WR=KSC8Mh*vda6- z81bDx|D%hWZ`txv5g!;jPYp9oQCYPN;Eq~m%ISi=Guj$=ZHqg%%_BTQ2 Jj*t5p^)DXUXFMN)V-(q zLZre2G69&o5{dwPdybl6Oom$e8<*a&@*BI}u!?{gyTwq?{43XNP!AYn6uReBF(t9- zQ9!=eG$|$~(+aEJykw>|Lv@L}5=)24V^%Uq&iin*B}gu!_$(N-P!^O2+XadB`$Rx? z;W`|&9szO1#fX(4z}?8Z5j=r_ta>A22vFYyR2N9reYc72GyB!~aF%&eLQ95ax&gq$ zNQq@2(!^6O6rX`4y)i|cR#-i2xSERSd?vE8wr2w!VYueQWOJuucQ_i0h;A|JZVznPUk`+0T&KOBXF1*-iG@#a{2g3zjmR1foc6;RyhUuS^O)210EM7f zYeUh1sNP-}17tdqKvnE;VFTBSD%W&r_+coI;AQv;C^V3UV@?0jgkz2DSaYd<{I$4a zcW>=vR^iZ7Bh|yzqxm=X#IyFDIjk-*4z2TKDMq#}5NV03If7Mc#oH8(h mAXZ&OhQ zY61*%Uy7d8iTab>NEX2jJ+s^Np1Be@z@1hVAAt_E8p0a@zS7Y&eVfX?O>MkQZNE)< zZ&Od+rnXE`t7nX6dJjExbi_aGpP>++S#G2~{oG)5AUZ< 03$zGW7f;gNLsPlm1lMV zslt_QT8r9=M4J?n)Uh0=jZ~|(aO@yE^&@|@B_};6Ghq{{Q`0&p>FMD=+Y)u^f7;)7 zXJ=nti6l)f%(r*${pLQu_r3bD%T>Z5J^3&79j=ue_e**)k~Ni?eb&TrmpFkF_z35x zUsHtdG5JkA<;@XukHv3cc}v9FQ{*pVd26J&$L6=Od{M;SQ{pdS`QnJ9$LV*nyba|p zzl-JVk uxLA{9LzzlY_WdcQrD{>q*ze-+AH=Q)41iQB^orRO=p zEn2#pjNxZ~Uo-1@{~{A7dc< 3f33iIe6!pXeF(M=9ek2$P3&D6e7TqmL zF$qOwhr41?u`SVaQj}W4Vnje$`N7~>U?#*AIzudO7DM5lU dtt!PC^QO%g+5_%tfa5)qeXXCrEsf@f0MmRK|%;!}i0KZHil><|FBi9g2+ zrgNrv8mBu&k*H3m0q(U_{W +z-?jm3P$_l()Rfo6392`|5M*GwQQc z$qLm$;9LdfTk4?tf*0jifpvuye_we^c~_ZIhrR2(n>K7XyLrO~ukt=nsP(s$AK-br z$!FEq&l2kuqnh *GzHA^L@|sjokOs;@VO3 zcS~L=8T0?td+(bsuwF!(r1bS~+4u-VSKymVF5Y92X*BBx7f0z1V{1K^Y?F=LODh zf-Ew3+YGeKuV_WNGxKib1klrj`88S!B!4mczD$41hJr<~3Pq^33&n!Xkb|B4ggyOj z32Gf^&nlEmIMUM7Id6+j;JPMC)0i%XS)1Lfo)_G}WkxM z%^r&eARWZGs5yEiY_8N7I3@OJPVnu?m@EdO!5;BuJsN3A&^jsKQlC|y2PqSUzoEQ$ zYcUE>JRV%vzhj+W8Cj>iu1u~|hm~j4i%+awd220wGD`Fha(_!5B60^0;9Gq_? VnHDQK}hXrmS`dpVXfs*FzA-0*(LbN(67Mz&4S5q5zL*u-`Z#K zSwD9fd)IVOj0Y1$#L71y38vWEJ)0=aD^Oq1$`jz`KmgKM40OlBQBi0cFVbuQwt0bo zRuTw+l@k#Wd1oN-R3aFmZ4CtUmGxxrb)Ywrkb)7-7Lx=~3P(G~If?dIssYd}G$x76 zhdMlR6~K9JrlxVoIaA-H*p|*zu2wv2F4*)>?nQNud@n`;NsL)P %dfu>%&S4kNS>rAPqnmarFA0_bt6()`z`3G$xq;AKVdOHu14V`&I#(R0wPvZi z+Q?;og(9KYkPPQ+1I67m{JbRC1}uVoz&250$Q7O&DC#C&%1eS{o^>uDt-i?#&X>~b zL)PYR`)y$w2oRmH6em{HbIXm~0Qcp4IBtLsa|5RD@L%D1t`Gafv%NaQ`AXX~P9jsm zXSx~1kF*6qGe5LvXMgdEmJRf;|86KdQgU(}22qGqAHD54aA@a_1IIgHnaIcYNWs(L zc;7nMJBbL$J|6G5NfN_nlD1K+1km7po9Um=q**$`kq96@?sxZyLO8fSEl~O$f#B&N zF;91Ir*sFkQlU9}yJGQJszS36?`jreX3ZW6!jd8`)k-?Tl99J2dV57lHwVm7@r*>& zrdi0Ql8D?iTU<(r@xESBv&6--am_-;m}a9kSz{Ikt#X2zp{@6o07r~;XqKSVDQiWi z&d{$!DqXXMqv3cs7?FWO3g5#z6R5N8l(h!}A&gTF1Z0w|WL&T`$b^N|in9KUIHQrQ zK#@EL@N3u$ZqKyad)@7wsabsK%*8X4?N^UoIW~RwUiI$1*H-?-_aoo*z7y)c6Uyem z&l{c`YaX?X9(lF+rwvbDuL(}qbgDI-*K5K y>v8 z?f%eHdujW{?W2v?J!^)V@iy&gR6UK#s*{S)aoy87)cldNY`FD8>qytAZLDu9KGd3Y zHqSWAhxc9Bce!D#^7X~zi>G~CRo_-+&9 <#qeGeR|C{b mo8b&RXMORC&lwNCAP7Wj; zPY*WFlrI~po-SXemM 8z5GElxS*oV zJh<;)owcLQlU8MqkaTto?w%>FAL^JctyfFy$5u?XU)z=}JvO*!# a=o zN@RndVK?ynw!RXdLv!qi!a0ZpNVQ07(Dtn|0NCK<+QOwEFIIU=T8=_#1wcFYcqP4f z39KSOCV7tB<5571ld_2mOR}S!L|X%jB9$aP0+1!77(4fSvIf_bl2N;;VKSbXq8aYH z(5KiIeQ_me43uVR@iQxF*yVj@pXKwi?B>Y;W=@atZOr(6ukwBTz!8F<@GhK$? xkJ%1RlgA6V;NmTT0Sysp?odDl6OC)F)0s==AWd zB+mAm&XV7Lg72fZC-{E)*=62CQq8&7JlOoHg|{yLtjJ{D@+k+P50!cd;YlY$p3ELb zQD*fQqGQ24VKMAyKWu4GE&Oy)Z4sz8Z3Fv@`)oct{9s6%&Y0B4NVZ*yp&P^NBXVTa z`8(63^b|EwkRr>Bjtz2bBUFh1QAf@q{3aymO1H=8k9-9 Cww%aD8UQ$gCrw*xiMH;_qb=L~w8eOGUa~q%eGnitnWRP@Sxs(MS|3k3p2(t? zO++u7bb6srbC!yfJ*8O$nSY}=5J|pViea=>C^Ce2&qNmeFuXFoyKE@f5CckWncvQ^ zNOa^S(Si8WqP#-9=EREh2v8w;?PQT6%#o76bY6aN3T{M{3_L`M(5shylmmn^u^jTg ze4--FITZ|- 6ytYVmV=Aq#g #dXHl zqd9rX3Q-;K&3lLjA^ZgKJt_5Ju*_{t(55JVLlGBca@?d93t~qw5s5Q-k&1&+m=;0W zl;(qe^3vDm0LD!c1 8FdW>;w5m){5J`CjK{kpS zqjzJJ1-|RI!y2MV%IkHVlL=SlP7F55S{e{j!(QYxoAITTz$=UxrzA!oD+T6qvXS?j zH#BXyN!IvHBCrJUp7Q4u`GabI1}}Q3P6&5~VcC@m`tbn5N5PON>kCy%pU|o!dWE1N z3 ii_fZA5i|{*(wuPA!;#?0a0Jf3bO57~{+IyyvzR;iNfMLiq$qXQ zfwV1bylltUnWDfZviL}f$;1of_d49eTP|$5%>UW;8Sl!W=ASw1KJqpWH7A{QAHsR; z9Eq#8Wuu!F+g)S#T({k&D~$9+(FS#9#xqM%jrsh=ly8`l4M0pM)R L5`;iY)ZNgB1bckXTs3xsBPS%q_CfWG?{bSG{DqdbL`;TB%wyW*%#Pec$-L zv2ByG;@PS=w=SUnh)Xg?fMJ4Vg+|j$%9J3ZE}f}TEUa^8PLcXTfAKmA5uRvgo3sHP z6x4%%fr=hH%mgPJYc=V?4J@EpH?lQ5p6T<>uMJ1ggjRVNhbnQLd$mSkd!$a)q>EH# zZ%0Umd8L{|5ao~*?xnLht)wL;;WQ_@U+iP*QaVQ1wouA=(VRWOXrdz+iYFw5hDu`+ zcrF?U#S+mtOq&xxW@j;)OAjZdHc@jQ3`YCfV+3_qI7-brf*DI*bEZ!9^m>wdTG1JH zu%tP6#$pjM7}cx3Or5+)fVhB}-MS?ipw}k>vfXFKE(Dlyv KRj<{5uv2;TF{N8dy5fT^GoDp6vsJ2Rm2&T%q^C81R@;)!BZIr= zELQ8LPfL00w$F;p)`nYf*Bf+0hn6bG&@rUfEG>D4Cz!Gg0^rthJK$tTcI}@M?jThhKNPZGhOrTK>9s3q`1rfk9u>h9N=igv^UQ3sL3r} zi59T1uqxF@Y}n#wfGB$aAgjukjjsHz?-k$ZQpLSav8`J`Jdv4~*$P8EF%Qv^>VV{u zaX>>xIUAh%+!u>pSimSBM?d{E#FWFgXbpr>!}>g<+*wczUB-7T=E6jX9zAn4LyokE zd-QmiR+0*}1Q0`;*K&WA+94p*vjc!E_gZoYYgI?><;Nzguhw6wSB{)YI(jJh)kwjw zMzy?=OnM<%-Z8k3T)-xB0XLFKzfq@jYLhl9ozj$k4Mmyd{XI~6AwIFqV{DqU_+(zA zo^eS^5&IpCOK{x#1uk(hE^+B3ky4YoS(ihx^BpP 0em9!{Oh=YQUINounXS-o0*?)&)@Rm=PBIao6&tF?hBL)zoXn+y z?r>GkVi =y6Q=X)vK=h%cl+g?N7P}pukES zDCpdvmNtwQPu_EN`<3m=(NMBfMC93h2kG5ARQDaq)+0&x(ZRjM*gJXR?43NZ_D){s zZR)QuZ_}`Uue@D`2J;eg^9}BtpNFjo9~oG;<6-L|Is?xrx&)oUDu$kebjK|qJose{ zsb5P-UoT*{f!IBXNqBtkC{sBMORUBiRyX43*LmdU6bi y43`s_+Ob7d<7;7)Lzx?ReAHCc<`Uq_JgX0Is9#Gs{72E&I zf-lkgWA;0_mYHGe7ah{GfZgs`$F3l-YYhw7?r) M$Hu6BW?cU~F zfZf=U4;kKUximXzP2E;6$&5q#OCV@va#y&w7cK=eXK>&&KO??H4H6(jPCg0%Ml58? z#**%*V9I7rk(9eyljZvd_rVz%IXzvoTCG{FeCgq2&7+E?k~okVkt;rh5xGKVKk6li z{S3!<_A4Ox4EuG$!1^}soj}D}x@i;gl2}ym<^tWDN_mrh8~YZ{bbb;`1PfZN&M!yg zEBmy8Zb@0X$=}OMV(C0z7f;yIhAhRoECu6ScA-RYOgPh+ JxF-f!T zrk`6iXg%x7RF3c(WIYRPD6;ep-VibRQ~YG&ShtwBouv*T^PU67%|U?ngbz@;44a?s zcj4+IZermMBXbC#X35k+yobfRzK;(HTlx-xzXnKn0hDhkSJ(l{8@QNu5joiO>M)5= z`fQRUnayw_B>Lbc*+y*5bjg8`8KKhM%hb^m4i&p%2w=!8TE#y4LrGv4&ETtujbRLQ zvCf b+`+W&hzY2nQdx1eQkldN`RORn% emVE z4?o=6tP5^SA^|?J65OmgbtxWYSDmHD&?%G4daT9DDkbJVy-HQg u;%wHbN^&^wM=Z0bUf&)^UX>v49eIpFSh-4LtHc0i5SPH5FAC4Yqw;##OSTeHIoG zUhf|7R`!LG9+5%_UJ8tORi}5fYVz2%RX=I^QIpbrI_W%%2uUGhE|_$MV9aH7$k@>- zi_+GYEdL|ukwQLNR^eD&+1;5e4+GOxM}}gZ>Z%*7m^^Xqn9_AR={h^uLTYC}3_r8A zp7c(=u6Jl+IeI7U(&0i@7QsPw{+4%jvz#(Lc<~2t>6l(J^nhdDF*@gQ9E-EYi1Qpc zgSn^YrR? jM7GM`)c?McTi)hwQHV^ZXlk9?vo!)%h%A zaP2@dj6b9q%B8uCMIdxmyq7BOAwVKYzohf;lq2va9$5ldI7pGXLo@pLRLlEqZ?`GO z6M77?AaBgiVxL(|*6rl_=og#VAaYnBZF*JyzFDAv=OfzZAx<-kSXi(yNEFeVhXLuZ z(y3!*LmY@^qKEp$c2XgE39Xjm;5|jAIA*j7c3d$v>u7%c>be64kTY!nmG!xNrCQNL zEG(blg?8x|_(&q6WZ{pSBuLoljBb65!n$}HDwYC%--Cs+imIO>;04H8|I}y}WEzLw zzkbb{mQ~5=K$(*M6NL+Kz<;6oAMvC)z(*X=l*a+(zcB|eokaAkmG!3NMW8DsFvyRW z$c@$(8|Mp0aUUm=bI4Fk^+oz=N5Oj@zob?Okj$1Z04&TgHEYTBSgY2o9Xs^F>3@Fu zhfgb^&W{nE #Y9P=xYfu!r{!4_hq z^~6Z)b-t#t`Bq9l$B$+{+ DzW-kEyuh)F#%`wJMYj@ eOc;oVGM&{+d8y%Z4Lf_V-N^=@|W*;gU2y&RN1In_z!->8;B8 zEyYFYaixlzWSrvQzO3Y+3Al~wu#5|fp)QGdjNRB}cXjnM8|y*(>nuHH+eP&e0(4TN z9|f_Ef0bS-yrP>dw0lhEu)WL^i=W%J>6iVtOSgbWoFF>@KQ{9`|8Jb*23K{1tG&Uk zxxsC@!EL_5Exo~Qyuq!#!8P6BR{jUKR^`@yT4d#qnC43B`3Hth4-Z@znB$QB e8JT@0{b1ovXI-n~Y|W zovU8LBm6WRxe%G-ke%CN=Qj>LGJO2P@i`9JxkV-XPJX22(t(Qy<~YjFEphNGhFXRX nTtES`bG0>mz0m`*bDM4a_K}WDk&9>%S?Y1U-r_C1>$LWN5Ij6X literal 3340 zcmb_e%}*Og6yNo?@%jq`A`RHa1d5Z2wn?FFM5BbSd^?qhQVAigHr@dit#_T-C5@vV z94QBoDnWWlq^c4<)e#)Xp-TRTURc?Zt(AJpiCZM-C71TST>}R35w#s@pWn><{N~Nf z`@J`R1cOZsv}@_Nq{YK9Z?Ut}+;wH^4JgkUkr7#$$+43x%Q%>;jOcjEh)%-Jxpw}r z_q*z}^+~6NbOF+R0@7t6J%IF{fOK0(A0YiFAU%bqbYK%*NwcOWr;0?@vU^@KOx;ap zYmmh)5@wPWnMsF(A h#W%Rc@zuwvC{$e9Mu;Cln0sxaqM@=7Z z`NH#N6VHS7d6|ID@%)2%K}Iimp5pFJ|H!OB$0Z_*l!HFSb hD~KW`nr8Y(1)bPaQA%bc*npr*s=|vfZU%-WMW6+Ho&T$_oz# zU7$1yi@jthMiY&oK)PE3ebasd@sz1WlFOcIBxyvFrIAYHv*Ptyv}?Jo8tpQoU8RXi z^z-74Lq@och4CuaVQ?KKM}<3A9IJ7iIMQiwon ix*Ccbp?Img66!Brt+n^P z@KoFTjP|~A``HawYc1BZJXnqO7_pvm?Bn9CEf?z^wB1Edv+(V 9{I@j5^FPo; zr|4R9uh!#l(xxb$)Pc538vl{x^E8m}Xo@zXY>FP1f*Mhrwc g B|BWXH;4+xtyTPPYYRno)T(?R0>C+@L6?U(P@Fk(Q?q{Xx=_QGax9|;pl}tq=9i+ z73wQ^z9-VmtZs7G6);ZhEMj_)`^t>PZJI=P_voF%E($yi?ROAB@4)GW!D`^N5jee~ zRRZUVqctvpL`@i6qICX^P~k2ES({VKz18NF(VQwbpDEs~g%b-8tKozZPLwWG!k-qe z)neVq)ovr!UD7JC3&mTt)}G~i)z%)PwP!t6X&oqLYAwCX }Tv7a=8$#O7N9LEfB%H9#~ yC^WxX%|7@C8h9^Qbs7X^5y#UYvq+v z35~%e#d?wUy+*9J9P0zp@4JjA*KD(BECa7Zzc?o-Gitwh-+ukLZ{vI1es);N$%+qa z{UrQl&!_jkA^R0|iC%{ZEC|{S5bvBU%l^r9Y`X&N;KIG7sl};n2Gs42AbV ` jkofQgmIrQ5W92L5(i5o1#BzV1agqn1I3n+IHLeNBc`glK$wQ z_MAJUEGf?BPthyt%(?fT`#$Hp_nco}_`& lL=;9 zVl9;SW;SJ8W3AaxEChMq4JOtmH3AJwexU7A6VQkh02-B=fo@KDrQi+b4lMg4Tsuv% zEl}EWgDGz)?ttP=UlHz u|G11#GE;DBS`is7lH=`oI +UAL?*1h2JvD z;g)}ggW9?&KDZA`dO3n9LIflm4@`vCaANT*>C{#7CP-XTKH1dS76mSenov(TNu1v2 zlNN=w?y!~^VE(zam6HXfYz?qBCDGp8xX9jtMjx# xM#SU1ZXQ)jO}lwqAEJ%(V695G>1Gua<0=IONIqWVG8_0tqiRvrpSg_5~lVPav_9 zb()tuai+M&mJ(m$7VUSS`A4)1Y&$K;U3G!OCAK6i@*4yka&LVUhLMDlV{&yhi;nfO z=a`&ZjwrwFXem$IWi-WFDlt++$x^bGxRPBGKd|0`L;DC1jwXOV=P1}AYSTT|u#Y7Q zmr}CPPzRW_L~y=TR}ml+*?ci4lQAd*EutpHODP$&u3%Wkiq`-Z%Z@w&5RK=G+3Sr{ zP&YL-V0PO-A!jqaR>Ns#<7qjSEv)9`JRlV9nW}nkkf3%`L?p+MqodhhrZXhRu>^O= zuqR0>A*T$NS#!E 12u=KpF9L;#xM9lh+%i zA)dlz9HfggY&1hH#^7L6a07cAOv8K~cyrzp$d%LBDVs12R>F+a+!1r53>(cA&;+UN zJ~d#o7u;L||Ao6?HnYrQPf+(ns-BLDr{ivLu}$@KXr5u+Gdz2AS@hi;sfy8x7+si9 z#i%9@=wf-GDh^k~VNHBN7hhOmSljTjFL g%fby6zrTeO;Pwm+sp&XJ2;tZ@yV| zMJley!g JTYHl}U(31ew f&H zB>Qz32%vM_Ju_|3y>0fdXkwrZmm}F1h4tVELg#Du5D5Jr?J ipI!zq7*c)c7HtA9}*LZ5P-YjCNFf9d}z)Ux((~srz;Uj5c=s z^vHcqZ5-4Z2ld9mxiY^jw&-HCDt1@I?)&_wc2(@w#3Q p!3do=i^Y19@ O6sBH+{w9 a z0MN8d+VB;3e67eNx=}RM;cPADPNLG%1o*ZAaRJ{>Df_KKCE45@uuS4zZ%T4? 8pbshv zFJP`UYn?&P1;z_+7-Xr1Q)8UPEUxxm%@ vxRw)G4b;@eqna4j#jt7( z{|;>&`l0pt{%=x0iK{sifs$pxO1&abn&YT6rtj1QcmA_(X}AYHu!FUP>PmeYiMtM3 zwrE|i7oash<@s=H85G1`QxH@OxLojL4TpI+ad^@`RTRfYMZp`wuuG{-3h znHJ_1@qOht*pHU-f`3@Om*j{xBSHSXTYq-$2jc=XOq8!Oyk9zrADyU-zYHzGRn! z^^O70_(><#iw%W%4bwE~#_IB_uWK*auuZ+1`oFfDBkMg~$p&sDTLM|h{tQ g zKoUrjNZ=XDT=&+zz+xdqYCa%!=E&<5Y| e}D%gu0 zeLPTDLwC>ANYqyIH8X`Ao>s50##KW<(tH3-FhjupA?9%sqzI&dI7e{|2!%3pGS~`Z zW`*snawjxc1{dM0zSsYs>s4;_&z^YdfN{1hD+~~Hz`oJ{S`z&8mv3Fygw1o}oCr=N z`a0VmS|9bO$voJ{e(ofi$qwr900j$i(&qtCD7TG*tMlN$LjNY5xd0nNV*>_XC=!fD z8de&UgnebmZY1 RVZ%o@x&E~XA<&56vC6~-T(C}a{z?~k$elu9wc;rB66rp2A_H>nJI$1Pp> 2eDYlQEY?{uBz$9Unsu9~FibV?^fUgsIx(40k;`RST%tr$`*w zLJ(TiEqBA$e3Lk+`lKA7d*ovf{)Y$Kd%m!Sd&x;0%PUPLa^v~_!bG0P$zm<$u6%3z z|CC`*&AJJQ>(hnPohKLuq@EHDh|?%H4ItCtD~+C-K=Urj;RA@ghXgl@PT(FxpAmF+ z|1G?jg{XceHA4O#>haPkY~mPZ#lm*5>=NUerGHDzu==c@^0WRW >wFju5cEKqQxy;ih`*814U3Ik-d4hwpCwjI2ZI%%{cw@Mn_)IC^3qenS*c!k+W KMYD*m?SBDl&71rH delta 1898 zcmZ`(U2GIp6rMXfJ3H-kce`84Zhu{9ZC#Q6qL|RXP$(gSs1yl9%rfjuw@YVsmou}4 z0HJ7zG5R984<>5ji@_A45B3Fp^3lWxwn-nzBpQvx#1~V8`oN2xa~E{MFgx?@chAqg z=bn4cefJvs?o{lvXtY_vXYbw6!dIDVvGmGcIQl@cB#SwcLI1MDT-lHr@sJa86+;nR zal-Q?3p=VCF(N{y)@@zQ(8M_6G`Y=2v)~$X-OvSZa$4M|5f!}IiMeqjF1YTjw7Ll+ zfrAz+>LlGZqfIDc&K9@bXcs*0Y;{vc3VG{Q$w*rX#11Qo*lD#Pc3E2xyRCM_9y@Mr zy((SDP2Hq@ipS`+QmA{%N+V{h4#aI1J1S*6f0bfr@$xDQRIp2y4g5Vez!d%^tFFz+ zCs;y3byf}{V4tnpo)263jnG`U2c^liKSP)0r4&*~BLpGSaRT)<(=V0^foh*GdcFt3 zUxh9*XsJNis^ Nl*He-b%9 z03j5tGBK~m$m^j)x#XL9AD%;5AMe$=g~KerthG&%59~l_^az`$%T*tSP&`1YHiRqE z_j=;}!CKeQx<0(257(4o=v}+5^{Lt@s&U I)LvLomTNQu{QTEgQuNGU=|B85{(${jOPb4wVbV(p(wby6-;n*iR5Ac!i*e z;8g+ X^mxyM>fCut`SzLG@KJo%_4y5bzNXA$oi304ti6;&b8+NB#H#`| zT%d@y6V JAR?pm!vTaKVxP}DRlJfc5)BeWNgl?g zDgz}igu(DHCZC?nkWvJ 8t^29Z~)x2{>e-R2aR4S&w7^s%**uEXeMGFq| z*wnU>tp3O`pk<7*m0LEQqGkGJ2$ EkQ z4<)@F4$}Iq))})@C=YpyW$^P=-{ZgU`+EiGJ{5PIxVOY*Bzj+Tm1ql5+Vy