triflix commited on
Commit
26fca56
Β·
verified Β·
1 Parent(s): 4a70696

Upload 8 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ Screenshot.png filter=lfs diff=lfs merge=lfs -text
Event_Scheduler.postman_collection.json ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "info": {
3
+ "_postman_id": "75a812d6-1091-4b90-9574-9726c8e127aa",
4
+ "name": "Event_Scheduler",
5
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
6
+ "_exporter_id": "46285586",
7
+ "_collection_link": "https://user-130337.postman.co/workspace/User's-Workspace~7437678a-b9a7-4293-800b-f9f22a3e898f/collection/46285586-75a812d6-1091-4b90-9574-9726c8e127aa?action=share&source=collection_link&creator=46285586"
8
+ },
9
+ "item": [
10
+ {
11
+ "name": "http://127.0.0.1:5000/events/6",
12
+ "request": {
13
+ "method": "DELETE",
14
+ "header": [],
15
+ "body": {
16
+ "mode": "raw",
17
+ "raw": "{\r\n \"description\": \"Traveling Location - XYZ\",\r\n \"end_time\": \"2025-07-01 11:00:00\",\r\n \"id\": \"3\",\r\n \"start_time\": \"2025-07-01 10:00:00\",\r\n \"title\": \"Traveling with ABCD\"\r\n}",
18
+ "options": {
19
+ "raw": {
20
+ "language": "json"
21
+ }
22
+ }
23
+ },
24
+ "url": {
25
+ "raw": "http://127.0.0.1:5000/events/6",
26
+ "protocol": "http",
27
+ "host": [
28
+ "127",
29
+ "0",
30
+ "0",
31
+ "1"
32
+ ],
33
+ "port": "5000",
34
+ "path": [
35
+ "events",
36
+ "6"
37
+ ]
38
+ }
39
+ },
40
+ "response": []
41
+ }
42
+ ]
43
+ }
Screenshot.png ADDED

Git LFS Details

  • SHA256: f81c3d9050c8a705d894e9de989230590c290f9c94369aeaea601cd400c3796b
  • Pointer size: 131 Bytes
  • Size of remote file: 108 kB
