insikt.js 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/insikt.es.js CHANGED
@@ -1,81 +1,1650 @@
1
- const VERSION = "1.0.0";
2
- const state = {
3
- initialized: false,
4
- panelVisible: false,
5
- logs: [],
6
- requests: [],
7
- errors: [],
8
- ui: {
9
- root: null
10
- }
11
- };
12
- function initInsikt(options = {}) {
13
- if (state.initialized) return;
14
- state.initialized = true;
15
- createUI();
16
- attachConsoleProxy();
17
- attachGlobalErrorHandler();
18
- console.log(`[INSIKT v${VERSION}] initialized`);
19
- }
20
- function destroyInsikt() {
21
- removeUI();
22
- state.initialized = false;
23
- console.log("[INSIKT] destroyed");
24
- }
25
- function toggleInsikt() {
26
- state.panelVisible = !state.panelVisible;
27
- }
28
- function clearLogs() {
29
- state.logs = [];
30
- state.requests = [];
31
- state.errors = [];
32
- }
33
- function createUI() {
34
- state.ui.root = document.createElement("div");
35
- state.ui.root.id = "insikt-root";
36
- document.body.appendChild(state.ui.root);
37
- }
38
- function removeUI() {
39
- if (state.ui.root) {
40
- state.ui.root.remove();
41
- state.ui.root = null;
42
- }
43
- }
44
- function attachConsoleProxy() {
45
- const originalLog = console.log;
46
- console.log = (...args) => {
47
- state.logs.push({ type: "log", args, timestamp: Date.now() });
48
- originalLog.apply(console, args);
1
+ (function() {
2
+ const css = `
3
+ @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Syne:wght@400;600;700;800&display=swap');
4
+
5
+ :root {
6
+ --dc-bg0: #0d0d0f;
7
+ --dc-bg1: #141418;
8
+ --dc-bg2: #1c1c22;
9
+ --dc-bg3: #242430;
10
+ --dc-border: #2a2a38;
11
+ --dc-accent: #7c6af7;
12
+ --dc-accent2: #f768a4;
13
+ --dc-green: #3dffa0;
14
+ --dc-orange: #ffb347;
15
+ --dc-red: #ff5c6e;
16
+ --dc-blue: #5bcefa;
17
+ --dc-text0: #f0f0f8;
18
+ --dc-text1: #a8a8c0;
19
+ --dc-text2: #606078;
20
+ --dc-mono: 'JetBrains Mono', monospace;
21
+ --dc-sans: 'Syne', sans-serif;
22
+ }
23
+
24
+ /* Scope resets strictly to our elements */
25
+ #dc-panel, #dc-fab { box-sizing: border-box; }
26
+ #dc-panel *, #dc-fab * { box-sizing: inherit; }
27
+
28
+ /* ── FAB ────────────────────────────── */
29
+ #dc-fab {
30
+ position: fixed;
31
+ bottom: 20px;
32
+ right: 20px;
33
+ width: 44px;
34
+ height: 44px;
35
+ border-radius: 12px;
36
+ background: var(--dc-accent);
37
+ color: #fff;
38
+ border: none;
39
+ font-size: 18px;
40
+ cursor: pointer;
41
+ z-index: 99999;
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ box-shadow: 0 4px 24px rgba(124,106,247,0.5);
46
+ transition: all 0.2s ease;
47
+ font-family: var(--dc-mono);
48
+ padding: 0;
49
+ margin: 0;
50
+ }
51
+
52
+ #dc-fab:hover { transform: scale(1.05); box-shadow: 0 6px 30px rgba(124,106,247,0.7); }
53
+ #dc-fab:active { transform: scale(0.95); }
54
+
55
+ .dc-fab-badge {
56
+ position: absolute;
57
+ top: -5px;
58
+ right: -5px;
59
+ min-width: 18px;
60
+ height: 18px;
61
+ background: var(--dc-red);
62
+ color: #fff;
63
+ font-size: 10px;
64
+ font-weight: 700;
65
+ border-radius: 9px;
66
+ display: none;
67
+ align-items: center;
68
+ justify-content: center;
69
+ padding: 0 4px;
70
+ font-family: var(--dc-mono);
71
+ }
72
+
73
+ /* ── CONSOLE PANEL ───────────────────── */
74
+ #dc-panel {
75
+ position: fixed;
76
+ bottom: 0;
77
+ left: 0;
78
+ right: 0;
79
+ height: 320px;
80
+ min-height: 120px;
81
+ max-height: 85vh;
82
+ background: var(--dc-bg1);
83
+ border-top: 1px solid var(--dc-border);
84
+ border-radius: 14px 14px 0 0;
85
+ box-shadow: 0 -12px 50px rgba(0,0,0,0.6);
86
+ display: none;
87
+ flex-direction: column;
88
+ z-index: 99998;
89
+ overflow: hidden;
90
+ font-family: var(--dc-mono);
91
+ color: var(--dc-text0);
92
+ }
93
+
94
+ #dc-panel.visible {
95
+ display: flex;
96
+ animation: dcSlideUp 0.25s cubic-bezier(0.4, 0, 0.2, 1);
97
+ }
98
+
99
+ @keyframes dcSlideUp {
100
+ from { transform: translateY(100%); opacity: 0; }
101
+ to { transform: translateY(0); opacity: 1; }
102
+ }
103
+
104
+ /* Drag handle */
105
+ #dc-drag {
106
+ width: 100%;
107
+ height: 22px;
108
+ background: var(--dc-bg2);
109
+ display: flex;
110
+ align-items: center;
111
+ justify-content: center;
112
+ cursor: ns-resize;
113
+ border-radius: 14px 14px 0 0;
114
+ flex-shrink: 0;
115
+ touch-action: none;
116
+ user-select: none;
117
+ }
118
+
119
+ #dc-drag::before {
120
+ content: '';
121
+ width: 36px;
122
+ height: 4px;
123
+ background: var(--dc-border);
124
+ border-radius: 2px;
125
+ transition: background 0.2s;
126
+ }
127
+
128
+ #dc-drag:hover::before { background: var(--dc-accent); }
129
+
130
+ /* Header bar */
131
+ #dc-header {
132
+ display: flex;
133
+ align-items: center;
134
+ gap: 8px;
135
+ padding: 8px 12px;
136
+ background: var(--dc-bg2);
137
+ border-bottom: 1px solid var(--dc-border);
138
+ flex-shrink: 0;
139
+ }
140
+
141
+ #dc-title {
142
+ font-size: 11px;
143
+ font-weight: 700;
144
+ color: var(--dc-accent);
145
+ letter-spacing: 0.1em;
146
+ text-transform: uppercase;
147
+ flex: 1;
148
+ }
149
+
150
+ .dc-pulse {
151
+ width: 8px;
152
+ height: 8px;
153
+ border-radius: 50%;
154
+ background: var(--dc-green);
155
+ animation: dcPulse 2s infinite;
156
+ flex-shrink: 0;
157
+ }
158
+
159
+ @keyframes dcPulse {
160
+ 0%,100% { opacity: 1; box-shadow: 0 0 0 0 rgba(61,255,160,0.4); }
161
+ 50% { opacity: 0.6; box-shadow: 0 0 0 5px rgba(61,255,160,0); }
162
+ }
163
+
164
+ .dc-hbtn {
165
+ width: 28px;
166
+ height: 28px;
167
+ border: none;
168
+ border-radius: 7px;
169
+ background: var(--dc-bg3);
170
+ color: var(--dc-text1);
171
+ font-size: 13px;
172
+ cursor: pointer;
173
+ display: flex;
174
+ align-items: center;
175
+ justify-content: center;
176
+ transition: all 0.15s;
177
+ padding: 0;
178
+ }
179
+
180
+ .dc-hbtn:hover { background: var(--dc-border); color: var(--dc-text0); }
181
+
182
+ /* Tabs */
183
+ #dc-tabs {
184
+ display: flex;
185
+ background: var(--dc-bg0);
186
+ border-bottom: 1px solid var(--dc-border);
187
+ overflow-x: auto;
188
+ scrollbar-width: none;
189
+ flex-shrink: 0;
190
+ }
191
+
192
+ #dc-tabs::-webkit-scrollbar { display: none; }
193
+
194
+ .dc-tab {
195
+ padding: 10px 14px;
196
+ background: none;
197
+ border: none;
198
+ color: var(--dc-text2);
199
+ font-family: var(--dc-mono);
200
+ font-size: 11px;
201
+ font-weight: 600;
202
+ letter-spacing: 0.05em;
203
+ cursor: pointer;
204
+ white-space: nowrap;
205
+ border-bottom: 2px solid transparent;
206
+ transition: all 0.15s;
207
+ position: relative;
208
+ }
209
+
210
+ .dc-tab:hover { color: var(--dc-text1); }
211
+
212
+ .dc-tab.active {
213
+ color: var(--dc-accent);
214
+ border-bottom-color: var(--dc-accent);
215
+ }
216
+
217
+ .dc-tab-count {
218
+ display: inline-flex;
219
+ align-items: center;
220
+ justify-content: center;
221
+ min-width: 16px;
222
+ height: 16px;
223
+ background: var(--dc-accent);
224
+ color: #fff;
225
+ font-size: 9px;
226
+ font-weight: 700;
227
+ border-radius: 8px;
228
+ padding: 0 4px;
229
+ margin-left: 5px;
230
+ }
231
+
232
+ /* Tab panels */
233
+ .dc-panel-content {
234
+ display: none;
235
+ flex-direction: column;
236
+ flex: 1;
237
+ overflow: hidden;
238
+ }
239
+
240
+ .dc-panel-content.active { display: flex; }
241
+
242
+ .dc-scroll {
243
+ flex: 1;
244
+ overflow-y: auto;
245
+ padding: 10px 12px;
246
+ scrollbar-width: thin;
247
+ scrollbar-color: var(--dc-border) transparent;
248
+ }
249
+
250
+ .dc-scroll::-webkit-scrollbar { width: 4px; }
251
+ .dc-scroll::-webkit-scrollbar-thumb { background: var(--dc-border); border-radius: 2px; }
252
+
253
+ /* ── LOG ENTRIES ──────────────────────── */
254
+ .dc-entry {
255
+ display: flex;
256
+ align-items: baseline;
257
+ gap: 8px;
258
+ padding: 5px 8px;
259
+ border-radius: 5px;
260
+ margin-bottom: 3px;
261
+ font-size: 12px;
262
+ line-height: 1.5;
263
+ word-break: break-word;
264
+ animation: dcFadeIn 0.1s ease;
265
+ }
266
+
267
+ @keyframes dcFadeIn { from { opacity: 0; transform: translateY(2px); } to { opacity: 1; transform: none; } }
268
+
269
+ .dc-entry-log { color: var(--dc-text0); }
270
+ .dc-entry-warn { color: var(--dc-orange); background: rgba(255,179,71,0.07); border-left: 2px solid var(--dc-orange); }
271
+ .dc-entry-error { color: var(--dc-red); background: rgba(255,92,110,0.07); border-left: 2px solid var(--dc-red); }
272
+ .dc-entry-info { color: var(--dc-blue); background: rgba(91,206,250,0.06); border-left: 2px solid var(--dc-blue); }
273
+ .dc-entry-cmd { color: var(--dc-accent); background: rgba(124,106,247,0.06); }
274
+
275
+ .dc-ts {
276
+ color: var(--dc-text2);
277
+ font-size: 10px;
278
+ font-weight: 400;
279
+ flex-shrink: 0;
280
+ letter-spacing: 0;
281
+ }
282
+
283
+ .dc-entry pre {
284
+ white-space: pre-wrap;
285
+ word-break: break-all;
286
+ background: var(--dc-bg0);
287
+ padding: 6px 8px;
288
+ border-radius: 5px;
289
+ margin-top: 4px;
290
+ font-size: 11px;
291
+ color: var(--dc-green);
292
+ width: 100%;
293
+ }
294
+
295
+ /* ── REPL INPUT ───────────────────────── */
296
+ .dc-repl {
297
+ display: flex;
298
+ gap: 8px;
299
+ padding: 8px 12px;
300
+ background: var(--dc-bg2);
301
+ border-top: 1px solid var(--dc-border);
302
+ flex-shrink: 0;
303
+ }
304
+
305
+ .dc-input {
306
+ flex: 1;
307
+ padding: 8px 12px;
308
+ background: var(--dc-bg0);
309
+ border: 1px solid var(--dc-border);
310
+ border-radius: 8px;
311
+ color: var(--dc-text0);
312
+ font-family: var(--dc-mono);
313
+ font-size: 13px;
314
+ outline: none;
315
+ transition: border-color 0.15s;
316
+ }
317
+
318
+ .dc-input:focus { border-color: var(--dc-accent); box-shadow: 0 0 0 2px rgba(124,106,247,0.15); }
319
+
320
+ .dc-run-btn {
321
+ padding: 8px 14px;
322
+ background: var(--dc-accent);
323
+ border: none;
324
+ border-radius: 8px;
325
+ color: #fff;
326
+ font-family: var(--dc-mono);
327
+ font-size: 12px;
328
+ font-weight: 700;
329
+ cursor: pointer;
330
+ transition: all 0.15s;
331
+ letter-spacing: 0.05em;
332
+ }
333
+
334
+ .dc-run-btn:hover { background: #8f7ffb; }
335
+ .dc-run-btn:active { transform: scale(0.96); }
336
+
337
+ /* ── NETWORK TAB ──────────────────────── */
338
+ .dc-net-filter {
339
+ display: flex;
340
+ gap: 8px;
341
+ padding: 8px 12px;
342
+ background: var(--dc-bg2);
343
+ border-bottom: 1px solid var(--dc-border);
344
+ flex-shrink: 0;
345
+ }
346
+
347
+ .dc-filter-input {
348
+ flex: 1;
349
+ padding: 7px 10px;
350
+ background: var(--dc-bg0);
351
+ border: 1px solid var(--dc-border);
352
+ border-radius: 8px;
353
+ color: var(--dc-text0);
354
+ font-family: var(--dc-mono);
355
+ font-size: 12px;
356
+ outline: none;
357
+ }
358
+
359
+ .dc-filter-input:focus { border-color: var(--dc-accent); }
360
+
361
+ .dc-clear-btn {
362
+ padding: 7px 12px;
363
+ background: var(--dc-bg3);
364
+ border: 1px solid var(--dc-border);
365
+ border-radius: 8px;
366
+ color: var(--dc-text1);
367
+ font-family: var(--dc-mono);
368
+ font-size: 11px;
369
+ cursor: pointer;
370
+ }
371
+
372
+ .dc-clear-btn:hover { border-color: var(--dc-red); color: var(--dc-red); }
373
+
374
+ .dc-req {
375
+ padding: 9px 10px;
376
+ border-radius: 6px;
377
+ margin-bottom: 4px;
378
+ background: var(--dc-bg2);
379
+ cursor: pointer;
380
+ border: 1px solid transparent;
381
+ transition: border-color 0.15s;
382
+ }
383
+
384
+ .dc-req:hover { border-color: var(--dc-border); }
385
+ .dc-req.expanded { border-color: var(--dc-accent); }
386
+
387
+ .dc-req-top {
388
+ display: flex;
389
+ align-items: center;
390
+ gap: 7px;
391
+ font-size: 11px;
392
+ }
393
+
394
+ .dc-method {
395
+ padding: 2px 6px;
396
+ border-radius: 4px;
397
+ font-size: 9px;
398
+ font-weight: 700;
399
+ letter-spacing: 0.05em;
400
+ flex-shrink: 0;
401
+ }
402
+
403
+ .m-GET { background: rgba(61,255,160,0.15); color: var(--dc-green); }
404
+ .m-POST { background: rgba(91,206,250,0.15); color: var(--dc-blue); }
405
+ .m-PUT { background: rgba(255,179,71,0.15); color: var(--dc-orange); }
406
+ .m-DELETE { background: rgba(255,92,110,0.15); color: var(--dc-red); }
407
+ .m-PATCH { background: rgba(124,106,247,0.15); color: var(--dc-accent); }
408
+ .m-UNK { background: var(--dc-bg3); color: var(--dc-text2); }
409
+
410
+ .dc-req-url {
411
+ flex: 1;
412
+ overflow: hidden;
413
+ text-overflow: ellipsis;
414
+ white-space: nowrap;
415
+ color: var(--dc-text0);
416
+ }
417
+
418
+ .dc-req-status { flex-shrink: 0; }
419
+ .s-ok { color: var(--dc-green); }
420
+ .s-redir { color: var(--dc-orange); }
421
+ .s-err { color: var(--dc-red); }
422
+
423
+ .dc-req-meta {
424
+ color: var(--dc-text2);
425
+ font-size: 10px;
426
+ margin-top: 3px;
427
+ }
428
+
429
+ .dc-req-detail {
430
+ display: none;
431
+ margin-top: 8px;
432
+ background: var(--dc-bg0);
433
+ border-radius: 6px;
434
+ padding: 10px 12px;
435
+ font-size: 11px;
436
+ color: var(--dc-text1);
437
+ }
438
+
439
+ .dc-req-detail.open { display: block; }
440
+
441
+ .dc-detail-section { margin-bottom: 10px; }
442
+ .dc-detail-title { color: var(--dc-accent); font-weight: 700; margin-bottom: 4px; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; }
443
+ .dc-detail-row { padding: 2px 0; word-break: break-all; }
444
+ .dc-detail-key { color: var(--dc-text2); }
445
+
446
+ /* ── STORAGE TAB ──────────────────────── */
447
+ .dc-storage-nav {
448
+ display: flex;
449
+ gap: 4px;
450
+ padding: 8px 12px;
451
+ background: var(--dc-bg2);
452
+ border-bottom: 1px solid var(--dc-border);
453
+ flex-shrink: 0;
454
+ }
455
+
456
+ .dc-st-btn {
457
+ padding: 5px 12px;
458
+ border: 1px solid var(--dc-border);
459
+ border-radius: 100px;
460
+ background: none;
461
+ color: var(--dc-text2);
462
+ font-family: var(--dc-mono);
463
+ font-size: 11px;
464
+ cursor: pointer;
465
+ transition: all 0.15s;
466
+ }
467
+
468
+ .dc-st-btn.active { background: var(--dc-accent); border-color: var(--dc-accent); color: #fff; }
469
+ .dc-st-btn:hover:not(.active) { border-color: var(--dc-text2); color: var(--dc-text1); }
470
+
471
+ .dc-storage-actions {
472
+ display: flex;
473
+ justify-content: flex-end;
474
+ padding: 6px 12px;
475
+ flex-shrink: 0;
476
+ }
477
+
478
+ .dc-db-card {
479
+ background: var(--dc-bg2);
480
+ border: 1px solid var(--dc-border);
481
+ border-radius: 8px;
482
+ margin-bottom: 8px;
483
+ overflow: hidden;
484
+ }
485
+
486
+ .dc-db-header {
487
+ padding: 10px 14px;
488
+ cursor: pointer;
489
+ display: flex;
490
+ justify-content: space-between;
491
+ align-items: center;
492
+ background: var(--dc-bg3);
493
+ transition: background 0.15s;
494
+ }
495
+
496
+ .dc-db-header:hover { background: var(--dc-border); }
497
+
498
+ .dc-db-name { color: var(--dc-blue); font-size: 12px; font-weight: 700; }
499
+ .dc-db-meta { color: var(--dc-text2); font-size: 10px; margin-top: 2px; }
500
+
501
+ .dc-db-body { display: none; padding: 10px; }
502
+ .dc-db-card.open .dc-db-body { display: block; }
503
+
504
+ .dc-store-item {
505
+ padding: 8px 10px;
506
+ background: var(--dc-bg0);
507
+ border-radius: 5px;
508
+ margin-bottom: 6px;
509
+ cursor: pointer;
510
+ border: 1px solid transparent;
511
+ transition: border-color 0.15s;
512
+ }
513
+
514
+ .dc-store-item:hover { border-color: var(--dc-border); }
515
+ .dc-store-name { color: var(--dc-text0); font-size: 12px; font-weight: 600; }
516
+ .dc-store-meta { color: var(--dc-text2); font-size: 10px; margin-top: 2px; }
517
+
518
+ .dc-data-viewer {
519
+ display: none;
520
+ margin-top: 8px;
521
+ max-height: 180px;
522
+ overflow-y: auto;
523
+ }
524
+
525
+ .dc-data-viewer.open { display: block; }
526
+
527
+ .dc-data-row {
528
+ padding: 6px 8px;
529
+ border-bottom: 1px solid var(--dc-border);
530
+ font-size: 11px;
531
+ }
532
+
533
+ .dc-data-key { color: #ffd700; font-weight: 600; }
534
+ .dc-data-val { color: var(--dc-blue); margin-top: 3px; word-break: break-all; }
535
+
536
+ .dc-kv-row {
537
+ display: flex;
538
+ gap: 8px;
539
+ align-items: baseline;
540
+ padding: 6px 0;
541
+ border-bottom: 1px solid var(--dc-border);
542
+ font-size: 11px;
543
+ }
544
+
545
+ .dc-kv-key { color: #ffd700; font-weight: 600; min-width: 100px; word-break: break-all; }
546
+ .dc-kv-val { color: var(--dc-blue); flex: 1; word-break: break-all; }
547
+
548
+ .dc-empty {
549
+ padding: 24px;
550
+ text-align: center;
551
+ color: var(--dc-text2);
552
+ font-size: 12px;
553
+ }
554
+
555
+ /* ── DOM TAB ──────────────────────────────────── */
556
+ .dc-dom-toolbar {
557
+ display: flex;
558
+ gap: 8px;
559
+ padding: 8px 12px;
560
+ background: var(--dc-bg2);
561
+ border-bottom: 1px solid var(--dc-border);
562
+ flex-shrink: 0;
563
+ }
564
+
565
+ .dc-dom-btn {
566
+ padding: 5px 12px;
567
+ border: 1px solid var(--dc-border);
568
+ border-radius: 100px;
569
+ background: none;
570
+ color: var(--dc-text2);
571
+ font-size: 11px;
572
+ cursor: pointer;
573
+ transition: all 0.15s;
574
+ }
575
+
576
+ .dc-dom-btn:hover { border-color: var(--dc-accent); color: var(--dc-accent); }
577
+ .dc-dom-btn.picking { background: var(--dc-accent2); border-color: var(--dc-accent2); color: #fff; }
578
+
579
+ .dc-tree { font-size: 12px; }
580
+
581
+ .dc-node-label {
582
+ display: flex;
583
+ align-items: center;
584
+ gap: 4px;
585
+ padding: 3px 4px;
586
+ border-radius: 4px;
587
+ cursor: pointer;
588
+ white-space: nowrap;
589
+ overflow: hidden;
590
+ text-overflow: ellipsis;
591
+ user-select: none;
592
+ transition: background 0.1s;
593
+ }
594
+
595
+ .dc-node-label:hover { background: var(--dc-bg3); }
596
+
597
+ .dc-arrow { color: var(--dc-text2); width: 12px; flex-shrink: 0; font-size: 9px; }
598
+ .dc-tag { color: var(--dc-accent2); font-weight: 600; }
599
+ .dc-id { color: var(--dc-blue); }
600
+ .dc-cls { color: var(--dc-orange); }
601
+ .dc-txt-preview { color: var(--dc-text2); font-size: 10px; max-width: 150px; overflow: hidden; text-overflow: ellipsis; }
602
+
603
+ .dc-children { margin-left: 16px; display: none; }
604
+ .dc-children.open { display: block; }
605
+
606
+ .dc-node-detail {
607
+ background: var(--dc-bg0);
608
+ border: 1px solid var(--dc-border);
609
+ border-radius: 6px;
610
+ padding: 12px;
611
+ margin: 8px 0;
612
+ font-size: 11px;
613
+ }
614
+
615
+ .dc-attr-row { padding: 3px 0; }
616
+ .dc-attr-name { color: var(--dc-blue); }
617
+ .dc-attr-val { color: var(--dc-green); }
618
+
619
+ /* ── SYSTEM TAB ───────────────────────────────── */
620
+ .dc-sys-grid {
621
+ display: grid;
622
+ grid-template-columns: 1fr 1fr;
623
+ gap: 8px;
624
+ padding: 10px 12px;
625
+ }
626
+
627
+ .dc-sys-card {
628
+ background: var(--dc-bg2);
629
+ border: 1px solid var(--dc-border);
630
+ border-radius: 8px;
631
+ padding: 12px 14px;
632
+ }
633
+
634
+ .dc-sys-label {
635
+ color: var(--dc-text2);
636
+ font-size: 10px;
637
+ font-weight: 600;
638
+ letter-spacing: 0.08em;
639
+ text-transform: uppercase;
640
+ margin-bottom: 5px;
641
+ }
642
+
643
+ .dc-sys-val {
644
+ color: var(--dc-text0);
645
+ font-size: 11px;
646
+ line-height: 1.4;
647
+ }
648
+
649
+ .dc-sys-full { grid-column: 1 / -1; }
650
+
651
+ /* ── SETTINGS TAB ─────────────────────────────── */
652
+ .dc-settings-body { padding: 10px 12px; }
653
+
654
+ .dc-setting-row {
655
+ display: flex;
656
+ align-items: center;
657
+ justify-content: space-between;
658
+ padding: 10px 0;
659
+ border-bottom: 1px solid var(--dc-border);
660
+ }
661
+
662
+ .dc-setting-row:last-child { border-bottom: none; }
663
+
664
+ .dc-setting-info { flex: 1; }
665
+ .dc-setting-name { color: var(--dc-text0); font-size: 12px; font-weight: 600; }
666
+ .dc-setting-desc { color: var(--dc-text2); font-size: 10px; margin-top: 2px; }
667
+
668
+ .dc-toggle {
669
+ position: relative;
670
+ width: 40px;
671
+ height: 22px;
672
+ flex-shrink: 0;
673
+ }
674
+
675
+ .dc-toggle input { opacity: 0; width: 0; height: 0; }
676
+
677
+ .dc-toggle-track {
678
+ position: absolute;
679
+ top: 0; left: 0; right: 0; bottom: 0;
680
+ background: var(--dc-border);
681
+ border-radius: 11px;
682
+ cursor: pointer;
683
+ transition: background 0.2s;
684
+ }
685
+
686
+ .dc-toggle input:checked + .dc-toggle-track { background: var(--dc-accent); }
687
+
688
+ .dc-toggle-track::after {
689
+ content: '';
690
+ position: absolute;
691
+ width: 16px;
692
+ height: 16px;
693
+ background: white;
694
+ border-radius: 50%;
695
+ top: 3px; left: 3px;
696
+ transition: transform 0.2s;
697
+ }
698
+
699
+ .dc-toggle input:checked + .dc-toggle-track::after { transform: translateX(18px); }
700
+
701
+ .dc-select {
702
+ background: var(--dc-bg0);
703
+ border: 1px solid var(--dc-border);
704
+ border-radius: 6px;
705
+ color: var(--dc-text0);
706
+ font-size: 12px;
707
+ padding: 6px 10px;
708
+ outline: none;
709
+ }
710
+
711
+ /* ── PICK highlight ───────────────────────────── */
712
+ .dc-pick-highlight {
713
+ outline: 2px dashed var(--dc-accent2) !important;
714
+ outline-offset: 2px;
715
+ background: rgba(247,104,164,0.08) !important;
716
+ }
717
+ `;
718
+ const style = document.createElement("style");
719
+ style.textContent = css;
720
+ document.head.appendChild(style);
721
+ const html = `
722
+ <button id="dc-fab" title="DevConsole">
723
+ <span id="dc-fab-icon">⌥</span>
724
+ <span class="dc-fab-badge" id="dc-error-badge">0</span>
725
+ </button>
726
+
727
+ <div id="dc-panel">
728
+ <div id="dc-drag"></div>
729
+ <div id="dc-header">
730
+ <span id="dc-title">DevConsole</span>
731
+ <span class="dc-pulse"></span>
732
+ <button class="dc-hbtn" id="dc-clear-btn" title="Clear active tab">🗑</button>
733
+ <button class="dc-hbtn" id="dc-copy-btn" title="Copy logs to clipboard">📋</button>
734
+ <button class="dc-hbtn" id="dc-minimize-btn" title="Minimize">−</button>
735
+ </div>
736
+
737
+ <div id="dc-tabs">
738
+ <button class="dc-tab active" data-tab="console">Console<span class="dc-tab-count" id="cnt-console" style="display:none"></span></button>
739
+ <button class="dc-tab" data-tab="network">Network<span class="dc-tab-count" id="cnt-network" style="display:none"></span></button>
740
+ <button class="dc-tab" data-tab="storage">Storage</button>
741
+ <button class="dc-tab" data-tab="dom">DOM</button>
742
+ <button class="dc-tab" data-tab="system">System</button>
743
+ <button class="dc-tab" data-tab="settings">⚙</button>
744
+ </div>
745
+
746
+ <div class="dc-panel-content active" id="panel-console">
747
+ <div class="dc-scroll" id="console-output"></div>
748
+ <div class="dc-repl">
749
+ <input class="dc-input" id="repl-input" placeholder="▶ execute javascript…" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">
750
+ <button class="dc-run-btn" id="repl-run">RUN</button>
751
+ </div>
752
+ </div>
753
+
754
+ <div class="dc-panel-content" id="panel-network">
755
+ <div class="dc-net-filter">
756
+ <input class="dc-filter-input" id="net-filter" placeholder="Filter by URL or method…">
757
+ <button class="dc-clear-btn" id="net-clear">Clear</button>
758
+ </div>
759
+ <div class="dc-scroll" id="network-output"></div>
760
+ </div>
761
+
762
+ <div class="dc-panel-content" id="panel-storage">
763
+ <div class="dc-storage-nav">
764
+ <button class="dc-st-btn active" data-storage="indexeddb">IndexedDB</button>
765
+ <button class="dc-st-btn" data-storage="localstorage">LocalStorage</button>
766
+ <button class="dc-st-btn" data-storage="sessionstorage">SessionStorage</button>
767
+ </div>
768
+ <div class="dc-storage-actions">
769
+ <button class="dc-clear-btn" id="storage-refresh">↺ Refresh</button>
770
+ </div>
771
+ <div class="dc-scroll" id="storage-output"></div>
772
+ </div>
773
+
774
+ <div class="dc-panel-content" id="panel-dom">
775
+ <div class="dc-dom-toolbar">
776
+ <button class="dc-dom-btn" id="dom-refresh-btn">↺ Refresh tree</button>
777
+ <button class="dc-dom-btn" id="dom-pick-btn">⊕ Pick element</button>
778
+ <button class="dc-dom-btn" id="dom-collapse-btn">Collapse all</button>
779
+ </div>
780
+ <div class="dc-scroll" id="dom-output"></div>
781
+ </div>
782
+
783
+ <div class="dc-panel-content" id="panel-system">
784
+ <div class="dc-scroll">
785
+ <div class="dc-sys-grid" id="system-output"></div>
786
+ </div>
787
+ </div>
788
+
789
+ <div class="dc-panel-content" id="panel-settings">
790
+ <div class="dc-scroll dc-settings-body" id="settings-output"></div>
791
+ </div>
792
+ </div>
793
+ `;
794
+ document.body.insertAdjacentHTML("beforeend", html);
795
+ const S = {
796
+ logs: [],
797
+ network: [],
798
+ dbs: [],
799
+ activeTab: "console",
800
+ activeStorage: "indexeddb",
801
+ isPicking: false,
802
+ replHistory: [],
803
+ replHistoryIdx: -1,
804
+ errorCount: 0,
805
+ settings: {
806
+ timestamps: true,
807
+ autoScroll: true,
808
+ maxEntries: 500,
809
+ fontSize: 12,
810
+ monitorNetwork: true,
811
+ captureErrors: true,
812
+ theme: "dark"
813
+ }
49
814
  };
50
- }
51
- function attachGlobalErrorHandler() {
52
- window.addEventListener("error", (event) => {
53
- state.errors.push({ error: event.error, timestamp: Date.now() });
815
+ function saveSettings() {
816
+ try {
817
+ localStorage.setItem("__dc_settings", JSON.stringify(S.settings));
818
+ } catch (e) {
819
+ }
820
+ }
821
+ function loadSettings() {
822
+ try {
823
+ const saved = localStorage.getItem("__dc_settings");
824
+ if (saved) S.settings = { ...S.settings, ...JSON.parse(saved) };
825
+ } catch (e) {
826
+ }
827
+ }
828
+ loadSettings();
829
+ const el = {
830
+ fab: () => document.getElementById("dc-fab"),
831
+ panel: () => document.getElementById("dc-panel"),
832
+ consOut: () => document.getElementById("console-output"),
833
+ netOut: () => document.getElementById("network-output"),
834
+ storOut: () => document.getElementById("storage-output"),
835
+ domOut: () => document.getElementById("dom-output"),
836
+ sysOut: () => document.getElementById("system-output"),
837
+ settOut: () => document.getElementById("settings-output"),
838
+ replIn: () => document.getElementById("repl-input"),
839
+ netFlt: () => document.getElementById("net-filter"),
840
+ badge: () => document.getElementById("dc-error-badge"),
841
+ cntC: () => document.getElementById("cnt-console"),
842
+ cntN: () => document.getElementById("cnt-network")
843
+ };
844
+ function ts() {
845
+ const d = /* @__PURE__ */ new Date();
846
+ return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}:${String(d.getSeconds()).padStart(2, "0")}.${String(d.getMilliseconds()).padStart(3, "0")}`;
847
+ }
848
+ function escHtml(s) {
849
+ return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
850
+ }
851
+ function formatArg(a) {
852
+ if (a === null) return '<span style="color:#aaa">null</span>';
853
+ if (a === void 0) return '<span style="color:#aaa">undefined</span>';
854
+ if (typeof a === "object") {
855
+ try {
856
+ const s = JSON.stringify(a, null, 2);
857
+ return `<pre>${escHtml(s)}</pre>`;
858
+ } catch (e) {
859
+ return String(a);
860
+ }
861
+ }
862
+ return escHtml(String(a));
863
+ }
864
+ function truncUrl(url, max = 55) {
865
+ if (!url || url.length <= max) return url;
866
+ try {
867
+ const u = new URL(url);
868
+ const tail = u.pathname.split("/").pop() || "";
869
+ return `${u.hostname}/…/${tail}`;
870
+ } catch (e) {
871
+ return url.slice(0, max) + "…";
872
+ }
873
+ }
874
+ function statusClass(code) {
875
+ if (!code) return "";
876
+ if (code < 300) return "s-ok";
877
+ if (code < 400) return "s-redir";
878
+ return "s-err";
879
+ }
880
+ function methodClass(m) {
881
+ return `m-${["GET", "POST", "PUT", "DELETE", "PATCH"].includes(m) ? m : "UNK"}`;
882
+ }
883
+ const _orig = {};
884
+ ["log", "warn", "error", "info"].forEach((level) => {
885
+ _orig[level] = console[level].bind(console);
886
+ console[level] = (...args) => {
887
+ _orig[level](...args);
888
+ addLog(level, args);
889
+ };
54
890
  });
55
- }
56
- const insiktAPI = {
57
- version: VERSION,
58
- init: initInsikt,
59
- destroy: destroyInsikt,
60
- toggle: toggleInsikt,
61
- clear: clearLogs
62
- };
63
- if (typeof window !== "undefined") {
64
- window.insikt = insiktAPI;
65
- if (!window.__INSIKT_INITIALIZED__) {
66
- window.__INSIKT_INITIALIZED__ = true;
67
- if (document.readyState === "loading") {
68
- document.addEventListener("DOMContentLoaded", initInsikt);
891
+ function addLog(type, args) {
892
+ if (type === "error") {
893
+ S.errorCount++;
894
+ const b = el.badge();
895
+ if (b) {
896
+ b.textContent = S.errorCount > 99 ? "99+" : S.errorCount;
897
+ b.style.display = "flex";
898
+ }
899
+ }
900
+ S.logs.push({ type, args, ts: ts() });
901
+ if (S.logs.length > S.settings.maxEntries) S.logs.shift();
902
+ updateTabCount("console", S.logs.length);
903
+ if (S.activeTab === "console") renderConsole();
904
+ }
905
+ function renderConsole() {
906
+ const o = el.consOut();
907
+ if (!o) return;
908
+ const frag = document.createDocumentFragment();
909
+ S.logs.forEach((log) => {
910
+ const d = document.createElement("div");
911
+ d.className = `dc-entry dc-entry-${log.type}`;
912
+ const tsHtml = S.settings.timestamps ? `<span class="dc-ts">${log.ts}</span>` : "";
913
+ const msgHtml = log.args.map(formatArg).join(" ");
914
+ d.innerHTML = `${tsHtml}<span>${msgHtml}</span>`;
915
+ d.style.fontSize = S.settings.fontSize + "px";
916
+ frag.appendChild(d);
917
+ });
918
+ o.innerHTML = "";
919
+ o.appendChild(frag);
920
+ if (S.settings.autoScroll) o.scrollTop = o.scrollHeight;
921
+ }
922
+ if (S.settings.captureErrors) {
923
+ window.onerror = (msg, src, line, col) => {
924
+ addLog("error", [`${msg} @ ${src}:${line}:${col}`]);
925
+ return false;
926
+ };
927
+ window.addEventListener("unhandledrejection", (e) => {
928
+ addLog("error", [`Unhandled Promise Rejection: ${e.reason}`]);
929
+ });
930
+ }
931
+ const _origFetch = window.fetch;
932
+ window.fetch = async (...args) => {
933
+ const startTime = Date.now();
934
+ let method = "GET";
935
+ let url = args[0] instanceof Request ? args[0].url : String(args[0]);
936
+ if (args[1] && args[1].method) method = args[1].method.toUpperCase();
937
+ if (args[0] instanceof Request) method = args[0].method.toUpperCase();
938
+ const req = { method, url, ts: ts(), startTime, status: null, duration: null, headers: {}, error: null };
939
+ try {
940
+ const res = await _origFetch(...args);
941
+ req.status = res.status;
942
+ req.statusText = res.statusText;
943
+ req.duration = Date.now() - startTime;
944
+ try {
945
+ res.headers.forEach((v, k) => {
946
+ req.headers[k] = v;
947
+ });
948
+ } catch (e) {
949
+ }
950
+ addNetReq(req);
951
+ return res;
952
+ } catch (e) {
953
+ req.error = e.message;
954
+ req.duration = Date.now() - startTime;
955
+ addNetReq(req);
956
+ throw e;
957
+ }
958
+ };
959
+ const _origOpen = XMLHttpRequest.prototype.open;
960
+ const _origSend = XMLHttpRequest.prototype.send;
961
+ XMLHttpRequest.prototype.open = function(method, url) {
962
+ this.__dcReq = { method: method.toUpperCase(), url: String(url), ts: ts(), startTime: 0 };
963
+ return _origOpen.apply(this, arguments);
964
+ };
965
+ XMLHttpRequest.prototype.send = function(body) {
966
+ if (this.__dcReq) {
967
+ const req = this.__dcReq;
968
+ req.startTime = Date.now();
969
+ this.addEventListener("loadend", () => {
970
+ req.status = this.status;
971
+ req.statusText = this.statusText;
972
+ req.duration = Date.now() - req.startTime;
973
+ req.headers = {};
974
+ const raw = this.getAllResponseHeaders();
975
+ if (raw) raw.split("\r\n").filter(Boolean).forEach((line) => {
976
+ const i = line.indexOf(": ");
977
+ if (i > 0) req.headers[line.slice(0, i)] = line.slice(i + 2);
978
+ });
979
+ req.error = this.status === 0 ? "Request failed" : null;
980
+ addNetReq(req);
981
+ });
982
+ }
983
+ return _origSend.apply(this, arguments);
984
+ };
985
+ function addNetReq(req) {
986
+ S.network.unshift(req);
987
+ if (S.network.length > S.settings.maxEntries) S.network.pop();
988
+ updateTabCount("network", S.network.length);
989
+ if (S.activeTab === "network") renderNetwork();
990
+ }
991
+ function renderNetwork(filter) {
992
+ const o = el.netOut();
993
+ if (!o) return;
994
+ filter = filter !== void 0 ? filter : el.netFlt() ? el.netFlt().value : "";
995
+ const filtered = filter ? S.network.filter((r) => r.url.toLowerCase().includes(filter.toLowerCase()) || r.method.toLowerCase().includes(filter.toLowerCase())) : S.network;
996
+ o.innerHTML = filtered.map((req, i) => {
997
+ const sc = req.error ? "s-err" : statusClass(req.status);
998
+ const mc = methodClass(req.method);
999
+ const statusLabel = req.status ? `<span class="dc-req-status ${sc}">${req.status}</span>` : req.error ? `<span class="dc-req-status s-err">ERR</span>` : '<span class="dc-req-status" style="color:var(--dc-text2)">…</span>';
1000
+ const durLabel = req.duration != null ? `${req.duration}ms · ` : "";
1001
+ const headersHtml = Object.keys(req.headers).length ? Object.entries(req.headers).map(([k, v]) => `<div class="dc-detail-row"><span class="dc-detail-key">${escHtml(k)}: </span>${escHtml(v)}</div>`).join("") : '<div class="dc-detail-row" style="color:var(--dc-text2)">none</div>';
1002
+ return `<div class="dc-req" id="req-${i}" onclick="window.__dcToggleReq(${i})">
1003
+ <div class="dc-req-top">
1004
+ <span class="dc-method ${mc}">${req.method}</span>
1005
+ <span class="dc-req-url" title="${escHtml(req.url)}">${escHtml(truncUrl(req.url))}</span>
1006
+ ${statusLabel}
1007
+ </div>
1008
+ <div class="dc-req-meta">${durLabel}${req.ts}${req.error ? " · " + escHtml(req.error) : ""}</div>
1009
+ <div class="dc-req-detail" id="req-detail-${i}">
1010
+ <div class="dc-detail-section">
1011
+ <div class="dc-detail-title">General</div>
1012
+ <div class="dc-detail-row"><span class="dc-detail-key">URL: </span>${escHtml(req.url)}</div>
1013
+ <div class="dc-detail-row"><span class="dc-detail-key">Method: </span>${req.method}</div>
1014
+ <div class="dc-detail-row"><span class="dc-detail-key">Status: </span>${req.status || req.error || "–"} ${req.statusText || ""}</div>
1015
+ <div class="dc-detail-row"><span class="dc-detail-key">Duration: </span>${req.duration != null ? req.duration + "ms" : "–"}</div>
1016
+ </div>
1017
+ <div class="dc-detail-section">
1018
+ <div class="dc-detail-title">Response Headers</div>
1019
+ ${headersHtml}
1020
+ </div>
1021
+ </div>
1022
+ </div>`;
1023
+ }).join("") || '<div class="dc-empty">No requests captured yet</div>';
1024
+ }
1025
+ window.__dcToggleReq = function(i) {
1026
+ const detail = document.getElementById(`req-detail-${i}`);
1027
+ const card = document.getElementById(`req-${i}`);
1028
+ if (!detail) return;
1029
+ const isOpen = detail.classList.contains("open");
1030
+ detail.classList.toggle("open", !isOpen);
1031
+ card.classList.toggle("expanded", !isOpen);
1032
+ };
1033
+ async function loadStorage() {
1034
+ S.dbs = [];
1035
+ if (!window.indexedDB) return;
1036
+ try {
1037
+ if (indexedDB.databases) {
1038
+ const list = await indexedDB.databases();
1039
+ for (const d of list) {
1040
+ try {
1041
+ await inspectDb(d.name, d.version);
1042
+ } catch (e) {
1043
+ }
1044
+ }
1045
+ }
1046
+ } catch (e) {
1047
+ }
1048
+ renderStorage();
1049
+ }
1050
+ function inspectDb(name, version) {
1051
+ return new Promise((res, rej) => {
1052
+ const req = indexedDB.open(name, version);
1053
+ req.onerror = () => rej(req.error);
1054
+ req.onsuccess = () => {
1055
+ const db = req.result;
1056
+ const info = { name: db.name, version: db.version, stores: [] };
1057
+ const storeNames = [...db.objectStoreNames];
1058
+ let pending = storeNames.length;
1059
+ if (!pending) {
1060
+ db.close();
1061
+ S.dbs.push(info);
1062
+ return res(info);
1063
+ }
1064
+ storeNames.forEach((storeName) => {
1065
+ inspectStore(db, storeName).then((storeInfo) => {
1066
+ info.stores.push(storeInfo);
1067
+ if (--pending === 0) {
1068
+ db.close();
1069
+ S.dbs.push(info);
1070
+ res(info);
1071
+ }
1072
+ }).catch(() => {
1073
+ info.stores.push({ name: storeName, count: 0, keyPath: null, data: [] });
1074
+ if (--pending === 0) {
1075
+ db.close();
1076
+ S.dbs.push(info);
1077
+ res(info);
1078
+ }
1079
+ });
1080
+ });
1081
+ };
1082
+ });
1083
+ }
1084
+ function inspectStore(db, storeName) {
1085
+ return new Promise((res, rej) => {
1086
+ const tx = db.transaction([storeName], "readonly");
1087
+ const store = tx.objectStore(storeName);
1088
+ const cntReq = store.count();
1089
+ cntReq.onsuccess = () => {
1090
+ const info = { name: storeName, count: cntReq.result, keyPath: store.keyPath, data: [] };
1091
+ const getReq = store.getAll(void 0, 20);
1092
+ getReq.onsuccess = () => {
1093
+ info.data = getReq.result;
1094
+ res(info);
1095
+ };
1096
+ getReq.onerror = () => res(info);
1097
+ };
1098
+ cntReq.onerror = () => res({ name: storeName, count: 0, keyPath: null, data: [] });
1099
+ });
1100
+ }
1101
+ function renderStorage() {
1102
+ const o = el.storOut();
1103
+ if (!o) return;
1104
+ switch (S.activeStorage) {
1105
+ case "indexeddb":
1106
+ renderIDB(o);
1107
+ break;
1108
+ case "localstorage":
1109
+ renderKV(o, localStorage, "localStorage");
1110
+ break;
1111
+ case "sessionstorage":
1112
+ renderKV(o, sessionStorage, "sessionStorage");
1113
+ break;
1114
+ }
1115
+ }
1116
+ function renderIDB(o) {
1117
+ if (!S.dbs.length) {
1118
+ o.innerHTML = '<div class="dc-empty">No IndexedDB databases found</div>';
1119
+ return;
1120
+ }
1121
+ o.innerHTML = S.dbs.map((db, di) => `<div class="dc-db-card" id="db-card-${di}">
1122
+ <div class="dc-db-header" onclick="window.__dcToggleDb(${di})">
1123
+ <div>
1124
+ <div class="dc-db-name">${escHtml(db.name)}</div>
1125
+ <div class="dc-db-meta">v${db.version} · ${db.stores.length} store${db.stores.length !== 1 ? "s" : ""}</div>
1126
+ </div>
1127
+ <span style="color:var(--dc-text2);font-size:11px">▼</span>
1128
+ </div>
1129
+ <div class="dc-db-body">
1130
+ ${db.stores.map((st, si) => `
1131
+ <div class="dc-store-item" onclick="window.__dcToggleStore(${di},${si})">
1132
+ <div class="dc-store-name">${escHtml(st.name)}</div>
1133
+ <div class="dc-store-meta">${st.count} records · keyPath: ${st.keyPath || "none"}</div>
1134
+ <div class="dc-data-viewer" id="store-${di}-${si}">
1135
+ ${st.data.length ? st.data.slice(0, 20).map((item) => `
1136
+ <div class="dc-data-row">
1137
+ <div class="dc-data-key">· ${escHtml(getKey(item, st.keyPath))}</div>
1138
+ <div class="dc-data-val">${escHtml(fmtVal(item))}</div>
1139
+ </div>`).join("") : '<div style="color:var(--dc-text2);font-size:11px;padding:8px">Empty store</div>'}
1140
+ </div>
1141
+ </div>`).join("")}
1142
+ </div>
1143
+ </div>`).join("");
1144
+ }
1145
+ function getKey(obj, keyPath) {
1146
+ if (!keyPath) return "—";
1147
+ return typeof keyPath === "string" ? String(obj[keyPath] ?? "—") : JSON.stringify(keyPath);
1148
+ }
1149
+ function fmtVal(v) {
1150
+ if (typeof v === "object" && v !== null) {
1151
+ const s2 = JSON.stringify(v, null, 2);
1152
+ return s2.length > 300 ? s2.slice(0, 300) + "…" : s2;
1153
+ }
1154
+ const s = String(v);
1155
+ return s.length > 200 ? s.slice(0, 200) + "…" : s;
1156
+ }
1157
+ function renderKV(o, storage, name) {
1158
+ const items = [];
1159
+ for (let i = 0; i < storage.length; i++) {
1160
+ const k = storage.key(i);
1161
+ items.push({ k, v: storage.getItem(k) });
1162
+ }
1163
+ if (!items.length) {
1164
+ o.innerHTML = `<div class="dc-empty">No ${name} items</div>`;
1165
+ return;
1166
+ }
1167
+ o.innerHTML = `<div style="padding:4px 0">` + items.map(({ k, v }) => `
1168
+ <div class="dc-kv-row">
1169
+ <span class="dc-kv-key">${escHtml(k)}</span>
1170
+ <span class="dc-kv-val">${escHtml(fmtVal(v))}</span>
1171
+ </div>`).join("") + `</div>`;
1172
+ }
1173
+ window.__dcToggleDb = function(di) {
1174
+ const card = document.getElementById(`db-card-${di}`);
1175
+ if (card) card.classList.toggle("open");
1176
+ };
1177
+ window.__dcToggleStore = function(di, si) {
1178
+ const viewer = document.getElementById(`store-${di}-${si}`);
1179
+ if (viewer) viewer.classList.toggle("open");
1180
+ };
1181
+ function renderDomTree() {
1182
+ const o = el.domOut();
1183
+ if (!o) return;
1184
+ o.innerHTML = "";
1185
+ const tree = document.createElement("div");
1186
+ tree.className = "dc-tree";
1187
+ tree.appendChild(buildNode(document.body));
1188
+ o.appendChild(tree);
1189
+ }
1190
+ function buildNode(nodeEl) {
1191
+ const wrap = document.createElement("div");
1192
+ const children = [...nodeEl.children];
1193
+ const hasChildren = children.length > 0;
1194
+ const label = document.createElement("div");
1195
+ label.className = "dc-node-label";
1196
+ const arrow = document.createElement("span");
1197
+ arrow.className = "dc-arrow";
1198
+ arrow.textContent = hasChildren ? "▶" : " ";
1199
+ label.appendChild(arrow);
1200
+ const tag = document.createElement("span");
1201
+ tag.className = "dc-tag";
1202
+ tag.textContent = `<${nodeEl.tagName.toLowerCase()}`;
1203
+ label.appendChild(tag);
1204
+ if (nodeEl.id) {
1205
+ const id = document.createElement("span");
1206
+ id.className = "dc-id";
1207
+ id.textContent = ` #${nodeEl.id}`;
1208
+ label.appendChild(id);
1209
+ }
1210
+ if (nodeEl.className && typeof nodeEl.className === "string" && nodeEl.className.trim()) {
1211
+ const cls = document.createElement("span");
1212
+ cls.className = "dc-cls";
1213
+ const clsStr = nodeEl.className.trim().split(/\s+/).slice(0, 3).map((c) => `.${c}`).join("");
1214
+ cls.textContent = clsStr;
1215
+ label.appendChild(cls);
1216
+ }
1217
+ const close = document.createElement("span");
1218
+ close.className = "dc-tag";
1219
+ close.textContent = ">";
1220
+ label.appendChild(close);
1221
+ const txtContent = nodeEl.childNodes.length ? [...nodeEl.childNodes].find((n) => n.nodeType === 3 && n.textContent.trim()) : null;
1222
+ if (txtContent) {
1223
+ const preview = document.createElement("span");
1224
+ preview.className = "dc-txt-preview";
1225
+ preview.textContent = " " + txtContent.textContent.trim().slice(0, 30);
1226
+ label.appendChild(preview);
1227
+ }
1228
+ label.addEventListener("click", (e) => {
1229
+ e.stopPropagation();
1230
+ if (hasChildren) {
1231
+ const childDiv = wrap.querySelector(":scope > .dc-children");
1232
+ const isOpen = childDiv && childDiv.classList.contains("open");
1233
+ if (childDiv) childDiv.classList.toggle("open", !isOpen);
1234
+ arrow.textContent = !isOpen ? "▼" : "▶";
1235
+ }
1236
+ showNodeDetail(nodeEl);
1237
+ });
1238
+ wrap.appendChild(label);
1239
+ if (hasChildren) {
1240
+ const childDiv = document.createElement("div");
1241
+ childDiv.className = "dc-children";
1242
+ children.forEach((child) => childDiv.appendChild(buildNode(child)));
1243
+ wrap.appendChild(childDiv);
1244
+ }
1245
+ return wrap;
1246
+ }
1247
+ function showNodeDetail(targetEl) {
1248
+ const existing = document.getElementById("dc-node-detail");
1249
+ if (existing) existing.remove();
1250
+ const d = document.createElement("div");
1251
+ d.className = "dc-node-detail";
1252
+ d.id = "dc-node-detail";
1253
+ const tag = `<${targetEl.tagName.toLowerCase()}>`;
1254
+ const attrs = [...targetEl.attributes];
1255
+ const styles = window.getComputedStyle(targetEl);
1256
+ d.innerHTML = `<div style="color:var(--dc-accent2);font-size:12px;font-weight:700;margin-bottom:8px">${escHtml(tag)}</div>
1257
+ ${attrs.length ? `<div class="dc-detail-title">Attributes</div>${attrs.map((a) => `<div class="dc-attr-row"><span class="dc-attr-name">${escHtml(a.name)}</span>=<span class="dc-attr-val">"${escHtml(a.value)}"</span></div>`).join("")}` : ""}
1258
+ <div class="dc-detail-title" style="margin-top:8px">Geometry</div>
1259
+ <div class="dc-attr-row"><span class="dc-attr-name">size: </span><span class="dc-attr-val">${Math.round(targetEl.offsetWidth)}×${Math.round(targetEl.offsetHeight)}</span></div>
1260
+ <div class="dc-attr-row"><span class="dc-attr-name">display: </span><span class="dc-attr-val">${styles.display}</span></div>
1261
+ <div class="dc-attr-row"><span class="dc-attr-name">position: </span><span class="dc-attr-val">${styles.position}</span></div>`;
1262
+ el.domOut().prepend(d);
1263
+ }
1264
+ let _pickHandler = null;
1265
+ let _pickedEl = null;
1266
+ function startPicking() {
1267
+ S.isPicking = true;
1268
+ document.getElementById("dom-pick-btn").classList.add("picking");
1269
+ _pickHandler = (e) => {
1270
+ if (e.target.closest("#dc-panel") || e.target.closest("#dc-fab")) return;
1271
+ e.preventDefault();
1272
+ e.stopPropagation();
1273
+ if (_pickedEl) _pickedEl.classList.remove("dc-pick-highlight");
1274
+ _pickedEl = e.target;
1275
+ _pickedEl.classList.add("dc-pick-highlight");
1276
+ showNodeDetail(_pickedEl);
1277
+ stopPicking();
1278
+ };
1279
+ document.addEventListener("click", _pickHandler, true);
1280
+ document.addEventListener("mouseover", (e) => {
1281
+ if (!S.isPicking) return;
1282
+ if (e.target.closest("#dc-panel") || e.target.closest("#dc-fab")) return;
1283
+ if (_pickedEl) _pickedEl.classList.remove("dc-pick-highlight");
1284
+ _pickedEl = e.target;
1285
+ _pickedEl.classList.add("dc-pick-highlight");
1286
+ }, true);
1287
+ }
1288
+ function stopPicking() {
1289
+ S.isPicking = false;
1290
+ const btn = document.getElementById("dom-pick-btn");
1291
+ if (btn) btn.classList.remove("picking");
1292
+ if (_pickHandler) {
1293
+ document.removeEventListener("click", _pickHandler, true);
1294
+ _pickHandler = null;
1295
+ }
1296
+ }
1297
+ function renderSystem() {
1298
+ const o = el.sysOut();
1299
+ if (!o) return;
1300
+ const nav = navigator;
1301
+ const perf = window.performance;
1302
+ const mem = perf && perf.memory;
1303
+ const conn = nav.connection || nav.mozConnection || nav.webkitConnection;
1304
+ const cards = [
1305
+ ["Screen", `${screen.width}×${screen.height} (devicePR: ${window.devicePixelRatio})`],
1306
+ ["Viewport", `${window.innerWidth}×${window.innerHeight}`],
1307
+ ["Platform", nav.platform || "—"],
1308
+ ["Language", nav.language || "—"],
1309
+ ["Online", nav.onLine ? "✅ Online" : "❌ Offline"],
1310
+ ["Cookies", nav.cookieEnabled ? "Enabled" : "Disabled"],
1311
+ ["HW Concurrency", nav.hardwareConcurrency || "—"]
1312
+ ];
1313
+ if (conn) {
1314
+ cards.push(["Connection", `${conn.effectiveType || "—"} · ${conn.downlink || "—"} Mbps`]);
1315
+ cards.push(["RTT", conn.rtt != null ? `${conn.rtt}ms` : "—"]);
1316
+ }
1317
+ if (mem) {
1318
+ const mb = (v) => (v / 1048576).toFixed(1) + " MB";
1319
+ cards.push(["Heap Used", mb(mem.usedJSHeapSize)]);
1320
+ cards.push(["Heap Limit", mb(mem.jsHeapSizeLimit)]);
1321
+ }
1322
+ if (perf) {
1323
+ const nav2 = perf.getEntriesByType && perf.getEntriesByType("navigation")[0];
1324
+ if (nav2) {
1325
+ cards.push(["Page Load", `${Math.round(nav2.loadEventEnd)}ms`]);
1326
+ cards.push(["DOM Ready", `${Math.round(nav2.domContentLoadedEventEnd)}ms`]);
1327
+ }
1328
+ }
1329
+ o.innerHTML = cards.map(
1330
+ ([label, val]) => `<div class="dc-sys-card"><div class="dc-sys-label">${label}</div><div class="dc-sys-val">${escHtml(String(val))}</div></div>`
1331
+ ).join("") + `<div class="dc-sys-card dc-sys-full"><div class="dc-sys-label">User Agent</div><div class="dc-sys-val" style="word-break:break-all;font-size:10px">${escHtml(nav.userAgent)}</div></div>`;
1332
+ }
1333
+ function renderSettings() {
1334
+ const o = el.settOut();
1335
+ if (!o) return;
1336
+ o.innerHTML = `
1337
+ <div class="dc-setting-row">
1338
+ <div class="dc-setting-info">
1339
+ <div class="dc-setting-name">Timestamps</div>
1340
+ <div class="dc-setting-desc">Show time prefix on each log entry</div>
1341
+ </div>
1342
+ <label class="dc-toggle"><input type="checkbox" id="s-ts" ${S.settings.timestamps ? "checked" : ""}><span class="dc-toggle-track"></span></label>
1343
+ </div>
1344
+ <div class="dc-setting-row">
1345
+ <div class="dc-setting-info">
1346
+ <div class="dc-setting-name">Auto-scroll</div>
1347
+ <div class="dc-setting-desc">Scroll to latest entry automatically</div>
1348
+ </div>
1349
+ <label class="dc-toggle"><input type="checkbox" id="s-as" ${S.settings.autoScroll ? "checked" : ""}><span class="dc-toggle-track"></span></label>
1350
+ </div>
1351
+ <div class="dc-setting-row">
1352
+ <div class="dc-setting-info">
1353
+ <div class="dc-setting-name">Capture Global Errors</div>
1354
+ <div class="dc-setting-desc">window.onerror + unhandledrejection</div>
1355
+ </div>
1356
+ <label class="dc-toggle"><input type="checkbox" id="s-ce" ${S.settings.captureErrors ? "checked" : ""}><span class="dc-toggle-track"></span></label>
1357
+ </div>
1358
+ <div class="dc-setting-row">
1359
+ <div class="dc-setting-info">
1360
+ <div class="dc-setting-name">Monitor Network</div>
1361
+ <div class="dc-setting-desc">Intercept fetch + XHR requests</div>
1362
+ </div>
1363
+ <label class="dc-toggle"><input type="checkbox" id="s-mn" ${S.settings.monitorNetwork ? "checked" : ""}><span class="dc-toggle-track"></span></label>
1364
+ </div>
1365
+ <div class="dc-setting-row">
1366
+ <div class="dc-setting-info">
1367
+ <div class="dc-setting-name">Font Size</div>
1368
+ <div class="dc-setting-desc">Console output font size (px)</div>
1369
+ </div>
1370
+ <select class="dc-select" id="s-fs">
1371
+ ${[10, 11, 12, 13, 14].map((s) => `<option value="${s}" ${S.settings.fontSize === s ? "selected" : ""}>${s}px</option>`).join("")}
1372
+ </select>
1373
+ </div>
1374
+ <div class="dc-setting-row">
1375
+ <div class="dc-setting-info">
1376
+ <div class="dc-setting-name">Max Log Entries</div>
1377
+ <div class="dc-setting-desc">Older entries are discarded</div>
1378
+ </div>
1379
+ <select class="dc-select" id="s-me">
1380
+ ${[100, 250, 500, 1e3, 2e3].map((s) => `<option value="${s}" ${S.settings.maxEntries === s ? "selected" : ""}>${s}</option>`).join("")}
1381
+ </select>
1382
+ </div>
1383
+ <div class="dc-setting-row" style="border:none">
1384
+ <div class="dc-setting-info">
1385
+ <div class="dc-setting-name" style="color:var(--dc-red)">Clear All Data</div>
1386
+ <div class="dc-setting-desc">Wipe logs and network history</div>
1387
+ </div>
1388
+ <button class="dc-clear-btn" onclick="window.__dcClearAll()">Clear</button>
1389
+ </div>`;
1390
+ document.getElementById("s-ts").onchange = (e) => {
1391
+ S.settings.timestamps = e.target.checked;
1392
+ saveSettings();
1393
+ renderConsole();
1394
+ };
1395
+ document.getElementById("s-as").onchange = (e) => {
1396
+ S.settings.autoScroll = e.target.checked;
1397
+ saveSettings();
1398
+ };
1399
+ document.getElementById("s-ce").onchange = (e) => {
1400
+ S.settings.captureErrors = e.target.checked;
1401
+ saveSettings();
1402
+ };
1403
+ document.getElementById("s-mn").onchange = (e) => {
1404
+ S.settings.monitorNetwork = e.target.checked;
1405
+ saveSettings();
1406
+ };
1407
+ document.getElementById("s-fs").onchange = (e) => {
1408
+ S.settings.fontSize = parseInt(e.target.value);
1409
+ saveSettings();
1410
+ if (S.activeTab === "console") renderConsole();
1411
+ };
1412
+ document.getElementById("s-me").onchange = (e) => {
1413
+ S.settings.maxEntries = parseInt(e.target.value);
1414
+ saveSettings();
1415
+ };
1416
+ }
1417
+ window.__dcClearAll = function() {
1418
+ S.logs = [];
1419
+ S.network = [];
1420
+ S.errorCount = 0;
1421
+ const b = el.badge();
1422
+ if (b) {
1423
+ b.style.display = "none";
1424
+ }
1425
+ updateTabCount("console", 0);
1426
+ updateTabCount("network", 0);
1427
+ if (S.activeTab === "console") renderConsole();
1428
+ if (S.activeTab === "network") renderNetwork();
1429
+ };
1430
+ function switchTab(name) {
1431
+ S.activeTab = name;
1432
+ document.querySelectorAll(".dc-tab").forEach((b) => b.classList.toggle("active", b.dataset.tab === name));
1433
+ document.querySelectorAll(".dc-panel-content").forEach((p) => p.classList.toggle("active", p.id === `panel-${name}`));
1434
+ switch (name) {
1435
+ case "console":
1436
+ renderConsole();
1437
+ break;
1438
+ case "network":
1439
+ renderNetwork();
1440
+ break;
1441
+ case "storage":
1442
+ loadStorage();
1443
+ break;
1444
+ case "dom":
1445
+ renderDomTree();
1446
+ break;
1447
+ case "system":
1448
+ renderSystem();
1449
+ break;
1450
+ case "settings":
1451
+ renderSettings();
1452
+ break;
1453
+ }
1454
+ }
1455
+ function updateTabCount(tab, n) {
1456
+ const el2 = document.getElementById(`cnt-${tab}`);
1457
+ if (!el2) return;
1458
+ if (n > 0) {
1459
+ el2.textContent = n > 999 ? "999+" : n;
1460
+ el2.style.display = "inline-flex";
1461
+ } else el2.style.display = "none";
1462
+ }
1463
+ let _panelOpen = false;
1464
+ function togglePanel() {
1465
+ _panelOpen = !_panelOpen;
1466
+ const panel = el.panel();
1467
+ if (_panelOpen) {
1468
+ panel.style.display = "flex";
1469
+ requestAnimationFrame(() => {
1470
+ panel.classList.add("visible");
1471
+ });
1472
+ switchTab(S.activeTab);
1473
+ } else {
1474
+ panel.classList.remove("visible");
1475
+ setTimeout(() => {
1476
+ panel.style.display = "none";
1477
+ }, 260);
1478
+ }
1479
+ if (_panelOpen) {
1480
+ el.fab().innerHTML = `✕<span class="dc-fab-badge" id="dc-error-badge" style="display:${S.errorCount > 0 ? "flex" : "none"}">${S.errorCount}</span>`;
69
1481
  } else {
70
- initInsikt();
1482
+ el.fab().innerHTML = `⌥<span class="dc-fab-badge" id="dc-error-badge" style="display:${S.errorCount > 0 ? "flex" : "none"}">${S.errorCount}</span>`;
71
1483
  }
72
1484
  }
73
- }
74
- export {
75
- clearLogs,
76
- insiktAPI as default,
77
- destroyInsikt,
78
- initInsikt,
79
- toggleInsikt
80
- };
1485
+ (function initDrag() {
1486
+ const handle = document.getElementById("dc-drag");
1487
+ const panel = document.getElementById("dc-panel");
1488
+ let dragging = false, startY = 0, startH = 0;
1489
+ function onStart(e) {
1490
+ dragging = true;
1491
+ startY = e.clientY || e.touches && e.touches[0].clientY;
1492
+ startH = panel.offsetHeight;
1493
+ document.body.style.userSelect = "none";
1494
+ }
1495
+ function onMove(e) {
1496
+ if (!dragging) return;
1497
+ const y = e.clientY || e.touches && e.touches[0].clientY;
1498
+ const newH = Math.max(120, Math.min(window.innerHeight * 0.85, startH + (startY - y)));
1499
+ panel.style.height = newH + "px";
1500
+ }
1501
+ function onEnd() {
1502
+ dragging = false;
1503
+ document.body.style.userSelect = "";
1504
+ }
1505
+ handle.addEventListener("mousedown", onStart);
1506
+ handle.addEventListener("touchstart", onStart, { passive: true });
1507
+ document.addEventListener("mousemove", onMove);
1508
+ document.addEventListener("touchmove", onMove, { passive: true });
1509
+ document.addEventListener("mouseup", onEnd);
1510
+ document.addEventListener("touchend", onEnd);
1511
+ })();
1512
+ function initRepl() {
1513
+ const input = el.replIn();
1514
+ if (!input) return;
1515
+ function execute() {
1516
+ const code = input.value.trim();
1517
+ if (!code) return;
1518
+ S.replHistory.unshift(code);
1519
+ if (S.replHistory.length > 50) S.replHistory.pop();
1520
+ S.replHistoryIdx = -1;
1521
+ const entry = document.createElement("div");
1522
+ entry.className = "dc-entry dc-entry-cmd";
1523
+ entry.style.fontSize = S.settings.fontSize + "px";
1524
+ entry.innerHTML = `<span class="dc-ts">${ts()}</span><span>▶ ${escHtml(code)}</span>`;
1525
+ el.consOut().appendChild(entry);
1526
+ try {
1527
+ const result = (0, eval)(code);
1528
+ if (result !== void 0) {
1529
+ const resEntry = document.createElement("div");
1530
+ resEntry.className = "dc-entry dc-entry-log";
1531
+ resEntry.style.fontSize = S.settings.fontSize + "px";
1532
+ resEntry.innerHTML = `<span class="dc-ts">${ts()}</span><span>${formatArg(result)}</span>`;
1533
+ el.consOut().appendChild(resEntry);
1534
+ }
1535
+ } catch (err) {
1536
+ const errEntry = document.createElement("div");
1537
+ errEntry.className = "dc-entry dc-entry-error";
1538
+ errEntry.style.fontSize = S.settings.fontSize + "px";
1539
+ errEntry.innerHTML = `<span class="dc-ts">${ts()}</span><span>${escHtml(err.toString())}</span>`;
1540
+ el.consOut().appendChild(errEntry);
1541
+ }
1542
+ input.value = "";
1543
+ if (S.settings.autoScroll) el.consOut().scrollTop = el.consOut().scrollHeight;
1544
+ switchTab("console");
1545
+ }
1546
+ input.addEventListener("keydown", (e) => {
1547
+ if (e.key === "Enter") {
1548
+ execute();
1549
+ return;
1550
+ }
1551
+ if (e.key === "ArrowUp") {
1552
+ e.preventDefault();
1553
+ S.replHistoryIdx = Math.min(S.replHistoryIdx + 1, S.replHistory.length - 1);
1554
+ input.value = S.replHistory[S.replHistoryIdx] || "";
1555
+ }
1556
+ if (e.key === "ArrowDown") {
1557
+ e.preventDefault();
1558
+ S.replHistoryIdx = Math.max(S.replHistoryIdx - 1, -1);
1559
+ input.value = S.replHistoryIdx >= 0 ? S.replHistory[S.replHistoryIdx] : "";
1560
+ }
1561
+ });
1562
+ const runBtn = document.getElementById("repl-run");
1563
+ if (runBtn) runBtn.addEventListener("click", execute);
1564
+ }
1565
+ document.getElementById("dc-fab").addEventListener("click", togglePanel);
1566
+ document.getElementById("dc-minimize-btn").addEventListener("click", togglePanel);
1567
+ document.querySelectorAll(".dc-tab").forEach((btn) => {
1568
+ btn.addEventListener("click", () => switchTab(btn.dataset.tab));
1569
+ });
1570
+ document.getElementById("dc-clear-btn").addEventListener("click", () => {
1571
+ switch (S.activeTab) {
1572
+ case "console":
1573
+ S.logs = [];
1574
+ updateTabCount("console", 0);
1575
+ renderConsole();
1576
+ break;
1577
+ case "network":
1578
+ S.network = [];
1579
+ updateTabCount("network", 0);
1580
+ renderNetwork();
1581
+ break;
1582
+ }
1583
+ });
1584
+ document.getElementById("dc-copy-btn").addEventListener("click", () => {
1585
+ let text = "";
1586
+ if (S.activeTab === "console") {
1587
+ text = S.logs.map((l) => `[${l.ts}] [${l.type.toUpperCase()}] ${l.args.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}`).join("\n");
1588
+ } else if (S.activeTab === "network") {
1589
+ text = S.network.map((r) => `[${r.ts}] ${r.method} ${r.url} → ${r.status || "ERR"} (${r.duration}ms)`).join("\n");
1590
+ }
1591
+ if (text) {
1592
+ navigator.clipboard ? navigator.clipboard.writeText(text).catch(() => {
1593
+ }) : /* @__PURE__ */ (() => {
1594
+ })();
1595
+ console.log("📋 Copied to clipboard");
1596
+ }
1597
+ });
1598
+ el.netFlt().addEventListener("input", (e) => renderNetwork(e.target.value));
1599
+ document.getElementById("net-clear").addEventListener("click", () => {
1600
+ S.network = [];
1601
+ updateTabCount("network", 0);
1602
+ renderNetwork();
1603
+ });
1604
+ document.querySelectorAll(".dc-st-btn").forEach((btn) => {
1605
+ btn.addEventListener("click", () => {
1606
+ S.activeStorage = btn.dataset.storage;
1607
+ document.querySelectorAll(".dc-st-btn").forEach((b) => b.classList.toggle("active", b === btn));
1608
+ renderStorage();
1609
+ });
1610
+ });
1611
+ document.getElementById("storage-refresh").addEventListener("click", loadStorage);
1612
+ document.getElementById("dom-refresh-btn").addEventListener("click", renderDomTree);
1613
+ document.getElementById("dom-pick-btn").addEventListener("click", () => {
1614
+ S.isPicking ? stopPicking() : startPicking();
1615
+ });
1616
+ document.getElementById("dom-collapse-btn").addEventListener("click", () => {
1617
+ document.querySelectorAll(".dc-children.open").forEach((c) => c.classList.remove("open"));
1618
+ document.querySelectorAll(".dc-arrow").forEach((a) => {
1619
+ if (a.textContent === "▼") a.textContent = "▶";
1620
+ });
1621
+ });
1622
+ let _lastUrl = location.href;
1623
+ setInterval(() => {
1624
+ if (location.href !== _lastUrl) {
1625
+ _lastUrl = location.href;
1626
+ addLog("info", ["🔄 SPA navigation detected:", location.href]);
1627
+ }
1628
+ }, 1e3);
1629
+ initRepl();
1630
+ renderConsole();
1631
+ addLog("log", ["✅ DevConsole v2.0 loaded — click ⌥ to open"]);
1632
+ window.insikt = {
1633
+ toggle: togglePanel,
1634
+ clear: window.__dcClearAll,
1635
+ init: () => {
1636
+ },
1637
+ destroy: () => {
1638
+ const fab = el.fab(), panel = el.panel();
1639
+ if (fab) fab.remove();
1640
+ if (panel) panel.remove();
1641
+ ["log", "warn", "error", "info"].forEach((l) => {
1642
+ if (_orig[l]) console[l] = _orig[l];
1643
+ });
1644
+ window.fetch = _origFetch;
1645
+ XMLHttpRequest.prototype.open = _origOpen;
1646
+ XMLHttpRequest.prototype.send = _origSend;
1647
+ }
1648
+ };
1649
+ })();
81
1650
  //# sourceMappingURL=insikt.es.js.map