nzgnzg73 commited on
Commit
a7ef04e
·
verified ·
1 Parent(s): 46f982d

Upload voice to text.html

Browse files
Files changed (1) hide show
  1. Speech to text/voice to text.html +1433 -0
Speech to text/voice to text.html ADDED
@@ -0,0 +1,1433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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, maximum-scale=1.0, user-scalable=no">
6
+ <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
7
+ <title>NZG 73 Pro - Speech to Text (Complete)</title>
8
+ <style>
9
+ * { margin: 0; padding: 0; box-sizing: border-box; }
10
+ :root {
11
+ --bg-primary: #0a0a0a; --bg-secondary: #1a1a2e; --bg-card: rgba(255,255,255,0.05);
12
+ --text-primary: #ffffff; --text-secondary: #888888; --accent: #00d4ff; --accent2: #00ff88; --danger: #ff0040;
13
+ --font-size: 18px;
14
+ }
15
+ body.light-mode {
16
+ --bg-primary: #f5f5f5; --bg-secondary: #ffffff; --bg-card: rgba(0,0,0,0.05); --text-primary: #1a1a1a; --text-secondary: #666666;
17
+ }
18
+ body {
19
+ font-family: 'Segoe UI', Tahoma, sans-serif;
20
+ background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%);
21
+ min-height: 100vh;
22
+ color: var(--text-primary);
23
+ transition: all 0.3s ease;
24
+ }
25
+
26
+ /* Top Bar */
27
+ .top-bar {
28
+ display: flex;
29
+ justify-content: space-between;
30
+ align-items: center;
31
+ padding: 10px 15px;
32
+ background: rgba(0,0,0,0.3);
33
+ position: sticky;
34
+ top: 0;
35
+ z-index: 100;
36
+ backdrop-filter: blur(10px);
37
+ animation: slideDown 0.5s ease;
38
+ }
39
+ .logo {
40
+ font-size: 24px;
41
+ font-weight: bold;
42
+ background: linear-gradient(45deg, #ff0080, #00d4ff, #00ff88);
43
+ -webkit-background-clip: text;
44
+ -webkit-text-fill-color: transparent;
45
+ animation: glow 2s infinite alternate;
46
+ }
47
+ .icon-btn {
48
+ width: 40px;
49
+ height: 40px;
50
+ border-radius: 50%;
51
+ border: 2px solid var(--accent);
52
+ background: transparent;
53
+ color: var(--text-primary);
54
+ cursor: pointer;
55
+ display: flex;
56
+ align-items: center;
57
+ justify-content: center;
58
+ font-size: 18px;
59
+ transition: all 0.3s;
60
+ }
61
+ .icon-btn:hover {
62
+ transform: scale(1.1);
63
+ box-shadow: 0 0 10px var(--accent);
64
+ }
65
+
66
+ /* Tabs */
67
+ .tabs {
68
+ display: flex;
69
+ justify-content: center;
70
+ gap: 5px;
71
+ padding: 15px;
72
+ background: var(--bg-card);
73
+ flex-wrap: wrap;
74
+ animation: fadeIn 0.8s ease;
75
+ }
76
+ .tab-btn {
77
+ padding: 10px 20px;
78
+ border: none;
79
+ background: transparent;
80
+ color: var(--text-secondary);
81
+ cursor: pointer;
82
+ font-weight: bold;
83
+ border-radius: 25px;
84
+ transition: all 0.3s;
85
+ }
86
+ .tab-btn:hover {
87
+ transform: translateY(-2px);
88
+ }
89
+ .tab-btn.active {
90
+ background: var(--accent);
91
+ color: #000;
92
+ animation: pulseBtn 2s infinite;
93
+ }
94
+
95
+ /* Content */
96
+ .tab-content {
97
+ display: none;
98
+ padding: 15px;
99
+ max-width: 1000px;
100
+ margin: 0 auto;
101
+ }
102
+ .tab-content.active {
103
+ display: block;
104
+ animation: slideUp 0.5s ease;
105
+ }
106
+
107
+ /* Animations */
108
+ @keyframes slideDown {
109
+ from { transform: translateY(-20px); opacity: 0; }
110
+ to { transform: translateY(0); opacity: 1; }
111
+ }
112
+ @keyframes slideUp {
113
+ from { transform: translateY(20px); opacity: 0; }
114
+ to { transform: translateY(0); opacity: 1; }
115
+ }
116
+ @keyframes fadeIn {
117
+ from { opacity: 0; }
118
+ to { opacity: 1; }
119
+ }
120
+ @keyframes glow {
121
+ from { text-shadow: 0 0 10px #00d4ff, 0 0 20px #00d4ff; }
122
+ to { text-shadow: 0 0 20px #ff0080, 0 0 30px #ff0080; }
123
+ }
124
+ @keyframes pulseBtn {
125
+ 0% { box-shadow: 0 0 0 0 rgba(0, 212, 255, 0.7); }
126
+ 70% { box-shadow: 0 0 0 10px rgba(0, 212, 255, 0); }
127
+ 100% { box-shadow: 0 0 0 0 rgba(0, 212, 255, 0); }
128
+ }
129
+ @keyframes bounce {
130
+ 0%, 100% { transform: translateY(0); }
131
+ 50% { transform: translateY(-10px); }
132
+ }
133
+
134
+ /* Mic & Lang */
135
+ .lang-section {
136
+ background: var(--bg-card);
137
+ border-radius: 15px;
138
+ padding: 15px;
139
+ margin-bottom: 15px;
140
+ text-align: center;
141
+ animation: fadeIn 1s ease;
142
+ }
143
+ .lang-buttons {
144
+ display: flex;
145
+ justify-content: center;
146
+ gap: 8px;
147
+ flex-wrap: wrap;
148
+ margin-top: 10px;
149
+ }
150
+ .lang-btn {
151
+ padding: 8px 16px;
152
+ border: 2px solid #444;
153
+ background: transparent;
154
+ color: var(--text-primary);
155
+ border-radius: 20px;
156
+ cursor: pointer;
157
+ transition: all 0.3s;
158
+ }
159
+ .lang-btn:hover {
160
+ transform: scale(1.05);
161
+ }
162
+ .lang-btn.active {
163
+ background: var(--accent);
164
+ color: #000;
165
+ border-color: var(--accent);
166
+ animation: bounce 0.5s;
167
+ }
168
+
169
+ .mic-section {
170
+ text-align: center;
171
+ padding: 20px;
172
+ animation: fadeIn 1.2s ease;
173
+ }
174
+ .mic-btn {
175
+ width: 90px;
176
+ height: 90px;
177
+ border-radius: 50%;
178
+ border: 4px solid #333;
179
+ background: #222;
180
+ cursor: pointer;
181
+ font-size: 40px;
182
+ transition: all 0.3s;
183
+ color: #fff;
184
+ animation: bounce 2s infinite;
185
+ }
186
+ .mic-btn:hover {
187
+ border-color: var(--accent);
188
+ transform: scale(1.05);
189
+ }
190
+ .mic-btn.recording {
191
+ border-color: var(--danger);
192
+ animation: pulse 1s infinite;
193
+ background: #300;
194
+ }
195
+ @keyframes pulse {
196
+ 0% { box-shadow: 0 0 0 0 rgba(255,0,64,0.7); }
197
+ 70% { box-shadow: 0 0 0 20px rgba(255,0,64,0); }
198
+ }
199
+ .mic-status {
200
+ margin-top: 10px;
201
+ color: var(--text-secondary);
202
+ font-weight: bold;
203
+ }
204
+
205
+ /* Editor */
206
+ .text-section {
207
+ background: var(--bg-card);
208
+ border-radius: 15px;
209
+ padding: 15px;
210
+ animation: fadeIn 1.5s ease;
211
+ }
212
+ .text-header {
213
+ display: flex;
214
+ justify-content: space-between;
215
+ align-items: center;
216
+ margin-bottom: 10px;
217
+ flex-wrap: wrap;
218
+ gap: 10px;
219
+ }
220
+ .action-btn {
221
+ padding: 6px 12px;
222
+ border: 1px solid #444;
223
+ background: rgba(255,255,255,0.05);
224
+ color: var(--text-primary);
225
+ border-radius: 15px;
226
+ cursor: pointer;
227
+ font-size: 12px;
228
+ transition: all 0.3s;
229
+ display: flex;
230
+ align-items: center;
231
+ gap: 5px;
232
+ }
233
+ .action-btn:hover {
234
+ background: var(--accent);
235
+ color: #000;
236
+ transform: translateY(-2px);
237
+ }
238
+
239
+ /* Text zoom buttons */
240
+ .zoom-controls {
241
+ display: flex;
242
+ gap: 5px;
243
+ margin-left: 10px;
244
+ }
245
+ .zoom-btn {
246
+ width: 30px;
247
+ height: 30px;
248
+ border-radius: 50%;
249
+ border: 1px solid #444;
250
+ background: rgba(255,255,255,0.05);
251
+ color: var(--text-primary);
252
+ cursor: pointer;
253
+ display: flex;
254
+ align-items: center;
255
+ justify-content: center;
256
+ font-weight: bold;
257
+ transition: all 0.3s;
258
+ }
259
+ .zoom-btn:hover {
260
+ background: var(--accent);
261
+ color: #000;
262
+ }
263
+
264
+ .text-editor {
265
+ width: 100%;
266
+ min-height: 250px;
267
+ background: rgba(0,0,0,0.3);
268
+ border: 1px solid #333;
269
+ border-radius: 10px;
270
+ padding: 15px;
271
+ color: var(--text-primary);
272
+ font-size: var(--font-size);
273
+ line-height: 1.6;
274
+ resize: vertical;
275
+ font-family: inherit;
276
+ transition: all 0.3s;
277
+ overflow-y: auto;
278
+ overflow-x: hidden;
279
+ white-space: pre-wrap;
280
+ word-break: break-word;
281
+ -webkit-overflow-scrolling: touch;
282
+ }
283
+ .text-editor.urdu-mode {
284
+ direction: rtl;
285
+ text-align: right;
286
+ font-family: 'Noto Nastaliq Urdu', 'Segoe UI', Arial, serif;
287
+ }
288
+ body.light-mode .text-editor {
289
+ background: #fff;
290
+ border-color: #ccc;
291
+ color: #000;
292
+ }
293
+
294
+ /* History Items */
295
+ .history-list {
296
+ display: flex;
297
+ flex-direction: column;
298
+ gap: 10px;
299
+ }
300
+ .history-item {
301
+ background: var(--bg-card);
302
+ padding: 15px;
303
+ border-radius: 10px;
304
+ border: 1px solid rgba(255,255,255,0.1);
305
+ animation: slideUp 0.3s ease;
306
+ }
307
+ .history-item-header {
308
+ display: flex;
309
+ justify-content: space-between;
310
+ margin-bottom: 5px;
311
+ }
312
+ .history-title {
313
+ color: var(--accent);
314
+ font-weight: bold;
315
+ }
316
+ .history-text {
317
+ font-size: 14px;
318
+ color: var(--text-secondary);
319
+ max-height: 60px;
320
+ overflow: hidden;
321
+ margin-bottom: 10px;
322
+ }
323
+ .history-actions {
324
+ display: flex;
325
+ gap: 5px;
326
+ flex-wrap: wrap;
327
+ }
328
+ .delete-btn {
329
+ color: var(--danger);
330
+ border-color: var(--danger);
331
+ }
332
+ .delete-btn:hover {
333
+ background: var(--danger);
334
+ color: #fff;
335
+ }
336
+
337
+ /* Modals */
338
+ .modal-overlay {
339
+ display: none;
340
+ position: fixed;
341
+ top: 0;
342
+ left: 0;
343
+ width: 100%;
344
+ height: 100%;
345
+ background: rgba(0,0,0,0.8);
346
+ z-index: 1000;
347
+ justify-content: center;
348
+ align-items: center;
349
+ animation: fadeIn 0.3s ease;
350
+ }
351
+ .modal-overlay.active {
352
+ display: flex;
353
+ }
354
+ .modal {
355
+ background: var(--bg-secondary);
356
+ padding: 25px;
357
+ border-radius: 15px;
358
+ width: 90%;
359
+ max-width: 400px;
360
+ border: 1px solid #444;
361
+ animation: slideUp 0.5s ease;
362
+ }
363
+ .modal h3 {
364
+ color: var(--accent);
365
+ margin-bottom: 15px;
366
+ text-align: center;
367
+ }
368
+ .modal input {
369
+ width: 100%;
370
+ padding: 10px;
371
+ margin-bottom: 15px;
372
+ background: rgba(0,0,0,0.3);
373
+ border: 1px solid #444;
374
+ color: #fff;
375
+ border-radius: 5px;
376
+ }
377
+ body.light-mode .modal input {
378
+ background: #f5f5f5;
379
+ color: #000;
380
+ border-color: #ccc;
381
+ }
382
+ .modal-btns {
383
+ display: flex;
384
+ gap: 10px;
385
+ }
386
+ .modal-btn {
387
+ flex: 1;
388
+ padding: 10px;
389
+ border: none;
390
+ border-radius: 5px;
391
+ cursor: pointer;
392
+ font-weight: bold;
393
+ transition: all 0.3s;
394
+ }
395
+ .modal-btn:hover {
396
+ transform: translateY(-2px);
397
+ }
398
+ .primary {
399
+ background: var(--accent);
400
+ color: #000;
401
+ }
402
+ .secondary {
403
+ background: #444;
404
+ color: #fff;
405
+ }
406
+
407
+ /* Toast */
408
+ .toast {
409
+ position: fixed;
410
+ bottom: 80px;
411
+ left: 50%;
412
+ transform: translateX(-50%);
413
+ background: var(--accent);
414
+ color: #000;
415
+ padding: 10px 20px;
416
+ border-radius: 20px;
417
+ font-weight: bold;
418
+ z-index: 2000;
419
+ animation: slideUp 0.3s;
420
+ }
421
+
422
+ /* Fullscreen */
423
+ .fullscreen-controls {
424
+ display: none;
425
+ position: fixed;
426
+ bottom: 20px;
427
+ left: 50%;
428
+ transform: translateX(-50%);
429
+ background: rgba(0,0,0,0.9);
430
+ padding: 10px 20px;
431
+ border-radius: 30px;
432
+ gap: 10px;
433
+ z-index: 2000;
434
+ border: 1px solid #444;
435
+ animation: slideUp 0.5s;
436
+ }
437
+ body.fullscreen-mode .fullscreen-controls {
438
+ display: flex;
439
+ }
440
+ body.fullscreen-mode .top-bar,
441
+ body.fullscreen-mode .tabs,
442
+ body.fullscreen-mode .mic-section {
443
+ display: none;
444
+ }
445
+ body.fullscreen-mode .tab-content.active {
446
+ padding-top: 20px;
447
+ }
448
+ body.fullscreen-mode .text-editor {
449
+ height: 80vh;
450
+ }
451
+
452
+ /* Share Modal */
453
+ .share-options {
454
+ display: flex;
455
+ flex-direction: column;
456
+ gap: 10px;
457
+ margin-top: 15px;
458
+ }
459
+ .share-btn {
460
+ padding: 10px;
461
+ border: none;
462
+ border-radius: 10px;
463
+ background: rgba(0,0,0,0.3);
464
+ color: var(--text-primary);
465
+ cursor: pointer;
466
+ display: flex;
467
+ align-items: center;
468
+ gap: 10px;
469
+ transition: all 0.3s;
470
+ }
471
+ .share-btn:hover {
472
+ background: var(--accent);
473
+ color: #000;
474
+ transform: translateY(-2px);
475
+ }
476
+ </style>
477
+ </head>
478
+ <body>
479
+
480
+ <div class="top-bar">
481
+ <div class="logo">🎤 NZG 73 Pro</div>
482
+ <div>
483
+ <button class="icon-btn" onclick="toggleTheme()">🌓</button>
484
+ <button class="icon-btn" onclick="toggleFullscreen()" style="margin-left:5px">⛶</button>
485
+ </div>
486
+ </div>
487
+
488
+ <div class="tabs">
489
+ <button class="tab-btn active" onclick="showTab('speech')">🎙️ Speech</button>
490
+ <button class="tab-btn" onclick="showTab('history')">📚 History (36 Years)</button>
491
+ <button class="tab-btn" onclick="showTab('trash')">🗑️ Trash</button>
492
+ </div>
493
+
494
+ <div id="tab-speech" class="tab-content active">
495
+ <div class="lang-section">
496
+ <div class="lang-buttons">
497
+ <button class="lang-btn active" onclick="setLang('ur-PK')" id="btn-urdu">اردو</button>
498
+ <button class="lang-btn" onclick="setLang('en-US')" id="btn-english">English</button>
499
+ <button class="lang-btn" onclick="setLang('en-PK')" id="btn-pak-english">Pakistan English</button>
500
+ </div>
501
+ </div>
502
+
503
+ <div class="mic-section">
504
+ <button class="mic-btn" id="micBtn" onclick="toggleMic()">🎙️</button>
505
+ <p class="mic-status" id="micStatus">Tap to Start</p>
506
+ </div>
507
+
508
+ <div class="text-section">
509
+ <div class="text-header">
510
+ <h3 style="color:var(--accent)">📝 Text</h3>
511
+ <div style="display:flex; gap:5px; flex-wrap:wrap; align-items:center;">
512
+ <!-- Text Zoom Controls -->
513
+ <div class="zoom-controls">
514
+ <button class="zoom-btn" onclick="textZoom('out')">A-</button>
515
+ <button class="zoom-btn" onclick="textZoom('in')">A+</button>
516
+ </div>
517
+
518
+ <!-- Action Buttons -->
519
+ <button class="action-btn" onclick="toggleSpeak()" id="speakBtn">🔊 Speak</button>
520
+ <button class="action-btn" onclick="copyText()">📋 Copy</button>
521
+ <button class="action-btn" onclick="pasteText()">📥 Paste</button>
522
+ <button class="action-btn" onclick="clearText()">🗑️ Clear</button>
523
+
524
+ <!-- Undo/Redo Buttons -->
525
+ <button class="action-btn" onclick="undoText()" id="undoBtn" disabled>↶ Undo</button>
526
+ <button class="action-btn" onclick="redoText()" id="redoBtn" disabled>↷ Redo</button>
527
+
528
+ <!-- Share Button -->
529
+ <button class="action-btn" onclick="shareText()" style="background:linear-gradient(45deg, #ff0080, #00d4ff); color:white;">📤 Share</button>
530
+
531
+ <!-- Save Button -->
532
+ <button class="action-btn" onclick="openSaveModal()" style="background:var(--accent2); color:#000;">💾 SAVE</button>
533
+ </div>
534
+ </div>
535
+ <textarea class="text-editor" id="textEditor" placeholder="یہاں بولیں یا لکھیں..." oninput="updateCounts(); saveToHistoryStack();" onclick="saveCursorPosition()"></textarea>
536
+ <div style="margin-top:10px; text-align:center; color:var(--text-secondary); font-size:12px">
537
+ Words: <span id="wordCount">0</span> | Chars: <span id="charCount">0</span> | Cursor: <span id="cursorPos">0</span>
538
+ </div>
539
+ </div>
540
+ </div>
541
+
542
+ <div id="tab-history" class="tab-content">
543
+ <div class="text-header">
544
+ <h3>Saved Files</h3>
545
+ <button class="action-btn delete-btn" onclick="clearAllHistory()">Clear All</button>
546
+ </div>
547
+ <div class="history-list" id="historyList"></div>
548
+ </div>
549
+
550
+ <div id="tab-trash" class="tab-content">
551
+ <div class="text-header">
552
+ <h3>Trash Bin (36 Years Safe)</h3>
553
+ <button class="action-btn delete-btn" onclick="emptyTrash()">Empty Trash</button>
554
+ </div>
555
+ <div class="history-list" id="trashList"></div>
556
+ </div>
557
+
558
+ <div class="modal-overlay" id="saveModal">
559
+ <div class="modal">
560
+ <h3>💾 Save File</h3>
561
+ <input type="text" id="saveFileName" placeholder="File Name likhein...">
562
+ <div class="modal-btns">
563
+ <button class="modal-btn secondary" onclick="closeModals()">Cancel</button>
564
+ <button class="modal-btn primary" onclick="saveToHistory()">SAVE NOW</button>
565
+ </div>
566
+ </div>
567
+ </div>
568
+
569
+ <div class="modal-overlay" id="renameModal">
570
+ <div class="modal">
571
+ <h3>✏️ Rename File</h3>
572
+ <input type="text" id="renameInput" placeholder="New Name...">
573
+ <input type="hidden" id="renameId">
574
+ <div class="modal-btns">
575
+ <button class="modal-btn secondary" onclick="closeModals()">Cancel</button>
576
+ <button class="modal-btn primary" onclick="confirmRename()">RENAME</button>
577
+ </div>
578
+ </div>
579
+ </div>
580
+
581
+ <div class="modal-overlay" id="shareModal">
582
+ <div class="modal">
583
+ <h3>📤 Share Text</h3>
584
+ <div class="share-options">
585
+ <button class="share-btn" onclick="shareViaWhatsApp()">
586
+ <span style="font-size:20px;">📱</span> WhatsApp
587
+ </button>
588
+ <button class="share-btn" onclick="shareAsText()">
589
+ <span style="font-size:20px;">📝</span> Copy as Text
590
+ </button>
591
+ <button class="share-btn" onclick="shareAsFile()">
592
+ <span style="font-size:20px;">📄</span> Download as File
593
+ </button>
594
+ </div>
595
+ <div class="modal-btns" style="margin-top:15px;">
596
+ <button class="modal-btn secondary" onclick="closeModals()">Cancel</button>
597
+ </div>
598
+ </div>
599
+ </div>
600
+
601
+ <div class="fullscreen-controls">
602
+ <button class="action-btn" onclick="toggleMic()" id="fs-mic">🎙️</button>
603
+ <button class="action-btn" onclick="undoText()">↶ Undo</button>
604
+ <button class="action-btn" onclick="redoText()">↷ Redo</button>
605
+ <button class="action-btn" onclick="copyText()">📋 Copy</button>
606
+ <button class="action-btn" onclick="openSaveModal()">💾 Save</button>
607
+ <button class="action-btn" onclick="toggleFullscreen()">❌ Exit</button>
608
+ </div>
609
+
610
+ <script>
611
+ // --- VARIABLES ---
612
+ var savedHistory = [];
613
+ var trashBin = [];
614
+ var recognition = null;
615
+ var isRecording = false;
616
+ var currentLang = 'ur-PK';
617
+
618
+ // Undo/Redo stacks
619
+ var undoStack = [];
620
+ var redoStack = [];
621
+ var currentTextState = "";
622
+
623
+ // Cursor position
624
+ var cursorPosition = 0;
625
+
626
+ // 36 Years in milliseconds
627
+ var RETENTION_TIME = 1135296000000;
628
+
629
+ // Font size
630
+ var currentFontSize = 18;
631
+
632
+ // ═══════════════════════════════════════════════════════════════════════════════
633
+ // ڈرافٹ ٹیکسٹ پرزسٹنس سسٹم - ٹیکسٹ باکس
634
+ // DRAFT TEXT PERSISTENCE SYSTEM - TEXT BOX
635
+ // ═══════════════════════════════════════════════════════════════════════════════
636
+ var DRAFT_STORAGE_KEY = 'nzg73_speech_draft_v1';
637
+ var draftSaveTimer = null;
638
+ var DRAFT_SAVE_DELAY = 300;
639
+ // ═══════════════════════════════════════════════════════════════════════════════
640
+ // ختم ڈرافٹ ٹیکسٹ پرزسٹنس سسٹم - ٹیکسٹ باکس
641
+ // END DRAFT TEXT PERSISTENCE SYSTEM - TEXT BOX
642
+ // ═══════════════════════════════════════════════════════════════════════════════
643
+
644
+ // --- INIT ---
645
+ window.onload = function() {
646
+ loadData();
647
+ loadTheme();
648
+ var editor = document.getElementById('textEditor');
649
+ editor.addEventListener('input', updateCounts);
650
+ editor.addEventListener('input', scheduleDraftSave);
651
+ editor.addEventListener('click', saveCursorPosition);
652
+ editor.addEventListener('keyup', saveCursorPosition);
653
+ editor.addEventListener('keydown', saveCursorPosition);
654
+
655
+ // Initialize undo/redo
656
+ saveToHistoryStack();
657
+
658
+ // Default to Urdu
659
+ setLang('ur-PK');
660
+
661
+ // Restore saved draft only for this text box
662
+ restoreDraftText();
663
+
664
+ // Update UI
665
+ updateUndoRedoButtons();
666
+ };
667
+
668
+ // --- SPEECH ENGINE (IMPROVED) ---
669
+ function initSpeech() {
670
+ if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
671
+ showToast("⚠️ Browser not supported");
672
+ return null;
673
+ }
674
+
675
+ var Speech = window.SpeechRecognition || window.webkitSpeechRecognition;
676
+ var rec = new Speech();
677
+ rec.continuous = true;
678
+ rec.interimResults = true;
679
+ rec.lang = currentLang;
680
+
681
+ // Improved settings for better Urdu recognition
682
+ rec.maxAlternatives = 3;
683
+ rec.interimResults = true;
684
+
685
+ rec.onstart = function() {
686
+ isRecording = true;
687
+ updateMicUI(true);
688
+ showToast("🎤 Recording started...");
689
+ };
690
+
691
+ rec.onend = function() {
692
+ if (isRecording) {
693
+ // Auto-restart if not manually stopped
694
+ setTimeout(function() {
695
+ try { rec.start(); } catch(e) {}
696
+ }, 100);
697
+ } else {
698
+ updateMicUI(false);
699
+ }
700
+ };
701
+
702
+ rec.onresult = function(event) {
703
+ var final = "";
704
+ var interim = "";
705
+
706
+ for (var i = event.resultIndex; i < event.results.length; ++i) {
707
+ if (event.results[i].isFinal) {
708
+ final += event.results[i][0].transcript;
709
+
710
+ // For Pakistani English, adjust pronunciation
711
+ if (currentLang === 'en-PK') {
712
+ final = adjustPakistaniEnglish(final);
713
+ }
714
+ } else {
715
+ interim += event.results[i][0].transcript;
716
+ }
717
+ }
718
+
719
+ if (final) {
720
+ var editor = document.getElementById('textEditor');
721
+ var text = editor.value;
722
+
723
+ // Insert at cursor position
724
+ var beforeCursor = text.substring(0, cursorPosition);
725
+ var afterCursor = text.substring(cursorPosition);
726
+
727
+ // Add space before if needed
728
+ if (beforeCursor.length > 0 && !beforeCursor.endsWith(' ') && !beforeCursor.endsWith('\n')) {
729
+ final = ' ' + final;
730
+ }
731
+
732
+ // Add space after if needed
733
+ if (final.length > 0 && !final.endsWith(' ') && !final.endsWith('\n')) {
734
+ final = final + ' ';
735
+ }
736
+
737
+ editor.value = beforeCursor + final + afterCursor;
738
+
739
+ // Move cursor to after inserted text
740
+ cursorPosition = beforeCursor.length + final.length;
741
+ editor.selectionStart = cursorPosition;
742
+ editor.selectionEnd = cursorPosition;
743
+
744
+ updateCounts();
745
+ saveToHistoryStack();
746
+ scheduleDraftSave();
747
+
748
+ // Scroll to cursor position
749
+ if (editor.value.length > 0) {
750
+ editor.scrollTop = editor.scrollHeight * (cursorPosition / editor.value.length);
751
+ }
752
+ }
753
+ };
754
+
755
+ rec.onerror = function(event) {
756
+ console.error("Speech recognition error:", event.error);
757
+ if(event.error === 'not-allowed') {
758
+ showToast("⚠️ Please ALLOW Microphone access!");
759
+ isRecording = false;
760
+ updateMicUI(false);
761
+ } else if (event.error === 'no-speech') {
762
+ showToast("🎤 No speech detected. Try again.");
763
+ } else if (event.error === 'audio-capture') {
764
+ showToast("🎤 No microphone found. Check your microphone.");
765
+ }
766
+ };
767
+
768
+ return rec;
769
+ }
770
+
771
+ // Adjust text for Pakistani English pronunciation
772
+ function adjustPakistaniEnglish(text) {
773
+ var adjustments = {
774
+ // Common Pakistani pronunciations
775
+ 'hello': 'hello ji',
776
+ 'how are you': 'how are you ji',
777
+ 'thank you': 'thank you ji',
778
+ 'please': 'please ji',
779
+ 'sorry': 'sorry ji',
780
+ 'welcome': 'welcome ji'
781
+ };
782
+
783
+ var adjustedText = text.toLowerCase();
784
+ for (var word in adjustments) {
785
+ var regex = new RegExp('\\b' + word + '\\b', 'gi');
786
+ adjustedText = adjustedText.replace(regex, adjustments[word]);
787
+ }
788
+
789
+ return adjustedText;
790
+ }
791
+
792
+ function toggleMic() {
793
+ if (!recognition) {
794
+ recognition = initSpeech();
795
+ }
796
+
797
+ if (!recognition) return;
798
+
799
+ if (isRecording) {
800
+ isRecording = false;
801
+ try {
802
+ recognition.stop();
803
+ } catch(e) {}
804
+ updateMicUI(false);
805
+ showToast("⏹️ Recording stopped");
806
+ } else {
807
+ try {
808
+ recognition.start();
809
+ showToast("🎤 Recording... Speak now!");
810
+ } catch(e) {
811
+ console.error(e);
812
+ showToast("⚠️ Error starting microphone");
813
+ // Try re-initializing
814
+ recognition = initSpeech();
815
+ setTimeout(function() {
816
+ try { recognition.start(); } catch(e2) {}
817
+ }, 500);
818
+ }
819
+ }
820
+ }
821
+
822
+ function updateMicUI(on) {
823
+ var btn = document.getElementById('micBtn');
824
+ var status = document.getElementById('micStatus');
825
+ var fsBtn = document.getElementById('fs-mic');
826
+
827
+ if(on) {
828
+ btn.classList.add('recording');
829
+ status.textContent = "🔴 Recording... (Tap to Stop)";
830
+ status.style.color = "var(--danger)";
831
+ if(fsBtn) fsBtn.style.background = "var(--danger)";
832
+ btn.style.animation = "pulse 1s infinite, bounce 2s infinite";
833
+ } else {
834
+ btn.classList.remove('recording');
835
+ status.textContent = "Tap to Start";
836
+ status.style.color = "var(--text-secondary)";
837
+ if(fsBtn) fsBtn.style.background = "";
838
+ btn.style.animation = "bounce 2s infinite";
839
+ }
840
+ }
841
+
842
+ function setLang(lang) {
843
+ currentLang = lang;
844
+
845
+ // Update UI buttons
846
+ document.querySelectorAll('.lang-btn').forEach(b => b.classList.remove('active'));
847
+
848
+ if (lang === 'ur-PK') {
849
+ document.getElementById('btn-urdu').classList.add('active');
850
+ document.getElementById('textEditor').classList.add('urdu-mode');
851
+ document.getElementById('textEditor').placeholder = "یہاں بولیں یا لکھیں...";
852
+ showToast("🇵🇰 اردو زبان منتخب کی گئی ہے");
853
+ } else if (lang === 'en-US') {
854
+ document.getElementById('btn-english').classList.add('active');
855
+ document.getElementById('textEditor').classList.remove('urdu-mode');
856
+ document.getElementById('textEditor').placeholder = "Speak or type here...";
857
+ showToast("🇺🇸 English language selected");
858
+ } else if (lang === 'en-PK') {
859
+ document.getElementById('btn-pak-english').classList.add('active');
860
+ document.getElementById('textEditor').classList.remove('urdu-mode');
861
+ document.getElementById('textEditor').placeholder = "Speak or type here (Pakistani English)...";
862
+ showToast("🇵🇰 Pakistani English selected");
863
+ }
864
+
865
+ // Update speech recognition
866
+ if(recognition) {
867
+ recognition.lang = currentLang;
868
+ if(isRecording) {
869
+ // Restart with new language
870
+ recognition.stop();
871
+ setTimeout(function() {
872
+ try { recognition.start(); } catch(e) {}
873
+ }, 500);
874
+ }
875
+ }
876
+ }
877
+
878
+ // --- TEXT ZOOM ---
879
+ function textZoom(direction) {
880
+ var editor = document.getElementById('textEditor');
881
+
882
+ if (direction === 'in') {
883
+ currentFontSize += 2;
884
+ if (currentFontSize > 36) currentFontSize = 36;
885
+ } else {
886
+ currentFontSize -= 2;
887
+ if (currentFontSize < 12) currentFontSize = 12;
888
+ }
889
+
890
+ document.documentElement.style.setProperty('--font-size', currentFontSize + 'px');
891
+ editor.style.fontSize = currentFontSize + 'px';
892
+
893
+ showToast("Font size: " + currentFontSize + "px");
894
+ }
895
+
896
+ // ═══════════════════════════════════════════════════════════════════════════════
897
+ // ڈرافٹ ٹیکسٹ باکس لاجک - جاوا اسکرپٹ
898
+ // DRAFT TEXT BOX LOGIC - JAVASCRIPT
899
+ // ═══════════════════════════════════════════════════════════════════════════════
900
+ function getDraftPayload() {
901
+ try {
902
+ var raw = localStorage.getItem(DRAFT_STORAGE_KEY);
903
+ return raw ? JSON.parse(raw) : null;
904
+ } catch (error) {
905
+ console.error('Draft payload read error:', error);
906
+ return null;
907
+ }
908
+ }
909
+
910
+ function scheduleDraftSave() {
911
+ if (draftSaveTimer) {
912
+ clearTimeout(draftSaveTimer);
913
+ }
914
+
915
+ draftSaveTimer = setTimeout(function() {
916
+ persistDraftText();
917
+ }, DRAFT_SAVE_DELAY);
918
+ }
919
+
920
+ function persistDraftText() {
921
+ try {
922
+ var editor = document.getElementById('textEditor');
923
+ if (!editor) return;
924
+
925
+ var payload = {
926
+ text: editor.value || '',
927
+ lang: currentLang,
928
+ savedAt: Date.now()
929
+ };
930
+
931
+ localStorage.setItem(DRAFT_STORAGE_KEY, JSON.stringify(payload));
932
+ } catch (error) {
933
+ console.error('Draft save error:', error);
934
+ }
935
+ }
936
+
937
+ function restoreDraftText() {
938
+ try {
939
+ var editor = document.getElementById('textEditor');
940
+ var payload = getDraftPayload();
941
+ if (!editor || !payload || typeof payload.text !== 'string') return;
942
+
943
+ editor.value = payload.text;
944
+ currentTextState = payload.text;
945
+ cursorPosition = payload.text.length;
946
+ editor.selectionStart = cursorPosition;
947
+ editor.selectionEnd = cursorPosition;
948
+
949
+ if (payload.lang === 'ur-PK' || payload.lang === 'en-US' || payload.lang === 'en-PK') {
950
+ setLang(payload.lang);
951
+ }
952
+
953
+ updateCounts();
954
+ updateUndoRedoButtons();
955
+ } catch (error) {
956
+ console.error('Draft restore error:', error);
957
+ }
958
+ }
959
+
960
+ function clearDraftText() {
961
+ try {
962
+ if (draftSaveTimer) {
963
+ clearTimeout(draftSaveTimer);
964
+ draftSaveTimer = null;
965
+ }
966
+ localStorage.removeItem(DRAFT_STORAGE_KEY);
967
+ } catch (error) {
968
+ console.error('Draft clear error:', error);
969
+ }
970
+ }
971
+ // ═══════════════════════════════════════════════════════════════════════════════
972
+ // ختم ڈرافٹ ٹیکسٹ باکس لاجک - جاوا اسکرپٹ
973
+ // END DRAFT TEXT BOX LOGIC - JAVASCRIPT
974
+ // ═══════════════════════════════════════════════════════════════════════════════
975
+
976
+
977
+ // 👇 یہ فنکشن یہاں ایڈ کریں (Speak Logic Start/Stop) 👇
978
+ function toggleSpeak() {
979
+ var btn = document.getElementById('speakBtn');
980
+ var text = document.getElementById('textEditor').value;
981
+
982
+ // اگر پہلے سے بول رہا ہے تو روک دو (Stop Logic)
983
+ if (window.speechSynthesis.speaking) {
984
+ window.speechSynthesis.cancel();
985
+ btn.innerHTML = "🔊 Speak";
986
+ btn.style.background = "";
987
+ return;
988
+ }
989
+
990
+ if (!text.trim()) { showToast("❌ No text to speak!"); return; }
991
+
992
+ // بولنے کا نیا حکم (Start Logic)
993
+ var msg = new SpeechSynthesisUtterance(text);
994
+
995
+ // زبان کی چیکنگ (اردو ہے یا انگلش)
996
+ if (currentLang === 'ur-PK' || document.getElementById('textEditor').classList.contains('urdu-mode')) {
997
+ msg.lang = 'ur-PK';
998
+ } else {
999
+ msg.lang = 'en-US';
1000
+ }
1001
+
1002
+ // جب بولنا ختم ہو جائے تو بٹن واپس نارمل ہو جائے
1003
+ msg.onend = function() {
1004
+ btn.innerHTML = "🔊 Speak";
1005
+ btn.style.background = "";
1006
+ };
1007
+
1008
+ window.speechSynthesis.speak(msg);
1009
+ btn.innerHTML = "⏹️ Stop"; // بٹن کا نام تبدیل کر کے Stop کر دو
1010
+ btn.style.background = "var(--danger)"; // بٹن کا رنگ لال کر دو
1011
+ }
1012
+ // 👆 یہاں تک 👆
1013
+
1014
+
1015
+ // --- UNDO/REDO SYSTEM ---
1016
+ function saveToHistoryStack() {
1017
+ var editor = document.getElementById('textEditor');
1018
+ var currentText = editor.value;
1019
+
1020
+ if (currentText !== currentTextState) {
1021
+ undoStack.push(currentTextState);
1022
+ currentTextState = currentText;
1023
+ redoStack = []; // Clear redo stack when new change is made
1024
+ updateUndoRedoButtons();
1025
+ }
1026
+ }
1027
+
1028
+ function undoText() {
1029
+ if (undoStack.length > 0) {
1030
+ var editor = document.getElementById('textEditor');
1031
+ redoStack.push(currentTextState);
1032
+ currentTextState = undoStack.pop();
1033
+ editor.value = currentTextState;
1034
+
1035
+ updateCounts();
1036
+ updateUndoRedoButtons();
1037
+ scheduleDraftSave();
1038
+ showToast("↶ Undo performed");
1039
+ }
1040
+ }
1041
+
1042
+ function redoText() {
1043
+ if (redoStack.length > 0) {
1044
+ var editor = document.getElementById('textEditor');
1045
+ undoStack.push(currentTextState);
1046
+ currentTextState = redoStack.pop();
1047
+ editor.value = currentTextState;
1048
+
1049
+ updateCounts();
1050
+ updateUndoRedoButtons();
1051
+ scheduleDraftSave();
1052
+ showToast("↷ Redo performed");
1053
+ }
1054
+ }
1055
+
1056
+ function updateUndoRedoButtons() {
1057
+ document.getElementById('undoBtn').disabled = undoStack.length === 0;
1058
+ document.getElementById('redoBtn').disabled = redoStack.length === 0;
1059
+ }
1060
+
1061
+ // --- CURSOR POSITION TRACKING ---
1062
+ function saveCursorPosition() {
1063
+ var editor = document.getElementById('textEditor');
1064
+ cursorPosition = editor.selectionStart;
1065
+ document.getElementById('cursorPos').textContent = cursorPosition;
1066
+ }
1067
+
1068
+ function insertAtCursor(text) {
1069
+ var editor = document.getElementById('textEditor');
1070
+ var beforeCursor = editor.value.substring(0, cursorPosition);
1071
+ var afterCursor = editor.value.substring(cursorPosition);
1072
+
1073
+ editor.value = beforeCursor + text + afterCursor;
1074
+ cursorPosition = beforeCursor.length + text.length;
1075
+ editor.selectionStart = cursorPosition;
1076
+ editor.selectionEnd = cursorPosition;
1077
+
1078
+ updateCounts();
1079
+ saveToHistoryStack();
1080
+ scheduleDraftSave();
1081
+ }
1082
+
1083
+ // --- SHARE FUNCTIONALITY ---
1084
+ function shareText() {
1085
+ document.getElementById('shareModal').classList.add('active');
1086
+ }
1087
+
1088
+ function shareViaWhatsApp() {
1089
+ var text = document.getElementById('textEditor').value;
1090
+ if (!text.trim()) {
1091
+ showToast("❌ No text to share!");
1092
+ return;
1093
+ }
1094
+
1095
+ var whatsappUrl = "https://wa.me/?text=" + encodeURIComponent(text);
1096
+ window.open(whatsappUrl, '_blank');
1097
+ closeModals();
1098
+ showToast("📱 Opening WhatsApp...");
1099
+ }
1100
+
1101
+ function shareAsText() {
1102
+ var text = document.getElementById('textEditor').value;
1103
+ if (!text.trim()) {
1104
+ showToast("❌ No text to share!");
1105
+ return;
1106
+ }
1107
+
1108
+ navigator.clipboard.writeText(text).then(function() {
1109
+ showToast("📋 Text copied to clipboard!");
1110
+ closeModals();
1111
+ }).catch(function() {
1112
+ showToast("❌ Failed to copy text");
1113
+ });
1114
+ }
1115
+
1116
+ function shareAsFile() {
1117
+ var text = document.getElementById('textEditor').value;
1118
+ if (!text.trim()) {
1119
+ showToast("❌ No text to share!");
1120
+ return;
1121
+ }
1122
+
1123
+ var blob = new Blob([text], {type: 'text/plain'});
1124
+ var url = URL.createObjectURL(blob);
1125
+ var a = document.createElement('a');
1126
+ a.href = url;
1127
+ a.download = 'NZG73_Text_' + new Date().getTime() + '.txt';
1128
+ document.body.appendChild(a);
1129
+ a.click();
1130
+ document.body.removeChild(a);
1131
+ URL.revokeObjectURL(url);
1132
+
1133
+ closeModals();
1134
+ showToast("📄 File downloaded!");
1135
+ }
1136
+
1137
+ // --- DATA MANAGEMENT ---
1138
+ function saveToHistory() {
1139
+ var nameInput = document.getElementById('saveFileName');
1140
+ var name = nameInput.value.trim();
1141
+ var text = document.getElementById('textEditor').value;
1142
+
1143
+ if (!text.trim()) {
1144
+ showToast("❌ Text khali hai!");
1145
+ closeModals();
1146
+ return;
1147
+ }
1148
+ if (!name) name = "Untitled " + new Date().toLocaleTimeString();
1149
+
1150
+ var newItem = {
1151
+ id: Date.now(),
1152
+ name: name,
1153
+ text: text,
1154
+ date: new Date().toLocaleString(),
1155
+ isUrdu: currentLang === 'ur-PK'
1156
+ };
1157
+
1158
+ savedHistory.unshift(newItem);
1159
+ saveToLocal();
1160
+ renderHistory();
1161
+ closeModals();
1162
+ showToast("✅ Saved Successfully!");
1163
+ nameInput.value = "";
1164
+ }
1165
+
1166
+ function confirmRename() {
1167
+ var id = parseInt(document.getElementById('renameId').value);
1168
+ var newName = document.getElementById('renameInput').value.trim();
1169
+
1170
+ if(!newName) { showToast("❌ Name likhein!"); return; }
1171
+
1172
+ var item = savedHistory.find(i => i.id === id);
1173
+ if(item) {
1174
+ item.name = newName;
1175
+ saveToLocal();
1176
+ renderHistory();
1177
+ closeModals();
1178
+ showToast("✅ Renamed!");
1179
+ }
1180
+ }
1181
+
1182
+ function deleteItem(id, permanent) {
1183
+ if(permanent) {
1184
+ if(!confirm("Delete forever?")) return;
1185
+ trashBin = trashBin.filter(i => i.id !== id);
1186
+ showToast("🗑️ Deleted Forever");
1187
+ } else {
1188
+ var item = savedHistory.find(i => i.id === id);
1189
+ if(item) {
1190
+ savedHistory = savedHistory.filter(i => i.id !== id);
1191
+ item.deletedAt = Date.now();
1192
+ trashBin.unshift(item);
1193
+ showToast("🗑️ Moved to Trash");
1194
+ }
1195
+ }
1196
+ saveToLocal();
1197
+ renderHistory();
1198
+ renderTrash();
1199
+ }
1200
+
1201
+ function restoreItem(id) {
1202
+ var item = trashBin.find(i => i.id === id);
1203
+ if(item) {
1204
+ trashBin = trashBin.filter(i => i.id !== id);
1205
+ delete item.deletedAt;
1206
+ savedHistory.unshift(item);
1207
+ saveToLocal();
1208
+ renderHistory();
1209
+ renderTrash();
1210
+ showToast("♻️ Restored!");
1211
+ }
1212
+ }
1213
+
1214
+ // --- STORAGE & RETENTION ---
1215
+ function saveToLocal() {
1216
+ localStorage.setItem('nzg73_data', JSON.stringify(savedHistory));
1217
+ localStorage.setItem('nzg73_trash', JSON.stringify(trashBin));
1218
+ localStorage.setItem('nzg73_fontsize', currentFontSize);
1219
+ }
1220
+
1221
+ function loadData() {
1222
+ var d = localStorage.getItem('nzg73_data');
1223
+ var t = localStorage.getItem('nzg73_trash');
1224
+ var fs = localStorage.getItem('nzg73_fontsize');
1225
+
1226
+ if(d) savedHistory = JSON.parse(d);
1227
+ if(t) trashBin = JSON.parse(t);
1228
+ if(fs) {
1229
+ currentFontSize = parseInt(fs);
1230
+ document.documentElement.style.setProperty('--font-size', currentFontSize + 'px');
1231
+ document.getElementById('textEditor').style.fontSize = currentFontSize + 'px';
1232
+ }
1233
+
1234
+ // Cleanup old data
1235
+ var now = Date.now();
1236
+ savedHistory = savedHistory.filter(i => (now - i.id) < RETENTION_TIME);
1237
+ trashBin = trashBin.filter(i => (now - (i.deletedAt || 0)) < RETENTION_TIME);
1238
+
1239
+ saveToLocal();
1240
+ renderHistory();
1241
+ renderTrash();
1242
+ }
1243
+
1244
+ // --- RENDERING ---
1245
+ function renderHistory() {
1246
+ var html = '';
1247
+ if(savedHistory.length === 0) html = '<div style="padding:20px; text-align:center">No Saved Files</div>';
1248
+
1249
+ savedHistory.forEach(item => {
1250
+ html += `
1251
+ <div class="history-item">
1252
+ <div class="history-item-header">
1253
+ <span class="history-title">${escapeHtml(item.name)}</span>
1254
+ <span style="font-size:10px">${item.date}</span>
1255
+ </div>
1256
+ <div class="history-text ${item.isUrdu ? 'urdu-mode' : ''}">${escapeHtml(item.text.substring(0,100))}...</div>
1257
+ <div class="history-actions">
1258
+ <button class="action-btn" onclick="loadItem(${item.id})">📂 Load</button>
1259
+ <button class="action-btn" onclick="openRename(${item.id})">✏️ Rename</button>
1260
+ <button class="action-btn delete-btn" onclick="deleteItem(${item.id}, false)">🗑️ Del</button>
1261
+ </div>
1262
+ </div>`;
1263
+ });
1264
+ document.getElementById('historyList').innerHTML = html;
1265
+ }
1266
+
1267
+ function renderTrash() {
1268
+ var html = '';
1269
+ if(trashBin.length === 0) html = '<div style="padding:20px; text-align:center">Trash Empty</div>';
1270
+
1271
+ trashBin.forEach(item => {
1272
+ html += `
1273
+ <div class="history-item" style="opacity:0.7">
1274
+ <div class="history-item-header">
1275
+ <span class="history-title">${escapeHtml(item.name)}</span>
1276
+ </div>
1277
+ <div class="history-actions">
1278
+ <button class="action-btn" onclick="restoreItem(${item.id})">♻️ Restore</button>
1279
+ <button class="action-btn delete-btn" onclick="deleteItem(${item.id}, true)">🔥 Delete Forever</button>
1280
+ </div>
1281
+ </div>`;
1282
+ });
1283
+ document.getElementById('trashList').innerHTML = html;
1284
+ }
1285
+
1286
+ // --- UTILS ---
1287
+ function loadItem(id) {
1288
+ var item = savedHistory.find(i => i.id === id);
1289
+ if(item) {
1290
+ document.getElementById('textEditor').value = item.text;
1291
+ if(item.isUrdu) {
1292
+ setLang('ur-PK');
1293
+ } else {
1294
+ setLang('en-US');
1295
+ }
1296
+ showTab('speech');
1297
+ updateCounts();
1298
+ saveToHistoryStack();
1299
+ scheduleDraftSave();
1300
+ cursorPosition = item.text.length;
1301
+ }
1302
+ }
1303
+
1304
+ function openRename(id) {
1305
+ var item = savedHistory.find(i => i.id === id);
1306
+ if(item) {
1307
+ document.getElementById('renameInput').value = item.name;
1308
+ document.getElementById('renameId').value = id;
1309
+ document.getElementById('renameModal').classList.add('active');
1310
+ }
1311
+ }
1312
+
1313
+ function closeModals() {
1314
+ document.querySelectorAll('.modal-overlay').forEach(el => el.classList.remove('active'));
1315
+ }
1316
+
1317
+ function clearAllHistory() {
1318
+ if(confirm("Move ALL to Trash?")) {
1319
+ savedHistory.forEach(i => { i.deletedAt = Date.now(); trashBin.unshift(i); });
1320
+ savedHistory = [];
1321
+ saveToLocal();
1322
+ renderHistory();
1323
+ renderTrash();
1324
+ showToast("🗑️ All moved to trash");
1325
+ }
1326
+ }
1327
+
1328
+ function emptyTrash() {
1329
+ if(confirm("Permanently delete everything in Trash?")) {
1330
+ trashBin = [];
1331
+ saveToLocal();
1332
+ renderTrash();
1333
+ showToast("🔥 Trash Emptied");
1334
+ }
1335
+ }
1336
+
1337
+ // UI Helpers
1338
+ function showTab(tab) {
1339
+ document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active'));
1340
+ document.querySelectorAll('.tab-btn').forEach(el => el.classList.remove('active'));
1341
+ document.getElementById('tab-'+tab).classList.add('active');
1342
+
1343
+ var btns = document.getElementsByClassName('tab-btn');
1344
+ if(tab=='speech') btns[0].classList.add('active');
1345
+ if(tab=='history') btns[1].classList.add('active');
1346
+ if(tab=='trash') btns[2].classList.add('active');
1347
+ }
1348
+
1349
+ function toggleTheme() {
1350
+ document.body.classList.toggle('light-mode');
1351
+ localStorage.setItem('nzg73_theme', document.body.classList.contains('light-mode') ? 'light' : 'dark');
1352
+ showToast("Theme changed");
1353
+ }
1354
+
1355
+ function loadTheme() {
1356
+ if(localStorage.getItem('nzg73_theme') === 'light') document.body.classList.add('light-mode');
1357
+ }
1358
+
1359
+ function toggleFullscreen() {
1360
+ document.body.classList.toggle('fullscreen-mode');
1361
+ if(document.body.classList.contains('fullscreen-mode')) {
1362
+ document.documentElement.requestFullscreen().catch(e=>{});
1363
+ showToast("⛶ Fullscreen mode");
1364
+ } else {
1365
+ document.exitFullscreen().catch(e=>{});
1366
+ showToast("Normal mode");
1367
+ }
1368
+ }
1369
+
1370
+ function showToast(msg) {
1371
+ var t = document.createElement('div');
1372
+ t.className = 'toast';
1373
+ t.textContent = msg;
1374
+ document.body.appendChild(t);
1375
+ setTimeout(() => t.remove(), 2500);
1376
+ }
1377
+
1378
+ function copyText() {
1379
+ var txt = document.getElementById('textEditor').value;
1380
+ navigator.clipboard.writeText(txt).then(() => showToast("📋 Copied!"));
1381
+ }
1382
+
1383
+ async function pasteText() {
1384
+ try {
1385
+ const text = await navigator.clipboard.readText();
1386
+ insertAtCursor(text);
1387
+ showToast("📥 Pasted!");
1388
+ } catch(e) {
1389
+ showToast("❌ Use Ctrl+V to paste");
1390
+ }
1391
+ }
1392
+
1393
+ function clearText() {
1394
+ document.getElementById('textEditor').value = "";
1395
+ updateCounts();
1396
+ saveToHistoryStack();
1397
+ clearDraftText();
1398
+ cursorPosition = 0;
1399
+ showToast("🗑️ Text cleared");
1400
+ }
1401
+
1402
+ function updateCounts() {
1403
+ var t = document.getElementById('textEditor').value;
1404
+ document.getElementById('wordCount').innerText = t.trim() === '' ? 0 : t.trim().split(/\s+/).length;
1405
+ document.getElementById('charCount').innerText = t.length;
1406
+ }
1407
+
1408
+ function escapeHtml(text) {
1409
+ var map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' };
1410
+ return text.replace(/[&<>"']/g, function(m) { return map[m]; });
1411
+ }
1412
+
1413
+
1414
+ // ═══════════════════════════════════════════════════════════════════════════════
1415
+ // صفحہ بند ہونے سے پہلے ڈرافٹ محفوظ کرنا - جاوا اسکرپٹ
1416
+ // SAVE DRAFT BEFORE PAGE CLOSE - JAVASCRIPT
1417
+ // ═══════════════════════════════════════════════════════════════════════════════
1418
+ window.addEventListener('beforeunload', function() {
1419
+ persistDraftText();
1420
+ });
1421
+ // ═══════════════════════════════════════════════════════════════════════════════
1422
+ // ختم صفحہ بند ہونے سے پہلے ڈرافٹ محفوظ کرنا - جاوا اسکرپٹ
1423
+ // END SAVE DRAFT BEFORE PAGE CLOSE - JAVASCRIPT
1424
+ // ═══════════════════════════════════════════════════════════════════════════════
1425
+
1426
+ function openSaveModal() {
1427
+ document.getElementById('saveFileName').value = "";
1428
+ document.getElementById('saveModal').classList.add('active');
1429
+ }
1430
+
1431
+ </script>
1432
+ </body>
1433
+ </html>