app.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, render_template, jsonify, redirect
2
+ import json
3
+ from datetime import datetime, timedelta
4
+ import os
5
+ from flask_cors import CORS
6
+
7
+ app = Flask(__name__)
8
+ CORS(app) # Enable CORS for all routes (for front-end testing on a different port/domain)
9
+ DATA_FILE = 'events.json'
10
+
11
+ def load_events():
12
+ if not os.path.exists(DATA_FILE):
13
+ return []
14
+ with open(DATA_FILE, 'r') as f:
15
+ return json.load(f)
16
+
17
+ def save_events(events):
18
+ with open(DATA_FILE, 'w') as f:
19
+ json.dump(events, f, indent=2)
20
+
21
+ def get_upcoming_reminders(events):
22
+ now = datetime.now()
23
+ end = now + timedelta(hours=4)
24
+ upcoming = []
25
+
26
+ for e in events:
27
+ start = datetime.fromisoformat(e['start_time'])
28
+ if now <= start < end:
29
+ upcoming.append(e)
30
+
31
+ return upcoming
32
+
33
+ @app.route('/')
34
+ def index():
35
+ all_events = load_events()
36
+ reminders = get_upcoming_reminders(all_events)
37
+
38
+ search_query = request.args.get('search', '').lower()
39
+ if search_query:
40
+ events = [e for e in all_events if search_query in e['title'].lower()]
41
+ else:
42
+ events = all_events
43
+
44
+ return render_template('index.html', events=events, reminders=reminders, search=search_query)
45
+
46
+ # Get all events
47
+ @app.route('/events', methods=['GET', 'POST'])
48
+ @app.route('/events/', methods=['GET', 'POST']) # For routes with trailing slash
49
+ def events():
50
+ if request.method == 'GET':
51
+ events = load_events()
52
+ return jsonify(events)
53
+ elif request.method == 'POST':
54
+ events = load_events()
55
+ data = request.get_json()
56
+ new_event = {
57
+ 'id': str(len(events) + 1),
58
+ 'title': data['title'],
59
+ 'description': data.get('description', ''),
60
+ 'start_time': data['start_time'],
61
+ 'end_time': data['end_time'],
62
+ }
63
+ events.append(new_event)
64
+ save_events(events)
65
+ return jsonify(new_event), 201
66
+
67
+ # Update an existing event
68
+ @app.route('/events/<event_id>', methods=['PUT'])
69
+ def update_event(event_id):
70
+ events = load_events()
71
+ data = request.get_json()
72
+ for event in events:
73
+ if event['id'] == event_id:
74
+ event.update(data)
75
+ save_events(events)
76
+ return jsonify(event)
77
+ return jsonify({'error': 'Event not found'}), 404
78
+
79
+ # Delete an event
80
+ @app.route('/events/<event_id>', methods=['DELETE'])
81
+ def delete_event(event_id):
82
+ events = load_events()
83
+ events = [e for e in events if e['id'] != event_id]
84
+ save_events(events)
85
+ return '', 204
86
+
87
+ # Custom template filter for formatting time (12-hour clock)
88
+ @app.template_filter('format12')
89
+ def format12(value):
90
+ dt = datetime.fromisoformat(value)
91
+ return dt.strftime('%I:%M %p, %b %d')
92
+
93
+ if __name__ == "__main__":
94
+ # Make sure it listens on 0.0.0.0 (the container's network interface)
95
+ app.run(host="0.0.0.0", port=5000)
events.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ [
2
+
3
+ ]
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Flask
2
+ flask-cors
static/script.js ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.getElementById('event-form').onsubmit = async (e) => {
2
+ e.preventDefault();
3
+ const data = {
4
+ title: document.getElementById('title').value,
5
+ description: document.getElementById('description').value,
6
+ start_time: document.getElementById('start_time').value,
7
+ end_time: document.getElementById('end_time').value,
8
+ };
9
+ await fetch('/events', {
10
+ method: 'POST',
11
+ headers: { 'Content-Type': 'application/json' },
12
+ body: JSON.stringify(data)
13
+ });
14
+ location.reload();
15
+ };
16
+
17
+ document.querySelectorAll('.delete-btn').forEach(btn => {
18
+ btn.onclick = async () => {
19
+ const id = btn.parentElement.dataset.id;
20
+ await fetch(`/events/${id}`, { method: 'DELETE' });
21
+ location.reload();
22
+ };
23
+ });
24
+
25
+ let editingId = null;
26
+ document.querySelectorAll('.edit-btn').forEach(btn => {
27
+ btn.onclick = () => {
28
+ const card = btn.parentElement;
29
+ editingId = card.dataset.id;
30
+ document.getElementById('edit-title').value = card.querySelector('h3').innerText;
31
+ document.getElementById('edit-description').value = card.querySelectorAll('p')[0].innerText;
32
+
33
+ const times = card.querySelectorAll('p')[1].innerText.replace("πŸ•’ ", "").split(" - ");
34
+ const parseToInputFormat = (timeStr) => {
35
+ const date = new Date(timeStr);
36
+ const pad = n => n.toString().padStart(2, '0');
37
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
38
+ };
39
+
40
+ document.getElementById('edit-start').value = parseToInputFormat(times[0]);
41
+ document.getElementById('edit-end').value = parseToInputFormat(times[1]);
42
+ document.getElementById('modal').style.display = 'flex';
43
+ };
44
+ });
45
+
46
+ document.getElementById('save-edit').onclick = async () => {
47
+ const data = {
48
+ title: document.getElementById('edit-title').value,
49
+ description: document.getElementById('edit-description').value,
50
+ start_time: document.getElementById('edit-start').value,
51
+ end_time: document.getElementById('edit-end').value,
52
+ };
53
+ await fetch(`/events/${editingId}`, {
54
+ method: 'PUT',
55
+ headers: { 'Content-Type': 'application/json' },
56
+ body: JSON.stringify(data)
57
+ });
58
+ location.reload();
59
+ };
60
+
61
+ function closeModal() {
62
+ document.getElementById('modal').style.display = 'none';
63
+ }
64
+
65
+ window.onclick = (event) => {
66
+ const modal = document.getElementById('modal');
67
+ if (event.target === modal) {
68
+ closeModal();
69
+ }
70
+ };
71
+
72
+ document.getElementById('clear-search').onclick = () => {
73
+ window.location.href = '/';
74
+ };
75
+
76
+ document.getElementById('search-btn').onclick = () => {
77
+ const query = document.getElementById('search').value.trim();
78
+ if (query.length > 0) {
79
+ window.location.href = `/?search=${encodeURIComponent(query)}`;
80
+ }
81
+ };
82
+
83
+ window.onload = () => {
84
+ const now = new Date();
85
+ const pad = n => n.toString().padStart(2, '0');
86
+
87
+ const toDatetimeLocal = dt => {
88
+ return `${dt.getFullYear()}-${pad(dt.getMonth() + 1)}-${pad(dt.getDate())}T${pad(dt.getHours())}:${pad(dt.getMinutes())}`;
89
+ };
90
+
91
+ document.getElementById('start_time').value = toDatetimeLocal(now);
92
+
93
+ now.setHours(now.getHours() + 4);
94
+ document.getElementById('end_time').value = toDatetimeLocal(now);
95
+
96
+ // Convert event display times to 12-hour format
97
+ document.querySelectorAll(".event-card").forEach(card => {
98
+ const timePara = card.querySelectorAll("p")[1];
99
+ if (timePara) {
100
+ const [startRaw, endRaw] = timePara.innerText.replace("πŸ•’ ", "").split(" - ");
101
+ const start = new Date(startRaw);
102
+ const end = new Date(endRaw);
103
+
104
+ const format12 = dt => dt.toLocaleString(undefined, {
105
+ year: "numeric", month: "short", day: "numeric",
106
+ hour: "numeric", minute: "2-digit", hour12: true
107
+ });
108
+
109
+ timePara.innerText = `πŸ•’ ${format12(start)} - ${format12(end)}`;
110
+ }
111
+ });
112
+ };
113
+
114
+
115
+ // script.js
116
+ const themeToggle = document.getElementById("theme-toggle");
117
+
118
+ themeToggle.addEventListener("change", function() {
119
+ const currentTheme = document.documentElement.getAttribute("data-theme");
120
+
121
+ // Toggle between light and dark themes
122
+ if (this.checked) {
123
+ document.documentElement.setAttribute("data-theme", "dark");
124
+ } else {
125
+ document.documentElement.setAttribute("data-theme", "light");
126
+ }
127
+ });
static/styles.css ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Global styles for both light and dark themes */
2
+ :root {
3
+ --background-color-light: #f7f9fc;
4
+ --text-color-light: #333;
5
+ --panel-background-light: #ffffff;
6
+ --button-background-light: #4a90e2;
7
+ --button-hover-light: #357abd;
8
+ --event-card-background-light: #f0f4fa;
9
+ --event-card-border-left-light: #4a90e2;
10
+ --modal-background-light: rgba(0, 0, 0, 0.4);
11
+ --input-background-light: #ffffff;
12
+ --input-border-light: #ccc;
13
+ --input-text-light: #333;
14
+
15
+ --background-color-dark: #181818;
16
+ --text-color-dark: #e0e0e0;
17
+ --panel-background-dark: #2e2e2e;
18
+ --button-background-dark: #4a90e2;
19
+ --button-hover-dark: #357abd;
20
+ --event-card-background-dark: #252525;
21
+ --event-card-border-left-dark: #4a90e2;
22
+ --modal-background-dark: rgba(0, 0, 0, 0.6);
23
+ --input-background-dark: #333;
24
+ --input-border-dark: #444;
25
+ --input-text-dark: #e0e0e0;
26
+ }
27
+
28
+ /* Default light theme */
29
+ body {
30
+ margin: 0;
31
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
32
+ background: var(--background-color-light);
33
+ color: var(--text-color-light);
34
+ }
35
+
36
+ .container {
37
+ display: flex;
38
+ flex-wrap: wrap;
39
+ padding: 30px;
40
+ gap: 30px;
41
+ max-width: 1200px;
42
+ margin: auto;
43
+ }
44
+
45
+ .left-panel,
46
+ .right-panel {
47
+ flex: 1;
48
+ min-width: 300px;
49
+ background: var(--panel-background-light);
50
+ border-radius: 16px;
51
+ padding: 24px;
52
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
53
+ }
54
+
55
+ h2, h3 {
56
+ color: var(--text-color-light);
57
+ margin-bottom: 16px;
58
+ }
59
+
60
+ input[type="text"],
61
+ input[type="datetime-local"],
62
+ button {
63
+ width: 100%;
64
+ margin: 8px 0 0 -12px;
65
+ padding: 12px;
66
+ border-radius: 10px;
67
+ border: 1px solid var(--input-border-light);
68
+ font-size: 1rem;
69
+ background-color: var(--input-background-light);
70
+ color: var(--input-text-light);
71
+ }
72
+
73
+ button {
74
+ background-color: var(--button-background-light);
75
+ color: white;
76
+ border: none;
77
+ cursor: pointer;
78
+ margin-inline: 0px;
79
+ transition: background 0.3s ease;
80
+ }
81
+
82
+ button:hover {
83
+ background-color: var(--button-hover-light);
84
+ }
85
+
86
+ #event-list {
87
+ margin-top: 20px;
88
+ }
89
+
90
+ .event-card {
91
+ background: var(--event-card-background-light);
92
+ border-left: 6px solid var(--event-card-border-left-light);
93
+ border-radius: 12px;
94
+ padding: 16px;
95
+ margin-bottom: 16px;
96
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
97
+ }
98
+
99
+ .event-card h3 {
100
+ margin: 0 0 8px 0;
101
+ font-size: 1.2em;
102
+ }
103
+
104
+ .event-card p {
105
+ margin: 4px 0;
106
+ }
107
+
108
+ .edit-btn, .delete-btn {
109
+ margin-top: 8px;
110
+ margin-right: 8px;
111
+ background-color: #e2e8f0;
112
+ color: #333;
113
+ padding: 8px 12px;
114
+ border-radius: 8px;
115
+ border: none;
116
+ cursor: pointer;
117
+ font-size: 0.9em;
118
+ }
119
+
120
+ .edit-btn:hover {
121
+ background-color: #d0e2ff;
122
+ }
123
+
124
+ .delete-btn:hover {
125
+ background-color: #ffe1e1;
126
+ }
127
+
128
+ .search-bar {
129
+ display: flex;
130
+ gap: 10px;
131
+ margin-bottom: 20px;
132
+ align-items: center;
133
+ }
134
+
135
+ .search-bar input[type="text"] {
136
+ flex-grow: 1;
137
+ min-width: 200px;
138
+ padding: 12px;
139
+ border-radius: 10px;
140
+ border: 1px solid var(--input-border-light);
141
+ font-size: 1rem;
142
+ }
143
+
144
+ /* Modal Styles */
145
+ .modal {
146
+ display: none;
147
+ position: fixed;
148
+ z-index: 100;
149
+ left: 0; top: 0;
150
+ width: 100%; height: 100%;
151
+ background-color: rgba(0, 0, 0, 0.4);
152
+ align-items: center;
153
+ justify-content: center;
154
+ }
155
+
156
+ .modal-content {
157
+ background: var(--panel-background-light);
158
+ padding: 30px;
159
+ border-radius: 16px;
160
+ width: 90%;
161
+ max-width: 400px;
162
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
163
+ animation: fadeIn 0.3s ease;
164
+ }
165
+
166
+ @keyframes fadeIn {
167
+ from { transform: translateY(-20px); opacity: 0; }
168
+ to { transform: translateY(0); opacity: 1; }
169
+ }
170
+
171
+ /* Reminder styles */
172
+ .reminders {
173
+ margin-top: 40px;
174
+ }
175
+
176
+ .reminder-item {
177
+ background: var(--event-card-background-light);
178
+ padding: 10px;
179
+ border-radius: 8px;
180
+ margin-bottom: 10px;
181
+ }
182
+
183
+ /* Styling the toggle switch */
184
+ .switch {
185
+ --false: #63a2ff;
186
+ --true: #373737;
187
+ position: fixed;
188
+ top: 20px;
189
+ right: 20px;
190
+ z-index: 1000;
191
+ }
192
+
193
+ input[type=checkbox] {
194
+ appearance: none;
195
+ height: 2.1rem;
196
+ width: 3.5rem;
197
+ background-color: #fafafa;
198
+ position: relative;
199
+ border: 1px royalblue solid;
200
+ border-radius: 1em;
201
+ cursor: pointer;
202
+ }
203
+
204
+ input[type=checkbox]::before {
205
+ content: '';
206
+ display: block;
207
+ height: 1.9em;
208
+ width: 1.9em;
209
+ transform: translate(-50%, -50%);
210
+ position: absolute;
211
+ top: 50%;
212
+ left: calc(1.9em / 2 + .3em);
213
+ background-color: var(--false);
214
+ border-radius: 1em;
215
+ transition: .3s ease;
216
+ }
217
+
218
+ input[type=checkbox]:checked::before {
219
+ background-color: var(--true);
220
+ left: calc(100% - (1.9em / 2 + .3em));
221
+ }
222
+
223
+ /* Dark Theme */
224
+ [data-theme="dark"] {
225
+ --background-color-light: var(--background-color-dark);
226
+ --text-color-light: var(--text-color-dark);
227
+ --panel-background-light: var(--panel-background-dark);
228
+ --button-background-light: var(--button-background-dark);
229
+ --button-hover-light: var(--button-hover-dark);
230
+ --event-card-background-light: var(--event-card-background-dark);
231
+ --event-card-border-left-light: var(--event-card-border-left-dark);
232
+ --modal-background-light: var(--modal-background-dark);
233
+ --input-background-light: var(--input-background-dark);
234
+ --input-border-light: var(--input-border-dark);
235
+ --input-text-light: var(--input-text-dark);
236
+ }
templates/index.html ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>πŸ“… Event Scheduler</title>
6
+ <link rel="stylesheet" href="/static/styles.css">
7
+ </head>
8
+ <body>
9
+ <div class="container">
10
+ <div class="left-panel">
11
+ <h2>βž• Add Event</h2>
12
+ <form id="event-form">
13
+ <input type="text" id="title" placeholder="Title" required>
14
+ <input type="text" id="description" placeholder="Description">
15
+ <input type="datetime-local" id="start_time" required>
16
+ <input type="datetime-local" id="end_time" required>
17
+ <button type="submit">Add</button>
18
+ </form>
19
+
20
+ <div class="reminders">
21
+ <h3>⏰ Upcoming Reminders</h3>
22
+ {% for r in reminders %}
23
+ <div class="reminder-item">
24
+ <strong>{{ r.title }}</strong><br>
25
+ {{ r.start_time }}
26
+ </div>
27
+ {% else %}
28
+ <p>No upcoming events</p>
29
+ {% endfor %}
30
+ </div>
31
+ </div>
32
+
33
+ <div class="right-panel">
34
+ <div class="search-bar">
35
+ <input type="text" id="search" placeholder="πŸ” Search..." value="{{ search or '' }}">
36
+ <button id="search-btn">Search</button>
37
+ <button id="clear-search">Clear Filter</button>
38
+ </div>
39
+
40
+
41
+ <div id="event-list">
42
+ {% for e in events %}
43
+ <div class="event-card" data-id="{{ e.id }}">
44
+ <h3>{{ e.title }}</h3>
45
+ <p>{{ e.description }}</p>
46
+ <p>πŸ•’ {{ e.start_time }} - {{ e.end_time }}</p>
47
+ <button class="edit-btn">✏️ Edit</button>
48
+ <button class="delete-btn">πŸ—‘οΈ Delete</button>
49
+ </div>
50
+ {% else %}
51
+ <p>No events found.</p>
52
+ {% endfor %}
53
+ </div>
54
+ </div>
55
+ </div>
56
+
57
+ <!-- Modal -->
58
+ <div id="modal" class="modal">
59
+ <div class="modal-content">
60
+ <h2>Edit Event</h2>
61
+ <input type="text" id="edit-title">
62
+ <input type="text" id="edit-description">
63
+ <input type="datetime-local" id="edit-start">
64
+ <input type="datetime-local" id="edit-end">
65
+ <button id="save-edit">Save</button>
66
+ <button onclick="closeModal()">Cancel</button>
67
+ </div>
68
+ </div>
69
+
70
+
71
+ <label class="switch">
72
+ <input type="checkbox" id="theme-toggle" checked />
73
+ </label>
74
+
75
+
76
+ <script src="/static/script.js"></script>
77
+ </body>
78
+
79
+ </html>