Comparing changes

Choose two branches to see what's changed or to start a new pull request.

base: submissions
Choose a base ref
compare: trunk
Choose a head ref
Create pull request
Able to merge. These branches can be automatically merged.
27 commits 35 files changed 3 contributors

Commits on trunk

.eslintrc.jsondeleted
@@ -1,3 +0,0 @@
1
-{
2
-  "extends": ["next/core-web-vitals", "next/typescript"]
3
-}
.gitignoremodified
@@ -34,3 +34,5 @@ yarn-error.log*
3434
 # typescript
3535
 *.tsbuildinfo
3636
 next-env.d.ts
37
+
38
+CLAUDE.md
README.mdmodified
@@ -1,36 +1,1 @@
1
-This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
2
-
3
-## Getting Started
4
-
5
-First, run the development server:
6
-
7
-```bash
8
-npm run dev
9
-# or
10
-yarn dev
11
-# or
12
-pnpm dev
13
-# or
14
-bun dev
15
-```
16
-
17
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18
-
19
-You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20
-
21
-This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22
-
23
-## Learn More
24
-
25
-To learn more about Next.js, take a look at the following resources:
26
-
27
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29
-
30
-You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31
-
32
-## Deploy on Vercel
33
-
34
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35
-
36
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
1
+scratch 1760458369
app/apple-icon.svgadded
@@ -0,0 +1,13 @@
1
+<svg width="180" height="180" viewBox="0 0 180 180" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+  <!-- Background -->
3
+  <rect width="180" height="180" rx="40" fill="#AE122A"/>
4
+
5
+  <!-- Gold border -->
6
+  <rect x="10" y="10" width="160" height="160" rx="30" fill="none" stroke="#FFD619" stroke-width="4"/>
7
+
8
+  <!-- VMI Text -->
9
+  <text x="90" y="115" font-family="Arial, sans-serif" font-size="60" font-weight="bold" fill="#FFD619" text-anchor="middle">VMI</text>
10
+
11
+  <!-- Small subtitle -->
12
+  <text x="90" y="140" font-family="Arial, sans-serif" font-size="14" fill="#FFD619" text-anchor="middle" opacity="0.8">Memorial</text>
13
+</svg>
app/awards/[id]/page.tsxadded
@@ -0,0 +1,193 @@
1
+'use client';
2
+
3
+import { useState, useEffect } from 'react';
4
+import { useParams } from 'next/navigation';
5
+import Link from 'next/link';
6
+import Image from 'next/image';
7
+import Header from '@/components/Header';
8
+import DocumentIcon from '@/components/DocumentIcon';
9
+import { getAwardDetail, AwardDetail, AwardRecipient } from '@/lib/api';
10
+
11
+export default function AwardDetailPage() {
12
+  const params = useParams();
13
+  const awardId = Number(params.id);
14
+
15
+  const [award, setAward] = useState<AwardDetail | null>(null);
16
+  const [loading, setLoading] = useState(true);
17
+  const [error, setError] = useState<string | null>(null);
18
+
19
+  useEffect(() => {
20
+    async function fetchAward() {
21
+      try {
22
+        const data = await getAwardDetail(awardId);
23
+        setAward(data);
24
+      } catch (err) {
25
+        setError('Failed to load award details');
26
+        console.error(err);
27
+      } finally {
28
+        setLoading(false);
29
+      }
30
+    }
31
+    if (awardId) {
32
+      fetchAward();
33
+    }
34
+  }, [awardId]);
35
+
36
+  // Helper to get image path
37
+  const getImagePath = (filename: string) => {
38
+    const extensions = ['.jpg', '.png', '.jpeg', '.gif'];
39
+    for (const ext of extensions) {
40
+      if (filename.toLowerCase().endsWith(ext)) {
41
+        return `/${filename}`;
42
+      }
43
+    }
44
+    return `/${filename}.jpg`;
45
+  };
46
+
47
+  const breadcrumbs = [
48
+    { label: 'Home', href: '/' },
49
+    { label: 'Awards', href: '/awards' },
50
+    { label: award?.name || 'Loading...' }
51
+  ];
52
+
53
+  if (loading) {
54
+    return (
55
+      <div className="min-h-screen bg-vmi-cream">
56
+        <Header breadcrumbs={breadcrumbs} showAwards={false} />
57
+        <main className="max-w-6xl mx-auto px-4 py-12">
58
+          <p className="text-center text-gray-600">Loading award details...</p>
59
+        </main>
60
+      </div>
61
+    );
62
+  }
63
+
64
+  if (error || !award) {
65
+    return (
66
+      <div className="min-h-screen bg-vmi-cream">
67
+        <Header breadcrumbs={breadcrumbs} showAwards={false} />
68
+        <main className="max-w-6xl mx-auto px-4 py-12">
69
+          <p className="text-center text-red-600">{error || 'Award not found'}</p>
70
+          <div className="text-center mt-4">
71
+            <Link href="/awards" className="text-vmi-red hover:underline">
72
+              ← Back to Awards
73
+            </Link>
74
+          </div>
75
+        </main>
76
+      </div>
77
+    );
78
+  }
79
+
80
+  return (
81
+    <div className="min-h-screen bg-vmi-cream">
82
+      <Header breadcrumbs={breadcrumbs} showAwards={false} />
83
+
84
+      <main className="max-w-6xl mx-auto px-4 py-12">
85
+        {/* Award Header Section */}
86
+        <div className="bg-vmi-light-gold border-2 border-vmi-gold rounded-lg p-8 mb-8 shadow-xl">
87
+          <div className="flex flex-col md:flex-row items-center gap-8">
88
+            {/* Award Image */}
89
+            <div className="relative w-32 h-44 flex-shrink-0">
90
+              <Image
91
+                src={getImagePath(award.image_filename)}
92
+                alt={award.name}
93
+                fill
94
+                className="object-contain"
95
+                sizes="128px"
96
+                priority
97
+              />
98
+            </div>
99
+
100
+            {/* Award Info */}
101
+            <div className="text-center md:text-left">
102
+              <h1 className="text-3xl md:text-4xl font-black mb-4 text-vmi-red">
103
+                {award.name}
104
+              </h1>
105
+              <p className="text-gray-700 text-lg mb-4">
106
+                {award.short_description}
107
+              </p>
108
+              <p className="text-vmi-red font-bold text-xl">
109
+                {award.recipient_count} VMI {award.recipient_count === 1 ? 'Recipient' : 'Recipients'}
110
+                {award.total_awards_given > award.recipient_count && (
111
+                  <span className="text-gray-600 font-normal text-base ml-2">
112
+                    ({award.total_awards_given} total awards)
113
+                  </span>
114
+                )}
115
+              </p>
116
+            </div>
117
+          </div>
118
+        </div>
119
+
120
+        {/* Long Description Section */}
121
+        <div className="bg-white border-2 border-gray-300 rounded-lg p-8 mb-8 shadow-xl">
122
+          <h2 className="text-2xl font-bold mb-4 text-vmi-red">About This Award</h2>
123
+          <div className="prose max-w-none text-gray-700 whitespace-pre-line">
124
+            {award.long_description}
125
+          </div>
126
+        </div>
127
+
128
+        {/* Recipients Section */}
129
+        <div className="bg-white border-2 border-gray-300 rounded-lg p-8 shadow-xl">
130
+          <h2 className="text-2xl font-bold mb-6 text-vmi-red">
131
+            VMI Alumni Recipients
132
+          </h2>
133
+
134
+          {award.recipients.length === 0 ? (
135
+            <p className="text-center text-gray-600">
136
+              No VMI recipients have been added yet.
137
+            </p>
138
+          ) : (
139
+            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
140
+              {award.recipients.map((recipient: AwardRecipient) => (
141
+                <Link
142
+                  key={`${recipient.person_id}-${recipient.count}`}
143
+                  href={`/memorial/person/${recipient.person_id}`}
144
+                  className="block p-4 rounded-lg border-2 border-gray-200 hover:border-vmi-gold hover:bg-vmi-light-gold transition-all duration-200 group"
145
+                >
146
+                  <div className="flex items-start justify-between">
147
+                    <div className="flex-1">
148
+                      <h3 className="font-bold text-gray-800 group-hover:text-vmi-red transition-colors">
149
+                        {recipient.display_name}
150
+                        {recipient.count > 1 && (
151
+                          <span className="ml-2 text-sm text-vmi-gold font-normal">
152
+                            (×{recipient.count})
153
+                          </span>
154
+                        )}
155
+                      </h3>
156
+                      {recipient.class_year && (
157
+                        <p className="text-sm text-gray-600">
158
+                          Class of {recipient.class_year}
159
+                          {recipient.class_letter && ` (${recipient.class_letter})`}
160
+                        </p>
161
+                      )}
162
+                      <p className="text-sm text-gray-500">{recipient.conflict_name}</p>
163
+                      {recipient.date_awarded && (
164
+                        <p className="text-xs text-gray-400 mt-1">
165
+                          Awarded: {new Date(recipient.date_awarded).toLocaleDateString()}
166
+                        </p>
167
+                      )}
168
+                    </div>
169
+                    {recipient.pdf_key && (
170
+                      <DocumentIcon className="ml-2 flex-shrink-0" />
171
+                    )}
172
+                  </div>
173
+                  {recipient.citation && (
174
+                    <p className="mt-2 text-sm text-gray-600 line-clamp-2 italic">
175
+                      &ldquo;{recipient.citation}&rdquo;
176
+                    </p>
177
+                  )}
178
+                </Link>
179
+              ))}
180
+            </div>
181
+          )}
182
+        </div>
183
+
184
+        {/* Back Link */}
185
+        <div className="mt-8 text-center">
186
+          <Link href="/awards" className="text-vmi-red hover:underline font-semibold">
187
+            ← Back to All Awards
188
+          </Link>
189
+        </div>
190
+      </main>
191
+    </div>
192
+  );
193
+}
app/awards/page.tsxadded
@@ -0,0 +1,123 @@
1
+'use client';
2
+
3
+import { useState, useEffect } from 'react';
4
+import Link from 'next/link';
5
+import Image from 'next/image';
6
+import Header from '@/components/Header';
7
+import { getAwards, Award } from '@/lib/api';
8
+
9
+export default function AwardsPage() {
10
+  const [awards, setAwards] = useState<Award[]>([]);
11
+  const [loading, setLoading] = useState(true);
12
+  const [error, setError] = useState<string | null>(null);
13
+
14
+  useEffect(() => {
15
+    async function fetchAwards() {
16
+      try {
17
+        const data = await getAwards();
18
+        setAwards(data);
19
+      } catch (err) {
20
+        setError('Failed to load awards');
21
+        console.error(err);
22
+      } finally {
23
+        setLoading(false);
24
+      }
25
+    }
26
+    fetchAwards();
27
+  }, []);
28
+
29
+  const breadcrumbs = [
30
+    { label: 'Home', href: '/' },
31
+    { label: 'Awards for Heroism and Gallantry' }
32
+  ];
33
+
34
+  // Helper to get image extension
35
+  const getImagePath = (filename: string) => {
36
+    // Check for common extensions in public folder
37
+    const extensions = ['.jpg', '.png', '.jpeg', '.gif'];
38
+    for (const ext of extensions) {
39
+      // The filename in the DB might already include extension or not
40
+      if (filename.toLowerCase().endsWith(ext)) {
41
+        return `/${filename}`;
42
+      }
43
+    }
44
+    // Default to .jpg if no extension
45
+    return `/${filename}.jpg`;
46
+  };
47
+
48
+  return (
49
+    <div className="min-h-screen bg-vmi-cream">
50
+      <Header breadcrumbs={breadcrumbs} showAwards={false} />
51
+
52
+      <main className="max-w-6xl mx-auto px-4 py-12">
53
+        {/* Title Section */}
54
+        <div className="bg-vmi-light-gold border-2 border-vmi-gold rounded-lg p-8 mb-12 shadow-xl">
55
+          <h1 className="text-4xl font-black text-center mb-4 text-vmi-red">
56
+            Awards for Heroism and Gallantry
57
+          </h1>
58
+          <p className="text-center text-gray-700 max-w-3xl mx-auto">
59
+            Those Alumni who &ldquo;Gave All&rdquo; on this memorial website who were also recognized for valor and heroism in combat are listed on this page with a link to their profile.
60
+            These awards honor extraordinary acts of bravery and selfless service in defense of our country.
61
+          </p>
62
+        </div>
63
+
64
+        {/* Awards Grid */}
65
+        <div className="bg-white border-2 border-gray-300 rounded-lg p-8 shadow-xl">
66
+          <h2 className="text-3xl font-bold mb-8 text-center text-vmi-red">
67
+            Military Decorations
68
+          </h2>
69
+
70
+          {loading && (
71
+            <p className="text-center text-gray-600">Loading awards...</p>
72
+          )}
73
+
74
+          {error && (
75
+            <p className="text-center text-red-600">{error}</p>
76
+          )}
77
+
78
+          {!loading && !error && awards.length === 0 && (
79
+            <p className="text-center text-gray-600">
80
+              No awards found. Please add some through the admin panel.
81
+            </p>
82
+          )}
83
+
84
+          {!loading && !error && awards.length > 0 && (
85
+            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
86
+              {awards.map((award) => (
87
+                <Link
88
+                  key={award.id}
89
+                  href={`/awards/${award.id}`}
90
+                  className="block p-6 rounded-lg border-2 border-gray-200 hover:border-vmi-gold hover:bg-vmi-light-gold transition-all duration-200 group"
91
+                >
92
+                  <div className="flex flex-col items-center text-center">
93
+                    {/* Award Image */}
94
+                    <div className="relative w-24 h-32 mb-4">
95
+                      <Image
96
+                        src={getImagePath(award.image_filename)}
97
+                        alt={award.name}
98
+                        fill
99
+                        className="object-contain"
100
+                        sizes="96px"
101
+                      />
102
+                    </div>
103
+
104
+                    {/* Award Info */}
105
+                    <h3 className="text-lg font-bold text-gray-800 group-hover:text-vmi-red transition-colors mb-2">
106
+                      {award.name}
107
+                    </h3>
108
+                    <p className="text-gray-600 text-sm line-clamp-2 mb-3">
109
+                      {award.short_description}
110
+                    </p>
111
+                    <p className="text-vmi-red font-bold">
112
+                      {award.recipient_count} VMI {award.recipient_count === 1 ? 'Recipient' : 'Recipients'}
113
+                    </p>
114
+                  </div>
115
+                </Link>
116
+              ))}
117
+            </div>
118
+          )}
119
+        </div>
120
+      </main>
121
+    </div>
122
+  );
123
+}
app/icon.svgadded
@@ -0,0 +1,10 @@
1
+<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+  <!-- Background circle -->
3
+  <circle cx="16" cy="16" r="16" fill="#AE122A"/>
4
+
5
+  <!-- Gold border ring -->
6
+  <circle cx="16" cy="16" r="14" fill="none" stroke="#FFD619" stroke-width="1.5"/>
7
+
8
+  <!-- VMI Text -->
9
+  <text x="16" y="20" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#FFD619" text-anchor="middle">VMI</text>
10
+</svg>
app/layout.tsxmodified
@@ -1,10 +1,31 @@
11
 import type { Metadata } from "next";
22
 import "./globals.css";
33
 import Footer from "@/components/Footer";
4
+import { Analytics } from "@vercel/analytics/react";
45
 
56
 export const metadata: Metadata = {
67
   title: "VMI Virtual Memorial",
78
   description: "Honoring VMI's fallen heroes who made the ultimate sacrifice in service to their country",
9
+  icons: {
10
+    icon: [
11
+      { url: '/icon.svg', type: 'image/svg+xml' },
12
+      { url: '/favicon.ico', sizes: 'any' },
13
+    ],
14
+    apple: [
15
+      { url: '/apple-icon.svg', type: 'image/svg+xml' },
16
+    ],
17
+  },
18
+  openGraph: {
19
+    title: "VMI Virtual Memorial",
20
+    description: "Honoring VMI's fallen heroes who made the ultimate sacrifice in service to their country",
21
+    siteName: "VMI Virtual Memorial",
22
+    type: 'website',
23
+  },
24
+  twitter: {
25
+    card: 'summary_large_image',
26
+    title: "VMI Virtual Memorial",
27
+    description: "Honoring VMI's fallen heroes who made the ultimate sacrifice in service to their country",
28
+  },
829
 };
930
 
