├── ims ├── __init__.py ├── asgi.py ├── wsgi.py ├── urls.py └── settings.py ├── ims_product ├── __init__.py ├── tests.py ├── apps.py ├── admin.py ├── urls.py ├── models.py ├── forms.py └── views.py ├── ims_user ├── __init__.py ├── tests.py ├── apps.py ├── admin.py ├── urls.py ├── models.py ├── forms.py └── views.py ├── ims_inventory ├── __init__.py ├── tests.py ├── apps.py ├── admin.py ├── urls.py ├── models.py ├── forms.py └── views.py ├── requirements.txt ├── README.md ├── db.sqlite3 ├── media ├── product │ ├── rain-coat.jpg │ ├── THUNDER-420X4201.png │ ├── hand-gloves-othoba.jpeg │ ├── THUNDER-420X4201_DivV58Y.png │ ├── THUNDER-420X4201_xk3bX55.png │ └── Nitrile-Surgical-Hand-Gloves-Blue-Color-Price-in-BD.jpg └── category │ ├── rain-coat.jpg │ ├── THUNDER-420X4201.png │ └── mobile-category.jpg ├── .gitignore ├── templates ├── category_add.html ├── login.html ├── product_add.html ├── sale_add.html ├── purchase_add.html ├── sale_list.html ├── customer_add.html ├── supplier_add.html ├── purchase_list.html ├── category_list.html ├── customer_list.html ├── supplier_list.html ├── product_list.html ├── base.html └── index.html ├── manage.py └── static └── bootstrap └── js └── bootstrap.bundle.min.js /ims/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ims_product/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ims_user/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ims_inventory/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django == 4.1.1 2 | Pillow -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # inventory-management-system-django -------------------------------------------------------------------------------- /ims_product/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /ims_user/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rkshaon/inventory-management-system-django/HEAD/db.sqlite3 -------------------------------------------------------------------------------- /ims_inventory/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /media/product/rain-coat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rkshaon/inventory-management-system-django/HEAD/media/product/rain-coat.jpg -------------------------------------------------------------------------------- /media/category/rain-coat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rkshaon/inventory-management-system-django/HEAD/media/category/rain-coat.jpg -------------------------------------------------------------------------------- /media/category/THUNDER-420X4201.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rkshaon/inventory-management-system-django/HEAD/media/category/THUNDER-420X4201.png -------------------------------------------------------------------------------- /media/category/mobile-category.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rkshaon/inventory-management-system-django/HEAD/media/category/mobile-category.jpg -------------------------------------------------------------------------------- /media/product/THUNDER-420X4201.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rkshaon/inventory-management-system-django/HEAD/media/product/THUNDER-420X4201.png -------------------------------------------------------------------------------- /media/product/hand-gloves-othoba.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rkshaon/inventory-management-system-django/HEAD/media/product/hand-gloves-othoba.jpeg -------------------------------------------------------------------------------- /media/product/THUNDER-420X4201_DivV58Y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rkshaon/inventory-management-system-django/HEAD/media/product/THUNDER-420X4201_DivV58Y.png -------------------------------------------------------------------------------- /media/product/THUNDER-420X4201_xk3bX55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rkshaon/inventory-management-system-django/HEAD/media/product/THUNDER-420X4201_xk3bX55.png -------------------------------------------------------------------------------- /ims_user/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ImsUserConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'ims_user' 7 | -------------------------------------------------------------------------------- /ims_product/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ImsProductConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'ims_product' 7 | -------------------------------------------------------------------------------- /ims_inventory/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ImsInventoryConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'ims_inventory' 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /env 2 | 3 | ims/__pycache__ 4 | ims_inventory/migrations/ 5 | ims_inventory/__pycache__ 6 | ims_product/migrations/ 7 | ims_product/__pycache__ 8 | ims_user/migrations/ 9 | ims_user/__pycache__ -------------------------------------------------------------------------------- /ims_user/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from ims_user.models import Supplier 4 | from ims_user.models import Customer 5 | 6 | admin.site.register(Supplier) 7 | admin.site.register(Customer) -------------------------------------------------------------------------------- /media/product/Nitrile-Surgical-Hand-Gloves-Blue-Color-Price-in-BD.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rkshaon/inventory-management-system-django/HEAD/media/product/Nitrile-Surgical-Hand-Gloves-Blue-Color-Price-in-BD.jpg -------------------------------------------------------------------------------- /ims_product/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from ims_product.models import Category 4 | from ims_product.models import Product 5 | 6 | 7 | admin.site.register(Category) 8 | admin.site.register(Product) -------------------------------------------------------------------------------- /ims_inventory/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from ims_inventory.models import Inventory 4 | from ims_inventory.models import Purchase 5 | from ims_inventory.models import Sale 6 | 7 | admin.site.register(Inventory) 8 | admin.site.register(Purchase) 9 | admin.site.register(Sale) -------------------------------------------------------------------------------- /ims_inventory/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from ims_inventory import views 4 | 5 | 6 | urlpatterns = [ 7 | path('purchase', views.purchase_list, name='purchase_list'), 8 | path('purchase/add', views.purchase_add, name='purchase_add'), 9 | path('sale', views.sale_list, name='sale_list'), 10 | path('sale/add', views.sale_add, name='sale_add'), 11 | ] -------------------------------------------------------------------------------- /ims_user/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from ims_user import views 4 | 5 | 6 | urlpatterns = [ 7 | path('supplier', views.supplier_list, name='supplier_list'), 8 | path('suppler/add', views.supplier_add, name='supplier_add'), 9 | path('customer', views.customer_list, name='customer_list'), 10 | path('customer/add', views.customer_add, name='customer_add'), 11 | ] -------------------------------------------------------------------------------- /ims/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for ims project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ims.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /ims/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for ims project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ims.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /ims_product/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from ims_product import views 4 | 5 | urlpatterns = [ 6 | path('category', views.category_list, name='category_list'), 7 | path('category/add', views.category_add, name='category_add'), 8 | path('category/delete/', views.category_delete, name='category_delete'), 9 | path('', views.product_list, name='product_list'), 10 | path('add', views.product_add, name='product_add'), 11 | path('delete/', views.product_delete, name='product_delete'), 12 | ] -------------------------------------------------------------------------------- /templates/category_add.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Add Category

7 | Show List 8 |
9 | {% csrf_token %} 10 |
11 | 12 | {{ form.name }} 13 |
14 |
15 | 16 | {{ form.image }} 17 |
18 | 19 |
20 | {% endblock %} -------------------------------------------------------------------------------- /templates/login.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |
7 | {% csrf_token %} 8 |
9 | 10 | 11 |
12 |
13 | 14 | 15 |
16 | 17 |
18 | {% endblock %} -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ims.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /templates/product_add.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Add Category

7 | Show List 8 |
9 | {% csrf_token %} 10 |
11 | 12 | {{ form.name }} 13 |
14 |
15 | 16 | {{ form.image }} 17 |
18 |
19 | 20 | {{ form.category }} 21 |
22 | 23 |
24 | {% endblock %} -------------------------------------------------------------------------------- /ims_product/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Category(models.Model): 5 | name = models.CharField(max_length=200, null=False, blank=False) 6 | image = models.ImageField(upload_to='category', null=True, blank=True) 7 | is_deleted = models.BooleanField(default=False) 8 | added_date_time = models.DateTimeField(auto_now_add=True) 9 | 10 | def __str__(self): 11 | return self.name 12 | 13 | 14 | class Product(models.Model): 15 | name = models.CharField(max_length=200, null=False, blank=False) 16 | image = models.ImageField(upload_to='product', null=True, blank=True) 17 | category = models.ForeignKey(Category, on_delete=models.CASCADE) 18 | is_deleted = models.BooleanField(default=False) 19 | added_date_time = models.DateTimeField(auto_now_add=True) 20 | 21 | def __str__(self): 22 | return self.name -------------------------------------------------------------------------------- /templates/sale_add.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Add Sale

