micymike commited on
Commit
7762995
·
verified ·
1 Parent(s): 7adeecf

Upload 13 files

Browse files
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .env
2
+ templates/node_modules
3
+ __pycache__
4
+ textbelt.py
app.py ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from datetime import datetime, timedelta
3
+ import logging
4
+ from dotenv import load_dotenv
5
+ import google.generativeai as genai
6
+ from flask import Flask, render_template, request, jsonify
7
+ from flask_socketio import SocketIO
8
+ from flask_sqlalchemy import SQLAlchemy
9
+ from apscheduler.schedulers.background import BackgroundScheduler
10
+ import smtplib
11
+ from email.mime.text import MIMEText
12
+ from email.mime.multipart import MIMEMultipart
13
+
14
+ # Load environment variables
15
+ load_dotenv()
16
+
17
+ # Initialize Flask app
18
+ app = Flask(__name__)
19
+ socketio = SocketIO(app, cors_allowed_origins="*")
20
+
21
+ # Configure SQLAlchemy
22
+ app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///appointments.db'
23
+ app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
24
+ db = SQLAlchemy(app)
25
+
26
+ # Set up logging
27
+ logging.basicConfig(level=logging.DEBUG)
28
+ logger = logging.getLogger(__name__)
29
+
30
+ # Configure the Gemini API key
31
+ genai.configure(api_key=os.getenv('GEMINI_API_KEY'))
32
+
33
+ # Set up the Gemini model
34
+ model = genai.GenerativeModel('gemini-pro')
35
+
36
+ # Email configuration
37
+ smtp_server = "smtp.gmail.com"
38
+ smtp_port = 587
39
+ smtp_user = "mosesmichael878@gmail.com" # Default sender email
40
+ smtp_password = os.getenv('GMAIL_APP_PASSWORD')
41
+
42
+ # Define Appointment model
43
+ class Appointment(db.Model):
44
+ id = db.Column(db.Integer, primary_key=True)
45
+ user_name = db.Column(db.String(100), nullable=False)
46
+ user_email = db.Column(db.String(120), nullable=False)
47
+ doctor_name = db.Column(db.String(100), nullable=False)
48
+ appointment_time = db.Column(db.DateTime, nullable=False)
49
+
50
+ # List of dummy doctors
51
+ doctors = [
52
+ {"id": 1, "name": "Dr. Emily Johnson", "specialty": "General Practitioner"},
53
+ {"id": 2, "name": "Dr. Michael Chen", "specialty": "Cardiologist"},
54
+ {"id": 3, "name": "Dr. Sarah Patel", "specialty": "Pediatrician"},
55
+ {"id": 4, "name": "Dr. David Kim", "specialty": "Dermatologist"},
56
+ {"id": 5, "name": "Dr. Lisa Rodriguez", "specialty": "Neurologist"}
57
+ ]
58
+
59
+ # Generate message using Gemini
60
+ def generate_message(prompt, enhance_accuracy=False):
61
+ try:
62
+ if enhance_accuracy:
63
+ response = model.generate_content(
64
+ prompt,
65
+ generation_config=genai.types.GenerationConfig(
66
+ temperature=0.7,
67
+ top_p=0.95,
68
+ top_k=50,
69
+ max_output_tokens=100
70
+ )
71
+ )
72
+ else:
73
+ response = model.generate_content(prompt)
74
+
75
+ message = response.text
76
+ if not message.endswith(('.', '!', '?')):
77
+ message += '...'
78
+ logger.debug(f"Generated message: {message}")
79
+ return message
80
+ except Exception as e:
81
+ logger.error(f"Error generating message: {str(e)}")
82
+ return "Error generating message. Please try again."
83
+
84
+ # Send email notification
85
+ def send_email(recipient_email, subject, body):
86
+ try:
87
+ msg = MIMEMultipart()
88
+ msg['From'] = smtp_user
89
+ msg['To'] = recipient_email
90
+ msg['Subject'] = subject
91
+
92
+ msg.attach(MIMEText(body, 'plain'))
93
+
94
+ with smtplib.SMTP(smtp_server, smtp_port) as server:
95
+ server.starttls()
96
+ server.login(smtp_user, smtp_password)
97
+ server.send_message(msg)
98
+
99
+ logger.info(f"Email sent to {recipient_email}")
100
+ except Exception as e:
101
+ logger.error(f"Error sending email: {str(e)}")
102
+ raise
103
+
104
+ # Schedule the job for notifications
105
+ scheduler = BackgroundScheduler()
106
+ scheduler.start()
107
+
108
+ @app.route('/')
109
+ def index():
110
+ return render_template('index.html', doctors=doctors)
111
+
112
+ @app.route('/submit', methods=['POST'])
113
+ def submit():
114
+ try:
115
+ data = request.json
116
+ name = data['name']
117
+ condition = data['condition']
118
+ age = data['age']
119
+ email = data['email']
120
+ notification_type = data['notificationType']
121
+ time = data.get('time')
122
+ enhance_accuracy = data.get('enhance_accuracy', False)
123
+
124
+ if notification_type == 'motivational':
125
+ prompt = f"Generate a motivational message for {name}, who is {age} years old and has {condition}. The message should be encouraging and uplifting."
126
+ elif notification_type == 'medicational':
127
+ prompt = f"Generate a gentle medication reminder for {name}, who is {age} years old and has {condition}. The reminder should be friendly and supportive."
128
+ elif notification_type == 'advice':
129
+ prompt = f"Provide helpful advice for managing {condition} for {name}, who is {age} years old. The advice should be practical and easy to follow."
130
+ else:
131
+ return jsonify({'status': 'error', 'message': 'Invalid notification type'}), 400
132
+
133
+ message = generate_message(prompt, enhance_accuracy)
134
+
135
+ if time:
136
+ # Schedule the notification
137
+ schedule_time = datetime.strptime(time, "%H:%M").time()
138
+ now = datetime.now()
139
+ schedule_datetime = datetime.combine(now.date(), schedule_time)
140
+
141
+ if schedule_datetime <= now:
142
+ schedule_datetime += timedelta(days=1) # Schedule for tomorrow if time has passed
143
+
144
+ scheduler.add_job(send_email, 'date', run_date=schedule_datetime, args=[email, 'Your Notification', message])
145
+ response_message = f"Notification scheduled for {time}. You will receive it at the specified time. Remember to check you email"
146
+ else:
147
+ # Send notification immediately
148
+ send_email(email, 'Your Notification', message)
149
+ response_message = "Notification sent. Please check your email."
150
+
151
+ logger.info(f"Successfully processed submission for {name}, {notification_type}")
152
+ return jsonify({'status': 'success', 'message': response_message})
153
+ except Exception as e:
154
+ logger.error(f"Error processing submission: {str(e)}")
155
+ return jsonify({'status': 'error', 'message': str(e)}), 500
156
+
157
+ @app.route('/book_appointment', methods=['POST'])
158
+ def book_appointment():
159
+ try:
160
+ data = request.json
161
+ user_name = data['appointmentName']
162
+ user_email = data['appointmentEmail']
163
+ doctor_id = int(data['doctor'])
164
+ appointment_date = data['appointmentDate']
165
+ appointment_time = data['appointmentTime']
166
+
167
+ # Validate doctor_id
168
+ doctor = next((d for d in doctors if d['id'] == doctor_id), None)
169
+ if not doctor:
170
+ return jsonify({'status': 'error', 'message': 'Invalid doctor selected'}), 400
171
+
172
+ # Combine date and time
173
+ appointment_datetime = datetime.strptime(f"{appointment_date} {appointment_time}", "%Y-%m-%d %H:%M")
174
+
175
+ # Create new appointment
176
+ new_appointment = Appointment(
177
+ user_name=user_name,
178
+ user_email=user_email,
179
+ doctor_name=doctor['name'],
180
+ appointment_time=appointment_datetime
181
+ )
182
+ db.session.add(new_appointment)
183
+ db.session.commit()
184
+
185
+ # Send confirmation email
186
+ subject = "Appointment Confirmation"
187
+ body = f"""
188
+ Dear {user_name},
189
+
190
+ Your appointment has been confirmed:
191
+
192
+ Doctor: {doctor['name']} ({doctor['specialty']})
193
+ Date and Time: {appointment_datetime.strftime('%A, %B %d, %Y at %I:%M %p')}
194
+
195
+ Please arrive 15 minutes before your scheduled appointment time.
196
+
197
+ If you need to reschedule or cancel, please contact us at least 24 hours in advance.
198
+
199
+ Thank you for choosing our service!
200
+
201
+ Best regards,
202
+ Elderly companion
203
+ """
204
+ send_email(user_email, subject, body)
205
+
206
+ return jsonify({'status': 'success', 'message': 'Appointment booked successfully'})
207
+ except Exception as e:
208
+ logger.error(f"Error booking appointment: {str(e)}")
209
+ return jsonify({'status': 'error', 'message': str(e)}), 500
210
+
211
+ @socketio.on('connect')
212
+ def handle_connect():
213
+ logger.info('Client connected')
214
+
215
+ @socketio.on('disconnect')
216
+ def handle_disconnect():
217
+ logger.info('Client disconnected')
218
+
219
+ if __name__ == '__main__':
220
+ with app.app_context():
221
+ db.create_all() # Create database tables
222
+ socketio.run(app, debug=True)
instance/appointments.db ADDED
Binary file (8.19 kB). View file
 
