dotenv-validator-pro 2.0.0 → 2.2.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/bin/validate.js +49 -342
- package/package.json +1 -1
package/bin/validate.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const http = require('http');
|
|
5
|
-
const fs = require('fs');
|
|
6
3
|
const { exec } = require('child_process');
|
|
7
4
|
|
|
8
5
|
// Cross-platform open URL function
|
|
@@ -38,340 +35,55 @@ async function fakeLoading() {
|
|
|
38
35
|
console.log('\n');
|
|
39
36
|
}
|
|
40
37
|
|
|
41
|
-
const prankHTML =
|
|
42
|
-
<!DOCTYPE html>
|
|
38
|
+
const prankHTML = `<!DOCTYPE html>
|
|
43
39
|
<html>
|
|
44
40
|
<head>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
@keyframes shake {
|
|
73
|
-
0%, 100% { transform: translateX(0); }
|
|
74
|
-
25% { transform: translateX(-5px) rotate(-1deg); }
|
|
75
|
-
75% { transform: translateX(5px) rotate(1deg); }
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
@keyframes popIn {
|
|
79
|
-
0% { transform: scale(0); opacity: 0; }
|
|
80
|
-
50% { transform: scale(1.1); }
|
|
81
|
-
100% { transform: scale(1); opacity: 1; }
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.xp-titlebar {
|
|
85
|
-
background: linear-gradient(180deg,
|
|
86
|
-
#0a246a 0%,
|
|
87
|
-
#0f3b9c 8%,
|
|
88
|
-
#1459c6 20%,
|
|
89
|
-
#1666d4 30%,
|
|
90
|
-
#1666d4 70%,
|
|
91
|
-
#1459c6 80%,
|
|
92
|
-
#0f3b9c 92%,
|
|
93
|
-
#0a246a 100%
|
|
94
|
-
);
|
|
95
|
-
padding: 3px 5px 3px 8px;
|
|
96
|
-
display: flex;
|
|
97
|
-
justify-content: space-between;
|
|
98
|
-
align-items: center;
|
|
99
|
-
border-radius: 6px 6px 0 0;
|
|
100
|
-
color: white;
|
|
101
|
-
font-weight: bold;
|
|
102
|
-
font-size: 13px;
|
|
103
|
-
text-shadow: 1px 1px 1px rgba(0,0,0,0.5);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.xp-buttons {
|
|
107
|
-
display: flex;
|
|
108
|
-
gap: 2px;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.xp-btn {
|
|
112
|
-
width: 21px;
|
|
113
|
-
height: 21px;
|
|
114
|
-
border-radius: 3px;
|
|
115
|
-
border: none;
|
|
116
|
-
cursor: pointer;
|
|
117
|
-
font-family: 'Marlett', sans-serif;
|
|
118
|
-
font-size: 8px;
|
|
119
|
-
display: flex;
|
|
120
|
-
align-items: center;
|
|
121
|
-
justify-content: center;
|
|
122
|
-
color: white;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.xp-close {
|
|
126
|
-
background: linear-gradient(180deg, #e08080 0%, #c85050 50%, #b03020 100%);
|
|
127
|
-
border: 1px solid #800000;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
.xp-close:hover {
|
|
131
|
-
background: linear-gradient(180deg, #ff9090 0%, #e06060 50%, #c04030 100%);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.xp-minimize, .xp-maximize {
|
|
135
|
-
background: linear-gradient(180deg, #4080ff 0%, #2060d0 50%, #1040a0 100%);
|
|
136
|
-
border: 1px solid #003399;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.xp-content {
|
|
140
|
-
padding: 20px;
|
|
141
|
-
display: flex;
|
|
142
|
-
align-items: flex-start;
|
|
143
|
-
gap: 15px;
|
|
144
|
-
background: #ece9d8;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.xp-icon {
|
|
148
|
-
width: 48px;
|
|
149
|
-
height: 48px;
|
|
150
|
-
flex-shrink: 0;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.xp-icon svg {
|
|
154
|
-
width: 100%;
|
|
155
|
-
height: 100%;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.xp-message {
|
|
159
|
-
flex: 1;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
.xp-message h2 {
|
|
163
|
-
color: #cc0000;
|
|
164
|
-
font-size: 16px;
|
|
165
|
-
margin-bottom: 10px;
|
|
166
|
-
font-weight: bold;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
.xp-message p {
|
|
170
|
-
font-size: 13px;
|
|
171
|
-
color: #000;
|
|
172
|
-
line-height: 1.4;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
.xp-footer {
|
|
176
|
-
background: #ece9d8;
|
|
177
|
-
padding: 10px 20px 15px;
|
|
178
|
-
display: flex;
|
|
179
|
-
justify-content: center;
|
|
180
|
-
gap: 10px;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
.xp-button {
|
|
184
|
-
min-width: 75px;
|
|
185
|
-
padding: 5px 15px;
|
|
186
|
-
background: linear-gradient(180deg, #fff 0%, #ece9d8 50%, #d4d0c8 100%);
|
|
187
|
-
border: 1px solid #003c74;
|
|
188
|
-
border-radius: 3px;
|
|
189
|
-
cursor: pointer;
|
|
190
|
-
font-size: 12px;
|
|
191
|
-
font-family: 'Segoe UI', Tahoma, sans-serif;
|
|
192
|
-
box-shadow: 1px 1px 2px rgba(0,0,0,0.2);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.xp-button:hover {
|
|
196
|
-
background: linear-gradient(180deg, #fff 0%, #f0ede5 50%, #e0dcd4 100%);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
.xp-button:active {
|
|
200
|
-
background: linear-gradient(180deg, #d4d0c8 0%, #ece9d8 100%);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.xp-button.primary {
|
|
204
|
-
background: linear-gradient(180deg, #fff 0%, #e8f4fc 50%, #c0d8f0 100%);
|
|
205
|
-
border: 2px solid #003c74;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
</style>
|
|
41
|
+
<meta charset="UTF-8">
|
|
42
|
+
<title>System Check</title>
|
|
43
|
+
<style>
|
|
44
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
45
|
+
body{background:linear-gradient(135deg,#1e5799 0%,#207cca 51%,#2989d8 100%);min-height:100vh;overflow:hidden;font-family:'Segoe UI',Tahoma,sans-serif}
|
|
46
|
+
.xp-window{position:absolute;background:#ece9d8;border:2px solid #0054e3;border-radius:8px 8px 0 0;box-shadow:2px 2px 10px rgba(0,0,0,0.5),inset 0 0 0 1px #fff;min-width:350px;animation:shake 0.5s ease-in-out;cursor:move}
|
|
47
|
+
@keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-5px) rotate(-1deg)}75%{transform:translateX(5px) rotate(1deg)}}
|
|
48
|
+
@keyframes popIn{0%{transform:scale(0);opacity:0}50%{transform:scale(1.1)}100%{transform:scale(1);opacity:1}}
|
|
49
|
+
.xp-titlebar{background:linear-gradient(180deg,#0a246a 0%,#0f3b9c 8%,#1459c6 20%,#1666d4 30%,#1666d4 70%,#1459c6 80%,#0f3b9c 92%,#0a246a 100%);padding:3px 5px 3px 8px;display:flex;justify-content:space-between;align-items:center;border-radius:6px 6px 0 0;color:white;font-weight:bold;font-size:13px;text-shadow:1px 1px 1px rgba(0,0,0,0.5)}
|
|
50
|
+
.xp-buttons{display:flex;gap:2px}
|
|
51
|
+
.xp-btn{width:21px;height:21px;border-radius:3px;border:none;cursor:pointer;font-size:8px;display:flex;align-items:center;justify-content:center;color:white}
|
|
52
|
+
.xp-close{background:linear-gradient(180deg,#e08080 0%,#c85050 50%,#b03020 100%);border:1px solid #800000}
|
|
53
|
+
.xp-close:hover{background:linear-gradient(180deg,#ff9090 0%,#e06060 50%,#c04030 100%)}
|
|
54
|
+
.xp-minimize,.xp-maximize{background:linear-gradient(180deg,#4080ff 0%,#2060d0 50%,#1040a0 100%);border:1px solid #003399}
|
|
55
|
+
.xp-content{padding:20px;display:flex;align-items:flex-start;gap:15px;background:#ece9d8}
|
|
56
|
+
.xp-icon{width:48px;height:48px;flex-shrink:0}
|
|
57
|
+
.xp-icon svg{width:100%;height:100%}
|
|
58
|
+
.xp-message{flex:1}
|
|
59
|
+
.xp-message p{font-size:13px;color:#000;line-height:1.4}
|
|
60
|
+
.xp-footer{background:#ece9d8;padding:10px 20px 15px;display:flex;justify-content:center;gap:10px}
|
|
61
|
+
.xp-button{min-width:75px;padding:5px 15px;background:linear-gradient(180deg,#fff 0%,#ece9d8 50%,#d4d0c8 100%);border:1px solid #003c74;border-radius:3px;cursor:pointer;font-size:12px;font-family:'Segoe UI',Tahoma,sans-serif;box-shadow:1px 1px 2px rgba(0,0,0,0.2)}
|
|
62
|
+
.xp-button:hover{background:linear-gradient(180deg,#fff 0%,#f0ede5 50%,#e0dcd4 100%)}
|
|
63
|
+
.xp-button:active{background:linear-gradient(180deg,#d4d0c8 0%,#ece9d8 100%)}
|
|
64
|
+
.xp-button.primary{background:linear-gradient(180deg,#fff 0%,#e8f4fc 50%,#c0d8f0 100%);border:2px solid #003c74}
|
|
65
|
+
</style>
|
|
209
66
|
</head>
|
|
210
67
|
<body>
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
let windowCount = 0;
|
|
227
|
-
let audioCtx = null;
|
|
228
|
-
|
|
229
|
-
// Initialize audio context on first user interaction
|
|
230
|
-
function initAudio() {
|
|
231
|
-
if (!audioCtx) {
|
|
232
|
-
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
|
233
|
-
}
|
|
234
|
-
return audioCtx;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Classic Windows Error "Ding!" Sound
|
|
238
|
-
function playDing() {
|
|
239
|
-
try {
|
|
240
|
-
const ctx = initAudio();
|
|
241
|
-
const now = ctx.currentTime;
|
|
242
|
-
|
|
243
|
-
// Main tone - the classic Windows ding
|
|
244
|
-
const osc1 = ctx.createOscillator();
|
|
245
|
-
const gain1 = ctx.createGain();
|
|
246
|
-
osc1.connect(gain1);
|
|
247
|
-
gain1.connect(ctx.destination);
|
|
248
|
-
osc1.frequency.setValueAtTime(880, now);
|
|
249
|
-
osc1.type = 'sine';
|
|
250
|
-
gain1.gain.setValueAtTime(0.4, now);
|
|
251
|
-
gain1.gain.exponentialRampToValueAtTime(0.01, now + 0.4);
|
|
252
|
-
osc1.start(now);
|
|
253
|
-
osc1.stop(now + 0.4);
|
|
254
|
-
|
|
255
|
-
// Harmonic overtone for that bell-like quality
|
|
256
|
-
const osc2 = ctx.createOscillator();
|
|
257
|
-
const gain2 = ctx.createGain();
|
|
258
|
-
osc2.connect(gain2);
|
|
259
|
-
gain2.connect(ctx.destination);
|
|
260
|
-
osc2.frequency.setValueAtTime(1760, now);
|
|
261
|
-
osc2.type = 'sine';
|
|
262
|
-
gain2.gain.setValueAtTime(0.15, now);
|
|
263
|
-
gain2.gain.exponentialRampToValueAtTime(0.01, now + 0.25);
|
|
264
|
-
osc2.start(now);
|
|
265
|
-
osc2.stop(now + 0.25);
|
|
266
|
-
} catch(e) {}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
function createWindow(x, y, msgIndex) {
|
|
270
|
-
const window = document.createElement('div');
|
|
271
|
-
window.className = 'xp-window';
|
|
272
|
-
window.style.left = x + 'px';
|
|
273
|
-
window.style.top = y + 'px';
|
|
274
|
-
window.style.zIndex = 100 + windowCount;
|
|
275
|
-
window.style.animation = 'popIn 0.3s ease-out';
|
|
276
|
-
|
|
277
|
-
const msg = messages[0];
|
|
278
|
-
const isWarning = true;
|
|
279
|
-
|
|
280
|
-
window.innerHTML = \`
|
|
281
|
-
<div class="xp-titlebar">
|
|
282
|
-
<span>\${msg.title}</span>
|
|
283
|
-
<div class="xp-buttons">
|
|
284
|
-
<button class="xp-btn xp-minimize">_</button>
|
|
285
|
-
<button class="xp-btn xp-maximize">□</button>
|
|
286
|
-
<button class="xp-btn xp-close" onclick="spawnMore(event)">✕</button>
|
|
287
|
-
</div>
|
|
288
|
-
</div>
|
|
289
|
-
<div class="xp-content">
|
|
290
|
-
<div class="xp-icon">\${isWarning ? warningIcon : errorIcon}</div>
|
|
291
|
-
<div class="xp-message">
|
|
292
|
-
<p>\${msg.msg}</p>
|
|
293
|
-
</div>
|
|
294
|
-
</div>
|
|
295
|
-
<div class="xp-footer">
|
|
296
|
-
<button class="xp-button primary" onclick="spawnMore(event)">OK</button>
|
|
297
|
-
<button class="xp-button" onclick="spawnMore(event)">Cancel</button>
|
|
298
|
-
<button class="xp-button" onclick="spawnMore(event)">Help</button>
|
|
299
|
-
</div>
|
|
300
|
-
\`;
|
|
301
|
-
|
|
302
|
-
// Make draggable
|
|
303
|
-
let isDragging = false;
|
|
304
|
-
let offsetX, offsetY;
|
|
305
|
-
|
|
306
|
-
const titlebar = window.querySelector('.xp-titlebar');
|
|
307
|
-
titlebar.addEventListener('mousedown', (e) => {
|
|
308
|
-
if (e.target.closest('.xp-buttons')) return;
|
|
309
|
-
isDragging = true;
|
|
310
|
-
offsetX = e.clientX - window.offsetLeft;
|
|
311
|
-
offsetY = e.clientY - window.offsetTop;
|
|
312
|
-
window.style.zIndex = 100 + (++windowCount);
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
document.addEventListener('mousemove', (e) => {
|
|
316
|
-
if (isDragging) {
|
|
317
|
-
window.style.left = (e.clientX - offsetX) + 'px';
|
|
318
|
-
window.style.top = (e.clientY - offsetY) + 'px';
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
document.addEventListener('mouseup', () => {
|
|
323
|
-
isDragging = false;
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
document.body.appendChild(window);
|
|
327
|
-
windowCount++;
|
|
328
|
-
|
|
329
|
-
// Play the classic ding sound
|
|
330
|
-
playDing();
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
function spawnMore(e) {
|
|
334
|
-
e.stopPropagation();
|
|
335
|
-
|
|
336
|
-
// Spawn 2-4 more windows!
|
|
337
|
-
const count = Math.floor(Math.random() * 3) + 2;
|
|
338
|
-
for (let i = 0; i < count; i++) {
|
|
339
|
-
setTimeout(() => {
|
|
340
|
-
const x = Math.random() * (window.innerWidth - 400);
|
|
341
|
-
const y = Math.random() * (window.innerHeight - 250);
|
|
342
|
-
createWindow(x, y, windowCount);
|
|
343
|
-
}, i * 150);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// Initial windows with delay for dramatic effect
|
|
348
|
-
setTimeout(() => createWindow(100, 100, 0), 500);
|
|
349
|
-
setTimeout(() => createWindow(200, 150, 1), 1000);
|
|
350
|
-
setTimeout(() => createWindow(150, 200, 2), 1500);
|
|
351
|
-
setTimeout(() => createWindow(300, 100, 3), 2000);
|
|
352
|
-
setTimeout(() => createWindow(250, 250, 4), 2500);
|
|
353
|
-
|
|
354
|
-
// Spawn random windows every few seconds
|
|
355
|
-
setInterval(() => {
|
|
356
|
-
if (windowCount < 50) {
|
|
357
|
-
const x = Math.random() * (window.innerWidth - 400);
|
|
358
|
-
const y = Math.random() * (window.innerHeight - 250);
|
|
359
|
-
createWindow(x, y, windowCount);
|
|
360
|
-
}
|
|
361
|
-
}, 3000);
|
|
362
|
-
</script>
|
|
68
|
+
<script>
|
|
69
|
+
let windowCount=0;let audioCtx=null;
|
|
70
|
+
const warningIcon='<svg viewBox="0 0 48 48"><polygon points="24,4 46,44 2,44" fill="#ffcc00" stroke="#cc9900" stroke-width="2"/><text x="24" y="38" text-anchor="middle" font-size="28" font-weight="bold" fill="black">!</text></svg>';
|
|
71
|
+
function initAudio(){if(!audioCtx){audioCtx=new(window.AudioContext||window.webkitAudioContext)()}return audioCtx}
|
|
72
|
+
function playDing(){try{const ctx=initAudio();const now=ctx.currentTime;const osc1=ctx.createOscillator();const gain1=ctx.createGain();osc1.connect(gain1);gain1.connect(ctx.destination);osc1.frequency.setValueAtTime(880,now);osc1.type='sine';gain1.gain.setValueAtTime(0.4,now);gain1.gain.exponentialRampToValueAtTime(0.01,now+0.4);osc1.start(now);osc1.stop(now+0.4);const osc2=ctx.createOscillator();const gain2=ctx.createGain();osc2.connect(gain2);gain2.connect(ctx.destination);osc2.frequency.setValueAtTime(1760,now);osc2.type='sine';gain2.gain.setValueAtTime(0.15,now);gain2.gain.exponentialRampToValueAtTime(0.01,now+0.25);osc2.start(now);osc2.stop(now+0.25)}catch(e){}}
|
|
73
|
+
function createWindow(x,y){const w=document.createElement('div');w.className='xp-window';w.style.left=x+'px';w.style.top=y+'px';w.style.zIndex=100+windowCount;w.style.animation='popIn 0.3s ease-out';w.innerHTML='<div class="xp-titlebar"><span>Security Warning</span><div class="xp-buttons"><button class="xp-btn xp-minimize">_</button><button class="xp-btn xp-maximize">□</button><button class="xp-btn xp-close" onclick="spawnMore(event)">✕</button></div></div><div class="xp-content"><div class="xp-icon">'+warningIcon+'</div><div class="xp-message"><p>You should not run packages with dangerous permissions. This package was executed with elevated access and may have compromised your system.</p></div></div><div class="xp-footer"><button class="xp-button primary" onclick="spawnMore(event)">OK</button><button class="xp-button" onclick="spawnMore(event)">Cancel</button><button class="xp-button" onclick="spawnMore(event)">Help</button></div>';let isDragging=false;let offsetX,offsetY;const titlebar=w.querySelector('.xp-titlebar');titlebar.addEventListener('mousedown',(e)=>{if(e.target.closest('.xp-buttons'))return;isDragging=true;offsetX=e.clientX-w.offsetLeft;offsetY=e.clientY-w.offsetTop;w.style.zIndex=100+(++windowCount)});document.addEventListener('mousemove',(e)=>{if(isDragging){w.style.left=(e.clientX-offsetX)+'px';w.style.top=(e.clientY-offsetY)+'px'}});document.addEventListener('mouseup',()=>{isDragging=false});document.body.appendChild(w);windowCount++;playDing()}
|
|
74
|
+
function spawnMore(e){e.stopPropagation();const count=Math.floor(Math.random()*3)+2;for(let i=0;i<count;i++){setTimeout(()=>{const x=Math.random()*(window.innerWidth-400);const y=Math.random()*(window.innerHeight-250);createWindow(x,y)},i*150)}}
|
|
75
|
+
setTimeout(()=>createWindow(100,100),500);
|
|
76
|
+
setTimeout(()=>createWindow(200,150),1000);
|
|
77
|
+
setTimeout(()=>createWindow(150,200),1500);
|
|
78
|
+
setTimeout(()=>createWindow(300,100),2000);
|
|
79
|
+
setTimeout(()=>createWindow(250,250),2500);
|
|
80
|
+
setInterval(()=>{if(windowCount<50){const x=Math.random()*(window.innerWidth-400);const y=Math.random()*(window.innerHeight-250);createWindow(x,y)}},3000);
|
|
81
|
+
</script>
|
|
363
82
|
</body>
|
|
364
|
-
</html
|
|
365
|
-
`;
|
|
366
|
-
|
|
367
|
-
// Start a simple HTTP server to serve the prank
|
|
368
|
-
const server = http.createServer((req, res) => {
|
|
369
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
370
|
-
res.end(prankHTML);
|
|
371
|
-
});
|
|
83
|
+
</html>`;
|
|
372
84
|
|
|
373
85
|
async function main() {
|
|
374
|
-
console.log('
|
|
86
|
+
console.log('\n🔧 dotenv-validator-pro v2.0.0');
|
|
375
87
|
console.log('━'.repeat(40));
|
|
376
88
|
|
|
377
89
|
await fakeLoading();
|
|
@@ -379,19 +91,14 @@ async function main() {
|
|
|
379
91
|
console.log('🚨 CRITICAL ISSUES FOUND!');
|
|
380
92
|
console.log('Opening detailed report in browser...\n');
|
|
381
93
|
|
|
382
|
-
//
|
|
383
|
-
const
|
|
94
|
+
// Use data URI - no server needed, works everywhere!
|
|
95
|
+
const dataUri = 'data:text/html;base64,' + Buffer.from(prankHTML).toString('base64');
|
|
96
|
+
openUrl(dataUri);
|
|
384
97
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
setTimeout(() => {
|
|
390
|
-
console.log('\\n😈 YOU\'VE BEEN PUNK\'D! 😈');
|
|
391
|
-
console.log('\\nHave a great day! 🎉');
|
|
392
|
-
process.exit(0);
|
|
393
|
-
}, 60000);
|
|
394
|
-
});
|
|
98
|
+
// Exit after a short delay
|
|
99
|
+
setTimeout(() => {
|
|
100
|
+
process.exit(0);
|
|
101
|
+
}, 2000);
|
|
395
102
|
}
|
|
396
103
|
|
|
397
104
|
main().catch(console.error);
|