1031
 export default function RootLayout({
@@ -19,6 +40,7 @@ export default function RootLayout({
1940
           {children}
2041
         </div>
2142
         <Footer />
43
+        <Analytics />
2244
       </body>
2345
     </html>
2446
   );
app/memorial/conflict/[id]/page.tsxmodified
@@ -1,30 +1,38 @@
11
 'use client';
22
 
3
-import { useState, useEffect } from 'react';
3
+import { useState, useEffect, useRef } from 'react';
44
 import Link from 'next/link';
55
 import { useParams } from 'next/navigation';
6
-import { getConflicts, getPeopleByConflict, Conflict, Person } from '@/lib/api';
6
+import { getConflicts, getPeopleByConflict, Conflict, PersonDetail } from '@/lib/api';
77
 import Header from '@/components/Header';
8
+import DocumentIcon from '@/components/DocumentIcon';
9
+import AwardIcon from '@/components/AwardIcon';
10
+import Pagination from '@/components/Pagination';
811
 
912
 export default function ConflictPage() {
1013
   const params = useParams();
1114
   const conflictId = parseInt(params.id as string);
12
-  
15
+
1316
   const [conflict, setConflict] = useState<Conflict | null>(null);
14
-  const [people, setPeople] = useState<Person[]>([]);
17
+  const [people, setPeople] = useState<PersonDetail[]>([]);
1518
   const [loading, setLoading] = useState(true);
1619
   const [error, setError] = useState<string | null>(null);
20
+  const [currentPage, setCurrentPage] = useState(1);
21
+  const [itemsPerPage, setItemsPerPage] = useState(30);
22
+
23
+  // Ref for scrolling to top of results list
24
+  const resultsRef = useRef<HTMLDivElement>(null);
1725
 
18
-  useEffect(() => {
26
+useEffect(() => {
1927
     async function fetchData() {
2028
       try {
2129
         const conflicts = await getConflicts();
2230
         const currentConflict = conflicts.find(c => c.id === conflictId);
23
-        
31
+
2432
         if (!currentConflict) {
2533
           throw new Error('Conflict not found');
2634
         }
27
-        
35
+
2836
         setConflict(currentConflict);
2937
         const peopleData = await getPeopleByConflict(conflictId);
3038
         setPeople(peopleData);
@@ -35,10 +43,28 @@ export default function ConflictPage() {
3543
         setLoading(false);
3644
       }
3745
     }
38
-    
46
+
3947
     fetchData();
4048
   }, [conflictId]);
4149
 
50
+  // Calculate paginated data
51
+  const totalItems = people.length;
52
+  const startIndex = (currentPage - 1) * itemsPerPage;
53
+  const endIndex = startIndex + itemsPerPage;
54
+  const paginatedPeople = people.slice(startIndex, endIndex);
55
+
56
+  // Handlers for pagination
57
+  const handlePageChange = (page: number) => {
58
+    setCurrentPage(page);
59
+    // Scroll to top of results list
60
+    resultsRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
61
+  };
62
+
63
+  const handleItemsPerPageChange = (newItemsPerPage: number) => {
64
+    setItemsPerPage(newItemsPerPage);
65
+    setCurrentPage(1); // Reset to first page when changing items per page
66
+  };
67
+
4268
   if (loading) {
4369
     return (
4470
       <div className="min-h-screen bg-vmi-cream flex items-center justify-center">
@@ -77,7 +103,9 @@ export default function ConflictPage() {
77103
             {conflict.name}
78104
           </h1>
79105
           <p className="text-xl text-gray-700 mb-4">
80
-            {conflict.start_year} – {conflict.end_year || 'Present'}
106
+            {conflict.start_year === conflict.end_year
107
+              ? conflict.start_year
108
+              : `${conflict.start_year} – ${conflict.end_year || 'Present'}`}
81109
           </p>
82110
           {conflict.description && (
83111
             <p className="text-gray-800 leading-relaxed mb-6">{conflict.description}</p>
@@ -90,40 +118,68 @@ export default function ConflictPage() {
90118
         </div>
91119
 
92120
         {/* People List */}
93
-        <div className="bg-white border-2 border-gray-300 rounded-lg p-8 shadow-xl">
121
+        <div ref={resultsRef} className="bg-white border-2 border-gray-300 rounded-lg p-8 shadow-xl">
94122
           <h2 className="text-3xl font-bold mb-8 text-center text-vmi-red">
95123
             Honor Roll
96124
           </h2>
97
-          
125
+
98126
           {people.length === 0 ? (
99127
             <p className="text-center text-gray-600 text-lg">No casualties recorded yet.</p>
100128
           ) : (
101
-            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
102
-              {people.map((person) => (
103
-                <Link
104
-                  key={person.id}
105
-                  href={`/memorial/person/${person.id}`}
106
-                  className="block p-6 border-2 border-gray-200 rounded-lg hover:border-vmi-gold hover:bg-vmi-light-gold transition-all duration-200 group"
107
-                >
108
-                  <h3 className="text-xl font-bold text-gray-800 group-hover:text-vmi-red transition-colors mb-2">
109
-                    {person.full_display_name ? 
110
-                      person.full_display_name.replace(person.rank + ' ', '').replace(person.rank + ', ', '') 
111
-                      : person.display_name.replace(person.rank + ' ', '').replace(person.rank + ', ', '')}
112
-                  </h3>
113
-                  {person.rank && (
114
-                    <p className="text-gray-700 font-semibold">{person.rank}</p>
115
-                  )}
116
-                  {person.unit && (
117
-                    <p className="text-gray-600 text-sm italic">{person.unit}</p>
118
-                  )}
119
-                  {person.death_description && (
120
-                    <p className="text-gray-600 text-sm italic mt-3 line-clamp-3">
121
-                      {person.death_description}
122
-                    </p>
123
-                  )}
124
-                </Link>
125
-              ))}
126
-            </div>
129
+            <>
130
+              {/* Pagination Controls - Top */}
131
+              <Pagination
132
+                currentPage={currentPage}
133
+                totalItems={totalItems}
134
+                itemsPerPage={itemsPerPage}
135
+                onPageChange={handlePageChange}
136
+                onItemsPerPageChange={handleItemsPerPageChange}
137
+              />
138
+
139
+              {/* People Grid */}
140
+              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
141
+                {paginatedPeople.map((person) => (
142
+                  <Link
143
+                    key={person.id}
144
+                    href={`/memorial/person/${person.id}`}
145
+                    className="block p-6 border-2 border-gray-200 rounded-lg hover:border-vmi-gold hover:bg-vmi-light-gold transition-all duration-200 group"
146
+                  >
147
+                    <h3 className="text-xl font-bold text-gray-800 group-hover:text-vmi-red transition-colors mb-2 flex items-center gap-2">
148
+                      {(() => {
149
+                        const name = person.full_display_name || person.display_name;
150
+                        // Only remove rank if it exists
151
+                        if (person.rank) {
152
+                          return name.replace(person.rank + ' ', '').replace(person.rank + ', ', '');
153
+                        }
154
+                        return name;
155
+                      })()}
156
+                      {person.has_awards && <AwardIcon className="flex-shrink-0" />}
157
+                      {person.pdf_key && <DocumentIcon className="flex-shrink-0" />}
158
+                    </h3>
159
+                    {person.rank && (
160
+                      <p className="text-gray-700 font-semibold">{person.rank}</p>
161
+                    )}
162
+                    {person.unit && (
163
+                      <p className="text-gray-600 text-sm italic">{person.unit}</p>
164
+                    )}
165
+                    {person.death_description && (
166
+                      <p className="text-gray-600 text-sm italic mt-3 line-clamp-3">
167
+                        {person.death_description}
168
+                      </p>
169
+                    )}
170
+                  </Link>
171
+                ))}
172
+              </div>
173
+
174
+              {/* Pagination Controls - Bottom */}
175
+              <Pagination
176
+                currentPage={currentPage}
177
+                totalItems={totalItems}
178
+                itemsPerPage={itemsPerPage}
179
+                onPageChange={handlePageChange}
180
+                onItemsPerPageChange={handleItemsPerPageChange}
181
+              />
182
+            </>
127183
           )}
128184
         </div>
129185
       </main>
app/memorial/page.tsxmodified
@@ -3,14 +3,9 @@
33
 import { useState, useEffect } from 'react';
44
 import Link from 'next/link';
55
 import Header from '@/components/Header';
6
-
7
-interface Person {
8
-  id: number;
9
-  display_name: string;
10
-  rank: string;
11
-  unit: string;
12
-  death_description?: string;
13
-}
6
+import DocumentIcon from '@/components/DocumentIcon';
7
+import AwardIcon from '@/components/AwardIcon';
8
+import { PersonDetail } from '@/lib/api';
149
 
1510
 interface ConflictWithCasualties {
1611
   id: number;
@@ -19,7 +14,7 @@ interface ConflictWithCasualties {
1914
   end_year: number | null;
2015
   description: string;
2116
   casualty_count: number;
22
-  casualties: Person[];
17
+  casualties: PersonDetail[];
2318
 }
2419
 
2520
 export default function MemorialIndexPage() {
@@ -27,25 +22,30 @@ export default function MemorialIndexPage() {
2722
   const [loading, setLoading] = useState(true);
2823
   const [error, setError] = useState<string | null>(null);
2924
   const [expandedConflicts, setExpandedConflicts] = useState<Set<number>>(new Set());
25
+  const [sortBy, setSortBy] = useState<'alphabetical' | 'class_year'>('alphabetical');
26
+  const [isInitialLoad, setIsInitialLoad] = useState(true);
3027
 
3128
   useEffect(() => {
3229
     async function fetchData() {
3330
       try {
3431
         const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000/api';
35
-        const response = await fetch(`${apiUrl}/memorial/index/`);
36
-        
32
+        const response = await fetch(`${apiUrl}/memorial/index/?sort=${sortBy}`);
33
+
3734
         if (!response.ok) {
3835
           throw new Error('Failed to fetch memorial index');
3936
         }
40
-        
37
+
4138
         const data = await response.json();
4239
         setConflicts(data);
43
-        
44
-        // By default, expand conflicts with casualties
45
-        const defaultExpanded = new Set<number>(
46
-          data.filter((c: ConflictWithCasualties) => c.casualty_count > 0).map((c: ConflictWithCasualties) => c.id)
47
-        );
48
-        setExpandedConflicts(defaultExpanded);
40
+
41
+        // By default, expand conflicts with casualties (only on first load)
42
+        if (isInitialLoad) {
43
+          const defaultExpanded = new Set<number>(
44
+            data.filter((c: ConflictWithCasualties) => c.casualty_count > 0).map((c: ConflictWithCasualties) => c.id)
45
+          );
46
+          setExpandedConflicts(defaultExpanded);
47
+          setIsInitialLoad(false);
48
+        }
4949
       } catch (err) {
5050
         setError(err instanceof Error ? err.message : 'Failed to load data');
5151
         console.error(err);
@@ -53,9 +53,9 @@ export default function MemorialIndexPage() {
5353
         setLoading(false);
5454
       }
5555
     }
56
-    
56
+
5757
     fetchData();
58
-  }, []);
58
+  }, [sortBy, isInitialLoad]);
5959
 
6060
   const toggleConflict = (conflictId: number) => {
6161
     const newExpanded = new Set(expandedConflicts);
@@ -129,13 +129,41 @@ export default function MemorialIndexPage() {
129129
               <span className="text-vmi-red font-bold">{totalCasualties}</span>
130130
             </div>
131131
           </div>
132
-          <div className="mt-6">
132
+          <div className="mt-6 flex justify-between items-center">
133133
             <button
134134
               onClick={toggleAll}
135135
               className="bg-vmi-red text-white px-6 py-2 rounded hover:bg-vmi-dark-red transition-colors font-semibold"
136136
             >
137137
               {expandedConflicts.size === conflicts.length ? 'Collapse All' : 'Expand All'}
138138
             </button>
139
+
140
+            {/* Sort Toggle */}
141
+            <div className="flex items-center gap-2">
142
+              <span className="text-sm text-gray-600">Sort by:</span>
143
+              <button
144
+                onClick={() => setSortBy(sortBy === 'alphabetical' ? 'class_year' : 'alphabetical')}
145
+                className="flex items-center bg-white border-2 border-gray-300 rounded-full p-1 shadow-sm hover:shadow-md transition-shadow"
146
+              >
147
+                <span
148
+                  className={`px-3 py-1 rounded-full transition-all ${
149
+                    sortBy === 'alphabetical'
150
+                      ? 'bg-vmi-red text-white font-semibold'
151
+                      : 'text-gray-500'
152
+                  }`}
153
+                >
154
+                  ABC
155
+                </span>
156
+                <span
157
+                  className={`px-3 py-1 rounded-full transition-all ${
158
+                    sortBy === 'class_year'
159
+                      ? 'bg-vmi-red text-white font-semibold'
160
+                      : 'text-gray-500'
161
+                  }`}
162
+                >
163
+                  &apos;42
164
+                </span>
165
+              </button>
166
+            </div>
139167
           </div>
140168
         </div>
141169
 
@@ -154,7 +182,9 @@ export default function MemorialIndexPage() {
154182
                       {conflict.name}
155183
                     </h2>
156184
                     <p className="text-gray-600">
157
-                      {conflict.start_year} – {conflict.end_year || 'Present'}
185
+                      {conflict.start_year === conflict.end_year
186
+                        ? conflict.start_year
187
+                        : `${conflict.start_year} – ${conflict.end_year || 'Present'}`}
158188
                     </p>
159189
                   </div>
160190
                   <div className="flex items-center gap-4">
@@ -179,8 +209,15 @@ export default function MemorialIndexPage() {
179209
                         href={`/memorial/person/${person.id}`}
180210
                         className="block p-4 border border-gray-200 rounded hover:border-vmi-gold hover:bg-vmi-light-gold transition-all duration-200 group"
181211
                       >
182
-                        <h3 className="font-bold text-gray-800 group-hover:text-vmi-red transition-colors">
183
-                          {person.display_name.replace(person.rank + ' ', '').replace(person.rank + ', ', '')}
212
+                        <h3 className="font-bold text-gray-800 group-hover:text-vmi-red transition-colors flex items-center gap-2">
213
+                          {person.rank
214
+                            ? person.display_name.replace(person.rank + ' ', '').replace(person.rank + ', ', '')
215
+                            : person.display_name}
216
+                          {person.class_year && (
217
+                            <span className="text-gray-600 font-normal">&apos;{String(person.class_year).slice(-2)}</span>
218
+                          )}
219
+                          {person.has_awards && <AwardIcon className="flex-shrink-0" />}
220
+                          {person.pdf_key && <DocumentIcon className="flex-shrink-0" />}
184221
                         </h3>
185222
                         {person.rank && (
186223
                           <p className="text-gray-700 text-sm">{person.rank}</p>
app/memorial/person/[id]/page.tsxmodified
@@ -2,6 +2,7 @@
22
 
33
 import { useState, useEffect } from 'react';
44
 import Link from 'next/link';
5
+import Image from 'next/image';
56
 import { useParams } from 'next/navigation';
67
 import { getPersonDetail, PersonDetailWithContributions } from '@/lib/api';
78
 import Header from '@/components/Header';
@@ -85,14 +86,18 @@ export default function PersonPage() {
8586
     );
8687
   }
8788
 
88
-  const displayName = person.full_display_name ? 
89
-    person.full_display_name.replace(person.rank + ' ', '').replace(person.rank + ', ', '') 
90
-    : person.display_name;
89
+  const displayName = (() => {
90
+    const name = person.full_display_name || person.display_name;
91
+    if (person.rank && person.full_display_name) {
92
+      return name.replace(person.rank + ' ', '').replace(person.rank + ', ', '');
93
+    }
94
+    return person.full_display_name ? name : person.display_name;
95
+  })();
9196
 
9297
   return (
9398
     <div className="min-h-screen bg-vmi-cream">
9499
       <Header 
95
-        breadcrumbs={[
100
+        breadcrumbs={[ 
96101
           { label: 'Home', href: '/' },
97102
           { label: person.conflict_name, href: `/memorial/conflict/${person.conflict}` },
98103
           { label: person.display_name }
@@ -103,8 +108,20 @@ export default function PersonPage() {
103108
       <main className="max-w-6xl mx-auto px-4 py-12">
104109
         {/* Person Header */}
105110
         <div className="bg-vmi-light-gold border-2 border-vmi-gold rounded-lg p-8 mb-12 shadow-xl">
106
-          <h1 className="text-4xl font-black text-vmi-red mb-2">
111
+          <h1 className="text-4xl font-black text-vmi-red mb-2 flex items-center gap-2">
107112
             {displayName}
113
+            {person.pdf_key && (
114
+              <span title="Memorial document available" className="inline-block align-middle">
115
+                {/* Simple document icon SVG */}
116
+                <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#b91c1c" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="feather feather-file-text">
117
+                  <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
118
+                  <polyline points="14 2 14 8 20 8" />
119
+                  <line x1="16" y1="13" x2="8" y2="13" />
120
+                  <line x1="16" y1="17" x2="8" y2="17" />
121
+                  <line x1="10" y1="9" x2="9" y2="9" />
122
+                </svg>
123
+              </span>
124
+            )}
108125
           </h1>
109126
           
110127
           {/* Rank and Unit subtitle */}
@@ -123,7 +140,7 @@ export default function PersonPage() {
123140
             <div className="space-y-3">
124141
               {person.class_year && (
125142
                 <p className="text-lg">
126
-                  <span className="font-bold text-gray-700">Class Year:</span> {person.class_year}
143
+                  <span className="font-bold text-gray-700">Class Year:</span> {person.class_year}{person.class_letter || ''}
127144
                 </p>
128145
               )}
129146
               <p className="text-lg">
@@ -153,10 +170,70 @@ export default function PersonPage() {
153170
           </div>
154171
         )}
155172
 
173
+        {/* Awards Section */}
174
+        {person.awards && person.awards.length > 0 && (
175
+          <div className="bg-white border-2 border-gray-300 rounded-lg p-8 mb-12 shadow-xl">
176
+            <h2 className="text-2xl font-bold mb-6 text-vmi-red">
177
+              Awards for Heroism &amp; Gallantry
178
+            </h2>
179
+            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
180
+              {person.awards.map((award) => {
181
+                const getImagePath = (filename: string) => {
182
+                  const extensions = ['.jpg', '.png', '.jpeg', '.gif'];
183
+                  for (const ext of extensions) {
184
+                    if (filename.toLowerCase().endsWith(ext)) {
185
+                      return `/${filename}`;
186
+                    }
187
+                  }
188
+                  return `/${filename}.jpg`;
189
+                };
190
+
191
+                return (
192
+                  <Link
193
+                    key={award.award_id}
194
+                    href={`/awards/${award.award_id}`}
195
+                    className="flex items-center gap-4 p-4 rounded-lg border-2 border-gray-200 hover:border-vmi-gold hover:bg-vmi-light-gold transition-all duration-200 group"
196
+                  >
197
+                    <div className="relative w-16 h-20 flex-shrink-0">
198
+                      <Image
199
+                        src={getImagePath(award.award_image_filename)}
200
+                        alt={award.award_name}
201
+                        fill
202
+                        className="object-contain"
203
+                        sizes="64px"
204
+                      />
205
+                    </div>
206
+                    <div>
207
+                      <h3 className="font-bold text-gray-800 group-hover:text-vmi-red transition-colors">
208
+                        {award.award_name}
209
+                        {award.count > 1 && (
210
+                          <span className="ml-2 text-sm text-vmi-gold">
211
+                            (×{award.count})
212
+                          </span>
213
+                        )}
214
+                      </h3>
215
+                      {award.date_awarded && (
216
+                        <p className="text-sm text-gray-500">
217
+                          {new Date(award.date_awarded).toLocaleDateString()}
218
+                        </p>
219
+                      )}
220
+                      {award.citation && (
221
+                        <p className="text-sm text-gray-600 italic line-clamp-2 mt-1">
222
+                          &ldquo;{award.citation}&rdquo;
223
+                        </p>
224
+                      )}
225
+                    </div>
226
+                  </Link>
227
+                );
228
+              })}
229
+            </div>
230
+          </div>
231
+        )}
232
+
156233
         {/* PDF Viewer */}
157234
         <div className="bg-white border-2 border-gray-300 rounded-lg p-8 shadow-xl mb-12">
158235
           <h2 className="text-3xl font-bold mb-6 text-center text-vmi-red">
159
-            Memorial Document
236
+            Memorial Portrait
160237
           </h2>
161238
           
162239
           {person.pdf_key ? (
@@ -171,11 +248,11 @@ export default function PersonPage() {
171248
                     Unable to load PDF viewer. 
172249
                   </p>
173250
                   {pdfUrl && (
174
-                    <a 
251
+                    <a
175252
                       href={pdfUrl}
176253
                       target="_blank"
177254
                       rel="noopener noreferrer"
178
-                      className="inline-block bg-vmi-red text-white px-6 py-3 rounded hover:bg-vmi-dark-red transition-colors font-semibold"
255
+                      className="inline-block bg-vmi-red text-white px-6 py-3 rounded hover:bg-vmi-dark-red hover:text-white transition-colors font-semibold"
179256
                     >
180257
                       Open PDF in New Tab
181258
                     </a>
@@ -190,11 +267,11 @@ export default function PersonPage() {
190267
                     title={`Memorial document for ${person.display_name}`}
191268
                   />
192269
                   <div className="p-6 bg-gray-100 text-center border-t-2 border-gray-400">
193
-                    <a 
270
+                    <a
194271
                       href={pdfUrl}
195272
                       target="_blank"
196273
                       rel="noopener noreferrer"
197
-                      className="inline-block bg-vmi-red text-white px-6 py-3 rounded hover:bg-vmi-dark-red transition-colors font-semibold"
274
+                      className="inline-block bg-vmi-red text-white px-6 py-3 rounded hover:bg-vmi-dark-red hover:text-white transition-colors font-semibold"
198275
                     >
199276
                       Open PDF in Full Screen
200277
                     </a>
app/memorial/search/page.tsxmodified
@@ -2,8 +2,10 @@
22
 
33
 import { useState, useEffect } from 'react';
44
 import Link from 'next/link';
5
-import { searchPeople, getSearchFilters, PersonSearchResult, SearchFilters } from '@/lib/api';
5
+import { searchPeople, getSearchFilters, PersonDetail, SearchFilters } from '@/lib/api';
66
 import Header from '@/components/Header';
7
+import DocumentIcon from '@/components/DocumentIcon';
8
+import AwardIcon from '@/components/AwardIcon';
79
 
810
 export default function MemorialSearchPage() {
911
   // Search state
@@ -13,9 +15,10 @@ export default function MemorialSearchPage() {
1315
   const [dateFrom, setDateFrom] = useState('');
1416
   const [dateTo, setDateTo] = useState('');
1517
   const [noDate, setNoDate] = useState(false);
18
+  const [hasDocument, setHasDocument] = useState(false);
1619
   
1720
   // Results state
18
-  const [results, setResults] = useState<PersonSearchResult[]>([]);
21
+  const [results, setResults] = useState<PersonDetail[]>([]);
1922
   const [totalCount, setTotalCount] = useState(0);
2023
   const [loading, setLoading] = useState(false);
2124
   const [hasSearched, setHasSearched] = useState(false);
@@ -30,7 +33,7 @@ export default function MemorialSearchPage() {
3033
         // Get filters
3134
         const filterData = await getSearchFilters();
3235
         setFilters(filterData);
33
-        
36
+
3437
         // Load all people initially
3538
         const params = {
3639
           q: '',
@@ -38,9 +41,10 @@ export default function MemorialSearchPage() {
3841
           conflict: '',
3942
           date_from: '',
4043
           date_to: '',
41
-          no_date: false
44
+          no_date: false,
45
+          has_document: false
4246
         };
43
-        
47
+
4448
         const data = await searchPeople(params);
4549
         setResults(data.results);
4650
         setTotalCount(data.count);
@@ -49,14 +53,14 @@ export default function MemorialSearchPage() {
4953
         console.error('Failed to initialize:', err);
5054
       }
5155
     }
52
-    
56
+
5357
     initialize();
5458
   }, []);
5559
 
5660
   const performSearch = async () => {
5761
     setLoading(true);
5862
     setHasSearched(true);
59
-    
63
+
6064
     try {
6165
       const params = {
6266
         q: searchTerm,
@@ -64,9 +68,10 @@ export default function MemorialSearchPage() {
6468
         conflict: selectedConflicts.join(','),
6569
         date_from: dateFrom,
6670
         date_to: dateTo,
67
-        no_date: noDate
71
+        no_date: noDate,
72
+        has_document: hasDocument
6873
       };
69
-      
74
+
7075
       const data = await searchPeople(params);
7176
       setResults(data.results);
7277
       setTotalCount(data.count);
@@ -107,6 +112,7 @@ export default function MemorialSearchPage() {
107112
     setDateFrom('');
108113
     setDateTo('');
109114
     setNoDate(false);
115
+    setHasDocument(false);
110116
   };
111117
 
112118
   return (
@@ -129,6 +135,19 @@ export default function MemorialSearchPage() {
129135
               <h2 className="text-2xl font-bold text-vmi-red mb-6">Search Filters</h2>
130136
               
131137
               <form onSubmit={handleSubmit} className="space-y-6">
138
+                {/* Memorial Document Filter */}
139
+                <div>
140
+                  <label className="flex items-center cursor-pointer hover:bg-gray-50 p-2 rounded">
141
+                    <input
142
+                      type="checkbox"
143
+                      checked={hasDocument}
144
+                      onChange={(e) => setHasDocument(e.target.checked)}
145
+                      className="mr-3 text-vmi-red focus:ring-vmi-gold w-4 h-4"
146
+                    />
147
+                    <span className="text-sm font-bold text-gray-700">Memorial Document Available</span>
148
+                  </label>
149
+                </div>
150
+
132151
                 {/* Name Search */}
133152
                 <div>
134153
                   <label htmlFor="search" className="block text-sm font-bold text-gray-700 mb-2">
@@ -264,10 +283,16 @@ export default function MemorialSearchPage() {
264283
                     >
265284
                       <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
266285
                         <div>
267
-                          <h3 className="text-xl font-bold text-gray-800 group-hover:text-vmi-red transition-colors">
268
-                            {person.full_display_name ? 
269
-                              person.full_display_name.replace(person.rank + ' ', '').replace(person.rank + ', ', '') 
270
-                              : person.display_name}
286
+                          <h3 className="text-xl font-bold text-gray-800 group-hover:text-vmi-red transition-colors flex items-center gap-2">
287
+                            {(() => {
288
+                              const name = person.full_display_name || person.display_name;
289
+                              if (person.rank && person.full_display_name) {
290
+                                return name.replace(person.rank + ' ', '').replace(person.rank + ', ', '');
291
+                              }
292
+                              return person.full_display_name ? name : person.display_name;
293
+                            })()}
294
+                            {person.has_awards && <AwardIcon className="flex-shrink-0" />}
295
+                            {person.pdf_key && <DocumentIcon className="flex-shrink-0" />}
271296
                           </h3>
272297
                           {person.rank && (
273298
                             <p className="text-gray-700">{person.rank}</p>
app/opengraph-image.svgadded
@@ -0,0 +1,20 @@
1
+<svg width="1200" height="630" viewBox="0 0 1200 630" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+  <!-- Background -->
3
+  <rect width="1200" height="630" fill="#AE122A"/>
4
+
5
+  <!-- Decorative border -->
6
+  <rect x="20" y="20" width="1160" height="590" fill="none" stroke="#FFD619" stroke-width="4"/>
7
+
8
+  <!-- VMI Circle Logo -->
9
+  <circle cx="600" cy="250" r="100" fill="#FFD619"/>
10
+  <text x="600" y="280" font-family="Arial, sans-serif" font-size="72" font-weight="bold" fill="#AE122A" text-anchor="middle">VMI</text>
11
+
12
+  <!-- Title -->
13
+  <text x="600" y="420" font-family="Georgia, serif" font-size="48" font-weight="bold" fill="#FFD619" text-anchor="middle">Virtual Memorial</text>
14
+
15
+  <!-- Subtitle -->
16
+  <text x="600" y="480" font-family="Georgia, serif" font-size="28" fill="#FFD619" text-anchor="middle" opacity="0.9">Honoring Those Who Gave All</text>
17
+
18
+  <!-- Bottom text -->
19
+  <text x="600" y="560" font-family="Arial, sans-serif" font-size="20" fill="#FFD619" text-anchor="middle" opacity="0.7">Virginia Military Institute</text>
20
+</svg>
app/page.tsxmodified
@@ -43,14 +43,20 @@ export default function Home() {
4343
             </div>
4444
             {/* Navigation */}
4545
             <nav className="flex items-center space-x-4">
46
-              <Link 
47
-                href="/memorial/search" 
46
+              <Link
47
+                href="/memorial/search"
4848
                 className="text-vmi-gold hover:text-white transition-colors font-semibold"
4949
               >
5050
                 Search Memorial
5151
               </Link>
52
-              <Link 
53
-                href="/memorial" 
52
+              <Link
53
+                href="/awards"
54
+                className="bg-vmi-gold text-vmi-red px-4 py-2 rounded font-bold hover:bg-white transition-colors shadow-md text-center text-sm leading-tight"
55
+              >
56
+                Awards for<br />Heroism &amp; Gallantry
57
+              </Link>
58
+              <Link
59
+                href="/memorial"
5460
                 className="bg-vmi-gold text-vmi-red px-6 py-2 rounded font-bold hover:bg-white transition-colors shadow-md"
5561
               >
5662
                 View Complete Index
@@ -132,7 +138,9 @@ export default function Home() {
132138
                           {conflict.name}
133139
                         </h3>
134140
                         <p className="text-gray-600">
135
-                          {conflict.start_year} – {conflict.end_year || 'Present'}
141
+                          {conflict.start_year === conflict.end_year
142
+                            ? conflict.start_year
143
+                            : `${conflict.start_year} – ${conflict.end_year || 'Present'}`}
136144
                         </p>
137145
                       </div>
138146
                       <div className="text-right">
components/AwardIcon.tsxadded
@@ -0,0 +1,22 @@
1
+interface AwardIconProps {
2
+  className?: string;
3
+  title?: string;
4
+}
5
+
6
+export default function AwardIcon({ className = "", title = "Award recipient" }: AwardIconProps) {
7
+  return (
8
+    <span title={title} className={`inline-block ${className}`}>
9
+      <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#FFD619" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
10
+        {/* Ribbon top */}
11
+        <rect x="7" y="2" width="10" height="4" rx="1" />
12
+        {/* Ribbon tails */}
13
+        <path d="M7 6v4l2.5-2L7 6z" />
14
+        <path d="M17 6v4l-2.5-2L17 6z" />
15
+        {/* Medal circle */}
16
+        <circle cx="12" cy="15" r="5" />
17
+        {/* Star in medal */}
18
+        <path d="M12 12l1 2h2l-1.5 1.5.5 2.5-2-1.5-2 1.5.5-2.5L9 14h2z" />
19
+      </svg>
20
+    </span>
21
+  );
22
+}
components/ContributionForm.tsxmodified
@@ -126,7 +126,7 @@ export default function ContributionForm({ personId, personName, onSuccess }: Co
126126
           </p>
127127
           <button
128128
             onClick={() => setIsOpen(true)}
129
-            className="bg-vmi-red text-white px-6 py-2 rounded hover:bg-vmi-dark-red transition-colors font-semibold"
129
+            className="bg-vmi-red text-white px-6 py-2 rounded hover:bg-vmi-dark-red hover:text-white transition-colors font-semibold"
130130
           >
131131
             Add Information or Image
132132
           </button>
@@ -271,9 +271,9 @@ export default function ContributionForm({ personId, personName, onSuccess }: Co
271271
               type="submit"
272272
               disabled={submitting}
273273
               className={`px-6 py-2 rounded font-semibold transition-colors ${
274
-                submitting 
275
-                  ? 'bg-gray-400 text-gray-200 cursor-not-allowed' 
276
-                  : 'bg-vmi-red text-white hover:bg-vmi-dark-red'
274
+                submitting
275
+                  ? 'bg-gray-400 text-gray-200 cursor-not-allowed'
276
+                  : 'bg-vmi-red text-white hover:bg-vmi-dark-red hover:text-white'
277277
               }`}
278278
             >
279279
               {submitting ? 'Submitting...' : 'Submit Contribution'}
components/DocumentIcon.tsxadded
@@ -0,0 +1,18 @@
1
+interface DocumentIconProps {
2
+  className?: string;
3
+  title?: string;
4
+}
5
+
6
+export default function DocumentIcon({ className = "", title = "Memorial document available" }: DocumentIconProps) {
7
+  return (
8
+    <span title={title} className={`inline-block ${className}`}>
9
+      <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#b91c1c" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="feather feather-file-text">
10
+        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
11
+        <polyline points="14 2 14 8 20 8" />
12
+        <line x1="16" y1="13" x2="8" y2="13" />
13
+        <line x1="16" y1="17" x2="8" y2="17" />
14
+        <line x1="10" y1="9" x2="9" y2="9" />
15
+      </svg>
16
+    </span>
17
+  );
18
+}
components/Header.tsxmodified
@@ -9,9 +9,10 @@ interface HeaderProps {
99
   breadcrumbs: BreadcrumbItem[];
1010
   showSearch?: boolean;
1111
   showIndex?: boolean;
12
+  showAwards?: boolean;
1213
 }
1314
 
14
-export default function Header({ breadcrumbs, showSearch = true, showIndex = true }: HeaderProps) {
15
+export default function Header({ breadcrumbs, showSearch = true, showIndex = true, showAwards = true }: HeaderProps) {
1516
   return (
1617
     <header className="bg-[#AE122A] shadow-lg">
1718
       <div className="max-w-6xl mx-auto px-4 py-6">
@@ -38,19 +39,27 @@ export default function Header({ breadcrumbs, showSearch = true, showIndex = tru
3839
           </nav>
3940
 
4041
           {/* Right Navigation */}
41
-          {(showSearch || showIndex) && (
42
+          {(showSearch || showIndex || showAwards) && (
4243
             <div className="flex items-center space-x-4">
4344
               {showSearch && (
44
-                <Link 
45
-                  href="/memorial/search" 
45
+                <Link
46
+                  href="/memorial/search"
4647
                   className="text-[#FFD619] hover:text-white transition-colors font-semibold"
4748
                 >
4849
                   Search Memorial
4950
                 </Link>
5051
               )}
52
+              {showAwards && (
53
+                <Link
54
+                  href="/awards"
55
+                  className="bg-[#FFD619] text-[#AE122A] px-4 py-2 rounded font-bold hover:bg-white transition-colors shadow-md text-center text-sm leading-tight"
56
+                >
57
+                  Awards for<br />Heroism &amp; Gallantry
58
+                </Link>
59
+              )}
5160
               {showIndex && (
52
-                <Link 
53
-                  href="/memorial" 
61
+                <Link
62
+                  href="/memorial"
5463
                   className="bg-[#FFD619] text-[#AE122A] px-6 py-2 rounded font-bold hover:bg-white transition-colors shadow-md"
5564
                 >
5665
                   View Complete Index
components/Pagination.tsxadded
@@ -0,0 +1,157 @@
1
+import React from 'react';
2
+
3
+interface PaginationProps {
4
+  currentPage: number;
5
+  totalItems: number;
6
+  itemsPerPage: number;
7
+  onPageChange: (page: number) => void;
8
+  onItemsPerPageChange: (itemsPerPage: number) => void;
9
+  itemsPerPageOptions?: number[];
10
+}
11
+
12
+export default function Pagination({
13
+  currentPage,
14
+  totalItems,
15
+  itemsPerPage,
16
+  onPageChange,
17
+  onItemsPerPageChange,
18
+  itemsPerPageOptions = [30, 40, 50],
19
+}: PaginationProps) {
20
+  const totalPages = Math.ceil(totalItems / itemsPerPage);
21
+
22
+  // Don't show pagination if there's only one page or less
23
+  if (totalPages <= 1) {
24
+    return null;
25
+  }
26
+
27
+  const startItem = (currentPage - 1) * itemsPerPage + 1;
28
+  const endItem = Math.min(currentPage * itemsPerPage, totalItems);
29
+
30
+  // Generate page numbers to display
31
+  const getPageNumbers = () => {
32
+    const pages: (number | string)[] = [];
33
+    const maxVisiblePages = 7;
34
+
35
+    if (totalPages <= maxVisiblePages) {
36
+      // Show all pages if total is small
37
+      for (let i = 1; i <= totalPages; i++) {
38
+        pages.push(i);
39
+      }
40
+    } else {
41
+      // Always show first page
42
+      pages.push(1);
43
+
44
+      if (currentPage <= 4) {
45
+        // Near the beginning
46
+        for (let i = 2; i <= 5; i++) {
47
+          pages.push(i);
48
+        }
49
+        pages.push('...');
50
+        pages.push(totalPages);
51
+      } else if (currentPage >= totalPages - 3) {
52
+        // Near the end
53
+        pages.push('...');
54
+        for (let i = totalPages - 4; i <= totalPages; i++) {
55
+          pages.push(i);
56
+        }
57
+      } else {
58
+        // In the middle
59
+        pages.push('...');
60
+        for (let i = currentPage - 1; i <= currentPage + 1; i++) {
61
+          pages.push(i);
62
+        }
63
+        pages.push('...');
64
+        pages.push(totalPages);
65
+      }
66
+    }
67
+
68
+    return pages;
69
+  };
70
+
71
+  const pageNumbers = getPageNumbers();
72
+
73
+  return (
74
+    <div className="flex flex-col sm:flex-row items-center justify-between gap-4 py-6">
75
+      {/* Items per page selector */}
76
+      <div className="flex items-center gap-3">
77
+        <label htmlFor="items-per-page" className="text-gray-700 font-semibold">
78
+          Per page:
79
+        </label>
80
+        <select
81
+          id="items-per-page"
82
+          value={itemsPerPage}
83
+          onChange={(e) => onItemsPerPageChange(Number(e.target.value))}
84
+          className="px-3 py-2 border-2 border-gray-300 rounded bg-white text-gray-800 font-semibold hover:border-vmi-gold focus:border-vmi-gold focus:outline-none focus:ring-2 focus:ring-vmi-light-gold transition-colors"
85
+        >
86
+          {itemsPerPageOptions.map((option) => (
87
+            <option key={option} value={option}>
88
+              {option}
89
+            </option>
90
+          ))}
91
+          <option value={totalItems}>All ({totalItems})</option>
92
+        </select>
93
+        <span className="text-gray-600 text-sm">
94
+          Showing {startItem}-{endItem} of {totalItems}
95
+        </span>
96
+      </div>
97
+
98
+      {/* Page navigation */}
99
+      <div className="flex items-center gap-2">
100
+        {/* Previous button */}
101
+        <button
102
+          onClick={() => onPageChange(currentPage - 1)}
103
+          disabled={currentPage === 1}
104
+          className="px-4 py-2 border-2 border-gray-300 rounded font-semibold text-gray-700 hover:border-vmi-gold hover:bg-vmi-light-gold disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:border-gray-300 disabled:hover:bg-transparent transition-all"
105
+          aria-label="Previous page"
106
+        >
107
+          ← Prev
108
+        </button>
109
+
110
+        {/* Page numbers */}
111
+        <div className="flex gap-1">
112
+          {pageNumbers.map((page, index) => {
113
+            if (page === '...') {
114
+              return (
115
+                <span
116
+                  key={`ellipsis-${index}`}
117
+                  className="px-3 py-2 text-gray-500"
118
+                >
119
+                  ...
120
+                </span>
121
+              );
122
+            }
123
+
124
+            const pageNum = page as number;
125
+            const isCurrentPage = pageNum === currentPage;
126
+
127
+            return (
128
+              <button
129
+                key={pageNum}
130
+                onClick={() => onPageChange(pageNum)}
131
+                className={`px-4 py-2 border-2 rounded font-semibold transition-all ${
132
+                  isCurrentPage
133
+                    ? 'bg-vmi-red text-white border-vmi-red'
134
+                    : 'border-gray-300 text-gray-700 hover:border-vmi-gold hover:bg-vmi-light-gold'
135
+                }`}
136
+                aria-label={`Page ${pageNum}`}
137
+                aria-current={isCurrentPage ? 'page' : undefined}
138
+              >
139
+                {pageNum}
140
+              </button>
141
+            );
142
+          })}
143
+        </div>
144
+
145
+        {/* Next button */}
146
+        <button
147
+          onClick={() => onPageChange(currentPage + 1)}
148
+          disabled={currentPage === totalPages}
149
+          className="px-4 py-2 border-2 border-gray-300 rounded font-semibold text-gray-700 hover:border-vmi-gold hover:bg-vmi-light-gold disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:border-gray-300 disabled:hover:bg-transparent transition-all"
150
+          aria-label="Next page"
151
+        >
152
+          Next →
153
+        </button>
154
+      </div>
155
+    </div>
156
+  );
157
+}
eslint.config.mjsadded
@@ -0,0 +1,17 @@
1
+import { dirname } from "path";
2
+import { fileURLToPath } from "url";
3
+import { FlatCompat } from "@eslint/eslintrc";
4
+
5
+const __filename = fileURLToPath(import.meta.url);
6
+const __dirname = dirname(__filename);
7
+
8
+const compat = new FlatCompat({
9
+  baseDirectory: __dirname,
10
+});
11
+
12
+const eslintConfig = [
13
+  { ignores: [".next/", "next-env.d.ts"] },
14
+  ...compat.extends("next/core-web-vitals", "next/typescript"),
15
+];
16
+
17
+export default eslintConfig;
lib/api.tsmodified
@@ -77,8 +77,11 @@ export interface Person {
7777
   rank: string;
7878
   unit: string;
7979
   class_year?: number;
80
+  class_letter?: string;
8081
   full_display_name?: string;
8182
   death_description?: string;
83
+  pdf_key?: string;
84
+  has_awards?: boolean;
8285
 }
8386
 
8487
 export interface PersonDetail extends Person {
@@ -95,8 +98,47 @@ export interface PersonDetail extends Person {
9598
   pdf_url: string | null;
9699
 }
97100
 
101
+// Award interfaces
102
+export interface Award {
103
+  id: number;
104
+  name: string;
105
+  short_description: string;
106
+  image_filename: string;
107
+  recipient_count: number;
108
+  total_awards_given: number;
109
+  order: number;
110
+}
111
+
112
+export interface AwardRecipient {
113
+  person_id: number;
114
+  display_name: string;
115
+  full_display_name: string;
116
+  class_year: number | null;
117
+  class_letter: string;
118
+  conflict_name: string;
119
+  pdf_key: string;
120
+  count: number;
121
+  date_awarded: string | null;
122
+  citation: string;
123
+}
124
+
125
+export interface AwardDetail extends Award {
126
+  long_description: string;
127
+  recipients: AwardRecipient[];
128
+}
129
+
130
+export interface PersonAward {
131
+  award_id: number;
132
+  award_name: string;
133
+  award_image_filename: string;
134
+  count: number;
135
+  date_awarded: string | null;
136
+  citation: string;
137
+}
138
+
98139
 export interface PersonDetailWithContributions extends PersonDetail {
99140
   contributions?: Contribution[];
141
+  awards?: PersonAward[];
100142
 }
101143
 
102144
 export interface PersonSearchResult {
@@ -104,12 +146,15 @@ export interface PersonSearchResult {
104146
   display_name: string;
105147
   full_display_name: string;
106148
   class_year: number | null;
149
+  class_letter?: string;
107150
   rank: string;
108151
   unit: string;
109152
   date_of_death: string | null;
110153
   death_date_display?: string;
111154
   conflict_name: string;
112155
   conflict_id: number;
156
+  pdf_key?: string;
157
+  has_awards?: boolean;
113158
 }
114159
 
115160
 export interface SearchFilters {
@@ -124,6 +169,7 @@ export interface SearchParams {
124169
   date_from?: string;
125170
   date_to?: string;
126171
   no_date?: boolean;
172
+  has_document?: boolean;
127173
 }
128174
 
129175
 // Fetch all conflicts
@@ -137,8 +183,8 @@ export async function getConflicts(): Promise<Conflict[]> {
137183
 }
138184
 
139185
 // Fetch people by conflict
140
-export async function getPeopleByConflict(conflictId: number): Promise<Person[]> {
141
-  const response = await fetch(`${API_BASE_URL}/memorial/persons/?conflict=${conflictId}`);
186
+export async function getPeopleByConflict(conflictId: number): Promise<PersonDetail[]> {
187
+  const response = await fetch(`${API_BASE_URL}/memorial/persons/?conflict=${conflictId}&paginate=false`);
142188
   if (!response.ok) {
143189
     throw new Error('Failed to fetch people');
144190
   }
@@ -165,16 +211,17 @@ export async function getMemorialIndex(): Promise<Conflict[]> {
165211
 }
166212
 
167213
 // Search people with filters
168
-export async function searchPeople(params: SearchParams): Promise<{ count: number; results: PersonSearchResult[] }> {
214
+export async function searchPeople(params: SearchParams): Promise<{ count: number; results: PersonDetail[] }> {
169215
   const queryParams = new URLSearchParams();
170
-  
216
+
171217
   if (params.q) queryParams.append('q', params.q);
172218
   if (params.class_year) queryParams.append('class_year', params.class_year);
173219
   if (params.conflict) queryParams.append('conflict', params.conflict);
174220
   if (params.date_from) queryParams.append('date_from', params.date_from);
175221
   if (params.date_to) queryParams.append('date_to', params.date_to);
176222
   if (params.no_date !== undefined) queryParams.append('no_date', params.no_date.toString());
177
-  
223
+  if (params.has_document !== undefined) queryParams.append('has_document', params.has_document.toString());
224
+
178225
   const response = await fetch(`${API_BASE_URL}/memorial/persons/search/?${queryParams.toString()}`);
179226
   if (!response.ok) {
180227
     throw new Error('Failed to search people');
@@ -243,11 +290,30 @@ export async function getPersonContributions(personId: number): Promise<Contribu
243290
   const response = await fetch(
244291
     `${API_BASE_URL}/memorial/persons/${personId}/contributions/`
245292
   );
246
-  
293
+
247294
   if (!response.ok) {
248295
     throw new Error('Failed to fetch contributions');
249296
   }
250
-  
297
+
251298
   const data = await response.json();
252299
   return data.results || [];
300
+}
301
+
302
+// Fetch all awards
303
+export async function getAwards(): Promise<Award[]> {
304
+  const response = await fetch(`${API_BASE_URL}/memorial/awards/`);
305
+  if (!response.ok) {
306
+    throw new Error('Failed to fetch awards');
307
+  }
308
+  const data = await response.json();
309
+  return data.results || data;
310
+}
311
+
312
+// Fetch award detail with recipients
313
+export async function getAwardDetail(awardId: number): Promise<AwardDetail> {
314
+  const response = await fetch(`${API_BASE_URL}/memorial/awards/${awardId}/`);
315
+  if (!response.ok) {
316
+    throw new Error('Failed to fetch award details');
317
+  }
318
+  return response.json();
253319
 }
package-lock.jsonmodified
3112 lines changed — click to load
@@ -8,16 +8,18 @@
88
       "name": "vmi-wardead-fe",
99
       "version": "0.1.0",
1010
       "dependencies": {
11
-        "next": "14.2.30",
11
+        "@vercel/analytics": "^1.5.0",
12
+        "next": "15.5.12",
1213
         "react": "^18",
1314
         "react-dom": "^18"
1415
       },
1516
       "devDependencies": {
17
+        "@eslint/eslintrc": "^3",
1618
         "@types/node": "^20",
1719
         "@types/react": "^18",
1820
         "@types/react-dom": "^18",
19
-        "eslint": "^8",
20
-        "eslint-config-next": "14.2.30",
21
+        "eslint": "^9",
22
+        "eslint-config-next": "15.5.12",
2123
         "postcss": "^8",
2224
         "tailwindcss": "^3.4.1",
2325
         "typescript": "^5"
@@ -37,22 +39,21 @@
3739
       }
3840
     },
3941
     "node_modules/@emnapi/core": {
40
-      "version": "1.4.4",
41
-      "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.4.tgz",
42
-      "integrity": "sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g==",
42
+      "version": "1.8.1",
43
+      "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz",
44
+      "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==",
4345
       "dev": true,
4446
       "license": "MIT",
4547
       "optional": true,
4648
       "dependencies": {
47
-        "@emnapi/wasi-threads": "1.0.3",
49
+        "@emnapi/wasi-threads": "1.1.0",
4850
         "tslib": "^2.4.0"
4951
       }
5052
     },
5153
     "node_modules/@emnapi/runtime": {
52
-      "version": "1.4.4",
53
-      "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz",
54
-      "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==",
55
-      "dev": true,
54
+      "version": "1.8.1",
55
+      "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz",
56
+      "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==",
5657
       "license": "MIT",
5758
       "optional": true,
5859
       "dependencies": {
@@ -60,9 +61,9 @@
6061
       }
6162
     },
6263
     "node_modules/@emnapi/wasi-threads": {
63
-      "version": "1.0.3",
64
-      "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.3.tgz",
65
-      "integrity": "sha512-8K5IFFsQqF9wQNJptGbS6FNKgUTsSRYnTqNCG1vPP8jFdjSv18n2mQfJpkt2Oibo9iBEzcDnDxNwKTzC7svlJw==",
64
+      "version": "1.1.0",
65
+      "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz",
66
+      "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
6667
       "dev": true,
6768
       "license": "MIT",
6869
       "optional": true,
@@ -71,9 +72,9 @@
7172
       }
7273
     },
7374
     "node_modules/@eslint-community/eslint-utils": {
74
-      "version": "4.7.0",
75
-      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
76
-      "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
75
+      "version": "4.9.1",
76
+      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
77
+      "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
7778
       "dev": true,
7879
       "license": "MIT",
7980
       "dependencies": {
@@ -89,64 +90,153 @@
8990
         "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
9091
       }
9192
     },
93
+    "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
94
+      "version": "3.4.3",
95
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
96
+      "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
97
+      "dev": true,
98
+      "license": "Apache-2.0",
99
+      "engines": {
100
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
101
+      },
102
+      "funding": {
103
+        "url": "https://opencollective.com/eslint"
104
+      }
105
+    },
92106
     "node_modules/@eslint-community/regexpp": {
93
-      "version": "4.12.1",
94
-      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
95
-      "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
107
+      "version": "4.12.2",
108
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
109
+      "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
96110
       "dev": true,
97111
       "license": "MIT",
98112
       "engines": {
99113
         "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
100114
       }
101115
     },
116
+    "node_modules/@eslint/config-array": {
117
+      "version": "0.21.1",
118
+      "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
119
+      "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
120
+      "dev": true,
121
+      "license": "Apache-2.0",
122
+      "dependencies": {
123
+        "@eslint/object-schema": "^2.1.7",
124
+        "debug": "^4.3.1",
125
+        "minimatch": "^3.1.2"
126
+      },
127
+      "engines": {
128
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
129
+      }
130
+    },
131
+    "node_modules/@eslint/config-helpers": {
132
+      "version": "0.4.2",
133
+      "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
134
+      "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
135
+      "dev": true,
136
+      "license": "Apache-2.0",
137
+      "dependencies": {
138
+        "@eslint/core": "^0.17.0"
139
+      },
140
+      "engines": {
141
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
142
+      }
143
+    },
144
+    "node_modules/@eslint/core": {
145
+      "version": "0.17.0",
146
+      "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
147
+      "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
148
+      "dev": true,
149
+      "license": "Apache-2.0",
150
+      "dependencies": {
151
+        "@types/json-schema": "^7.0.15"
152
+      },
153
+      "engines": {
154
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
155
+      }
156
+    },
102157
     "node_modules/@eslint/eslintrc": {
103
-      "version": "2.1.4",
104
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
105
-      "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
158
+      "version": "3.3.3",
159
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
160
+      "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
106161
       "dev": true,
107162
       "license": "MIT",
108163
       "dependencies": {
109164
         "ajv": "^6.12.4",
110165
         "debug": "^4.3.2",
111
-        "espree": "^9.6.0",
112
-        "globals": "^13.19.0",
166
+        "espree": "^10.0.1",
167
+        "globals": "^14.0.0",
113168
         "ignore": "^5.2.0",
114169
         "import-fresh": "^3.2.1",
115
-        "js-yaml": "^4.1.0",
170
+        "js-yaml": "^4.1.1",
116171
         "minimatch": "^3.1.2",
117172
         "strip-json-comments": "^3.1.1"
118173
       },
119174
       "engines": {
120
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
175
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
121176
       },
122177
       "funding": {
123178
         "url": "https://opencollective.com/eslint"
124179
       }
125180
     },
126181
     "node_modules/@eslint/js": {
127
-      "version": "8.57.1",
128
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
129
-      "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
182
+      "version": "9.39.2",
183
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz",
184
+      "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==",
130185
       "dev": true,
131186
       "license": "MIT",
132187
       "engines": {
133
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
188
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
189
+      },
190
+      "funding": {
191
+        "url": "https://eslint.org/donate"
134192
       }
135193
     },
136
-    "node_modules/@humanwhocodes/config-array": {
137
-      "version": "0.13.0",
138
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
139
-      "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
140
-      "deprecated": "Use @eslint/config-array instead",
194
+    "node_modules/@eslint/object-schema": {
195
+      "version": "2.1.7",
196
+      "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
197
+      "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
198
+      "dev": true,
199
+      "license": "Apache-2.0",
200
+      "engines": {
201
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
202
+      }
203
+    },
204
+    "node_modules/@eslint/plugin-kit": {
205
+      "version": "0.4.1",
206
+      "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
207
+      "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
141208
       "dev": true,
142209
       "license": "Apache-2.0",
143210
       "dependencies": {
144
-        "@humanwhocodes/object-schema": "^2.0.3",
145
-        "debug": "^4.3.1",
146
-        "minimatch": "^3.0.5"
211
+        "@eslint/core": "^0.17.0",
212
+        "levn": "^0.4.1"
213
+      },
214
+      "engines": {
215
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
216
+      }
217
+    },
218
+    "node_modules/@humanfs/core": {
219
+      "version": "0.19.1",
220
+      "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
221
+      "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
222
+      "dev": true,
223
+      "license": "Apache-2.0",
224
+      "engines": {
225
+        "node": ">=18.18.0"
226
+      }
227
+    },
228
+    "node_modules/@humanfs/node": {
229
+      "version": "0.16.7",
230
+      "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
231
+      "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
232
+      "dev": true,
233
+      "license": "Apache-2.0",
234
+      "dependencies": {
235
+        "@humanfs/core": "^0.19.1",
236
+        "@humanwhocodes/retry": "^0.4.0"
147237
       },
148238
       "engines": {
149
-        "node": ">=10.10.0"
239
+        "node": ">=18.18.0"
150240
       }
151241
     },
152242
     "node_modules/@humanwhocodes/module-importer": {
@@ -163,65 +253,490 @@
163253
         "url": "https://github.com/sponsors/nzakas"
164254
       }
165255
     },
166
-    "node_modules/@humanwhocodes/object-schema": {
167
-      "version": "2.0.3",
168
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
169
-      "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
170
-      "deprecated": "Use @eslint/object-schema instead",
256
+    "node_modules/@humanwhocodes/retry": {
257
+      "version": "0.4.3",
258
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
259
+      "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
171260
       "dev": true,
172
-      "license": "BSD-3-Clause"
261
+      "license": "Apache-2.0",
262
+      "engines": {
263
+        "node": ">=18.18"
264
+      },
265
+      "funding": {
266
+        "type": "github",
267
+        "url": "https://github.com/sponsors/nzakas"
268
+      }
173269
     },
174
-    "node_modules/@isaacs/cliui": {
175
-      "version": "8.0.2",
176
-      "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
177
-      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
178
-      "dev": true,
179
-      "license": "ISC",
180
-      "dependencies": {
181
-        "string-width": "^5.1.2",
182
-        "string-width-cjs": "npm:string-width@^4.2.0",
183
-        "strip-ansi": "^7.0.1",
184
-        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
185
-        "wrap-ansi": "^8.1.0",
186
-        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
270
+    "node_modules/@img/colour": {
271
+      "version": "1.0.0",
272
+      "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz",
273
+      "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==",
274
+      "license": "MIT",
275
+      "optional": true,
276
+      "engines": {
277
+        "node": ">=18"
278
+      }
279
+    },
280
+    "node_modules/@img/sharp-darwin-arm64": {
281
+      "version": "0.34.5",
282
+      "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
283
+      "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
284
+      "cpu": [
285
+        "arm64"
286
+      ],
287
+      "license": "Apache-2.0",
288
+      "optional": true,
289
+      "os": [
290
+        "darwin"
291
+      ],
292
+      "engines": {
293
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
294
+      },
295
+      "funding": {
296
+        "url": "https://opencollective.com/libvips"
187297
       },
298
+      "optionalDependencies": {
299
+        "@img/sharp-libvips-darwin-arm64": "1.2.4"
300
+      }
301
+    },
302
+    "node_modules/@img/sharp-darwin-x64": {
303
+      "version": "0.34.5",
304
+      "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
305
+      "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
306
+      "cpu": [
307
+        "x64"
308
+      ],
309
+      "license": "Apache-2.0",
310
+      "optional": true,
311
+      "os": [
312
+        "darwin"
313
+      ],
188314
       "engines": {
189
-        "node": ">=12"
315
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
316
+      },
317
+      "funding": {
318
+        "url": "https://opencollective.com/libvips"
319
+      },
320
+      "optionalDependencies": {
321
+        "@img/sharp-libvips-darwin-x64": "1.2.4"
190322
       }
191323
     },
192
-    "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
193
-      "version": "6.1.0",
194
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
195
-      "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
196
-      "dev": true,
197
-      "license": "MIT",
324
+    "node_modules/@img/sharp-libvips-darwin-arm64": {
325
+      "version": "1.2.4",
326
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
327
+      "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
328
+      "cpu": [
329
+        "arm64"
330
+      ],
331
+      "license": "LGPL-3.0-or-later",
332
+      "optional": true,
333
+      "os": [
334
+        "darwin"
335
+      ],
336
+      "funding": {
337
+        "url": "https://opencollective.com/libvips"
338
+      }
339
+    },
340
+    "node_modules/@img/sharp-libvips-darwin-x64": {
341
+      "version": "1.2.4",
342
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
343
+      "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
344
+      "cpu": [
345
+        "x64"
346
+      ],
347
+      "license": "LGPL-3.0-or-later",
348
+      "optional": true,
349
+      "os": [
350
+        "darwin"
351
+      ],
352
+      "funding": {
353
+        "url": "https://opencollective.com/libvips"
354
+      }
355
+    },
356
+    "node_modules/@img/sharp-libvips-linux-arm": {
357
+      "version": "1.2.4",
358
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
359
+      "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
360
+      "cpu": [
361
+        "arm"
362
+      ],
363
+      "license": "LGPL-3.0-or-later",
364
+      "optional": true,
365
+      "os": [
366
+        "linux"
367
+      ],
368
+      "funding": {
369
+        "url": "https://opencollective.com/libvips"
370
+      }
371
+    },
372
+    "node_modules/@img/sharp-libvips-linux-arm64": {
373
+      "version": "1.2.4",
374
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
375
+      "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
376
+      "cpu": [
377
+        "arm64"
378
+      ],
379
+      "license": "LGPL-3.0-or-later",
380
+      "optional": true,
381
+      "os": [
382
+        "linux"
383
+      ],
384
+      "funding": {
385
+        "url": "https://opencollective.com/libvips"
386
+      }
387
+    },
388
+    "node_modules/@img/sharp-libvips-linux-ppc64": {
389
+      "version": "1.2.4",
390
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
391
+      "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
392
+      "cpu": [
393
+        "ppc64"
394
+      ],
395
+      "license": "LGPL-3.0-or-later",
396
+      "optional": true,
397
+      "os": [
398
+        "linux"
399
+      ],
400
+      "funding": {
401
+        "url": "https://opencollective.com/libvips"
402
+      }
403
+    },
404
+    "node_modules/@img/sharp-libvips-linux-riscv64": {
405
+      "version": "1.2.4",
406
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
407
+      "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
408
+      "cpu": [
409
+        "riscv64"
410
+      ],
411
+      "license": "LGPL-3.0-or-later",
412
+      "optional": true,
413
+      "os": [
414
+        "linux"
415
+      ],
416
+      "funding": {
417
+        "url": "https://opencollective.com/libvips"
418
+      }
419
+    },
420
+    "node_modules/@img/sharp-libvips-linux-s390x": {
421
+      "version": "1.2.4",
422
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
423
+      "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
424
+      "cpu": [
425
+        "s390x"
426
+      ],
427
+      "license": "LGPL-3.0-or-later",
428
+      "optional": true,
429
+      "os": [
430
+        "linux"
431
+      ],
432
+      "funding": {
433
+        "url": "https://opencollective.com/libvips"
434
+      }
435
+    },
436
+    "node_modules/@img/sharp-libvips-linux-x64": {
437
+      "version": "1.2.4",
438
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
439
+      "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
440
+      "cpu": [
441
+        "x64"
442
+      ],
443
+      "license": "LGPL-3.0-or-later",
444
+      "optional": true,
445
+      "os": [
446
+        "linux"
447
+      ],
448
+      "funding": {
449
+        "url": "https://opencollective.com/libvips"
450
+      }
451
+    },
452
+    "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
453
+      "version": "1.2.4",
454
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
455
+      "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
456
+      "cpu": [
457
+        "arm64"
458
+      ],
459
+      "license": "LGPL-3.0-or-later",
460
+      "optional": true,
461
+      "os": [
462
+        "linux"
463
+      ],
464
+      "funding": {
465
+        "url": "https://opencollective.com/libvips"
466
+      }
467
+    },
468
+    "node_modules/@img/sharp-libvips-linuxmusl-x64": {
469
+      "version": "1.2.4",
470
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
471
+      "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
472
+      "cpu": [
473
+        "x64"
474
+      ],
475
+      "license": "LGPL-3.0-or-later",
476
+      "optional": true,
477
+      "os": [
478
+        "linux"
479
+      ],
480
+      "funding": {
481
+        "url": "https://opencollective.com/libvips"
482
+      }
483
+    },
484
+    "node_modules/@img/sharp-linux-arm": {
485
+      "version": "0.34.5",
486
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
487
+      "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
488
+      "cpu": [
489
+        "arm"
490
+      ],
491
+      "license": "Apache-2.0",
492
+      "optional": true,
493
+      "os": [
494
+        "linux"
495
+      ],
198496
       "engines": {
199
-        "node": ">=12"
497
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
200498
       },
201499
       "funding": {
202
-        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
500
+        "url": "https://opencollective.com/libvips"
501
+      },
502
+      "optionalDependencies": {
503
+        "@img/sharp-libvips-linux-arm": "1.2.4"
203504
       }
204505
     },
205
-    "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
206
-      "version": "7.1.0",
207
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
208
-      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
209
-      "dev": true,
210
-      "license": "MIT",
506
+    "node_modules/@img/sharp-linux-arm64": {
507
+      "version": "0.34.5",
508
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
509
+      "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
510
+      "cpu": [
511
+        "arm64"
512
+      ],
513
+      "license": "Apache-2.0",
514
+      "optional": true,
515
+      "os": [
516
+        "linux"
517
+      ],
518
+      "engines": {
519
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
520
+      },
521
+      "funding": {
522
+        "url": "https://opencollective.com/libvips"
523
+      },
524
+      "optionalDependencies": {
525
+        "@img/sharp-libvips-linux-arm64": "1.2.4"
526
+      }
527
+    },
528
+    "node_modules/@img/sharp-linux-ppc64": {
529
+      "version": "0.34.5",
530
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
531
+      "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
532
+      "cpu": [
533
+        "ppc64"
534
+      ],
535
+      "license": "Apache-2.0",
536
+      "optional": true,
537
+      "os": [
538
+        "linux"
539
+      ],
540
+      "engines": {
541
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
542
+      },
543
+      "funding": {
544
+        "url": "https://opencollective.com/libvips"
545
+      },
546
+      "optionalDependencies": {
547
+        "@img/sharp-libvips-linux-ppc64": "1.2.4"
548
+      }
549
+    },
550
+    "node_modules/@img/sharp-linux-riscv64": {
551
+      "version": "0.34.5",
552
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
553
+      "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
554
+      "cpu": [
555
+        "riscv64"
556
+      ],
557
+      "license": "Apache-2.0",
558
+      "optional": true,
559
+      "os": [
560
+        "linux"
561
+      ],
562
+      "engines": {
563
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
564
+      },
565
+      "funding": {
566
+        "url": "https://opencollective.com/libvips"
567
+      },
568
+      "optionalDependencies": {
569
+        "@img/sharp-libvips-linux-riscv64": "1.2.4"
570
+      }
571
+    },
572
+    "node_modules/@img/sharp-linux-s390x": {
573
+      "version": "0.34.5",
574
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
575
+      "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
576
+      "cpu": [
577
+        "s390x"
578
+      ],
579
+      "license": "Apache-2.0",
580
+      "optional": true,
581
+      "os": [
582
+        "linux"
583
+      ],
584
+      "engines": {
585
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
586
+      },
587
+      "funding": {
588
+        "url": "https://opencollective.com/libvips"
589
+      },
590
+      "optionalDependencies": {
591
+        "@img/sharp-libvips-linux-s390x": "1.2.4"
592
+      }
593
+    },
594
+    "node_modules/@img/sharp-linux-x64": {
595
+      "version": "0.34.5",
596
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
597
+      "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
598
+      "cpu": [
599
+        "x64"
600
+      ],
601
+      "license": "Apache-2.0",
602
+      "optional": true,
603
+      "os": [
604
+        "linux"
605
+      ],
606
+      "engines": {
607
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
608
+      },
609
+      "funding": {
610
+        "url": "https://opencollective.com/libvips"
611
+      },
612
+      "optionalDependencies": {
613
+        "@img/sharp-libvips-linux-x64": "1.2.4"
614
+      }
615
+    },
616
+    "node_modules/@img/sharp-linuxmusl-arm64": {
617
+      "version": "0.34.5",
618
+      "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
619
+      "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
620
+      "cpu": [
621
+        "arm64"
622
+      ],
623
+      "license": "Apache-2.0",
624
+      "optional": true,
625
+      "os": [
626
+        "linux"
627
+      ],
628
+      "engines": {
629
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
630
+      },
631
+      "funding": {
632
+        "url": "https://opencollective.com/libvips"
633
+      },
634
+      "optionalDependencies": {
635
+        "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
636
+      }
637
+    },
638
+    "node_modules/@img/sharp-linuxmusl-x64": {
639
+      "version": "0.34.5",
640
+      "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
641
+      "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
642
+      "cpu": [
643
+        "x64"
644
+      ],
645
+      "license": "Apache-2.0",
646
+      "optional": true,
647
+      "os": [
648
+        "linux"
649
+      ],
650
+      "engines": {
651
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
652
+      },
653
+      "funding": {
654
+        "url": "https://opencollective.com/libvips"
655
+      },
656
+      "optionalDependencies": {
657
+        "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
658
+      }
659
+    },
660
+    "node_modules/@img/sharp-wasm32": {
661
+      "version": "0.34.5",
662
+      "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
663
+      "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
664
+      "cpu": [
665
+        "wasm32"
666
+      ],
667
+      "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
668
+      "optional": true,
211669
       "dependencies": {
212
-        "ansi-regex": "^6.0.1"
670
+        "@emnapi/runtime": "^1.7.0"
213671
       },
214672
       "engines": {
215
-        "node": ">=12"
673
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
674
+      },
675
+      "funding": {
676
+        "url": "https://opencollective.com/libvips"
677
+      }
678
+    },
679
+    "node_modules/@img/sharp-win32-arm64": {
680
+      "version": "0.34.5",
681
+      "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
682
+      "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
683
+      "cpu": [
684
+        "arm64"
685
+      ],
686
+      "license": "Apache-2.0 AND LGPL-3.0-or-later",
687
+      "optional": true,
688
+      "os": [
689
+        "win32"
690
+      ],
691
+      "engines": {
692
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
693
+      },
694
+      "funding": {
695
+        "url": "https://opencollective.com/libvips"
696
+      }
697
+    },
698
+    "node_modules/@img/sharp-win32-ia32": {
699
+      "version": "0.34.5",
700
+      "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
701
+      "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
702
+      "cpu": [
703
+        "ia32"
704
+      ],
705
+      "license": "Apache-2.0 AND LGPL-3.0-or-later",
706
+      "optional": true,
707
+      "os": [
708
+        "win32"
709
+      ],
710
+      "engines": {
711
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
216712
       },
217713
       "funding": {
218
-        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
714
+        "url": "https://opencollective.com/libvips"
715
+      }
716
+    },
717
+    "node_modules/@img/sharp-win32-x64": {
718
+      "version": "0.34.5",
719
+      "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
720
+      "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
721
+      "cpu": [
722
+        "x64"
723
+      ],
724
+      "license": "Apache-2.0 AND LGPL-3.0-or-later",
725
+      "optional": true,
726
+      "os": [
727
+        "win32"
728
+      ],
729
+      "engines": {
730
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
731
+      },
732
+      "funding": {
733
+        "url": "https://opencollective.com/libvips"
219734
       }
220735
     },
221736
     "node_modules/@jridgewell/gen-mapping": {
222
-      "version": "0.3.12",
223
-      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
224
-      "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
737
+      "version": "0.3.13",
738
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
739
+      "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
225740
       "dev": true,
226741
       "license": "MIT",
227742
       "dependencies": {
@@ -240,16 +755,16 @@
240755
       }
241756
     },
242757
     "node_modules/@jridgewell/sourcemap-codec": {
243
-      "version": "1.5.4",
244
-      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
245
-      "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
758
+      "version": "1.5.5",
759
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
760
+      "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
246761
       "dev": true,
247762
       "license": "MIT"
248763
     },
249764
     "node_modules/@jridgewell/trace-mapping": {
250
-      "version": "0.3.29",
251
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
252
-      "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
765
+      "version": "0.3.31",
766
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
767
+      "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
253768
       "dev": true,
254769
       "license": "MIT",
255770
       "dependencies": {
@@ -258,38 +773,38 @@
258773
       }
259774
     },
260775
     "node_modules/@napi-rs/wasm-runtime": {
261
-      "version": "0.2.11",
262
-      "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz",
263
-      "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==",
776
+      "version": "0.2.12",
777
+      "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz",
778
+      "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==",
264779
       "dev": true,
265780
       "license": "MIT",
266781
       "optional": true,
267782
       "dependencies": {
268783
         "@emnapi/core": "^1.4.3",
269784
         "@emnapi/runtime": "^1.4.3",
270
-        "@tybys/wasm-util": "^0.9.0"
785
+        "@tybys/wasm-util": "^0.10.0"
271786
       }
272787
     },
273788
     "node_modules/@next/env": {
274
-      "version": "14.2.30",
275
-      "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.30.tgz",
276
-      "integrity": "sha512-KBiBKrDY6kxTQWGzKjQB7QirL3PiiOkV7KW98leHFjtVRKtft76Ra5qSA/SL75xT44dp6hOcqiiJ6iievLOYug==",
789
+      "version": "15.5.12",
790
+      "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.12.tgz",
791
+      "integrity": "sha512-pUvdJN1on574wQHjaBfNGDt9Mz5utDSZFsIIQkMzPgNS8ZvT4H2mwOrOIClwsQOb6EGx5M76/CZr6G8i6pSpLg==",
277792
       "license": "MIT"
278793
     },
279794
     "node_modules/@next/eslint-plugin-next": {
280
-      "version": "14.2.30",
281
-      "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.30.tgz",
282
-      "integrity": "sha512-mvVsMIutMxQ4NGZEMZ1kiBNc+la8Xmlk30bKUmCPQz2eFkmsLv54Mha8QZarMaCtSPkkFA1TMD+FIZk0l/PpzA==",
795
+      "version": "15.5.12",
796
+      "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.5.12.tgz",
797
+      "integrity": "sha512-+ZRSDFTv4aC96aMb5E41rMjysx8ApkryevnvEYZvPZO52KvkqP5rNExLUXJFr9P4s0f3oqNQR6vopCZsPWKDcQ==",
283798
       "dev": true,
284799
       "license": "MIT",
285800
       "dependencies": {
286
-        "glob": "10.3.10"
801
+        "fast-glob": "3.3.1"
287802
       }
288803
     },
289804
     "node_modules/@next/swc-darwin-arm64": {
290
-      "version": "14.2.30",
291
-      "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.30.tgz",
292
-      "integrity": "sha512-EAqfOTb3bTGh9+ewpO/jC59uACadRHM6TSA9DdxJB/6gxOpyV+zrbqeXiFTDy9uV6bmipFDkfpAskeaDcO+7/g==",
805
+      "version": "15.5.12",
806
+      "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.12.tgz",
807
+      "integrity": "sha512-RnRjBtH8S8eXCpUNkQ+543DUc7ys8y15VxmFU9HRqlo9BG3CcBUiwNtF8SNoi2xvGCVJq1vl2yYq+3oISBS0Zg==",
293808
       "cpu": [
294809
         "arm64"
295810
       ],
@@ -303,9 +818,9 @@
303818
       }
304819
     },
305820
     "node_modules/@next/swc-darwin-x64": {
306
-      "version": "14.2.30",
307
-      "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.30.tgz",
308
-      "integrity": "sha512-TyO7Wz1IKE2kGv8dwQ0bmPL3s44EKVencOqwIY69myoS3rdpO1NPg5xPM5ymKu7nfX4oYJrpMxv8G9iqLsnL4A==",
821
+      "version": "15.5.12",
822
+      "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.12.tgz",
823
+      "integrity": "sha512-nqa9/7iQlboF1EFtNhWxQA0rQstmYRSBGxSM6g3GxvxHxcoeqVXfGNr9stJOme674m2V7r4E3+jEhhGvSQhJRA==",
309824
       "cpu": [
310825
         "x64"
311826
       ],
@@ -319,9 +834,9 @@
319834
       }
320835
     },
321836
     "node_modules/@next/swc-linux-arm64-gnu": {
322
-      "version": "14.2.30",
323
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.30.tgz",
324
-      "integrity": "sha512-I5lg1fgPJ7I5dk6mr3qCH1hJYKJu1FsfKSiTKoYwcuUf53HWTrEkwmMI0t5ojFKeA6Vu+SfT2zVy5NS0QLXV4Q==",
837
+      "version": "15.5.12",
838
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.12.tgz",
839
+      "integrity": "sha512-dCzAjqhDHwmoB2M4eYfVKqXs99QdQxNQVpftvP1eGVppamXh/OkDAwV737Zr0KPXEqRUMN4uCjh6mjO+XtF3Mw==",
325840
       "cpu": [
326841
         "arm64"
327842
       ],
@@ -335,9 +850,9 @@
335850
       }
336851
     },
337852
     "node_modules/@next/swc-linux-arm64-musl": {
338
-      "version": "14.2.30",
339
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.30.tgz",
340
-      "integrity": "sha512-8GkNA+sLclQyxgzCDs2/2GSwBc92QLMrmYAmoP2xehe5MUKBLB2cgo34Yu242L1siSkwQkiV4YLdCnjwc/Micw==",
853
+      "version": "15.5.12",
854
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.12.tgz",
855
+      "integrity": "sha512-+fpGWvQiITgf7PUtbWY1H7qUSnBZsPPLyyq03QuAKpVoTy/QUx1JptEDTQMVvQhvizCEuNLEeghrQUyXQOekuw==",
341856
       "cpu": [
342857
         "arm64"
343858
       ],
@@ -351,9 +866,9 @@
351866
       }
352867
     },
353868
     "node_modules/@next/swc-linux-x64-gnu": {
354
-      "version": "14.2.30",
355
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.30.tgz",
356
-      "integrity": "sha512-8Ly7okjssLuBoe8qaRCcjGtcMsv79hwzn/63wNeIkzJVFVX06h5S737XNr7DZwlsbTBDOyI6qbL2BJB5n6TV/w==",
869
+      "version": "15.5.12",
870
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.12.tgz",
871
+      "integrity": "sha512-jSLvgdRRL/hrFAPqEjJf1fFguC719kmcptjNVDJl26BnJIpjL3KH5h6mzR4mAweociLQaqvt4UyzfbFjgAdDcw==",
357872
       "cpu": [
358873
         "x64"
359874
       ],
@@ -367,9 +882,9 @@
367882
       }
368883
     },
369884
     "node_modules/@next/swc-linux-x64-musl": {
370
-      "version": "14.2.30",
371
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.30.tgz",
372
-      "integrity": "sha512-dBmV1lLNeX4mR7uI7KNVHsGQU+OgTG5RGFPi3tBJpsKPvOPtg9poyav/BYWrB3GPQL4dW5YGGgalwZ79WukbKQ==",
885
+      "version": "15.5.12",
886
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.12.tgz",
887
+      "integrity": "sha512-/uaF0WfmYqQgLfPmN6BvULwxY0dufI2mlN2JbOKqqceZh1G4hjREyi7pg03zjfyS6eqNemHAZPSoP84x17vo6w==",
373888
       "cpu": [
374889
         "x64"
375890
       ],
@@ -383,9 +898,9 @@
383898
       }
384899
     },
385900
     "node_modules/@next/swc-win32-arm64-msvc": {
386
-      "version": "14.2.30",
387
-      "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.30.tgz",
388
-      "integrity": "sha512-6MMHi2Qc1Gkq+4YLXAgbYslE1f9zMGBikKMdmQRHXjkGPot1JY3n5/Qrbg40Uvbi8//wYnydPnyvNhI1DMUW1g==",
901
+      "version": "15.5.12",
902
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.12.tgz",
903
+      "integrity": "sha512-xhsL1OvQSfGmlL5RbOmU+FV120urrgFpYLq+6U8C6KIym32gZT6XF/SDE92jKzzlPWskkbjOKCpqk5m4i8PEfg==",
389904
       "cpu": [
390905
         "arm64"
391906
       ],
@@ -398,26 +913,10 @@
398913
         "node": ">= 10"
399914
       }
400915
     },
401
-    "node_modules/@next/swc-win32-ia32-msvc": {
402
-      "version": "14.2.30",
403
-      "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.30.tgz",
404
-      "integrity": "sha512-pVZMnFok5qEX4RT59mK2hEVtJX+XFfak+/rjHpyFh7juiT52r177bfFKhnlafm0UOSldhXjj32b+LZIOdswGTg==",
405
-      "cpu": [
406
-        "ia32"
407
-      ],
408
-      "license": "MIT",
409
-      "optional": true,
410
-      "os": [
411
-        "win32"
412
-      ],
413
-      "engines": {
414
-        "node": ">= 10"
415
-      }
416
-    },
417916
     "node_modules/@next/swc-win32-x64-msvc": {
418
-      "version": "14.2.30",
419
-      "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.30.tgz",
420
-      "integrity": "sha512-4KCo8hMZXMjpTzs3HOqOGYYwAXymXIy7PEPAXNEcEOyKqkjiDlECumrWziy+JEF0Oi4ILHGxzgQ3YiMGG2t/Lg==",
917
+      "version": "15.5.12",
918
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.12.tgz",
919
+      "integrity": "sha512-Z1Dh6lhFkxvBDH1FoW6OU/L6prYwPSlwjLiZkExIAh8fbP6iI/M7iGTQAJPYJ9YFlWobCZ1PHbchFhFYb2ADkw==",
421920
       "cpu": [
422921
         "x64"
423922
       ],
@@ -478,17 +977,6 @@
478977
         "node": ">=12.4.0"
479978
       }
480979
     },
481
-    "node_modules/@pkgjs/parseargs": {
482
-      "version": "0.11.0",
483
-      "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
484
-      "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
485
-      "dev": true,
486
-      "license": "MIT",
487
-      "optional": true,
488
-      "engines": {
489
-        "node": ">=14"
490
-      }
491
-    },
492980
     "node_modules/@rtsao/scc": {
493981
       "version": "1.1.0",
494982
       "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
@@ -497,32 +985,25 @@
497985
       "license": "MIT"
498986
     },
499987
     "node_modules/@rushstack/eslint-patch": {
500
-      "version": "1.12.0",
501
-      "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.12.0.tgz",
502
-      "integrity": "sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==",
988
+      "version": "1.15.0",
989
+      "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.15.0.tgz",
990
+      "integrity": "sha512-ojSshQPKwVvSMR8yT2L/QtUkV5SXi/IfDiJ4/8d6UbTPjiHVmxZzUAzGD8Tzks1b9+qQkZa0isUOvYObedITaw==",
503991
       "dev": true,
504992
       "license": "MIT"
505993
     },
506
-    "node_modules/@swc/counter": {
507
-      "version": "0.1.3",
508
-      "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
509
-      "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
510
-      "license": "Apache-2.0"
511
-    },
512994
     "node_modules/@swc/helpers": {
513
-      "version": "0.5.5",
514
-      "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz",
515
-      "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==",
995
+      "version": "0.5.15",
996
+      "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
997
+      "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
516998
       "license": "Apache-2.0",
517999
       "dependencies": {
518
-        "@swc/counter": "^0.1.3",
519
-        "tslib": "^2.4.0"
1000
+        "tslib": "^2.8.0"
5201001
       }
5211002
     },
5221003
     "node_modules/@tybys/wasm-util": {
523
-      "version": "0.9.0",
524
-      "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz",
525
-      "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==",
1004
+      "version": "0.10.1",
1005
+      "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
1006
+      "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
5261007
       "dev": true,
5271008
       "license": "MIT",
5281009
       "optional": true,
@@ -530,6 +1011,20 @@
5301011
         "tslib": "^2.4.0"
5311012
       }
5321013
     },
1014
+    "node_modules/@types/estree": {
1015
+      "version": "1.0.8",
1016
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
1017
+      "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
1018
+      "dev": true,
1019
+      "license": "MIT"
1020
+    },
1021
+    "node_modules/@types/json-schema": {
1022
+      "version": "7.0.15",
1023
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
1024
+      "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
1025
+      "dev": true,
1026
+      "license": "MIT"
1027
+    },
5331028
     "node_modules/@types/json5": {
5341029
       "version": "0.0.29",
5351030
       "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@@ -538,9 +1033,9 @@
5381033
       "license": "MIT"
5391034
     },
5401035
     "node_modules/@types/node": {
541
-      "version": "20.19.6",
542
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.6.tgz",
543
-      "integrity": "sha512-uYssdp9z5zH5GQ0L4zEJ2ZuavYsJwkozjiUzCRfGtaaQcyjAMJ34aP8idv61QlqTozu6kudyr6JMq9Chf09dfA==",
1036
+      "version": "20.19.33",
1037
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz",
1038
+      "integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==",
5441039
       "dev": true,
5451040
       "license": "MIT",
5461041
       "dependencies": {
@@ -555,14 +1050,14 @@
5551050
       "license": "MIT"
5561051
     },
5571052
     "node_modules/@types/react": {
558
-      "version": "18.3.23",
559
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
560
-      "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
1053
+      "version": "18.3.28",
1054
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz",
1055
+      "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==",
5611056
       "dev": true,
5621057
       "license": "MIT",
5631058
       "dependencies": {
5641059
         "@types/prop-types": "*",
565
-        "csstype": "^3.0.2"
1060
+        "csstype": "^3.2.2"
5661061
       }
5671062
     },
5681063
     "node_modules/@types/react-dom": {
@@ -576,21 +1071,20 @@
5761071
       }
5771072
     },
5781073
     "node_modules/@typescript-eslint/eslint-plugin": {
579
-      "version": "8.36.0",
580
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.36.0.tgz",
581
-      "integrity": "sha512-lZNihHUVB6ZZiPBNgOQGSxUASI7UJWhT8nHyUGCnaQ28XFCw98IfrMCG3rUl1uwUWoAvodJQby2KTs79UTcrAg==",
1074
+      "version": "8.56.0",
1075
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz",
1076
+      "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==",
5821077
       "dev": true,
5831078
       "license": "MIT",
5841079
       "dependencies": {
585
-        "@eslint-community/regexpp": "^4.10.0",
586
-        "@typescript-eslint/scope-manager": "8.36.0",
587
-        "@typescript-eslint/type-utils": "8.36.0",
588
-        "@typescript-eslint/utils": "8.36.0",
589
-        "@typescript-eslint/visitor-keys": "8.36.0",
590
-        "graphemer": "^1.4.0",
591
-        "ignore": "^7.0.0",
1080
+        "@eslint-community/regexpp": "^4.12.2",
1081
+        "@typescript-eslint/scope-manager": "8.56.0",
1082
+        "@typescript-eslint/type-utils": "8.56.0",
1083
+        "@typescript-eslint/utils": "8.56.0",
1084
+        "@typescript-eslint/visitor-keys": "8.56.0",
1085
+        "ignore": "^7.0.5",
5921086
         "natural-compare": "^1.4.0",
593
-        "ts-api-utils": "^2.1.0"
1087
+        "ts-api-utils": "^2.4.0"
5941088
       },
5951089
       "engines": {
5961090
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -600,9 +1094,9 @@
6001094
         "url": "https://opencollective.com/typescript-eslint"
6011095
       },
6021096
       "peerDependencies": {
603
-        "@typescript-eslint/parser": "^8.36.0",
604
-        "eslint": "^8.57.0 || ^9.0.0",
605
-        "typescript": ">=4.8.4 <5.9.0"
1097
+        "@typescript-eslint/parser": "^8.56.0",
1098
+        "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
1099
+        "typescript": ">=4.8.4 <6.0.0"
6061100
       }
6071101
     },
6081102
     "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
@@ -616,17 +1110,17 @@
6161110
       }
6171111
     },
6181112
     "node_modules/@typescript-eslint/parser": {
619
-      "version": "8.36.0",
620
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.36.0.tgz",
621
-      "integrity": "sha512-FuYgkHwZLuPbZjQHzJXrtXreJdFMKl16BFYyRrLxDhWr6Qr7Kbcu2s1Yhu8tsiMXw1S0W1pjfFfYEt+R604s+Q==",
1113
+      "version": "8.56.0",
1114
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz",
1115
+      "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==",
6221116
       "dev": true,
6231117
       "license": "MIT",
6241118
       "dependencies": {
625
-        "@typescript-eslint/scope-manager": "8.36.0",
626
-        "@typescript-eslint/types": "8.36.0",
627
-        "@typescript-eslint/typescript-estree": "8.36.0",
628
-        "@typescript-eslint/visitor-keys": "8.36.0",
629
-        "debug": "^4.3.4"
1119
+        "@typescript-eslint/scope-manager": "8.56.0",
1120
+        "@typescript-eslint/types": "8.56.0",
1121
+        "@typescript-eslint/typescript-estree": "8.56.0",
1122
+        "@typescript-eslint/visitor-keys": "8.56.0",
1123
+        "debug": "^4.4.3"
6301124
       },
6311125
       "engines": {
6321126
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -636,20 +1130,20 @@
6361130
         "url": "https://opencollective.com/typescript-eslint"
6371131
       },
6381132
       "peerDependencies": {
639
-        "eslint": "^8.57.0 || ^9.0.0",
640
-        "typescript": ">=4.8.4 <5.9.0"
1133
+        "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
1134
+        "typescript": ">=4.8.4 <6.0.0"
6411135
       }
6421136
     },
6431137
     "node_modules/@typescript-eslint/project-service": {
644
-      "version": "8.36.0",
645
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.36.0.tgz",
646
-      "integrity": "sha512-JAhQFIABkWccQYeLMrHadu/fhpzmSQ1F1KXkpzqiVxA/iYI6UnRt2trqXHt1sYEcw1mxLnB9rKMsOxXPxowN/g==",
1138
+      "version": "8.56.0",
1139
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz",
1140
+      "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==",
6471141
       "dev": true,
6481142
       "license": "MIT",
6491143
       "dependencies": {
650
-        "@typescript-eslint/tsconfig-utils": "^8.36.0",
651
-        "@typescript-eslint/types": "^8.36.0",
652
-        "debug": "^4.3.4"
1144
+        "@typescript-eslint/tsconfig-utils": "^8.56.0",
1145
+        "@typescript-eslint/types": "^8.56.0",
1146
+        "debug": "^4.4.3"
6531147
       },
6541148
       "engines": {
6551149
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -659,18 +1153,18 @@
6591153
         "url": "https://opencollective.com/typescript-eslint"
6601154
       },
6611155
       "peerDependencies": {
662
-        "typescript": ">=4.8.4 <5.9.0"
1156
+        "typescript": ">=4.8.4 <6.0.0"
6631157
       }
6641158
     },
6651159
     "node_modules/@typescript-eslint/scope-manager": {
666
-      "version": "8.36.0",
667
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.36.0.tgz",
668
-      "integrity": "sha512-wCnapIKnDkN62fYtTGv2+RY8FlnBYA3tNm0fm91kc2BjPhV2vIjwwozJ7LToaLAyb1ca8BxrS7vT+Pvvf7RvqA==",
1160
+      "version": "8.56.0",
1161
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz",
1162
+      "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==",
6691163
       "dev": true,
6701164
       "license": "MIT",
6711165
       "dependencies": {
672
-        "@typescript-eslint/types": "8.36.0",
673
-        "@typescript-eslint/visitor-keys": "8.36.0"
1166
+        "@typescript-eslint/types": "8.56.0",
1167
+        "@typescript-eslint/visitor-keys": "8.56.0"
6741168
       },
6751169
       "engines": {
6761170
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -681,9 +1175,9 @@
6811175
       }
6821176
     },
6831177
     "node_modules/@typescript-eslint/tsconfig-utils": {
684
-      "version": "8.36.0",
685
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.36.0.tgz",
686
-      "integrity": "sha512-Nhh3TIEgN18mNbdXpd5Q8mSCBnrZQeY9V7Ca3dqYvNDStNIGRmJA6dmrIPMJ0kow3C7gcQbpsG2rPzy1Ks/AnA==",
1178
+      "version": "8.56.0",
1179
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz",
1180
+      "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==",
6871181
       "dev": true,
6881182
       "license": "MIT",
6891183
       "engines": {
@@ -694,20 +1188,21 @@
6941188
         "url": "https://opencollective.com/typescript-eslint"
6951189
       },
6961190
       "peerDependencies": {
697
-        "typescript": ">=4.8.4 <5.9.0"
1191
+        "typescript": ">=4.8.4 <6.0.0"
6981192
       }
6991193
     },
7001194
     "node_modules/@typescript-eslint/type-utils": {
701
-      "version": "8.36.0",
702
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.36.0.tgz",
703
-      "integrity": "sha512-5aaGYG8cVDd6cxfk/ynpYzxBRZJk7w/ymto6uiyUFtdCozQIsQWh7M28/6r57Fwkbweng8qAzoMCPwSJfWlmsg==",
1195
+      "version": "8.56.0",
1196
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz",
1197
+      "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==",
7041198
       "dev": true,
7051199
       "license": "MIT",
7061200
       "dependencies": {
707
-        "@typescript-eslint/typescript-estree": "8.36.0",
708
-        "@typescript-eslint/utils": "8.36.0",
709
-        "debug": "^4.3.4",
710
-        "ts-api-utils": "^2.1.0"
1201
+        "@typescript-eslint/types": "8.56.0",
1202
+        "@typescript-eslint/typescript-estree": "8.56.0",
1203
+        "@typescript-eslint/utils": "8.56.0",
1204
+        "debug": "^4.4.3",
1205
+        "ts-api-utils": "^2.4.0"
7111206
       },
7121207
       "engines": {
7131208
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -717,14 +1212,14 @@
7171212
         "url": "https://opencollective.com/typescript-eslint"
7181213
       },
7191214
       "peerDependencies": {
720
-        "eslint": "^8.57.0 || ^9.0.0",
721
-        "typescript": ">=4.8.4 <5.9.0"
1215
+        "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
1216
+        "typescript": ">=4.8.4 <6.0.0"
7221217
       }
7231218
     },
7241219
     "node_modules/@typescript-eslint/types": {
725
-      "version": "8.36.0",
726
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.36.0.tgz",
727
-      "integrity": "sha512-xGms6l5cTJKQPZOKM75Dl9yBfNdGeLRsIyufewnxT4vZTrjC0ImQT4fj8QmtJK84F58uSh5HVBSANwcfiXxABQ==",
1220
+      "version": "8.56.0",
1221
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz",
1222
+      "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==",
7281223
       "dev": true,
7291224
       "license": "MIT",
7301225
       "engines": {
@@ -736,22 +1231,21 @@
7361231
       }
7371232
     },
7381233
     "node_modules/@typescript-eslint/typescript-estree": {
739
-      "version": "8.36.0",
740
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.36.0.tgz",
741
-      "integrity": "sha512-JaS8bDVrfVJX4av0jLpe4ye0BpAaUW7+tnS4Y4ETa3q7NoZgzYbN9zDQTJ8kPb5fQ4n0hliAt9tA4Pfs2zA2Hg==",
1234
+      "version": "8.56.0",
1235
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz",
1236
+      "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==",
7421237
       "dev": true,
7431238
       "license": "MIT",
7441239
       "dependencies": {
745
-        "@typescript-eslint/project-service": "8.36.0",
746
-        "@typescript-eslint/tsconfig-utils": "8.36.0",
747
-        "@typescript-eslint/types": "8.36.0",
748
-        "@typescript-eslint/visitor-keys": "8.36.0",
749
-        "debug": "^4.3.4",
750
-        "fast-glob": "^3.3.2",
751
-        "is-glob": "^4.0.3",
752
-        "minimatch": "^9.0.4",
753
-        "semver": "^7.6.0",
754
-        "ts-api-utils": "^2.1.0"
1240
+        "@typescript-eslint/project-service": "8.56.0",
1241
+        "@typescript-eslint/tsconfig-utils": "8.56.0",
1242
+        "@typescript-eslint/types": "8.56.0",
1243
+        "@typescript-eslint/visitor-keys": "8.56.0",
1244
+        "debug": "^4.4.3",
1245
+        "minimatch": "^9.0.5",
1246
+        "semver": "^7.7.3",
1247
+        "tinyglobby": "^0.2.15",
1248
+        "ts-api-utils": "^2.4.0"
7551249
       },
7561250
       "engines": {
7571251
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -761,7 +1255,7 @@
7611255
         "url": "https://opencollective.com/typescript-eslint"
7621256
       },
7631257
       "peerDependencies": {
764
-        "typescript": ">=4.8.4 <5.9.0"
1258
+        "typescript": ">=4.8.4 <6.0.0"
7651259
       }
7661260
     },
7671261
     "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
@@ -791,16 +1285,16 @@
7911285
       }
7921286
     },
7931287
     "node_modules/@typescript-eslint/utils": {
794
-      "version": "8.36.0",
795
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.36.0.tgz",
796
-      "integrity": "sha512-VOqmHu42aEMT+P2qYjylw6zP/3E/HvptRwdn/PZxyV27KhZg2IOszXod4NcXisWzPAGSS4trE/g4moNj6XmH2g==",
1288
+      "version": "8.56.0",
1289
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz",
1290
+      "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==",
7971291
       "dev": true,
7981292
       "license": "MIT",
7991293
       "dependencies": {
800
-        "@eslint-community/eslint-utils": "^4.7.0",
801
-        "@typescript-eslint/scope-manager": "8.36.0",
802
-        "@typescript-eslint/types": "8.36.0",
803
-        "@typescript-eslint/typescript-estree": "8.36.0"
1294
+        "@eslint-community/eslint-utils": "^4.9.1",
1295
+        "@typescript-eslint/scope-manager": "8.56.0",
1296
+        "@typescript-eslint/types": "8.56.0",
1297
+        "@typescript-eslint/typescript-estree": "8.56.0"
8041298
       },
8051299
       "engines": {
8061300
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -810,19 +1304,19 @@
8101304
         "url": "https://opencollective.com/typescript-eslint"
8111305
       },
8121306
       "peerDependencies": {
813
-        "eslint": "^8.57.0 || ^9.0.0",
814
-        "typescript": ">=4.8.4 <5.9.0"
1307
+        "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
1308
+        "typescript": ">=4.8.4 <6.0.0"
8151309
       }
8161310
     },
8171311
     "node_modules/@typescript-eslint/visitor-keys": {
818
-      "version": "8.36.0",
819
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.36.0.tgz",
820
-      "integrity": "sha512-vZrhV2lRPWDuGoxcmrzRZyxAggPL+qp3WzUrlZD+slFueDiYHxeBa34dUXPuC0RmGKzl4lS5kFJYvKCq9cnNDA==",
1312
+      "version": "8.56.0",
1313
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz",
1314
+      "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==",
8211315
       "dev": true,
8221316
       "license": "MIT",
8231317
       "dependencies": {
824
-        "@typescript-eslint/types": "8.36.0",
825
-        "eslint-visitor-keys": "^4.2.1"
1318
+        "@typescript-eslint/types": "8.56.0",
1319
+        "eslint-visitor-keys": "^5.0.0"
8261320
       },
8271321
       "engines": {
8281322
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -833,25 +1327,18 @@
8331327
       }
8341328
     },
8351329
     "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
836
-      "version": "4.2.1",
837
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
838
-      "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
1330
+      "version": "5.0.0",
1331
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz",
1332
+      "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==",
8391333
       "dev": true,
8401334
       "license": "Apache-2.0",
8411335
       "engines": {
842
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1336
+        "node": "^20.19.0 || ^22.13.0 || >=24"
8431337
       },
8441338
       "funding": {
8451339
         "url": "https://opencollective.com/eslint"
8461340
       }
8471341
     },
848
-    "node_modules/@ungap/structured-clone": {
849
-      "version": "1.3.0",
850
-      "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
851
-      "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
852
-      "dev": true,
853
-      "license": "ISC"
854
-    },
8551342
     "node_modules/@unrs/resolver-binding-android-arm-eabi": {
8561343
       "version": "1.11.1",
8571344
       "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz",
@@ -1121,6 +1608,44 @@
11211608
         "win32"
11221609
       ]
11231610
     },
1611
+    "node_modules/@vercel/analytics": {
1612
+      "version": "1.6.1",
1613
+      "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.6.1.tgz",
1614
+      "integrity": "sha512-oH9He/bEM+6oKlv3chWuOOcp8Y6fo6/PSro8hEkgCW3pu9/OiCXiUpRUogDh3Fs3LH2sosDrx8CxeOLBEE+afg==",
1615
+      "license": "MPL-2.0",
1616
+      "peerDependencies": {
1617
+        "@remix-run/react": "^2",
1618
+        "@sveltejs/kit": "^1 || ^2",
1619
+        "next": ">= 13",
1620
+        "react": "^18 || ^19 || ^19.0.0-rc",
1621
+        "svelte": ">= 4",
1622
+        "vue": "^3",
1623
+        "vue-router": "^4"
1624
+      },
1625
+      "peerDependenciesMeta": {
1626
+        "@remix-run/react": {
1627
+          "optional": true
1628
+        },
1629
+        "@sveltejs/kit": {
1630
+          "optional": true
1631
+        },
1632
+        "next": {
1633
+          "optional": true
1634
+        },
1635
+        "react": {
1636
+          "optional": true
1637
+        },
1638
+        "svelte": {
1639
+          "optional": true
1640
+        },
1641
+        "vue": {
1642
+          "optional": true
1643
+        },
1644
+        "vue-router": {
1645
+          "optional": true
1646
+        }
1647
+      }
1648
+    },
11241649
     "node_modules/acorn": {
11251650
       "version": "8.15.0",
11261651
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
@@ -1161,16 +1686,6 @@
11611686
         "url": "https://github.com/sponsors/epoberezkin"
11621687
       }
11631688
     },
1164
-    "node_modules/ansi-regex": {
1165
-      "version": "5.0.1",
1166
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1167
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1168
-      "dev": true,
1169
-      "license": "MIT",
1170
-      "engines": {
1171
-        "node": ">=8"
1172
-      }
1173
-    },
11741689
     "node_modules/ansi-styles": {
11751690
       "version": "4.3.0",
11761691
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -1426,9 +1941,9 @@
14261941
       }
14271942
     },
14281943
     "node_modules/axe-core": {
1429
-      "version": "4.10.3",
1430
-      "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz",
1431
-      "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==",
1944
+      "version": "4.11.1",
1945
+      "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.1.tgz",
1946
+      "integrity": "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==",
14321947
       "dev": true,
14331948
       "license": "MPL-2.0",
14341949
       "engines": {
@@ -1489,17 +2004,6 @@
14892004
         "node": ">=8"
14902005
       }
14912006
     },
1492
-    "node_modules/busboy": {
1493
-      "version": "1.6.0",
1494
-      "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
1495
-      "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
1496
-      "dependencies": {
1497
-        "streamsearch": "^1.1.0"
1498
-      },
1499
-      "engines": {
1500
-        "node": ">=10.16.0"
1501
-      }
1502
-    },
15032007
     "node_modules/call-bind": {
15042008
       "version": "1.0.8",
15052009
       "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
@@ -1571,9 +2075,9 @@
15712075
       }
15722076
     },
15732077
     "node_modules/caniuse-lite": {
1574
-      "version": "1.0.30001727",
1575
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz",
1576
-      "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==",
2078
+      "version": "1.0.30001770",
2079
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz",
2080
+      "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==",
15772081
       "funding": [
15782082
         {
15792083
           "type": "opencollective",
@@ -1717,9 +2221,9 @@
17172221
       }
17182222
     },
17192223
     "node_modules/csstype": {
1720
-      "version": "3.1.3",
1721
-      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
1722
-      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
2224
+      "version": "3.2.3",
2225
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
2226
+      "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
17232227
       "dev": true,
17242228
       "license": "MIT"
17252229
     },
@@ -1785,9 +2289,9 @@
17852289
       }
17862290
     },
17872291
     "node_modules/debug": {
1788
-      "version": "4.4.1",
1789
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
1790
-      "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
2292
+      "version": "4.4.3",
2293
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
2294
+      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
17912295
       "dev": true,
17922296
       "license": "MIT",
17932297
       "dependencies": {
@@ -1845,6 +2349,16 @@
18452349
         "url": "https://github.com/sponsors/ljharb"
18462350
       }
18472351
     },
2352
+    "node_modules/detect-libc": {
2353
+      "version": "2.1.2",
2354
+      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
2355
+      "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
2356
+      "license": "Apache-2.0",
2357
+      "optional": true,
2358
+      "engines": {
2359
+        "node": ">=8"
2360
+      }
2361
+    },
18482362
     "node_modules/didyoumean": {
18492363
       "version": "1.2.2",
18502364
       "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
@@ -1860,16 +2374,16 @@
18602374
       "license": "MIT"
18612375
     },
18622376
     "node_modules/doctrine": {
1863
-      "version": "3.0.0",
1864
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
1865
-      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
2377
+      "version": "2.1.0",
2378
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
2379
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
18662380
       "dev": true,
18672381
       "license": "Apache-2.0",
18682382
       "dependencies": {
18692383
         "esutils": "^2.0.2"
18702384
       },
18712385
       "engines": {
1872
-        "node": ">=6.0.0"
2386
+        "node": ">=0.10.0"
18732387
       }
18742388
     },
18752389
     "node_modules/dunder-proto": {
@@ -1887,13 +2401,6 @@
18872401
         "node": ">= 0.4"
18882402
       }
18892403
     },
1890
-    "node_modules/eastasianwidth": {
1891
-      "version": "0.2.0",
1892
-      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
1893
-      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
1894
-      "dev": true,
1895
-      "license": "MIT"
1896
-    },
18972404
     "node_modules/emoji-regex": {
18982405
       "version": "9.2.2",
18992406
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
@@ -1902,9 +2409,9 @@
19022409
       "license": "MIT"
19032410
     },
19042411
     "node_modules/es-abstract": {
1905
-      "version": "1.24.0",
1906
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz",
1907
-      "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==",
2412
+      "version": "1.24.1",
2413
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz",
2414
+      "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==",
19082415
       "dev": true,
19092416
       "license": "MIT",
19102417
       "dependencies": {
@@ -1991,27 +2498,27 @@
19912498
       }
19922499
     },
19932500
     "node_modules/es-iterator-helpers": {
1994
-      "version": "1.2.1",
1995
-      "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz",
1996
-      "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==",
2501
+      "version": "1.2.2",
2502
+      "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz",
2503
+      "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==",
19972504
       "dev": true,
19982505
       "license": "MIT",
19992506
       "dependencies": {
20002507
         "call-bind": "^1.0.8",
2001
-        "call-bound": "^1.0.3",
2508
+        "call-bound": "^1.0.4",
20022509
         "define-properties": "^1.2.1",
2003
-        "es-abstract": "^1.23.6",
2510
+        "es-abstract": "^1.24.1",
20042511
         "es-errors": "^1.3.0",
2005
-        "es-set-tostringtag": "^2.0.3",
2512
+        "es-set-tostringtag": "^2.1.0",
20062513
         "function-bind": "^1.1.2",
2007
-        "get-intrinsic": "^1.2.6",
2514
+        "get-intrinsic": "^1.3.0",
20082515
         "globalthis": "^1.0.4",
20092516
         "gopd": "^1.2.0",
20102517
         "has-property-descriptors": "^1.0.2",
20112518
         "has-proto": "^1.2.0",
20122519
         "has-symbols": "^1.1.0",
20132520
         "internal-slot": "^1.1.0",
2014
-        "iterator.prototype": "^1.1.4",
2521
+        "iterator.prototype": "^1.1.5",
20152522
         "safe-array-concat": "^1.1.3"
20162523
       },
20172524
       "engines": {
@@ -2092,82 +2599,85 @@
20922599
       }
20932600
     },
20942601
     "node_modules/eslint": {
2095
-      "version": "8.57.1",
2096
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
2097
-      "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
2098
-      "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
2602
+      "version": "9.39.2",
2603
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
2604
+      "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
20992605
       "dev": true,
21002606
       "license": "MIT",
21012607
       "dependencies": {
2102
-        "@eslint-community/eslint-utils": "^4.2.0",
2103
-        "@eslint-community/regexpp": "^4.6.1",
2104
-        "@eslint/eslintrc": "^2.1.4",
2105
-        "@eslint/js": "8.57.1",
2106
-        "@humanwhocodes/config-array": "^0.13.0",
2608
+        "@eslint-community/eslint-utils": "^4.8.0",
2609
+        "@eslint-community/regexpp": "^4.12.1",
2610
+        "@eslint/config-array": "^0.21.1",
2611
+        "@eslint/config-helpers": "^0.4.2",
2612
+        "@eslint/core": "^0.17.0",
2613
+        "@eslint/eslintrc": "^3.3.1",
2614
+        "@eslint/js": "9.39.2",
2615
+        "@eslint/plugin-kit": "^0.4.1",
2616
+        "@humanfs/node": "^0.16.6",
21072617
         "@humanwhocodes/module-importer": "^1.0.1",
2108
-        "@nodelib/fs.walk": "^1.2.8",
2109
-        "@ungap/structured-clone": "^1.2.0",
2618
+        "@humanwhocodes/retry": "^0.4.2",
2619
+        "@types/estree": "^1.0.6",
21102620
         "ajv": "^6.12.4",
21112621
         "chalk": "^4.0.0",
2112
-        "cross-spawn": "^7.0.2",
2622
+        "cross-spawn": "^7.0.6",
21132623
         "debug": "^4.3.2",
2114
-        "doctrine": "^3.0.0",
21152624
         "escape-string-regexp": "^4.0.0",
2116
-        "eslint-scope": "^7.2.2",
2117
-        "eslint-visitor-keys": "^3.4.3",
2118
-        "espree": "^9.6.1",
2119
-        "esquery": "^1.4.2",
2625
+        "eslint-scope": "^8.4.0",
2626
+        "eslint-visitor-keys": "^4.2.1",
2627
+        "espree": "^10.4.0",
2628
+        "esquery": "^1.5.0",
21202629
         "esutils": "^2.0.2",
21212630
         "fast-deep-equal": "^3.1.3",
2122
-        "file-entry-cache": "^6.0.1",
2631
+        "file-entry-cache": "^8.0.0",
21232632
         "find-up": "^5.0.0",
21242633
         "glob-parent": "^6.0.2",
2125
-        "globals": "^13.19.0",
2126
-        "graphemer": "^1.4.0",
21272634
         "ignore": "^5.2.0",
21282635
         "imurmurhash": "^0.1.4",
21292636
         "is-glob": "^4.0.0",
2130
-        "is-path-inside": "^3.0.3",
2131
-        "js-yaml": "^4.1.0",
21322637
         "json-stable-stringify-without-jsonify": "^1.0.1",
2133
-        "levn": "^0.4.1",
21342638
         "lodash.merge": "^4.6.2",
21352639
         "minimatch": "^3.1.2",
21362640
         "natural-compare": "^1.4.0",
2137
-        "optionator": "^0.9.3",
2138
-        "strip-ansi": "^6.0.1",
2139
-        "text-table": "^0.2.0"
2641
+        "optionator": "^0.9.3"
21402642
       },
21412643
       "bin": {
21422644
         "eslint": "bin/eslint.js"
21432645
       },
21442646
       "engines": {
2145
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
2647
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
21462648
       },
21472649
       "funding": {
2148
-        "url": "https://opencollective.com/eslint"
2650
+        "url": "https://eslint.org/donate"
2651
+      },
2652
+      "peerDependencies": {
2653
+        "jiti": "*"
2654
+      },
2655
+      "peerDependenciesMeta": {
2656
+        "jiti": {
2657
+          "optional": true
2658
+        }
21492659
       }
21502660
     },
21512661
     "node_modules/eslint-config-next": {
2152
-      "version": "14.2.30",
2153
-      "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.30.tgz",
2154
-      "integrity": "sha512-4pTMb3wfpI+piVeEz3TWG1spjuXJJBZaYabi2H08z2ZTk6/N304POEovHdFmK6EZb4QlKpETulBNaRIITA0+xg==",
2662
+      "version": "15.5.12",
2663
+      "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.5.12.tgz",
2664
+      "integrity": "sha512-ktW3XLfd+ztEltY5scJNjxjHwtKWk6vU2iwzZqSN09UsbBmMeE/cVlJ1yESg6Yx5LW7p/Z8WzUAgYXGLEmGIpg==",
21552665
       "dev": true,
21562666
       "license": "MIT",
21572667
       "dependencies": {
2158
-        "@next/eslint-plugin-next": "14.2.30",
2159
-        "@rushstack/eslint-patch": "^1.3.3",
2668
+        "@next/eslint-plugin-next": "15.5.12",
2669
+        "@rushstack/eslint-patch": "^1.10.3",
21602670
         "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0",
21612671
         "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0",
21622672
         "eslint-import-resolver-node": "^0.3.6",
21632673
         "eslint-import-resolver-typescript": "^3.5.2",
2164
-        "eslint-plugin-import": "^2.28.1",
2165
-        "eslint-plugin-jsx-a11y": "^6.7.1",
2166
-        "eslint-plugin-react": "^7.33.2",
2167
-        "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705"
2674
+        "eslint-plugin-import": "^2.31.0",
2675
+        "eslint-plugin-jsx-a11y": "^6.10.0",
2676
+        "eslint-plugin-react": "^7.37.0",
2677
+        "eslint-plugin-react-hooks": "^5.0.0"
21682678
       },
21692679
       "peerDependencies": {
2170
-        "eslint": "^7.23.0 || ^8.0.0",
2680
+        "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0",
21712681
         "typescript": ">=3.3.1"
21722682
       },
21732683
       "peerDependenciesMeta": {
@@ -2305,19 +2815,6 @@
23052815
         "ms": "^2.1.1"
23062816
       }
23072817
     },
2308
-    "node_modules/eslint-plugin-import/node_modules/doctrine": {
2309
-      "version": "2.1.0",
2310
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
2311
-      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
2312
-      "dev": true,
2313
-      "license": "Apache-2.0",
2314
-      "dependencies": {
2315
-        "esutils": "^2.0.2"
2316
-      },
2317
-      "engines": {
2318
-        "node": ">=0.10.0"
2319
-      }
2320
-    },
23212818
     "node_modules/eslint-plugin-import/node_modules/semver": {
23222819
       "version": "6.3.1",
23232820
       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -2392,45 +2889,38 @@
23922889
       }
23932890
     },
23942891
     "node_modules/eslint-plugin-react-hooks": {
2395
-      "version": "5.0.0-canary-7118f5dd7-20230705",
2396
-      "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz",
2397
-      "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==",
2892
+      "version": "5.2.0",
2893
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
2894
+      "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
23982895
       "dev": true,
23992896
       "license": "MIT",
24002897
       "engines": {
24012898
         "node": ">=10"
24022899
       },
24032900
       "peerDependencies": {
2404
-        "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
2405
-      }
2406
-    },
2407
-    "node_modules/eslint-plugin-react/node_modules/doctrine": {
2408
-      "version": "2.1.0",
2409
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
2410
-      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
2411
-      "dev": true,
2412
-      "license": "Apache-2.0",
2413
-      "dependencies": {
2414
-        "esutils": "^2.0.2"
2415
-      },
2416
-      "engines": {
2417
-        "node": ">=0.10.0"
2901
+        "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
24182902
       }
24192903
     },
24202904
     "node_modules/eslint-plugin-react/node_modules/resolve": {
2421
-      "version": "2.0.0-next.5",
2422
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
2423
-      "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==",
2905
+      "version": "2.0.0-next.6",
2906
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz",
2907
+      "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==",
24242908
       "dev": true,
24252909
       "license": "MIT",
24262910
       "dependencies": {
2427
-        "is-core-module": "^2.13.0",
2911
+        "es-errors": "^1.3.0",
2912
+        "is-core-module": "^2.16.1",
2913
+        "node-exports-info": "^1.6.0",
2914
+        "object-keys": "^1.1.1",
24282915
         "path-parse": "^1.0.7",
24292916
         "supports-preserve-symlinks-flag": "^1.0.0"
24302917
       },
24312918
       "bin": {
24322919
         "resolve": "bin/resolve"
24332920
       },
2921
+      "engines": {
2922
+        "node": ">= 0.4"
2923
+      },
24342924
       "funding": {
24352925
         "url": "https://github.com/sponsors/ljharb"
24362926
       }
@@ -2446,9 +2936,9 @@
24462936
       }
24472937
     },
24482938
     "node_modules/eslint-scope": {
2449
-      "version": "7.2.2",
2450
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
2451
-      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
2939
+      "version": "8.4.0",
2940
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
2941
+      "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
24522942
       "dev": true,
24532943
       "license": "BSD-2-Clause",
24542944
       "dependencies": {
@@ -2456,47 +2946,47 @@
24562946
         "estraverse": "^5.2.0"
24572947
       },
24582948
       "engines": {
2459
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
2949
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
24602950
       },
24612951
       "funding": {
24622952
         "url": "https://opencollective.com/eslint"
24632953
       }
24642954
     },
24652955
     "node_modules/eslint-visitor-keys": {
2466
-      "version": "3.4.3",
2467
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
2468
-      "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
2956
+      "version": "4.2.1",
2957
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
2958
+      "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
24692959
       "dev": true,
24702960
       "license": "Apache-2.0",
24712961
       "engines": {
2472
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
2962
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
24732963
       },
24742964
       "funding": {
24752965
         "url": "https://opencollective.com/eslint"
24762966
       }
24772967
     },
24782968
     "node_modules/espree": {
2479
-      "version": "9.6.1",
2480
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
2481
-      "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
2969
+      "version": "10.4.0",
2970
+      "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
2971
+      "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
24822972
       "dev": true,
24832973
       "license": "BSD-2-Clause",
24842974
       "dependencies": {
2485
-        "acorn": "^8.9.0",
2975
+        "acorn": "^8.15.0",
24862976
         "acorn-jsx": "^5.3.2",
2487
-        "eslint-visitor-keys": "^3.4.1"
2977
+        "eslint-visitor-keys": "^4.2.1"
24882978
       },
24892979
       "engines": {
2490
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
2980
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
24912981
       },
24922982
       "funding": {
24932983
         "url": "https://opencollective.com/eslint"
24942984
       }
24952985
     },
24962986
     "node_modules/esquery": {
2497
-      "version": "1.6.0",
2498
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
2499
-      "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
2987
+      "version": "1.7.0",
2988
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
2989
+      "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
25002990
       "dev": true,
25012991
       "license": "BSD-3-Clause",
25022992
       "dependencies": {
@@ -2547,9 +3037,9 @@
25473037
       "license": "MIT"
25483038
     },
25493039
     "node_modules/fast-glob": {
2550
-      "version": "3.3.3",
2551
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
2552
-      "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
3040
+      "version": "3.3.1",
3041
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
3042
+      "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
25533043
       "dev": true,
25543044
       "license": "MIT",
25553045
       "dependencies": {
@@ -2557,7 +3047,7 @@
25573047
         "@nodelib/fs.walk": "^1.2.3",
25583048
         "glob-parent": "^5.1.2",
25593049
         "merge2": "^1.3.0",
2560
-        "micromatch": "^4.0.8"
3050
+        "micromatch": "^4.0.4"
25613051
       },
25623052
       "engines": {
25633053
         "node": ">=8.6.0"
@@ -2591,9 +3081,9 @@
25913081
       "license": "MIT"
25923082
     },
25933083
     "node_modules/fastq": {
2594
-      "version": "1.19.1",
2595
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
2596
-      "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
3084
+      "version": "1.20.1",
3085
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
3086
+      "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
25973087
       "dev": true,
25983088
       "license": "ISC",
25993089
       "dependencies": {
@@ -2601,16 +3091,16 @@
26013091
       }
26023092
     },
26033093
     "node_modules/file-entry-cache": {
2604
-      "version": "6.0.1",
2605
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
2606
-      "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
3094
+      "version": "8.0.0",
3095
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
3096
+      "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
26073097
       "dev": true,
26083098
       "license": "MIT",
26093099
       "dependencies": {
2610
-        "flat-cache": "^3.0.4"
3100
+        "flat-cache": "^4.0.0"
26113101
       },
26123102
       "engines": {
2613
-        "node": "^10.12.0 || >=12.0.0"
3103
+        "node": ">=16.0.0"
26143104
       }
26153105
     },
26163106
     "node_modules/fill-range": {
@@ -2644,18 +3134,17 @@
26443134
       }
26453135
     },
26463136
     "node_modules/flat-cache": {
2647
-      "version": "3.2.0",
2648
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
2649
-      "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
3137
+      "version": "4.0.1",
3138
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
3139
+      "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
26503140
       "dev": true,
26513141
       "license": "MIT",
26523142
       "dependencies": {
26533143
         "flatted": "^3.2.9",
2654
-        "keyv": "^4.5.3",
2655
-        "rimraf": "^3.0.2"
3144
+        "keyv": "^4.5.4"
26563145
       },
26573146
       "engines": {
2658
-        "node": "^10.12.0 || >=12.0.0"
3147
+        "node": ">=16"
26593148
       }
26603149
     },
26613150
     "node_modules/flatted": {
@@ -2681,30 +3170,6 @@
26813170
         "url": "https://github.com/sponsors/ljharb"
26823171
       }
26833172
     },
2684
-    "node_modules/foreground-child": {
2685
-      "version": "3.3.1",
2686
-      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
2687
-      "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
2688
-      "dev": true,
2689
-      "license": "ISC",
2690
-      "dependencies": {
2691
-        "cross-spawn": "^7.0.6",
2692
-        "signal-exit": "^4.0.1"
2693
-      },
2694
-      "engines": {
2695
-        "node": ">=14"
2696
-      },
2697
-      "funding": {
2698
-        "url": "https://github.com/sponsors/isaacs"
2699
-      }
2700
-    },
2701
-    "node_modules/fs.realpath": {
2702
-      "version": "1.0.0",
2703
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
2704
-      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
2705
-      "dev": true,
2706
-      "license": "ISC"
2707
-    },
27083173
     "node_modules/fsevents": {
27093174
       "version": "2.3.3",
27103175
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -2761,6 +3226,16 @@
27613226
         "url": "https://github.com/sponsors/ljharb"
27623227
       }
27633228
     },
3229
+    "node_modules/generator-function": {
3230
+      "version": "2.0.1",
3231
+      "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
3232
+      "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
3233
+      "dev": true,
3234
+      "license": "MIT",
3235
+      "engines": {
3236
+        "node": ">= 0.4"
3237
+      }
3238
+    },
27643239
     "node_modules/get-intrinsic": {
27653240
       "version": "1.3.0",
27663241
       "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
@@ -2819,9 +3294,9 @@
28193294
       }
28203295
     },
28213296
     "node_modules/get-tsconfig": {
2822
-      "version": "4.10.1",
2823
-      "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
2824
-      "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
3297
+      "version": "4.13.6",
3298
+      "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz",
3299
+      "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==",
28253300
       "dev": true,
28263301
       "license": "MIT",
28273302
       "dependencies": {
@@ -2831,29 +3306,6 @@
28313306
         "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
28323307
       }
28333308
     },
2834
-    "node_modules/glob": {
2835
-      "version": "10.3.10",
2836
-      "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
2837
-      "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
2838
-      "dev": true,
2839
-      "license": "ISC",
2840
-      "dependencies": {
2841
-        "foreground-child": "^3.1.0",
2842
-        "jackspeak": "^2.3.5",
2843
-        "minimatch": "^9.0.1",
2844
-        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
2845
-        "path-scurry": "^1.10.1"
2846
-      },
2847
-      "bin": {
2848
-        "glob": "dist/esm/bin.mjs"
2849
-      },
2850
-      "engines": {
2851
-        "node": ">=16 || 14 >=14.17"
2852
-      },
2853
-      "funding": {
2854
-        "url": "https://github.com/sponsors/isaacs"
2855
-      }
2856
-    },
28573309
     "node_modules/glob-parent": {
28583310
       "version": "6.0.2",
28593311
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -2867,43 +3319,14 @@
28673319
         "node": ">=10.13.0"
28683320
       }
28693321
     },
2870
-    "node_modules/glob/node_modules/brace-expansion": {
2871
-      "version": "2.0.2",
2872
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
2873
-      "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
2874
-      "dev": true,
2875
-      "license": "MIT",
2876
-      "dependencies": {
2877
-        "balanced-match": "^1.0.0"
2878
-      }
2879
-    },
2880
-    "node_modules/glob/node_modules/minimatch": {
2881
-      "version": "9.0.5",
2882
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
2883
-      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
2884
-      "dev": true,
2885
-      "license": "ISC",
2886
-      "dependencies": {
2887
-        "brace-expansion": "^2.0.1"
2888
-      },
2889
-      "engines": {
2890
-        "node": ">=16 || 14 >=14.17"
2891
-      },
2892
-      "funding": {
2893
-        "url": "https://github.com/sponsors/isaacs"
2894
-      }
2895
-    },
28963322
     "node_modules/globals": {
2897
-      "version": "13.24.0",
2898
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
2899
-      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
3323
+      "version": "14.0.0",
3324
+      "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
3325
+      "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
29003326
       "dev": true,
29013327
       "license": "MIT",
2902
-      "dependencies": {
2903
-        "type-fest": "^0.20.2"
2904
-      },
29053328
       "engines": {
2906
-        "node": ">=8"
3329
+        "node": ">=18"
29073330
       },
29083331
       "funding": {
29093332
         "url": "https://github.com/sponsors/sindresorhus"
@@ -2939,19 +3362,6 @@
29393362
         "url": "https://github.com/sponsors/ljharb"
29403363
       }
29413364
     },
2942
-    "node_modules/graceful-fs": {
2943
-      "version": "4.2.11",
2944
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
2945
-      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
2946
-      "license": "ISC"
2947
-    },
2948
-    "node_modules/graphemer": {
2949
-      "version": "1.4.0",
2950
-      "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
2951
-      "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
2952
-      "dev": true,
2953
-      "license": "MIT"
2954
-    },
29553365
     "node_modules/has-bigints": {
29563366
       "version": "1.1.0",
29573367
       "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
@@ -3083,25 +3493,6 @@
30833493
         "node": ">=0.8.19"
30843494
       }
30853495
     },
3086
-    "node_modules/inflight": {
3087
-      "version": "1.0.6",
3088
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
3089
-      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
3090
-      "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
3091
-      "dev": true,
3092
-      "license": "ISC",
3093
-      "dependencies": {
3094
-        "once": "^1.3.0",
3095
-        "wrappy": "1"
3096
-      }
3097
-    },
3098
-    "node_modules/inherits": {
3099
-      "version": "2.0.4",
3100
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
3101
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
3102
-      "dev": true,
3103
-      "license": "ISC"
3104
-    },
31053496
     "node_modules/internal-slot": {
31063497
       "version": "1.1.0",
31073498
       "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
@@ -3301,25 +3692,16 @@
33013692
         "url": "https://github.com/sponsors/ljharb"
33023693
       }
33033694
     },
3304
-    "node_modules/is-fullwidth-code-point": {
3305
-      "version": "3.0.0",
3306
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
3307
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
3308
-      "dev": true,
3309
-      "license": "MIT",
3310
-      "engines": {
3311
-        "node": ">=8"
3312
-      }
3313
-    },
33143695
     "node_modules/is-generator-function": {
3315
-      "version": "1.1.0",
3316
-      "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
3317
-      "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
3696
+      "version": "1.1.2",
3697
+      "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
3698
+      "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
33183699
       "dev": true,
33193700
       "license": "MIT",
33203701
       "dependencies": {
3321
-        "call-bound": "^1.0.3",
3322
-        "get-proto": "^1.0.0",
3702
+        "call-bound": "^1.0.4",
3703
+        "generator-function": "^2.0.0",
3704
+        "get-proto": "^1.0.1",
33233705
         "has-tostringtag": "^1.0.2",
33243706
         "safe-regex-test": "^1.1.0"
33253707
       },
@@ -3396,16 +3778,6 @@
33963778
         "url": "https://github.com/sponsors/ljharb"
33973779
       }
33983780
     },
3399
-    "node_modules/is-path-inside": {
3400
-      "version": "3.0.3",
3401
-      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
3402
-      "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
3403
-      "dev": true,
3404
-      "license": "MIT",
3405
-      "engines": {
3406
-        "node": ">=8"
3407
-      }
3408
-    },
34093781
     "node_modules/is-regex": {
34103782
       "version": "1.2.1",
34113783
       "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
@@ -3583,25 +3955,6 @@
35833955
         "node": ">= 0.4"
35843956
       }
35853957
     },
3586
-    "node_modules/jackspeak": {
3587
-      "version": "2.3.6",
3588
-      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
3589
-      "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
3590
-      "dev": true,
3591
-      "license": "BlueOak-1.0.0",
3592
-      "dependencies": {
3593
-        "@isaacs/cliui": "^8.0.2"
3594
-      },
3595
-      "engines": {
3596
-        "node": ">=14"
3597
-      },
3598
-      "funding": {
3599
-        "url": "https://github.com/sponsors/isaacs"
3600
-      },
3601
-      "optionalDependencies": {
3602
-        "@pkgjs/parseargs": "^0.11.0"
3603
-      }
3604
-    },
36053958
     "node_modules/jiti": {
36063959
       "version": "1.21.7",
36073960
       "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
@@ -3619,9 +3972,9 @@
36193972
       "license": "MIT"
36203973
     },
36213974
     "node_modules/js-yaml": {
3622
-      "version": "4.1.0",
3623
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
3624
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
3975
+      "version": "4.1.1",
3976
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
3977
+      "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
36253978
       "dev": true,
36263979
       "license": "MIT",
36273980
       "dependencies": {
@@ -3780,13 +4133,6 @@
37804133
         "loose-envify": "cli.js"
37814134
       }
37824135
     },
3783
-    "node_modules/lru-cache": {
3784
-      "version": "10.4.3",
3785
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
3786
-      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
3787
-      "dev": true,
3788
-      "license": "ISC"
3789
-    },
37904136
     "node_modules/math-intrinsics": {
37914137
       "version": "1.1.0",
37924138
       "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -3844,16 +4190,6 @@
38444190
         "url": "https://github.com/sponsors/ljharb"
38454191
       }
38464192
     },
3847
-    "node_modules/minipass": {
3848
-      "version": "7.1.2",
3849
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
3850
-      "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
3851
-      "dev": true,
3852
-      "license": "ISC",
3853
-      "engines": {
3854
-        "node": ">=16 || 14 >=14.17"
3855
-      }
3856
-    },
38574193
     "node_modules/ms": {
38584194
       "version": "2.1.3",
38594195
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -3892,9 +4228,9 @@
38924228
       }
38934229
     },
38944230
     "node_modules/napi-postinstall": {
3895
-      "version": "0.3.0",
3896
-      "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.0.tgz",
3897
-      "integrity": "sha512-M7NqKyhODKV1gRLdkwE7pDsZP2/SC2a2vHkOYh9MCpKMbWVfyVfUw5MaH83Fv6XMjxr5jryUp3IDDL9rlxsTeA==",
4231
+      "version": "0.3.4",
4232
+      "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz",
4233
+      "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==",
38984234
       "dev": true,
38994235
       "license": "MIT",
39004236
       "bin": {
@@ -3915,41 +4251,40 @@
39154251
       "license": "MIT"
39164252
     },
39174253
     "node_modules/next": {
3918
-      "version": "14.2.30",
3919
-      "resolved": "https://registry.npmjs.org/next/-/next-14.2.30.tgz",
3920
-      "integrity": "sha512-+COdu6HQrHHFQ1S/8BBsCag61jZacmvbuL2avHvQFbWa2Ox7bE+d8FyNgxRLjXQ5wtPyQwEmk85js/AuaG2Sbg==",
4254
+      "version": "15.5.12",
4255
+      "resolved": "https://registry.npmjs.org/next/-/next-15.5.12.tgz",
4256
+      "integrity": "sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA==",
39214257
       "license": "MIT",
39224258
       "dependencies": {
3923
-        "@next/env": "14.2.30",
3924
-        "@swc/helpers": "0.5.5",
3925
-        "busboy": "1.6.0",
4259
+        "@next/env": "15.5.12",
4260
+        "@swc/helpers": "0.5.15",
39264261
         "caniuse-lite": "^1.0.30001579",
3927
-        "graceful-fs": "^4.2.11",
39284262
         "postcss": "8.4.31",
3929
-        "styled-jsx": "5.1.1"
4263
+        "styled-jsx": "5.1.6"
39304264
       },
39314265
       "bin": {
39324266
         "next": "dist/bin/next"
39334267
       },
39344268
       "engines": {
3935
-        "node": ">=18.17.0"
4269
+        "node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
39364270
       },
39374271
       "optionalDependencies": {
3938
-        "@next/swc-darwin-arm64": "14.2.30",
3939
-        "@next/swc-darwin-x64": "14.2.30",
3940
-        "@next/swc-linux-arm64-gnu": "14.2.30",
3941
-        "@next/swc-linux-arm64-musl": "14.2.30",
3942
-        "@next/swc-linux-x64-gnu": "14.2.30",
3943
-        "@next/swc-linux-x64-musl": "14.2.30",
3944
-        "@next/swc-win32-arm64-msvc": "14.2.30",
3945
-        "@next/swc-win32-ia32-msvc": "14.2.30",
3946
-        "@next/swc-win32-x64-msvc": "14.2.30"
4272
+        "@next/swc-darwin-arm64": "15.5.12",
4273
+        "@next/swc-darwin-x64": "15.5.12",
4274
+        "@next/swc-linux-arm64-gnu": "15.5.12",
4275
+        "@next/swc-linux-arm64-musl": "15.5.12",
4276
+        "@next/swc-linux-x64-gnu": "15.5.12",
4277
+        "@next/swc-linux-x64-musl": "15.5.12",
4278
+        "@next/swc-win32-arm64-msvc": "15.5.12",
4279
+        "@next/swc-win32-x64-msvc": "15.5.12",
4280
+        "sharp": "^0.34.3"
39474281
       },
39484282
       "peerDependencies": {
39494283
         "@opentelemetry/api": "^1.1.0",
3950
-        "@playwright/test": "^1.41.2",
3951
-        "react": "^18.2.0",
3952
-        "react-dom": "^18.2.0",
4284
+        "@playwright/test": "^1.51.1",
4285
+        "babel-plugin-react-compiler": "*",
4286
+        "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
4287
+        "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
39534288
         "sass": "^1.3.0"
39544289
       },
39554290
       "peerDependenciesMeta": {
@@ -3959,6 +4294,9 @@
39594294
         "@playwright/test": {
39604295
           "optional": true
39614296
         },
4297
+        "babel-plugin-react-compiler": {
4298
+          "optional": true
4299
+        },
39624300
         "sass": {
39634301
           "optional": true
39644302
         }
@@ -3992,6 +4330,35 @@
39924330
         "node": "^10 || ^12 || >=14"
39934331
       }
39944332
     },
4333
+    "node_modules/node-exports-info": {
4334
+      "version": "1.6.0",
4335
+      "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz",
4336
+      "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==",
4337
+      "dev": true,
4338
+      "license": "MIT",
4339
+      "dependencies": {
4340
+        "array.prototype.flatmap": "^1.3.3",
4341
+        "es-errors": "^1.3.0",
4342
+        "object.entries": "^1.1.9",
4343
+        "semver": "^6.3.1"
4344
+      },
4345
+      "engines": {
4346
+        "node": ">= 0.4"
4347
+      },
4348
+      "funding": {
4349
+        "url": "https://github.com/sponsors/ljharb"
4350
+      }
4351
+    },
4352
+    "node_modules/node-exports-info/node_modules/semver": {
4353
+      "version": "6.3.1",
4354
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
4355
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
4356
+      "dev": true,
4357
+      "license": "ISC",
4358
+      "bin": {
4359
+        "semver": "bin/semver.js"
4360
+      }
4361
+    },
39954362
     "node_modules/normalize-path": {
39964363
       "version": "3.0.0",
39974364
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -4135,16 +4502,6 @@
41354502
         "url": "https://github.com/sponsors/ljharb"
41364503
       }
41374504
     },
4138
-    "node_modules/once": {
4139
-      "version": "1.4.0",
4140
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
4141
-      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
4142
-      "dev": true,
4143
-      "license": "ISC",
4144
-      "dependencies": {
4145
-        "wrappy": "1"
4146
-      }
4147
-    },
41484505
     "node_modules/optionator": {
41494506
       "version": "0.9.4",
41504507
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -4236,16 +4593,6 @@
42364593
         "node": ">=8"
42374594
       }
42384595
     },
4239
-    "node_modules/path-is-absolute": {
4240
-      "version": "1.0.1",
4241
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
4242
-      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
4243
-      "dev": true,
4244
-      "license": "MIT",
4245
-      "engines": {
4246
-        "node": ">=0.10.0"
4247
-      }
4248
-    },
42494596
     "node_modules/path-key": {
42504597
       "version": "3.1.1",
42514598
       "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -4263,23 +4610,6 @@
42634610
       "dev": true,
42644611
       "license": "MIT"
42654612
     },
4266
-    "node_modules/path-scurry": {
4267
-      "version": "1.11.1",
4268
-      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
4269
-      "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
4270
-      "dev": true,
4271
-      "license": "BlueOak-1.0.0",
4272
-      "dependencies": {
4273
-        "lru-cache": "^10.2.0",
4274
-        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
4275
-      },
4276
-      "engines": {
4277
-        "node": ">=16 || 14 >=14.18"
4278
-      },
4279
-      "funding": {
4280
-        "url": "https://github.com/sponsors/isaacs"
4281
-      }
4282
-    },
42834613
     "node_modules/picocolors": {
42844614
       "version": "1.1.1",
42854615
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -4377,23 +4707,72 @@
43774707
       }
43784708
     },
43794709
     "node_modules/postcss-js": {
4380
-      "version": "4.0.1",
4381
-      "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
4382
-      "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
4710
+      "version": "4.1.0",
4711
+      "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
4712
+      "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
4713
+      "dev": true,
4714
+      "funding": [
4715
+        {
4716
+          "type": "opencollective",
4717
+          "url": "https://opencollective.com/postcss/"
4718
+        },
4719
+        {
4720
+          "type": "github",
4721
+          "url": "https://github.com/sponsors/ai"
4722
+        }
4723
+      ],
4724
+      "license": "MIT",
4725
+      "dependencies": {
4726
+        "camelcase-css": "^2.0.1"
4727
+      },
4728
+      "engines": {
4729
+        "node": "^12 || ^14 || >= 16"
4730
+      },
4731
+      "peerDependencies": {
4732
+        "postcss": "^8.4.21"
4733
+      }
4734
+    },
4735
+    "node_modules/postcss-load-config": {
4736
+      "version": "6.0.1",
4737
+      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
4738
+      "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
43834739
       "dev": true,
4740
+      "funding": [
4741
+        {
4742
+          "type": "opencollective",
4743
+          "url": "https://opencollective.com/postcss/"
4744
+        },
4745
+        {
4746
+          "type": "github",
4747
+          "url": "https://github.com/sponsors/ai"
4748
+        }
4749
+      ],
43844750
       "license": "MIT",
43854751
       "dependencies": {
4386
-        "camelcase-css": "^2.0.1"
4752
+        "lilconfig": "^3.1.1"
43874753
       },
43884754
       "engines": {
4389
-        "node": "^12 || ^14 || >= 16"
4390
-      },
4391
-      "funding": {
4392
-        "type": "opencollective",
4393
-        "url": "https://opencollective.com/postcss/"
4755
+        "node": ">= 18"
43944756
       },
43954757
       "peerDependencies": {
4396
-        "postcss": "^8.4.21"
4758
+        "jiti": ">=1.21.0",
4759
+        "postcss": ">=8.0.9",
4760
+        "tsx": "^4.8.1",
4761
+        "yaml": "^2.4.2"
4762
+      },
4763
+      "peerDependenciesMeta": {
4764
+        "jiti": {
4765
+          "optional": true
4766
+        },
4767
+        "postcss": {
4768
+          "optional": true
4769
+        },
4770
+        "tsx": {
4771
+          "optional": true
4772
+        },
4773
+        "yaml": {
4774
+          "optional": true
4775
+        }
43974776
       }
43984777
     },
43994778
     "node_modules/postcss-nested": {
@@ -4596,13 +4975,13 @@
45964975
       }
45974976
     },
45984977
     "node_modules/resolve": {
4599
-      "version": "1.22.10",
4600
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
4601
-      "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
4978
+      "version": "1.22.11",
4979
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
4980
+      "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
46024981
       "dev": true,
46034982
       "license": "MIT",
46044983
       "dependencies": {
4605
-        "is-core-module": "^2.16.0",
4984
+        "is-core-module": "^2.16.1",
46064985
         "path-parse": "^1.0.7",
46074986
         "supports-preserve-symlinks-flag": "^1.0.0"
46084987
       },
@@ -4647,45 +5026,6 @@
46475026
         "node": ">=0.10.0"
46485027
       }
46495028
     },
4650
-    "node_modules/rimraf": {
4651
-      "version": "3.0.2",
4652
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
4653
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
4654
-      "deprecated": "Rimraf versions prior to v4 are no longer supported",
4655
-      "dev": true,
4656
-      "license": "ISC",
4657
-      "dependencies": {
4658
-        "glob": "^7.1.3"
4659
-      },
4660
-      "bin": {
4661
-        "rimraf": "bin.js"
4662
-      },
4663
-      "funding": {
4664
-        "url": "https://github.com/sponsors/isaacs"
4665
-      }
4666
-    },
4667
-    "node_modules/rimraf/node_modules/glob": {
4668
-      "version": "7.2.3",
4669
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
4670
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
4671
-      "deprecated": "Glob versions prior to v9 are no longer supported",
4672
-      "dev": true,
4673
-      "license": "ISC",
4674
-      "dependencies": {
4675
-        "fs.realpath": "^1.0.0",
4676
-        "inflight": "^1.0.4",
4677
-        "inherits": "2",
4678
-        "minimatch": "^3.1.1",
4679
-        "once": "^1.3.0",
4680
-        "path-is-absolute": "^1.0.0"
4681
-      },
4682
-      "engines": {
4683
-        "node": "*"
4684
-      },
4685
-      "funding": {
4686
-        "url": "https://github.com/sponsors/isaacs"
4687
-      }
4688
-    },
46895029
     "node_modules/run-parallel": {
46905030
       "version": "1.2.0",
46915031
       "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -4775,10 +5115,10 @@
47755115
       }
47765116
     },
47775117
     "node_modules/semver": {
4778
-      "version": "7.7.2",
4779
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
4780
-      "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
4781
-      "dev": true,
5118
+      "version": "7.7.4",
5119
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
5120
+      "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
5121
+      "devOptional": true,
47825122
       "license": "ISC",
47835123
       "bin": {
47845124
         "semver": "bin/semver.js"
@@ -4836,6 +5176,51 @@
48365176
         "node": ">= 0.4"
48375177
       }
48385178
     },
5179
+    "node_modules/sharp": {
5180
+      "version": "0.34.5",
5181
+      "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
5182
+      "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
5183
+      "hasInstallScript": true,
5184
+      "license": "Apache-2.0",
5185
+      "optional": true,
5186
+      "dependencies": {
5187
+        "@img/colour": "^1.0.0",
5188
+        "detect-libc": "^2.1.2",
5189
+        "semver": "^7.7.3"
5190
+      },
5191
+      "engines": {
5192
+        "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
5193
+      },
5194
+      "funding": {
5195
+        "url": "https://opencollective.com/libvips"
5196
+      },
5197
+      "optionalDependencies": {
5198
+        "@img/sharp-darwin-arm64": "0.34.5",
5199
+        "@img/sharp-darwin-x64": "0.34.5",
5200
+        "@img/sharp-libvips-darwin-arm64": "1.2.4",
5201
+        "@img/sharp-libvips-darwin-x64": "1.2.4",
5202
+        "@img/sharp-libvips-linux-arm": "1.2.4",
5203
+        "@img/sharp-libvips-linux-arm64": "1.2.4",
5204
+        "@img/sharp-libvips-linux-ppc64": "1.2.4",
5205
+        "@img/sharp-libvips-linux-riscv64": "1.2.4",
5206
+        "@img/sharp-libvips-linux-s390x": "1.2.4",
5207
+        "@img/sharp-libvips-linux-x64": "1.2.4",
5208
+        "@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
5209
+        "@img/sharp-libvips-linuxmusl-x64": "1.2.4",
5210
+        "@img/sharp-linux-arm": "0.34.5",
5211
+        "@img/sharp-linux-arm64": "0.34.5",
5212
+        "@img/sharp-linux-ppc64": "0.34.5",
5213
+        "@img/sharp-linux-riscv64": "0.34.5",
5214
+        "@img/sharp-linux-s390x": "0.34.5",
5215
+        "@img/sharp-linux-x64": "0.34.5",
5216
+        "@img/sharp-linuxmusl-arm64": "0.34.5",
5217
+        "@img/sharp-linuxmusl-x64": "0.34.5",
5218
+        "@img/sharp-wasm32": "0.34.5",
5219
+        "@img/sharp-win32-arm64": "0.34.5",
5220
+        "@img/sharp-win32-ia32": "0.34.5",
5221
+        "@img/sharp-win32-x64": "0.34.5"
5222
+      }
5223
+    },
48395224
     "node_modules/shebang-command": {
48405225
       "version": "2.0.0",
48415226
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -4935,19 +5320,6 @@
49355320
         "url": "https://github.com/sponsors/ljharb"
49365321
       }
49375322
     },
4938
-    "node_modules/signal-exit": {
4939
-      "version": "4.1.0",
4940
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
4941
-      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
4942
-      "dev": true,
4943
-      "license": "ISC",
4944
-      "engines": {
4945
-        "node": ">=14"
4946
-      },
4947
-      "funding": {
4948
-        "url": "https://github.com/sponsors/isaacs"
4949
-      }
4950
-    },
49515323
     "node_modules/source-map-js": {
49525324
       "version": "1.2.1",
49535325
       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -4978,84 +5350,6 @@
49785350
         "node": ">= 0.4"
49795351
       }
49805352
     },
4981
-    "node_modules/streamsearch": {
4982
-      "version": "1.1.0",
4983
-      "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
4984
-      "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
4985
-      "engines": {
4986
-        "node": ">=10.0.0"
4987
-      }
4988
-    },
4989
-    "node_modules/string-width": {
4990
-      "version": "5.1.2",
4991
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
4992
-      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
4993
-      "dev": true,
4994
-      "license": "MIT",
4995
-      "dependencies": {
4996
-        "eastasianwidth": "^0.2.0",
4997
-        "emoji-regex": "^9.2.2",
4998
-        "strip-ansi": "^7.0.1"
4999
-      },
5000
-      "engines": {
5001
-        "node": ">=12"
5002
-      },
5003
-      "funding": {
5004
-        "url": "https://github.com/sponsors/sindresorhus"
5005
-      }
5006
-    },
5007
-    "node_modules/string-width-cjs": {
5008
-      "name": "string-width",
5009
-      "version": "4.2.3",
5010
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
5011
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
5012
-      "dev": true,
5013
-      "license": "MIT",
5014
-      "dependencies": {
5015
-        "emoji-regex": "^8.0.0",
5016
-        "is-fullwidth-code-point": "^3.0.0",
5017
-        "strip-ansi": "^6.0.1"
5018
-      },
5019
-      "engines": {
5020
-        "node": ">=8"
5021
-      }
5022
-    },
5023
-    "node_modules/string-width-cjs/node_modules/emoji-regex": {
5024
-      "version": "8.0.0",
5025
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
5026
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
5027
-      "dev": true,
5028
-      "license": "MIT"
5029
-    },
5030
-    "node_modules/string-width/node_modules/ansi-regex": {
5031
-      "version": "6.1.0",
5032
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
5033
-      "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
5034
-      "dev": true,
5035
-      "license": "MIT",
5036
-      "engines": {
5037
-        "node": ">=12"
5038
-      },
5039
-      "funding": {
5040
-        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
5041
-      }
5042
-    },
5043
-    "node_modules/string-width/node_modules/strip-ansi": {
5044
-      "version": "7.1.0",
5045
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
5046
-      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
5047
-      "dev": true,
5048
-      "license": "MIT",
5049
-      "dependencies": {
5050
-        "ansi-regex": "^6.0.1"
5051
-      },
5052
-      "engines": {
5053
-        "node": ">=12"
5054
-      },
5055
-      "funding": {
5056
-        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
5057
-      }
5058
-    },
50595353
     "node_modules/string.prototype.includes": {
50605354
       "version": "2.0.1",
50615355
       "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz",
@@ -5169,33 +5463,6 @@
51695463
         "url": "https://github.com/sponsors/ljharb"
51705464
       }
51715465
     },
5172
-    "node_modules/strip-ansi": {
5173
-      "version": "6.0.1",
5174
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
5175
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
5176
-      "dev": true,
5177
-      "license": "MIT",
5178
-      "dependencies": {
5179
-        "ansi-regex": "^5.0.1"
5180
-      },
5181
-      "engines": {
5182
-        "node": ">=8"
5183
-      }
5184
-    },
5185
-    "node_modules/strip-ansi-cjs": {
5186
-      "name": "strip-ansi",
5187
-      "version": "6.0.1",
5188
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
5189
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
5190
-      "dev": true,
5191
-      "license": "MIT",
5192
-      "dependencies": {
5193
-        "ansi-regex": "^5.0.1"
5194
-      },
5195
-      "engines": {
5196
-        "node": ">=8"
5197
-      }
5198
-    },
51995466
     "node_modules/strip-bom": {
52005467
       "version": "3.0.0",
52015468
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
@@ -5220,9 +5487,9 @@
52205487
       }
52215488
     },
52225489
     "node_modules/styled-jsx": {
5223
-      "version": "5.1.1",
5224
-      "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
5225
-      "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
5490
+      "version": "5.1.6",
5491
+      "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
5492
+      "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==",
52265493
       "license": "MIT",
52275494
       "dependencies": {
52285495
         "client-only": "0.0.1"
@@ -5231,7 +5498,7 @@
52315498
         "node": ">= 12.0.0"
52325499
       },
52335500
       "peerDependencies": {
5234
-        "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
5501
+        "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0"
52355502
       },
52365503
       "peerDependenciesMeta": {
52375504
         "@babel/core": {
@@ -5243,18 +5510,18 @@
52435510
       }
52445511
     },
52455512
     "node_modules/sucrase": {
5246
-      "version": "3.35.0",
5247
-      "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
5248
-      "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
5513
+      "version": "3.35.1",
5514
+      "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz",
5515
+      "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==",
52495516
       "dev": true,
52505517
       "license": "MIT",
52515518
       "dependencies": {
52525519
         "@jridgewell/gen-mapping": "^0.3.2",
52535520
         "commander": "^4.0.0",
5254
-        "glob": "^10.3.10",
52555521
         "lines-and-columns": "^1.1.6",
52565522
         "mz": "^2.7.0",
52575523
         "pirates": "^4.0.1",
5524
+        "tinyglobby": "^0.2.11",
52585525
         "ts-interface-checker": "^0.1.9"
52595526
       },
52605527
       "bin": {
@@ -5292,9 +5559,9 @@
52925559
       }
52935560
     },
52945561
     "node_modules/tailwindcss": {
5295
-      "version": "3.4.17",
5296
-      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
5297
-      "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
5562
+      "version": "3.4.19",
5563
+      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz",
5564
+      "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==",
52985565
       "dev": true,
52995566
       "license": "MIT",
53005567
       "dependencies": {
@@ -5306,7 +5573,7 @@
53065573
         "fast-glob": "^3.3.2",
53075574
         "glob-parent": "^6.0.2",
53085575
         "is-glob": "^4.0.3",
5309
-        "jiti": "^1.21.6",
5576
+        "jiti": "^1.21.7",
53105577
         "lilconfig": "^3.1.3",
53115578
         "micromatch": "^4.0.8",
53125579
         "normalize-path": "^3.0.0",
@@ -5315,7 +5582,7 @@
53155582
         "postcss": "^8.4.47",
53165583
         "postcss-import": "^15.1.0",
53175584
         "postcss-js": "^4.0.1",
5318
-        "postcss-load-config": "^4.0.2",
5585
+        "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
53195586
         "postcss-nested": "^6.2.0",
53205587
         "postcss-selector-parser": "^6.1.2",
53215588
         "resolve": "^1.22.8",
@@ -5329,48 +5596,35 @@
53295596
         "node": ">=14.0.0"
53305597
       }
53315598
     },
5332
-    "node_modules/tailwindcss/node_modules/postcss-load-config": {
5333
-      "version": "4.0.2",
5334
-      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
5335
-      "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
5599
+    "node_modules/tailwindcss/node_modules/fast-glob": {
5600
+      "version": "3.3.3",
5601
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
5602
+      "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
53365603
       "dev": true,
5337
-      "funding": [
5338
-        {
5339
-          "type": "opencollective",
5340
-          "url": "https://opencollective.com/postcss/"
5341
-        },
5342
-        {
5343
-          "type": "github",
5344
-          "url": "https://github.com/sponsors/ai"
5345
-        }
5346
-      ],
53475604
       "license": "MIT",
53485605
       "dependencies": {
5349
-        "lilconfig": "^3.0.0",
5350
-        "yaml": "^2.3.4"
5606
+        "@nodelib/fs.stat": "^2.0.2",
5607
+        "@nodelib/fs.walk": "^1.2.3",
5608
+        "glob-parent": "^5.1.2",
5609
+        "merge2": "^1.3.0",
5610
+        "micromatch": "^4.0.8"
53515611
       },
53525612
       "engines": {
5353
-        "node": ">= 14"
5354
-      },
5355
-      "peerDependencies": {
5356
-        "postcss": ">=8.0.9",
5357
-        "ts-node": ">=9.0.0"
5358
-      },
5359
-      "peerDependenciesMeta": {
5360
-        "postcss": {
5361
-          "optional": true
5362
-        },
5363
-        "ts-node": {
5364
-          "optional": true
5365
-        }
5613
+        "node": ">=8.6.0"
53665614
       }
53675615
     },
5368
-    "node_modules/text-table": {
5369
-      "version": "0.2.0",
5370
-      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
5371
-      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
5616
+    "node_modules/tailwindcss/node_modules/fast-glob/node_modules/glob-parent": {
5617
+      "version": "5.1.2",
5618
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
5619
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
53725620
       "dev": true,
5373
-      "license": "MIT"
5621
+      "license": "ISC",
5622
+      "dependencies": {
5623
+        "is-glob": "^4.0.1"
5624
+      },
5625
+      "engines": {
5626
+        "node": ">= 6"
5627
+      }
53745628
     },
53755629
     "node_modules/thenify": {
53765630
       "version": "3.3.1",
@@ -5396,14 +5650,14 @@
53965650
       }
53975651
     },
53985652
     "node_modules/tinyglobby": {
5399
-      "version": "0.2.14",
5400
-      "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
5401
-      "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
5653
+      "version": "0.2.15",
5654
+      "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
5655
+      "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
54025656
       "dev": true,
54035657
       "license": "MIT",
54045658
       "dependencies": {
5405
-        "fdir": "^6.4.4",
5406
-        "picomatch": "^4.0.2"
5659
+        "fdir": "^6.5.0",
5660
+        "picomatch": "^4.0.3"
54075661
       },
54085662
       "engines": {
54095663
         "node": ">=12.0.0"
@@ -5413,11 +5667,14 @@
54135667
       }
54145668
     },
54155669
     "node_modules/tinyglobby/node_modules/fdir": {
5416
-      "version": "6.4.6",
5417
-      "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
5418
-      "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
5670
+      "version": "6.5.0",
5671
+      "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
5672
+      "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
54195673
       "dev": true,
54205674
       "license": "MIT",
5675
+      "engines": {
5676
+        "node": ">=12.0.0"
5677
+      },
54215678
       "peerDependencies": {
54225679
         "picomatch": "^3 || ^4"
54235680
       },
@@ -5428,9 +5685,9 @@
54285685
       }
54295686
     },
54305687
     "node_modules/tinyglobby/node_modules/picomatch": {
5431
-      "version": "4.0.2",
5432
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
5433
-      "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
5688
+      "version": "4.0.3",
5689
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
5690
+      "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
54345691
       "dev": true,
54355692
       "license": "MIT",
54365693
       "engines": {
@@ -5454,9 +5711,9 @@
54545711
       }
54555712
     },
54565713
     "node_modules/ts-api-utils": {
5457
-      "version": "2.1.0",
5458
-      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
5459
-      "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
5714
+      "version": "2.4.0",
5715
+      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
5716
+      "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
54605717
       "dev": true,
54615718
       "license": "MIT",
54625719
       "engines": {
@@ -5505,19 +5762,6 @@
55055762
         "node": ">= 0.8.0"
55065763
       }
55075764
     },
5508
-    "node_modules/type-fest": {
5509
-      "version": "0.20.2",
5510
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
5511
-      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
5512
-      "dev": true,
5513
-      "license": "(MIT OR CC0-1.0)",
5514
-      "engines": {
5515
-        "node": ">=10"
5516
-      },
5517
-      "funding": {
5518
-        "url": "https://github.com/sponsors/sindresorhus"
5519
-      }
5520
-    },
55215765
     "node_modules/typed-array-buffer": {
55225766
       "version": "1.0.3",
55235767
       "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
@@ -5597,9 +5841,9 @@
55975841
       }
55985842
     },
55995843
     "node_modules/typescript": {
5600
-      "version": "5.8.3",
5601
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
5602
-      "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
5844
+      "version": "5.9.3",
5845
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
5846
+      "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
56035847
       "dev": true,
56045848
       "license": "Apache-2.0",
56055849
       "bin": {
@@ -5772,9 +6016,9 @@
57726016
       }
57736017
     },
57746018
     "node_modules/which-typed-array": {
5775
-      "version": "1.1.19",
5776
-      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
5777
-      "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
6019
+      "version": "1.1.20",
6020
+      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz",
6021
+      "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==",
57786022
       "dev": true,
57796023
       "license": "MIT",
57806024
       "dependencies": {
@@ -5803,127 +6047,6 @@
58036047
         "node": ">=0.10.0"
58046048
       }
58056049
     },
5806
-    "node_modules/wrap-ansi": {
5807
-      "version": "8.1.0",
5808
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
5809
-      "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
5810
-      "dev": true,
5811
-      "license": "MIT",
5812
-      "dependencies": {
5813
-        "ansi-styles": "^6.1.0",
5814
-        "string-width": "^5.0.1",
5815
-        "strip-ansi": "^7.0.1"
5816
-      },
5817
-      "engines": {
5818
-        "node": ">=12"
5819
-      },
5820
-      "funding": {
5821
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
5822
-      }
5823
-    },
5824
-    "node_modules/wrap-ansi-cjs": {
5825
-      "name": "wrap-ansi",
5826
-      "version": "7.0.0",
5827
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
5828
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
5829
-      "dev": true,
5830
-      "license": "MIT",
5831
-      "dependencies": {
5832
-        "ansi-styles": "^4.0.0",
5833
-        "string-width": "^4.1.0",
5834
-        "strip-ansi": "^6.0.0"
5835
-      },
5836
-      "engines": {
5837
-        "node": ">=10"
5838
-      },
5839
-      "funding": {
5840
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
5841
-      }
5842
-    },
5843
-    "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
5844
-      "version": "8.0.0",
5845
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
5846
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
5847
-      "dev": true,
5848
-      "license": "MIT"
5849
-    },
5850
-    "node_modules/wrap-ansi-cjs/node_modules/string-width": {
5851
-      "version": "4.2.3",
5852
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
5853
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
5854
-      "dev": true,
5855
-      "license": "MIT",
5856
-      "dependencies": {
5857
-        "emoji-regex": "^8.0.0",
5858
-        "is-fullwidth-code-point": "^3.0.0",
5859
-        "strip-ansi": "^6.0.1"
5860
-      },
5861
-      "engines": {
5862
-        "node": ">=8"
5863
-      }
5864
-    },
5865
-    "node_modules/wrap-ansi/node_modules/ansi-regex": {
5866
-      "version": "6.1.0",
5867
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
5868
-      "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
5869
-      "dev": true,
5870
-      "license": "MIT",
5871
-      "engines": {
5872
-        "node": ">=12"
5873
-      },
5874
-      "funding": {
5875
-        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
5876
-      }
5877
-    },
5878
-    "node_modules/wrap-ansi/node_modules/ansi-styles": {
5879
-      "version": "6.2.1",
5880
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
5881
-      "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
5882
-      "dev": true,
5883
-      "license": "MIT",
5884
-      "engines": {
5885
-        "node": ">=12"
5886
-      },
5887
-      "funding": {
5888
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
5889
-      }
5890
-    },
5891
-    "node_modules/wrap-ansi/node_modules/strip-ansi": {
5892
-      "version": "7.1.0",
5893
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
5894
-      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
5895
-      "dev": true,
5896
-      "license": "MIT",
5897
-      "dependencies": {
5898
-        "ansi-regex": "^6.0.1"
5899
-      },
5900
-      "engines": {
5901
-        "node": ">=12"
5902
-      },
5903
-      "funding": {
5904
-        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
5905
-      }
5906
-    },
5907
-    "node_modules/wrappy": {
5908
-      "version": "1.0.2",
5909
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
5910
-      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
5911
-      "dev": true,
5912
-      "license": "ISC"
5913
-    },
5914
-    "node_modules/yaml": {
5915
-      "version": "2.8.0",
5916
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz",
5917
-      "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==",
5918
-      "dev": true,
5919
-      "license": "ISC",
5920
-      "bin": {
5921
-        "yaml": "bin.mjs"
5922
-      },
5923
-      "engines": {
5924
-        "node": ">= 14.6"
5925
-      }
5926
-    },
59276050
     "node_modules/yocto-queue": {
59286051
       "version": "0.1.0",
59296052
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
package.jsonmodified
@@ -6,21 +6,23 @@
66
     "dev": "next dev",
77
     "build": "next build",
88
     "start": "next start",
9
-    "lint": "next lint"
9
+    "lint": "eslint ."
1010
   },
1111
   "dependencies": {
12
+    "@vercel/analytics": "^1.5.0",
13
+    "next": "15.5.12",
1214
     "react": "^18",
13
-    "react-dom": "^18",
14
-    "next": "14.2.30"
15
+    "react-dom": "^18"
1516
   },
1617
   "devDependencies": {
17
-    "typescript": "^5",
1818
     "@types/node": "^20",
1919
     "@types/react": "^18",
2020
     "@types/react-dom": "^18",
21
+    "@eslint/eslintrc": "^3",
22
+    "eslint": "^9",
23
+    "eslint-config-next": "15.5.12",
2124
     "postcss": "^8",
2225
     "tailwindcss": "^3.4.1",
23
-    "eslint": "^8",
24
-    "eslint-config-next": "14.2.30"
26
+    "typescript": "^5"
2527
   }
2628
 }
public/AirForceCross.jpgadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
public/CroixDeGuerre.jpgadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
public/DistinguishedServiceCross.jpgadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
public/DistinguishedServiceOrder.pngadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
public/MedailleMilitaire.jpgadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
public/MoHAirForce.jpgadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
public/MoHArmy.jpgadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
public/MoHNavy.jpgadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
public/NavyCross.jpgadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
public/SilverStar.pngadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
public/VictoriaCross.jpgadded
Image file changed (preview rendering wires once /raw URLs are threaded into the diff renderer).
tsconfig.jsonmodified
@@ -1,6 +1,10 @@
11
 {
22
   "compilerOptions": {
3
-    "lib": ["dom", "dom.iterable", "esnext"],
3
+    "lib": [
4
+      "dom",
5
+      "dom.iterable",
6
+      "esnext"
7
+    ],
48
     "allowJs": true,
59
     "skipLibCheck": true,
610
     "strict": true,
@@ -18,9 +22,19 @@
1822
       }
1923
     ],
2024
     "paths": {
21
-      "@/*": ["./*"]
22
-    }
25
+      "@/*": [
26
+        "./*"
27
+      ]
28
+    },
29
+    "target": "ES2017"
2330
   },
24
-  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25
-  "exclude": ["node_modules"]
31
+  "include": [
32
+    "next-env.d.ts",
33
+    "**/*.ts",
34
+    "**/*.tsx",
35
+    ".next/types/**/*.ts"
36
+  ],
37
+  "exclude": [
38
+    "node_modules"
39
+  ]
2640
 }