package-lock.json ADDED
@@ -0,0 +1,1384 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "auto-notification",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "auto-notification",
9
+ "version": "1.0.0",
10
+ "license": "ISC",
11
+ "devDependencies": {
12
+ "tailwindcss": "^3.4.4"
13
+ }
14
+ },
15
+ "node_modules/@alloc/quick-lru": {
16
+ "version": "5.2.0",
17
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
18
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
19
+ "dev": true,
20
+ "engines": {
21
+ "node": ">=10"
22
+ },
23
+ "funding": {
24
+ "url": "https://github.com/sponsors/sindresorhus"
25
+ }
26
+ },
27
+ "node_modules/@isaacs/cliui": {
28
+ "version": "8.0.2",
29
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
30
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
31
+ "dev": true,
32
+ "dependencies": {
33
+ "string-width": "^5.1.2",
34
+ "string-width-cjs": "npm:string-width@^4.2.0",
35
+ "strip-ansi": "^7.0.1",
36
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
37
+ "wrap-ansi": "^8.1.0",
38
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
39
+ },
40
+ "engines": {
41
+ "node": ">=12"
42
+ }
43
+ },
44
+ "node_modules/@jridgewell/gen-mapping": {
45
+ "version": "0.3.5",
46
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
47
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
48
+ "dev": true,
49
+ "dependencies": {
50
+ "@jridgewell/set-array": "^1.2.1",
51
+ "@jridgewell/sourcemap-codec": "^1.4.10",
52
+ "@jridgewell/trace-mapping": "^0.3.24"
53
+ },
54
+ "engines": {
55
+ "node": ">=6.0.0"
56
+ }
57
+ },
58
+ "node_modules/@jridgewell/resolve-uri": {
59
+ "version": "3.1.2",
60
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
61
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
62
+ "dev": true,
63
+ "engines": {
64
+ "node": ">=6.0.0"
65
+ }
66
+ },
67
+ "node_modules/@jridgewell/set-array": {
68
+ "version": "1.2.1",
69
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
70
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
71
+ "dev": true,
72
+ "engines": {
73
+ "node": ">=6.0.0"
74
+ }
75
+ },
76
+ "node_modules/@jridgewell/sourcemap-codec": {
77
+ "version": "1.5.0",
78
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
79
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
80
+ "dev": true
81
+ },
82
+ "node_modules/@jridgewell/trace-mapping": {
83
+ "version": "0.3.25",
84
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
85
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
86
+ "dev": true,
87
+ "dependencies": {
88
+ "@jridgewell/resolve-uri": "^3.1.0",
89
+ "@jridgewell/sourcemap-codec": "^1.4.14"
90
+ }
91
+ },
92
+ "node_modules/@nodelib/fs.scandir": {
93
+ "version": "2.1.5",
94
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
95
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
96
+ "dev": true,
97
+ "dependencies": {
98
+ "@nodelib/fs.stat": "2.0.5",
99
+ "run-parallel": "^1.1.9"
100
+ },
101
+ "engines": {
102
+ "node": ">= 8"
103
+ }
104
+ },
105
+ "node_modules/@nodelib/fs.stat": {
106
+ "version": "2.0.5",
107
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
108
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
109
+ "dev": true,
110
+ "engines": {
111
+ "node": ">= 8"
112
+ }
113
+ },
114
+ "node_modules/@nodelib/fs.walk": {
115
+ "version": "1.2.8",
116
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
117
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
118
+ "dev": true,
119
+ "dependencies": {
120
+ "@nodelib/fs.scandir": "2.1.5",
121
+ "fastq": "^1.6.0"
122
+ },
123
+ "engines": {
124
+ "node": ">= 8"
125
+ }
126
+ },
127
+ "node_modules/@pkgjs/parseargs": {
128
+ "version": "0.11.0",
129
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
130
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
131
+ "dev": true,
132
+ "optional": true,
133
+ "engines": {
134
+ "node": ">=14"
135
+ }
136
+ },
137
+ "node_modules/ansi-regex": {
138
+ "version": "6.0.1",
139
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
140
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
141
+ "dev": true,
142
+ "engines": {
143
+ "node": ">=12"
144
+ },
145
+ "funding": {
146
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
147
+ }
148
+ },
149
+ "node_modules/ansi-styles": {
150
+ "version": "6.2.1",
151
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
152
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
153
+ "dev": true,
154
+ "engines": {
155
+ "node": ">=12"
156
+ },
157
+ "funding": {
158
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
159
+ }
160
+ },
161
+ "node_modules/any-promise": {
162
+ "version": "1.3.0",
163
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
164
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
165
+ "dev": true
166
+ },
167
+ "node_modules/anymatch": {
168
+ "version": "3.1.3",
169
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
170
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
171
+ "dev": true,
172
+ "dependencies": {
173
+ "normalize-path": "^3.0.0",
174
+ "picomatch": "^2.0.4"
175
+ },
176
+ "engines": {
177
+ "node": ">= 8"
178
+ }
179
+ },
180
+ "node_modules/arg": {
181
+ "version": "5.0.2",
182
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
183
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
184
+ "dev": true
185
+ },
186
+ "node_modules/balanced-match": {
187
+ "version": "1.0.2",
188
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
189
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
190
+ "dev": true
191
+ },
192
+ "node_modules/binary-extensions": {
193
+ "version": "2.3.0",
194
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
195
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
196
+ "dev": true,
197
+ "engines": {
198
+ "node": ">=8"
199
+ },
200
+ "funding": {
201
+ "url": "https://github.com/sponsors/sindresorhus"
202
+ }
203
+ },
204
+ "node_modules/brace-expansion": {
205
+ "version": "2.0.1",
206
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
207
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
208
+ "dev": true,
209
+ "dependencies": {
210
+ "balanced-match": "^1.0.0"
211
+ }
212
+ },
213
+ "node_modules/braces": {
214
+ "version": "3.0.3",
215
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
216
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
217
+ "dev": true,
218
+ "dependencies": {
219
+ "fill-range": "^7.1.1"
220
+ },
221
+ "engines": {
222
+ "node": ">=8"
223
+ }
224
+ },
225
+ "node_modules/camelcase-css": {
226
+ "version": "2.0.1",
227
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
228
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
229
+ "dev": true,
230
+ "engines": {
231
+ "node": ">= 6"
232
+ }
233
+ },
234
+ "node_modules/chokidar": {
235
+ "version": "3.6.0",
236
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
237
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
238
+ "dev": true,
239
+ "dependencies": {
240
+ "anymatch": "~3.1.2",
241
+ "braces": "~3.0.2",
242
+ "glob-parent": "~5.1.2",
243
+ "is-binary-path": "~2.1.0",
244
+ "is-glob": "~4.0.1",
245
+ "normalize-path": "~3.0.0",
246
+ "readdirp": "~3.6.0"
247
+ },
248
+ "engines": {
249
+ "node": ">= 8.10.0"
250
+ },
251
+ "funding": {
252
+ "url": "https://paulmillr.com/funding/"
253
+ },
254
+ "optionalDependencies": {
255
+ "fsevents": "~2.3.2"
256
+ }
257
+ },
258
+ "node_modules/chokidar/node_modules/glob-parent": {
259
+ "version": "5.1.2",
260
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
261
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
262
+ "dev": true,
263
+ "dependencies": {
264
+ "is-glob": "^4.0.1"
265
+ },
266
+ "engines": {
267
+ "node": ">= 6"
268
+ }
269
+ },
270
+ "node_modules/color-convert": {
271
+ "version": "2.0.1",
272
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
273
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
274
+ "dev": true,
275
+ "dependencies": {
276
+ "color-name": "~1.1.4"
277
+ },
278
+ "engines": {
279
+ "node": ">=7.0.0"
280
+ }
281
+ },
282
+ "node_modules/color-name": {
283
+ "version": "1.1.4",
284
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
285
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
286
+ "dev": true
287
+ },
288
+ "node_modules/commander": {
289
+ "version": "4.1.1",
290
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
291
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
292
+ "dev": true,
293
+ "engines": {
294
+ "node": ">= 6"
295
+ }
296
+ },
297
+ "node_modules/cross-spawn": {
298
+ "version": "7.0.3",
299
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
300
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
301
+ "dev": true,
302
+ "dependencies": {
303
+ "path-key": "^3.1.0",
304
+ "shebang-command": "^2.0.0",
305
+ "which": "^2.0.1"
306
+ },
307
+ "engines": {
308
+ "node": ">= 8"
309
+ }
310
+ },
311
+ "node_modules/cssesc": {
312
+ "version": "3.0.0",
313
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
314
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
315
+ "dev": true,
316
+ "bin": {
317
+ "cssesc": "bin/cssesc"
318
+ },
319
+ "engines": {
320
+ "node": ">=4"
321
+ }
322
+ },
323
+ "node_modules/didyoumean": {
324
+ "version": "1.2.2",
325
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
326
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
327
+ "dev": true
328
+ },
329
+ "node_modules/dlv": {
330
+ "version": "1.1.3",
331
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
332
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
333
+ "dev": true
334
+ },
335
+ "node_modules/eastasianwidth": {
336
+ "version": "0.2.0",
337
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
338
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
339
+ "dev": true
340
+ },
341
+ "node_modules/emoji-regex": {
342
+ "version": "9.2.2",
343
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
344
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
345
+ "dev": true
346
+ },
347
+ "node_modules/fast-glob": {
348
+ "version": "3.3.2",
349
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
350
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
351
+ "dev": true,
352
+ "dependencies": {
353
+ "@nodelib/fs.stat": "^2.0.2",
354
+ "@nodelib/fs.walk": "^1.2.3",
355
+ "glob-parent": "^5.1.2",
356
+ "merge2": "^1.3.0",
357
+ "micromatch": "^4.0.4"
358
+ },
359
+ "engines": {
360
+ "node": ">=8.6.0"
361
+ }
362
+ },
363
+ "node_modules/fast-glob/node_modules/glob-parent": {
364
+ "version": "5.1.2",
365
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
366
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
367
+ "dev": true,
368
+ "dependencies": {
369
+ "is-glob": "^4.0.1"
370
+ },
371
+ "engines": {
372
+ "node": ">= 6"
373
+ }
374
+ },
375
+ "node_modules/fastq": {
376
+ "version": "1.17.1",
377
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
378
+ "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
379
+ "dev": true,
380
+ "dependencies": {
381
+ "reusify": "^1.0.4"
382
+ }
383
+ },
384
+ "node_modules/fill-range": {
385
+ "version": "7.1.1",
386
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
387
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
388
+ "dev": true,
389
+ "dependencies": {
390
+ "to-regex-range": "^5.0.1"
391
+ },
392
+ "engines": {
393
+ "node": ">=8"
394
+ }
395
+ },
396
+ "node_modules/foreground-child": {
397
+ "version": "3.2.1",
398
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
399
+ "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
400
+ "dev": true,
401
+ "dependencies": {
402
+ "cross-spawn": "^7.0.0",
403
+ "signal-exit": "^4.0.1"
404
+ },
405
+ "engines": {
406
+ "node": ">=14"
407
+ },
408
+ "funding": {
409
+ "url": "https://github.com/sponsors/isaacs"
410
+ }
411
+ },
412
+ "node_modules/fsevents": {
413
+ "version": "2.3.3",
414
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
415
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
416
+ "dev": true,
417
+ "hasInstallScript": true,
418
+ "optional": true,
419
+ "os": [
420
+ "darwin"
421
+ ],
422
+ "engines": {
423
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
424
+ }
425
+ },
426
+ "node_modules/function-bind": {
427
+ "version": "1.1.2",
428
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
429
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
430
+ "dev": true,
431
+ "funding": {
432
+ "url": "https://github.com/sponsors/ljharb"
433
+ }
434
+ },
435
+ "node_modules/glob": {
436
+ "version": "10.4.5",
437
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
438
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
439
+ "dev": true,
440
+ "dependencies": {
441
+ "foreground-child": "^3.1.0",
442
+ "jackspeak": "^3.1.2",
443
+ "minimatch": "^9.0.4",
444
+ "minipass": "^7.1.2",
445
+ "package-json-from-dist": "^1.0.0",
446
+ "path-scurry": "^1.11.1"
447
+ },
448
+ "bin": {
449
+ "glob": "dist/esm/bin.mjs"
450
+ },
451
+ "funding": {
452
+ "url": "https://github.com/sponsors/isaacs"
453
+ }
454
+ },
455
+ "node_modules/glob-parent": {
456
+ "version": "6.0.2",
457
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
458
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
459
+ "dev": true,
460
+ "dependencies": {
461
+ "is-glob": "^4.0.3"
462
+ },
463
+ "engines": {
464
+ "node": ">=10.13.0"
465
+ }
466
+ },
467
+ "node_modules/hasown": {
468
+ "version": "2.0.2",
469
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
470
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
471
+ "dev": true,
472
+ "dependencies": {
473
+ "function-bind": "^1.1.2"
474
+ },
475
+ "engines": {
476
+ "node": ">= 0.4"
477
+ }
478
+ },
479
+ "node_modules/is-binary-path": {
480
+ "version": "2.1.0",
481
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
482
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
483
+ "dev": true,
484
+ "dependencies": {
485
+ "binary-extensions": "^2.0.0"
486
+ },
487
+ "engines": {
488
+ "node": ">=8"
489
+ }
490
+ },
491
+ "node_modules/is-core-module": {
492
+ "version": "2.14.0",
493
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz",
494
+ "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==",
495
+ "dev": true,
496
+ "dependencies": {
497
+ "hasown": "^2.0.2"
498
+ },
499
+ "engines": {
500
+ "node": ">= 0.4"
501
+ },
502
+ "funding": {
503
+ "url": "https://github.com/sponsors/ljharb"
504
+ }
505
+ },
506
+ "node_modules/is-extglob": {
507
+ "version": "2.1.1",
508
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
509
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
510
+ "dev": true,
511
+ "engines": {
512
+ "node": ">=0.10.0"
513
+ }
514
+ },
515
+ "node_modules/is-fullwidth-code-point": {
516
+ "version": "3.0.0",
517
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
518
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
519
+ "dev": true,
520
+ "engines": {
521
+ "node": ">=8"
522
+ }
523
+ },
524
+ "node_modules/is-glob": {
525
+ "version": "4.0.3",
526
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
527
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
528
+ "dev": true,
529
+ "dependencies": {
530
+ "is-extglob": "^2.1.1"
531
+ },
532
+ "engines": {
533
+ "node": ">=0.10.0"
534
+ }
535
+ },
536
+ "node_modules/is-number": {
537
+ "version": "7.0.0",
538
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
539
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
540
+ "dev": true,
541
+ "engines": {
542
+ "node": ">=0.12.0"
543
+ }
544
+ },
545
+ "node_modules/isexe": {
546
+ "version": "2.0.0",
547
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
548
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
549
+ "dev": true
550
+ },
551
+ "node_modules/jackspeak": {
552
+ "version": "3.4.3",
553
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
554
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
555
+ "dev": true,
556
+ "dependencies": {
557
+ "@isaacs/cliui": "^8.0.2"
558
+ },
559
+ "funding": {
560
+ "url": "https://github.com/sponsors/isaacs"
561
+ },
562
+ "optionalDependencies": {
563
+ "@pkgjs/parseargs": "^0.11.0"
564
+ }
565
+ },
566
+ "node_modules/jiti": {
567
+ "version": "1.21.6",
568
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
569
+ "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
570
+ "dev": true,
571
+ "bin": {
572
+ "jiti": "bin/jiti.js"
573
+ }
574
+ },
575
+ "node_modules/lilconfig": {
576
+ "version": "2.1.0",
577
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
578
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
579
+ "dev": true,
580
+ "engines": {
581
+ "node": ">=10"
582
+ }
583
+ },
584
+ "node_modules/lines-and-columns": {
585
+ "version": "1.2.4",
586
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
587
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
588
+ "dev": true
589
+ },
590
+ "node_modules/lru-cache": {
591
+ "version": "10.4.3",
592
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
593
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
594
+ "dev": true
595
+ },
596
+ "node_modules/merge2": {
597
+ "version": "1.4.1",
598
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
599
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
600
+ "dev": true,
601
+ "engines": {
602
+ "node": ">= 8"
603
+ }
604
+ },
605
+ "node_modules/micromatch": {
606
+ "version": "4.0.7",
607
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
608
+ "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
609
+ "dev": true,
610
+ "dependencies": {
611
+ "braces": "^3.0.3",
612
+ "picomatch": "^2.3.1"
613
+ },
614
+ "engines": {
615
+ "node": ">=8.6"
616
+ }
617
+ },
618
+ "node_modules/minimatch": {
619
+ "version": "9.0.5",
620
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
621
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
622
+ "dev": true,
623
+ "dependencies": {
624
+ "brace-expansion": "^2.0.1"
625
+ },
626
+ "engines": {
627
+ "node": ">=16 || 14 >=14.17"
628
+ },
629
+ "funding": {
630
+ "url": "https://github.com/sponsors/isaacs"
631
+ }
632
+ },
633
+ "node_modules/minipass": {
634
+ "version": "7.1.2",
635
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
636
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
637
+ "dev": true,
638
+ "engines": {
639
+ "node": ">=16 || 14 >=14.17"
640
+ }
641
+ },
642
+ "node_modules/mz": {
643
+ "version": "2.7.0",
644
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
645
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
646
+ "dev": true,
647
+ "dependencies": {
648
+ "any-promise": "^1.0.0",
649
+ "object-assign": "^4.0.1",
650
+ "thenify-all": "^1.0.0"
651
+ }
652
+ },
653
+ "node_modules/nanoid": {
654
+ "version": "3.3.7",
655
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
656
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
657
+ "dev": true,
658
+ "funding": [
659
+ {
660
+ "type": "github",
661
+ "url": "https://github.com/sponsors/ai"
662
+ }
663
+ ],
664
+ "bin": {
665
+ "nanoid": "bin/nanoid.cjs"
666
+ },
667
+ "engines": {
668
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
669
+ }
670
+ },
671
+ "node_modules/normalize-path": {
672
+ "version": "3.0.0",
673
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
674
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
675
+ "dev": true,
676
+ "engines": {
677
+ "node": ">=0.10.0"
678
+ }
679
+ },
680
+ "node_modules/object-assign": {
681
+ "version": "4.1.1",
682
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
683
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
684
+ "dev": true,
685
+ "engines": {
686
+ "node": ">=0.10.0"
687
+ }
688
+ },
689
+ "node_modules/object-hash": {
690
+ "version": "3.0.0",
691
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
692
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
693
+ "dev": true,
694
+ "engines": {
695
+ "node": ">= 6"
696
+ }
697
+ },
698
+ "node_modules/package-json-from-dist": {
699
+ "version": "1.0.0",
700
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
701
+ "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
702
+ "dev": true
703
+ },
704
+ "node_modules/path-key": {
705
+ "version": "3.1.1",
706
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
707
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
708
+ "dev": true,
709
+ "engines": {
710
+ "node": ">=8"
711
+ }
712
+ },
713
+ "node_modules/path-parse": {
714
+ "version": "1.0.7",
715
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
716
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
717
+ "dev": true
718
+ },
719
+ "node_modules/path-scurry": {
720
+ "version": "1.11.1",
721
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
722
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
723
+ "dev": true,
724
+ "dependencies": {
725
+ "lru-cache": "^10.2.0",
726
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
727
+ },
728
+ "engines": {
729
+ "node": ">=16 || 14 >=14.18"
730
+ },
731
+ "funding": {
732
+ "url": "https://github.com/sponsors/isaacs"
733
+ }
734
+ },
735
+ "node_modules/picocolors": {
736
+ "version": "1.0.1",
737
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
738
+ "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
739
+ "dev": true
740
+ },
741
+ "node_modules/picomatch": {
742
+ "version": "2.3.1",
743
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
744
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
745
+ "dev": true,
746
+ "engines": {
747
+ "node": ">=8.6"
748
+ },
749
+ "funding": {
750
+ "url": "https://github.com/sponsors/jonschlinkert"
751
+ }
752
+ },
753
+ "node_modules/pify": {
754
+ "version": "2.3.0",
755
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
756
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
757
+ "dev": true,
758
+ "engines": {
759
+ "node": ">=0.10.0"
760
+ }
761
+ },
762
+ "node_modules/pirates": {
763
+ "version": "4.0.6",
764
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
765
+ "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
766
+ "dev": true,
767
+ "engines": {
768
+ "node": ">= 6"
769
+ }
770
+ },
771
+ "node_modules/postcss": {
772
+ "version": "8.4.39",
773
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
774
+ "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
775
+ "dev": true,
776
+ "funding": [
777
+ {
778
+ "type": "opencollective",
779
+ "url": "https://opencollective.com/postcss/"
780
+ },
781
+ {
782
+ "type": "tidelift",
783
+ "url": "https://tidelift.com/funding/github/npm/postcss"
784
+ },
785
+ {
786
+ "type": "github",
787
+ "url": "https://github.com/sponsors/ai"
788
+ }
789
+ ],
790
+ "dependencies": {
791
+ "nanoid": "^3.3.7",
792
+ "picocolors": "^1.0.1",
793
+ "source-map-js": "^1.2.0"
794
+ },
795
+ "engines": {
796
+ "node": "^10 || ^12 || >=14"
797
+ }
798
+ },
799
+ "node_modules/postcss-import": {
800
+ "version": "15.1.0",
801
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
802
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
803
+ "dev": true,
804
+ "dependencies": {
805
+ "postcss-value-parser": "^4.0.0",
806
+ "read-cache": "^1.0.0",
807
+ "resolve": "^1.1.7"
808
+ },
809
+ "engines": {
810
+ "node": ">=14.0.0"
811
+ },
812
+ "peerDependencies": {
813
+ "postcss": "^8.0.0"
814
+ }
815
+ },
816
+ "node_modules/postcss-js": {
817
+ "version": "4.0.1",
818
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
819
+ "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
820
+ "dev": true,
821
+ "dependencies": {
822
+ "camelcase-css": "^2.0.1"
823
+ },
824
+ "engines": {
825
+ "node": "^12 || ^14 || >= 16"
826
+ },
827
+ "funding": {
828
+ "type": "opencollective",
829
+ "url": "https://opencollective.com/postcss/"
830
+ },
831
+ "peerDependencies": {
832
+ "postcss": "^8.4.21"
833
+ }
834
+ },
835
+ "node_modules/postcss-load-config": {
836
+ "version": "4.0.2",
837
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
838
+ "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
839
+ "dev": true,
840
+ "funding": [
841
+ {
842
+ "type": "opencollective",
843
+ "url": "https://opencollective.com/postcss/"
844
+ },
845
+ {
846
+ "type": "github",
847
+ "url": "https://github.com/sponsors/ai"
848
+ }
849
+ ],
850
+ "dependencies": {
851
+ "lilconfig": "^3.0.0",
852
+ "yaml": "^2.3.4"
853
+ },
854
+ "engines": {
855
+ "node": ">= 14"
856
+ },
857
+ "peerDependencies": {
858
+ "postcss": ">=8.0.9",
859
+ "ts-node": ">=9.0.0"
860
+ },
861
+ "peerDependenciesMeta": {
862
+ "postcss": {
863
+ "optional": true
864
+ },
865
+ "ts-node": {
866
+ "optional": true
867
+ }
868
+ }
869
+ },
870
+ "node_modules/postcss-load-config/node_modules/lilconfig": {
871
+ "version": "3.1.2",
872
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz",
873
+ "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==",
874
+ "dev": true,
875
+ "engines": {
876
+ "node": ">=14"
877
+ },
878
+ "funding": {
879
+ "url": "https://github.com/sponsors/antonk52"
880
+ }
881
+ },
882
+ "node_modules/postcss-nested": {
883
+ "version": "6.0.1",
884
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
885
+ "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
886
+ "dev": true,
887
+ "dependencies": {
888
+ "postcss-selector-parser": "^6.0.11"
889
+ },
890
+ "engines": {
891
+ "node": ">=12.0"
892
+ },
893
+ "funding": {
894
+ "type": "opencollective",
895
+ "url": "https://opencollective.com/postcss/"
896
+ },
897
+ "peerDependencies": {
898
+ "postcss": "^8.2.14"
899
+ }
900
+ },
901
+ "node_modules/postcss-selector-parser": {
902
+ "version": "6.1.0",
903
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz",
904
+ "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==",
905
+ "dev": true,
906
+ "dependencies": {
907
+ "cssesc": "^3.0.0",
908
+ "util-deprecate": "^1.0.2"
909
+ },
910
+ "engines": {
911
+ "node": ">=4"
912
+ }
913
+ },
914
+ "node_modules/postcss-value-parser": {
915
+ "version": "4.2.0",
916
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
917
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
918
+ "dev": true
919
+ },
920
+ "node_modules/queue-microtask": {
921
+ "version": "1.2.3",
922
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
923
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
924
+ "dev": true,
925
+ "funding": [
926
+ {
927
+ "type": "github",
928
+ "url": "https://github.com/sponsors/feross"
929
+ },
930
+ {
931
+ "type": "patreon",
932
+ "url": "https://www.patreon.com/feross"
933
+ },
934
+ {
935
+ "type": "consulting",
936
+ "url": "https://feross.org/support"
937
+ }
938
+ ]
939
+ },
940
+ "node_modules/read-cache": {
941
+ "version": "1.0.0",
942
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
943
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
944
+ "dev": true,
945
+ "dependencies": {
946
+ "pify": "^2.3.0"
947
+ }
948
+ },
949
+ "node_modules/readdirp": {
950
+ "version": "3.6.0",
951
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
952
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
953
+ "dev": true,
954
+ "dependencies": {
955
+ "picomatch": "^2.2.1"
956
+ },
957
+ "engines": {
958
+ "node": ">=8.10.0"
959
+ }
960
+ },
961
+ "node_modules/resolve": {
962
+ "version": "1.22.8",
963
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
964
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
965
+ "dev": true,
966
+ "dependencies": {
967
+ "is-core-module": "^2.13.0",
968
+ "path-parse": "^1.0.7",
969
+ "supports-preserve-symlinks-flag": "^1.0.0"
970
+ },
971
+ "bin": {
972
+ "resolve": "bin/resolve"
973
+ },
974
+ "funding": {
975
+ "url": "https://github.com/sponsors/ljharb"
976
+ }
977
+ },
978
+ "node_modules/reusify": {
979
+ "version": "1.0.4",
980
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
981
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
982
+ "dev": true,
983
+ "engines": {
984
+ "iojs": ">=1.0.0",
985
+ "node": ">=0.10.0"
986
+ }
987
+ },
988
+ "node_modules/run-parallel": {
989
+ "version": "1.2.0",
990
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
991
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
992
+ "dev": true,
993
+ "funding": [
994
+ {
995
+ "type": "github",
996
+ "url": "https://github.com/sponsors/feross"
997
+ },
998
+ {
999
+ "type": "patreon",
1000
+ "url": "https://www.patreon.com/feross"
1001
+ },
1002
+ {
1003
+ "type": "consulting",
1004
+ "url": "https://feross.org/support"
1005
+ }
1006
+ ],
1007
+ "dependencies": {
1008
+ "queue-microtask": "^1.2.2"
1009
+ }
1010
+ },
1011
+ "node_modules/shebang-command": {
1012
+ "version": "2.0.0",
1013
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1014
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1015
+ "dev": true,
1016
+ "dependencies": {
1017
+ "shebang-regex": "^3.0.0"
1018
+ },
1019
+ "engines": {
1020
+ "node": ">=8"
1021
+ }
1022
+ },
1023
+ "node_modules/shebang-regex": {
1024
+ "version": "3.0.0",
1025
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1026
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1027
+ "dev": true,
1028
+ "engines": {
1029
+ "node": ">=8"
1030
+ }
1031
+ },
1032
+ "node_modules/signal-exit": {
1033
+ "version": "4.1.0",
1034
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
1035
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
1036
+ "dev": true,
1037
+ "engines": {
1038
+ "node": ">=14"
1039
+ },
1040
+ "funding": {
1041
+ "url": "https://github.com/sponsors/isaacs"
1042
+ }
1043
+ },
1044
+ "node_modules/source-map-js": {
1045
+ "version": "1.2.0",
1046
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
1047
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
1048
+ "dev": true,
1049
+ "engines": {
1050
+ "node": ">=0.10.0"
1051
+ }
1052
+ },
1053
+ "node_modules/string-width": {
1054
+ "version": "5.1.2",
1055
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
1056
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
1057
+ "dev": true,
1058
+ "dependencies": {
1059
+ "eastasianwidth": "^0.2.0",
1060
+ "emoji-regex": "^9.2.2",
1061
+ "strip-ansi": "^7.0.1"
1062
+ },
1063
+ "engines": {
1064
+ "node": ">=12"
1065
+ },
1066
+ "funding": {
1067
+ "url": "https://github.com/sponsors/sindresorhus"
1068
+ }
1069
+ },
1070
+ "node_modules/string-width-cjs": {
1071
+ "name": "string-width",
1072
+ "version": "4.2.3",
1073
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1074
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1075
+ "dev": true,
1076
+ "dependencies": {
1077
+ "emoji-regex": "^8.0.0",
1078
+ "is-fullwidth-code-point": "^3.0.0",
1079
+ "strip-ansi": "^6.0.1"
1080
+ },
1081
+ "engines": {
1082
+ "node": ">=8"
1083
+ }
1084
+ },
1085
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
1086
+ "version": "5.0.1",
1087
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1088
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1089
+ "dev": true,
1090
+ "engines": {
1091
+ "node": ">=8"
1092
+ }
1093
+ },
1094
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
1095
+ "version": "8.0.0",
1096
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
1097
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
1098
+ "dev": true
1099
+ },
1100
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
1101
+ "version": "6.0.1",
1102
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1103
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1104
+ "dev": true,
1105
+ "dependencies": {
1106
+ "ansi-regex": "^5.0.1"
1107
+ },
1108
+ "engines": {
1109
+ "node": ">=8"
1110
+ }
1111
+ },
1112
+ "node_modules/strip-ansi": {
1113
+ "version": "7.1.0",
1114
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
1115
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
1116
+ "dev": true,
1117
+ "dependencies": {
1118
+ "ansi-regex": "^6.0.1"
1119
+ },
1120
+ "engines": {
1121
+ "node": ">=12"
1122
+ },
1123
+ "funding": {
1124
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
1125
+ }
1126
+ },
1127
+ "node_modules/strip-ansi-cjs": {
1128
+ "name": "strip-ansi",
1129
+ "version": "6.0.1",
1130
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1131
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1132
+ "dev": true,
1133
+ "dependencies": {
1134
+ "ansi-regex": "^5.0.1"
1135
+ },
1136
+ "engines": {
1137
+ "node": ">=8"
1138
+ }
1139
+ },
1140
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
1141
+ "version": "5.0.1",
1142
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1143
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1144
+ "dev": true,
1145
+ "engines": {
1146
+ "node": ">=8"
1147
+ }
1148
+ },
1149
+ "node_modules/sucrase": {
1150
+ "version": "3.35.0",
1151
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
1152
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
1153
+ "dev": true,
1154
+ "dependencies": {
1155
+ "@jridgewell/gen-mapping": "^0.3.2",
1156
+ "commander": "^4.0.0",
1157
+ "glob": "^10.3.10",
1158
+ "lines-and-columns": "^1.1.6",
1159
+ "mz": "^2.7.0",
1160
+ "pirates": "^4.0.1",
1161
+ "ts-interface-checker": "^0.1.9"
1162
+ },
1163
+ "bin": {
1164
+ "sucrase": "bin/sucrase",
1165
+ "sucrase-node": "bin/sucrase-node"
1166
+ },
1167
+ "engines": {
1168
+ "node": ">=16 || 14 >=14.17"
1169
+ }
1170
+ },
1171
+ "node_modules/supports-preserve-symlinks-flag": {
1172
+ "version": "1.0.0",
1173
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
1174
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
1175
+ "dev": true,
1176
+ "engines": {
1177
+ "node": ">= 0.4"
1178
+ },
1179
+ "funding": {
1180
+ "url": "https://github.com/sponsors/ljharb"
1181
+ }
1182
+ },
1183
+ "node_modules/tailwindcss": {
1184
+ "version": "3.4.4",
1185
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
1186
+ "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
1187
+ "dev": true,
1188
+ "dependencies": {
1189
+ "@alloc/quick-lru": "^5.2.0",
1190
+ "arg": "^5.0.2",
1191
+ "chokidar": "^3.5.3",
1192
+ "didyoumean": "^1.2.2",
1193
+ "dlv": "^1.1.3",
1194
+ "fast-glob": "^3.3.0",
1195
+ "glob-parent": "^6.0.2",
1196
+ "is-glob": "^4.0.3",
1197
+ "jiti": "^1.21.0",
1198
+ "lilconfig": "^2.1.0",
1199
+ "micromatch": "^4.0.5",
1200
+ "normalize-path": "^3.0.0",
1201
+ "object-hash": "^3.0.0",
1202
+ "picocolors": "^1.0.0",
1203
+ "postcss": "^8.4.23",
1204
+ "postcss-import": "^15.1.0",
1205
+ "postcss-js": "^4.0.1",
1206
+ "postcss-load-config": "^4.0.1",
1207
+ "postcss-nested": "^6.0.1",
1208
+ "postcss-selector-parser": "^6.0.11",
1209
+ "resolve": "^1.22.2",
1210
+ "sucrase": "^3.32.0"
1211
+ },
1212
+ "bin": {
1213
+ "tailwind": "lib/cli.js",
1214
+ "tailwindcss": "lib/cli.js"
1215
+ },
1216
+ "engines": {
1217
+ "node": ">=14.0.0"
1218
+ }
1219
+ },
1220
+ "node_modules/thenify": {
1221
+ "version": "3.3.1",
1222
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
1223
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
1224
+ "dev": true,
1225
+ "dependencies": {
1226
+ "any-promise": "^1.0.0"
1227
+ }
1228
+ },
1229
+ "node_modules/thenify-all": {
1230
+ "version": "1.6.0",
1231
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
1232
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
1233
+ "dev": true,
1234
+ "dependencies": {
1235
+ "thenify": ">= 3.1.0 < 4"
1236
+ },
1237
+ "engines": {
1238
+ "node": ">=0.8"
1239
+ }
1240
+ },
1241
+ "node_modules/to-regex-range": {
1242
+ "version": "5.0.1",
1243
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1244
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1245
+ "dev": true,
1246
+ "dependencies": {
1247
+ "is-number": "^7.0.0"
1248
+ },
1249
+ "engines": {
1250
+ "node": ">=8.0"
1251
+ }
1252
+ },
1253
+ "node_modules/ts-interface-checker": {
1254
+ "version": "0.1.13",
1255
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
1256
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
1257
+ "dev": true
1258
+ },
1259
+ "node_modules/util-deprecate": {
1260
+ "version": "1.0.2",
1261
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1262
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
1263
+ "dev": true
1264
+ },
1265
+ "node_modules/which": {
1266
+ "version": "2.0.2",
1267
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1268
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1269
+ "dev": true,
1270
+ "dependencies": {
1271
+ "isexe": "^2.0.0"
1272
+ },
1273
+ "bin": {
1274
+ "node-which": "bin/node-which"
1275
+ },
1276
+ "engines": {
1277
+ "node": ">= 8"
1278
+ }
1279
+ },
1280
+ "node_modules/wrap-ansi": {
1281
+ "version": "8.1.0",
1282
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
1283
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
1284
+ "dev": true,
1285
+ "dependencies": {
1286
+ "ansi-styles": "^6.1.0",
1287
+ "string-width": "^5.0.1",
1288
+ "strip-ansi": "^7.0.1"
1289
+ },
1290
+ "engines": {
1291
+ "node": ">=12"
1292
+ },
1293
+ "funding": {
1294
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1295
+ }
1296
+ },
1297
+ "node_modules/wrap-ansi-cjs": {
1298
+ "name": "wrap-ansi",
1299
+ "version": "7.0.0",
1300
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1301
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1302
+ "dev": true,
1303
+ "dependencies": {
1304
+ "ansi-styles": "^4.0.0",
1305
+ "string-width": "^4.1.0",
1306
+ "strip-ansi": "^6.0.0"
1307
+ },
1308
+ "engines": {
1309
+ "node": ">=10"
1310
+ },
1311
+ "funding": {
1312
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1313
+ }
1314
+ },
1315
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
1316
+ "version": "5.0.1",
1317
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1318
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1319
+ "dev": true,
1320
+ "engines": {
1321
+ "node": ">=8"
1322
+ }
1323
+ },
1324
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
1325
+ "version": "4.3.0",
1326
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1327
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1328
+ "dev": true,
1329
+ "dependencies": {
1330
+ "color-convert": "^2.0.1"
1331
+ },
1332
+ "engines": {
1333
+ "node": ">=8"
1334
+ },
1335
+ "funding": {
1336
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1337
+ }
1338
+ },
1339
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
1340
+ "version": "8.0.0",
1341
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
1342
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
1343
+ "dev": true
1344
+ },
1345
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
1346
+ "version": "4.2.3",
1347
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1348
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1349
+ "dev": true,
1350
+ "dependencies": {
1351
+ "emoji-regex": "^8.0.0",
1352
+ "is-fullwidth-code-point": "^3.0.0",
1353
+ "strip-ansi": "^6.0.1"
1354
+ },
1355
+ "engines": {
1356
+ "node": ">=8"
1357
+ }
1358
+ },
1359
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
1360
+ "version": "6.0.1",
1361
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1362
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1363
+ "dev": true,
1364
+ "dependencies": {
1365
+ "ansi-regex": "^5.0.1"
1366
+ },
1367
+ "engines": {
1368
+ "node": ">=8"
1369
+ }
1370
+ },
1371
+ "node_modules/yaml": {
1372
+ "version": "2.4.5",
1373
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz",
1374
+ "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==",
1375
+ "dev": true,
1376
+ "bin": {
1377
+ "yaml": "bin.mjs"
1378
+ },
1379
+ "engines": {
1380
+ "node": ">= 14"
1381
+ }
1382
+ }
1383
+ }
1384
+ }
package.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "auto-notification",
3
+ "version": "1.0.0",
4
+ "main": "server.js",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "start": "node server.js"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "ISC",
12
+ "description": "",
13
+ "devDependencies": {
14
+ "tailwindcss": "^3.4.4"
15
+ }
16
+ }
requirements.txt ADDED
Binary file (178 Bytes). View file
 