7 | Show List 8 | Customer Add (+) 9 |
10 | {% csrf_token %} 11 |
12 | 13 | {{ form.customer }} 14 |
15 |
16 | 17 | {{ form.inventory }} 18 |
19 |
20 | 21 | {{ form.quantity }} 22 |
23 | 24 |
25 | {% endblock %} -------------------------------------------------------------------------------- /templates/purchase_add.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Add Purchase

7 | Show List 8 | Add Supplier (+) 9 |
10 | {% csrf_token %} 11 |
12 | 13 | {{ form.product }} 14 |
15 |
16 | 17 | {{ form.supplier }} 18 |
19 |
20 | 21 | {{ form.quantity }} 22 |
23 | 24 |
25 | {% endblock %} -------------------------------------------------------------------------------- /templates/sale_list.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Sale

7 | Customer List (+) 8 | Add (+) 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% for sale in sales %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 | 28 |
CustomerProductQuantityDate
{{ sale.customer }}{{ sale.quantity }}{{ sale.inventory.product.name }}{{ sale.added_date_time }}
29 | {% endblock %} -------------------------------------------------------------------------------- /templates/customer_add.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Add Customer

7 | Show List 8 |
9 | {% csrf_token %} 10 |
11 | 12 | {{ form.name }} 13 |
14 |
15 | 16 | {{ form.address }} 17 |
18 |
19 | 20 | {{ form.email }} 21 |
22 |
23 | 24 | {{ form.cell }} 25 |
26 | 27 |
28 | {% endblock %} -------------------------------------------------------------------------------- /templates/supplier_add.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Add Supplier

7 | Show List 8 |
9 | {% csrf_token %} 10 |
11 | 12 | {{ form.name }} 13 |
14 |
15 | 16 | {{ form.address }} 17 |
18 |
19 | 20 | {{ form.email }} 21 |
22 |
23 | 24 | {{ form.cell }} 25 |
26 | 27 |
28 | {% endblock %} -------------------------------------------------------------------------------- /templates/purchase_list.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Purchase

7 | Supplier List (+) 8 | Add (+) 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% for purchase in purchases %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 | 28 |
ProductQuantitySupplierDate
{{ purchase.product }}{{ purchase.quantity }}{{ purchase.supplier }}{{ purchase.added_date_time }}
29 | {% endblock %} -------------------------------------------------------------------------------- /templates/category_list.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Category

7 | Add (+) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% for category in categories %} 18 | 19 | 20 | 23 | 24 | 25 | {% endfor %} 26 | 27 |
Category NameImageAction
{{ category.name }} 21 | {{ category.name }} 22 | Delete
28 | {% endblock %} -------------------------------------------------------------------------------- /templates/customer_list.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Customer

7 | Add (+) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% for customer in customers %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {% endfor %} 28 | 29 |
NameAddressE-mailCell NoAction
{{ customer.name }}{{ customer.address }}{{ customer.email }}{{ customer.cell }}
30 | {% endblock %} -------------------------------------------------------------------------------- /templates/supplier_list.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Supplier

7 | Add (+) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% for supplier in suppliers %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {% endfor %} 28 | 29 |
NameAddressE-mailCell NoAction
{{ supplier.name }}{{ supplier.address }}{{ supplier.email }}{{ supplier.cell }}
30 | {% endblock %} -------------------------------------------------------------------------------- /templates/product_list.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |

Products

