From 0d3fd954a3a411509153328aa93792aace9ba741 Mon Sep 17 00:00:00 2001 From: imperosol Date: Sun, 29 Dec 2024 18:09:43 +0100 Subject: [PATCH 01/27] make ajax select appearance consistant with other inputs --- core/static/core/components/ajax-select.scss | 67 ++++++++++++++++---- core/static/core/forms.scss | 50 +++++++++------ 2 files changed, 82 insertions(+), 35 deletions(-) diff --git a/core/static/core/components/ajax-select.scss b/core/static/core/components/ajax-select.scss index cb9d466c..59d146fc 100644 --- a/core/static/core/components/ajax-select.scss +++ b/core/static/core/components/ajax-select.scss @@ -1,11 +1,27 @@ +.ts-wrapper.multi .ts-control { + min-width: calc(100% - 0.2rem); +} + /* This also requires ajax-select-index.css */ .ts-dropdown { + width: calc(100% - 0.2rem); + left: 0.1rem; + top: calc(100% - 0.2rem - var(--nf-input-border-bottom-width)); + border: var(--nf-input-border-color) var(--nf-input-border-width) solid; + border-top: none; + border-bottom-width: var(--nf-input-border-bottom-width); + + .option.active { + background-color: #e5eafa; + color: inherit; + } .select-item { display: flex; flex-direction: row; gap: 10px; align-items: center; + overflow: hidden; img { height: 40px; @@ -16,19 +32,44 @@ } } -.ts-wrapper { - margin: 5px; +.ts-wrapper.single { + > .ts-control { + box-shadow: none; + max-width: 300px; + background-color: var(--nf-input-background-color); + + &::after { + content: none; + } + } + + > .ts-dropdown { + max-width: 300px; + } } -.ts-wrapper.single { - width: 263px; // same length as regular text inputs +.ts-wrapper input[type="text"] { + border: none; + border-radius: 0; +} + +.ts-wrapper.multi, .ts-wrapper.single { + .ts-control:has(input:focus) { + outline: none; + border-color: var(--nf-input-focus-border-color); + box-shadow: none; + } } .ts-wrapper.plugin-remove_button:not(.rtl) .item .remove { border-left: 1px solid #aaa; } -.ts-wrapper.multi .ts-control { +.ts-wrapper.multi.has-items .ts-control { + padding: calc(var(--nf-input-size) * 0.65); + display: flex; + gap: calc(var(--nf-input-size) / 3); + [data-value], [data-value].active { background-image: none; @@ -37,19 +78,17 @@ border: 1px solid #aaa; border-radius: 4px; display: inline-block; - margin-left: 5px; - margin-top: 5px; - margin-bottom: 5px; padding-right: 10px; padding-left: 10px; text-shadow: none; box-shadow: none; + + .remove { + vertical-align: baseline; + } } } -.ts-dropdown { - .option.active { - background-color: #e5eafa; - color: inherit; - } -} \ No newline at end of file +.ts-wrapper.focus .ts-control { + box-shadow: none; +} diff --git a/core/static/core/forms.scss b/core/static/core/forms.scss index ae6f8a21..8ac2e298 100644 --- a/core/static/core/forms.scss +++ b/core/static/core/forms.scss @@ -48,7 +48,8 @@ input, textarea[type="text"], - [type="number"] { + [type="number"], + .ts-control { border: none; text-decoration: none; background-color: $background-button-color; @@ -69,7 +70,7 @@ font-family: sans-serif; } - select { + select, .ts-control { border: none; text-decoration: none; font-size: 1.2em; @@ -176,7 +177,7 @@ form { } // wrap texts - label, legend, ul.errorlist>li, .helptext { + label, legend, ul.errorlist > li, .helptext { text-wrap: wrap; } @@ -225,23 +226,25 @@ form { } } - input[type="text"], - input[type="email"], - input[type="tel"], - input[type="url"], - input[type="password"], - input[type="number"], - input[type="date"], - input[type="week"], - input[type="time"], - input[type="month"], - input[type="search"], - textarea, - select { - min-width: 300px; + :not(.ts-control) > { + input[type="text"], + input[type="email"], + input[type="tel"], + input[type="url"], + input[type="password"], + input[type="number"], + input[type="date"], + input[type="week"], + input[type="time"], + input[type="search"], + textarea, + input[type="month"], + select { + min-width: 300px; - &.grow { - width: 95%; + &.grow { + width: 95%; + } } } @@ -260,7 +263,8 @@ form { input[type="month"], input[type="search"], textarea, - select { + select, + .ts-control { background: var(--nf-input-background-color); font-size: var(--nf-input-font-size); border-color: var(--nf-input-border-color); @@ -720,7 +724,11 @@ form { // ---------------- SELECT - select { + select, + .ts-wrapper.multi .ts-control, + .ts-wrapper.single .ts-control, + .ts-wrapper.single.input-active .ts-control { + background-color: var(--nf-input-background-color); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-chevron-down'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); background-position: right calc(var(--nf-input-size) * 0.75) bottom 50%; background-repeat: no-repeat; From 2db3290bed341736e40923ee0ee80c6ff00defb2 Mon Sep 17 00:00:00 2001 From: Sli Date: Sun, 5 Jan 2025 20:17:30 +0100 Subject: [PATCH 02/27] Remove some jquery --- core/templates/core/base.jinja | 15 +++++----- core/templates/core/file.jinja | 9 ------ core/templates/core/user_detail.jinja | 41 ++++++++++++++------------- 3 files changed, 29 insertions(+), 36 deletions(-) diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index 17b9befa..ef184fbf 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -125,15 +125,14 @@ navbar.style.setProperty("display", current === "none" ? "block" : "none"); } - $(document).keydown(function (e) { - if ($(e.target).is('input')) { return } - if ($(e.target).is('textarea')) { return } - if ($(e.target).is('select')) { return } - if (e.keyCode === 83) { - $("#search").focus(); - return false; + document.addEventListener("keydown", (e) => { + // Looking at the `s` key when not typing in a form + if (e.keyCode !== 83 || ["INPUT", "TEXTAREA", "SELECT"].includes(e.target.nodeName)) { + return; } - }); + document.getElementById("search").focus(); + e.preventDefault(); // Don't type the character in the focused search input + }) {% endblock %} diff --git a/core/templates/core/file.jinja b/core/templates/core/file.jinja index 95c29bdc..09b86936 100644 --- a/core/templates/core/file.jinja +++ b/core/templates/core/file.jinja @@ -57,13 +57,4 @@ {% endblock %} {% endif %} - {% block script %} - {{ super() }} - {% if popup %} - - {% endif %} - {% endblock %} - {% endblock %} diff --git a/core/templates/core/user_detail.jinja b/core/templates/core/user_detail.jinja index 58836b6f..cb93b1cd 100644 --- a/core/templates/core/user_detail.jinja +++ b/core/templates/core/user_detail.jinja @@ -244,27 +244,30 @@ {% block script %} {{ super() }} {% endblock %} -{% block additional_js %} - +{% block additional_css %} + {% endblock %} {% block content %} @@ -68,7 +68,7 @@

{{ role.title }}

-

{{ role.description }}

+

{{ role.description }}

{%- if role.max_choice > 1 and not election.has_voted(user) and election.can_vote(user) %} {% trans %}You may choose up to{% endtrans %} {{ role.max_choice }} {% trans %}people.{% endtrans %} {%- endif %} @@ -139,7 +139,9 @@
{{ candidature.user.first_name }} {{candidature.user.nick_name or ''}} {{ candidature.user.last_name }}
{%- if not election.is_vote_finished %} - {{ candidature.program | markdown or '' }} + + {{ candidature.program|markdown or '' }} + {%- endif %}
{%- if user.can_edit(candidature) -%} @@ -198,18 +200,6 @@ {% block script %} {{ super() }} - -{% endblock %} - - diff --git a/com/templates/com/news_list.jinja b/com/templates/com/news_list.jinja index 0cd04749..168a95b4 100644 --- a/com/templates/com/news_list.jinja +++ b/com/templates/com/news_list.jinja @@ -15,37 +15,21 @@ {% endblock %} {% block content %} - {% if user.is_com_admin %} - -
- {% endif %}
- {% for news in object_list.filter(type="NOTICE") %} -
-

{{ news.title }}

-
{{ news.summary|markdown }}
-
- {% endfor %} - - {% for news in object_list.filter(dates__start_date__lte=timezone.now(), dates__end_date__gte=timezone.now(), type="CALL") %} -
-

{{ news.title }}

-
- {{ news.dates.first().start_date|localtime|date(DATETIME_FORMAT) }} - {{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }} - - {{ news.dates.first().end_date|localtime|date(DATETIME_FORMAT) }} - {{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }} -
-
{{ news.summary|markdown }}
-
- {% endfor %} - - {% set events_dates = NewsDate.objects.filter(end_date__gte=timezone.now(), start_date__lte=timezone.now()+timedelta(days=5), news__type="EVENT", news__is_moderated=True).datetimes('start_date', 'day') %} + {% set events_dates = NewsDate.objects.filter(end_date__gte=timezone.now(), start_date__lte=timezone.now()+timedelta(days=5), news__is_moderated=True).datetimes('start_date', 'day') %}

{% trans %}Events today and the next few days{% endtrans %}

+ {% if user.is_authenticated and (user.is_com_admin or user.memberships.board().ongoing().exists()) %} + + + {% trans %}Create news{% endtrans %} + + {% endif %} + {% if user.is_com_admin %} + {% trans %}Administrate news{% endtrans %} +
+ {% endif %} {% if events_dates %} {% for d in events_dates %}
@@ -57,113 +41,104 @@
- {% for news in object_list.filter(dates__start_date__gte=d, - dates__start_date__lte=d+timedelta(days=1), - type="EVENT").exclude(dates__end_date__lt=timezone.now()) - .order_by('dates__start_date') %} -
- -

{{ news.title }}

- -
- {{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }} - - {{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }} -
-
{{ news.summary|markdown }} -
- {{ fb_quick(news) }} - {{ tweet_quick(news) }} + {% for news in object_list.filter(dates__start_date__gte=d,dates__start_date__lte=d+timedelta(days=1)).exclude(dates__end_date__lt=timezone.now()).order_by('dates__start_date') %} +
+ -
-
+

{{ news.title }}

+ +
+ {{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }} - + {{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }} +
+
{{ news.summary|markdown }} +
+ {{ fb_quick(news) }} + {{ tweet_quick(news) }} +
+
+ + {% endfor %} +
+
{% endfor %} + {% else %} +
+ {% trans %}Nothing to come...{% endtrans %}
-
- {% endfor %} -{% else %} -
- {% trans %}Nothing to come...{% endtrans %} -
-{% endif %} + {% endif %} - -

{% trans %}All coming events{% endtrans %}

- - - - - -
- -
-

{% trans %}Birthdays{% endtrans %}

-
- {%- if user.was_subscribed -%} - +
+

{% trans %}Social media{% endtrans %}

+ +
+
+ +
+

{% trans %}Birthdays{% endtrans %}

+
+ {%- if user.was_subscribed -%} +
    + {%- for year, users in birthdays -%} +
  • + {% trans age=timezone.now().year - year %}{{ age }} year old{% endtrans %} + +
  • + {%- endfor -%} +
+ {%- else -%} +

{% trans %}You need to subscribe to access this content{% endtrans %}

+ {%- endif -%} +
+
- - - - - {% endblock %} diff --git a/com/tests/test_views.py b/com/tests/test_views.py index 3f98bfdc..c526dee5 100644 --- a/com/tests/test_views.py +++ b/com/tests/test_views.py @@ -12,6 +12,9 @@ # OR WITHIN THE LOCAL FILE "LICENSE" # # +from datetime import timedelta +from unittest.mock import patch + import pytest from django.conf import settings from django.core.files.uploadedfile import SimpleUploadedFile @@ -20,9 +23,12 @@ from django.urls import reverse from django.utils import html from django.utils.timezone import localtime, now from django.utils.translation import gettext as _ +from model_bakery import baker +from pytest_django.asserts import assertRedirects from club.models import Club, Membership -from com.models import News, Poster, Sith, Weekmail, WeekmailArticle +from com.models import News, NewsDate, Poster, Sith, Weekmail, WeekmailArticle +from core.baker_recipes import subscriber_user from core.models import AnonymousUser, Group, User @@ -137,15 +143,8 @@ class TestNews(TestCase): @classmethod def setUpTestData(cls): cls.com_admin = User.objects.get(username="comunity") - new = News.objects.create( - title="dummy new", - summary="This is a dummy new", - content="Look at that beautiful dummy new", - author=User.objects.get(username="subscriber"), - club=Club.objects.first(), - ) - cls.new = new - cls.author = new.author + cls.new = baker.make(News) + cls.author = cls.new.author cls.sli = User.objects.get(username="sli") cls.anonymous = AnonymousUser() @@ -176,11 +175,11 @@ class TestNews(TestCase): assert self.new.can_be_viewed_by(self.author) def test_news_editor(self): - """Test that only com admins can edit news.""" + """Test that only com admins and the original author can edit news.""" assert self.new.can_be_edited_by(self.com_admin) + assert self.new.can_be_edited_by(self.author) assert not self.new.can_be_edited_by(self.sli) assert not self.new.can_be_edited_by(self.anonymous) - assert not self.new.can_be_edited_by(self.author) class TestWeekmailArticle(TestCase): @@ -230,3 +229,93 @@ class TestPoster(TestCase): assert not self.poster.is_owned_by(self.susbcriber) assert self.poster.is_owned_by(self.sli) + + +class TestNewsCreation(TestCase): + @classmethod + def setUpTestData(cls): + cls.club = baker.make(Club) + cls.user = subscriber_user.make() + baker.make(Membership, user=cls.user, club=cls.club, role=5) + + def setUp(self): + self.client.force_login(self.user) + self.start = now() + timedelta(days=1) + self.end = self.start + timedelta(hours=5) + self.valid_payload = { + "title": "Test news", + "summary": "This is a test news", + "content": "This is a test news", + "club": self.club.pk, + "is_weekly": False, + "start_date": self.start, + "end_date": self.end, + } + + def test_create_news(self): + response = self.client.post(reverse("com:news_new"), self.valid_payload) + created = News.objects.order_by("id").last() + assertRedirects(response, created.get_absolute_url()) + assert created.title == "Test news" + assert not created.is_moderated + dates = list(created.dates.values("start_date", "end_date")) + assert dates == [{"start_date": self.start, "end_date": self.end}] + + def test_create_news_multiple_dates(self): + self.valid_payload["is_weekly"] = True + self.valid_payload["occurrences"] = 2 + response = self.client.post(reverse("com:news_new"), self.valid_payload) + created = News.objects.order_by("id").last() + + assertRedirects(response, created.get_absolute_url()) + dates = list( + created.dates.values("start_date", "end_date").order_by("start_date") + ) + assert dates == [ + {"start_date": self.start, "end_date": self.end}, + { + "start_date": self.start + timedelta(days=7), + "end_date": self.end + timedelta(days=7), + }, + ] + + def test_edit_news(self): + news = baker.make(News, author=self.user, is_moderated=True) + baker.make( + NewsDate, + news=news, + start_date=self.start + timedelta(hours=1), + end_date=self.end + timedelta(hours=1), + _quantity=2, + ) + + response = self.client.post( + reverse("com:news_edit", kwargs={"news_id": news.id}), self.valid_payload + ) + created = News.objects.order_by("id").last() + assertRedirects(response, created.get_absolute_url()) + assert created.title == "Test news" + assert not created.is_moderated + dates = list(created.dates.values("start_date", "end_date")) + assert dates == [{"start_date": self.start, "end_date": self.end}] + + def test_ics_updated(self): + """Test that the internal ICS is updated when news are created""" + + # we will just test that the ICS is modified. + # Checking that the ICS is *well* modified is up to the ICS tests + with patch("com.calendar.IcsCalendar.make_internal") as mocked: + self.client.post(reverse("com:news_new"), self.valid_payload) + mocked.assert_called() + + # The ICS file should also change after an update + self.valid_payload["is_weekly"] = True + self.valid_payload["occurrences"] = 2 + last_news = News.objects.order_by("id").last() + + with patch("com.calendar.IcsCalendar.make_internal") as mocked: + self.client.post( + reverse("com:news_edit", kwargs={"news_id": last_news.id}), + self.valid_payload, + ) + mocked.assert_called() diff --git a/com/urls.py b/com/urls.py index 304e5312..592e653b 100644 --- a/com/urls.py +++ b/com/urls.py @@ -25,9 +25,9 @@ from com.views import ( NewsCreateView, NewsDeleteView, NewsDetailView, - NewsEditView, NewsListView, NewsModerateView, + NewsUpdateView, PosterCreateView, PosterDeleteView, PosterEditView, @@ -75,11 +75,11 @@ urlpatterns = [ path("news/", NewsListView.as_view(), name="news_list"), path("news/admin/", NewsAdminListView.as_view(), name="news_admin_list"), path("news/create/", NewsCreateView.as_view(), name="news_new"), + path("news//edit/", NewsUpdateView.as_view(), name="news_edit"), path("news//delete/", NewsDeleteView.as_view(), name="news_delete"), path( "news//moderate/", NewsModerateView.as_view(), name="news_moderate" ), - path("news//edit/", NewsEditView.as_view(), name="news_edit"), path("news//", NewsDetailView.as_view(), name="news_detail"), path("mailings/", MailingListAdminView.as_view(), name="mailing_admin"), path( diff --git a/com/views.py b/com/views.py index 4396e6f2..54e37578 100644 --- a/com/views.py +++ b/com/views.py @@ -24,10 +24,15 @@ import itertools from datetime import timedelta from smtplib import SMTPRecipientsRefused +from typing import Any from django.conf import settings +from django.contrib.auth.mixins import ( + AccessMixin, + PermissionRequiredMixin, +) from django.core.exceptions import PermissionDenied, ValidationError -from django.db.models import Exists, Max, OuterRef +from django.db.models import Max from django.forms.models import modelform_factory from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, redirect @@ -36,16 +41,14 @@ from django.utils import timezone from django.utils.timezone import localdate from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView, View -from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import CreateView, DeleteView, UpdateView from club.models import Club, Mailing -from com.forms import NewsForm, PosterForm +from com.calendar import IcsCalendar +from com.forms import NewsDateForm, NewsForm, PosterForm from com.models import News, NewsDate, Poster, Screen, Sith, Weekmail, WeekmailArticle -from core.models import Notification, User +from core.models import User from core.views import ( - CanCreateMixin, - CanEditMixin, CanEditPropMixin, CanViewMixin, QuickNotifMixin, @@ -63,52 +66,42 @@ class ComTabsMixin(TabedViewMixin): return _("Communication administration") def get_list_of_tabs(self): - tab_list = [] - tab_list.append( - {"url": reverse("com:weekmail"), "slug": "weekmail", "name": _("Weekmail")} - ) - tab_list.append( + return [ + {"url": reverse("com:weekmail"), "slug": "weekmail", "name": _("Weekmail")}, { "url": reverse("com:weekmail_destinations"), "slug": "weekmail_destinations", "name": _("Weekmail destinations"), - } - ) - tab_list.append( - {"url": reverse("com:info_edit"), "slug": "info", "name": _("Info message")} - ) - tab_list.append( + }, + { + "url": reverse("com:info_edit"), + "slug": "info", + "name": _("Info message"), + }, { "url": reverse("com:alert_edit"), "slug": "alert", "name": _("Alert message"), - } - ) - tab_list.append( + }, { "url": reverse("com:mailing_admin"), "slug": "mailings", "name": _("Mailing lists administration"), - } - ) - tab_list.append( + }, { "url": reverse("com:poster_list"), "slug": "posters", "name": _("Posters list"), - } - ) - tab_list.append( + }, { "url": reverse("com:screen_list"), "slug": "screens", "name": _("Screens list"), - } - ) - return tab_list + }, + ] -class IsComAdminMixin(View): +class IsComAdminMixin(AccessMixin): def dispatch(self, request, *args, **kwargs): if not request.user.is_com_admin: raise PermissionDenied @@ -145,99 +138,89 @@ class WeekmailDestinationEditView(ComEditView): success_url = reverse_lazy("com:weekmail_destinations") -class NewsEditView(CanEditMixin, UpdateView): +# News + + +class NewsCreateView(PermissionRequiredMixin, CreateView): + """View to either create or update News.""" + + model = News + form_class = NewsForm + template_name = "com/news_edit.jinja" + permission_required = "com.add_news" + + def get_date_form_kwargs(self) -> dict[str, Any]: + """Get initial data for NewsDateForm""" + if self.request.method == "POST": + return {"data": self.request.POST} + return {} + + def get_form_kwargs(self): + return super().get_form_kwargs() | { + "author": self.request.user, + "date_form": NewsDateForm(**self.get_date_form_kwargs()), + } + + def get_initial(self): + init = super().get_initial() + # if the id of a club is provided, select it by default + if club_id := self.request.GET.get("club"): + init["club"] = Club.objects.filter(id=club_id).first() + return init + + +class NewsUpdateView(UpdateView): model = News form_class = NewsForm template_name = "com/news_edit.jinja" pk_url_kwarg = "news_id" - def get_initial(self): - news_date: NewsDate = self.object.dates.order_by("id").first() - if news_date is None: - return {"start_date": None, "end_date": None} - return {"start_date": news_date.start_date, "end_date": news_date.end_date} - - def post(self, request, *args, **kwargs): - form = self.get_form() - if form.is_valid() and "preview" not in request.POST: - return self.form_valid(form) - else: - return self.form_invalid(form) + def dispatch(self, request, *args, **kwargs): + if ( + not request.user.has_perm("com.edit_news") + and self.get_object().author != request.user + ): + raise PermissionDenied + return super().dispatch(request, *args, **kwargs) def form_valid(self, form): self.object = form.save() - if form.cleaned_data["automoderation"] and self.request.user.is_com_admin: - self.object.moderator = self.request.user - self.object.is_moderated = True - self.object.save() - else: - self.object.is_moderated = False - self.object.save() - unread_notif_subquery = Notification.objects.filter( - user=OuterRef("pk"), viewed=False - ) - for user in User.objects.with_perm("com.moderate_news").filter( - ~Exists(unread_notif_subquery) - ): - Notification.objects.create( - user=user, - url=self.object.get_absolute_url(), - type="NEWS_MODERATION", - ) + IcsCalendar.make_internal() return super().form_valid(form) + def get_date_form_kwargs(self) -> dict[str, Any]: + """Get initial data for NewsDateForm""" + response = {} + if self.request.method == "POST": + response["data"] = self.request.POST + dates = list(self.object.dates.order_by("id")) + if len(dates) == 0: + return {} + response["instance"] = dates[0] + occurrences = NewsDateForm.get_occurrences(len(dates)) + if occurrences is not None: + response["initial"] = {"is_weekly": True, "occurrences": occurrences} + return response -class NewsCreateView(CanCreateMixin, CreateView): - model = News - form_class = NewsForm - template_name = "com/news_edit.jinja" - - def get_initial(self): - init = {"author": self.request.user} - if "club" not in self.request.GET: - return init - init["club"] = Club.objects.filter(id=self.request.GET["club"]).first() - return init - - def post(self, request, *args, **kwargs): - form = self.get_form() - if form.is_valid() and "preview" not in request.POST: - return self.form_valid(form) - else: - self.object = form.instance - return self.form_invalid(form) - - def form_valid(self, form): - self.object = form.save() - if form.cleaned_data["automoderation"] and self.request.user.is_com_admin: - self.object.moderator = self.request.user - self.object.is_moderated = True - self.object.save() - else: - unread_notif_subquery = Notification.objects.filter( - user=OuterRef("pk"), viewed=False - ) - for user in User.objects.with_perm("com.moderate_news").filter( - ~Exists(unread_notif_subquery) - ): - Notification.objects.create( - user=user, - url=reverse("com:news_admin_list"), - type="NEWS_MODERATION", - ) - return super().form_valid(form) + def get_form_kwargs(self): + return super().get_form_kwargs() | { + "author": self.request.user, + "date_form": NewsDateForm(**self.get_date_form_kwargs()), + } -class NewsDeleteView(CanEditMixin, DeleteView): +class NewsDeleteView(PermissionRequiredMixin, DeleteView): model = News pk_url_kwarg = "news_id" template_name = "core/delete_confirm.jinja" success_url = reverse_lazy("com:news_admin_list") + permission_required = "com.delete_news" -class NewsModerateView(CanEditMixin, SingleObjectMixin): +class NewsModerateView(PermissionRequiredMixin, DetailView): model = News pk_url_kwarg = "news_id" + permission_required = "com.moderate_news" def get(self, request, *args, **kwargs): self.object = self.get_object() @@ -252,17 +235,23 @@ class NewsModerateView(CanEditMixin, SingleObjectMixin): return redirect("com:news_admin_list") -class NewsAdminListView(CanEditMixin, ListView): +class NewsAdminListView(PermissionRequiredMixin, ListView): model = News template_name = "com/news_admin_list.jinja" - queryset = News.objects.all() + queryset = News.objects.select_related( + "club", "author", "moderator" + ).prefetch_related("dates") + permission_required = ["com.moderate_news", "com.delete_news"] -class NewsListView(CanViewMixin, ListView): +class NewsListView(ListView): model = News template_name = "com/news_list.jinja" queryset = News.objects.filter(is_moderated=True) + def get_queryset(self): + return super().get_queryset().viewable_by(self.request.user) + def get_context_data(self, **kwargs): kwargs = super().get_context_data(**kwargs) kwargs["NewsDate"] = NewsDate @@ -283,6 +272,10 @@ class NewsDetailView(CanViewMixin, DetailView): model = News template_name = "com/news_detail.jinja" pk_url_kwarg = "news_id" + queryset = News.objects.select_related("club", "author", "moderator") + + def get_context_data(self, **kwargs): + return super().get_context_data(**kwargs) | {"date": self.object.dates.first()} # Weekmail diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index 1f8fcb7e..a5131d64 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -894,6 +894,7 @@ Welcome to the wiki page! public_group = Group.objects.create(name="Public") subscribers = Group.objects.create(name="Subscribers") + subscribers.permissions.add(*list(perms.filter(codename__in=["add_news"]))) old_subscribers = Group.objects.create(name="Old subscribers") old_subscribers.permissions.add( *list( diff --git a/core/static/core/forms.scss b/core/static/core/forms.scss index 326be76c..9982e77f 100644 --- a/core/static/core/forms.scss +++ b/core/static/core/forms.scss @@ -665,7 +665,9 @@ form { } &:checked { - background: var(--nf-input-focus-border-color) none initial; + background: none; + background-position: 0 0; + background-color: var(--nf-input-focus-border-color); &::after { transform: translateY(-50%) translateX( diff --git a/core/static/core/style.scss b/core/static/core/style.scss index 6a4f0235..a89d33cf 100644 --- a/core/static/core/style.scss +++ b/core/static/core/style.scss @@ -436,8 +436,8 @@ body { $row-gap: 0.5rem; &.gap { - column-gap: var($col-gap); - row-gap: var($row-gap); + column-gap: $col-gap; + row-gap: $row-gap; } @for $i from 2 through 5 { diff --git a/core/templatetags/renderer.py b/core/templatetags/renderer.py index 383f0383..62f9f730 100644 --- a/core/templatetags/renderer.py +++ b/core/templatetags/renderer.py @@ -26,6 +26,7 @@ import datetime import phonenumbers from django import template +from django.forms import BoundField from django.template.defaultfilters import stringfilter from django.utils.safestring import mark_safe from django.utils.translation import ngettext @@ -80,3 +81,43 @@ def format_timedelta(value: datetime.timedelta) -> str: return ngettext( "%(nb_days)d day, %(remainder)s", "%(nb_days)d days, %(remainder)s", days ) % {"nb_days": days, "remainder": str(remainder)} + + +@register.filter(name="add_attr") +def add_attr(field: BoundField, attr: str): + """Add attributes to a form field directly in the template. + + Attributes are `key=value` pairs, separated by commas. + + Example: + ```jinja +
+ {{ form.field|add_attr("x-model=alpineField") }} +
+ ``` + + will render : + ```html +
+ +
+ ``` + + Notes: + Doing this gives the same result as setting the attribute + directly in the python code. + However, sometimes there are attributes that are tightly + coupled to the frontend logic (like Alpine variables) + and that shouldn't be declared outside of it. + """ + attrs = {} + definition = attr.split(",") + + for d in definition: + if "=" not in d: + attrs["class"] = d + else: + key, val = d.split("=") + attrs[key] = val + + return field.as_widget(attrs=attrs) diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index c2ca80d8..64af1695 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-08 12:23+0100\n" +"POT-Creation-Date: 2025-01-10 00:25+0100\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Maréchal \n" @@ -841,7 +841,7 @@ msgstr "vous devez spécifier au moins un utilisateur ou une adresse email" msgid "Begin date" msgstr "Date de début" -#: club/forms.py com/views.py counter/forms.py election/views.py +#: club/forms.py com/forms.py counter/forms.py election/views.py #: subscription/forms.py msgid "End date" msgstr "Date de fin" @@ -1259,6 +1259,43 @@ msgstr "Liste d'affiches" msgid "Props" msgstr "Propriétés" +#: com/forms.py +msgid "Format: 16:9 | Resolution: 1920x1080" +msgstr "Format : 16:9 | Résolution : 1920x1080" + +#: com/forms.py election/views.py subscription/forms.py +msgid "Start date" +msgstr "Date de début" + +#: com/forms.py +msgid "Weekly event" +msgstr "Événement Hebdomadaire" + +#: com/forms.py +msgid "Weekly events will occur each week for a specified timespan." +msgstr "Les événements hebdomadaires se répéteront chaque semaine pendant une durée déterminée" + +#: com/forms.py +#, python-format +msgid "%d times" +msgstr "%d fois" + +#: com/forms.py +msgid "Until the end of the semester" +msgstr "Jusqu'à la fin du semestre" + +#: com/forms.py +msgid "Occurrences" +msgstr "Occurences" + +#: com/forms.py +msgid "How much times should the event occur (including the first one)" +msgstr "Combien de fois l'événement doit-il se répéter (en incluant la première fois)" + +#: com/forms.py +msgid "Automoderation" +msgstr "Automodération" + #: com/models.py msgid "alert message" msgstr "message d'alerte" @@ -1271,22 +1308,6 @@ msgstr "message d'info" msgid "weekmail destinations" msgstr "destinataires du weekmail" -#: com/models.py -msgid "Notice" -msgstr "Information" - -#: com/models.py -msgid "Event" -msgstr "Événement" - -#: com/models.py -msgid "Weekly" -msgstr "Hebdomadaire" - -#: com/models.py -msgid "Call" -msgstr "Appel" - #: com/models.py core/templates/core/macros.jinja election/models.py #: forum/models.py pedagogy/models.py msgid "title" @@ -1312,10 +1333,6 @@ msgstr "contenu" msgid "A more detailed and exhaustive description of the event." msgstr "Une description plus détaillée et exhaustive de l'évènement." -#: com/models.py core/models.py launderette/models.py -msgid "type" -msgstr "type" - #: com/models.py msgid "The club which organizes the event." msgstr "Le club qui organise l'évènement." @@ -1324,6 +1341,10 @@ msgstr "Le club qui organise l'évènement." msgid "author" msgstr "auteur" +#: com/models.py +msgid "news" +msgstr "nouvelle" + #: com/models.py msgid "news_date" msgstr "date de la nouvelle" @@ -1336,6 +1357,14 @@ msgstr "date de début" msgid "end_date" msgstr "date de fin" +#: com/models.py +msgid "news date" +msgstr "date de la nouvelle" + +#: com/models.py +msgid "news dates" +msgstr "dates de la nouvelle" + #: com/models.py msgid "intro" msgstr "intro" @@ -1372,6 +1401,10 @@ msgstr "fichier" msgid "display time" msgstr "temps d'affichage" +#: com/models.py +msgid "Can moderate poster" +msgstr "Peut modérer les posters" + #: com/models.py msgid "Begin date should be before end date" msgstr "La date de début doit être avant celle de fin" @@ -1420,23 +1453,17 @@ msgid "News" msgstr "Nouvelles" #: com/templates/com/news_admin_list.jinja com/templates/com/news_edit.jinja -#: core/templates/core/user_tools.jinja +#: com/templates/com/news_list.jinja core/templates/core/user_tools.jinja msgid "Create news" -msgstr "Créer nouvelle" +msgstr "Créer une nouvelle" #: com/templates/com/news_admin_list.jinja -msgid "Notices" -msgstr "Information" +msgid "Weeklies" +msgstr "Événements hebdomadaires" #: com/templates/com/news_admin_list.jinja -msgid "Displayed notices" -msgstr "Informations affichées" - -#: com/templates/com/news_admin_list.jinja -#: launderette/templates/launderette/launderette_admin.jinja -#: launderette/views.py -msgid "Type" -msgstr "Type" +msgid "Displayed weeklies" +msgstr "Événements hebdomadaires affichées" #: com/templates/com/news_admin_list.jinja com/templates/com/weekmail.jinja #: forum/templates/forum/forum.jinja forum/templates/forum/main.jinja @@ -1457,18 +1484,6 @@ msgstr "Auteur" msgid "Moderator" msgstr "Modérateur" -#: com/templates/com/news_admin_list.jinja -msgid "Notices to moderate" -msgstr "Informations à modérer" - -#: com/templates/com/news_admin_list.jinja -msgid "Weeklies" -msgstr "Nouvelles hebdomadaires" - -#: com/templates/com/news_admin_list.jinja -msgid "Displayed weeklies" -msgstr "Nouvelles hebdomadaires affichées" - #: com/templates/com/news_admin_list.jinja #: trombi/templates/trombi/edit_profile.jinja msgid "Dates" @@ -1478,18 +1493,6 @@ msgstr "Dates" msgid "Weeklies to moderate" msgstr "Nouvelles hebdomadaires à modérer" -#: com/templates/com/news_admin_list.jinja -msgid "Calls" -msgstr "Appels" - -#: com/templates/com/news_admin_list.jinja -msgid "Displayed calls" -msgstr "Appels affichés" - -#: com/templates/com/news_admin_list.jinja -msgid "Calls to moderate" -msgstr "Appels à modérer" - #: com/templates/com/news_admin_list.jinja #: core/templates/core/base/navbar.jinja msgid "Events" @@ -1507,7 +1510,7 @@ msgstr "Événements à modérer" msgid "Back to news" msgstr "Retour aux nouvelles" -#: com/templates/com/news_detail.jinja com/templates/com/news_edit.jinja +#: com/templates/com/news_detail.jinja msgid "Author: " msgstr "Auteur : " @@ -1523,41 +1526,14 @@ msgstr "Éditer (sera soumise de nouveau à la modération)" msgid "Edit news" msgstr "Éditer la nouvelle" -#: com/templates/com/news_edit.jinja -msgid "Notice: Information, election result - no date" -msgstr "Information, résultat d'élection - sans date" - -#: com/templates/com/news_edit.jinja -msgid "Event: punctual event, associated with one date" -msgstr "Événement : événement ponctuel associé à une date" - -#: com/templates/com/news_edit.jinja -msgid "" -"Weekly: recurrent event, associated with many dates (specify the first one, " -"and a deadline)" -msgstr "" -"Hebdomadaire : événement récurrent, associé à plusieurs dates (spécifier la " -"première, ainsi que la date de fin)" - -#: com/templates/com/news_edit.jinja -msgid "" -"Call: long time event, associated with a long date (like election appliance)" -msgstr "" -"Appel : événement de longue durée, associé à une longue date (comme des " -"candidatures à une élection)" - -#: com/templates/com/news_edit.jinja com/templates/com/weekmail.jinja -msgid "Preview" -msgstr "Prévisualiser" +#: com/templates/com/news_list.jinja +msgid "Events today and the next few days" +msgstr "Événements aujourd'hui et dans les prochains jours" #: com/templates/com/news_list.jinja msgid "Administrate news" msgstr "Administrer les news" -#: com/templates/com/news_list.jinja -msgid "Events today and the next few days" -msgstr "Événements aujourd'hui et dans les prochains jours" - #: com/templates/com/news_list.jinja msgid "Nothing to come..." msgstr "Rien à venir..." @@ -1679,6 +1655,10 @@ msgstr "Diaporama" msgid "Weekmail" msgstr "Weekmail" +#: com/templates/com/weekmail.jinja +msgid "Preview" +msgstr "Prévisualiser" + #: com/templates/com/weekmail.jinja com/templates/com/weekmail_preview.jinja msgid "Send" msgstr "Envoyer" @@ -1768,14 +1748,6 @@ msgstr "Astuce" msgid "Final word" msgstr "Le mot de la fin" -#: com/views.py -msgid "Format: 16:9 | Resolution: 1920x1080" -msgstr "Format : 16:9 | Résolution : 1920x1080" - -#: com/views.py election/views.py subscription/forms.py -msgid "Start date" -msgstr "Date de début" - #: com/views.py msgid "Communication administration" msgstr "Administration de la communication" @@ -1796,22 +1768,6 @@ msgstr "Message d'alerte" msgid "Screens list" msgstr "Liste d'écrans" -#: com/views.py rootplace/templates/rootplace/userban.jinja -msgid "Until" -msgstr "Jusqu'à" - -#: com/views.py -msgid "Automoderation" -msgstr "Automodération" - -#: com/views.py -msgid "This field is required." -msgstr "Ce champ est obligatoire." - -#: com/views.py -msgid "An event cannot end before its beginning." -msgstr "Un évènement ne peut pas se finir avant d'avoir commencé." - #: com/views.py msgid "Delete and save to regenerate" msgstr "Supprimer et sauver pour régénérer" @@ -2215,6 +2171,10 @@ msgstr "url" msgid "param" msgstr "param" +#: core/models.py launderette/models.py +msgid "type" +msgstr "type" + #: core/models.py msgid "viewed" msgstr "vue" @@ -4734,6 +4694,11 @@ msgstr "Machines" msgid "New machine" msgstr "Nouvelle machine" +#: launderette/templates/launderette/launderette_admin.jinja +#: launderette/views.py +msgid "Type" +msgstr "Type" + #: launderette/templates/launderette/launderette_book.jinja msgid "Choose" msgstr "Choisir" @@ -5134,6 +5099,10 @@ msgstr "Fusion" msgid "Ban a user" msgstr "Bannir un utilisateur" +#: rootplace/templates/rootplace/userban.jinja +msgid "Until" +msgstr "Jusqu'à" + #: rootplace/templates/rootplace/userban.jinja msgid "not specified" msgstr "non spécifié" diff --git a/sith/settings.py b/sith/settings.py index 42e46603..61079d64 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -152,6 +152,7 @@ TEMPLATES = [ "phonenumber": "core.templatetags.renderer.phonenumber", "truncate_time": "core.templatetags.renderer.truncate_time", "format_timedelta": "core.templatetags.renderer.format_timedelta", + "add_attr": "core.templatetags.renderer.add_attr", }, "globals": { "can_edit_prop": "core.views.can_edit_prop", From 8d73ec797b6472051b7f766e1e36fa9dd6e7b6cc Mon Sep 17 00:00:00 2001 From: imperosol Date: Fri, 10 Jan 2025 14:52:53 +0100 Subject: [PATCH 15/27] remove unwanted translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Django ne traduit pas ses permissions. Si on traduit les nôtres, ça devient inconsistant --- com/models.py | 2 +- locale/fr/LC_MESSAGES/django.po | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/com/models.py b/com/models.py index b6a388f1..011e8900 100644 --- a/com/models.py +++ b/com/models.py @@ -344,7 +344,7 @@ class Poster(models.Model): ) class Meta: - permissions = [("moderate_poster", _("Can moderate poster"))] + permissions = [("moderate_poster", "Can moderate poster")] def __str__(self): return self.name diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 64af1695..56b03b07 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-10 00:25+0100\n" +"POT-Creation-Date: 2025-01-10 14:52+0100\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Maréchal \n" @@ -1273,7 +1273,9 @@ msgstr "Événement Hebdomadaire" #: com/forms.py msgid "Weekly events will occur each week for a specified timespan." -msgstr "Les événements hebdomadaires se répéteront chaque semaine pendant une durée déterminée" +msgstr "" +"Les événements hebdomadaires se répéteront chaque semaine pendant une durée " +"déterminée" #: com/forms.py #, python-format @@ -1290,7 +1292,8 @@ msgstr "Occurences" #: com/forms.py msgid "How much times should the event occur (including the first one)" -msgstr "Combien de fois l'événement doit-il se répéter (en incluant la première fois)" +msgstr "" +"Combien de fois l'événement doit-il se répéter (en incluant la première fois)" #: com/forms.py msgid "Automoderation" @@ -1401,10 +1404,6 @@ msgstr "fichier" msgid "display time" msgstr "temps d'affichage" -#: com/models.py -msgid "Can moderate poster" -msgstr "Peut modérer les posters" - #: com/models.py msgid "Begin date should be before end date" msgstr "La date de début doit être avant celle de fin" From 9f35f5356b0cce79ff806a276ed1864fba29d463 Mon Sep 17 00:00:00 2001 From: imperosol Date: Fri, 10 Jan 2025 22:05:37 +0100 Subject: [PATCH 16/27] fix `NewsQuerySet.viewable_by` --- com/models.py | 15 ++++++++++---- com/tests/test_models.py | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 com/tests/test_models.py diff --git a/com/models.py b/com/models.py index 011e8900..85c2b63d 100644 --- a/com/models.py +++ b/com/models.py @@ -21,7 +21,7 @@ # Place - Suite 330, Boston, MA 02111-1307, USA. # # - +from typing import Self from django.conf import settings from django.core.exceptions import ValidationError @@ -55,13 +55,20 @@ class Sith(models.Model): class NewsQuerySet(models.QuerySet): - def moderated(self): + def moderated(self) -> Self: return self.filter(is_moderated=True) - def viewable_by(self, user: User): + def viewable_by(self, user: User) -> Self: + """Filter news that the given user can view. + + If the user has the `com.view_unmoderated_news` permission, + all news are viewable. + Else the viewable news are those that are either moderated + or authored by the user. + """ if user.has_perm("com.view_unmoderated_news"): return self - return self.moderated() + return self.filter(Q(is_moderated=True) | Q(author_id=user.id)) class News(models.Model): diff --git a/com/tests/test_models.py b/com/tests/test_models.py new file mode 100644 index 00000000..41be34ee --- /dev/null +++ b/com/tests/test_models.py @@ -0,0 +1,42 @@ +import itertools + +from django.contrib.auth.models import Permission +from django.test import TestCase +from model_bakery import baker + +from com.models import News +from core.models import User + + +class TestNewsViewableBy(TestCase): + @classmethod + def setUpTestData(cls): + News.objects.all().delete() + cls.users = baker.make(User, _quantity=3, _bulk_create=True) + # There are six news and six authors. + # Each author has one moderated and one non-moderated news + cls.news = baker.make( + News, + author=itertools.cycle(cls.users), + is_moderated=iter([True, True, True, False, False, False]), + _quantity=6, + _bulk_create=True, + ) + + def test_admin_can_view_everything(self): + """Test with a user that can view non moderated news.""" + user = baker.make( + User, + user_permissions=[Permission.objects.get(codename="view_unmoderated_news")], + ) + assert set(News.objects.viewable_by(user)) == set(self.news) + + def test_normal_user_can_view_moderated_and_self_news(self): + """Test that basic users can view moderated news and news they authored.""" + user = self.news[0].author + assert set(News.objects.viewable_by(user)) == { + self.news[0], + self.news[1], + self.news[2], + self.news[3], + } From c6bb509fc372ac582f009d951b3923b53d27bc44 Mon Sep 17 00:00:00 2001 From: imperosol Date: Fri, 10 Jan 2025 14:10:27 +0100 Subject: [PATCH 17/27] remove call to deprecated `imghdr` module --- core/models.py | 18 +++++++----------- locale/fr/LC_MESSAGES/django.po | 4 ++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/core/models.py b/core/models.py index 1b0ee0a3..b1caa912 100644 --- a/core/models.py +++ b/core/models.py @@ -29,6 +29,7 @@ import os import string import unicodedata from datetime import timedelta +from io import BytesIO from pathlib import Path from typing import TYPE_CHECKING, Optional, Self @@ -50,6 +51,7 @@ from django.utils.html import escape from django.utils.timezone import localdate, now from django.utils.translation import gettext_lazy as _ from phonenumber_field.modelfields import PhoneNumberField +from PIL import Image if TYPE_CHECKING: from pydantic import NonNegativeInt @@ -988,17 +990,11 @@ class SithFile(models.Model): if self.is_folder: if self.file: try: - import imghdr - - if imghdr.what(None, self.file.read()) not in [ - "gif", - "png", - "jpeg", - ]: - self.file.delete() - self.file = None - except: # noqa E722 I don't know the exception that can be raised - self.file = None + Image.open(BytesIO(self.file.read())) + except Image.UnidentifiedImageError as e: + raise ValidationError( + _("This is not a valid folder thumbnail") + ) from e self.mime_type = "inode/directory" if self.is_file and (self.file is None or self.file == ""): raise ValidationError(_("You must provide a file")) diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 56b03b07..07eede14 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -2110,6 +2110,10 @@ msgstr "" msgid "Duplicate file" msgstr "Un fichier de ce nom existe déjà" +#: core/models.py +msgid "This is not a valid folder thumbnail" +msgstr "Ceci n'est pas une miniature de dossier valide" + #: core/models.py msgid "You must provide a file" msgstr "Vous devez fournir un fichier" From 7ac41ac5cb479eae003b6a9f62b0112bb3a56a1f Mon Sep 17 00:00:00 2001 From: imperosol Date: Fri, 10 Jan 2025 15:17:41 +0100 Subject: [PATCH 18/27] remove `UserIsRootMixin` --- club/views.py | 5 +++-- core/templates/core/user_clubs.jinja | 4 ++-- core/views/__init__.py | 12 ------------ docs/tutorial/perms.md | 18 +++++++++--------- 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/club/views.py b/club/views.py index d713a1cc..eda5ac48 100644 --- a/club/views.py +++ b/club/views.py @@ -25,6 +25,7 @@ import csv from django.conf import settings +from django.contrib.auth.mixins import PermissionRequiredMixin from django.core.exceptions import NON_FIELD_ERRORS, PermissionDenied, ValidationError from django.core.paginator import InvalidPage, Paginator from django.db.models import Sum @@ -58,7 +59,6 @@ from core.views import ( DetailFormView, PageEditViewBase, TabedViewMixin, - UserIsRootMixin, ) from counter.models import Selling @@ -512,12 +512,13 @@ class MembershipSetOldView(CanEditMixin, DetailView): ) -class MembershipDeleteView(UserIsRootMixin, DeleteView): +class MembershipDeleteView(PermissionRequiredMixin, DeleteView): """Delete a membership (for admins only).""" model = Membership pk_url_kwarg = "membership_id" template_name = "core/delete_confirm.jinja" + permission_required = "club.delete_membership" def get_success_url(self): return reverse_lazy("core:user_clubs", kwargs={"user_id": self.object.user.id}) diff --git a/core/templates/core/user_clubs.jinja b/core/templates/core/user_clubs.jinja index 324f8389..51b6827f 100644 --- a/core/templates/core/user_clubs.jinja +++ b/core/templates/core/user_clubs.jinja @@ -30,7 +30,7 @@ {% if m.can_be_edited_by(user) %} {% trans %}Mark as old{% endtrans %} {% endif %} - {% if user.is_root %} + {% if user.has_perm("club.delete_membership") %} {% trans %}Delete{% endtrans %} {% endif %} @@ -59,7 +59,7 @@ {{ m.description }} {{ m.start_date }} {{ m.end_date }} - {% if user.is_root %} + {% if user.has_perm("club.delete_membership") %} {% trans %}Delete{% endtrans %} {% endif %} diff --git a/core/views/__init__.py b/core/views/__init__.py index f72addb6..debbc810 100644 --- a/core/views/__init__.py +++ b/core/views/__init__.py @@ -225,18 +225,6 @@ class CanViewMixin(GenericContentPermissionMixinBuilder): permission_function = can_view -class UserIsRootMixin(GenericContentPermissionMixinBuilder): - """Allow only root admins. - - Raises: - PermissionDenied: if the user isn't root - """ - - @staticmethod - def permission_function(obj: Any, user: User): - return user.is_root - - class FormerSubscriberMixin(AccessMixin): """Check if the user was at least an old subscriber. diff --git a/docs/tutorial/perms.md b/docs/tutorial/perms.md index c78292ab..0100f24c 100644 --- a/docs/tutorial/perms.md +++ b/docs/tutorial/perms.md @@ -154,7 +154,7 @@ Voici un exemple d'utilisation en reprenant l'objet Article crée précédemment ```python from django.views.generic import CreateView, ListView -from core.views import CanViewMixin, CanCreateMixin +from core.auth.mixins import CanViewMixin, CanCreateMixin from com.models import WeekmailArticle @@ -172,14 +172,14 @@ class ArticlesCreateView(CanCreateMixin, CreateView): Les mixins suivants sont implémentés : -- [CanCreateMixin][core.views.CanCreateMixin] : l'utilisateur peut-il créer l'objet ? -- [CanEditPropMixin][core.views.CanEditPropMixin] : l'utilisateur peut-il éditer les propriétés de l'objet ? -- [CanEditMixin][core.views.CanEditMixin] : L'utilisateur peut-il éditer l'objet ? -- [CanViewMixin][core.views.CanViewMixin] : L'utilisateur peut-il voir l'objet ? -- [UserIsRootMixin][core.views.UserIsRootMixin] : L'utilisateur a-t-il les droit root ? -- [FormerSubscriberMixin][core.views.FormerSubscriberMixin] : L'utilisateur a-t-il déjà été cotisant ? -- [UserIsLoggedMixin][core.views.UserIsLoggedMixin] : L'utilisateur est-il connecté ? - (à éviter ; préférez `LoginRequiredMixin`, fourni par Django) +- [CanCreateMixin][core.auth.mixins.CanCreateMixin] : l'utilisateur peut-il créer l'objet ? +- [CanEditPropMixin][core.auth.mixins.CanEditPropMixin] : l'utilisateur peut-il éditer les propriétés de l'objet ? +- [CanEditMixin][core.auth.mixins.CanEditMixin] : L'utilisateur peut-il éditer l'objet ? +- [CanViewMixin][core.auth.mixins.CanViewMixin] : L'utilisateur peut-il voir l'objet ? +- [FormerSubscriberMixin][core.auth.mixins.FormerSubscriberMixin] : L'utilisateur a-t-il déjà été cotisant ? +- [PermissionOrAuthorRequiredMixin][core.auth.mixins.PermissionOrAuthorRequiredMixin] : + L'utilisateur a-t-il la permission requise, ou bien est-il l'auteur de l'objet + auquel on veut accéder ? !!!danger "Performance" From cba915c34d36415780c42ba90e01faa91c2c4474 Mon Sep 17 00:00:00 2001 From: imperosol Date: Fri, 10 Jan 2025 15:58:22 +0100 Subject: [PATCH 19/27] Move core views mixins to their own file --- accounting/views.py | 9 ++---- club/views.py | 2 +- com/views.py | 13 ++------ core/views/__init__.py | 71 +---------------------------------------- core/views/files.py | 2 +- core/views/mixins.py | 67 ++++++++++++++++++++++++++++++++++++++ core/views/user.py | 9 ++---- counter/views/mixins.py | 2 +- pedagogy/views.py | 1 - trombi/views.py | 10 ++---- 10 files changed, 80 insertions(+), 106 deletions(-) create mode 100644 core/views/mixins.py diff --git a/accounting/views.py b/accounting/views.py index ce0ae45b..dd5d2e09 100644 --- a/accounting/views.py +++ b/accounting/views.py @@ -45,14 +45,9 @@ from accounting.widgets.select import ( from club.models import Club from club.widgets.select import AutoCompleteSelectClub from core.models import User -from core.views import ( - CanCreateMixin, - CanEditMixin, - CanEditPropMixin, - CanViewMixin, - TabedViewMixin, -) +from core.views import CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import SelectDate, SelectFile +from core.views.mixins import TabedViewMixin from core.views.widgets.select import AutoCompleteSelectUser from counter.models import Counter, Product, Selling diff --git a/club/views.py b/club/views.py index eda5ac48..a6b6d009 100644 --- a/club/views.py +++ b/club/views.py @@ -58,8 +58,8 @@ from core.views import ( CanViewMixin, DetailFormView, PageEditViewBase, - TabedViewMixin, ) +from core.views.mixins import TabedViewMixin from counter.models import Selling diff --git a/com/views.py b/com/views.py index 54e37578..9216cb00 100644 --- a/com/views.py +++ b/com/views.py @@ -27,10 +27,7 @@ from smtplib import SMTPRecipientsRefused from typing import Any from django.conf import settings -from django.contrib.auth.mixins import ( - AccessMixin, - PermissionRequiredMixin, -) +from django.contrib.auth.mixins import AccessMixin, PermissionRequiredMixin from django.core.exceptions import PermissionDenied, ValidationError from django.db.models import Max from django.forms.models import modelform_factory @@ -48,12 +45,8 @@ from com.calendar import IcsCalendar from com.forms import NewsDateForm, NewsForm, PosterForm from com.models import News, NewsDate, Poster, Screen, Sith, Weekmail, WeekmailArticle from core.models import User -from core.views import ( - CanEditPropMixin, - CanViewMixin, - QuickNotifMixin, - TabedViewMixin, -) +from core.views import CanEditPropMixin, CanViewMixin, QuickNotifMixin, TabedViewMixin +from core.views.mixins import QuickNotifMixin, TabedViewMixin from core.views.widgets.markdown import MarkdownInput # Sith object diff --git a/core/views/__init__.py b/core/views/__init__.py index debbc810..0cff8afe 100644 --- a/core/views/__init__.py +++ b/core/views/__init__.py @@ -25,18 +25,13 @@ import types from typing import Any -from django.conf import settings from django.contrib.auth.mixins import AccessMixin -from django.core.exceptions import ( - ImproperlyConfigured, - PermissionDenied, -) +from django.core.exceptions import PermissionDenied from django.http import ( HttpResponseForbidden, HttpResponseNotFound, HttpResponseServerError, ) -from django.shortcuts import render from django.utils.functional import cached_property from django.views.generic.base import View from django.views.generic.detail import SingleObjectMixin @@ -245,62 +240,6 @@ class SubscriberMixin(AccessMixin): return super().dispatch(request, *args, **kwargs) -class TabedViewMixin(View): - """Basic functions for displaying tabs in the template.""" - - def get_tabs_title(self): - if hasattr(self, "tabs_title"): - return self.tabs_title - raise ImproperlyConfigured("tabs_title is required") - - def get_current_tab(self): - if hasattr(self, "current_tab"): - return self.current_tab - raise ImproperlyConfigured("current_tab is required") - - def get_list_of_tabs(self): - if hasattr(self, "list_of_tabs"): - return self.list_of_tabs - raise ImproperlyConfigured("list_of_tabs is required") - - def get_context_data(self, **kwargs): - kwargs = super().get_context_data(**kwargs) - kwargs["tabs_title"] = self.get_tabs_title() - kwargs["current_tab"] = self.get_current_tab() - kwargs["list_of_tabs"] = self.get_list_of_tabs() - return kwargs - - -class QuickNotifMixin: - quick_notif_list = [] - - def dispatch(self, request, *arg, **kwargs): - # In some cases, the class can stay instanciated, so we need to reset the list - self.quick_notif_list = [] - return super().dispatch(request, *arg, **kwargs) - - def get_success_url(self): - ret = super().get_success_url() - if hasattr(self, "quick_notif_url_arg"): - if "?" in ret: - ret += "&" + self.quick_notif_url_arg - else: - ret += "?" + self.quick_notif_url_arg - return ret - - def get_context_data(self, **kwargs): - """Add quick notifications to context.""" - kwargs = super().get_context_data(**kwargs) - kwargs["quick_notifs"] = [] - for n in self.quick_notif_list: - kwargs["quick_notifs"].append(settings.SITH_QUICK_NOTIF[n]) - for key, val in settings.SITH_QUICK_NOTIF.items(): - for gk in self.request.GET: - if key == gk: - kwargs["quick_notifs"].append(val) - return kwargs - - class DetailFormView(SingleObjectMixin, FormView): """Class that allow both a detail view and a form view.""" @@ -314,14 +253,6 @@ class DetailFormView(SingleObjectMixin, FormView): return super().get_object() -class AllowFragment: - """Add `is_fragment` to templates. It's only True if the request is emitted by htmx""" - - def get_context_data(self, **kwargs): - kwargs["is_fragment"] = self.request.headers.get("HX-Request", False) - return super().get_context_data(**kwargs) - - # F403: those star-imports would be hellish to refactor # E402: putting those import at the top of the file would also be difficult from .files import * # noqa: F403 E402 diff --git a/core/views/files.py b/core/views/files.py index d5ffabb6..e2ccaa6b 100644 --- a/core/views/files.py +++ b/core/views/files.py @@ -35,12 +35,12 @@ from django.views.generic.edit import DeleteView, FormMixin, UpdateView from core.models import Notification, SithFile, User from core.views import ( - AllowFragment, CanEditMixin, CanEditPropMixin, CanViewMixin, can_view, ) +from core.views.mixins import AllowFragment from core.views.widgets.select import ( AutoCompleteSelectMultipleGroup, AutoCompleteSelectSithFile, diff --git a/core/views/mixins.py b/core/views/mixins.py new file mode 100644 index 00000000..9687f5d9 --- /dev/null +++ b/core/views/mixins.py @@ -0,0 +1,67 @@ +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured +from django.views import View + + +class TabedViewMixin(View): + """Basic functions for displaying tabs in the template.""" + + def get_tabs_title(self): + if hasattr(self, "tabs_title"): + return self.tabs_title + raise ImproperlyConfigured("tabs_title is required") + + def get_current_tab(self): + if hasattr(self, "current_tab"): + return self.current_tab + raise ImproperlyConfigured("current_tab is required") + + def get_list_of_tabs(self): + if hasattr(self, "list_of_tabs"): + return self.list_of_tabs + raise ImproperlyConfigured("list_of_tabs is required") + + def get_context_data(self, **kwargs): + kwargs = super().get_context_data(**kwargs) + kwargs["tabs_title"] = self.get_tabs_title() + kwargs["current_tab"] = self.get_current_tab() + kwargs["list_of_tabs"] = self.get_list_of_tabs() + return kwargs + + +class QuickNotifMixin: + quick_notif_list = [] + + def dispatch(self, request, *arg, **kwargs): + # In some cases, the class can stay instanciated, so we need to reset the list + self.quick_notif_list = [] + return super().dispatch(request, *arg, **kwargs) + + def get_success_url(self): + ret = super().get_success_url() + if hasattr(self, "quick_notif_url_arg"): + if "?" in ret: + ret += "&" + self.quick_notif_url_arg + else: + ret += "?" + self.quick_notif_url_arg + return ret + + def get_context_data(self, **kwargs): + """Add quick notifications to context.""" + kwargs = super().get_context_data(**kwargs) + kwargs["quick_notifs"] = [] + for n in self.quick_notif_list: + kwargs["quick_notifs"].append(settings.SITH_QUICK_NOTIF[n]) + for key, val in settings.SITH_QUICK_NOTIF.items(): + for gk in self.request.GET: + if key == gk: + kwargs["quick_notifs"].append(val) + return kwargs + + +class AllowFragment: + """Add `is_fragment` to templates. It's only True if the request is emitted by htmx""" + + def get_context_data(self, **kwargs): + kwargs["is_fragment"] = self.request.headers.get("HX-Request", False) + return super().get_context_data(**kwargs) diff --git a/core/views/user.py b/core/views/user.py index 264a8dd6..38966900 100644 --- a/core/views/user.py +++ b/core/views/user.py @@ -55,13 +55,7 @@ from django.views.generic.edit import FormView, UpdateView from honeypot.decorators import check_honeypot from core.models import Gift, Preferences, User -from core.views import ( - CanEditMixin, - CanEditPropMixin, - CanViewMixin, - QuickNotifMixin, - TabedViewMixin, -) +from core.views import CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import ( GiftForm, LoginForm, @@ -70,6 +64,7 @@ from core.views.forms import ( UserGroupsForm, UserProfileForm, ) +from core.views.mixins import QuickNotifMixin, TabedViewMixin from counter.models import Refilling, Selling from counter.views.student_card import StudentCardFormView from eboutic.models import Invoice diff --git a/counter/views/mixins.py b/counter/views/mixins.py index b72d6694..5c01392a 100644 --- a/counter/views/mixins.py +++ b/counter/views/mixins.py @@ -19,7 +19,7 @@ from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from django.views.generic.base import View -from core.views import TabedViewMixin +from core.views.mixins import TabedViewMixin class CounterAdminMixin(View): diff --git a/pedagogy/views.py b/pedagogy/views.py index 99dd8168..c7ef0297 100644 --- a/pedagogy/views.py +++ b/pedagogy/views.py @@ -39,7 +39,6 @@ from core.models import Notification, User from core.views import ( CanCreateMixin, CanEditPropMixin, - CanViewMixin, DetailFormView, FormerSubscriberMixin, ) diff --git a/trombi/views.py b/trombi/views.py index c5a1d205..398b4dee 100644 --- a/trombi/views.py +++ b/trombi/views.py @@ -39,15 +39,9 @@ from django.views.generic.edit import CreateView, DeleteView, UpdateView from club.models import Club from core.models import User -from core.views import ( - CanCreateMixin, - CanEditMixin, - CanEditPropMixin, - CanViewMixin, - QuickNotifMixin, - TabedViewMixin, -) +from core.views import CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import SelectDate +from core.views.mixins import QuickNotifMixin, TabedViewMixin from core.views.widgets.select import AutoCompleteSelectUser from trombi.models import Trombi, TrombiClubMembership, TrombiComment, TrombiUser From 0c01ad1770232349ba2e71b092f348fc1e2f70e1 Mon Sep 17 00:00:00 2001 From: imperosol Date: Fri, 10 Jan 2025 21:37:12 +0100 Subject: [PATCH 20/27] Move core auth mixins to their own file --- accounting/api.py | 2 +- accounting/views.py | 7 +- club/api.py | 2 +- club/views.py | 7 +- com/views.py | 2 +- core/api.py | 5 +- core/auth/__init__.py | 0 core/{ => auth}/api_permissions.py | 0 core/{auth_backends.py => auth/backends.py} | 0 core/auth/mixins.py | 212 ++++++++++++++++++++ core/views/__init__.py | 188 +---------------- core/views/files.py | 4 +- core/views/group.py | 3 +- core/views/page.py | 7 +- core/views/user.py | 2 +- counter/api.py | 2 +- counter/views/admin.py | 2 +- counter/views/cash.py | 2 +- counter/views/click.py | 2 +- counter/views/eticket.py | 2 +- counter/views/home.py | 2 +- counter/views/student_card.py | 2 +- docs/reference/core/api_permissions.md | 2 +- election/views.py | 2 +- forum/views.py | 2 +- galaxy/views.py | 7 +- launderette/views.py | 7 +- matmat/views.py | 3 +- pedagogy/api.py | 2 +- pedagogy/views.py | 9 +- sas/api.py | 2 +- sas/views.py | 2 +- sith/settings.py | 9 +- trombi/views.py | 7 +- 34 files changed, 274 insertions(+), 235 deletions(-) create mode 100644 core/auth/__init__.py rename core/{ => auth}/api_permissions.py (100%) rename core/{auth_backends.py => auth/backends.py} (100%) create mode 100644 core/auth/mixins.py diff --git a/accounting/api.py b/accounting/api.py index a16fb7ab..5ba6c12d 100644 --- a/accounting/api.py +++ b/accounting/api.py @@ -7,7 +7,7 @@ from ninja_extra.schemas import PaginatedResponseSchema from accounting.models import ClubAccount, Company from accounting.schemas import ClubAccountSchema, CompanySchema -from core.api_permissions import CanAccessLookup +from core.auth.api_permissions import CanAccessLookup @api_controller("/lookup", permissions=[CanAccessLookup]) diff --git a/accounting/views.py b/accounting/views.py index dd5d2e09..d379b60d 100644 --- a/accounting/views.py +++ b/accounting/views.py @@ -44,8 +44,13 @@ from accounting.widgets.select import ( ) from club.models import Club from club.widgets.select import AutoCompleteSelectClub +from core.auth.mixins import ( + CanCreateMixin, + CanEditMixin, + CanEditPropMixin, + CanViewMixin, +) from core.models import User -from core.views import CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import SelectDate, SelectFile from core.views.mixins import TabedViewMixin from core.views.widgets.select import AutoCompleteSelectUser diff --git a/club/api.py b/club/api.py index 9a680154..2ad0f5c8 100644 --- a/club/api.py +++ b/club/api.py @@ -7,7 +7,7 @@ from ninja_extra.schemas import PaginatedResponseSchema from club.models import Club from club.schemas import ClubSchema -from core.api_permissions import CanAccessLookup +from core.auth.api_permissions import CanAccessLookup @api_controller("/club") diff --git a/club/views.py b/club/views.py index a6b6d009..498e16e1 100644 --- a/club/views.py +++ b/club/views.py @@ -50,15 +50,14 @@ from com.views import ( PosterEditBaseView, PosterListBaseView, ) -from core.models import PageRev -from core.views import ( +from core.auth.mixins import ( CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin, - DetailFormView, - PageEditViewBase, ) +from core.models import PageRev +from core.views import DetailFormView, PageEditViewBase from core.views.mixins import TabedViewMixin from counter.models import Selling diff --git a/com/views.py b/com/views.py index 9216cb00..179c2bed 100644 --- a/com/views.py +++ b/com/views.py @@ -44,8 +44,8 @@ from club.models import Club, Mailing from com.calendar import IcsCalendar from com.forms import NewsDateForm, NewsForm, PosterForm from com.models import News, NewsDate, Poster, Screen, Sith, Weekmail, WeekmailArticle +from core.auth.mixins import CanEditPropMixin, CanViewMixin from core.models import User -from core.views import CanEditPropMixin, CanViewMixin, QuickNotifMixin, TabedViewMixin from core.views.mixins import QuickNotifMixin, TabedViewMixin from core.views.widgets.markdown import MarkdownInput diff --git a/core/api.py b/core/api.py index 1662cb84..e1b3bbbd 100644 --- a/core/api.py +++ b/core/api.py @@ -11,10 +11,7 @@ from ninja_extra.pagination import PageNumberPaginationExtra from ninja_extra.schemas import PaginatedResponseSchema from club.models import Mailing -from core.api_permissions import ( - CanAccessLookup, - CanView, -) +from core.auth.api_permissions import CanAccessLookup, CanView from core.models import Group, SithFile, User from core.schemas import ( FamilyGodfatherSchema, diff --git a/core/auth/__init__.py b/core/auth/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/core/api_permissions.py b/core/auth/api_permissions.py similarity index 100% rename from core/api_permissions.py rename to core/auth/api_permissions.py diff --git a/core/auth_backends.py b/core/auth/backends.py similarity index 100% rename from core/auth_backends.py rename to core/auth/backends.py diff --git a/core/auth/mixins.py b/core/auth/mixins.py new file mode 100644 index 00000000..b25397b0 --- /dev/null +++ b/core/auth/mixins.py @@ -0,0 +1,212 @@ +# +# Copyright 2016,2017 +# - Skia +# - Sli +# +# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, +# http://ae.utbm.fr. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License a published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple +# Place - Suite 330, Boston, MA 02111-1307, USA. +# +# + +import types +from typing import Any + +from django.contrib.auth.mixins import AccessMixin +from django.core.exceptions import PermissionDenied +from django.views.generic.base import View + +from core.models import User + + +def can_edit_prop(obj: Any, user: User) -> bool: + """Can the user edit the properties of the object. + + Args: + obj: Object to test for permission + user: core.models.User to test permissions against + + Returns: + True if user is authorized to edit object properties else False + + Examples: + ```python + if not can_edit_prop(self.object ,request.user): + raise PermissionDenied + ``` + """ + return obj is None or user.is_owner(obj) + + +def can_edit(obj: Any, user: User) -> bool: + """Can the user edit the object. + + Args: + obj: Object to test for permission + user: core.models.User to test permissions against + + Returns: + True if user is authorized to edit object else False + + Examples: + ```python + if not can_edit(self.object, request.user): + raise PermissionDenied + ``` + """ + if obj is None or user.can_edit(obj): + return True + return can_edit_prop(obj, user) + + +def can_view(obj: Any, user: User) -> bool: + """Can the user see the object. + + Args: + obj: Object to test for permission + user: core.models.User to test permissions against + + Returns: + True if user is authorized to see object else False + + Examples: + ```python + if not can_view(self.object ,request.user): + raise PermissionDenied + ``` + """ + if obj is None or user.can_view(obj): + return True + return can_edit(obj, user) + + +class GenericContentPermissionMixinBuilder(View): + """Used to build permission mixins. + + This view protect any child view that would be showing an object that is restricted based + on two properties. + + Attributes: + raised_error: permission to be raised + """ + + raised_error = PermissionDenied + + @staticmethod + def permission_function(obj: Any, user: User) -> bool: + """Function to test permission with.""" + return False + + @classmethod + def get_permission_function(cls, obj, user): + return cls.permission_function(obj, user) + + def dispatch(self, request, *arg, **kwargs): + if hasattr(self, "get_object") and callable(self.get_object): + self.object = self.get_object() + if not self.get_permission_function(self.object, request.user): + raise self.raised_error + return super().dispatch(request, *arg, **kwargs) + + # If we get here, it's a ListView + + queryset = self.get_queryset() + l_id = [o.id for o in queryset if self.get_permission_function(o, request.user)] + if not l_id and queryset.count() != 0: + raise self.raised_error + self._get_queryset = self.get_queryset + + def get_qs(self2): + return self2._get_queryset().filter(id__in=l_id) + + self.get_queryset = types.MethodType(get_qs, self) + return super().dispatch(request, *arg, **kwargs) + + +class CanCreateMixin(View): + """Protect any child view that would create an object. + + Raises: + PermissionDenied: + If the user has not the necessary permission + to create the object of the view. + """ + + def dispatch(self, request, *arg, **kwargs): + res = super().dispatch(request, *arg, **kwargs) + if not request.user.is_authenticated: + raise PermissionDenied + return res + + def form_valid(self, form): + obj = form.instance + if can_edit_prop(obj, self.request.user): + return super().form_valid(form) + raise PermissionDenied + + +class CanEditPropMixin(GenericContentPermissionMixinBuilder): + """Ensure the user has owner permissions on the child view object. + + In other word, you can make a view with this view as parent, + and it will be retricted to the users that are in the + object's owner_group or that pass the `obj.can_be_viewed_by` test. + + Raises: + PermissionDenied: If the user cannot see the object + """ + + permission_function = can_edit_prop + + +class CanEditMixin(GenericContentPermissionMixinBuilder): + """Ensure the user has permission to edit this view's object. + + Raises: + PermissionDenied: if the user cannot edit this view's object. + """ + + permission_function = can_edit + + +class CanViewMixin(GenericContentPermissionMixinBuilder): + """Ensure the user has permission to view this view's object. + + Raises: + PermissionDenied: if the user cannot edit this view's object. + """ + + permission_function = can_view + + +class FormerSubscriberMixin(AccessMixin): + """Check if the user was at least an old subscriber. + + Raises: + PermissionDenied: if the user never subscribed. + """ + + def dispatch(self, request, *args, **kwargs): + if not request.user.was_subscribed: + raise PermissionDenied + return super().dispatch(request, *args, **kwargs) + + +class SubscriberMixin(AccessMixin): + def dispatch(self, request, *args, **kwargs): + if not request.user.is_subscribed: + return self.handle_no_permission() + return super().dispatch(request, *args, **kwargs) diff --git a/core/views/__init__.py b/core/views/__init__.py index 0cff8afe..c8152f78 100644 --- a/core/views/__init__.py +++ b/core/views/__init__.py @@ -22,23 +22,17 @@ # # -import types -from typing import Any - -from django.contrib.auth.mixins import AccessMixin -from django.core.exceptions import PermissionDenied from django.http import ( HttpResponseForbidden, HttpResponseNotFound, HttpResponseServerError, ) +from django.shortcuts import render from django.utils.functional import cached_property -from django.views.generic.base import View from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import FormView from sentry_sdk import last_event_id -from core.models import User from core.views.forms import LoginForm @@ -60,186 +54,6 @@ def internal_servor_error(request): return HttpResponseServerError(render(request, "core/500.jinja")) -def can_edit_prop(obj: Any, user: User) -> bool: - """Can the user edit the properties of the object. - - Args: - obj: Object to test for permission - user: core.models.User to test permissions against - - Returns: - True if user is authorized to edit object properties else False - - Examples: - ```python - if not can_edit_prop(self.object ,request.user): - raise PermissionDenied - ``` - """ - return obj is None or user.is_owner(obj) - - -def can_edit(obj: Any, user: User) -> bool: - """Can the user edit the object. - - Args: - obj: Object to test for permission - user: core.models.User to test permissions against - - Returns: - True if user is authorized to edit object else False - - Examples: - ```python - if not can_edit(self.object, request.user): - raise PermissionDenied - ``` - """ - if obj is None or user.can_edit(obj): - return True - return can_edit_prop(obj, user) - - -def can_view(obj: Any, user: User) -> bool: - """Can the user see the object. - - Args: - obj: Object to test for permission - user: core.models.User to test permissions against - - Returns: - True if user is authorized to see object else False - - Examples: - ```python - if not can_view(self.object ,request.user): - raise PermissionDenied - ``` - """ - if obj is None or user.can_view(obj): - return True - return can_edit(obj, user) - - -class GenericContentPermissionMixinBuilder(View): - """Used to build permission mixins. - - This view protect any child view that would be showing an object that is restricted based - on two properties. - - Attributes: - raised_error: permission to be raised - """ - - raised_error = PermissionDenied - - @staticmethod - def permission_function(obj: Any, user: User) -> bool: - """Function to test permission with.""" - return False - - @classmethod - def get_permission_function(cls, obj, user): - return cls.permission_function(obj, user) - - def dispatch(self, request, *arg, **kwargs): - if hasattr(self, "get_object") and callable(self.get_object): - self.object = self.get_object() - if not self.get_permission_function(self.object, request.user): - raise self.raised_error - return super().dispatch(request, *arg, **kwargs) - - # If we get here, it's a ListView - - queryset = self.get_queryset() - l_id = [o.id for o in queryset if self.get_permission_function(o, request.user)] - if not l_id and queryset.count() != 0: - raise self.raised_error - self._get_queryset = self.get_queryset - - def get_qs(self2): - return self2._get_queryset().filter(id__in=l_id) - - self.get_queryset = types.MethodType(get_qs, self) - return super().dispatch(request, *arg, **kwargs) - - -class CanCreateMixin(View): - """Protect any child view that would create an object. - - Raises: - PermissionDenied: - If the user has not the necessary permission - to create the object of the view. - """ - - def dispatch(self, request, *arg, **kwargs): - res = super().dispatch(request, *arg, **kwargs) - if not request.user.is_authenticated: - raise PermissionDenied - return res - - def form_valid(self, form): - obj = form.instance - if can_edit_prop(obj, self.request.user): - return super().form_valid(form) - raise PermissionDenied - - -class CanEditPropMixin(GenericContentPermissionMixinBuilder): - """Ensure the user has owner permissions on the child view object. - - In other word, you can make a view with this view as parent, - and it will be retricted to the users that are in the - object's owner_group or that pass the `obj.can_be_viewed_by` test. - - Raises: - PermissionDenied: If the user cannot see the object - """ - - permission_function = can_edit_prop - - -class CanEditMixin(GenericContentPermissionMixinBuilder): - """Ensure the user has permission to edit this view's object. - - Raises: - PermissionDenied: if the user cannot edit this view's object. - """ - - permission_function = can_edit - - -class CanViewMixin(GenericContentPermissionMixinBuilder): - """Ensure the user has permission to view this view's object. - - Raises: - PermissionDenied: if the user cannot edit this view's object. - """ - - permission_function = can_view - - -class FormerSubscriberMixin(AccessMixin): - """Check if the user was at least an old subscriber. - - Raises: - PermissionDenied: if the user never subscribed. - """ - - def dispatch(self, request, *args, **kwargs): - if not request.user.was_subscribed: - raise PermissionDenied - return super().dispatch(request, *args, **kwargs) - - -class SubscriberMixin(AccessMixin): - def dispatch(self, request, *args, **kwargs): - if not request.user.is_subscribed: - return self.handle_no_permission() - return super().dispatch(request, *args, **kwargs) - - class DetailFormView(SingleObjectMixin, FormView): """Class that allow both a detail view and a form view.""" diff --git a/core/views/files.py b/core/views/files.py index e2ccaa6b..04498d5c 100644 --- a/core/views/files.py +++ b/core/views/files.py @@ -33,13 +33,13 @@ from django.views.generic import DetailView, ListView from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import DeleteView, FormMixin, UpdateView -from core.models import Notification, SithFile, User -from core.views import ( +from core.auth.mixins import ( CanEditMixin, CanEditPropMixin, CanViewMixin, can_view, ) +from core.models import Notification, SithFile, User from core.views.mixins import AllowFragment from core.views.widgets.select import ( AutoCompleteSelectMultipleGroup, diff --git a/core/views/group.py b/core/views/group.py index 978fe686..afd6874d 100644 --- a/core/views/group.py +++ b/core/views/group.py @@ -21,8 +21,9 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import ListView from django.views.generic.edit import CreateView, DeleteView, UpdateView +from core.auth.mixins import CanCreateMixin, CanEditMixin from core.models import Group, User -from core.views import CanCreateMixin, CanEditMixin, DetailFormView +from core.views import DetailFormView from core.views.widgets.select import AutoCompleteSelectMultipleUser # Forms diff --git a/core/views/page.py b/core/views/page.py index 51a0e1a5..f4b04f9c 100644 --- a/core/views/page.py +++ b/core/views/page.py @@ -21,8 +21,13 @@ from django.urls import reverse_lazy from django.views.generic import DetailView, ListView from django.views.generic.edit import CreateView, DeleteView, UpdateView +from core.auth.mixins import ( + CanCreateMixin, + CanEditMixin, + CanEditPropMixin, + CanViewMixin, +) from core.models import LockError, Page, PageRev -from core.views import CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import PageForm, PagePropForm from core.views.widgets.markdown import MarkdownInput diff --git a/core/views/user.py b/core/views/user.py index 38966900..5647d720 100644 --- a/core/views/user.py +++ b/core/views/user.py @@ -54,8 +54,8 @@ from django.views.generic.dates import MonthMixin, YearMixin from django.views.generic.edit import FormView, UpdateView from honeypot.decorators import check_honeypot +from core.auth.mixins import CanEditMixin, CanEditPropMixin, CanViewMixin from core.models import Gift, Preferences, User -from core.views import CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import ( GiftForm, LoginForm, diff --git a/counter/api.py b/counter/api.py index dd7b75f0..44b58488 100644 --- a/counter/api.py +++ b/counter/api.py @@ -20,7 +20,7 @@ from ninja_extra import ControllerBase, api_controller, paginate, route from ninja_extra.pagination import PageNumberPaginationExtra from ninja_extra.schemas import PaginatedResponseSchema -from core.api_permissions import CanAccessLookup, CanView, IsInGroup, IsRoot +from core.auth.api_permissions import CanAccessLookup, CanView, IsInGroup, IsRoot from counter.models import Counter, Product, ProductType from counter.schemas import ( CounterFilterSchema, diff --git a/counter/views/admin.py b/counter/views/admin.py index ab46581b..ffe81ea0 100644 --- a/counter/views/admin.py +++ b/counter/views/admin.py @@ -24,8 +24,8 @@ from django.utils import timezone from django.views.generic import DetailView, ListView, TemplateView from django.views.generic.edit import CreateView, DeleteView, UpdateView +from core.auth.mixins import CanEditMixin, CanViewMixin from core.utils import get_semester_code, get_start_of_semester -from core.views import CanEditMixin, CanViewMixin from counter.forms import CounterEditForm, ProductEditForm from counter.models import Counter, Product, ProductType, Refilling, Selling from counter.utils import is_logged_in_counter diff --git a/counter/views/cash.py b/counter/views/cash.py index d4a03af1..711f6864 100644 --- a/counter/views/cash.py +++ b/counter/views/cash.py @@ -23,7 +23,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView from django.views.generic.edit import UpdateView -from core.views import CanViewMixin +from core.auth.mixins import CanViewMixin from counter.forms import CashSummaryFormBase from counter.models import ( CashRegisterSummary, diff --git a/counter/views/click.py b/counter/views/click.py index c1815dec..4a1e1c88 100644 --- a/counter/views/click.py +++ b/counter/views/click.py @@ -31,9 +31,9 @@ from django.views.generic import FormView from django.views.generic.detail import SingleObjectMixin from ninja.main import HttpRequest +from core.auth.mixins import CanViewMixin from core.models import User from core.utils import FormFragmentTemplateData -from core.views import CanViewMixin from counter.forms import RefillForm from counter.models import Counter, Customer, Product, Selling from counter.utils import is_logged_in_counter diff --git a/counter/views/eticket.py b/counter/views/eticket.py index a05020d6..c5b4b872 100644 --- a/counter/views/eticket.py +++ b/counter/views/eticket.py @@ -18,7 +18,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView from django.views.generic.edit import CreateView, UpdateView -from core.views import CanViewMixin +from core.auth.mixins import CanViewMixin from counter.forms import EticketForm from counter.models import Eticket, Selling from counter.views.mixins import CounterAdminMixin, CounterAdminTabsMixin diff --git a/counter/views/home.py b/counter/views/home.py index d66b0969..0f0cd6dd 100644 --- a/counter/views/home.py +++ b/counter/views/home.py @@ -22,7 +22,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView from django.views.generic.edit import FormMixin, ProcessFormView -from core.views import CanViewMixin +from core.auth.mixins import CanViewMixin from core.views.forms import LoginForm from counter.forms import GetUserForm from counter.models import Counter diff --git a/counter/views/student_card.py b/counter/views/student_card.py index f916260b..6e2a3358 100644 --- a/counter/views/student_card.py +++ b/counter/views/student_card.py @@ -21,8 +21,8 @@ from django.urls import reverse from django.utils.translation import gettext as _ from django.views.generic.edit import DeleteView, FormView +from core.auth.mixins import can_edit from core.utils import FormFragmentTemplateData -from core.views import can_edit from counter.forms import StudentCardForm from counter.models import Customer, StudentCard from counter.utils import is_logged_in_counter diff --git a/docs/reference/core/api_permissions.md b/docs/reference/core/api_permissions.md index 2d693fca..4ab3a2e0 100644 --- a/docs/reference/core/api_permissions.md +++ b/docs/reference/core/api_permissions.md @@ -1 +1 @@ -::: core.api_permissions \ No newline at end of file +::: core.auth.api_permissions \ No newline at end of file diff --git a/election/views.py b/election/views.py index 422205fd..1b5439f3 100644 --- a/election/views.py +++ b/election/views.py @@ -10,7 +10,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView -from core.views import CanCreateMixin, CanEditMixin, CanViewMixin +from core.auth.mixins import CanCreateMixin, CanEditMixin, CanViewMixin from core.views.forms import SelectDateTime from core.views.widgets.markdown import MarkdownInput from core.views.widgets.select import ( diff --git a/forum/views.py b/forum/views.py index 074f496d..9501cf1b 100644 --- a/forum/views.py +++ b/forum/views.py @@ -43,7 +43,7 @@ from haystack.query import RelatedSearchQuerySet from honeypot.decorators import check_honeypot from club.widgets.select import AutoCompleteSelectClub -from core.views import ( +from core.auth.mixins import ( CanCreateMixin, CanEditMixin, CanEditPropMixin, diff --git a/galaxy/views.py b/galaxy/views.py index fe27f978..cb116d02 100644 --- a/galaxy/views.py +++ b/galaxy/views.py @@ -27,12 +27,9 @@ from django.http import Http404, JsonResponse from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, View +from core.auth.mixins import CanViewMixin, FormerSubscriberMixin from core.models import User -from core.views import ( - CanViewMixin, - FormerSubscriberMixin, - UserTabsMixin, -) +from core.views import UserTabsMixin from galaxy.models import Galaxy, GalaxyLane diff --git a/launderette/views.py b/launderette/views.py index 7886d1e7..be2bfceb 100644 --- a/launderette/views.py +++ b/launderette/views.py @@ -28,8 +28,13 @@ from django.views.generic import DetailView, ListView, TemplateView from django.views.generic.edit import BaseFormView, CreateView, DeleteView, UpdateView from club.models import Club +from core.auth.mixins import ( + CanCreateMixin, + CanEditMixin, + CanEditPropMixin, + CanViewMixin, +) from core.models import Page, User -from core.views import CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin from counter.forms import GetUserForm from counter.models import Counter, Customer, Selling from launderette.models import Launderette, Machine, Slot, Token diff --git a/matmat/views.py b/matmat/views.py index 47840c2d..1f037234 100644 --- a/matmat/views.py +++ b/matmat/views.py @@ -32,8 +32,9 @@ from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import FormView from phonenumber_field.widgets import RegionalPhoneNumberWidget +from core.auth.mixins import FormerSubscriberMixin from core.models import User -from core.views import FormerSubscriberMixin, search_user +from core.views import search_user from core.views.forms import SelectDate # Enum to select search type diff --git a/pedagogy/api.py b/pedagogy/api.py index d7a8d457..68e3d5e2 100644 --- a/pedagogy/api.py +++ b/pedagogy/api.py @@ -7,7 +7,7 @@ from ninja_extra import ControllerBase, api_controller, paginate, route from ninja_extra.exceptions import NotFound from ninja_extra.pagination import PageNumberPaginationExtra, PaginatedResponseSchema -from core.api_permissions import IsInGroup, IsRoot, IsSubscriber +from core.auth.api_permissions import IsInGroup, IsRoot, IsSubscriber from pedagogy.models import UV from pedagogy.schemas import SimpleUvSchema, UvFilterSchema, UvSchema from pedagogy.utbm_api import find_uv diff --git a/pedagogy/views.py b/pedagogy/views.py index c7ef0297..770dc2a4 100644 --- a/pedagogy/views.py +++ b/pedagogy/views.py @@ -35,13 +35,14 @@ from django.views.generic import ( UpdateView, ) -from core.models import Notification, User -from core.views import ( +from core.auth.mixins import ( CanCreateMixin, CanEditPropMixin, - DetailFormView, + CanViewMixin, FormerSubscriberMixin, ) +from core.models import Notification, User +from core.views import DetailFormView from pedagogy.forms import ( UVCommentForm, UVCommentModerationForm, @@ -50,8 +51,6 @@ from pedagogy.forms import ( ) from pedagogy.models import UV, UVComment, UVCommentReport -# Acutal views - class UVDetailFormView(CanViewMixin, DetailFormView): """Display every comment of an UV and detailed infos about it. diff --git a/sas/api.py b/sas/api.py index 6a25607a..96bafb87 100644 --- a/sas/api.py +++ b/sas/api.py @@ -12,7 +12,7 @@ from ninja_extra.permissions import IsAuthenticated from ninja_extra.schemas import PaginatedResponseSchema from pydantic import NonNegativeInt -from core.api_permissions import CanAccessLookup, CanView, IsInGroup, IsRoot +from core.auth.api_permissions import CanAccessLookup, CanView, IsInGroup, IsRoot from core.models import Notification, User from sas.models import Album, PeoplePictureRelation, Picture from sas.schemas import ( diff --git a/sas/views.py b/sas/views.py index 748dc718..7c8c8ea2 100644 --- a/sas/views.py +++ b/sas/views.py @@ -23,8 +23,8 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, TemplateView from django.views.generic.edit import FormMixin, FormView, UpdateView +from core.auth.mixins import CanEditMixin, CanViewMixin from core.models import SithFile, User -from core.views import CanEditMixin, CanViewMixin from core.views.files import FileView, send_file from sas.forms import ( AlbumEditForm, diff --git a/sith/settings.py b/sith/settings.py index 61079d64..9929995e 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -155,13 +155,12 @@ TEMPLATES = [ "add_attr": "core.templatetags.renderer.add_attr", }, "globals": { - "can_edit_prop": "core.views.can_edit_prop", - "can_edit": "core.views.can_edit", - "can_view": "core.views.can_view", + "can_edit_prop": "core.auth.mixins.can_edit_prop", + "can_edit": "core.auth.mixins.can_edit", + "can_view": "core.auth.mixins.can_view", "settings": "sith.settings", "Launderette": "launderette.models.Launderette", "Counter": "counter.models.Counter", - "ProductType": "counter.models.ProductType", "timezone": "django.utils.timezone", "get_sith": "com.views.sith", "get_language": "django.utils.translation.get_language", @@ -292,7 +291,7 @@ STORAGES = { # Auth configuration AUTH_USER_MODEL = "core.User" AUTH_ANONYMOUS_MODEL = "core.models.AnonymousUser" -AUTHENTICATION_BACKENDS = ["core.auth_backends.SithModelBackend"] +AUTHENTICATION_BACKENDS = ["core.auth.backends.SithModelBackend"] LOGIN_URL = "/login" LOGOUT_URL = "/logout" LOGIN_REDIRECT_URL = "/" diff --git a/trombi/views.py b/trombi/views.py index 398b4dee..7f43e199 100644 --- a/trombi/views.py +++ b/trombi/views.py @@ -38,8 +38,13 @@ from django.views.generic import DetailView, RedirectView, TemplateView, View from django.views.generic.edit import CreateView, DeleteView, UpdateView from club.models import Club +from core.auth.mixins import ( + CanCreateMixin, + CanEditMixin, + CanEditPropMixin, + CanViewMixin, +) from core.models import User -from core.views import CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import SelectDate from core.views.mixins import QuickNotifMixin, TabedViewMixin from core.views.widgets.select import AutoCompleteSelectUser From 551091f6501388b1962b60a438a98bdf29c3aa4a Mon Sep 17 00:00:00 2001 From: imperosol Date: Sat, 11 Jan 2025 02:22:12 +0100 Subject: [PATCH 21/27] add `PermissionOrAuthorRequiredMixin` --- com/models.py | 13 +++++++-- com/views.py | 23 ++++++++------- core/auth/mixins.py | 68 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 86 insertions(+), 18 deletions(-) diff --git a/com/models.py b/com/models.py index 85c2b63d..1219410a 100644 --- a/com/models.py +++ b/com/models.py @@ -68,7 +68,10 @@ class NewsQuerySet(models.QuerySet): """ if user.has_perm("com.view_unmoderated_news"): return self - return self.filter(Q(is_moderated=True) | Q(author_id=user.id)) + q_filter = Q(is_moderated=True) + if user.is_authenticated: + q_filter |= Q(author_id=user.id) + return self.filter(q_filter) class News(models.Model): @@ -149,8 +152,12 @@ class News(models.Model): self.author_id == user.id or user.has_perm("com.change_news") ) - def can_be_viewed_by(self, user): - return self.is_moderated or user.has_perm("com.view_unmoderated_news") + def can_be_viewed_by(self, user: User): + return ( + self.is_moderated + or user.has_perm("com.view_unmoderated_news") + or (user.is_authenticated and self.author_id == user.id) + ) def news_notification_callback(notif): diff --git a/com/views.py b/com/views.py index 179c2bed..7d29dd62 100644 --- a/com/views.py +++ b/com/views.py @@ -44,7 +44,11 @@ from club.models import Club, Mailing from com.calendar import IcsCalendar from com.forms import NewsDateForm, NewsForm, PosterForm from com.models import News, NewsDate, Poster, Screen, Sith, Weekmail, WeekmailArticle -from core.auth.mixins import CanEditPropMixin, CanViewMixin +from core.auth.mixins import ( + CanEditPropMixin, + CanViewMixin, + PermissionOrAuthorRequiredMixin, +) from core.models import User from core.views.mixins import QuickNotifMixin, TabedViewMixin from core.views.widgets.markdown import MarkdownInput @@ -162,24 +166,19 @@ class NewsCreateView(PermissionRequiredMixin, CreateView): return init -class NewsUpdateView(UpdateView): +class NewsUpdateView(PermissionOrAuthorRequiredMixin, UpdateView): model = News form_class = NewsForm template_name = "com/news_edit.jinja" pk_url_kwarg = "news_id" - - def dispatch(self, request, *args, **kwargs): - if ( - not request.user.has_perm("com.edit_news") - and self.get_object().author != request.user - ): - raise PermissionDenied - return super().dispatch(request, *args, **kwargs) + permission_required = "com.edit_news" def form_valid(self, form): self.object = form.save() IcsCalendar.make_internal() - return super().form_valid(form) + # Don't call `super().form_valid()`, + # because it would trigger a second call to `form.save()` + return HttpResponseRedirect(self.get_success_url()) def get_date_form_kwargs(self) -> dict[str, Any]: """Get initial data for NewsDateForm""" @@ -202,7 +201,7 @@ class NewsUpdateView(UpdateView): } -class NewsDeleteView(PermissionRequiredMixin, DeleteView): +class NewsDeleteView(PermissionOrAuthorRequiredMixin, DeleteView): model = News pk_url_kwarg = "news_id" template_name = "core/delete_confirm.jinja" diff --git a/core/auth/mixins.py b/core/auth/mixins.py index b25397b0..794021d5 100644 --- a/core/auth/mixins.py +++ b/core/auth/mixins.py @@ -23,14 +23,17 @@ # import types -from typing import Any +from typing import TYPE_CHECKING, Any, LiteralString -from django.contrib.auth.mixins import AccessMixin -from django.core.exceptions import PermissionDenied +from django.contrib.auth.mixins import AccessMixin, PermissionRequiredMixin +from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.views.generic.base import View from core.models import User +if TYPE_CHECKING: + from django.db.models import Model + def can_edit_prop(obj: Any, user: User) -> bool: """Can the user edit the properties of the object. @@ -210,3 +213,62 @@ class SubscriberMixin(AccessMixin): if not request.user.is_subscribed: return self.handle_no_permission() return super().dispatch(request, *args, **kwargs) + + +class PermissionOrAuthorRequiredMixin(PermissionRequiredMixin): + """Require that the user has the required perm or is the object author. + + This mixin can be used in combination with `DetailView`, + or another base class that implements the `get_object` method. + + Example: + In the following code, a user will be able + to edit news if he has the `com.change_news` permission + or if he tries to edit his own news : + + ```python + class NewsEditView(PermissionOrAuthorRequiredMixin, DetailView): + model = News + author_field = "author" + permission_required = "com.change_news" + ``` + + This is more or less equivalent to : + + ```python + class NewsEditView(PermissionOrAuthorRequiredMixin, DetailView): + model = News + + def dispatch(self, request, *args, **kwargs): + self.object = self.get_object() + if not ( + user.has_perm("com.change_news") + or self.object.author == request.user + ): + raise PermissionDenied + return super().dispatch(request, *args, **kwargs) + ``` + """ + + author_field: LiteralString = "author" + + def has_permission(self): + if not hasattr(self, "get_object"): + raise ImproperlyConfigured( + f"{self.__class__.__name__} is missing the " + "get_object attribute. " + f"Define {self.__class__.__name__}.get_object, " + "or inherit from a class that implement it (like DetailView)" + ) + if super().has_permission(): + return True + if self.request.user.is_anonymous: + return False + obj: Model = self.get_object() + if not self.author_field.endswith("_id"): + # getting the related model could trigger a db query + # so we will rather get the foreign value than + # the object itself. + self.author_field += "_id" + author_id = getattr(obj, self.author_field, None) + return author_id == self.request.user.id From e500cf92ee72f31cb40d2f8e52a1e8fd87eeae77 Mon Sep 17 00:00:00 2001 From: imperosol Date: Mon, 13 Jan 2025 15:57:01 +0100 Subject: [PATCH 22/27] Remove `SubscriberMixin` --- core/auth/mixins.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core/auth/mixins.py b/core/auth/mixins.py index 794021d5..422d7bce 100644 --- a/core/auth/mixins.py +++ b/core/auth/mixins.py @@ -208,13 +208,6 @@ class FormerSubscriberMixin(AccessMixin): return super().dispatch(request, *args, **kwargs) -class SubscriberMixin(AccessMixin): - def dispatch(self, request, *args, **kwargs): - if not request.user.is_subscribed: - return self.handle_no_permission() - return super().dispatch(request, *args, **kwargs) - - class PermissionOrAuthorRequiredMixin(PermissionRequiredMixin): """Require that the user has the required perm or is the object author. From d0b1a4930014d5e7310312e4b416163664d98073 Mon Sep 17 00:00:00 2001 From: imperosol Date: Mon, 13 Jan 2025 17:31:04 +0100 Subject: [PATCH 23/27] deprecate `CanCreateMixin` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les motifs de cette déprécation sont indiqués dans la documentation. Le mixin a été remplacé par `PermissionRequiredMixin` dans les endroits où ce remplacement était aisé. --- accounting/views.py | 7 +++++-- club/views.py | 3 ++- com/tests/test_views.py | 6 +++--- core/auth/mixins.py | 19 ++++++++++++++++++ core/management/commands/populate.py | 4 +++- core/tests/test_core.py | 9 +++------ core/views/group.py | 6 ++++-- docs/tutorial/perms.md | 30 +++++++++++++++++++++++++--- election/views.py | 24 +++++++++------------- launderette/views.py | 14 ++++++------- pedagogy/tests/tests.py | 9 +++++---- pedagogy/views.py | 15 ++++++-------- sith/settings.py | 4 ++-- 13 files changed, 94 insertions(+), 56 deletions(-) diff --git a/accounting/views.py b/accounting/views.py index d379b60d..f9fd8412 100644 --- a/accounting/views.py +++ b/accounting/views.py @@ -17,6 +17,7 @@ import collections from django import forms from django.conf import settings +from django.contrib.auth.mixins import PermissionRequiredMixin from django.core.exceptions import PermissionDenied, ValidationError from django.db import transaction from django.db.models import Sum @@ -86,12 +87,13 @@ class SimplifiedAccountingTypeEditView(CanViewMixin, UpdateView): template_name = "core/edit.jinja" -class SimplifiedAccountingTypeCreateView(CanCreateMixin, CreateView): +class SimplifiedAccountingTypeCreateView(PermissionRequiredMixin, CreateView): """Create an accounting type (for the admins).""" model = SimplifiedAccountingType fields = ["label", "accounting_type"] template_name = "core/create.jinja" + permission_required = "accounting.add_simplifiedaccountingtype" # Accounting types @@ -113,12 +115,13 @@ class AccountingTypeEditView(CanViewMixin, UpdateView): template_name = "core/edit.jinja" -class AccountingTypeCreateView(CanCreateMixin, CreateView): +class AccountingTypeCreateView(PermissionRequiredMixin, CreateView): """Create an accounting type (for the admins).""" model = AccountingType fields = ["code", "label", "movement_type"] template_name = "core/create.jinja" + permission_required = "accounting.add_accountingtype" # BankAccount views diff --git a/club/views.py b/club/views.py index 498e16e1..de5ccaee 100644 --- a/club/views.py +++ b/club/views.py @@ -473,13 +473,14 @@ class ClubEditPropView(ClubTabsMixin, CanEditPropMixin, UpdateView): current_tab = "props" -class ClubCreateView(CanCreateMixin, CreateView): +class ClubCreateView(PermissionRequiredMixin, CreateView): """Create a club (for the Sith admin).""" model = Club pk_url_kwarg = "club_id" fields = ["name", "unix_name", "parent"] template_name = "core/edit.jinja" + permission_required = "club.add_club" class MembershipSetOldView(CanEditMixin, DetailView): diff --git a/com/tests/test_views.py b/com/tests/test_views.py index c526dee5..100a83ef 100644 --- a/com/tests/test_views.py +++ b/com/tests/test_views.py @@ -159,13 +159,13 @@ class TestNews(TestCase): def test_news_viewer(self): """Test that moderated news can be viewed by anyone - and not moderated news only by com admins. + and not moderated news only by com admins and by their author. """ - # by default a news isn't moderated + # by default news aren't moderated assert self.new.can_be_viewed_by(self.com_admin) + assert self.new.can_be_viewed_by(self.author) assert not self.new.can_be_viewed_by(self.sli) assert not self.new.can_be_viewed_by(self.anonymous) - assert not self.new.can_be_viewed_by(self.author) self.new.is_moderated = True self.new.save() diff --git a/core/auth/mixins.py b/core/auth/mixins.py index 422d7bce..c25ecb57 100644 --- a/core/auth/mixins.py +++ b/core/auth/mixins.py @@ -23,6 +23,7 @@ # import types +import warnings from typing import TYPE_CHECKING, Any, LiteralString from django.contrib.auth.mixins import AccessMixin, PermissionRequiredMixin @@ -148,6 +149,24 @@ class CanCreateMixin(View): to create the object of the view. """ + def __init_subclass__(cls, **kwargs): + warnings.warn( + f"{cls.__name__} is deprecated and should be replaced " + "by other permission verification mecanism.", + DeprecationWarning, + stacklevel=2, + ) + super().__init_subclass__(**kwargs) + + def __init__(self, *args, **kwargs): + warnings.warn( + f"{self.__class__.__name__} is deprecated and should be replaced " + "by other permission verification mecanism.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) + def dispatch(self, request, *arg, **kwargs): res = super().dispatch(request, *arg, **kwargs) if not request.user.is_authenticated: diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index a5131d64..5e0f099d 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -894,7 +894,9 @@ Welcome to the wiki page! public_group = Group.objects.create(name="Public") subscribers = Group.objects.create(name="Subscribers") - subscribers.permissions.add(*list(perms.filter(codename__in=["add_news"]))) + subscribers.permissions.add( + *list(perms.filter(codename__in=["add_news", "add_uvcommentreport"])) + ) old_subscribers = Group.objects.create(name="Old subscribers") old_subscribers.permissions.add( *list( diff --git a/core/tests/test_core.py b/core/tests/test_core.py index 878db4e4..e6b37e5c 100644 --- a/core/tests/test_core.py +++ b/core/tests/test_core.py @@ -327,12 +327,9 @@ http://git.an class TestUserTools: def test_anonymous_user_unauthorized(self, client): """An anonymous user shouldn't have access to the tools page.""" - response = client.get(reverse("core:user_tools")) - assertRedirects( - response, - expected_url="/login?next=%2Fuser%2Ftools%2F", - target_status_code=301, - ) + url = reverse("core:user_tools") + response = client.get(url) + assertRedirects(response, expected_url=reverse("core:login") + f"?next={url}") @pytest.mark.parametrize("username", ["guy", "root", "skia", "comunity"]) def test_page_is_working(self, client, username): diff --git a/core/views/group.py b/core/views/group.py index afd6874d..e17db138 100644 --- a/core/views/group.py +++ b/core/views/group.py @@ -16,12 +16,13 @@ """Views to manage Groups.""" from django import forms +from django.contrib.auth.mixins import PermissionRequiredMixin from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from django.views.generic import ListView from django.views.generic.edit import CreateView, DeleteView, UpdateView -from core.auth.mixins import CanCreateMixin, CanEditMixin +from core.auth.mixins import CanEditMixin from core.models import Group, User from core.views import DetailFormView from core.views.widgets.select import AutoCompleteSelectMultipleUser @@ -74,13 +75,14 @@ class GroupEditView(CanEditMixin, UpdateView): fields = ["name", "description"] -class GroupCreateView(CanCreateMixin, CreateView): +class GroupCreateView(PermissionRequiredMixin, CreateView): """Add a new Group.""" model = Group queryset = Group.objects.filter(is_manually_manageable=True) template_name = "core/create.jinja" fields = ["name", "description"] + permission_required = "core.add_group" class GroupTemplateView(CanEditMixin, DetailFormView): diff --git a/docs/tutorial/perms.md b/docs/tutorial/perms.md index 0100f24c..8a84fda7 100644 --- a/docs/tutorial/perms.md +++ b/docs/tutorial/perms.md @@ -173,13 +173,37 @@ class ArticlesCreateView(CanCreateMixin, CreateView): Les mixins suivants sont implémentés : - [CanCreateMixin][core.auth.mixins.CanCreateMixin] : l'utilisateur peut-il créer l'objet ? + Ce mixin existe, mais est déprécié et ne doit plus être utilisé ! - [CanEditPropMixin][core.auth.mixins.CanEditPropMixin] : l'utilisateur peut-il éditer les propriétés de l'objet ? - [CanEditMixin][core.auth.mixins.CanEditMixin] : L'utilisateur peut-il éditer l'objet ? - [CanViewMixin][core.auth.mixins.CanViewMixin] : L'utilisateur peut-il voir l'objet ? - [FormerSubscriberMixin][core.auth.mixins.FormerSubscriberMixin] : L'utilisateur a-t-il déjà été cotisant ? -- [PermissionOrAuthorRequiredMixin][core.auth.mixins.PermissionOrAuthorRequiredMixin] : - L'utilisateur a-t-il la permission requise, ou bien est-il l'auteur de l'objet - auquel on veut accéder ? + +!!!danger "CanCreateMixin" + + L'usage de `CanCreateMixin` est dangereux et ne doit en aucun cas être + étendu. + La façon dont ce mixin marche est qu'il valide le formulaire + de création et crée l'objet sans le persister en base de données, puis + vérifie les droits sur cet objet non-persisté. + Le danger de ce système vient de multiples raisons : + - Les vérifications se faisant sur un objet non persisté, + l'utilisation de mécanismes nécessitant une persistance préalable + peut mener à des comportements indésirés, voire à des erreurs. + - Les développeurs de django ayant tendance à restreindre progressivement + les actions qui peuvent être faites sur des objets non-persistés, + les mises-à-jour de django deviennent plus compliquées. + - La vérification des droits ne se fait que dans les requêtes POST, + à la toute fin de la requête. + Tout ce qui arrive avant n'est absolument pas protégé. + Toute opération (même les suppressions et les créations) qui ont + lieu avant la persistance de l'objet seront appliquées, + même sans permission. + - Si un développeur du site fait l'erreur de surcharger + la méthode `form_valid` (ce qui est plutôt courant, + lorsqu'on veut accomplir certaines actions + quand un formulaire est valide), on peut se retrouver + dans une situation où l'objet est persisté sans aucune protection. !!!danger "Performance" diff --git a/election/views.py b/election/views.py index 1b5439f3..cd367b63 100644 --- a/election/views.py +++ b/election/views.py @@ -1,6 +1,7 @@ from typing import TYPE_CHECKING from django import forms +from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin from django.core.exceptions import PermissionDenied from django.db import transaction from django.db.models.query import QuerySet @@ -300,7 +301,7 @@ class VoteFormView(CanCreateMixin, FormView): # Create views -class CandidatureCreateView(CanCreateMixin, CreateView): +class CandidatureCreateView(LoginRequiredMixin, CreateView): """View dedicated to a cundidature creation.""" form_class = CandidateForm @@ -326,12 +327,13 @@ class CandidatureCreateView(CanCreateMixin, CreateView): def form_valid(self, form): """Verify that the selected user is in candidate group.""" obj = form.instance - obj.election = Election.objects.get(id=self.election.id) - obj.user = obj.user if hasattr(obj, "user") else self.request.user + obj.election = self.election + if not hasattr(obj, "user"): + obj.user = self.request.user if (obj.election.can_candidate(obj.user)) and ( obj.user == self.request.user or self.can_edit ): - return super(CreateView, self).form_valid(form) + return super().form_valid(form) raise PermissionDenied def get_context_data(self, **kwargs): @@ -343,22 +345,14 @@ class CandidatureCreateView(CanCreateMixin, CreateView): return reverse_lazy("election:detail", kwargs={"election_id": self.election.id}) -class ElectionCreateView(CanCreateMixin, CreateView): +class ElectionCreateView(PermissionRequiredMixin, CreateView): model = Election form_class = ElectionForm template_name = "core/create.jinja" - - def dispatch(self, request, *args, **kwargs): - if not request.user.is_subscribed: - raise PermissionDenied - return super().dispatch(request, *args, **kwargs) - - def form_valid(self, form): - """Allow every user that had passed the dispatch to create an election.""" - return super(CreateView, self).form_valid(form) + permission_required = "election.add_election" def get_success_url(self, **kwargs): - return reverse_lazy("election:detail", kwargs={"election_id": self.object.id}) + return reverse("election:detail", kwargs={"election_id": self.object.id}) class RoleCreateView(CanCreateMixin, CreateView): diff --git a/launderette/views.py b/launderette/views.py index be2bfceb..92a81dad 100644 --- a/launderette/views.py +++ b/launderette/views.py @@ -19,6 +19,7 @@ from datetime import timezone as tz from django import forms from django.conf import settings +from django.contrib.auth.mixins import PermissionRequiredMixin from django.db import transaction from django.template import defaultfilters from django.urls import reverse_lazy @@ -28,12 +29,7 @@ from django.views.generic import DetailView, ListView, TemplateView from django.views.generic.edit import BaseFormView, CreateView, DeleteView, UpdateView from club.models import Club -from core.auth.mixins import ( - CanCreateMixin, - CanEditMixin, - CanEditPropMixin, - CanViewMixin, -) +from core.auth.mixins import CanEditMixin, CanEditPropMixin, CanViewMixin from core.models import Page, User from counter.forms import GetUserForm from counter.models import Counter, Customer, Selling @@ -191,12 +187,13 @@ class LaunderetteEditView(CanEditPropMixin, UpdateView): template_name = "core/edit.jinja" -class LaunderetteCreateView(CanCreateMixin, CreateView): +class LaunderetteCreateView(PermissionRequiredMixin, CreateView): """Create a new launderette.""" model = Launderette fields = ["name"] template_name = "core/create.jinja" + permission_required = "launderette.add_launderette" def form_valid(self, form): club = Club.objects.filter( @@ -497,12 +494,13 @@ class MachineDeleteView(CanEditPropMixin, DeleteView): success_url = reverse_lazy("launderette:launderette_list") -class MachineCreateView(CanCreateMixin, CreateView): +class MachineCreateView(PermissionRequiredMixin, CreateView): """Create a new machine.""" model = Machine fields = ["name", "launderette", "type"] template_name = "core/create.jinja" + permission_required = "launderette.add_machine" def get_initial(self): ret = super().get_initial() diff --git a/pedagogy/tests/tests.py b/pedagogy/tests/tests.py index cc36f3c3..6e04b949 100644 --- a/pedagogy/tests/tests.py +++ b/pedagogy/tests/tests.py @@ -26,6 +26,7 @@ from django.conf import settings from django.test import Client, TestCase from django.urls import reverse from django.utils.translation import gettext_lazy as _ +from pytest_django.asserts import assertRedirects from core.models import Notification, User from pedagogy.models import UV, UVComment, UVCommentReport @@ -106,7 +107,7 @@ class TestUVCreation(TestCase): def test_create_uv_unauthorized_fail(self): # Test with anonymous user response = self.client.post(self.create_uv_url, create_uv_template(0)) - assert response.status_code == 403 + assertRedirects(response, reverse("core:login") + f"?next={self.create_uv_url}") # Test with subscribed user self.client.force_login(self.sli) @@ -815,11 +816,11 @@ class TestUVCommentReportCreate(TestCase): self.create_report_test("guy", success=False) def test_create_report_anonymous_fail(self): + url = reverse("pedagogy:comment_report", kwargs={"comment_id": self.comment.id}) response = self.client.post( - reverse("pedagogy:comment_report", kwargs={"comment_id": self.comment.id}), - {"comment": self.comment.id, "reporter": 0, "reason": "C'est moche"}, + url, {"comment": self.comment.id, "reporter": 0, "reason": "C'est moche"} ) - assert response.status_code == 403 + assertRedirects(response, reverse("core:login") + f"?next={url}") assert not UVCommentReport.objects.all().exists() def test_notifications(self): diff --git a/pedagogy/views.py b/pedagogy/views.py index 770dc2a4..88e9c186 100644 --- a/pedagogy/views.py +++ b/pedagogy/views.py @@ -22,7 +22,7 @@ # from django.conf import settings -from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin from django.core.exceptions import PermissionDenied from django.db.models import Exists, OuterRef from django.shortcuts import get_object_or_404 @@ -35,12 +35,7 @@ from django.views.generic import ( UpdateView, ) -from core.auth.mixins import ( - CanCreateMixin, - CanEditPropMixin, - CanViewMixin, - FormerSubscriberMixin, -) +from core.auth.mixins import CanEditPropMixin, CanViewMixin, FormerSubscriberMixin from core.models import Notification, User from core.views import DetailFormView from pedagogy.forms import ( @@ -136,12 +131,13 @@ class UVGuideView(LoginRequiredMixin, FormerSubscriberMixin, TemplateView): } -class UVCommentReportCreateView(CanCreateMixin, CreateView): +class UVCommentReportCreateView(PermissionRequiredMixin, CreateView): """Create a new report for an inapropriate comment.""" model = UVCommentReport form_class = UVCommentReportForm template_name = "core/edit.jinja" + permission_required = "pedagogy.add_uvcommentreport" def dispatch(self, request, *args, **kwargs): self.uv_comment = get_object_or_404(UVComment, pk=kwargs["comment_id"]) @@ -202,12 +198,13 @@ class UVModerationFormView(FormView): return reverse_lazy("pedagogy:moderation") -class UVCreateView(CanCreateMixin, CreateView): +class UVCreateView(PermissionRequiredMixin, CreateView): """Add a new UV (Privileged).""" model = UV form_class = UVForm template_name = "pedagogy/uv_edit.jinja" + permission_required = "pedagogy.add_uv" def get_form_kwargs(self): kwargs = super().get_form_kwargs() diff --git a/sith/settings.py b/sith/settings.py index 9929995e..d3acabec 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -292,8 +292,8 @@ STORAGES = { AUTH_USER_MODEL = "core.User" AUTH_ANONYMOUS_MODEL = "core.models.AnonymousUser" AUTHENTICATION_BACKENDS = ["core.auth.backends.SithModelBackend"] -LOGIN_URL = "/login" -LOGOUT_URL = "/logout" +LOGIN_URL = "/login/" +LOGOUT_URL = "/logout/" LOGIN_REDIRECT_URL = "/" DEFAULT_FROM_EMAIL = "bibou@git.an" SITH_COM_EMAIL = "bibou_com@git.an" From 9b5f08e13c8e07e56f0660ec7b5f3f5b6d791c75 Mon Sep 17 00:00:00 2001 From: imperosol Date: Mon, 13 Jan 2025 18:02:47 +0100 Subject: [PATCH 24/27] Improve permission documentation --- docs/tutorial/groups.md | 48 ++++- docs/tutorial/perms.md | 434 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 440 insertions(+), 42 deletions(-) diff --git a/docs/tutorial/groups.md b/docs/tutorial/groups.md index fbb58aab..9e310c75 100644 --- a/docs/tutorial/groups.md +++ b/docs/tutorial/groups.md @@ -157,7 +157,9 @@ il est automatiquement ajouté au groupe des membres du club. Lorsqu'il quitte le club, il est retiré du groupe. -## Les principaux groupes utilisés +## Les groupes utilisés + +### Groupes principaux Les groupes les plus notables gérables par les administrateurs du site sont : @@ -168,15 +170,45 @@ Les groupes les plus notables gérables par les administrateurs du site sont : - `SAS admin` : les administrateurs du SAS - `Forum admin` : les administrateurs du forum - `Pedagogy admin` : les administrateurs de la pédagogie (guide des UVs) -- `Banned from buying alcohol` : les utilisateurs interdits de vente d'alcool (non mineurs) -- `Banned from counters` : les utilisateurs interdits d'utilisation des comptoirs -- `Banned to subscribe` : les utilisateurs interdits de cotisation - En plus de ces groupes, on peut noter : -- `Public` : tous les utilisateurs du site -- `Subscribers` : tous les cotisants du site -- `Old subscribers` : tous les anciens cotisants +- `Public` : tous les utilisateurs du site. + Un utilisateur est automatiquement ajouté à ce group + lors de la création de son compte. +- `Subscribers` : tous les cotisants du site. + Les utilisateurs ne sont pas réellement ajoutés ce groupe ; + cependant, les utilisateurs cotisants sont implicitement + considérés comme membres du groupe lors de l'appel + à la méthode `User.has_perm`. +- `Old subscribers` : tous les anciens cotisants. + Un utilisateur est automatiquement ajouté à ce groupe + lors de sa première cotisation +### Groupes de club +Chaque club est associé à deux groupes : +le groupe des membres et le groupe du bureau. + +Lorsqu'un utilisateur rejoint un club, il est automatiquement +ajouté au groupe des membres. +S'il rejoint le club en tant que membre du bureau, +il est également ajouté au groupe du bureau. + +Lorsqu'un utilisateur quitte le club, il est automatiquement +retiré des groupes liés au club. +S'il quitte le bureau, mais reste dans le club, +il est retiré du groupe du bureau, mais reste dans le groupe des membres. + +### Groupes de ban + +Les groupes de ban sont une catégorie de groupes à part, +qui ne sont pas stockés dans la même table +et qui ne sont pas gérés sur la même interface +que les autres groupes. + +Les groupes de ban existants sont les suivants : + +- `Banned from buying alcohol` : les utilisateurs interdits de vente d'alcool (non mineurs) +- `Banned from counters` : les utilisateurs interdits d'utilisation des comptoirs +- `Banned to subscribe` : les utilisateurs interdits de cotisation diff --git a/docs/tutorial/perms.md b/docs/tutorial/perms.md index 8a84fda7..680c8ad3 100644 --- a/docs/tutorial/perms.md +++ b/docs/tutorial/perms.md @@ -1,15 +1,292 @@ -## Les permissions +## Objectifs du système de permissions -Le fonctionnement de l'AE ne permet pas d'utiliser le système de permissions -intégré à Django tel quel. Lors de la conception du Sith, ce qui paraissait le -plus simple à l'époque était de concevoir un système maison afin de se calquer -sur ce que faisait l'ancien site. +Les permissions attendues sur le site sont relativement spécifiques. +L'accès à une ressource peut se faire selon un certain nombre +de paramètres différents : -### Protéger un modèle +`L'état de la ressource` +: Certaines ressources + sont visibles par tous les cotisants (voire tous les utilisateurs), + à condition qu'elles aient passé une étape de modération. + La visibilité des ressources non-modérées nécessite des permissions + supplémentaires. -La gestion des permissions se fait directement par modèle. -Il existe trois niveaux de permission : +`L'appartenance à un groupe` +: Les groupes Root, Admin Com, Admin SAS, etc. + sont associés à des jeux de permissions. + Par exemple, les membres du groupe Admin SAS ont tous les droits sur + les ressources liées au SAS : ils peuvent voir, + créer, éditer, supprimer et éventuellement modérer + des images, des albums, des identifications de personnes... + Il en va de même avec les admins Com pour la communication, + les admins pédagogie pour le guide des UEs et ainsi de suite. + Quant aux membres du groupe Root, ils ont tous les droits + sur toutes les ressources du site. + +`Le statut de la cotisation` +: Les non-cotisants n'ont presque aucun + droit sur les ressources du site (ils peuvent seulement en voir une poignée), + les anciens cotisants peuvent voir un grand nombre de ressources + et les cotisants actuels ont la plupart des droits qui ne sont + pas liés à un club ou à l'administration du site. + +`L'appartenance à un club` +: Être dans un club donne le droit + de voir la plupart des ressources liées au club dans lequel ils + sont ; être dans le bureau du club donne en outre des droits + d'édition et de création sur ces ressources. + +`Être l'auteur ou le possesseur d'une ressource` +: Certaines ressources, comme les nouvelles, + enregistrent l'utilisateur qui les a créées ; + ce dernier a les droits de voir, de modifier et éventuellement + de supprimer ses ressources, quand bien même + elles ne seraient pas visibles pour les utilisateurs normaux + (par exemple, parce qu'elles ne sont pas encore modérées.) + + +Le système de permissions inclus par défaut dans django +permet de modéliser aisément l'accès à des ressources au niveau +de la table. +Ainsi, il n'est pas compliqué de gérer les permissions liées +aux groupes d'administration. + +Cependant, une surcouche est nécessaire dès lors que l'on veut +gérer les droits liés à une ligne en particulier +d'une table de la base de données. + +Nous essayons le plus possible de nous tenir aux fonctionnalités +de django, sans pour autant hésiter à nous rabattre sur notre +propre surcouche dès lors que les permissions attendues +deviennent trop spécifiques pour être gérées avec juste django. + +!!!info "Un peu d'histoire" + + Les permissions du site n'ont pas toujours été gérées + avec un mélange de fonctionnalités de django et de notre + propre code. + Pendant très longtemps, seule la surcouche était utilisée, + ce qui menait souvent à des vérifications de droits + inefficaces et à une gestion complexe de certaines + parties qui auraient pu être manipulées beaucoup plus simplement. + + En plus de ça, les permissions liées à la plupart + des groupes se faisait de manière hardcodée : + plutôt que d'associer un groupe à un jeu de permission + et de faire une jointure en db sur les groupes de l'utilisateur + ayant cette permissions, + on conservait la clef primaire du groupe dans la config + et on vérifiait en dur dans le code que l'utilisateur + était un des groupes voulus. + + Ce système possédait le triple désavantage de prendre énormément + de temps, d'être extrêmement limité (de fait, si tout est hardcodé, + on est obligé d'avoir le moins de groupes possibles pour que ça reste + gérable) et d'être désespérément dangereux (par exemple : fin novembre 2024, + une erreur dans le code a donné les accès à la création des cotisations + à tout le monde ; mi-octobre 2019, le calcul des permissions des etickets + pouvait faire tomber le site, cf. + [ce topic du forum](https://ae.utbm.fr/forum/topic/17943/?page=1msg2277272)) + +## Accès à toutes les ressources d'une table + +Gérer ce genre d'accès (par exemple : voir toutes les nouvelles +ou pouvoir supprimer n'importe quelle photo) +est exactement le problème que le système de permissions de django résout. +Nous utilisons donc ce système dans ce genre de situations. + +!!!note + + Nous décrivons ci-dessous l'usage que nous faisons du système + de permissions de django, + mais la seule source d'information complète et pleinement fiable + sur le fonctionnement réel de ce système est + [la documentation de django](https://docs.djangoproject.com/fr/stable/topics/auth/default/). + +### Permissions d'un modèle + +Par défaut, django crée quatre permissions pour chaque table de la base de données : + +- `add_` : créer un objet dans cette table +- `view_` : voir le contenu de la table +- `change_` : éditer des objets de la table +- `delete_` : supprimer des objets de la table + +Ces permissions sont créées au même moment que le modèle. +Si la table existe en base de données, ces permissions existent aussi. + +Il est également possible de rajouter nos propres permissions, +directement dans les options Meta du modèle. +Par exemple, prenons le modèle suivant : + +```python +from django.db import models + +class News(models.Model): + # ... + + class Meta: + permissions = [ + ("moderate_news", "Can moderate news"), + ("view_unmoderated_news", "Can view non-moderated news"), + ] +``` + +Ce dernier aura les permissions : `view_news`, `add_news`, `change_news`, +`delete_news`, `moderate_news` et `view_unmoderated_news`. + +### Utilisation des permissions d'un modèle + +Pour vérifier qu'un utilisateur a une permission, +on utilise les fonctions suivantes : + +- `User.has_perm(perm)` : retourne `True` si l'utilisateur + a la permission voulue, sinon `False` +- `User.has_perms([perm_a, perm_b, perm_c])` : retourne `True` si l'utilisateur + a toutes les permissions voulues, sinon `False`. + +Ces fonctions attendent un string suivant le format : +`.`. +Par exemple, la permission pour vérifier qu'un utilisateur +peut modérer une nouvelle sera : `com.moderate_news`. + +Ces fonctions sont utilisables aussi bien dans les templates Jinja +que dans le code Python : + +=== "Jinja" + + ```jinja + {% if user.has_perm("com.moderate_news") %} +
+ +
+ {% endif %} + ``` + +=== "Python" + + ```python + from com.models import News + from core.models import User + + + user = User.objects.get(username="bibou") + news = News.objects.get(id=387) + if user.has_perm("com.moderate_news"): + news.is_moderated = True + news.save() + else: + raise PermissionDenied + ``` + +Pour utiliser ce système de permissions dans une class-based view +(c'est-à-dire la plus grande partie de nos vues), +Django met à disposition `PermissionRequiredMixin`, +qui restreint l'accès à la vue aux utilisateurs ayant +la ou les permissions requises. +Pour les vues sous forme de fonction, il y a le décorateur +`permission_required`. + +=== "Class-Based View" + + ```python + from com.models import News + + from django.contrib.auth.mixins import PermissionRequiredMixin + from django.shortcuts import redirect + from django.urls import reverse + from django.views import View + from django.views.generic.detail import SingleObjectMixin + + class NewsModerateView(PermissionRequiredMixin, SingleObjectMixin, View): + model = News + pk_url_kwarg = "news_id" + permission_required = "com.moderate_news" + # On peut aussi fournir plusieurs permissions, par exemple : + # permission_required = ["com.moderate_news", "com.delete_news"] + + def post(self, request, *args, **kwargs): + # Si nous sommes ici, nous pouvons être certains que l'utilisateur + # a la permission requise + obj = self.get_object() + obj.is_moderated = True + obj.save() + return redirect(reverse("com:news_list")) + ``` + +=== "Function-based view" + + ```python + from com.models import News + + from django.contrib.auth.decorators import permission_required + from django.shortcuts import get_object_or_404, redirect + from django.urls import reverse + from django.views.decorators.http import require_POST + + @permission_required("com.moderate_news") + @require_POST + def moderate_news(request, news_id: int): + # Si nous sommes ici, nous pouvons être certains que l'utilisateur + # a la permission requise + news = get_object_or_404(News, id=news_id) + news.is_moderated = True + news.save() + return redirect(reverse("com:news_list")) + ``` + +## Accès à des éléments en particulier + +### Accès à l'auteur de la ressource + +Dans ce genre de cas, on peut identifier trois acteurs possibles : + +- les administrateurs peuvent accéder à toutes les ressources, + y compris non-modérées +- l'auteur d'une ressource non-modérée peut y accéder +- Les autres utilisateurs ne peuvent pas voir les ressources + non-modérées dont ils ne sont pas l'auteur + +Dans ce genre de cas, on souhaite donc accorder l'accès aux +utilisateurs qui ont la permission globale, selon le système +décrit plus haut, ou bien à l'auteur de la ressource. + +Pour cela, nous avons le mixin `PermissionOrAuthorRequired`. +Ce dernier va effectuer les mêmes vérifications que `PermissionRequiredMixin` +puis, si l'utilisateur n'a pas la permission requise, vérifier +s'il est l'auteur de la ressource. + +```python +from com.models import News +from core.auth.mixins import PermissionOrAuthorRequiredMixin + +from django.views.generic import UpdateView + +class NewsUpdateView(PermissionOrAuthorRequiredMixin, UpdateView): + model = News + pk_url_kwarg = "news_id" + permission_required = "com.change_news" + author_field = "author" # (1)! +``` + +1. Nom du champ du modèle utilisé comme clef étrangère vers l'auteur. + Par exemple, ici, la permission sera accordée si + l'utilisateur connecté correspond à l'utilisateur + désigné par `News.author`. + +### Accès en fonction de règles plus complexes + +Tout ce que nous avons décrit précédemment permet de couvrir +la plupart des cas simples. +Cependant, il arrivera souvent que les permissions attendues soient +plus complexes. +Dans ce genre de cas, on rentre entièrement dans notre surcouche. + +#### Implémentation dans les modèles + +La gestion de ce type de permissions se fait directement par modèle. +Il en existe trois niveaux : - Éditer des propriétés de l'objet - Éditer certaines valeurs l'objet @@ -47,28 +324,43 @@ Voici un exemple d'implémentation de ce système : from core.models import User, Group - # Utilisation de la protection par fonctions class Article(models.Model): title = models.CharField(_("title"), max_length=100) content = models.TextField(_("content")) - # Donne ou non les droits d'édition des propriétés de l'objet - # Un utilisateur dans le bureau AE aura tous les droits sur cet objet - def is_owned_by(self, user): + def is_owned_by(self, user): # (1)! return user.is_board_member - # Donne ou non les droits d'édition de l'objet - # L'objet ne sera modifiable que par un utilisateur cotisant - def can_be_edited_by(self, user): + def can_be_edited_by(self, user): # (2)! return user.is_subscribed - # Donne ou non les droits de vue de l'objet - # Ici, l'objet n'est visible que par un utilisateur connecté - def can_be_viewed_by(self, user): + def can_be_viewed_by(self, user): # (3)! return not user.is_anonymous ``` + 1. Donne ou non les droits d'édition des propriétés de l'objet. + Ici, un utilisateur dans le bureau AE aura tous les droits sur cet objet + 2. Donne ou non les droits d'édition de l'objet + Ici, l'objet ne sera modifiable que par un utilisateur cotisant + 3. Donne ou non les droits de vue de l'objet + Ici, l'objet n'est visible que par un utilisateur connecté + + !!!note + + Dans cet exemple, nous utilisons des permissions très simples + pour que vous puissiez constater le squelette de ce système, + plutôt que la logique de validation dans ce cas particulier. + + En réalité, il serait ici beaucoup plus approprié de + donner les permissions `com.delete_article` et + `com.change_article_properties` (en créant ce dernier + s'il n'existe pas encore) au groupe du bureau AE, + de donner également la permission `com.change_article` + au groupe `Cotisants` et enfin de restreindre l'accès + aux vues d'accès aux articles avec `LoginRequiredMixin`. + + === "Avec les groupes de permission" ```python @@ -83,15 +375,12 @@ Voici un exemple d'implémentation de ce système : content = models.TextField(_("content")) # relation one-to-many - # Groupe possédant l'objet - # Donne les droits d'édition des propriétés de l'objet - owner_group = models.ForeignKey( + owner_group = models.ForeignKey( # (1)! Group, related_name="owned_articles", default=settings.SITH_GROUP_ROOT_ID ) # relation many-to-many - # Tous les groupes qui seront ajouté dans ce champ auront les droits d'édition de l'objet - edit_groups = models.ManyToManyField( + edit_groups = models.ManyToManyField( # (2)! Group, related_name="editable_articles", verbose_name=_("edit groups"), @@ -99,8 +388,7 @@ Voici un exemple d'implémentation de ce système : ) # relation many-to-many - # Tous les groupes qui seront ajouté dans ce champ auront les droits de vue de l'objet - view_groups = models.ManyToManyField( + view_groups = models.ManyToManyField( # (3)! Group, related_name="viewable_articles", verbose_name=_("view groups"), @@ -108,9 +396,16 @@ Voici un exemple d'implémentation de ce système : ) ``` -### Appliquer les permissions + 1. Groupe possédant l'objet + Donne les droits d'édition des propriétés de l'objet. + Il ne peut y avoir qu'un seul groupe `owner` par objet. + 2. Tous les groupes ayant droit d'édition sur l'objet. + Il peut y avoir autant de groupes d'édition que l'on veut par objet. + 3. Tous les groupes ayant droit de voir l'objet. + Il peut y avoir autant de groupes de vue que l'on veut par objet. + -#### Dans un template +#### Application dans les templates Il existe trois fonctions de base sur lesquelles reposent les vérifications de permission. @@ -130,7 +425,7 @@ Voici un exemple d'utilisation dans un template : {% endif %} ``` -#### Dans une vue +#### Application dans les vues Généralement, les vérifications de droits dans les templates se limitent aux urls à afficher puisqu'il @@ -138,7 +433,7 @@ ne faut normalement pas mettre de logique autre que d'affichage à l'intérieur (en réalité, c'est un principe qu'on a beaucoup violé, mais promis on le fera plus). C'est donc habituellement au niveau des vues que cela a lieu. -Notre système s'appuie sur un système de mixin +Pour cela, nous avons rajouté des mixins à hériter lors de la création d'une vue basée sur une classe. Ces mixins ne sont compatibles qu'avec les classes récupérant un objet ou une liste d'objet. @@ -152,22 +447,23 @@ l'utilisateur recevra une liste vide d'objet. Voici un exemple d'utilisation en reprenant l'objet Article crée précédemment : ```python -from django.views.generic import CreateView, ListView +from django.views.generic import CreateView, DetailView from core.auth.mixins import CanViewMixin, CanCreateMixin from com.models import WeekmailArticle + # Il est important de mettre le mixin avant la classe héritée de Django # L'héritage multiple se fait de droite à gauche et les mixins ont besoin # d'une classe de base pour fonctionner correctement. -class ArticlesListView(CanViewMixin, ListView): - model = WeekmailArticle +class ArticlesDetailView(CanViewMixin, DetailView): + model = WeekmailArticle + - # Même chose pour une vue de création de l'objet Article class ArticlesCreateView(CanCreateMixin, CreateView): - model = WeekmailArticle + model = WeekmailArticle ``` Les mixins suivants sont implémentés : @@ -221,6 +517,76 @@ Les mixins suivants sont implémentés : Mais sur les `ListView`, on peut arriver à des temps de réponse extrêmement élevés. +### Filtrage des querysets + +Récupérer tous les objets d'un queryset et vérifier pour chacun que +l'utilisateur a le droit de les voir peut-être excessivement +coûteux en ressources +(cf. l'encart ci-dessus). + +Lorsqu'il est nécessaire de récupérer un certain nombre +d'objets depuis la base de données, il est donc préférable +de filtrer directement depuis le queryset. + +Pour cela, certains modèles, tels que [Picture][sas.models.Picture] +peuvent être filtrés avec la méthode de queryset `viewable_by`. +Cette dernière s'utilise comme n'importe quelle autre méthode +de queryset : + +```python +from sas.models import Picture +from core.models import User + +user = User.objects.get(username="bibou") +pictures = Picture.objects.viewable_by(user) +``` + +Le résultat de la requête contiendra uniquement des éléments +que l'utilisateur sélectionné a effectivement le droit de voir. + +Si vous désirez utiliser cette méthode sur un modèle +qui ne la possède pas, il est relativement facile de l'écrire : + +```python +from typing import Self + +from django.db import models + +from core.models import User + + +class NewsQuerySet(models.QuerySet): # (1)! + def viewable_by(self, user: User) -> Self: + if user.has_perm("com.view_unmoderated_news"): + # si l'utilisateur peut tout voir, on retourne tout + return self + # sinon, on retourne les nouvelles modérées ou dont l'utilisateur + # est l'auteur + return self.filter( + models.Q(is_moderated=True) + | models.Q(author=user) + ) + + +class News(models.Model): + is_moderated = models.BooleanField(default=False) + author = models.ForeignKey(User, on_delete=models.PROTECT) + # ... + + objects = NewsQuerySet.as_manager() # (2)! + + class Meta: + permissions = [("view_unmoderated_news", "Can view non moderated news")] +``` + +1. On crée un `QuerySet` maison, dans lequel on définit la méthode `viewable_by` +2. Puis, on attache ce `QuerySet` à notre modèle + +!!!note + + Pour plus d'informations sur la création de `QuerySet` personnalisés, voir + [la documentation de django](https://docs.djangoproject.com/fr/stable/topics/db/managers/) + ## API L'API utilise son propre système de permissions. From 9272f53beaca5e37a1901c6b3c4c9d7f8cc25ba4 Mon Sep 17 00:00:00 2001 From: imperosol Date: Tue, 14 Jan 2025 17:14:59 +0100 Subject: [PATCH 25/27] fix doc display --- core/auth/api_permissions.py | 4 ++- core/auth/mixins.py | 11 +++---- docs/reference/core/api_permissions.md | 1 - docs/reference/core/auth.md | 32 ++++++++++++++++++++ docs/tutorial/perms.md | 41 +++++++++++++------------- mkdocs.yml | 2 +- 6 files changed, 63 insertions(+), 28 deletions(-) delete mode 100644 docs/reference/core/api_permissions.md create mode 100644 docs/reference/core/auth.md diff --git a/core/auth/api_permissions.py b/core/auth/api_permissions.py index f4da67af..4d83143e 100644 --- a/core/auth/api_permissions.py +++ b/core/auth/api_permissions.py @@ -3,7 +3,8 @@ Some permissions are global (like `IsInGroup` or `IsRoot`), and some others are per-object (like `CanView` or `CanEdit`). -Examples: +Example: + ```python # restrict all the routes of this controller # to subscribed users @api_controller("/foo", permissions=[IsSubscriber]) @@ -33,6 +34,7 @@ Examples: ] def bar_delete(self, bar_id: int): # ... + ``` """ from typing import Any diff --git a/core/auth/mixins.py b/core/auth/mixins.py index c25ecb57..974e9bd1 100644 --- a/core/auth/mixins.py +++ b/core/auth/mixins.py @@ -21,6 +21,7 @@ # Place - Suite 330, Boston, MA 02111-1307, USA. # # +from __future__ import annotations import types import warnings @@ -30,11 +31,11 @@ from django.contrib.auth.mixins import AccessMixin, PermissionRequiredMixin from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.views.generic.base import View -from core.models import User - if TYPE_CHECKING: from django.db.models import Model + from core.models import User + def can_edit_prop(obj: Any, user: User) -> bool: """Can the user edit the properties of the object. @@ -46,7 +47,7 @@ def can_edit_prop(obj: Any, user: User) -> bool: Returns: True if user is authorized to edit object properties else False - Examples: + Example: ```python if not can_edit_prop(self.object ,request.user): raise PermissionDenied @@ -65,7 +66,7 @@ def can_edit(obj: Any, user: User) -> bool: Returns: True if user is authorized to edit object else False - Examples: + Example: ```python if not can_edit(self.object, request.user): raise PermissionDenied @@ -86,7 +87,7 @@ def can_view(obj: Any, user: User) -> bool: Returns: True if user is authorized to see object else False - Examples: + Example: ```python if not can_view(self.object ,request.user): raise PermissionDenied diff --git a/docs/reference/core/api_permissions.md b/docs/reference/core/api_permissions.md deleted file mode 100644 index 4ab3a2e0..00000000 --- a/docs/reference/core/api_permissions.md +++ /dev/null @@ -1 +0,0 @@ -::: core.auth.api_permissions \ No newline at end of file diff --git a/docs/reference/core/auth.md b/docs/reference/core/auth.md new file mode 100644 index 00000000..ade23f49 --- /dev/null +++ b/docs/reference/core/auth.md @@ -0,0 +1,32 @@ +## Backend + +::: core.auth.backends + handler: python + options: + heading_level: 3 + members: + - SithModelBackend + +## Mixins + +::: core.auth.mixins + handler: python + options: + heading_level: 3 + members: + - can_edit_prop + - can_edit + - can_view + - CanCreateMixin + - CanEditMixin + - CanViewMixin + - FormerSubscriberMixin + - PermissionOrAuthorRequiredMixin + + +## API Permissions + +::: core.auth.api_permissions + handler: python + options: + heading_level: 3 \ No newline at end of file diff --git a/docs/tutorial/perms.md b/docs/tutorial/perms.md index 680c8ad3..c23ca25f 100644 --- a/docs/tutorial/perms.md +++ b/docs/tutorial/perms.md @@ -412,9 +412,9 @@ reposent les vérifications de permission. Elles sont disponibles dans le contexte par défaut du moteur de template et peuvent être utilisées à tout moment. -- [can_edit_prop(obj, user)][core.views.can_edit_prop] : équivalent de `obj.is_owned_by(user)` -- [can_edit(obj, user)][core.views.can_edit] : équivalent de `obj.can_be_edited_by(user)` -- [can_view(obj, user)][core.views.can_view] : équivalent de `obj.can_be_viewed_by(user)` +- [can_edit_prop(obj, user)][core.auth.mixins.can_edit_prop] : équivalent de `obj.is_owned_by(user)` +- [can_edit(obj, user)][core.auth.mixins.can_edit] : équivalent de `obj.can_be_edited_by(user)` +- [can_view(obj, user)][core.auth.mixins.can_view] : équivalent de `obj.can_be_viewed_by(user)` Voici un exemple d'utilisation dans un template : @@ -483,23 +483,24 @@ Les mixins suivants sont implémentés : de création et crée l'objet sans le persister en base de données, puis vérifie les droits sur cet objet non-persisté. Le danger de ce système vient de multiples raisons : - - Les vérifications se faisant sur un objet non persisté, - l'utilisation de mécanismes nécessitant une persistance préalable - peut mener à des comportements indésirés, voire à des erreurs. - - Les développeurs de django ayant tendance à restreindre progressivement - les actions qui peuvent être faites sur des objets non-persistés, - les mises-à-jour de django deviennent plus compliquées. - - La vérification des droits ne se fait que dans les requêtes POST, - à la toute fin de la requête. - Tout ce qui arrive avant n'est absolument pas protégé. - Toute opération (même les suppressions et les créations) qui ont - lieu avant la persistance de l'objet seront appliquées, - même sans permission. - - Si un développeur du site fait l'erreur de surcharger - la méthode `form_valid` (ce qui est plutôt courant, - lorsqu'on veut accomplir certaines actions - quand un formulaire est valide), on peut se retrouver - dans une situation où l'objet est persisté sans aucune protection. + + - Les vérifications se faisant sur un objet non persisté, + l'utilisation de mécanismes nécessitant une persistance préalable + peut mener à des comportements indésirés, voire à des erreurs. + - Les développeurs de django ayant tendance à restreindre progressivement + les actions qui peuvent être faites sur des objets non-persistés, + les mises-à-jour de django deviennent plus compliquées. + - La vérification des droits ne se fait que dans les requêtes POST, + à la toute fin de la requête. + Tout ce qui arrive avant n'est absolument pas protégé. + Toute opération (même les suppressions et les créations) qui ont + lieu avant la persistance de l'objet seront appliquées, + même sans permission. + - Si un développeur du site fait l'erreur de surcharger + la méthode `form_valid` (ce qui est plutôt courant, + lorsqu'on veut accomplir certaines actions + quand un formulaire est valide), on peut se retrouver + dans une situation où l'objet est persisté sans aucune protection. !!!danger "Performance" diff --git a/mkdocs.yml b/mkdocs.yml index 70075794..f307cb8a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -98,7 +98,7 @@ nav: - Champs de modèle: reference/core/model_fields.md - reference/core/views.md - reference/core/schemas.md - - reference/core/api_permissions.md + - reference/core/auth.md - counter: - reference/counter/models.md - reference/counter/views.md From 71b096f9ef3de8c34aefe9e798d90f7a496fa10e Mon Sep 17 00:00:00 2001 From: imperosol Date: Tue, 14 Jan 2025 17:17:31 +0100 Subject: [PATCH 26/27] Apply review comment --- com/views.py | 6 ++---- docs/tutorial/groups.md | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/com/views.py b/com/views.py index 7d29dd62..a6faf214 100644 --- a/com/views.py +++ b/com/views.py @@ -174,11 +174,9 @@ class NewsUpdateView(PermissionOrAuthorRequiredMixin, UpdateView): permission_required = "com.edit_news" def form_valid(self, form): - self.object = form.save() + response = super().form_valid(form) # Does the saving part IcsCalendar.make_internal() - # Don't call `super().form_valid()`, - # because it would trigger a second call to `form.save()` - return HttpResponseRedirect(self.get_success_url()) + return response def get_date_form_kwargs(self) -> dict[str, Any]: """Get initial data for NewsDateForm""" diff --git a/docs/tutorial/groups.md b/docs/tutorial/groups.md index 9e310c75..bccd713f 100644 --- a/docs/tutorial/groups.md +++ b/docs/tutorial/groups.md @@ -185,6 +185,22 @@ En plus de ces groupes, on peut noter : Un utilisateur est automatiquement ajouté à ce groupe lors de sa première cotisation +!!!note "Utilisation du groupe Public" + + Le groupe Public est un groupe particulier. + Tout le monde faisant partie de ce groupe + (même les utilisateurs non-connectés en sont implicitement + considérés comme membres), + il ne doit pas être utilisé pour résoudre les + permissions d'une vue. + + En revanche, il est utile pour attribuer une ressource + à tout le monde. + Par exemple, un produit avec le groupe de vente Public + est considéré comme achetable par tous utilisateurs. + S'il n'avait eu aucun group de vente, il n'aurait + été accessible à personne. + ### Groupes de club Chaque club est associé à deux groupes : From 6f9f1ac1e7d10990023cf85ba8c91a2003459e5a Mon Sep 17 00:00:00 2001 From: Sli Date: Tue, 14 Jan 2025 17:17:41 +0100 Subject: [PATCH 27/27] Upgrade js dependencies * biomejs * hey-api * vite * threejs * other minor upgrades --- .pre-commit-config.yaml | 2 +- package-lock.json | 3230 ++++++++++++++++++++------------------- package.json | 10 +- 3 files changed, 1638 insertions(+), 1604 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e480eda0..506d9ebe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: rev: "v0.1.0" # Use the sha / tag you want to point at hooks: - id: biome-check - additional_dependencies: ["@biomejs/biome@1.9.3"] + additional_dependencies: ["@biomejs/biome@1.9.4"] - repo: https://github.com/rtts/djhtml rev: 3.0.7 hooks: diff --git a/package-lock.json b/package-lock.json index 948d13c4..012e48e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@fullcalendar/daygrid": "^6.1.15", "@fullcalendar/icalendar": "^6.1.15", "@fullcalendar/list": "^6.1.15", - "@hey-api/client-fetch": "^0.4.0", + "@hey-api/client-fetch": "^0.6.0", "@sentry/browser": "^8.34.0", "@zip.js/zip.js": "^2.7.52", "3d-force-graph": "^1.73.4", @@ -32,27 +32,27 @@ "jquery": "^3.7.1", "jquery-ui": "^1.14.0", "native-file-system-adapter": "^3.0.1", - "three": "^0.169.0", + "three": "^0.172.0", "three-spritetext": "^1.9.0", "tom-select": "^2.3.1" }, "devDependencies": { "@babel/core": "^7.25.2", "@babel/preset-env": "^7.25.4", - "@biomejs/biome": "1.9.3", - "@hey-api/openapi-ts": "^0.53.8", + "@biomejs/biome": "1.9.4", + "@hey-api/openapi-ts": "^0.61.3", "@rollup/plugin-inject": "^5.0.5", "@types/alpinejs": "^3.13.10", "@types/jquery": "^3.5.31", - "vite": "^5.4.11", + "vite": "^6.0.7", "vite-bundle-visualizer": "^1.2.1", "vite-plugin-static-copy": "^2.1.0" } }, "node_modules/@alpinejs/sort": { - "version": "3.14.7", - "resolved": "https://registry.npmjs.org/@alpinejs/sort/-/sort-3.14.7.tgz", - "integrity": "sha512-EJzxTBSoKvOxKHAUFeTSgxJR4rJQQPm10b4dB38kGcsxjUtOeNkbBF3xV4nlc0ZyTv7DarTWdppdoR/iP8jfdQ==", + "version": "3.14.8", + "resolved": "https://registry.npmjs.org/@alpinejs/sort/-/sort-3.14.8.tgz", + "integrity": "sha512-lmghR+eURvfGEaDqwr4EJJDBz5xHAgmxc522b13ZhOAmlfNblN9DXAcMW7qfI6WSfMGptkTm2lZx/dbCf636pg==", "license": "MIT" }, "node_modules/@ampproject/remapping": { @@ -60,6 +60,7 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -68,23 +69,6 @@ "node": ">=6.0.0" } }, - "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz", - "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==", - "dev": true, - "dependencies": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.15", - "js-yaml": "^4.1.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/philsturgeon" - } - }, "node_modules/@arendjr/text-clipper": { "name": "@jsr/arendjr__text-clipper", "version": "3.0.0", @@ -92,12 +76,14 @@ "integrity": "sha512-Uu3CYSvFrNdDkYKEaEKHAk0decaxVFlSSqf50Okte/9vJjO2rESzPF1ngQjS9H1aX45RIXRGMYOXJ/LPDFwUdQ==" }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -105,30 +91,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", - "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz", + "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", - "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -143,64 +131,46 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", + "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.25.6", + "@babel/parser": "^7.26.5", + "@babel/types": "^7.26.5", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", - "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -208,36 +178,19 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", - "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.4", + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", "semver": "^6.3.1" }, "engines": { @@ -247,23 +200,15 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", - "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "engines": { @@ -273,20 +218,12 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -299,41 +236,43 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", - "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.8" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -343,35 +282,38 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", - "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-wrap-function": "^7.25.0", - "@babel/traverse": "^7.25.0" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -381,14 +323,15 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", - "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/traverse": "^7.25.0" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -397,170 +340,87 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", - "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", - "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz", + "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.25.6" + "@babel/types": "^7.26.5" }, "bin": { "parser": "bin/babel-parser.js" @@ -570,13 +430,14 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", - "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/traverse": "^7.25.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -586,12 +447,13 @@ } }, "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", - "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -601,12 +463,13 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", - "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -616,14 +479,15 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -633,13 +497,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", - "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/traverse": "^7.25.0" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -653,6 +518,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" }, @@ -660,76 +526,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", - "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -739,138 +543,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", - "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -884,6 +563,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -896,12 +576,13 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -911,15 +592,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz", - "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-remap-async-to-generator": "^7.25.0", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/traverse": "^7.25.4" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -929,14 +610,15 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", - "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -946,12 +628,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", + "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -961,12 +644,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", - "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -976,13 +660,14 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", - "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.4", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -992,14 +677,14 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1009,16 +694,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", - "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/traverse": "^7.25.4", + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", "globals": "^11.1.0" }, "engines": { @@ -1029,13 +715,14 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1045,12 +732,13 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", - "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1060,13 +748,14 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1076,12 +765,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1091,13 +781,14 @@ } }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", - "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1107,13 +798,13 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1123,13 +814,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1139,13 +830,13 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1155,13 +846,14 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1171,14 +863,15 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.25.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", - "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/traverse": "^7.25.1" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1188,13 +881,13 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1204,12 +897,13 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", - "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1219,13 +913,13 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1235,12 +929,13 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1250,13 +945,14 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1266,14 +962,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", - "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.8", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-simple-access": "^7.24.7" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1283,15 +979,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", - "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.0" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1301,13 +998,14 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1317,13 +1015,14 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1333,12 +1032,13 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1348,13 +1048,13 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "version": "7.26.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", + "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1364,13 +1064,13 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1380,15 +1080,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1398,13 +1098,14 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1414,13 +1115,13 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1430,14 +1131,14 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", - "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1447,12 +1148,13 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1462,13 +1164,14 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", - "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.4", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1478,15 +1181,15 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1496,12 +1199,13 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1511,12 +1215,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1526,13 +1231,31 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1542,12 +1265,13 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1557,13 +1281,14 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1573,12 +1298,13 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1588,12 +1314,13 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1603,12 +1330,13 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", - "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1618,12 +1346,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1633,13 +1362,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1649,13 +1379,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1665,13 +1396,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", - "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.2", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1681,93 +1413,80 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz", - "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.4", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-validator-option": "^7.24.8", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.7", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.25.4", - "@babel/plugin-transform-async-to-generator": "^7.24.7", - "@babel/plugin-transform-block-scoped-functions": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.25.0", - "@babel/plugin-transform-class-properties": "^7.25.4", - "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.25.4", - "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.8", - "@babel/plugin-transform-dotall-regex": "^7.24.7", - "@babel/plugin-transform-duplicate-keys": "^7.24.7", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", - "@babel/plugin-transform-dynamic-import": "^7.24.7", - "@babel/plugin-transform-exponentiation-operator": "^7.24.7", - "@babel/plugin-transform-export-namespace-from": "^7.24.7", - "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.25.1", - "@babel/plugin-transform-json-strings": "^7.24.7", - "@babel/plugin-transform-literals": "^7.25.2", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", - "@babel/plugin-transform-member-expression-literals": "^7.24.7", - "@babel/plugin-transform-modules-amd": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.8", - "@babel/plugin-transform-modules-systemjs": "^7.25.0", - "@babel/plugin-transform-modules-umd": "^7.24.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", - "@babel/plugin-transform-new-target": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-numeric-separator": "^7.24.7", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-object-super": "^7.24.7", - "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.8", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.25.4", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-property-literals": "^7.24.7", - "@babel/plugin-transform-regenerator": "^7.24.7", - "@babel/plugin-transform-reserved-words": "^7.24.7", - "@babel/plugin-transform-shorthand-properties": "^7.24.7", - "@babel/plugin-transform-spread": "^7.24.7", - "@babel/plugin-transform-sticky-regex": "^7.24.7", - "@babel/plugin-transform-template-literals": "^7.24.7", - "@babel/plugin-transform-typeof-symbol": "^7.24.8", - "@babel/plugin-transform-unicode-escapes": "^7.24.7", - "@babel/plugin-transform-unicode-property-regex": "^7.24.7", - "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/plugin-transform-unicode-sets-regex": "^7.25.4", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.37.1", + "core-js-compat": "^3.38.1", "semver": "^6.3.1" }, "engines": { @@ -1777,20 +1496,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -1800,16 +1511,11 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1818,30 +1524,32 @@ } }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.5.tgz", + "integrity": "sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.5", + "@babel/parser": "^7.26.5", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.5", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1850,25 +1558,26 @@ } }, "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz", + "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@biomejs/biome": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.3.tgz", - "integrity": "sha512-POjAPz0APAmX33WOQFGQrwLvlu7WLV4CFJMlB12b6ZSg+2q6fYu9kZwLCOA+x83zXfcPd1RpuWOKJW0GbBwLIQ==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", + "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", "dev": true, "hasInstallScript": true, + "license": "MIT OR Apache-2.0", "bin": { "biome": "bin/biome" }, @@ -1880,24 +1589,25 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "1.9.3", - "@biomejs/cli-darwin-x64": "1.9.3", - "@biomejs/cli-linux-arm64": "1.9.3", - "@biomejs/cli-linux-arm64-musl": "1.9.3", - "@biomejs/cli-linux-x64": "1.9.3", - "@biomejs/cli-linux-x64-musl": "1.9.3", - "@biomejs/cli-win32-arm64": "1.9.3", - "@biomejs/cli-win32-x64": "1.9.3" + "@biomejs/cli-darwin-arm64": "1.9.4", + "@biomejs/cli-darwin-x64": "1.9.4", + "@biomejs/cli-linux-arm64": "1.9.4", + "@biomejs/cli-linux-arm64-musl": "1.9.4", + "@biomejs/cli-linux-x64": "1.9.4", + "@biomejs/cli-linux-x64-musl": "1.9.4", + "@biomejs/cli-win32-arm64": "1.9.4", + "@biomejs/cli-win32-x64": "1.9.4" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.3.tgz", - "integrity": "sha512-QZzD2XrjJDUyIZK+aR2i5DDxCJfdwiYbUKu9GzkCUJpL78uSelAHAPy7m0GuPMVtF/Uo+OKv97W3P9nuWZangQ==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", + "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT OR Apache-2.0", "optional": true, "os": [ "darwin" @@ -1907,13 +1617,14 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.3.tgz", - "integrity": "sha512-vSCoIBJE0BN3SWDFuAY/tRavpUtNoqiceJ5PrU3xDfsLcm/U6N93JSM0M9OAiC/X7mPPfejtr6Yc9vSgWlEgVw==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", + "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT OR Apache-2.0", "optional": true, "os": [ "darwin" @@ -1923,13 +1634,14 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.3.tgz", - "integrity": "sha512-vJkAimD2+sVviNTbaWOGqEBy31cW0ZB52KtpVIbkuma7PlfII3tsLhFa+cwbRAcRBkobBBhqZ06hXoZAN8NODQ==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", + "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT OR Apache-2.0", "optional": true, "os": [ "linux" @@ -1939,13 +1651,14 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.3.tgz", - "integrity": "sha512-VBzyhaqqqwP3bAkkBrhVq50i3Uj9+RWuj+pYmXrMDgjS5+SKYGE56BwNw4l8hR3SmYbLSbEo15GcV043CDSk+Q==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", + "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT OR Apache-2.0", "optional": true, "os": [ "linux" @@ -1955,13 +1668,14 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.3.tgz", - "integrity": "sha512-x220V4c+romd26Mu1ptU+EudMXVS4xmzKxPVb9mgnfYlN4Yx9vD5NZraSx/onJnd3Gh/y8iPUdU5CDZJKg9COA==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", + "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT OR Apache-2.0", "optional": true, "os": [ "linux" @@ -1971,13 +1685,14 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.3.tgz", - "integrity": "sha512-TJmnOG2+NOGM72mlczEsNki9UT+XAsMFAOo8J0me/N47EJ/vkLXxf481evfHLlxMejTY6IN8SdRSiPVLv6AHlA==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", + "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT OR Apache-2.0", "optional": true, "os": [ "linux" @@ -1987,13 +1702,14 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.3.tgz", - "integrity": "sha512-lg/yZis2HdQGsycUvHWSzo9kOvnGgvtrYRgoCEwPBwwAL8/6crOp3+f47tPwI/LI1dZrhSji7PNsGKGHbwyAhw==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", + "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT OR Apache-2.0", "optional": true, "os": [ "win32" @@ -2003,13 +1719,14 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.3.tgz", - "integrity": "sha512-cQMy2zanBkVLpmmxXdK6YePzmZx0s5Z7KEnwmrW54rcXK3myCNbQa09SwGZ8i/8sLw0H9F3X7K4rxVNGU8/D4Q==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", + "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT OR Apache-2.0", "optional": true, "os": [ "win32" @@ -2019,377 +1736,435 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", "cpu": [ - "x64" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@fortawesome/fontawesome-free": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.6.0.tgz", - "integrity": "sha512-60G28ke/sXdtS9KZCpZSHHkCbdsOGEhIUGlwq6yhY74UpTiToIh8np7A8yphhM4BWsvNFtIvLpi4co+h9Mr9Ow==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz", + "integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==", + "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", "engines": { "node": ">=6" } @@ -2398,6 +2173,7 @@ "version": "6.1.15", "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.15.tgz", "integrity": "sha512-BuX7o6ALpLb84cMw1FCB9/cSgF4JbVO894cjJZ6kP74jzbUZNjtwffwRdA+Id8rrLjT30d/7TrkW90k4zbXB5Q==", + "license": "MIT", "dependencies": { "preact": "~10.12.1" } @@ -2406,6 +2182,7 @@ "version": "6.1.15", "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.15.tgz", "integrity": "sha512-j8tL0HhfiVsdtOCLfzK2J0RtSkiad3BYYemwQKq512cx6btz6ZZ2RNc/hVnIxluuWFyvx5sXZwoeTJsFSFTEFA==", + "license": "MIT", "peerDependencies": { "@fullcalendar/core": "~6.1.15" } @@ -2414,6 +2191,7 @@ "version": "6.1.15", "resolved": "https://registry.npmjs.org/@fullcalendar/icalendar/-/icalendar-6.1.15.tgz", "integrity": "sha512-iroDc02fjxWCEYE9Lg8x+4HCJTrt04ZgDddwm0LLaWUbtx24rEcnzJP34NUx0KOTLsBjel6U/33lXvU9qDCrhg==", + "license": "MIT", "peerDependencies": { "@fullcalendar/core": "~6.1.15", "ical.js": "^1.4.0" @@ -2423,49 +2201,68 @@ "version": "6.1.15", "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.15.tgz", "integrity": "sha512-U1bce04tYDwkFnuVImJSy2XalYIIQr6YusOWRPM/5ivHcJh67Gm8CIMSWpi3KdRSNKFkqBxLPkfZGBMaOcJYug==", + "license": "MIT", "peerDependencies": { "@fullcalendar/core": "~6.1.15" } }, "node_modules/@hey-api/client-fetch": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@hey-api/client-fetch/-/client-fetch-0.4.0.tgz", - "integrity": "sha512-T8T3yCl2+AiVVDP6tvfnU/rXOkEHddMTOYCZXUVbydj7URVErh5BelIa8UWBkFYZBP2/mi2nViScNhe9eBolPw==" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@hey-api/client-fetch/-/client-fetch-0.6.0.tgz", + "integrity": "sha512-FlhFsVeH8RxJe/nq8xUzxNbiOpe+GadxlD2pfvDyOyLdCTU4o/LRv46ZVWstaW7DgF4nxhI328chy3+AulwVXw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/hey-api" + } + }, + "node_modules/@hey-api/json-schema-ref-parser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@hey-api/json-schema-ref-parser/-/json-schema-ref-parser-1.0.1.tgz", + "integrity": "sha512-dBt0A7op9kf4BcK++x6HBYDmvCvnJUZEGe5QytghPFHnMXPyKwDKomwL/v5e9ERk6E0e1GzL/e/y6pWUso9zrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.15", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/hey-api" + } }, "node_modules/@hey-api/openapi-ts": { - "version": "0.53.8", - "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.53.8.tgz", - "integrity": "sha512-UbiaIq+JNgG00N/iWYk+LSivOBgWsfGxEHDleWEgQcQr3q7oZJTKL8oH87+KkFDDbUngm1g8lnKI/zLdu1aElQ==", + "version": "0.61.3", + "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.61.3.tgz", + "integrity": "sha512-Ls9MBRa5+vg7UHw6fIcfdgcCyZ9vKtRw63nWxwF9zjJIPlzVOZO6xKuzGmDc6o0Pb6XCdTz6lPV5hcV0R4b/ag==", "dev": true, + "license": "MIT", "dependencies": { - "@apidevtools/json-schema-ref-parser": "11.7.0", + "@hey-api/json-schema-ref-parser": "1.0.1", "c12": "2.0.1", - "commander": "12.1.0", + "commander": "13.0.0", "handlebars": "4.7.8" }, "bin": { "openapi-ts": "bin/index.cjs" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.20.5 || ^20.11.1 || >=22.11.0" + }, + "funding": { + "url": "https://github.com/sponsors/hey-api" }, "peerDependencies": { - "typescript": "^5.x" - } - }, - "node_modules/@hey-api/openapi-ts/node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "dev": true, - "engines": { - "node": ">=18" + "typescript": "^5.5.3" } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -2479,10 +2276,11 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2497,6 +2295,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -2506,33 +2305,24 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2542,18 +2332,21 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@kurkle/color": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", - "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2567,6 +2360,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -2576,6 +2370,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2585,32 +2380,26 @@ } }, "node_modules/@orchidjs/sifter": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@orchidjs/sifter/-/sifter-1.0.3.tgz", - "integrity": "sha512-zCZbwKegHytfsPm8Amcfh7v/4vHqTAaOu6xFswBYcn8nznBOuseu6COB2ON7ez0tFV0mKL0nRNnCiZZA+lU9/g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@orchidjs/sifter/-/sifter-1.1.0.tgz", + "integrity": "sha512-mYwHCfr736cIWWdhhSZvDbf90AKt2xyrJspKFC3qyIJG1LtrJeJunYEqCGG4Aq2ijENbc4WkOjszcvNaIAS/pQ==", + "license": "Apache-2.0", "dependencies": { - "@orchidjs/unicode-variants": "^1.0.4" + "@orchidjs/unicode-variants": "^1.1.2" } }, "node_modules/@orchidjs/unicode-variants": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@orchidjs/unicode-variants/-/unicode-variants-1.0.4.tgz", - "integrity": "sha512-NvVBRnZNE+dugiXERFsET1JlKZfM5lJDEpSMilKW4bToYJ7pxf0Zne78xyXB2ny2c2aHfJ6WLnz1AaTNHAmQeQ==" - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, - "engines": { - "node": ">=14" - } + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@orchidjs/unicode-variants/-/unicode-variants-1.1.2.tgz", + "integrity": "sha512-5DobW1CHgnBROOEpFlEXytED5OosEWESFvg/VYmH0143oXcijYTprRYJTs+55HzGM4IqxiLFSuqEzu9mPNwVsA==", + "license": "Apache-2.0" }, "node_modules/@rollup/plugin-inject": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "estree-walker": "^2.0.2", @@ -2629,10 +2418,11 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", - "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -2651,337 +2441,342 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.2.tgz", - "integrity": "sha512-Tj+j7Pyzd15wAdSJswvs5CJzJNV+qqSUcr/aCD+jpQSBtXvGnV0pnrjoc8zFTe9fcKCatkpFpOO7yAzpO998HA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", + "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.2.tgz", - "integrity": "sha512-xsPeJgh2ThBpUqlLgRfiVYBEf/P1nWlWvReG+aBWfNv3XEBpa6ZCmxSVnxJgLgkNz4IbxpLy64h2gCmAAQLneQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", + "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.2.tgz", - "integrity": "sha512-KnXU4m9MywuZFedL35Z3PuwiTSn/yqRIhrEA9j+7OSkji39NzVkgxuxTYg5F8ryGysq4iFADaU5osSizMXhU2A==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", + "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.2.tgz", - "integrity": "sha512-Hj77A3yTvUeCIx/Vi+4d4IbYhyTwtHj07lVzUgpUq9YpJSEiGJj4vXMKwzJ3w5zp5v3PFvpJNgc/J31smZey6g==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", + "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.2.tgz", - "integrity": "sha512-RjgKf5C3xbn8gxvCm5VgKZ4nn0pRAIe90J0/fdHUsgztd3+Zesb2lm2+r6uX4prV2eUByuxJNdt647/1KPRq5g==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", + "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.2.tgz", - "integrity": "sha512-duq21FoXwQtuws+V9H6UZ+eCBc7fxSpMK1GQINKn3fAyd9DFYKPJNcUhdIKOrMFjLEJgQskoMoiuizMt+dl20g==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", + "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.2.tgz", - "integrity": "sha512-6npqOKEPRZkLrMcvyC/32OzJ2srdPzCylJjiTJT2c0bwwSGm7nz2F9mNQ1WrAqCBZROcQn91Fno+khFhVijmFA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", + "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.2.tgz", - "integrity": "sha512-V9Xg6eXtgBtHq2jnuQwM/jr2mwe2EycnopO8cbOvpzFuySCGtKlPCI3Hj9xup/pJK5Q0388qfZZy2DqV2J8ftw==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", + "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.2.tgz", - "integrity": "sha512-uCFX9gtZJoQl2xDTpRdseYuNqyKkuMDtH6zSrBTA28yTfKyjN9hQ2B04N5ynR8ILCoSDOrG/Eg+J2TtJ1e/CSA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", + "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.2.tgz", - "integrity": "sha512-/PU9P+7Rkz8JFYDHIi+xzHabOu9qEWR07L5nWLIUsvserrxegZExKCi2jhMZRd0ATdboKylu/K5yAXbp7fYFvA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", + "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", + "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.2.tgz", - "integrity": "sha512-eCHmol/dT5odMYi/N0R0HC8V8QE40rEpkyje/ZAXJYNNoSfrObOvG/Mn+s1F/FJyB7co7UQZZf6FuWnN6a7f4g==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", + "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.2.tgz", - "integrity": "sha512-DEP3Njr9/ADDln3kNi76PXonLMSSMiCir0VHXxmGSHxCxDfQ70oWjHcJGfiBugzaqmYdTC7Y+8Int6qbnxPBIQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", + "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.2.tgz", - "integrity": "sha512-NHGo5i6IE/PtEPh5m0yw5OmPMpesFnzMIS/lzvN5vknnC1sXM5Z/id5VgcNPgpD+wHmIcuYYgW+Q53v+9s96lQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", + "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.2.tgz", - "integrity": "sha512-PaW2DY5Tan+IFvNJGHDmUrORadbe/Ceh8tQxi8cmdQVCCYsLoQo2cuaSj+AU+YRX8M4ivS2vJ9UGaxfuNN7gmg==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", + "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.2.tgz", - "integrity": "sha512-dOlWEMg2gI91Qx5I/HYqOD6iqlJspxLcS4Zlg3vjk1srE67z5T2Uz91yg/qA8sY0XcwQrFzWWiZhMNERylLrpQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", + "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.2.tgz", - "integrity": "sha512-euMIv/4x5Y2/ImlbGl88mwKNXDsvzbWUlT7DFky76z2keajCtcbAsN9LUdmk31hAoVmJJYSThgdA0EsPeTr1+w==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", + "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.2.tgz", - "integrity": "sha512-RsnE6LQkUHlkC10RKngtHNLxb7scFykEbEwOFDjr3CeCMG+Rr+cKqlkKc2/wJ1u4u990urRHCbjz31x84PBrSQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", + "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.2.tgz", - "integrity": "sha512-foJM5vv+z2KQmn7emYdDLyTbkoO5bkHZE1oth2tWbQNGW7mX32d46Hz6T0MqXdWS2vBZhaEtHqdy9WYwGfiliA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", + "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@sentry-internal/browser-utils": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.34.0.tgz", - "integrity": "sha512-4AcYOzPzD1tL5eSRQ/GpKv5enquZf4dMVUez99/Bh3va8qiJrNP55AcM7UzZ7WZLTqKygIYruJTU5Zu2SpEAPQ==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.48.0.tgz", + "integrity": "sha512-pLtu0Fa1Ou0v3M1OEO1MB1EONJVmXEGtoTwFRCO1RPQI2ulmkG6BikINClFG5IBpoYKZ33WkEXuM6U5xh+pdZg==", + "license": "MIT", "dependencies": { - "@sentry/core": "8.34.0", - "@sentry/types": "8.34.0", - "@sentry/utils": "8.34.0" + "@sentry/core": "8.48.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.34.0.tgz", - "integrity": "sha512-aYSM2KPUs0FLPxxbJCFSwCYG70VMzlT04xepD1Y/tTlPPOja/02tSv2tyOdZbv8Uw7xslZs3/8Lhj74oYcTBxw==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.48.0.tgz", + "integrity": "sha512-6PwcJNHVPg0EfZxmN+XxVOClfQpv7MBAweV8t9i5l7VFr8sM/7wPNSeU/cG7iK19Ug9ZEkBpzMOe3G4GXJ5bpw==", + "license": "MIT", "dependencies": { - "@sentry/core": "8.34.0", - "@sentry/types": "8.34.0", - "@sentry/utils": "8.34.0" + "@sentry/core": "8.48.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.34.0.tgz", - "integrity": "sha512-EoMh9NYljNewZK1quY23YILgtNdGgrkzJ9TPsj6jXUG0LZ0Q7N7eFWd0xOEDBvFxrmI3cSXF1i4d1sBb+eyKRw==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.48.0.tgz", + "integrity": "sha512-csILVupc5RkrsTrncuUTGmlB56FQSFjXPYWG8I8yBTGlXEJ+o8oTuF6+55R4vbw3EIzBveXWi4kEBbnQlXW/eg==", + "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "8.34.0", - "@sentry/core": "8.34.0", - "@sentry/types": "8.34.0", - "@sentry/utils": "8.34.0" + "@sentry-internal/browser-utils": "8.48.0", + "@sentry/core": "8.48.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.34.0.tgz", - "integrity": "sha512-x8KhZcCDpbKHqFOykYXiamX6x0LRxv6N1OJHoH+XCrMtiDBZr4Yo30d/MaS6rjmKGMtSRij30v+Uq+YWIgxUrg==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.48.0.tgz", + "integrity": "sha512-LdivLfBXXB9us1aAc6XaL7/L2Ob4vi3C/fEOXElehg3qHjX6q6pewiv5wBvVXGX1NfZTRvu+X11k6TZoxKsezw==", + "license": "MIT", "dependencies": { - "@sentry-internal/replay": "8.34.0", - "@sentry/core": "8.34.0", - "@sentry/types": "8.34.0", - "@sentry/utils": "8.34.0" + "@sentry-internal/replay": "8.48.0", + "@sentry/core": "8.48.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/browser": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.34.0.tgz", - "integrity": "sha512-3HHG2NXxzHq1lVmDy2uRjYjGNf9NsJsTPlOC70vbQdOb+S49EdH/XMPy+J3ruIoyv6Cu0LwvA6bMOM6rHZOgNQ==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.48.0.tgz", + "integrity": "sha512-fuuVULB5/1vI8NoIwXwR3xwhJJqk+y4RdSdajExGF7nnUDBpwUJyXsmYJnOkBO+oLeEs58xaCpotCKiPUNnE3g==", + "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "8.34.0", - "@sentry-internal/feedback": "8.34.0", - "@sentry-internal/replay": "8.34.0", - "@sentry-internal/replay-canvas": "8.34.0", - "@sentry/core": "8.34.0", - "@sentry/types": "8.34.0", - "@sentry/utils": "8.34.0" + "@sentry-internal/browser-utils": "8.48.0", + "@sentry-internal/feedback": "8.48.0", + "@sentry-internal/replay": "8.48.0", + "@sentry-internal/replay-canvas": "8.48.0", + "@sentry/core": "8.48.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/core": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.34.0.tgz", - "integrity": "sha512-adrXCTK/zsg5pJ67lgtZqdqHvyx6etMjQW3P82NgWdj83c8fb+zH+K79Z47pD4zQjX0ou2Ws5nwwi4wJbz4bfA==", - "dependencies": { - "@sentry/types": "8.34.0", - "@sentry/utils": "8.34.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry/types": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.34.0.tgz", - "integrity": "sha512-zLRc60CzohGCo6zNsNeQ9JF3SiEeRE4aDCP9fDDdIVCOKovS+mn1rtSip0qd0Vp2fidOu0+2yY0ALCz1A3PJSQ==", - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry/utils": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.34.0.tgz", - "integrity": "sha512-W1KoRlFUjprlh3t86DZPFxLfM6mzjRzshVfMY7vRlJFymBelJsnJ3A1lPeBZM9nCraOSiw6GtOWu6k5BAkiGIg==", - "dependencies": { - "@sentry/types": "8.34.0" - }, + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.48.0.tgz", + "integrity": "sha512-VGwYgTfLpvJ5LRO5A+qWo1gpo6SfqaGXL9TOzVgBucAdpzbrYHpZ87sEarDVq/4275uk1b0S293/mfsskFczyw==", + "license": "MIT", "engines": { "node": ">=14.18" } @@ -2989,18 +2784,21 @@ "node_modules/@tweenjs/tween.js": { "version": "25.0.0", "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-25.0.0.tgz", - "integrity": "sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==" + "integrity": "sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==", + "license": "MIT" }, "node_modules/@types/alpinejs": { - "version": "3.13.10", - "resolved": "https://registry.npmjs.org/@types/alpinejs/-/alpinejs-3.13.10.tgz", - "integrity": "sha512-ah53tF6mWuuwerpDE7EHwbZErNDJQlsLISPqJhYj2RZ9nuTYbRknSkqebUd3igkhLIZKkPa7IiXjSn9qsU9O2w==", - "dev": true + "version": "3.13.11", + "resolved": "https://registry.npmjs.org/@types/alpinejs/-/alpinejs-3.13.11.tgz", + "integrity": "sha512-3KhGkDixCPiLdL3Z/ok1GxHwLxEWqQOKJccgaQL01wc0EVM2tCTaqlC3NIedmxAXkVzt/V6VTM8qPgnOHKJ1MA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/codemirror": { "version": "5.60.15", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", "integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==", + "license": "MIT", "dependencies": { "@types/tern": "*" } @@ -3008,13 +2806,15 @@ "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" }, "node_modules/@types/jquery": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.31.tgz", - "integrity": "sha512-rf/iB+cPJ/YZfMwr+FVuQbm7IaWC4y3FVYfVDxRGqmUCFjjPII0HWaP0vTPJGp6m4o13AXySCcMbWfrWtBFAKw==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.32.tgz", + "integrity": "sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/sizzle": "*" } @@ -3023,34 +2823,27 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/marked": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.3.2.tgz", - "integrity": "sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==" - }, - "node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "undici-types": "~6.19.2" - } + "integrity": "sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==", + "license": "MIT" }, "node_modules/@types/sizzle": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", - "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", - "dev": true + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz", + "integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/tern": { "version": "0.23.9", "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", + "license": "MIT", "dependencies": { "@types/estree": "*" } @@ -3059,6 +2852,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==", + "license": "MIT", "dependencies": { "@vue/shared": "3.1.5" } @@ -3066,12 +2860,14 @@ "node_modules/@vue/shared": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz", - "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==" + "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==", + "license": "MIT" }, "node_modules/@zip.js/zip.js": { - "version": "2.7.52", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.52.tgz", - "integrity": "sha512-+5g7FQswvrCHwYKNMd/KFxZSObctLSsQOgqBSi0LzwHo3li9Eh1w5cF5ndjQw9Zbr3ajVnd2+XyiX85gAetx1Q==", + "version": "2.7.54", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.54.tgz", + "integrity": "sha512-qMrJVg2hoEsZJjMJez9yI2+nZlBUxgYzGV3mqcb2B/6T1ihXp0fWBDYlVHlHquuorgNUQP5a8qSmX6HF5rFJNg==", + "license": "BSD-3-Clause", "engines": { "bun": ">=0.7.0", "deno": ">=1.0.0", @@ -3079,15 +2875,16 @@ } }, "node_modules/3d-force-graph": { - "version": "1.73.4", - "resolved": "https://registry.npmjs.org/3d-force-graph/-/3d-force-graph-1.73.4.tgz", - "integrity": "sha512-eMHZ1LVzh9APLv+An0AXz2dVPwasJlqAnJ61ABlb1qaO6DYuqIUTTErh0DN/24nIWJu1jCim2WiVujzz7slnWQ==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/3d-force-graph/-/3d-force-graph-1.75.0.tgz", + "integrity": "sha512-jZzLLBjA2lywFgGfS4RAkqD9VGdTo3Hvf3pJiY2IGohrJtahJas1XYwhPAALga3LtoKfN2Nzjl6vVshz2RrXSA==", + "license": "MIT", "dependencies": { "accessor-fn": "1", - "kapsule": "1", + "kapsule": "^1.16", "three": ">=0.118 <1", "three-forcegraph": "1", - "three-render-objects": "^1.29" + "three-render-objects": "^1.34" }, "engines": { "node": ">=12" @@ -3097,6 +2894,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/accessor-fn/-/accessor-fn-1.5.1.tgz", "integrity": "sha512-zZpFYBqIL1Aqg+f2qmYHJ8+yIZF7/tP6PUGx2/QM0uGPSO5UegpinmkNwDohxWtOj586BpMPVRUjce2HI6xB3A==", + "license": "MIT", "engines": { "node": ">=12" } @@ -3106,6 +2904,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3114,9 +2913,9 @@ } }, "node_modules/alpinejs": { - "version": "3.14.7", - "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.14.7.tgz", - "integrity": "sha512-ScnbydNBcWVnCiVupD3wWUvoMPm8244xkvDNMxVCspgmap9m4QuJ7pjc+77UtByU+1+Ejg0wzYkP4mQaOMcvng==", + "version": "3.14.8", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.14.8.tgz", + "integrity": "sha512-wT2fuP2DXpGk/jKaglwy7S/IJpm1FD+b7U6zUrhwErjoq5h27S4dxkJEXVvhbdwyPv9U+3OkUuNLkZT4h2Kfrg==", "license": "MIT", "dependencies": { "@vue/reactivity": "~3.1.1" @@ -3126,6 +2925,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -3137,6 +2937,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -3149,6 +2950,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3162,6 +2964,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -3173,36 +2976,30 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", + "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.10.6", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.2", "core-js-compat": "^3.38.0" @@ -3212,12 +3009,13 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -3226,13 +3024,15 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -3244,6 +3044,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -3253,6 +3054,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -3261,9 +3063,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, "funding": [ { @@ -3279,10 +3081,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { @@ -3292,19 +3095,12 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/c12": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz", "integrity": "sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": "^4.0.1", "confbox": "^0.1.7", @@ -3333,14 +3129,15 @@ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001680", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", - "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", + "version": "1.0.30001692", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz", + "integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==", "dev": true, "funding": [ { @@ -3355,12 +3152,14 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chart.js": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", - "integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==", + "version": "4.4.7", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.7.tgz", + "integrity": "sha512-pwkcKfdzTMAU/+jNosKhNL2bHtJc/sSmYgVbuGTEDhzkrhmyihmP7vUc/5ZK9WopidMDHNe3Wm7jOd/WhuHWuw==", + "license": "MIT", "dependencies": { "@kurkle/color": "^0.3.0" }, @@ -3369,10 +3168,11 @@ } }, "node_modules/chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, + "license": "MIT", "dependencies": { "readdirp": "^4.0.1" }, @@ -3388,6 +3188,7 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -3397,6 +3198,7 @@ "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", "dev": true, + "license": "MIT", "dependencies": { "consola": "^3.2.3" } @@ -3406,6 +3208,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -3420,6 +3223,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3429,6 +3233,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -3443,13 +3248,15 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cliui/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -3464,6 +3271,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -3476,6 +3284,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -3491,12 +3300,14 @@ "node_modules/codemirror": { "version": "5.65.18", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.18.tgz", - "integrity": "sha512-Gaz4gHnkbHMGgahNt3CA5HBk5lLQBqmD/pBgeB4kQU6OedZmqMBjlRF0LSrp2tJ4wlLNPm2FfaUd1pDy0mdlpA==" + "integrity": "sha512-Gaz4gHnkbHMGgahNt3CA5HBk5lLQBqmD/pBgeB4kQU6OedZmqMBjlRF0LSrp2tJ4wlLNPm2FfaUd1pDy0mdlpA==", + "license": "MIT" }, "node_modules/codemirror-spell-checker": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/codemirror-spell-checker/-/codemirror-spell-checker-1.1.2.tgz", "integrity": "sha512-2Tl6n0v+GJRsC9K3MLCdLaMOmvWL0uukajNJseorZJsslaxZyZMgENocPU8R0DyoTAiKsyqiemSOZo7kjGV0LQ==", + "license": "MIT", "dependencies": { "typo-js": "*" } @@ -3505,6 +3316,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -3515,27 +3327,32 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.0.0.tgz", + "integrity": "sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==", "dev": true, - "optional": true, - "peer": true + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/confbox": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/consola": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", - "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.0.tgz", + "integrity": "sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==", "dev": true, + "license": "MIT", "engines": { "node": "^14.18.0 || >=16.10.0" } @@ -3544,15 +3361,17 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/core-js-compat": { - "version": "3.38.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", - "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz", + "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.23.3" + "browserslist": "^4.24.3" }, "funding": { "type": "opencollective", @@ -3563,6 +3382,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3573,9 +3393,10 @@ } }, "node_modules/cytoscape": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.2.tgz", - "integrity": "sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==", + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.31.0.tgz", + "integrity": "sha512-zDGn1K/tfZwEnoGOcHc0H4XazqAAXAuDpcYw9mUnUjATjqljyCNGJv8uEvbvxGaGHaVshxMecyl6oc6uKzRfbw==", + "license": "MIT", "engines": { "node": ">=0.10" } @@ -3584,6 +3405,7 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/cytoscape-cxtmenu/-/cytoscape-cxtmenu-3.5.0.tgz", "integrity": "sha512-CoqgKAxvQhmHO5fEgJdBqqR2VjwK1dNkxehc2i0MUMqY0araA13z3oP/9KkprHp9Td++KlVBz6JnncNAD76T0Q==", + "license": "MIT", "peerDependencies": { "cytoscape": "^3.2.0" } @@ -3592,6 +3414,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/cytoscape-klay/-/cytoscape-klay-3.1.4.tgz", "integrity": "sha512-VwPj0VR25GPfy6qXVQRi/MYlZM/zkdvRhHlgqbM//lSvstgM6fhp3ik/uM8Wr8nlhskfqz/M1fIDmR6UckbS2A==", + "license": "MIT", "dependencies": { "klayjs": "^0.4.1" }, @@ -3603,6 +3426,7 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", "dependencies": { "internmap": "1 - 2" }, @@ -3613,12 +3437,14 @@ "node_modules/d3-binarytree": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/d3-binarytree/-/d3-binarytree-1.0.2.tgz", - "integrity": "sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==" + "integrity": "sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==", + "license": "MIT" }, "node_modules/d3-color": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -3627,6 +3453,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", "engines": { "node": ">=12" } @@ -3635,6 +3462,7 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/d3-force-3d/-/d3-force-3d-3.0.5.tgz", "integrity": "sha512-tdwhAhoTYZY/a6eo9nR7HP3xSW/C6XvJTbeRpR92nlPzH6OiE+4MliN9feuSFd0tPtEUo+191qOhCTWx3NYifg==", + "license": "MIT", "dependencies": { "d3-binarytree": "1", "d3-dispatch": "1 - 3", @@ -3650,6 +3478,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -3658,6 +3487,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3" }, @@ -3666,14 +3496,16 @@ } }, "node_modules/d3-octree": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/d3-octree/-/d3-octree-1.0.2.tgz", - "integrity": "sha512-Qxg4oirJrNXauiuC94uKMbgxwnhdda9xRLl9ihq45srlJ4Ga3CSgqGcAL8iW7N5CIv4Oz8x3E734ulxyvHPvwA==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-octree/-/d3-octree-1.1.0.tgz", + "integrity": "sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A==", + "license": "MIT" }, "node_modules/d3-quadtree": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", "engines": { "node": ">=12" } @@ -3682,6 +3514,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", @@ -3697,6 +3530,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" @@ -3705,10 +3539,20 @@ "node": ">=12" } }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/d3-time": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", "dependencies": { "d3-array": "2 - 3" }, @@ -3720,6 +3564,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", "dependencies": { "d3-time": "1 - 3" }, @@ -3731,26 +3576,29 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", "engines": { "node": ">=12" } }, - "node_modules/data-joint": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/data-joint/-/data-joint-1.3.1.tgz", - "integrity": "sha512-tMK0m4OVGqiA3zkn8JmO6YAqD8UwJqIAx4AAwFl1SKTtKAqcXePuT+n2aayiX9uITtlN3DFtKKTOxJRUc2+HvQ==", + "node_modules/data-bind-mapper": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-bind-mapper/-/data-bind-mapper-1.0.1.tgz", + "integrity": "sha512-xWkgLj/mSDs/Y2flAMXwLKxnCh+rFScf4N8hSOtpsMxXYXui7CbtIUYP52VXQze9HhRND2Ua/AiEHZ8j/vtB0w==", + "license": "MIT", "dependencies": { - "index-array-by": "^1.4.0" + "accessor-fn": "1" }, "engines": { "node": ">=12" } }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -3768,6 +3616,7 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3776,19 +3625,22 @@ "version": "6.1.4", "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/destr": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.3.tgz", "integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -3799,12 +3651,14 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" }, "node_modules/easymde": { "version": "2.18.0", "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.18.0.tgz", "integrity": "sha512-IxVVUxNWIoXLeqtBU4BLc+eS/ScYhT1Dcb6yF5Wchoj1iXAV+TIIDWx+NCaZhY7RcSHqDPKllbYq7nwGKILnoA==", + "license": "MIT", "dependencies": { "@types/codemirror": "^5.60.4", "@types/marked": "^4.0.7", @@ -3814,52 +3668,57 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.62", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.62.tgz", - "integrity": "sha512-t8c+zLmJHa9dJy96yBZRXGQYoiCEnHYgFwn1asvSPZSUdVxnB62A4RASd7k41ytG3ErFBA0TpHlKg9D9SQBmLg==", - "dev": true + "version": "1.5.82", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.82.tgz", + "integrity": "sha512-Zq16uk1hfQhyGx5GpwPAYDwddJuSGhtRhgOA2mCxANYaDT79nAeGnaXogMGng4KqLaJUVnOnuL0+TDop9nLOiA==", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" } }, "node_modules/escalade": { @@ -3867,30 +3726,24 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -3900,6 +3753,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -3919,26 +3773,28 @@ } }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" } }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -3957,6 +3813,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "optional": true, "dependencies": { "node-domexception": "^1.0.0", @@ -3971,6 +3828,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3978,10 +3836,24 @@ "node": ">=8" } }, + "node_modules/float-tooltip": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/float-tooltip/-/float-tooltip-1.5.0.tgz", + "integrity": "sha512-CdpIbFdc7PSN+xhJXnAijWhha2vkdrrMRYpyfvrP3kKGJHJP404UrREVvMlKXQq2UXkb9G5oiyPTa5Kq6gRXjg==", + "license": "MIT", + "dependencies": { + "d3-selection": "2 - 3", + "kapsule": "^1.16" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/foreground-child": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -3998,6 +3870,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -4012,6 +3885,7 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -4024,6 +3898,7 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -4035,7 +3910,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", @@ -4043,6 +3919,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -4056,6 +3933,7 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4065,6 +3943,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -4074,6 +3953,7 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -4083,6 +3963,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -4095,6 +3976,7 @@ "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.3.tgz", "integrity": "sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==", "dev": true, + "license": "MIT", "dependencies": { "citty": "^0.1.6", "consola": "^3.2.3", @@ -4110,9 +3992,10 @@ } }, "node_modules/glob": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", - "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz", + "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==", + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^4.0.1", @@ -4136,6 +4019,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -4148,6 +4032,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -4156,13 +4041,15 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/handlebars": { "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", @@ -4184,6 +4071,7 @@ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -4192,15 +4080,17 @@ } }, "node_modules/htmx.org": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-2.0.3.tgz", - "integrity": "sha512-AeoJUAjkCVVajbfKX+3sVQBTCt8Ct4lif1T+z/tptTXo8+8yyq3QIMQQe/IT+R8ssfrO1I0DeX4CAronzCL6oA==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-2.0.4.tgz", + "integrity": "sha512-HLxMCdfXDOJirs3vBZl/ZLoY+c7PfM4Ahr2Ad4YXh6d22T5ltbTXFFkpx9Tgb2vvmWFMbIc3LqN2ToNkZJvyYQ==", + "license": "0BSD" }, "node_modules/human-signals": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=16.17.0" } @@ -4209,6 +4099,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/ical.js/-/ical.js-1.5.0.tgz", "integrity": "sha512-7ZxMkogUkkaCx810yp0ZGKvq1ZpRgJeornPttpoxe6nYZ3NLesZe1wWMXDdwTkj/b5NtXT+Y16Aakph/ao98ZQ==", + "license": "MPL-2.0", "peer": true }, "node_modules/import-from-esm": { @@ -4216,6 +4107,7 @@ "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz", "integrity": "sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4", "import-meta-resolve": "^4.0.0" @@ -4229,23 +4121,17 @@ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/index-array-by": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/index-array-by/-/index-array-by-1.4.2.tgz", - "integrity": "sha512-SP23P27OUKzXWEC/TOyWlwLviofQkCSCKONnc62eItjp69yCZZPqDQtr3Pw5gJDnPeUMqExmKydNZaJO0FU9pw==", - "engines": { - "node": ">=12" - } - }, "node_modules/internmap": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", "engines": { "node": ">=12" } @@ -4255,6 +4141,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -4263,10 +4150,11 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.2" }, @@ -4282,6 +4170,7 @@ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, + "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -4297,6 +4186,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4305,6 +4195,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -4314,6 +4205,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -4326,6 +4218,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -4335,6 +4228,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -4347,6 +4241,7 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, + "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -4357,12 +4252,14 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" }, "node_modules/jackspeak": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", - "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -4371,16 +4268,14 @@ }, "funding": { "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/jiti": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.3.3.tgz", - "integrity": "sha512-EX4oNDwcXSivPrw2qKH2LB5PoFxEvgtv2JgwW0bU858HoLQ+kutSvjLMUqBd0PeJYEinLWhoI9Ol0eYMqj/wNQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", "dev": true, + "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -4388,12 +4283,14 @@ "node_modules/jquery": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" }, "node_modules/jquery-ui": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.14.0.tgz", - "integrity": "sha512-mPfYKBoRCf0MzaT2cyW5i3IuZ7PfTITaasO5OFLAQxrHuI+ZxruPa+4/K1OMNT8oElLWGtIxc9aRbyw20BKr8g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.14.1.tgz", + "integrity": "sha512-DhzsYH8VeIvOaxwi+B/2BCsFFT5EGjShdzOcm5DssWjtcpGWIMsn66rJciDA6jBruzNiLf1q0KvwMoX1uGNvnQ==", + "license": "MIT", "dependencies": { "jquery": ">=1.12.0 <5.0.0" } @@ -4402,13 +4299,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -4417,15 +4316,16 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json5": { @@ -4433,6 +4333,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -4445,6 +4346,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -4453,9 +4355,10 @@ } }, "node_modules/kapsule": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/kapsule/-/kapsule-1.14.6.tgz", - "integrity": "sha512-wSi6tHNOfXrIK2Pvv6BhZ9ukzhbp+XZlOOPWSVGUbqfFsnnli4Eq8FN6TaWJv2e17sY5+fKYVxa4DP2oPGlKhg==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/kapsule/-/kapsule-1.16.0.tgz", + "integrity": "sha512-4f/z/Luu0cEXmagCwaFyzvfZai2HKgB4CQLwmsMUA+jlUbW94HfFSX+TWZxzWoMSO6b6aR+FD2Xd5z88VYZJTw==", + "license": "MIT", "dependencies": { "lodash-es": "4" }, @@ -4466,32 +4369,38 @@ "node_modules/klayjs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/klayjs/-/klayjs-0.4.1.tgz", - "integrity": "sha512-WUNxuO7O79TEkxCj6OIaK5TJBkaWaR/IKNTakgV9PwDn+mrr63MLHed34AcE2yTaDntgO6l0zGFIzhcoTeroTA==" + "integrity": "sha512-WUNxuO7O79TEkxCj6OIaK5TJBkaWaR/IKNTakgV9PwDn+mrr63MLHed34AcE2yTaDntgO6l0zGFIzhcoTeroTA==", + "license": "EPL-1.0" }, "node_modules/lodash-es": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lru-cache": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz", - "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==", - "engines": { - "node": "20 || >=22" + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" } }, "node_modules/magic-string": { - "version": "0.30.12", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", - "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } @@ -4500,6 +4409,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "license": "MIT", "bin": { "marked": "bin/marked.js" }, @@ -4511,13 +4421,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -4527,6 +4439,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -4540,6 +4453,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -4552,6 +4466,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4563,6 +4478,7 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4578,6 +4494,7 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4586,6 +4503,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -4595,6 +4513,7 @@ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, + "license": "MIT", "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -4608,6 +4527,7 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -4619,13 +4539,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, + "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -4634,22 +4556,31 @@ } }, "node_modules/mlly": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", - "integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", "dev": true, + "license": "MIT", "dependencies": { - "acorn": "^8.12.1", - "pathe": "^1.1.2", - "pkg-types": "^1.2.0", + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", "ufo": "^1.5.4" } }, + "node_modules/mlly/node_modules/pathe": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.1.tgz", + "integrity": "sha512-6jpjMpOth5S9ITVu5clZ7NOgHNsv5vRQdheL9ztp2vZmM6fRbLvyua1tiBIL4lk8SAe3ARzeXEly6siXCjDHDw==", + "dev": true, + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.8", @@ -4662,6 +4593,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -4683,6 +4615,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "engines": { "node": ">=14.8.0" }, @@ -4694,17 +4627,20 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ngraph.events": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.2.2.tgz", - "integrity": "sha512-JsUbEOzANskax+WSYiAPETemLWYXmixuPAlmZmhIbIj6FH/WDgEGCGnRwUQBK0GjOnVm8Ui+e5IJ+5VZ4e32eQ==" + "integrity": "sha512-JsUbEOzANskax+WSYiAPETemLWYXmixuPAlmZmhIbIj6FH/WDgEGCGnRwUQBK0GjOnVm8Ui+e5IJ+5VZ4e32eQ==", + "license": "BSD-3-Clause" }, "node_modules/ngraph.forcelayout": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/ngraph.forcelayout/-/ngraph.forcelayout-3.3.1.tgz", "integrity": "sha512-MKBuEh1wujyQHFTW57y5vd/uuEOK0XfXYxm3lC7kktjJLRdt/KEKEknyOlc6tjXflqBKEuYBBcu7Ax5VY+S6aw==", + "license": "BSD-3-Clause", "dependencies": { "ngraph.events": "^1.0.0", "ngraph.merge": "^1.0.0", @@ -4715,6 +4651,7 @@ "version": "20.0.1", "resolved": "https://registry.npmjs.org/ngraph.graph/-/ngraph.graph-20.0.1.tgz", "integrity": "sha512-VFsQ+EMkT+7lcJO1QP8Ik3w64WbHJl27Q53EO9hiFU9CRyxJ8HfcXtfWz/U8okuoYKDctbciL6pX3vG5dt1rYA==", + "license": "BSD-3-Clause", "dependencies": { "ngraph.events": "^1.2.1" } @@ -4722,12 +4659,14 @@ "node_modules/ngraph.merge": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/ngraph.merge/-/ngraph.merge-1.0.0.tgz", - "integrity": "sha512-5J8YjGITUJeapsomtTALYsw7rFveYkM+lBj3QiYZ79EymQcuri65Nw3knQtFxQBU1r5iOaVRXrSwMENUPK62Vg==" + "integrity": "sha512-5J8YjGITUJeapsomtTALYsw7rFveYkM+lBj3QiYZ79EymQcuri65Nw3knQtFxQBU1r5iOaVRXrSwMENUPK62Vg==", + "license": "MIT" }, "node_modules/ngraph.random": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ngraph.random/-/ngraph.random-1.1.0.tgz", - "integrity": "sha512-h25UdUN/g8U7y29TzQtRm/GvGr70lK37yQPvPKXXuVfs7gCm82WipYFZcksQfeKumtOemAzBIcT7lzzyK/edLw==" + "integrity": "sha512-h25UdUN/g8U7y29TzQtRm/GvGr70lK37yQPvPKXXuVfs7gCm82WipYFZcksQfeKumtOemAzBIcT7lzzyK/edLw==", + "license": "BSD-3-Clause" }, "node_modules/node-domexception": { "version": "1.0.0", @@ -4743,6 +4682,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "optional": true, "engines": { "node": ">=10.5.0" @@ -4752,19 +4692,22 @@ "version": "1.6.4", "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz", "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4774,6 +4717,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -4789,6 +4733,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4801,6 +4746,7 @@ "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.12.tgz", "integrity": "sha512-D3pzNDWIvgA+7IORhD/IuWzEk4uXv6GsgOxiid4UU3h9oq5IqV1KtPDi63n4sZJ/xcWlr88c0QM2RgN5VbOhFA==", "dev": true, + "license": "MIT", "dependencies": { "citty": "^0.1.6", "consola": "^3.2.3", @@ -4820,13 +4766,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz", "integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/onetime": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^4.0.0" }, @@ -4842,6 +4790,7 @@ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, + "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -4855,14 +4804,16 @@ } }, "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", "engines": { "node": ">=8" } @@ -4871,12 +4822,14 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-scurry": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" @@ -4888,29 +4841,42 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/perfect-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4919,20 +4885,29 @@ } }, "node_modules/pkg-types": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", - "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", "dev": true, + "license": "MIT", "dependencies": { "confbox": "^0.1.8", - "mlly": "^1.7.2", - "pathe": "^1.1.2" + "mlly": "^1.7.4", + "pathe": "^2.0.1" } }, + "node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.1.tgz", + "integrity": "sha512-6jpjMpOth5S9ITVu5clZ7NOgHNsv5vRQdheL9ztp2vZmM6fRbLvyua1tiBIL4lk8SAe3ARzeXEly6siXCjDHDw==", + "dev": true, + "license": "MIT" + }, "node_modules/polished": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.17.8" }, @@ -4941,9 +4916,9 @@ } }, "node_modules/postcss": { - "version": "8.4.49", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", - "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "dev": true, "funding": [ { @@ -4959,8 +4934,9 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", + "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -4972,6 +4948,7 @@ "version": "10.12.1", "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -4995,25 +4972,28 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/rc9": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", "dev": true, + "license": "MIT", "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", + "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 14.16.0" + "node": ">= 14.18.0" }, "funding": { "type": "individual", @@ -5024,13 +5004,15 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerate-unicode-properties": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dev": true, + "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, @@ -5041,27 +5023,30 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/regenerator-transform": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -5069,25 +5054,37 @@ "node": ">=4" } }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "jsesc": "~0.5.0" + "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" } }, "node_modules/require-directory": { @@ -5095,23 +5092,28 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5121,16 +5123,18 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rollup": { - "version": "4.27.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.2.tgz", - "integrity": "sha512-KreA+PzWmk2yaFmZVwe6GB2uBD86nXl86OsDkt1bJS9p3vqWuEQ6HnJJ+j/mZi/q0920P99/MVRlB4L3crpF5w==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", + "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "1.0.6" }, @@ -5142,35 +5146,37 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.27.2", - "@rollup/rollup-android-arm64": "4.27.2", - "@rollup/rollup-darwin-arm64": "4.27.2", - "@rollup/rollup-darwin-x64": "4.27.2", - "@rollup/rollup-freebsd-arm64": "4.27.2", - "@rollup/rollup-freebsd-x64": "4.27.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.27.2", - "@rollup/rollup-linux-arm-musleabihf": "4.27.2", - "@rollup/rollup-linux-arm64-gnu": "4.27.2", - "@rollup/rollup-linux-arm64-musl": "4.27.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.27.2", - "@rollup/rollup-linux-riscv64-gnu": "4.27.2", - "@rollup/rollup-linux-s390x-gnu": "4.27.2", - "@rollup/rollup-linux-x64-gnu": "4.27.2", - "@rollup/rollup-linux-x64-musl": "4.27.2", - "@rollup/rollup-win32-arm64-msvc": "4.27.2", - "@rollup/rollup-win32-ia32-msvc": "4.27.2", - "@rollup/rollup-win32-x64-msvc": "4.27.2", + "@rollup/rollup-android-arm-eabi": "4.30.1", + "@rollup/rollup-android-arm64": "4.30.1", + "@rollup/rollup-darwin-arm64": "4.30.1", + "@rollup/rollup-darwin-x64": "4.30.1", + "@rollup/rollup-freebsd-arm64": "4.30.1", + "@rollup/rollup-freebsd-x64": "4.30.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", + "@rollup/rollup-linux-arm-musleabihf": "4.30.1", + "@rollup/rollup-linux-arm64-gnu": "4.30.1", + "@rollup/rollup-linux-arm64-musl": "4.30.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", + "@rollup/rollup-linux-riscv64-gnu": "4.30.1", + "@rollup/rollup-linux-s390x-gnu": "4.30.1", + "@rollup/rollup-linux-x64-gnu": "4.30.1", + "@rollup/rollup-linux-x64-musl": "4.30.1", + "@rollup/rollup-win32-arm64-msvc": "4.30.1", + "@rollup/rollup-win32-ia32-msvc": "4.30.1", + "@rollup/rollup-win32-x64-msvc": "4.30.1", "fsevents": "~2.3.2" } }, "node_modules/rollup-plugin-visualizer": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.12.0.tgz", - "integrity": "sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.14.0.tgz", + "integrity": "sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==", "dev": true, + "license": "MIT", "dependencies": { "open": "^8.4.0", - "picomatch": "^2.3.1", + "picomatch": "^4.0.2", "source-map": "^0.7.4", "yargs": "^17.5.1" }, @@ -5178,34 +5184,27 @@ "rollup-plugin-visualizer": "dist/bin/cli.js" }, "engines": { - "node": ">=14" + "node": ">=18" }, "peerDependencies": { + "rolldown": "1.x", "rollup": "2.x || 3.x || 4.x" }, "peerDependenciesMeta": { + "rolldown": { + "optional": true + }, "rollup": { "optional": true } } }, - "node_modules/rollup-plugin-visualizer/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/rollup-plugin-visualizer/node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } @@ -5229,14 +5228,26 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5248,6 +5259,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", "engines": { "node": ">=8" } @@ -5256,6 +5268,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", "engines": { "node": ">=14" }, @@ -5268,6 +5281,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -5277,26 +5291,16 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -5314,6 +5318,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5327,6 +5332,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -5334,12 +5340,14 @@ "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5351,6 +5359,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -5366,6 +5375,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5377,6 +5387,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -5386,6 +5397,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5398,6 +5410,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5410,6 +5423,7 @@ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, + "license": "ISC", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -5427,6 +5441,7 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=8" } @@ -5435,45 +5450,28 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/terser": { - "version": "5.33.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.33.0.tgz", - "integrity": "sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g==", "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } + "license": "ISC" }, "node_modules/three": { - "version": "0.169.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.169.0.tgz", - "integrity": "sha512-Ed906MA3dR4TS5riErd4QBsRGPcx+HBDX2O5yYE5GqJeFQTPU+M56Va/f/Oph9X7uZo3W3o4l2ZhBZ6f6qUv0w==" + "version": "0.172.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.172.0.tgz", + "integrity": "sha512-6HMgMlzU97MsV7D/tY8Va38b83kz8YJX+BefKjspMNAv0Vx6dxMogHOrnRl/sbMIs3BPUKijPqDqJ/+UwJbIow==", + "license": "MIT" }, "node_modules/three-forcegraph": { - "version": "1.41.15", - "resolved": "https://registry.npmjs.org/three-forcegraph/-/three-forcegraph-1.41.15.tgz", - "integrity": "sha512-E1j6bKt7lWg9t/ERdEiuxYfPbAioTCd9RG2bgqyC0yM3rwkBqn5VZN3fvb7umaOuTB1Tqpq6m07iVfJSfzTnCQ==", + "version": "1.42.11", + "resolved": "https://registry.npmjs.org/three-forcegraph/-/three-forcegraph-1.42.11.tgz", + "integrity": "sha512-MXESG+qXXzsZDaY1N0M3fW1sfgJinm/DjNwO9oS9XXT1NRK9KoRijYDt5ilzI8M4OdJ3pA4YdaV3nDBw2HPVOw==", + "license": "MIT", "dependencies": { "accessor-fn": "1", "d3-array": "1 - 3", "d3-force-3d": "2 - 3", "d3-scale": "1 - 4", "d3-scale-chromatic": "1 - 3", - "data-joint": "1", - "kapsule": "1", + "data-bind-mapper": "1", + "kapsule": "^1.16", "ngraph.forcelayout": "3", "ngraph.graph": "20", "tinycolor2": "1" @@ -5486,26 +5484,29 @@ } }, "node_modules/three-render-objects": { - "version": "1.29.5", - "resolved": "https://registry.npmjs.org/three-render-objects/-/three-render-objects-1.29.5.tgz", - "integrity": "sha512-OLtETrjF184NuaaI/vpRlIP9FxVNAgBBCgWYXhGFUDnPdl/2iX8rialUPGA1gEXvOTiKyepArVgm1LUkJw15rQ==", + "version": "1.34.0", + "resolved": "https://registry.npmjs.org/three-render-objects/-/three-render-objects-1.34.0.tgz", + "integrity": "sha512-6/+Eq+zSdB/8MlBVhwbR75UJQQn439cZL8jf9qMVv6RLERXZ1CwzjVHdOb2hciQg2gWKHcy2qL7uyR6IOQwa/w==", + "license": "MIT", "dependencies": { "@tweenjs/tween.js": "18 - 25", "accessor-fn": "1", - "kapsule": "1", + "float-tooltip": "^1.5", + "kapsule": "^1.16", "polished": "4" }, "engines": { "node": ">=12" }, "peerDependencies": { - "three": "*" + "three": ">=0.168" } }, "node_modules/three-spritetext": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/three-spritetext/-/three-spritetext-1.9.0.tgz", - "integrity": "sha512-+dMrxBsxTu5OviykIg5jTMry5TQ8u5yuS9zKH0mWElyldoFGdegEkIm71kDk34bxBp/NQhRLW+iom1b/GMTioA==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/three-spritetext/-/three-spritetext-1.9.3.tgz", + "integrity": "sha512-p7iEQr7anABRUJNOH2logMf1aRuWb026IshUC4aJ8F+bbMTn5Z43/Jd7/W3VihE3ToCwrWMl6u6VwgFMTw0jvA==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -5516,31 +5517,25 @@ "node_modules/tinycolor2": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "license": "MIT" }, "node_modules/tmp": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.14" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -5549,12 +5544,13 @@ } }, "node_modules/tom-select": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tom-select/-/tom-select-2.3.1.tgz", - "integrity": "sha512-QS4vnOcB6StNGqX4sGboGXL2fkhBF2gIBB+8Hwv30FZXYPn0CyYO8kkdATRvwfCTThxiR4WcXwKJZ3cOmtI9eg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tom-select/-/tom-select-2.4.1.tgz", + "integrity": "sha512-adI8H8+wk8RRzHYLQ3bXSk2Q+FAq/kzAATrcWlJ2fbIrEzb0VkwaXzKHTAlBwSJrhqbPJvhV/0eypFkED/nAug==", + "license": "Apache-2.0", "dependencies": { - "@orchidjs/sifter": "^1.0.3", - "@orchidjs/unicode-variants": "^1.0.4" + "@orchidjs/sifter": "^1.1.0", + "@orchidjs/unicode-variants": "^1.1.2" }, "engines": { "node": "*" @@ -5565,10 +5561,11 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, + "license": "Apache-2.0", "peer": true, "bin": { "tsc": "bin/tsc", @@ -5579,21 +5576,24 @@ } }, "node_modules/typo-js": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.4.tgz", - "integrity": "sha512-Oy/k+tFle5NAA3J/yrrYGfvEnPVrDZ8s8/WCwjUE75k331QyKIsFss7byQ/PzBmXLY6h1moRnZbnaxWBe3I3CA==" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.5.tgz", + "integrity": "sha512-F45vFWdGX8xahIk/sOp79z2NJs8ETMYsmMChm9D5Hlx3+9j7VnCyQyvij5MOCrNY3NNe8noSyokRjQRfq+Bc7A==", + "license": "BSD-3-Clause" }, "node_modules/ufo": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/uglify-js": { "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "dev": true, + "license": "BSD-2-Clause", "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -5602,19 +5602,12 @@ "node": ">=0.8.0" } }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5624,6 +5617,7 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, + "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -5637,6 +5631,7 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5646,6 +5641,7 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5655,14 +5651,15 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } }, "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", "dev": true, "funding": [ { @@ -5678,9 +5675,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.2.0", - "picocolors": "^1.1.0" + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -5690,20 +5688,21 @@ } }, "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.7.tgz", + "integrity": "sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -5712,19 +5711,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.4.0" + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -5745,6 +5750,12 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, @@ -5753,6 +5764,7 @@ "resolved": "https://registry.npmjs.org/vite-bundle-visualizer/-/vite-bundle-visualizer-1.2.1.tgz", "integrity": "sha512-cwz/Pg6+95YbgIDp+RPwEToc4TKxfsFWSG/tsl2DSZd9YZicUag1tQXjJ5xcL7ydvEoaC2FOZeaXOU60t9BRXw==", "dev": true, + "license": "MIT", "dependencies": { "cac": "^6.7.14", "import-from-esm": "^1.3.3", @@ -5767,10 +5779,11 @@ } }, "node_modules/vite-plugin-static-copy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.1.0.tgz", - "integrity": "sha512-n8lEOIVM00Y/zronm0RG8RdPyFd0SAAFR0sii3NWmgG3PSCyYMsvUNRQTlb3onp1XeMrKIDwCrPGxthKvqX9OQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.2.0.tgz", + "integrity": "sha512-ytMrKdR9iWEYHbUxs6x53m+MRl4SJsOSoMu1U1+Pfg0DjPeMlsRVx3RR5jvoonineDquIue83Oq69JvNsFSU5w==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": "^3.5.3", "fast-glob": "^3.2.11", @@ -5781,7 +5794,7 @@ "node": "^18.0.0 || >=20.0.0" }, "peerDependencies": { - "vite": "^5.0.0" + "vite": "^5.0.0 || ^6.0.0" } }, "node_modules/vite-plugin-static-copy/node_modules/chokidar": { @@ -5789,6 +5802,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -5813,6 +5827,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -5825,6 +5840,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -5836,6 +5852,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", "optional": true, "engines": { "node": ">= 8" @@ -5845,6 +5862,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5859,12 +5877,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -5882,6 +5902,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -5898,6 +5919,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -5906,6 +5928,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -5919,12 +5942,14 @@ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5938,6 +5963,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5950,6 +5976,7 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -5958,13 +5985,15 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -5983,6 +6012,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -5992,6 +6022,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6000,13 +6031,15 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/yargs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -6021,6 +6054,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, diff --git a/package.json b/package.json index 4ae80269..93494819 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,12 @@ "devDependencies": { "@babel/core": "^7.25.2", "@babel/preset-env": "^7.25.4", - "@biomejs/biome": "1.9.3", - "@hey-api/openapi-ts": "^0.53.8", + "@biomejs/biome": "1.9.4", + "@hey-api/openapi-ts": "^0.61.3", "@rollup/plugin-inject": "^5.0.5", "@types/alpinejs": "^3.13.10", "@types/jquery": "^3.5.31", - "vite": "^5.4.11", + "vite": "^6.0.7", "vite-bundle-visualizer": "^1.2.1", "vite-plugin-static-copy": "^2.1.0" }, @@ -42,7 +42,7 @@ "@fullcalendar/daygrid": "^6.1.15", "@fullcalendar/icalendar": "^6.1.15", "@fullcalendar/list": "^6.1.15", - "@hey-api/client-fetch": "^0.4.0", + "@hey-api/client-fetch": "^0.6.0", "@sentry/browser": "^8.34.0", "@zip.js/zip.js": "^2.7.52", "3d-force-graph": "^1.73.4", @@ -58,7 +58,7 @@ "jquery": "^3.7.1", "jquery-ui": "^1.14.0", "native-file-system-adapter": "^3.0.1", - "three": "^0.169.0", + "three": "^0.172.0", "three-spritetext": "^1.9.0", "tom-select": "^2.3.1" }