drbaker171 commited on
Commit
71e2585
·
verified ·
1 Parent(s): 7d73721

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +687 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Sp
3
- emoji: 📉
4
- colorFrom: blue
5
- colorTo: red
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: sp
3
+ emoji: 🐳
4
+ colorFrom: pink
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,687 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Serial Port Manager with Chrome Extension</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .gradient-bg {
11
+ background: linear-gradient(135deg, #6b73ff 0%, #000dff 100%);
12
+ }
13
+ .policy-card {
14
+ transition: all 0.3s ease;
15
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
16
+ }
17
+ .policy-card:hover {
18
+ transform: translateY(-5px);
19
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
20
+ }
21
+ .code-block {
22
+ font-family: 'Courier New', Courier, monospace;
23
+ background-color: #2d3748;
24
+ color: #f7fafc;
25
+ border-radius: 0.375rem;
26
+ }
27
+ .tab-active {
28
+ border-bottom: 3px solid #4f46e5;
29
+ color: #4f46e5;
30
+ font-weight: 600;
31
+ }
32
+ .fade-in {
33
+ animation: fadeIn 0.5s ease-in;
34
+ }
35
+ .serial-console {
36
+ height: 200px;
37
+ overflow-y: auto;
38
+ background-color: #1a202c;
39
+ color: #e2e8f0;
40
+ padding: 1rem;
41
+ border-radius: 0.375rem;
42
+ font-family: monospace;
43
+ white-space: pre-wrap;
44
+ }
45
+ @keyframes fadeIn {
46
+ from { opacity: 0; }
47
+ to { opacity: 1; }
48
+ }
49
+ .blink {
50
+ animation: blink 1s step-end infinite;
51
+ }
52
+ @keyframes blink {
53
+ from, to { opacity: 1; }
54
+ 50% { opacity: 0.5; }
55
+ }
56
+ </style>
57
+ </head>
58
+ <body class="bg-gray-50 min-h-screen">
59
+ <div class="gradient-bg text-white py-12 px-4 sm:px-6 lg:px-8">
60
+ <div class="max-w-4xl mx-auto text-center">
61
+ <h1 class="text-4xl font-extrabold tracking-tight sm:text-5xl lg:text-6xl">
62
+ <i class="fas fa-plug mr-3"></i> Serial Port Manager
63
+ </h1>
64
+ <p class="mt-6 text-xl text-blue-100 max-w-3xl mx-auto">
65
+ Manage serial port permissions and communicate with devices
66
+ </p>
67
+ </div>
68
+ </div>
69
+
70
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
71
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
72
+ <!-- Serial Port Control Card -->
73
+ <div class="policy-card bg-white rounded-xl p-6 col-span-2">
74
+ <div class="flex items-center mb-6">
75
+ <div class="p-3 rounded-full bg-blue-100 text-blue-600 mr-4">
76
+ <i class="fas fa-microchip text-2xl"></i>
77
+ </div>
78
+ <h2 class="text-2xl font-bold text-gray-800">Serial Port Control</h2>
79
+ </div>
80
+
81
+ <div class="space-y-6">
82
+ <div class="flex flex-col sm:flex-row gap-4">
83
+ <button id="requestPortBtn" class="flex-1 px-4 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition flex items-center justify-center">
84
+ <i class="fas fa-plug mr-2"></i> Request Port
85
+ </button>
86
+ <button id="connectBtn" disabled class="flex-1 px-4 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 transition flex items-center justify-center">
87
+ <i class="fas fa-link mr-2"></i> Connect
88
+ </button>
89
+ <button id="disconnectBtn" disabled class="flex-1 px-4 py-3 bg-red-600 text-white rounded-lg hover:bg-red-700 transition flex items-center justify-center">
90
+ <i class="fas fa-unlink mr-2"></i> Disconnect
91
+ </button>
92
+ </div>
93
+
94
+ <div id="portInfo" class="hidden bg-gray-50 p-4 rounded-lg">
95
+ <div class="grid grid-cols-2 gap-4">
96
+ <div>
97
+ <h3 class="text-sm font-medium text-gray-500">Selected Port</h3>
98
+ <p id="portName" class="mt-1 text-sm font-semibold text-gray-900">-</p>
99
+ </div>
100
+ <div>
101
+ <h3 class="text-sm font-medium text-gray-500">Connection Status</h3>
102
+ <p id="connectionStatus" class="mt-1 text-sm font-semibold text-gray-900">Disconnected</p>
103
+ </div>
104
+ </div>
105
+ </div>
106
+
107
+ <div>
108
+ <label for="baudRate" class="block text-sm font-medium text-gray-700 mb-1">Baud Rate</label>
109
+ <select id="baudRate" class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm rounded-md">
110
+ <option>9600</option>
111
+ <option>19200</option>
112
+ <option selected>115200</option>
113
+ <option>57600</option>
114
+ <option>38400</option>
115
+ </select>
116
+ </div>
117
+
118
+ <div>
119
+ <label for="dataInput" class="block text-sm font-medium text-gray-700 mb-1">Send Data</label>
120
+ <div class="mt-1 flex rounded-md shadow-sm">
121
+ <input type="text" id="dataInput" class="focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded-none rounded-l-md sm:text-sm border-gray-300" placeholder="Enter data to send">
122
+ <button id="sendDataBtn" disabled class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-r-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
123
+ Send
124
+ </button>
125
+ </div>
126
+ </div>
127
+
128
+ <div>
129
+ <label class="block text-sm font-medium text-gray-700 mb-1">Serial Console</label>
130
+ <div id="serialConsole" class="serial-console">
131
+ <div class="text-gray-400">No data received yet...</div>
132
+ </div>
133
+ <div class="mt-2 flex justify-between">
134
+ <button id="clearConsoleBtn" class="px-3 py-1 bg-gray-200 text-gray-700 rounded text-sm hover:bg-gray-300">
135
+ Clear Console
136
+ </button>
137
+ <div class="flex items-center text-sm text-gray-500">
138
+ <span id="bytesReceived">0</span> bytes received
139
+ </div>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ </div>
144
+
145
+ <!-- Quick Actions Card -->
146
+ <div class="policy-card bg-white rounded-xl p-6">
147
+ <div class="flex items-center mb-6">
148
+ <div class="p-3 rounded-full bg-purple-100 text-purple-600 mr-4">
149
+ <i class="fas fa-bolt text-2xl"></i>
150
+ </div>
151
+ <h2 class="text-2xl font-bold text-gray-800">Quick Actions</h2>
152
+ </div>
153
+
154
+ <div class="space-y-4">
155
+ <button onclick="showPolicyEditor()" class="w-full flex items-center justify-between px-4 py-3 bg-blue-50 text-blue-600 rounded-lg hover:bg-blue-100 transition">
156
+ <span>Add New URL Policy</span>
157
+ <i class="fas fa-plus"></i>
158
+ </button>
159
+
160
+ <button onclick="showExamples()" class="w-full flex items-center justify-between px-4 py-3 bg-green-50 text-green-600 rounded-lg hover:bg-green-100 transition">
161
+ <span>View Configuration Examples</span>
162
+ <i class="fas fa-code"></i>
163
+ </button>
164
+
165
+ <button onclick="showCompatibility()" class="w-full flex items-center justify-between px-4 py-3 bg-yellow-50 text-yellow-600 rounded-lg hover:bg-yellow-100 transition">
166
+ <span>Check Compatibility</span>
167
+ <i class="fas fa-check-circle"></i>
168
+ </button>
169
+
170
+ <button onclick="showRelatedPolicies()" class="w-full flex items-center justify-between px-4 py-3 bg-indigo-50 text-indigo-600 rounded-lg hover:bg-indigo-100 transition">
171
+ <span>Related Policies</span>
172
+ <i class="fas fa-link"></i>
173
+ </button>
174
+ </div>
175
+
176
+ <div class="mt-8 pt-6 border-t border-gray-200">
177
+ <h3 class="text-lg font-medium text-gray-900 mb-3">Extension Status</h3>
178
+ <div id="extensionStatus" class="flex items-center">
179
+ <div class="h-3 w-3 rounded-full bg-gray-300 mr-2"></div>
180
+ <span class="text-sm text-gray-600">Checking extension...</span>
181
+ </div>
182
+ <button id="installExtensionBtn" class="hidden mt-3 w-full px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500">
183
+ Install Extension
184
+ </button>
185
+ </div>
186
+ </div>
187
+ </div>
188
+
189
+ <!-- Policy Editor (Hidden by default) -->
190
+ <div id="policyEditor" class="hidden mt-8 policy-card bg-white rounded-xl p-6 fade-in">
191
+ <div class="flex items-center mb-6">
192
+ <div class="p-3 rounded-full bg-blue-100 text-blue-600 mr-4">
193
+ <i class="fas fa-edit text-2xl"></i>
194
+ </div>
195
+ <h2 class="text-2xl font-bold text-gray-800">Policy Editor</h2>
196
+ </div>
197
+
198
+ <div class="space-y-4">
199
+ <div>
200
+ <label for="urlInput" class="block text-sm font-medium text-gray-700 mb-1">Website URL</label>
201
+ <div class="mt-1 flex rounded-md shadow-sm">
202
+ <span class="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500">
203
+ https://
204
+ </span>
205
+ <input type="text" id="urlInput" class="focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded-none rounded-r-md sm:text-sm border-gray-300" placeholder="www.example.com">
206
+ </div>
207
+ <p class="mt-1 text-sm text-gray-500">Enter a valid URL (only scheme, host and port will be considered)</p>
208
+ </div>
209
+
210
+ <div class="flex justify-end space-x-3 pt-4">
211
+ <button onclick="hidePolicyEditor()" class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
212
+ Cancel
213
+ </button>
214
+ <button onclick="addPolicy()" class="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
215
+ Add Policy
216
+ </button>
217
+ </div>
218
+ </div>
219
+ </div>
220
+
221
+ <!-- Examples Section (Hidden by default) -->
222
+ <div id="examplesSection" class="hidden mt-8 policy-card bg-white rounded-xl p-6 fade-in">
223
+ <div class="flex items-center mb-6">
224
+ <div class="p-3 rounded-full bg-green-100 text-green-600 mr-4">
225
+ <i class="fas fa-code text-2xl"></i>
226
+ </div>
227
+ <h2 class="text-2xl font-bold text-gray-800">Configuration Examples</h2>
228
+ </div>
229
+
230
+ <div class="mb-4 border-b border-gray-200">
231
+ <nav class="-mb-px flex space-x-8">
232
+ <button onclick="switchTab('windowsTab')" id="windowsTabBtn" class="tab-active whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm">
233
+ Windows
234
+ </button>
235
+ <button onclick="switchTab('chromeOSTab')" id="chromeOSTabBtn" class="whitespace-nowrap py-4 px-1 border-b-2 border-transparent font-medium text-sm text-gray-500 hover:text-gray-700 hover:border-gray-300">
236
+ ChromeOS
237
+ </button>
238
+ <button onclick="switchTab('linuxTab')" id="linuxTabBtn" class="whitespace-nowrap py-4 px-1 border-b-2 border-transparent font-medium text-sm text-gray-500 hover:text-gray-700 hover:border-gray-300">
239
+ Linux
240
+ </button>
241
+ <button onclick="switchTab('macTab')" id="macTabBtn" class="whitespace-nowrap py-4 px-1 border-b-2 border-transparent font-medium text-sm text-gray-500 hover:text-gray-700 hover:border-gray-300">
242
+ macOS
243
+ </button>
244
+ </nav>
245
+ </div>
246
+
247
+ <div id="windowsTab" class="tab-content">
248
+ <div class="code-block p-4 rounded-lg">
249
+ <div class="flex justify-between items-center mb-2">
250
+ <span class="text-sm text-gray-400">Windows Registry</span>
251
+ <button onclick="copyCode('windowsCode')" class="text-blue-400 hover:text-blue-200 text-sm">
252
+ <i class="fas fa-copy mr-1"></i>Copy
253
+ </button>
254
+ </div>
255
+ <pre id="windowsCode" class="overflow-x-auto">Software\Policies\Google\Chrome\SerialAllowAllPortsForUrls\1 = "https://www.example.com"</pre>
256
+ </div>
257
+ </div>
258
+
259
+ <div id="chromeOSTab" class="hidden tab-content">
260
+ <div class="code-block p-4 rounded-lg">
261
+ <div class="flex justify-between items-center mb-2">
262
+ <span class="text-sm text-gray-400">ChromeOS (Active Directory)</span>
263
+ <button onclick="copyCode('chromeOSCode')" class="text-blue-400 hover:text-blue-200 text-sm">
264
+ <i class="fas fa-copy mr-1"></i>Copy
265
+ </button>
266
+ </div>
267
+ <pre id="chromeOSCode" class="overflow-x-auto">line 1 = "https://www.example.com"</pre>
268
+ </div>
269
+ </div>
270
+
271
+ <div id="linuxTab" class="hidden tab-content">
272
+ <div class="code-block p-4 rounded-lg">
273
+ <div class="flex justify-between items-center mb-2">
274
+ <span class="text-sm text-gray-400">Linux JSON</span>
275
+ <button onclick="copyCode('linuxCode')" class="text-blue-400 hover:text-blue-200 text-sm">
276
+ <i class="fas fa-copy mr-1"></i>Copy
277
+ </button>
278
+ </div>
279
+ <pre id="linuxCode" class="overflow-x-auto">[
280
+ "https://www.example.com"
281
+ ]</pre>
282
+ </div>
283
+ </div>
284
+
285
+ <div id="macTab" class="hidden tab-content">
286
+ <div class="code-block p-4 rounded-lg">
287
+ <div class="flex justify-between items-center mb-2">
288
+ <span class="text-sm text-gray-400">macOS PLIST</span>
289
+ <button onclick="copyCode('macCode')" class="text-blue-400 hover:text-blue-200 text-sm">
290
+ <i class="fas fa-copy mr-1"></i>Copy
291
+ </button>
292
+ </div>
293
+ <pre id="macCode" class="overflow-x-auto">&lt;array&gt;
294
+ &lt;string&gt;https://www.example.com&lt;/string&gt;
295
+ &lt;/array&gt;</pre>
296
+ </div>
297
+ </div>
298
+ </div>
299
+
300
+ <!-- Compatibility Checker (Hidden by default) -->
301
+ <div id="compatibilitySection" class="hidden mt-8 policy-card bg-white rounded-xl p-6 fade-in">
302
+ <div class="flex items-center mb-6">
303
+ <div class="p-3 rounded-full bg-yellow-100 text-yellow-600 mr-4">
304
+ <i class="fas fa-check-circle text-2xl"></i>
305
+ </div>
306
+ <h2 class="text-2xl font-bold text-gray-800">Compatibility Check</h2>
307
+ </div>
308
+
309
+ <div class="space-y-4">
310
+ <div class="flex items-start">
311
+ <div class="flex-shrink-0">
312
+ <div class="flex items-center justify-center h-12 w-12 rounded-full bg-green-100">
313
+ <i class="fas fa-check text-green-600"></i>
314
+ </div>
315
+ </div>
316
+ <div class="ml-4">
317
+ <h3 class="text-lg font-medium text-gray-900">Minimum Chrome Version</h3>
318
+ <p class="mt-1 text-sm text-gray-600">
319
+ This policy is supported on Chrome version 94 and later across all platforms.
320
+ </p>
321
+ </div>
322
+ </div>
323
+
324
+ <div class="flex items-start">
325
+ <div class="flex-shrink-0">
326
+ <div class="flex items-center justify-center h-12 w-12 rounded-full bg-blue-100">
327
+ <i class="fas fa-info-circle text-blue-600"></i>
328
+ </div>
329
+ </div>
330
+ <div class="ml-4">
331
+ <h3 class="text-lg font-medium text-gray-900">ChromeOS Specifics</h3>
332
+ <p class="mt-1 text-sm text-gray-600">
333
+ On ChromeOS, this policy only applies to affiliated users (managed devices).
334
+ </p>
335
+ </div>
336
+ </div>
337
+
338
+ <div class="flex items-start">
339
+ <div class="flex-shrink-0">
340
+ <div class="flex items-center justify-center h-12 w-12 rounded-full bg-purple-100">
341
+ <i class="fas fa-random text-purple-600"></i>
342
+ </div>
343
+ </div>
344
+ <div class="ml-4">
345
+ <h3 class="text-lg font-medium text-gray-900">Policy Precedence</h3>
346
+ <p class="mt-1 text-sm text-gray-600">
347
+ This policy overrides DefaultSerialGuardSetting, SerialAskForUrls, and SerialBlockedForUrls policies.
348
+ </p>
349
+ </div>
350
+ </div>
351
+ </div>
352
+ </div>
353
+
354
+ <!-- Related Policies (Hidden by default) -->
355
+ <div id="relatedPoliciesSection" class="hidden mt-8 policy-card bg-white rounded-xl p-6 fade-in">
356
+ <div class="flex items-center mb-6">
357
+ <div class="p-3 rounded-full bg-indigo-100 text-indigo-600 mr-4">
358
+ <i class="fas fa-link text-2xl"></i>
359
+ </div>
360
+ <h2 class="text-2xl font-bold text-gray-800">Related Policies</h2>
361
+ </div>
362
+
363
+ <div class="space-y-4">
364
+ <div class="p-4 border border-gray-200 rounded-lg hover:border-blue-300 transition">
365
+ <h3 class="text-lg font-medium text-gray-900">DefaultSerialGuardSetting</h3>
366
+ <p class="mt-1 text-sm text-gray-600">
367
+ Controls the default behavior for websites requesting access to serial ports.
368
+ </p>
369
+ </div>
370
+
371
+ <div class="p-4 border border-gray-200 rounded-lg hover:border-blue-300 transition">
372
+ <h3 class="text-lg font-medium text-gray-900">SerialAskForUrls</h3>
373
+ <p class="mt-1 text-sm text-gray-600">
374
+ Lists URLs that should prompt users for permission to access serial ports.
375
+ </p>
376
+ </div>
377
+
378
+ <div class="p-4 border border-gray-200 rounded-lg hover:border-blue-300 transition">
379
+ <h3 class="text-lg font-medium text-gray-900">SerialBlockedForUrls</h3>
380
+ <p class="mt-1 text-sm text-gray-600">
381
+ Lists URLs that should be blocked from accessing serial ports.
382
+ </p>
383
+ </div>
384
+ </div>
385
+ </div>
386
+ </div>
387
+
388
+ <script>
389
+ // Serial port variables
390
+ let port;
391
+ let reader;
392
+ let receivedBytes = 0;
393
+ let keepReading = true;
394
+
395
+ // DOM elements
396
+ const requestPortBtn = document.getElementById('requestPortBtn');
397
+ const connectBtn = document.getElementById('connectBtn');
398
+ const disconnectBtn = document.getElementById('disconnectBtn');
399
+ const sendDataBtn = document.getElementById('sendDataBtn');
400
+ const dataInput = document.getElementById('dataInput');
401
+ const baudRate = document.getElementById('baudRate');
402
+ const serialConsole = document.getElementById('serialConsole');
403
+ const clearConsoleBtn = document.getElementById('clearConsoleBtn');
404
+ const bytesReceived = document.getElementById('bytesReceived');
405
+ const portInfo = document.getElementById('portInfo');
406
+ const portName = document.getElementById('portName');
407
+ const connectionStatus = document.getElementById('connectionStatus');
408
+ const extensionStatus = document.getElementById('extensionStatus');
409
+ const installExtensionBtn = document.getElementById('installExtensionBtn');
410
+
411
+ // Check if Web Serial API is available
412
+ function checkWebSerialSupport() {
413
+ if ('serial' in navigator) {
414
+ extensionStatus.innerHTML = '<div class="h-3 w-3 rounded-full bg-green-500 mr-2"></div><span class="text-sm text-gray-600">Web Serial API supported</span>';
415
+ } else {
416
+ extensionStatus.innerHTML = '<div class="h-3 w-3 rounded-full bg-red-500 mr-2"></div><span class="text-sm text-gray-600">Web Serial API not supported</span>';
417
+ installExtensionBtn.classList.remove('hidden');
418
+ installExtensionBtn.addEventListener('click', () => {
419
+ window.open('https://chrome.google.com/webstore/detail/serial-api-polyfill/ghfdlgblclfcljllkjlbjdcbjgjkennf', '_blank');
420
+ });
421
+ }
422
+ }
423
+
424
+ // Request serial port access
425
+ async function requestPort() {
426
+ try {
427
+ port = await navigator.serial.requestPort();
428
+ portName.textContent = port.getInfo().usbProductId ?
429
+ `USB Device (${port.getInfo().usbProductId})` : 'Serial Port';
430
+ portInfo.classList.remove('hidden');
431
+ connectBtn.disabled = false;
432
+ showToast('Port selected successfully', 'success');
433
+ } catch (err) {
434
+ showToast('Port selection was canceled', 'error');
435
+ console.error('Error requesting port:', err);
436
+ }
437
+ }
438
+
439
+ // Connect to serial port
440
+ async function connectPort() {
441
+ try {
442
+ await port.open({ baudRate: parseInt(baudRate.value) });
443
+ connectionStatus.textContent = 'Connected';
444
+ connectionStatus.classList.add('text-green-600');
445
+ connectBtn.disabled = true;
446
+ disconnectBtn.disabled = false;
447
+ sendDataBtn.disabled = false;
448
+ showToast('Connected to port successfully', 'success');
449
+
450
+ // Start reading from the port
451
+ readFromPort();
452
+ } catch (err) {
453
+ showToast('Failed to connect to port', 'error');
454
+ console.error('Error opening port:', err);
455
+ }
456
+ }
457
+
458
+ // Disconnect from serial port
459
+ async function disconnectPort() {
460
+ try {
461
+ keepReading = false;
462
+ if (reader) {
463
+ await reader.cancel();
464
+ }
465
+ await port.close();
466
+ connectionStatus.textContent = 'Disconnected';
467
+ connectionStatus.classList.remove('text-green-600');
468
+ connectBtn.disabled = false;
469
+ disconnectBtn.disabled = true;
470
+ sendDataBtn.disabled = true;
471
+ showToast('Disconnected from port', 'info');
472
+ } catch (err) {
473
+ showToast('Error disconnecting from port', 'error');
474
+ console.error('Error closing port:', err);
475
+ }
476
+ }
477
+
478
+ // Read data from serial port
479
+ async function readFromPort() {
480
+ keepReading = true;
481
+ try {
482
+ while (port.readable && keepReading) {
483
+ reader = port.readable.getReader();
484
+ try {
485
+ while (keepReading) {
486
+ const { value, done } = await reader.read();
487
+ if (done) {
488
+ break;
489
+ }
490
+
491
+ // Convert received data to text
492
+ const textDecoder = new TextDecoder();
493
+ const text = textDecoder.decode(value);
494
+
495
+ // Update UI with received data
496
+ receivedBytes += text.length;
497
+ bytesReceived.textContent = receivedBytes;
498
+
499
+ // Add timestamp
500
+ const now = new Date();
501
+ const timestamp = `[${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}] `;
502
+
503
+ // Add to console
504
+ if (serialConsole.firstChild.textContent === 'No data received yet...') {
505
+ serialConsole.firstChild.remove();
506
+ }
507
+
508
+ const messageElement = document.createElement('div');
509
+ messageElement.innerHTML = `<span class="text-gray-400">${timestamp}</span>${text.replace(/\n/g, '<br>')}`;
510
+ serialConsole.appendChild(messageElement);
511
+ serialConsole.scrollTop = serialConsole.scrollHeight;
512
+ }
513
+ } catch (err) {
514
+ showToast('Error reading from port', 'error');
515
+ console.error('Error reading from port:', err);
516
+ } finally {
517
+ reader.releaseLock();
518
+ }
519
+ }
520
+ } catch (err) {
521
+ showToast('Port disconnected unexpectedly', 'error');
522
+ console.error('Port error:', err);
523
+ disconnectPort();
524
+ }
525
+ }
526
+
527
+ // Send data to serial port
528
+ async function sendData() {
529
+ if (!port || !port.writable) {
530
+ showToast('Port is not connected', 'error');
531
+ return;
532
+ }
533
+
534
+ const data = dataInput.value;
535
+ if (!data) {
536
+ showToast('Please enter data to send', 'error');
537
+ return;
538
+ }
539
+
540
+ try {
541
+ const writer = port.writable.getWriter();
542
+ const encoder = new TextEncoder();
543
+ await writer.write(encoder.encode(data + '\n'));
544
+ writer.releaseLock();
545
+
546
+ // Add to console as sent data
547
+ const now = new Date();
548
+ const timestamp = `[${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}] `;
549
+
550
+ const messageElement = document.createElement('div');
551
+ messageElement.innerHTML = `<span class="text-gray-400">${timestamp}</span><span class="text-blue-400">&gt; ${data}</span>`;
552
+ serialConsole.appendChild(messageElement);
553
+ serialConsole.scrollTop = serialConsole.scrollHeight;
554
+
555
+ dataInput.value = '';
556
+ showToast('Data sent successfully', 'success');
557
+ } catch (err) {
558
+ showToast('Failed to send data', 'error');
559
+ console.error('Error sending data:', err);
560
+ }
561
+ }
562
+
563
+ // Clear console
564
+ function clearConsole() {
565
+ serialConsole.innerHTML = '<div class="text-gray-400">No data received yet...</div>';
566
+ receivedBytes = 0;
567
+ bytesReceived.textContent = '0';
568
+ }
569
+
570
+ // Show toast notification
571
+ function showToast(message, type) {
572
+ const toast = document.createElement('div');
573
+ toast.className = `fixed bottom-4 right-4 px-4 py-2 rounded-md shadow-md text-white ${
574
+ type === 'success' ? 'bg-green-500' :
575
+ type === 'error' ? 'bg-red-500' : 'bg-blue-500'
576
+ }`;
577
+ toast.textContent = message;
578
+ document.body.appendChild(toast);
579
+
580
+ setTimeout(() => {
581
+ toast.classList.add('opacity-0', 'transition-opacity', 'duration-300');
582
+ setTimeout(() => toast.remove(), 300);
583
+ }, 3000);
584
+ }
585
+
586
+ // Event listeners
587
+ requestPortBtn.addEventListener('click', requestPort);
588
+ connectBtn.addEventListener('click', connectPort);
589
+ disconnectBtn.addEventListener('click', disconnectPort);
590
+ sendDataBtn.addEventListener('click', sendData);
591
+ clearConsoleBtn.addEventListener('click', clearConsole);
592
+ dataInput.addEventListener('keypress', (e) => {
593
+ if (e.key === 'Enter') {
594
+ sendData();
595
+ }
596
+ });
597
+
598
+ // Show/hide sections
599
+ function showPolicyEditor() {
600
+ hideAllSections();
601
+ document.getElementById('policyEditor').classList.remove('hidden');
602
+ }
603
+
604
+ function showExamples() {
605
+ hideAllSections();
606
+ document.getElementById('examplesSection').classList.remove('hidden');
607
+ }
608
+
609
+ function showCompatibility() {
610
+ hideAllSections();
611
+ document.getElementById('compatibilitySection').classList.remove('hidden');
612
+ }
613
+
614
+ function showRelatedPolicies() {
615
+ hideAllSections();
616
+ document.getElementById('relatedPoliciesSection').classList.remove('hidden');
617
+ }
618
+
619
+ function hidePolicyEditor() {
620
+ document.getElementById('policyEditor').classList.add('hidden');
621
+ }
622
+
623
+ function hideAllSections() {
624
+ document.getElementById('policyEditor').classList.add('hidden');
625
+ document.getElementById('examplesSection').classList.add('hidden');
626
+ document.getElementById('compatibilitySection').classList.add('hidden');
627
+ document.getElementById('relatedPoliciesSection').classList.add('hidden');
628
+ }
629
+
630
+ // Tab switching for examples
631
+ function switchTab(tabId) {
632
+ // Hide all tab contents
633
+ document.querySelectorAll('.tab-content').forEach(tab => {
634
+ tab.classList.add('hidden');
635
+ });
636
+
637
+ // Remove active class from all tab buttons
638
+ document.querySelectorAll('[id$="TabBtn"]').forEach(btn => {
639
+ btn.classList.remove('tab-active', 'text-blue-600', 'border-blue-500');
640
+ btn.classList.add('text-gray-500', 'border-transparent');
641
+ });
642
+
643
+ // Show selected tab content
644
+ document.getElementById(tabId).classList.remove('hidden');
645
+
646
+ // Add active class to selected tab button
647
+ document.getElementById(tabId + 'Btn').classList.add('tab-active', 'text-blue-600', 'border-blue-500');
648
+ document.getElementById(tabId + 'Btn').classList.remove('text-gray-500', 'border-transparent');
649
+ }
650
+
651
+ // Copy code to clipboard
652
+ function copyCode(elementId) {
653
+ const codeElement = document.getElementById(elementId);
654
+ const range = document.createRange();
655
+ range.selectNode(codeElement);
656
+ window.getSelection().removeAllRanges();
657
+ window.getSelection().addRange(range);
658
+ document.execCommand('copy');
659
+ window.getSelection().removeAllRanges();
660
+
661
+ // Show copied notification
662
+ const originalText = event.target.innerHTML;
663
+ event.target.innerHTML = '<i class="fas fa-check mr-1"></i>Copied!';
664
+ setTimeout(() => {
665
+ event.target.innerHTML = originalText;
666
+ }, 2000);
667
+ }
668
+
669
+ // Add policy (simulated)
670
+ function addPolicy() {
671
+ const urlInput = document.getElementById('urlInput');
672
+ if (urlInput.value.trim() === '') {
673
+ showToast('Please enter a valid URL', 'error');
674
+ return;
675
+ }
676
+
677
+ // In a real application, this would save the policy
678
+ showToast(`Policy added for: ${urlInput.value}`, 'success');
679
+ urlInput.value = '';
680
+ hidePolicyEditor();
681
+ }
682
+
683
+ // Initialize
684
+ checkWebSerialSupport();
685
+ </script>
686
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=drbaker171/sp" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
687
+ </html>