server.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require('express');
2
+ const http = require('http');
3
+ const socketIo = require('socket.io');
4
+
5
+ const app = express();
6
+ const server = http.createServer(app);
7
+ const io = socketIo(server);
8
+
9
+ io.on('connection', (socket) => {
10
+ console.log('a user connected');
11
+ socket.on('disconnect', () => {
12
+ console.log('user disconnected');
13
+ });
14
+ });
15
+
16
+ // Listen for messages from Flask app
17
+ io.on('new_message', (data) => {
18
+ io.emit('new_message', data);
19
+ });
20
+
21
+ server.listen(3000, () => {
22
+ console.log('listening on *:3000');
23
+ });
tailwind.config.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('tailwindcss').Config} */
2
+ module.exports = {
3
+ content: [],
4
+ theme: {
5
+ extend: {},
6
+ },
7
+ plugins: [],
8
+ }
9
+
templates/index.html ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Health Notification App</title>
7
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ </head>
10
+ <body class="bg-gray-100">
11
+ <div class="flex items-center justify-center min-h-screen">
12
+ <div class="container mx-auto p-4 flex flex-col items-center justify-center max-w-sm p-6 bg-white border border-gray-200 rounded-lg shadow hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700">
13
+ <h1 class="text-3xl font-bold mb-4">Elderly Companion App</h1>
14
+
15
+ <!-- Purpose Selection Buttons -->
16
+ <div class="mb-8 flex">
17
+ <button id="notificationBtn" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline transition duration-300 ease-in-out transform hover:scale-105" onclick="toggleForms('notification')">Schedule a Notification</button>
18
+ <button id="appointmentBtn" class="ml-4 bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline transition duration-300 ease-in-out transform hover:scale-105" onclick="toggleForms('appointment')">Book an Appointment</button>
19
+ </div>
20
+
21
+ <!-- Notification Form -->
22
+ <div id="notificationFormDiv" class="bg-white p-6 rounded-lg shadow-md mb-8 hidden w-full md:w-3/2 transition duration-500 ease-in-out transform">
23
+ <h2 class="text-2xl font-semibold mb-4">Schedule a Notification</h2>
24
+ <form id="notificationForm" class="space-y-4">
25
+ <div>
26
+ <label for="name" class="block text-sm font-medium text-gray-700">Name</label>
27
+ <input type="text" id="name" name="name" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
28
+ </div>
29
+ <div>
30
+ <label for="email" class="block text-sm font-medium text-gray-700">Email</label>
31
+ <input type="email" id="email" name="email" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
32
+ </div>
33
+ <div>
34
+ <label for="condition" class="block text-sm font-medium text-gray-700">Condition</label>
35
+ <input type="text" id="condition" name="condition" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
36
+ </div>
37
+ <div>
38
+ <label for="age" class="block text-sm font-medium text-gray-700">Age</label>
39
+ <input type="number" id="age" name="age" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
40
+ </div>
41
+ <div>
42
+ <label for="notificationType" class="block text-sm font-medium text-gray-700">Notification Type</label>
43
+ <select id="notificationType" name="notificationType" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
44
+ <option value="motivational">Motivational</option>
45
+ <option value="medicational">Medicational</option>
46
+ <option value="advice">Advice</option>
47
+ </select>
48
+ </div>
49
+ <div>
50
+ <label for="time" class="block text-sm font-medium text-gray-700">Time (optional)</label>
51
+ <input type="time" id="time" name="time" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
52
+ </div>
53
+ <button type="submit" class="w-full bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline transition duration-300 ease-in-out transform hover:scale-105">Schedule Notification</button>
54
+ </form>
55
+ </div>
56
+
57
+ <!-- Appointment Booking Form -->
58
+ <div id="appointmentFormDiv" class="bg-white p-6 rounded-lg shadow-md hidden w-full md:w-3/2 transition duration-500 ease-in-out transform">
59
+ <h2 class="text-2xl font-semibold mb-4">Book an Appointment</h2>
60
+ <form id="appointmentForm" class="space-y-4">
61
+ <div>
62
+ <label for="appointmentName" class="block text-sm font-medium text-gray-700">Name</label>
63
+ <input type="text" id="appointmentName" name="appointmentName" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
64
+ </div>
65
+ <div>
66
+ <label for="appointmentEmail" class="block text-sm font-medium text-gray-700">Email</label>
67
+ <input type="email" id="appointmentEmail" name="appointmentEmail" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
68
+ </div>
69
+ <div>
70
+ <label for="doctor" class="block text-sm font-medium text-gray-700">Select Doctor</label>
71
+ <select id="doctor" name="doctor" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
72
+ <option value="" disabled selected>Select a Doctor</option>
73
+ </select>
74
+ </div>
75
+ <div>
76
+ <label for="appointmentDate" class="block text-sm font-medium text-gray-700">Date</label>
77
+ <input type="date" id="appointmentDate" name="appointmentDate" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
78
+ </div>
79
+ <div>
80
+ <label for="appointmentTime" class="block text-sm font-medium text-gray-700">Time</label>
81
+ <input type="time" id="appointmentTime" name="appointmentTime" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
82
+ </div>
83
+ <button type="submit" class="w-full bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline transition duration-300 ease-in-out transform hover:scale-105">Book Appointment</button>
84
+ </form>
85
+ </div>
86
+ </div>
87
+ </div>
88
+
89
+ <script>
90
+ const socket = io();
91
+
92
+ function toggleForms(formType) {
93
+ if (formType === 'notification') {
94
+ document.getElementById('notificationFormDiv').classList.remove('hidden');
95
+ document.getElementById('appointmentFormDiv').classList.add('hidden');
96
+ } else if (formType === 'appointment') {
97
+ document.getElementById('notificationFormDiv').classList.add('hidden');
98
+ document.getElementById('appointmentFormDiv').classList.remove('hidden');
99
+ // Fetch doctors list dynamically
100
+ fetchDoctors();
101
+ }
102
+ }
103
+
104
+ function fetchDoctors() {
105
+ const doctors = [
106
+ { id: 1, name: 'Dr. John Doe', specialty: 'Cardiology' },
107
+ { id: 2, name: 'Dr. Jane Smith', specialty: 'Neurology' },
108
+ { id: 3, name: 'Dr. Michael Brown', specialty: 'Pediatrics' },
109
+ { id: 4, name: 'Dr. Sarah Lee', specialty: 'Dermatology' },
110
+ { id: 5, name: 'Dr. Robert Clark', specialty: 'Ophthalmology' },
111
+ { id: 6, name: 'Dr. Emily Davis', specialty: 'Orthopedics' },
112
+ { id: 7, name: 'Dr. Andrew Wilson', specialty: 'ENT' },
113
+ { id: 8, name: 'Dr. Laura Johnson', specialty: 'Psychiatry' },
114
+ { id: 9, name: 'Dr. William Martinez', specialty: 'Urology' },
115
+ { id: 10, name: 'Dr. Elizabeth Thomas', specialty: 'Gynecology' }
116
+ ];
117
+
118
+ const doctorSelect = document.getElementById('doctor');
119
+ doctorSelect.innerHTML = ''; // Clear existing options
120
+ doctors.forEach(doctor => {
121
+ const option = document.createElement('option');
122
+ option.value = doctor.id;
123
+ option.textContent = `${doctor.name} (${doctor.specialty})`;
124
+ doctorSelect.appendChild(option);
125
+ });
126
+ }
127
+
128
+ document.getElementById('notificationForm').addEventListener('submit', function(e) {
129
+ e.preventDefault();
130
+ const formData = new FormData(e.target);
131
+ const data = Object.fromEntries(formData.entries());
132
+
133
+ fetch('/submit', {
134
+ method: 'POST',
135
+ headers: {
136
+ 'Content-Type': 'application/json',
137
+ },
138
+ body: JSON.stringify(data),
139
+ })
140
+ .then(response => response.json())
141
+ .then(data => {
142
+ alert(data.message);
143
+ e.target.reset(); // Clear form fields
144
+ })
145
+ .catch((error) => {
146
+ console.error('Error:', error);
147
+ alert('An error occurred. Please try again.');
148
+ });
149
+ });
150
+
151
+ document.getElementById('appointmentForm').addEventListener('submit', function(e) {
152
+ e.preventDefault();
153
+ const formData = new FormData(e.target);
154
+ const data = Object.fromEntries(formData.entries());
155
+
156
+ fetch('/bookAppointment', {
157
+ method: 'POST',
158
+ headers: {
159
+ 'Content-Type': 'application/json',
160
+ },
161
+ body: JSON.stringify(data),
162
+ })
163
+ .then(response => response.json())
164
+ .then(data => {
165
+ alert(data.message);
166
+ e.target.reset(); // Clear form fields
167
+ })
168
+ .catch((error) => {
169
+ console.error('Error:', error);
170
+ alert('An error occurred. Please try again.');
171
+ });
172
+ });
173
+
174
+ socket.on('connect', function() {
175
+ console.log('Connected to server');
176
+ });
177
+
178
+ socket.on('disconnect', function() {
179
+ console.log('Disconnected from server');
180
+ });
181
+ </script>
182
+
183
+ </body>
184
+ </html>
templates/notification.html ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Motivational Messages</title>
6
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
8
+ <style>
9
+ body {
10
+ font-family: Arial, sans-serif;
11
+ background-color: #f0f2f5;
12
+ margin: 0;
13
+ padding: 0;
14
+ display: flex;
15
+ justify-content: center;
16
+ align-items: center;
17
+ height: 100vh;
18
+ }
19
+ .container {
20
+ background-color: #ffffff;
21
+ padding: 2em;
22
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
23
+ border-radius: 10px;
24
+ text-align: center;
25
+ }
26
+ h1 {
27
+ color: #434f94;
28
+ margin-bottom: 1em;
29
+ }
30
+ .spinner {
31
+ display: none;
32
+ border: 4px solid rgba(0, 0, 0, 0.1);
33
+ border-top: 4px solid #512da8;
34
+ border-radius: 50%;
35
+ width: 30px;
36
+ height: 30px;
37
+ animation: spin 1s linear infinite;
38
+ margin: 20px auto;
39
+ }
40
+ @keyframes spin {
41
+ 0% { transform: rotate(0deg); }
42
+ 100% { transform: rotate(360deg); }
43
+ }
44
+ </style>
45
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.0/socket.io.min.js"></script>
46
+ <script type="text/javascript">
47
+ document.addEventListener('DOMContentLoaded', (event) => {
48
+ var socket = io.connect('http://' + document.domain + ':' + location.port);
49
+
50
+ // Event listener for receiving new messages
51
+ socket.on('new_message', function(data) {
52
+ showMessage(data.message);
53
+ hideSpinner();
54
+ });
55
+
56
+ // Function to show message
57
+ function showMessage(message) {
58
+ const messageContainer = document.querySelector('.container');
59
+ const messageElement = document.createElement('p');
60
+ messageElement.textContent = message;
61
+ messageContainer.appendChild(messageElement);
62
+ }
63
+
64
+ // Function to show spinner
65
+ function showSpinner() {
66
+ const spinner = document.querySelector('.spinner');
67
+ spinner.style.display = 'block';
68
+ }
69
+
70
+ // Function to hide spinner
71
+ function hideSpinner() {
72
+ const spinner = document.querySelector('.spinner');
73
+ spinner.style.display = 'none';
74
+ }
75
+
76
+ // Request permission for notifications
77
+ if (Notification.permission !== "granted") {
78
+ Notification.requestPermission().then(function(result) {
79
+ if (result === "granted") {
80
+ console.log("Notification permission granted.");
81
+ }
82
+ });
83
+ }
84
+ });
85
+ </script>
86
+ </head>
87
+ <body>
88
+ <div class="container">
89
+ <h1>Motivational Messages</h1>
90
+ <p>You will receive motivational messages periodically.</p>
91
+ <div class="spinner"></div>
92
+ </div>
93
+ </body>
94
+ </html>
templates/src/input.css ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
templates/src/output.css ADDED
@@ -0,0 +1,555 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ ! tailwindcss v3.4.4 | MIT License | https://tailwindcss.com
3
+ */
4
+
5
+ /*
6
+ 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
7
+ 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
8
+ */
9
+
10
+ *,
11
+ ::before,
12
+ ::after {
13
+ box-sizing: border-box;
14
+ /* 1 */
15
+ border-width: 0;
16
+ /* 2 */
17
+ border-style: solid;
18
+ /* 2 */
19
+ border-color: #e5e7eb;
20
+ /* 2 */
21
+ }
22
+
23
+ ::before,
24
+ ::after {
25
+ --tw-content: '';
26
+ }
27
+
28
+ /*
29
+ 1. Use a consistent sensible line-height in all browsers.
30
+ 2. Prevent adjustments of font size after orientation changes in iOS.
31
+ 3. Use a more readable tab size.
32
+ 4. Use the user's configured `sans` font-family by default.
33
+ 5. Use the user's configured `sans` font-feature-settings by default.
34
+ 6. Use the user's configured `sans` font-variation-settings by default.
35
+ 7. Disable tap highlights on iOS
36
+ */
37
+
38
+ html,
39
+ :host {
40
+ line-height: 1.5;
41
+ /* 1 */
42
+ -webkit-text-size-adjust: 100%;
43
+ /* 2 */
44
+ -moz-tab-size: 4;
45
+ /* 3 */
46
+ -o-tab-size: 4;
47
+ tab-size: 4;
48
+ /* 3 */
49
+ font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
50
+ /* 4 */
51
+ font-feature-settings: normal;
52
+ /* 5 */
53
+ font-variation-settings: normal;
54
+ /* 6 */
55
+ -webkit-tap-highlight-color: transparent;
56
+ /* 7 */
57
+ }
58
+
59
+ /*
60
+ 1. Remove the margin in all browsers.
61
+ 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
62
+ */
63
+
64
+ body {
65
+ margin: 0;
66
+ /* 1 */
67
+ line-height: inherit;
68
+ /* 2 */
69
+ }
70
+
71
+ /*
72
+ 1. Add the correct height in Firefox.
73
+ 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
74
+ 3. Ensure horizontal rules are visible by default.
75
+ */
76
+
77
+ hr {
78
+ height: 0;
79
+ /* 1 */
80
+ color: inherit;
81
+ /* 2 */
82
+ border-top-width: 1px;
83
+ /* 3 */
84
+ }
85
+
86
+ /*
87
+ Add the correct text decoration in Chrome, Edge, and Safari.
88
+ */
89
+
90
+ abbr:where([title]) {
91
+ -webkit-text-decoration: underline dotted;
92
+ text-decoration: underline dotted;
93
+ }
94
+
95
+ /*
96
+ Remove the default font size and weight for headings.
97
+ */
98
+
99
+ h1,
100
+ h2,
101
+ h3,
102
+ h4,
103
+ h5,
104
+ h6 {
105
+ font-size: inherit;
106
+ font-weight: inherit;
107
+ }
108
+
109
+ /*
110
+ Reset links to optimize for opt-in styling instead of opt-out.
111
+ */
112
+
113
+ a {
114
+ color: inherit;
115
+ text-decoration: inherit;
116
+ }
117
+
118
+ /*
119
+ Add the correct font weight in Edge and Safari.
120
+ */
121
+
122
+ b,
123
+ strong {
124
+ font-weight: bolder;
125
+ }
126
+
127
+ /*
128
+ 1. Use the user's configured `mono` font-family by default.
129
+ 2. Use the user's configured `mono` font-feature-settings by default.
130
+ 3. Use the user's configured `mono` font-variation-settings by default.
131
+ 4. Correct the odd `em` font sizing in all browsers.
132
+ */
133
+
134
+ code,
135
+ kbd,
136
+ samp,
137
+ pre {
138
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
139
+ /* 1 */
140
+ font-feature-settings: normal;
141
+ /* 2 */
142
+ font-variation-settings: normal;
143
+ /* 3 */
144
+ font-size: 1em;
145
+ /* 4 */
146
+ }
147
+
148
+ /*
149
+ Add the correct font size in all browsers.
150
+ */
151
+
152
+ small {
153
+ font-size: 80%;
154
+ }
155
+
156
+ /*
157
+ Prevent `sub` and `sup` elements from affecting the line height in all browsers.
158
+ */
159
+
160
+ sub,
161
+ sup {
162
+ font-size: 75%;
163
+ line-height: 0;
164
+ position: relative;
165
+ vertical-align: baseline;
166
+ }
167
+
168
+ sub {
169
+ bottom: -0.25em;
170
+ }
171
+
172
+ sup {
173
+ top: -0.5em;
174
+ }
175
+
176
+ /*
177
+ 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
178
+ 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
179
+ 3. Remove gaps between table borders by default.
180
+ */
181
+
182
+ table {
183
+ text-indent: 0;
184
+ /* 1 */
185
+ border-color: inherit;
186
+ /* 2 */
187
+ border-collapse: collapse;
188
+ /* 3 */
189
+ }
190
+
191
+ /*
192
+ 1. Change the font styles in all browsers.
193
+ 2. Remove the margin in Firefox and Safari.
194
+ 3. Remove default padding in all browsers.
195
+ */
196
+
197
+ button,
198
+ input,
199
+ optgroup,
200
+ select,
201
+ textarea {
202
+ font-family: inherit;
203
+ /* 1 */
204
+ font-feature-settings: inherit;
205
+ /* 1 */
206
+ font-variation-settings: inherit;
207
+ /* 1 */
208
+ font-size: 100%;
209
+ /* 1 */
210
+ font-weight: inherit;
211
+ /* 1 */
212
+ line-height: inherit;
213
+ /* 1 */
214
+ letter-spacing: inherit;
215
+ /* 1 */
216
+ color: inherit;
217
+ /* 1 */
218
+ margin: 0;
219
+ /* 2 */
220
+ padding: 0;
221
+ /* 3 */
222
+ }
223
+
224
+ /*
225
+ Remove the inheritance of text transform in Edge and Firefox.
226
+ */
227
+
228
+ button,
229
+ select {
230
+ text-transform: none;
231
+ }
232
+
233
+ /*
234
+ 1. Correct the inability to style clickable types in iOS and Safari.
235
+ 2. Remove default button styles.
236
+ */
237
+
238
+ button,
239
+ input:where([type='button']),
240
+ input:where([type='reset']),
241
+ input:where([type='submit']) {
242
+ -webkit-appearance: button;
243
+ /* 1 */
244
+ background-color: transparent;
245
+ /* 2 */
246
+ background-image: none;
247
+ /* 2 */
248
+ }
249
+
250
+ /*
251
+ Use the modern Firefox focus style for all focusable elements.
252
+ */
253
+
254
+ :-moz-focusring {
255
+ outline: auto;
256
+ }
257
+
258
+ /*
259
+ Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
260
+ */
261
+
262
+ :-moz-ui-invalid {
263
+ box-shadow: none;
264
+ }
265
+
266
+ /*
267
+ Add the correct vertical alignment in Chrome and Firefox.
268
+ */
269
+
270
+ progress {
271
+ vertical-align: baseline;
272
+ }
273
+
274
+ /*
275
+ Correct the cursor style of increment and decrement buttons in Safari.
276
+ */
277
+
278
+ ::-webkit-inner-spin-button,
279
+ ::-webkit-outer-spin-button {
280
+ height: auto;
281
+ }
282
+
283
+ /*
284
+ 1. Correct the odd appearance in Chrome and Safari.
285
+ 2. Correct the outline style in Safari.
286
+ */
287
+
288
+ [type='search'] {
289
+ -webkit-appearance: textfield;
290
+ /* 1 */
291
+ outline-offset: -2px;
292
+ /* 2 */
293
+ }
294
+
295
+ /*
296
+ Remove the inner padding in Chrome and Safari on macOS.
297
+ */
298
+
299
+ ::-webkit-search-decoration {
300
+ -webkit-appearance: none;
301
+ }
302
+
303
+ /*
304
+ 1. Correct the inability to style clickable types in iOS and Safari.
305
+ 2. Change font properties to `inherit` in Safari.
306
+ */
307
+
308
+ ::-webkit-file-upload-button {
309
+ -webkit-appearance: button;
310
+ /* 1 */
311
+ font: inherit;
312
+ /* 2 */
313
+ }
314
+
315
+ /*
316
+ Add the correct display in Chrome and Safari.
317
+ */
318
+
319
+ summary {
320
+ display: list-item;
321
+ }
322
+
323
+ /*
324
+ Removes the default spacing and border for appropriate elements.
325
+ */
326
+
327
+ blockquote,
328
+ dl,
329
+ dd,
330
+ h1,
331
+ h2,
332
+ h3,
333
+ h4,
334
+ h5,
335
+ h6,
336
+ hr,
337
+ figure,
338
+ p,
339
+ pre {
340
+ margin: 0;
341
+ }
342
+
343
+ fieldset {
344
+ margin: 0;
345
+ padding: 0;
346
+ }
347
+
348
+ legend {
349
+ padding: 0;
350
+ }
351
+
352
+ ol,
353
+ ul,
354
+ menu {
355
+ list-style: none;
356
+ margin: 0;
357
+ padding: 0;
358
+ }
359
+
360
+ /*
361
+ Reset default styling for dialogs.
362
+ */
363
+
364
+ dialog {
365
+ padding: 0;
366
+ }
367
+
368
+ /*
369
+ Prevent resizing textareas horizontally by default.
370
+ */
371
+
372
+ textarea {
373
+ resize: vertical;
374
+ }
375
+
376
+ /*
377
+ 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
378
+ 2. Set the default placeholder color to the user's configured gray 400 color.
379
+ */
380
+
381
+ input::-moz-placeholder, textarea::-moz-placeholder {
382
+ opacity: 1;
383
+ /* 1 */
384
+ color: #9ca3af;
385
+ /* 2 */
386
+ }
387
+
388
+ input::placeholder,
389
+ textarea::placeholder {
390
+ opacity: 1;
391
+ /* 1 */
392
+ color: #9ca3af;
393
+ /* 2 */
394
+ }
395
+
396
+ /*
397
+ Set the default cursor for buttons.
398
+ */
399
+
400
+ button,
401
+ [role="button"] {
402
+ cursor: pointer;
403
+ }
404
+
405
+ /*
406
+ Make sure disabled buttons don't get the pointer cursor.
407
+ */
408
+
409
+ :disabled {
410
+ cursor: default;
411
+ }
412
+
413
+ /*
414
+ 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
415
+ 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
416
+ This can trigger a poorly considered lint error in some tools but is included by design.
417
+ */
418
+
419
+ img,
420
+ svg,
421
+ video,
422
+ canvas,
423
+ audio,
424
+ iframe,
425
+ embed,
426
+ object {
427
+ display: block;
428
+ /* 1 */
429
+ vertical-align: middle;
430
+ /* 2 */
431
+ }
432
+
433
+ /*
434
+ Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
435
+ */
436
+
437
+ img,
438
+ video {
439
+ max-width: 100%;
440
+ height: auto;
441
+ }
442
+
443
+ /* Make elements with the HTML hidden attribute stay hidden by default */
444
+
445
+ [hidden] {
446
+ display: none;
447
+ }
448
+
449
+ *, ::before, ::after {
450
+ --tw-border-spacing-x: 0;
451
+ --tw-border-spacing-y: 0;
452
+ --tw-translate-x: 0;
453
+ --tw-translate-y: 0;
454
+ --tw-rotate: 0;
455
+ --tw-skew-x: 0;
456
+ --tw-skew-y: 0;
457
+ --tw-scale-x: 1;
458
+ --tw-scale-y: 1;
459
+ --tw-pan-x: ;
460
+ --tw-pan-y: ;
461
+ --tw-pinch-zoom: ;
462
+ --tw-scroll-snap-strictness: proximity;
463
+ --tw-gradient-from-position: ;
464
+ --tw-gradient-via-position: ;
465
+ --tw-gradient-to-position: ;
466
+ --tw-ordinal: ;
467
+ --tw-slashed-zero: ;
468
+ --tw-numeric-figure: ;
469
+ --tw-numeric-spacing: ;
470
+ --tw-numeric-fraction: ;
471
+ --tw-ring-inset: ;
472
+ --tw-ring-offset-width: 0px;
473
+ --tw-ring-offset-color: #fff;
474
+ --tw-ring-color: rgb(59 130 246 / 0.5);
475
+ --tw-ring-offset-shadow: 0 0 #0000;
476
+ --tw-ring-shadow: 0 0 #0000;
477
+ --tw-shadow: 0 0 #0000;
478
+ --tw-shadow-colored: 0 0 #0000;
479
+ --tw-blur: ;
480
+ --tw-brightness: ;
481
+ --tw-contrast: ;
482
+ --tw-grayscale: ;
483
+ --tw-hue-rotate: ;
484
+ --tw-invert: ;
485
+ --tw-saturate: ;
486
+ --tw-sepia: ;
487
+ --tw-drop-shadow: ;
488
+ --tw-backdrop-blur: ;
489
+ --tw-backdrop-brightness: ;
490
+ --tw-backdrop-contrast: ;
491
+ --tw-backdrop-grayscale: ;
492
+ --tw-backdrop-hue-rotate: ;
493
+ --tw-backdrop-invert: ;
494
+ --tw-backdrop-opacity: ;
495
+ --tw-backdrop-saturate: ;
496
+ --tw-backdrop-sepia: ;
497
+ --tw-contain-size: ;
498
+ --tw-contain-layout: ;
499
+ --tw-contain-paint: ;
500
+ --tw-contain-style: ;
501
+ }
502
+
503
+ ::backdrop {
504
+ --tw-border-spacing-x: 0;
505
+ --tw-border-spacing-y: 0;
506
+ --tw-translate-x: 0;
507
+ --tw-translate-y: 0;
508
+ --tw-rotate: 0;
509
+ --tw-skew-x: 0;
510
+ --tw-skew-y: 0;
511
+ --tw-scale-x: 1;
512
+ --tw-scale-y: 1;
513
+ --tw-pan-x: ;
514
+ --tw-pan-y: ;
515
+ --tw-pinch-zoom: ;
516
+ --tw-scroll-snap-strictness: proximity;
517
+ --tw-gradient-from-position: ;
518
+ --tw-gradient-via-position: ;
519
+ --tw-gradient-to-position: ;
520
+ --tw-ordinal: ;
521
+ --tw-slashed-zero: ;
522
+ --tw-numeric-figure: ;
523
+ --tw-numeric-spacing: ;
524
+ --tw-numeric-fraction: ;
525
+ --tw-ring-inset: ;
526
+ --tw-ring-offset-width: 0px;
527
+ --tw-ring-offset-color: #fff;
528
+ --tw-ring-color: rgb(59 130 246 / 0.5);
529
+ --tw-ring-offset-shadow: 0 0 #0000;
530
+ --tw-ring-shadow: 0 0 #0000;
531
+ --tw-shadow: 0 0 #0000;
532
+ --tw-shadow-colored: 0 0 #0000;
533
+ --tw-blur: ;
534
+ --tw-brightness: ;
535
+ --tw-contrast: ;
536
+ --tw-grayscale: ;
537
+ --tw-hue-rotate: ;
538
+ --tw-invert: ;
539
+ --tw-saturate: ;
540
+ --tw-sepia: ;
541
+ --tw-drop-shadow: ;
542
+ --tw-backdrop-blur: ;
543
+ --tw-backdrop-brightness: ;
544
+ --tw-backdrop-contrast: ;
545
+ --tw-backdrop-grayscale: ;
546
+ --tw-backdrop-hue-rotate: ;
547
+ --tw-backdrop-invert: ;
548
+ --tw-backdrop-opacity: ;
549
+ --tw-backdrop-saturate: ;
550
+ --tw-backdrop-sepia: ;
551
+ --tw-contain-size: ;
552
+ --tw-contain-layout: ;
553
+ --tw-contain-paint: ;
554
+ --tw-contain-style: ;
555
+ }
templates/styles.css ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ font-family: Arial, sans-serif;
3
+ background-color: #f0f2f5;
4
+ margin: 0;
5
+ padding: 0;
6
+ display: flex;
7
+ justify-content: center;
8
+ align-items: center;
9
+ height: 100vh;
10
+ }
11
+ .container {
12
+ background-color: #ffffff;
13
+ padding: 2em;
14
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
15
+ border-radius: 10px;
16
+ text-align: center;
17
+ }
18
+ h1 {
19
+ color: #434f94;
20
+ margin-bottom: 1em;
21
+ }
22
+ label {
23
+ display: block;
24
+ font-size: 1.2em;
25
+ margin-bottom: 0.5em;
26
+ color: #333;
27
+ }
28
+ select, button {
29
+ font-size: 1em;
30
+ padding: 0.5em;
31
+ margin-top: 1em;
32
+ width: 100%;
33
+ border: 1px solid #ccc;
34
+ border-radius: 5px;
35
+ }
36
+ button {
37
+ background-color: #434f94;
38
+ color: #fff;
39
+ border: none;
40
+ cursor: pointer;
41
+ }
42
+ button:hover {
43
+ background-color: #512da8;
44
+ }
45
+ .spinner {
46
+ display: none;
47
+ border: 4px solid rgba(0, 0, 0, 0.1);
48
+ border-top: 4px solid #512da8;
49
+ border-radius: 50%;
50
+ width: 30px;
51
+ height: 30px;
52
+ animation: spin 1s linear infinite;
53
+ margin: 20px auto;
54
+ }
55
+ @keyframes spin {
56
+ 0% { transform: rotate(0deg); }
57
+ 100% { transform: rotate(360deg); }
58
+ }