7 | Add (+) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% for product in products %} 19 | 20 | 21 | 22 | 25 | 26 | 27 | {% endfor %} 28 | 29 |
NameCategoryImageAction
{{ product.name }}{{ product.category }} 23 | {{ product.name }} 24 | Delete
30 | {% endblock %} -------------------------------------------------------------------------------- /ims_user/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Supplier(models.Model): 5 | name = models.CharField(max_length=200, blank=False, null=False) 6 | address = models.TextField(blank=True, null=True) 7 | email = models.EmailField(blank=True, null=True) 8 | cell = models.CharField(max_length=500, null=True, blank=True) 9 | is_deleted = models.BooleanField(default=False) 10 | added_date_time = models.DateTimeField(auto_now_add=True) 11 | 12 | def __str__(self): 13 | return self.name 14 | 15 | 16 | class Customer(models.Model): 17 | name = models.CharField(max_length=200, blank=False, null=False) 18 | address = models.TextField(blank=True, null=True) 19 | email = models.EmailField(blank=True, null=True) 20 | cell = models.CharField(max_length=500, null=True, blank=True) 21 | is_deleted = models.BooleanField(default=False) 22 | added_date_time = models.DateTimeField(auto_now_add=True) 23 | 24 | def __str__(self): 25 | return self.name -------------------------------------------------------------------------------- /ims_product/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.forms import ClearableFileInput 3 | 4 | from ims_product.models import Category 5 | from ims_product.models import Product 6 | 7 | 8 | class NewCategoryForm(forms.ModelForm): 9 | name = forms.CharField(widget=forms.TextInput(attrs={ 10 | 'class': 'form-control', 11 | 'placeholder': 'Enter category name', 12 | }), required=True) 13 | image = forms.FileField(widget=forms.ClearableFileInput(attrs={'class': 'form-control'}), required=False) 14 | 15 | class Meta: 16 | model = Category 17 | fields = {'name', 'image'} 18 | 19 | 20 | class NewProductForm(forms.ModelForm): 21 | name = forms.CharField(widget=forms.TextInput(attrs={ 22 | 'class': 'form-control', 23 | 'placeholder': 'Enter product name', 24 | }), required=True) 25 | image = forms.FileField(widget=forms.ClearableFileInput(attrs={'class': 'form-control'}), required=False) 26 | category = forms.ModelChoiceField(queryset=Category.objects.filter(is_deleted=False), widget=forms.Select(attrs={ 27 | 'class': 'form-control', 28 | }), required=True) 29 | 30 | class Meta: 31 | model = Product 32 | fields = { 33 | 'name', 'image', 'category' 34 | } -------------------------------------------------------------------------------- /ims_inventory/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Inventory(models.Model): 5 | product = models.ForeignKey('ims_product.Product', on_delete=models.CASCADE) 6 | quantity = models.FloatField(default=0.0, blank=False, null=False) 7 | 8 | def __str__(self): 9 | return str(self.product.name) + ' - in stoke ' + str(self.quantity) + ' quantity' 10 | 11 | 12 | class Purchase(models.Model): 13 | quantity = models.FloatField(default=0.0, blank=False, null=False) 14 | product = models.ForeignKey('ims_product.Product', on_delete=models.CASCADE) 15 | supplier = models.ForeignKey('ims_user.Supplier', on_delete=models.CASCADE) 16 | added_date_time = models.DateTimeField(auto_now_add=True) 17 | 18 | def __str__(self): 19 | return 'product: ' + str(self.product.name) + ' from ' + str(self.supplier.name) 20 | 21 | 22 | class Sale(models.Model): 23 | inventory = models.ForeignKey(Inventory, on_delete=models.CASCADE) 24 | quantity = models.FloatField(default=0.0, blank=False, null=False) 25 | customer = models.ForeignKey('ims_user.Customer', on_delete=models.CASCADE) 26 | added_date_time = models.DateTimeField(auto_now_add=True) 27 | 28 | def __str__(self): 29 | return 'product: ' + str(self.inventory.product.name) + ' quantity: ' + str(self.quantity) -------------------------------------------------------------------------------- /ims/urls.py: -------------------------------------------------------------------------------- 1 | """ims URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/4.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | 19 | from django.conf import settings 20 | from django.conf.urls.static import static 21 | 22 | from ims_inventory import views as inventory_view 23 | from ims_user import views as user_view 24 | 25 | urlpatterns = [ 26 | path('admin/', admin.site.urls), 27 | path('', inventory_view.index, name='index'), 28 | path('login', user_view.user_login, name='login'), 29 | path('logout', user_view.user_logout, name='logout'), 30 | path('product/', include('ims_product.urls')), 31 | path('inventory/', include('ims_inventory.urls')), 32 | path('user/', include('ims_user.urls')), 33 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) -------------------------------------------------------------------------------- /ims_inventory/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | from ims_product.models import Product 4 | from ims_user.models import Supplier 5 | from ims_user.models import Customer 6 | from ims_inventory.models import Purchase 7 | from ims_inventory.models import Inventory 8 | from ims_inventory.models import Sale 9 | 10 | 11 | class NewPurchaseForm(forms.ModelForm): 12 | quantity = forms.DecimalField(widget=forms.TextInput(attrs={ 13 | 'class': 'form-control', 14 | 'placeholder': 'Enter quantity of the product', 15 | }), required=True) 16 | product = forms.ModelChoiceField(queryset=Product.objects.filter(is_deleted=False), widget=forms.Select(attrs={ 17 | 'class': 'form-control', 18 | }), required=True) 19 | supplier = forms.ModelChoiceField(queryset=Supplier.objects.all(), widget=forms.Select(attrs={ 20 | 'class': 'form-control', 21 | }), required=True) 22 | 23 | class Meta: 24 | model = Purchase 25 | fields = {'quantity', 'product'} 26 | 27 | 28 | class NewSaleForm(forms.ModelForm): 29 | quantity = forms.DecimalField(widget=forms.TextInput(attrs={ 30 | 'class': 'form-control', 31 | 'placeholder': 'Enter quantity of the product', 32 | }), required=True) 33 | inventory = forms.ModelChoiceField(queryset=Inventory.objects.all(), widget=forms.Select(attrs={ 34 | 'class': 'form-control', 35 | }), required=True) 36 | customer = forms.ModelChoiceField(queryset=Customer.objects.all(), widget=forms.Select(attrs={ 37 | 'class': 'form-control', 38 | }), required=True) 39 | 40 | class Meta: 41 | model = Sale 42 | fields = {'quantity', 'inventory', 'customer'} -------------------------------------------------------------------------------- /ims_user/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | from ims_user.models import Supplier 4 | from ims_user.models import Customer 5 | 6 | 7 | class NewSupplierForm(forms.ModelForm): 8 | name = forms.CharField(widget=forms.TextInput(attrs={ 9 | 'class': 'form-control', 10 | 'placeholder': 'Enter supplier name', 11 | }), required=True) 12 | address = forms.CharField(widget=forms.Textarea(attrs={ 13 | 'class': 'form-control', 14 | 'placeholder': 'Enter full address', 15 | 'rows': '3', 16 | }), required=False) 17 | email = forms.EmailField(widget=forms.TextInput(attrs={ 18 | 'class': 'form-control', 19 | 'placeholder': 'Enter e-mail address', 20 | }), required=False) 21 | cell = forms.CharField(widget=forms.TextInput(attrs={ 22 | 'class': 'form-control', 23 | 'placeholder': 'Enter cell number', 24 | }), required=False) 25 | 26 | class Meta: 27 | model = Supplier 28 | fields = {'name', 'address', 'email', 'cell'} 29 | 30 | 31 | class NewCustomerForm(forms.ModelForm): 32 | name = forms.CharField(widget=forms.TextInput(attrs={ 33 | 'class': 'form-control', 34 | 'placeholder': 'Enter supplier name', 35 | }), required=True) 36 | address = forms.CharField(widget=forms.Textarea(attrs={ 37 | 'class': 'form-control', 38 | 'placeholder': 'Enter full address', 39 | 'rows': '3', 40 | }), required=False) 41 | email = forms.EmailField(widget=forms.TextInput(attrs={ 42 | 'class': 'form-control', 43 | 'placeholder': 'Enter e-mail address', 44 | }), required=False) 45 | cell = forms.CharField(widget=forms.TextInput(attrs={ 46 | 'class': 'form-control', 47 | 'placeholder': 'Enter cell number', 48 | }), required=False) 49 | 50 | class Meta: 51 | model = Customer 52 | fields = {'name', 'address', 'email', 'cell'} 53 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | I M S 7 | 8 | 9 | 10 | 11 | 12 | 31 | {% if messages %} 32 | 33 | {% for message in messages %} 34 | 35 | 38 | {% endfor %} 39 | {% endif %} 40 |
41 | {% block content %} 42 | 43 | {% endblock %} 44 |
45 | 46 | 47 | -------------------------------------------------------------------------------- /ims_product/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, redirect 2 | from django.contrib import messages 3 | from django.contrib.auth.decorators import login_required 4 | 5 | from ims_product.models import Category 6 | from ims_product.models import Product 7 | 8 | from ims_product.forms import NewCategoryForm 9 | from ims_product.forms import NewProductForm 10 | 11 | 12 | @login_required(login_url='login') 13 | def category_list(request): 14 | categories = Category.objects.filter(is_deleted=False).order_by('name') 15 | 16 | context = { 17 | 'categories': categories, 18 | } 19 | 20 | return render(request, 'category_list.html', context) 21 | 22 | 23 | @login_required(login_url='login') 24 | def category_add(request): 25 | if request.method == 'POST': 26 | form = NewCategoryForm(request.POST, request.FILES) 27 | 28 | if form.is_valid(): 29 | image = request.FILES.get('image') 30 | name = request.POST.get('name') 31 | 32 | category = Category.objects.create(name=name, image=image) 33 | 34 | messages.info(request, 'Category added successfully!') 35 | 36 | return redirect('category_list') 37 | 38 | form = NewCategoryForm() 39 | 40 | context = { 41 | 'form': form, 42 | } 43 | 44 | return render(request, 'category_add.html', context) 45 | 46 | 47 | @login_required(login_url='login') 48 | def category_delete(request, pk): 49 | category = Category.objects.get(id=pk) 50 | category.is_deleted = True 51 | 52 | category.save() 53 | 54 | return redirect('category_list') 55 | 56 | 57 | @login_required(login_url='login') 58 | def product_list(request): 59 | products = Product.objects.filter(is_deleted=False).order_by('category__name') 60 | 61 | context = { 62 | 'products': products, 63 | } 64 | 65 | return render(request, 'product_list.html', context) 66 | 67 | 68 | @login_required(login_url='login') 69 | def product_add(request): 70 | if request.method == 'POST': 71 | form = NewProductForm(request.POST, request.FILES) 72 | 73 | if form.is_valid(): 74 | name = request.POST.get('name') 75 | image = request.FILES.get('image') 76 | category = Category.objects.get(id=request.POST.get('category')) 77 | 78 | product = Product.objects.create(name=name, image=image, category=category) 79 | 80 | messages.info(request, 'Product added successfully!') 81 | 82 | return redirect('product_list') 83 | 84 | form = NewProductForm() 85 | 86 | context = { 87 | 'form': form, 88 | } 89 | 90 | return render(request, 'product_add.html', context) 91 | 92 | 93 | @login_required(login_url='login') 94 | def product_delete(request, pk): 95 | product = Product.objects.get(id=pk) 96 | product.is_deleted = True 97 | product.save() 98 | 99 | return redirect('product_list') -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | {% include 'base.html' %} 4 | 5 | {% block body %} 6 |
7 |

Products in stock now {{total_inventory_products_count}} pcs now.

8 |

Available {{ total_products }} products in {{ total_categories }} categories.

9 |

Current customer {{ total_customers }} persons.

10 |

Current supplier {{ total_suppliers }} persons.

11 |
12 |

Customer added last 7 days

13 | View All Customer (+) 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {% for customer in customers %} 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% endfor %} 32 | 33 |
NameAddressE-mailCell No
{{ customer.name }}{{ customer.address }}{{ customer.email }}{{ customer.cell }}
34 |

Supplier added last 7 days

35 | View All Supplier (+) 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | {% for supplier in suppliers %} 47 | 48 | 49 | 50 | 51 | 52 | 53 | {% endfor %} 54 | 55 |
NameAddressE-mailCell No
{{ supplier.name }}{{ supplier.address }}{{ supplier.email }}{{ supplier.cell }}
56 |

Purchased last 7 days

57 | View All Purchases (+) 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | {% for purchase in purchases %} 69 | 70 | 71 | 72 | 73 | 74 | 75 | {% endfor %} 76 | 77 |
ProductQuantitySupplierDate
{{ purchase.product }}{{ purchase.quantity }}{{ purchase.supplier }}{{ purchase.added_date_time }}
78 |

Sale last 7 days

79 | View All Sales (+) 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | {% for sale in sales %} 91 | 92 | 93 | 94 | 95 | 96 | 97 | {% endfor %} 98 | 99 |
CustomerProductQuantityDate
{{ sale.customer }}{{ sale.quantity }}{{ sale.inventory.product.name }}{{ sale.added_date_time }}
100 | {% endblock %} -------------------------------------------------------------------------------- /ims_user/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, redirect 2 | from django.contrib import messages 3 | from django.contrib.auth import authenticate, login, logout 4 | from django.contrib.auth.decorators import login_required 5 | 6 | from django.contrib.auth.models import User 7 | from ims_user.models import Supplier 8 | from ims_user.models import Customer 9 | 10 | from ims_user.forms import NewSupplierForm 11 | from ims_user.forms import NewCustomerForm 12 | 13 | 14 | def user_login(request): 15 | if request.user.is_authenticated: 16 | return redirect('index') 17 | 18 | if request.method == 'POST': 19 | username = request.POST.get('username') 20 | password = request.POST.get('password') 21 | 22 | user = authenticate(request, username=username, password=password) 23 | 24 | if user is not None: 25 | login(request, user) 26 | messages.info(request, 'Successfully logged in, congrats!') 27 | return redirect('index') 28 | else: 29 | messages.info(request, 'Username OR password is incorrect') 30 | 31 | context = {} 32 | 33 | return render(request, 'login.html', context) 34 | 35 | 36 | def user_logout(request): 37 | logout(request) 38 | return redirect('login') 39 | 40 | @login_required(login_url='login') 41 | def supplier_list(request): 42 | suppliers = Supplier.objects.all() 43 | 44 | context = { 45 | 'suppliers': suppliers, 46 | } 47 | 48 | return render(request, 'supplier_list.html', context) 49 | 50 | 51 | @login_required(login_url='login') 52 | def supplier_add(request): 53 | if request.method == 'POST': 54 | form = NewSupplierForm(request.POST) 55 | 56 | if form.is_valid(): 57 | name = request.POST.get('name') 58 | address = request.POST.get('address') 59 | email = request.POST.get('email') 60 | cell = request.POST.get('cell') 61 | 62 | s, created = Supplier.objects.get_or_create( 63 | name=name, address=address, email=email, cell=cell) 64 | 65 | messages.info(request, 'Supplier added successfully!') 66 | 67 | return redirect('supplier_list') 68 | 69 | form = NewSupplierForm() 70 | 71 | context = { 72 | 'form': form, 73 | } 74 | 75 | return render(request, 'supplier_add.html', context) 76 | 77 | 78 | @login_required(login_url='login') 79 | def customer_list(request): 80 | customers = Customer.objects.all() 81 | 82 | context = { 83 | 'customers': customers, 84 | } 85 | 86 | return render(request, 'customer_list.html', context) 87 | 88 | 89 | @login_required(login_url='login') 90 | def customer_add(request): 91 | if request.method == 'POST': 92 | form = NewSupplierForm(request.POST) 93 | 94 | if form.is_valid(): 95 | name = request.POST.get('name') 96 | address = request.POST.get('address') 97 | email = request.POST.get('email') 98 | cell = request.POST.get('cell') 99 | 100 | c, created = Customer.objects.get_or_create( 101 | name=name, address=address, email=email, cell=cell) 102 | 103 | messages.info(request, 'Customer added successfully!') 104 | 105 | return redirect('customer_list') 106 | 107 | form = NewCustomerForm() 108 | 109 | context = { 110 | 'form': form 111 | } 112 | 113 | return render(request, 'customer_add.html', context) -------------------------------------------------------------------------------- /ims/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for ims project. 3 | 4 | Generated by 'django-admin startproject' using Django 4.1.1. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.1/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/4.1/ref/settings/ 11 | """ 12 | 13 | from pathlib import Path 14 | 15 | import os 16 | 17 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 18 | BASE_DIR = Path(__file__).resolve().parent.parent 19 | 20 | 21 | # Quick-start development settings - unsuitable for production 22 | # See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ 23 | 24 | # SECURITY WARNING: keep the secret key used in production secret! 25 | SECRET_KEY = 'django-insecure-_$)^64q09ohi!caqx=_91s(+^$(x3=7usjuwf176hi_#khdoo#' 26 | 27 | # SECURITY WARNING: don't run with debug turned on in production! 28 | DEBUG = True 29 | 30 | ALLOWED_HOSTS = [ 31 | 'joymoung.pythonanywhere.com', 32 | ] 33 | 34 | 35 | # Application definition 36 | 37 | INSTALLED_APPS = [ 38 | 'django.contrib.admin', 39 | 'django.contrib.auth', 40 | 'django.contrib.contenttypes', 41 | 'django.contrib.sessions', 42 | 'django.contrib.messages', 43 | 'django.contrib.staticfiles', 44 | 'ims_product', 45 | 'ims_user', 46 | 'ims_inventory', 47 | ] 48 | 49 | MIDDLEWARE = [ 50 | 'django.middleware.security.SecurityMiddleware', 51 | 'django.contrib.sessions.middleware.SessionMiddleware', 52 | 'django.middleware.common.CommonMiddleware', 53 | 'django.middleware.csrf.CsrfViewMiddleware', 54 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 55 | 'django.contrib.messages.middleware.MessageMiddleware', 56 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 57 | ] 58 | 59 | ROOT_URLCONF = 'ims.urls' 60 | 61 | TEMPLATES = [ 62 | { 63 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 64 | 'DIRS': [ 65 | os.path.join(BASE_DIR, 'templates'), 66 | ], 67 | 'APP_DIRS': True, 68 | 'OPTIONS': { 69 | 'context_processors': [ 70 | 'django.template.context_processors.debug', 71 | 'django.template.context_processors.request', 72 | 'django.contrib.auth.context_processors.auth', 73 | 'django.contrib.messages.context_processors.messages', 74 | ], 75 | }, 76 | }, 77 | ] 78 | 79 | WSGI_APPLICATION = 'ims.wsgi.application' 80 | 81 | 82 | # Database 83 | # https://docs.djangoproject.com/en/4.1/ref/settings/#databases 84 | 85 | DATABASES = { 86 | 'default': { 87 | 'ENGINE': 'django.db.backends.sqlite3', 88 | 'NAME': BASE_DIR / 'db.sqlite3', 89 | } 90 | } 91 | 92 | 93 | # Password validation 94 | # https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators 95 | 96 | AUTH_PASSWORD_VALIDATORS = [ 97 | { 98 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 99 | }, 100 | { 101 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 102 | }, 103 | { 104 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 105 | }, 106 | { 107 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 108 | }, 109 | ] 110 | 111 | 112 | # Internationalization 113 | # https://docs.djangoproject.com/en/4.1/topics/i18n/ 114 | 115 | LANGUAGE_CODE = 'en-us' 116 | 117 | TIME_ZONE = 'UTC' 118 | 119 | USE_I18N = True 120 | 121 | USE_TZ = True 122 | 123 | 124 | # Static files (CSS, JavaScript, Images) 125 | # https://docs.djangoproject.com/en/4.1/howto/static-files/ 126 | 127 | STATIC_URL = 'static/' 128 | 129 | # Media Files 130 | MEDIA_URL = '/media/' 131 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 132 | 133 | # Default primary key field type 134 | # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field 135 | 136 | DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' 137 | 138 | LOGIN_REDIRECT_URL = "/login" 139 | -------------------------------------------------------------------------------- /ims_inventory/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, redirect 2 | from django.contrib.auth.decorators import login_required 3 | from django.contrib import messages 4 | from django.db.models import Sum 5 | 6 | import datetime 7 | 8 | from ims_product.models import Category 9 | from ims_product.models import Product 10 | from ims_user.models import Supplier 11 | from ims_user.models import Customer 12 | from ims_inventory.models import Inventory 13 | from ims_inventory.models import Purchase 14 | from ims_inventory.models import Sale 15 | 16 | from ims_inventory.forms import NewPurchaseForm 17 | from ims_inventory.forms import NewSaleForm 18 | 19 | 20 | @login_required(login_url='login') 21 | def index(request): 22 | inventories = Inventory.objects.all().order_by('-quantity') 23 | total_inventory_products_count = Inventory.objects.all().aggregate(Sum('quantity')) 24 | total_categories = Category.objects.filter(is_deleted=False).count() 25 | total_products = Product.objects.filter(is_deleted=False).count() 26 | total_customers = Customer.objects.filter(is_deleted=False).count() 27 | total_suppliers = Supplier.objects.filter(is_deleted=False).count() 28 | customers = Customer.objects.filter(is_deleted=False, added_date_time__gte=datetime.datetime.now()-datetime.timedelta(days=7)) 29 | suppliers = Supplier.objects.filter(is_deleted=False, added_date_time__gte=datetime.datetime.now()-datetime.timedelta(days=7)) 30 | purchases = Purchase.objects.filter(added_date_time__gte=datetime.datetime.now()-datetime.timedelta(days=7)) 31 | sales = Sale.objects.filter(added_date_time__gte=datetime.datetime.now()-datetime.timedelta(days=7)) 32 | 33 | context = { 34 | 'inventories': inventories, 35 | 'total_inventory_products_count': total_inventory_products_count['quantity__sum'], 36 | 'total_categories': total_categories, 37 | 'total_products': total_products, 38 | 'total_customers': total_customers, 39 | 'total_suppliers': total_suppliers, 40 | 'customers': customers, 41 | 'suppliers': suppliers, 42 | 'purchases': purchases, 43 | 'sales': sales, 44 | } 45 | 46 | return render(request, 'index.html', context) 47 | 48 | 49 | @login_required(login_url='login') 50 | def purchase_list(request): 51 | purchases = Purchase.objects.all().order_by('-id') 52 | 53 | context = { 54 | 'purchases': purchases, 55 | } 56 | 57 | return render(request, 'purchase_list.html', context) 58 | 59 | 60 | @login_required(login_url='login') 61 | def purchase_add(request): 62 | if request.method == 'POST': 63 | form = NewPurchaseForm(request.POST) 64 | 65 | if form.is_valid(): 66 | quantity = request.POST.get('quantity') 67 | supplier = Supplier.objects.get(id=request.POST.get('supplier')) 68 | product = Product.objects.get(id=request.POST.get('product')) 69 | 70 | purchase = Purchase.objects.create( 71 | quantity=quantity, supplier=supplier, product=product 72 | ) 73 | 74 | inventory, created = Inventory.objects.get_or_create( 75 | product=product 76 | ) 77 | 78 | inventory.quantity = inventory.quantity + float(quantity) 79 | inventory.save() 80 | 81 | messages.info(request, 'Product purchase added successfully!') 82 | 83 | return redirect('purchase_list') 84 | 85 | form = NewPurchaseForm() 86 | 87 | context = { 88 | 'form': form, 89 | } 90 | 91 | return render(request, 'purchase_add.html', context) 92 | 93 | 94 | @login_required(login_url='login') 95 | def sale_list(request): 96 | sales = Sale.objects.all().order_by('-id') 97 | 98 | context = { 99 | 'sales': sales, 100 | } 101 | 102 | return render(request, 'sale_list.html', context) 103 | 104 | 105 | @login_required(login_url='login') 106 | def sale_add(request): 107 | if request.method == 'POST': 108 | form = NewSaleForm(request.POST) 109 | 110 | if form.is_valid(): 111 | customer = Customer.objects.get(id=request.POST.get('customer')) 112 | inventory = Inventory.objects.get(id=request.POST.get('inventory')) 113 | quantity = request.POST.get('quantity') 114 | 115 | sale = Sale.objects.create(customer=customer, inventory=inventory, quantity=quantity) 116 | 117 | inventory.quantity = inventory.quantity - float(quantity) 118 | inventory.save() 119 | 120 | messages.info(request, 'Product sale added successfully!') 121 | 122 | return redirect('sale_list') 123 | 124 | form = NewSaleForm() 125 | 126 | context = { 127 | 'form': form, 128 | } 129 | 130 | return render(request, 'sale_add.html', context) -------------------------------------------------------------------------------- /static/bootstrap/js/bootstrap.bundle.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v5.2.0 (https://getbootstrap.com/) 3 | * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=e=>{e.dispatchEvent(new Event(t))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,g=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},m=t=>{"function"==typeof t&&t()},_=(e,i,n=!0)=>{if(!n)return void m(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(i)+5;let r=!1;const a=({target:n})=>{n===i&&(r=!0,i.removeEventListener(t,a),m(e))};i.addEventListener(t,a),setTimeout((()=>{r||s(i)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=N(t);return C.has(o)||(o=t),[n,s,o]}function D(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return j(s,{delegateTarget:r}),n.oneOff&&P.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return j(n,{delegateTarget:t}),i.oneOff&&P.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function S(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function I(t,e,i,n){const s=e[i]||{};for(const o of Object.keys(s))if(o.includes(n)){const n=s[o];S(t,e,i,n.callable,n.delegationSelector)}}function N(t){return t=t.replace(y,""),T[t]||t}const P={on(t,e,i,n){D(t,e,i,n,!1)},one(t,e,i,n){D(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))I(t,l,i,e.slice(1));for(const i of Object.keys(c)){const n=i.replace(w,"");if(!a||e.includes(n)){const e=c[i];S(t,l,r,e.callable,e.delegationSelector)}}}else{if(!Object.keys(c).length)return;S(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==N(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());let l=new Event(e,{bubbles:o,cancelable:!0});return l=j(l,i),a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function j(t,e){for(const[i,n]of Object.entries(e||{}))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}const M=new Map,H={set(t,e,i){M.has(t)||M.set(t,new Map);const n=M.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>M.has(t)&&M.get(t).get(e)||null,remove(t,e){if(!M.has(t))return;const i=M.get(t);i.delete(e),0===i.size&&M.delete(t)}};function $(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function W(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const B={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${W(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${W(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=$(t.dataset[n])}return e},getDataAttribute:(t,e)=>$(t.getAttribute(`data-bs-${W(e)}`))};class F{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?B.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?B.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const n of Object.keys(e)){const s=e[n],r=t[n],a=o(r)?"element":null==(i=r)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(a))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)}var i}}class z extends F{constructor(t,e){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(e),H.set(this._element,this.constructor.DATA_KEY,this))}dispose(){H.remove(this._element,this.constructor.DATA_KEY),P.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return H.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.2.0"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,s=t.NAME;P.on(document,i,`[data-bs-dismiss="${s}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const o=n(this)||this.closest(`.${s}`);t.getOrCreateInstance(o)[e]()}))};class q extends z{static get NAME(){return"alert"}close(){if(P.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),P.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(q,"close"),g(q);const V='[data-bs-toggle="button"]';class K extends z{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=K.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}P.on(document,"click.bs.button.data-api",V,(t=>{t.preventDefault();const e=t.target.closest(V);K.getOrCreateInstance(e).toggle()})),g(K);const Q={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))}},X={endCallback:null,leftCallback:null,rightCallback:null},Y={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class U extends F{constructor(t,e){super(),this._element=t,t&&U.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return X}static get DefaultType(){return Y}static get NAME(){return"swipe"}dispose(){P.off(this._element,".bs.swipe")}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),m(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&m(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(P.on(this._element,"pointerdown.bs.swipe",(t=>this._start(t))),P.on(this._element,"pointerup.bs.swipe",(t=>this._end(t))),this._element.classList.add("pointer-event")):(P.on(this._element,"touchstart.bs.swipe",(t=>this._start(t))),P.on(this._element,"touchmove.bs.swipe",(t=>this._move(t))),P.on(this._element,"touchend.bs.swipe",(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const G="next",J="prev",Z="left",tt="right",et="slid.bs.carousel",it="carousel",nt="active",st={ArrowLeft:tt,ArrowRight:Z},ot={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},rt={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class at extends z{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=Q.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===it&&this.cycle()}static get Default(){return ot}static get DefaultType(){return rt}static get NAME(){return"carousel"}next(){this._slide(G)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(J)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?P.one(this._element,et,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void P.one(this._element,et,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?G:J;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&P.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(P.on(this._element,"mouseenter.bs.carousel",(()=>this.pause())),P.on(this._element,"mouseleave.bs.carousel",(()=>this._maybeEnableCycle()))),this._config.touch&&U.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of Q.find(".carousel-item img",this._element))P.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(Z)),rightCallback:()=>this._slide(this._directionToOrder(tt)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new U(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=st[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=Q.findOne(".active",this._indicatorsElement);e.classList.remove(nt),e.removeAttribute("aria-current");const i=Q.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(nt),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===G,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>P.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r("slide.bs.carousel").defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(nt),i.classList.remove(nt,c,l),this._isSliding=!1,r(et)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return Q.findOne(".active.carousel-item",this._element)}_getItems(){return Q.find(".carousel-item",this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===Z?J:G:t===Z?G:J}_orderToDirection(t){return p()?t===J?Z:tt:t===J?tt:Z}static jQueryInterface(t){return this.each((function(){const e=at.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}P.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",(function(t){const e=n(this);if(!e||!e.classList.contains(it))return;t.preventDefault();const i=at.getOrCreateInstance(e),s=this.getAttribute("data-bs-slide-to");return s?(i.to(s),void i._maybeEnableCycle()):"next"===B.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),P.on(window,"load.bs.carousel.data-api",(()=>{const t=Q.find('[data-bs-ride="carousel"]');for(const e of t)at.getOrCreateInstance(e)})),g(at);const lt="show",ct="collapse",ht="collapsing",dt='[data-bs-toggle="collapse"]',ut={parent:null,toggle:!0},ft={parent:"(null|element)",toggle:"boolean"};class pt extends z{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const n=Q.find(dt);for(const t of n){const e=i(t),n=Q.find(e).filter((t=>t===this._element));null!==e&&n.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return ut}static get DefaultType(){return ft}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>pt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(P.trigger(this._element,"show.bs.collapse").defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(ct),this._element.classList.add(ht),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct,lt),this._element.style[e]="",P.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(P.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(ht),this._element.classList.remove(ct,lt);for(const t of this._triggerArray){const e=n(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct),P.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(lt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(dt);for(const e of t){const t=n(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=Q.find(":scope .collapse .collapse",this._config.parent);return Q.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=pt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}P.on(document,"click.bs.collapse.data-api",dt,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=i(this),n=Q.find(e);for(const t of n)pt.getOrCreateInstance(t,{toggle:!1}).toggle()})),g(pt);var gt="top",mt="bottom",_t="right",bt="left",vt="auto",yt=[gt,mt,_t,bt],wt="start",At="end",Et="clippingParents",Tt="viewport",Ct="popper",Ot="reference",xt=yt.reduce((function(t,e){return t.concat([e+"-"+wt,e+"-"+At])}),[]),kt=[].concat(yt,[vt]).reduce((function(t,e){return t.concat([e,e+"-"+wt,e+"-"+At])}),[]),Lt="beforeRead",Dt="read",St="afterRead",It="beforeMain",Nt="main",Pt="afterMain",jt="beforeWrite",Mt="write",Ht="afterWrite",$t=[Lt,Dt,St,It,Nt,Pt,jt,Mt,Ht];function Wt(t){return t?(t.nodeName||"").toLowerCase():null}function Bt(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function Ft(t){return t instanceof Bt(t).Element||t instanceof Element}function zt(t){return t instanceof Bt(t).HTMLElement||t instanceof HTMLElement}function Rt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof Bt(t).ShadowRoot||t instanceof ShadowRoot)}const qt={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];zt(s)&&Wt(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});zt(n)&&Wt(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function Vt(t){return t.split("-")[0]}var Kt=Math.max,Qt=Math.min,Xt=Math.round;function Yt(t,e){void 0===e&&(e=!1);var i=t.getBoundingClientRect(),n=1,s=1;if(zt(t)&&e){var o=t.offsetHeight,r=t.offsetWidth;r>0&&(n=Xt(i.width)/r||1),o>0&&(s=Xt(i.height)/o||1)}return{width:i.width/n,height:i.height/s,top:i.top/s,right:i.right/n,bottom:i.bottom/s,left:i.left/n,x:i.left/n,y:i.top/s}}function Ut(t){var e=Yt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Gt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&Rt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Jt(t){return Bt(t).getComputedStyle(t)}function Zt(t){return["table","td","th"].indexOf(Wt(t))>=0}function te(t){return((Ft(t)?t.ownerDocument:t.document)||window.document).documentElement}function ee(t){return"html"===Wt(t)?t:t.assignedSlot||t.parentNode||(Rt(t)?t.host:null)||te(t)}function ie(t){return zt(t)&&"fixed"!==Jt(t).position?t.offsetParent:null}function ne(t){for(var e=Bt(t),i=ie(t);i&&Zt(i)&&"static"===Jt(i).position;)i=ie(i);return i&&("html"===Wt(i)||"body"===Wt(i)&&"static"===Jt(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&zt(t)&&"fixed"===Jt(t).position)return null;var i=ee(t);for(Rt(i)&&(i=i.host);zt(i)&&["html","body"].indexOf(Wt(i))<0;){var n=Jt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function se(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function oe(t,e,i){return Kt(t,Qt(e,i))}function re(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function ae(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const le={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=Vt(i.placement),l=se(a),c=[bt,_t].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return re("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:ae(t,yt))}(s.padding,i),d=Ut(o),u="y"===l?gt:bt,f="y"===l?mt:_t,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],g=r[l]-i.rects.reference[l],m=ne(o),_=m?"y"===l?m.clientHeight||0:m.clientWidth||0:0,b=p/2-g/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=oe(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Gt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ce(t){return t.split("-")[1]}var he={top:"auto",right:"auto",bottom:"auto",left:"auto"};function de(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,g=void 0===p?0:p,m="function"==typeof h?h({x:f,y:g}):{x:f,y:g};f=m.x,g=m.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=bt,y=gt,w=window;if(c){var A=ne(i),E="clientHeight",T="clientWidth";A===Bt(i)&&"static"!==Jt(A=te(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===gt||(s===bt||s===_t)&&o===At)&&(y=mt,g-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,g*=l?1:-1),s!==bt&&(s!==gt&&s!==mt||o!==At)||(v=_t,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&he),x=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:Xt(e*n)/n||0,y:Xt(i*n)/n||0}}({x:f,y:g}):{x:f,y:g};return f=x.x,g=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+g+"px)":"translate3d("+f+"px, "+g+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?g+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const ue={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:Vt(e.placement),variation:ce(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,de(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,de(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var fe={passive:!0};const pe={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=Bt(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,fe)})),a&&l.addEventListener("resize",i.update,fe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,fe)})),a&&l.removeEventListener("resize",i.update,fe)}},data:{}};var ge={left:"right",right:"left",bottom:"top",top:"bottom"};function me(t){return t.replace(/left|right|bottom|top/g,(function(t){return ge[t]}))}var _e={start:"end",end:"start"};function be(t){return t.replace(/start|end/g,(function(t){return _e[t]}))}function ve(t){var e=Bt(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ye(t){return Yt(te(t)).left+ve(t).scrollLeft}function we(t){var e=Jt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ae(t){return["html","body","#document"].indexOf(Wt(t))>=0?t.ownerDocument.body:zt(t)&&we(t)?t:Ae(ee(t))}function Ee(t,e){var i;void 0===e&&(e=[]);var n=Ae(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=Bt(n),r=s?[o].concat(o.visualViewport||[],we(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Ee(ee(r)))}function Te(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Ce(t,e){return e===Tt?Te(function(t){var e=Bt(t),i=te(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+ye(t),y:a}}(t)):Ft(e)?function(t){var e=Yt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Te(function(t){var e,i=te(t),n=ve(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=Kt(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=Kt(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ye(t),l=-n.scrollTop;return"rtl"===Jt(s||i).direction&&(a+=Kt(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(te(t)))}function Oe(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?Vt(s):null,r=s?ce(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case gt:e={x:a,y:i.y-n.height};break;case mt:e={x:a,y:i.y+i.height};break;case _t:e={x:i.x+i.width,y:l};break;case bt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?se(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case wt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case At:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function xe(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?Et:o,a=i.rootBoundary,l=void 0===a?Tt:a,c=i.elementContext,h=void 0===c?Ct:c,d=i.altBoundary,u=void 0!==d&&d,f=i.padding,p=void 0===f?0:f,g=re("number"!=typeof p?p:ae(p,yt)),m=h===Ct?Ot:Ct,_=t.rects.popper,b=t.elements[u?m:h],v=function(t,e,i){var n="clippingParents"===e?function(t){var e=Ee(ee(t)),i=["absolute","fixed"].indexOf(Jt(t).position)>=0&&zt(t)?ne(t):t;return Ft(i)?e.filter((function(t){return Ft(t)&&Gt(t,i)&&"body"!==Wt(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Ce(t,i);return e.top=Kt(n.top,e.top),e.right=Qt(n.right,e.right),e.bottom=Qt(n.bottom,e.bottom),e.left=Kt(n.left,e.left),e}),Ce(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}(Ft(b)?b:b.contextElement||te(t.elements.popper),r,l),y=Yt(t.elements.reference),w=Oe({reference:y,element:_,strategy:"absolute",placement:s}),A=Te(Object.assign({},_,w)),E=h===Ct?A:y,T={top:v.top-E.top+g.top,bottom:E.bottom-v.bottom+g.bottom,left:v.left-E.left+g.left,right:E.right-v.right+g.right},C=t.modifiersData.offset;if(h===Ct&&C){var O=C[s];Object.keys(T).forEach((function(t){var e=[_t,mt].indexOf(t)>=0?1:-1,i=[gt,mt].indexOf(t)>=0?"y":"x";T[t]+=O[i]*e}))}return T}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?kt:l,h=ce(n),d=h?a?xt:xt.filter((function(t){return ce(t)===h})):yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=xe(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[Vt(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const Le={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,g=i.allowedAutoPlacements,m=e.options.placement,_=Vt(m),b=l||(_!==m&&p?function(t){if(Vt(t)===vt)return[];var e=me(t);return[be(t),e,be(e)]}(m):[me(m)]),v=[m].concat(b).reduce((function(t,i){return t.concat(Vt(i)===vt?ke(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:g}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,D=L?"width":"height",S=xe(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),I=L?k?_t:bt:k?mt:gt;y[D]>w[D]&&(I=me(I));var N=me(I),P=[];if(o&&P.push(S[x]<=0),a&&P.push(S[I]<=0,S[N]<=0),P.every((function(t){return t}))){T=O,E=!1;break}A.set(O,P)}if(E)for(var j=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Se(t){return[gt,_t,mt,bt].some((function(e){return t[e]>=0}))}const Ie={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=xe(e,{elementContext:"reference"}),a=xe(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Se(l),d=Se(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Ne={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=kt.reduce((function(t,i){return t[i]=function(t,e,i){var n=Vt(t),s=[bt,gt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[bt,_t].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},Pe={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=Oe({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},je={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,g=void 0===p?0:p,m=xe(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=Vt(e.placement),b=ce(e.placement),v=!b,y=se(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof g?g(Object.assign({},e.rects,{placement:e.placement})):g,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,D="y"===y?gt:bt,S="y"===y?mt:_t,I="y"===y?"height":"width",N=A[y],P=N+m[D],j=N-m[S],M=f?-T[I]/2:0,H=b===wt?E[I]:T[I],$=b===wt?-T[I]:-E[I],W=e.elements.arrow,B=f&&W?Ut(W):{width:0,height:0},F=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=F[D],R=F[S],q=oe(0,E[I],B[I]),V=v?E[I]/2-M-q-z-O.mainAxis:H-q-z-O.mainAxis,K=v?-E[I]/2+M+q+R+O.mainAxis:$+q+R+O.mainAxis,Q=e.elements.arrow&&ne(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=N+K-Y,G=oe(f?Qt(P,N+V-Y-X):P,N,f?Kt(j,U):j);A[y]=G,k[y]=G-N}if(a){var J,Z="x"===y?gt:bt,tt="x"===y?mt:_t,et=A[w],it="y"===w?"height":"width",nt=et+m[Z],st=et-m[tt],ot=-1!==[gt,bt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=oe(t,e,i);return n>i?i:n}(at,et,lt):oe(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function Me(t,e,i){void 0===i&&(i=!1);var n,s,o=zt(e),r=zt(e)&&function(t){var e=t.getBoundingClientRect(),i=Xt(e.width)/t.offsetWidth||1,n=Xt(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=te(e),l=Yt(t,r),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==Wt(e)||we(a))&&(c=(n=e)!==Bt(n)&&zt(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:ve(n)),zt(e)?((h=Yt(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=ye(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var $e={placement:"bottom",modifiers:[],strategy:"absolute"};function We(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(B.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=Q.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Qe,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=li.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=Q.find(Je);for(const i of e){const e=li.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ke,Qe].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=Q.findOne(Ge,t.delegateTarget.parentNode),o=li.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}P.on(document,Ye,Ge,li.dataApiKeydownHandler),P.on(document,Ye,Ze,li.dataApiKeydownHandler),P.on(document,Xe,li.clearMenus),P.on(document,"keyup.bs.dropdown.data-api",li.clearMenus),P.on(document,Xe,Ge,(function(t){t.preventDefault(),li.getOrCreateInstance(this).toggle()})),g(li);const ci=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",hi=".sticky-top",di="padding-right",ui="margin-right";class fi{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,di,(e=>e+t)),this._setElementAttributes(ci,di,(e=>e+t)),this._setElementAttributes(hi,ui,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,di),this._resetElementAttributes(ci,di),this._resetElementAttributes(hi,ui)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&B.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=B.getDataAttribute(t,e);null!==i?(B.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of Q.find(t,this._element))e(i)}}const pi="show",gi="mousedown.bs.backdrop",mi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},_i={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class bi extends F{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return mi}static get DefaultType(){return _i}static get NAME(){return"backdrop"}show(t){if(!this._config.isVisible)return void m(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(pi),this._emulateAnimation((()=>{m(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(pi),this._emulateAnimation((()=>{this.dispose(),m(t)}))):m(t)}dispose(){this._isAppended&&(P.off(this._element,gi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),P.on(t,gi,(()=>{m(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const vi=".bs.focustrap",yi="backward",wi={autofocus:!0,trapElement:null},Ai={autofocus:"boolean",trapElement:"element"};class Ei extends F{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return wi}static get DefaultType(){return Ai}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),P.off(document,vi),P.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),P.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,P.off(document,vi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=Q.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===yi?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?yi:"forward")}}const Ti="hidden.bs.modal",Ci="show.bs.modal",Oi="modal-open",xi="show",ki="modal-static",Li={backdrop:!0,focus:!0,keyboard:!0},Di={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class Si extends z{constructor(t,e){super(t,e),this._dialog=Q.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new fi,this._addEventListeners()}static get Default(){return Li}static get DefaultType(){return Di}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||P.trigger(this._element,Ci,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(Oi),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(P.trigger(this._element,"hide.bs.modal").defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(xi),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){for(const t of[window,this._dialog])P.off(t,".bs.modal");this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new bi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ei({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=Q.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(xi),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,P.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){P.on(this._element,"keydown.dismiss.bs.modal",(t=>{if("Escape"===t.key)return this._config.keyboard?(t.preventDefault(),void this.hide()):void this._triggerBackdropTransition()})),P.on(window,"resize.bs.modal",(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),P.on(this._element,"mousedown.dismiss.bs.modal",(t=>{t.target===t.currentTarget&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Oi),this._resetAdjustments(),this._scrollBar.reset(),P.trigger(this._element,Ti)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(P.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(ki)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(ki),this._queueCallback((()=>{this._element.classList.remove(ki),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Si.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}P.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=n(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),P.one(e,Ci,(t=>{t.defaultPrevented||P.one(e,Ti,(()=>{a(this)&&this.focus()}))}));const i=Q.findOne(".modal.show");i&&Si.getInstance(i).hide(),Si.getOrCreateInstance(e).toggle(this)})),R(Si),g(Si);const Ii="show",Ni="showing",Pi="hiding",ji=".offcanvas.show",Mi="hidePrevented.bs.offcanvas",Hi="hidden.bs.offcanvas",$i={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Bi extends z{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return $i}static get DefaultType(){return Wi}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||P.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new fi).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Ni),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Ii),this._element.classList.remove(Ni),P.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(P.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(Pi),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Ii,Pi),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new fi).reset(),P.trigger(this._element,Hi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new bi({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():P.trigger(this._element,Mi)}:null})}_initializeFocusTrap(){return new Ei({trapElement:this._element})}_addEventListeners(){P.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():P.trigger(this._element,Mi))}))}static jQueryInterface(t){return this.each((function(){const e=Bi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}P.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=n(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;P.one(e,Hi,(()=>{a(this)&&this.focus()}));const i=Q.findOne(ji);i&&i!==e&&Bi.getInstance(i).hide(),Bi.getOrCreateInstance(e).toggle(this)})),P.on(window,"load.bs.offcanvas.data-api",(()=>{for(const t of Q.find(ji))Bi.getOrCreateInstance(t).show()})),P.on(window,"resize.bs.offcanvas",(()=>{for(const t of Q.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Bi.getOrCreateInstance(t).hide()})),R(Bi),g(Bi);const Fi=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),zi=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Ri=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,qi=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Fi.has(i)||Boolean(zi.test(t.nodeValue)||Ri.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Vi={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Ki={allowList:Vi,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Qi={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Xi={entry:"(string|element|function|null)",selector:"(string|element)"};class Yi extends F{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Ki}static get DefaultType(){return Qi}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Xi)}_setContent(t,e,i){const n=Q.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)qi(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return"function"==typeof t?t(this):t}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Ui=new Set(["sanitize","allowList","sanitizeFn"]),Gi="fade",Ji="show",Zi=".modal",tn="hide.bs.modal",en="hover",nn="focus",sn={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},on={allowList:Vi,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,0],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},rn={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class an extends z{constructor(t,e){if(void 0===qe)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=!1,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners()}static get Default(){return on}static get DefaultType(){return rn}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled){if(t){const e=this._initializeOnDelegatedTarget(t);return e._activeTrigger.click=!e._activeTrigger.click,void(e._isWithActiveTrigger()?e._enter():e._leave())}this._isShown()?this._leave():this._enter()}}dispose(){clearTimeout(this._timeout),P.off(this._element.closest(Zi),tn,this._hideModalHandler),this.tip&&this.tip.remove(),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=P.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this.tip&&(this.tip.remove(),this.tip=null);const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),P.trigger(this._element,this.constructor.eventName("inserted"))),this._popper?this._popper.update():this._popper=this._createPopper(i),i.classList.add(Ji),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))P.on(t,"mouseover",h);this._queueCallback((()=>{const t=this._isHovered;this._isHovered=!1,P.trigger(this._element,this.constructor.eventName("shown")),t&&this._leave()}),this.tip,this._isAnimated())}hide(){if(!this._isShown())return;if(P.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented)return;const t=this._getTipElement();if(t.classList.remove(Ji),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))P.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this._isHovered=!1,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||t.remove(),this._element.removeAttribute("aria-describedby"),P.trigger(this._element,this.constructor.eventName("hidden")),this._disposePopper())}),this.tip,this._isAnimated())}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(Gi,Ji),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(Gi),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Yi({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._config.originalTitle}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(Gi)}_isShown(){return this.tip&&this.tip.classList.contains(Ji)}_createPopper(t){const e="function"==typeof this._config.placement?this._config.placement.call(this,t,this._element):this._config.placement,i=sn[e.toUpperCase()];return Re(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)P.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>this.toggle(t)));else if("manual"!==e){const t=e===en?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===en?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");P.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?nn:en]=!0,e._enter()})),P.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?nn:en]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},P.on(this._element.closest(Zi),tn,this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._config.originalTitle;t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=B.getDataAttributes(this._element);for(const t of Object.keys(e))Ui.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),t.originalTitle=this._element.getAttribute("title")||"","number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null)}static jQueryInterface(t){return this.each((function(){const e=an.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(an);const ln={...an.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},cn={...an.DefaultType,content:"(null|string|element|function)"};class hn extends an{static get Default(){return ln}static get DefaultType(){return cn}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=hn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(hn);const dn="click.bs.scrollspy",un="active",fn="[href]",pn={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null},gn={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element"};class mn extends z{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return pn}static get DefaultType(){return gn}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(P.off(this._config.target,dn),P.on(this._config.target,dn,fn,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:[.1,.5,1],rootMargin:this._getRootMargin()};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_getRootMargin(){return this._config.offset?`${this._config.offset}px 0px -30%`:this._config.rootMargin}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=Q.find(fn,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=Q.findOne(e.hash,this._element);a(t)&&(this._targetLinks.set(e.hash,e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(un),this._activateParents(t),P.trigger(this._element,"activate.bs.scrollspy",{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))Q.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(un);else for(const e of Q.parents(t,".nav, .list-group"))for(const t of Q.prev(e,".nav-link, .nav-item > .nav-link, .list-group-item"))t.classList.add(un)}_clearActiveClass(t){t.classList.remove(un);const e=Q.find("[href].active",t);for(const t of e)t.classList.remove(un)}static jQueryInterface(t){return this.each((function(){const e=mn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}P.on(window,"load.bs.scrollspy.data-api",(()=>{for(const t of Q.find('[data-bs-spy="scroll"]'))mn.getOrCreateInstance(t)})),g(mn);const _n="ArrowLeft",bn="ArrowRight",vn="ArrowUp",yn="ArrowDown",wn="active",An="fade",En="show",Tn='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Cn=`.nav-link:not(.dropdown-toggle), .list-group-item:not(.dropdown-toggle), [role="tab"]:not(.dropdown-toggle), ${Tn}`;class On extends z{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),P.on(this._element,"keydown.bs.tab",(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?P.trigger(e,"hide.bs.tab",{relatedTarget:t}):null;P.trigger(t,"show.bs.tab",{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(wn),this._activate(n(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.focus(),t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),P.trigger(t,"shown.bs.tab",{relatedTarget:e})):t.classList.add(En)}),t,t.classList.contains(An)))}_deactivate(t,e){t&&(t.classList.remove(wn),t.blur(),this._deactivate(n(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),P.trigger(t,"hidden.bs.tab",{relatedTarget:e})):t.classList.remove(En)}),t,t.classList.contains(An)))}_keydown(t){if(![_n,bn,vn,yn].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=[bn,yn].includes(t.key),i=b(this._getChildren().filter((t=>!l(t))),t.target,e,!0);i&&On.getOrCreateInstance(i).show()}_getChildren(){return Q.find(Cn,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=n(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`#${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=Q.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",wn),n(".dropdown-menu",En),n(".dropdown-item",wn),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(wn)}_getInnerElement(t){return t.matches(Cn)?t:Q.findOne(Cn,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=On.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}P.on(document,"click.bs.tab",Tn,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||On.getOrCreateInstance(this).show()})),P.on(window,"load.bs.tab",(()=>{for(const t of Q.find('.active[data-bs-toggle="tab"], .active[data-bs-toggle="pill"], .active[data-bs-toggle="list"]'))On.getOrCreateInstance(t)})),g(On);const xn="hide",kn="show",Ln="showing",Dn={animation:"boolean",autohide:"boolean",delay:"number"},Sn={animation:!0,autohide:!0,delay:5e3};class In extends z{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return Sn}static get DefaultType(){return Dn}static get NAME(){return"toast"}show(){P.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(xn),d(this._element),this._element.classList.add(kn,Ln),this._queueCallback((()=>{this._element.classList.remove(Ln),P.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(P.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(Ln),this._queueCallback((()=>{this._element.classList.add(xn),this._element.classList.remove(Ln,kn),P.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(kn),super.dispose()}isShown(){return this._element.classList.contains(kn)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){P.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),P.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),P.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),P.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=In.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(In),g(In),{Alert:q,Button:K,Carousel:at,Collapse:pt,Dropdown:li,Modal:Si,Offcanvas:Bi,Popover:hn,ScrollSpy:mn,Tab:On,Toast:In,Tooltip:an}})); 7 | //# sourceMappingURL=bootstrap.bundle.min.js.map --------------------------------------------------------------------------------