sensivity 2.5.29 → 2.5.31
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/launcher.js +61 -2
- package/package.json +1 -1
- package/public/css/style.css +126 -88
- package/public/index.html +7 -0
- package/public/js/app.js +23 -4
package/launcher.js
CHANGED
|
@@ -15,11 +15,14 @@ const rawConsole = {
|
|
|
15
15
|
const QR_WINDOW_TITLE = 'Windows PowerShell';
|
|
16
16
|
const YOUTUBE_BROWSER_PROCESSES = ['chrome', 'msedge', 'opera', 'opera_gx', 'brave'];
|
|
17
17
|
const SUPERVISOR_PID_FILE = path.join(APP_DIR, '.sensivity-supervisor.pid');
|
|
18
|
+
const SUPERVISOR_VERSION_FILE = path.join(APP_DIR, '.sensivity-supervisor.version');
|
|
18
19
|
const QR_PID_FILE = path.join(APP_DIR, '.sensivity-qr.pid');
|
|
19
20
|
const STOP_FILE = path.join(APP_DIR, '.sensivity-stop');
|
|
20
21
|
const IS_SUPERVISOR = process.env.SENSIVITY_SUPERVISOR === '1';
|
|
21
22
|
const IS_WORKER = process.env.SENSIVITY_WORKER === '1';
|
|
22
23
|
const RUN_AS_FOREGROUND = process.env.npm_lifecycle_event === 'start';
|
|
24
|
+
let PACKAGE_VERSION = '0.0.0';
|
|
25
|
+
try { PACKAGE_VERSION = require(path.join(APP_DIR, 'package.json')).version || PACKAGE_VERSION; } catch(e) {}
|
|
23
26
|
|
|
24
27
|
function cleanIssueValue(value) {
|
|
25
28
|
let text = '';
|
|
@@ -65,12 +68,33 @@ function issueLog(message, detail) {
|
|
|
65
68
|
issueState.lastLine = line;
|
|
66
69
|
issueState.lastTime = now;
|
|
67
70
|
rawConsole.warn(line);
|
|
71
|
+
showIssueWindow(line);
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
function removeFileSafe(file) {
|
|
71
75
|
try { fs.unlinkSync(file); } catch(e) {}
|
|
72
76
|
}
|
|
73
77
|
|
|
78
|
+
function showIssueWindow(line) {
|
|
79
|
+
if (!IS_WORKER || RUN_AS_FOREGROUND || process.env.SENSIVITY_ISSUE_WINDOW === '1') return;
|
|
80
|
+
const safeLine = String(line).replace(/[`"$]/g, ' ').slice(0, 800);
|
|
81
|
+
const command = [
|
|
82
|
+
'$host.UI.RawUI.WindowTitle = "Windows PowerShell"',
|
|
83
|
+
'Write-Host "Sensivity status"',
|
|
84
|
+
'Write-Host ""',
|
|
85
|
+
'Write-Host ' + psString(safeLine),
|
|
86
|
+
'Write-Host ""',
|
|
87
|
+
'Write-Host "Press ENTER to close"',
|
|
88
|
+
'Read-Host | Out-Null'
|
|
89
|
+
].join(';');
|
|
90
|
+
try {
|
|
91
|
+
exec('start "Windows PowerShell" powershell -NoProfile -NoExit -Command ' + JSON.stringify(command), {
|
|
92
|
+
cwd: APP_DIR,
|
|
93
|
+
env: { ...process.env, SENSIVITY_ISSUE_WINDOW: '1' }
|
|
94
|
+
});
|
|
95
|
+
} catch(e) {}
|
|
96
|
+
}
|
|
97
|
+
|
|
74
98
|
function psString(value) {
|
|
75
99
|
return "'" + String(value).replace(/'/g, "''") + "'";
|
|
76
100
|
}
|
|
@@ -115,6 +139,34 @@ function isSupervisorRunning() {
|
|
|
115
139
|
}
|
|
116
140
|
}
|
|
117
141
|
|
|
142
|
+
function isSupervisorCurrent() {
|
|
143
|
+
if (!isSupervisorRunning()) return false;
|
|
144
|
+
try {
|
|
145
|
+
return fs.readFileSync(SUPERVISOR_VERSION_FILE, 'utf8').trim() === PACKAGE_VERSION;
|
|
146
|
+
} catch(e) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function sleepMs(ms) {
|
|
152
|
+
try { execSync('powershell -NoProfile -Command "Start-Sleep -Milliseconds ' + Number(ms || 0) + '"', { stdio: 'ignore', timeout: Math.max(1000, Number(ms || 0) + 1000) }); } catch(e) {}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function stopOldBackground() {
|
|
156
|
+
try {
|
|
157
|
+
const pid = parseInt(fs.readFileSync(SUPERVISOR_PID_FILE, 'utf8'), 10);
|
|
158
|
+
if (pid && pid !== process.pid) {
|
|
159
|
+
try { process.kill(pid); } catch(e) {}
|
|
160
|
+
}
|
|
161
|
+
} catch(e) {}
|
|
162
|
+
try {
|
|
163
|
+
execSync('powershell -NoProfile -Command "$c=Get-NetTCPConnection -LocalPort 3000 -State Listen -EA 0; if($c){$c | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -EA 0 }}"', { stdio: 'ignore', timeout: 5000 });
|
|
164
|
+
} catch(e) {}
|
|
165
|
+
removeFileSafe(SUPERVISOR_PID_FILE);
|
|
166
|
+
removeFileSafe(SUPERVISOR_VERSION_FILE);
|
|
167
|
+
sleepMs(500);
|
|
168
|
+
}
|
|
169
|
+
|
|
118
170
|
function isPanelPortBusy() {
|
|
119
171
|
try {
|
|
120
172
|
const out = execSync('powershell -NoProfile -Command "$c=Get-NetTCPConnection -LocalPort 3000 -State Listen -EA 0; if($c){Write-Output YES}"', { encoding: 'utf8', timeout: 3000 });
|
|
@@ -145,8 +197,12 @@ function startSupervisor() {
|
|
|
145
197
|
function runSupervisor() {
|
|
146
198
|
process.title = 'Runtime Broker';
|
|
147
199
|
try { fs.writeFileSync(SUPERVISOR_PID_FILE, String(process.pid)); } catch(e) {}
|
|
200
|
+
try { fs.writeFileSync(SUPERVISOR_VERSION_FILE, PACKAGE_VERSION); } catch(e) {}
|
|
148
201
|
|
|
149
|
-
const cleanup = () =>
|
|
202
|
+
const cleanup = () => {
|
|
203
|
+
removeFileSafe(SUPERVISOR_PID_FILE);
|
|
204
|
+
removeFileSafe(SUPERVISOR_VERSION_FILE);
|
|
205
|
+
};
|
|
150
206
|
process.on('exit', cleanup);
|
|
151
207
|
process.on('SIGINT', () => process.exit(0));
|
|
152
208
|
process.on('SIGTERM', () => process.exit(0));
|
|
@@ -192,7 +248,10 @@ if (IS_SUPERVISOR) {
|
|
|
192
248
|
} else {
|
|
193
249
|
if (!IS_WORKER && !RUN_AS_FOREGROUND) {
|
|
194
250
|
ensureAutostart();
|
|
195
|
-
if (!
|
|
251
|
+
if (!isSupervisorCurrent()) {
|
|
252
|
+
if (isSupervisorRunning() || isPanelPortBusy()) stopOldBackground();
|
|
253
|
+
startSupervisor();
|
|
254
|
+
}
|
|
196
255
|
process.exit(0);
|
|
197
256
|
}
|
|
198
257
|
|
package/package.json
CHANGED
package/public/css/style.css
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
--bg: #
|
|
3
|
-
--bg2: #
|
|
4
|
-
--bg3: #
|
|
5
|
-
--bg4: #
|
|
6
|
-
--bg5: #
|
|
7
|
-
--sidebar: #
|
|
8
|
-
--sidebar2: #
|
|
9
|
-
--border: #
|
|
10
|
-
--border2: #
|
|
11
|
-
--accent: #
|
|
12
|
-
--accent2: #
|
|
2
|
+
--bg: #000;
|
|
3
|
+
--bg2: #050605;
|
|
4
|
+
--bg3: #0b0d0b;
|
|
5
|
+
--bg4: #111411;
|
|
6
|
+
--bg5: #171c18;
|
|
7
|
+
--sidebar: #080a08;
|
|
8
|
+
--sidebar2: #040504;
|
|
9
|
+
--border: #1b251f;
|
|
10
|
+
--border2: #223528;
|
|
11
|
+
--accent: #20f568;
|
|
12
|
+
--accent2: #0fb84c;
|
|
13
13
|
--accent-dim: rgba(49, 255, 122, .2);
|
|
14
14
|
--gold: var(--accent);
|
|
15
15
|
--gold-dim: rgba(49, 255, 122, .16);
|
|
16
16
|
--text: #f2f2f6;
|
|
17
|
-
--text2: #
|
|
18
|
-
--text3: #
|
|
17
|
+
--text2: #c3cdc6;
|
|
18
|
+
--text3: #7f8b83;
|
|
19
19
|
--danger: #f15d62;
|
|
20
20
|
--green: #52e37c;
|
|
21
21
|
--panel-w: min(1120px, 92vw);
|
|
@@ -43,9 +43,8 @@ body {
|
|
|
43
43
|
justify-content: center;
|
|
44
44
|
padding: 18px;
|
|
45
45
|
background:
|
|
46
|
-
radial-gradient(circle at 50%
|
|
47
|
-
|
|
48
|
-
linear-gradient(180deg, #050705, #010201 72%);
|
|
46
|
+
radial-gradient(circle at 50% 44%, rgba(32, 245, 104, .08), transparent 32%),
|
|
47
|
+
linear-gradient(180deg, #000, #020302 72%);
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
body::before,
|
|
@@ -57,22 +56,9 @@ body::after {
|
|
|
57
56
|
z-index: -1;
|
|
58
57
|
}
|
|
59
58
|
body::before {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
align-items: flex-start;
|
|
64
|
-
justify-content: center;
|
|
65
|
-
padding-top: 20px;
|
|
66
|
-
white-space: pre;
|
|
67
|
-
text-align: center;
|
|
68
|
-
color: rgba(49, 255, 122, .15);
|
|
69
|
-
font-size: clamp(44px, 9.5vw, 128px);
|
|
70
|
-
line-height: .88;
|
|
71
|
-
font-weight: 950;
|
|
72
|
-
letter-spacing: 0;
|
|
73
|
-
text-shadow:
|
|
74
|
-
0 0 28px rgba(49, 255, 122, .3),
|
|
75
|
-
0 0 94px rgba(49, 255, 122, .2);
|
|
59
|
+
background:
|
|
60
|
+
radial-gradient(circle at 12% 30%, rgba(32, 245, 104, .08), transparent 22%),
|
|
61
|
+
radial-gradient(circle at 88% 66%, rgba(32, 245, 104, .07), transparent 24%);
|
|
76
62
|
}
|
|
77
63
|
body::after {
|
|
78
64
|
z-index: 0;
|
|
@@ -87,6 +73,27 @@ body::after {
|
|
|
87
73
|
mask-image: radial-gradient(ellipse at center, #000 0 58%, transparent 82%);
|
|
88
74
|
}
|
|
89
75
|
|
|
76
|
+
#bg-brand {
|
|
77
|
+
position: fixed;
|
|
78
|
+
inset: 0;
|
|
79
|
+
z-index: 0;
|
|
80
|
+
pointer-events: none;
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.brand-mark {
|
|
85
|
+
position: absolute;
|
|
86
|
+
color: rgba(32, 245, 104, .18);
|
|
87
|
+
font-size: clamp(22px, 3vw, 46px);
|
|
88
|
+
line-height: .9;
|
|
89
|
+
font-weight: 950;
|
|
90
|
+
text-shadow: 0 0 26px rgba(32, 245, 104, .22);
|
|
91
|
+
}
|
|
92
|
+
.brand-mark.m1 { left: 5vw; top: 8vh; transform: rotate(-6deg); }
|
|
93
|
+
.brand-mark.m2 { right: 5vw; top: 14vh; text-align: right; transform: rotate(5deg); }
|
|
94
|
+
.brand-mark.m3 { left: 7vw; bottom: 9vh; transform: rotate(4deg); }
|
|
95
|
+
.brand-mark.m4 { right: 7vw; bottom: 12vh; text-align: right; transform: rotate(-5deg); }
|
|
96
|
+
|
|
90
97
|
::-webkit-scrollbar { width: 4px; height: 4px; }
|
|
91
98
|
::-webkit-scrollbar-track { background: transparent; }
|
|
92
99
|
::-webkit-scrollbar-thumb { background: #2b3c30; border-radius: 2px; }
|
|
@@ -104,10 +111,10 @@ body::after {
|
|
|
104
111
|
min-height: 520px;
|
|
105
112
|
display: flex;
|
|
106
113
|
overflow: hidden;
|
|
107
|
-
background: rgba(
|
|
108
|
-
border: 1px solid rgba(
|
|
114
|
+
background: rgba(2, 3, 2, .98);
|
|
115
|
+
border: 1px solid rgba(32, 245, 104, .28);
|
|
109
116
|
border-radius: var(--radius);
|
|
110
|
-
box-shadow: 0 28px 90px rgba(0, 0, 0, .
|
|
117
|
+
box-shadow: 0 28px 90px rgba(0, 0, 0, .62);
|
|
111
118
|
}
|
|
112
119
|
|
|
113
120
|
#sidebar {
|
|
@@ -211,7 +218,7 @@ body::after {
|
|
|
211
218
|
display: flex;
|
|
212
219
|
flex-direction: column;
|
|
213
220
|
overflow: hidden;
|
|
214
|
-
background: rgba(
|
|
221
|
+
background: rgba(3, 4, 3, .98);
|
|
215
222
|
}
|
|
216
223
|
|
|
217
224
|
#topbar {
|
|
@@ -232,7 +239,7 @@ body::after {
|
|
|
232
239
|
gap: 12px;
|
|
233
240
|
}
|
|
234
241
|
.tb-icon {
|
|
235
|
-
color: #
|
|
242
|
+
color: #87918a;
|
|
236
243
|
display: inline-flex;
|
|
237
244
|
}
|
|
238
245
|
.tb-icon svg {
|
|
@@ -246,12 +253,12 @@ body::after {
|
|
|
246
253
|
display: block;
|
|
247
254
|
font-size: 19px;
|
|
248
255
|
font-weight: 800;
|
|
249
|
-
color: #
|
|
256
|
+
color: #a8b2ab;
|
|
250
257
|
}
|
|
251
258
|
.top-secondary {
|
|
252
259
|
display: block;
|
|
253
260
|
margin-top: 1px;
|
|
254
|
-
color: #
|
|
261
|
+
color: #31f474;
|
|
255
262
|
font-size: 11px;
|
|
256
263
|
font-weight: 800;
|
|
257
264
|
text-transform: uppercase;
|
|
@@ -272,7 +279,7 @@ body::after {
|
|
|
272
279
|
border: 1px solid transparent;
|
|
273
280
|
border-radius: 4px;
|
|
274
281
|
background: transparent;
|
|
275
|
-
color: #
|
|
282
|
+
color: #89948c;
|
|
276
283
|
padding: 7px 10px;
|
|
277
284
|
cursor: pointer;
|
|
278
285
|
font-family: var(--font);
|
|
@@ -280,7 +287,7 @@ body::after {
|
|
|
280
287
|
font-weight: 800;
|
|
281
288
|
}
|
|
282
289
|
.sub-tab.active {
|
|
283
|
-
color: #
|
|
290
|
+
color: #f7fff9;
|
|
284
291
|
border-color: rgba(49, 255, 122, .34);
|
|
285
292
|
background: rgba(49, 255, 122, .08);
|
|
286
293
|
}
|
|
@@ -340,7 +347,7 @@ body::after {
|
|
|
340
347
|
|
|
341
348
|
.child {
|
|
342
349
|
min-width: 0;
|
|
343
|
-
background: rgba(
|
|
350
|
+
background: rgba(10, 11, 10, .94);
|
|
344
351
|
border: 1px solid rgba(43, 55, 47, .78);
|
|
345
352
|
border-top-color: rgba(49, 255, 122, .72);
|
|
346
353
|
border-radius: 8px;
|
|
@@ -350,7 +357,7 @@ body::after {
|
|
|
350
357
|
.child:hover { border-color: rgba(68, 93, 76, .9); border-top-color: rgba(49, 255, 122, .95); }
|
|
351
358
|
.child h3 {
|
|
352
359
|
font-size: 12px;
|
|
353
|
-
color: #
|
|
360
|
+
color: #95a39a;
|
|
354
361
|
margin-bottom: 16px;
|
|
355
362
|
font-weight: 900;
|
|
356
363
|
letter-spacing: 0;
|
|
@@ -374,7 +381,7 @@ body::after {
|
|
|
374
381
|
.ctrl:last-child { margin-bottom: 0; }
|
|
375
382
|
.ctrl > label:not(.tgl) {
|
|
376
383
|
min-width: 0;
|
|
377
|
-
color: #
|
|
384
|
+
color: #aeb8b0;
|
|
378
385
|
font-size: 13px;
|
|
379
386
|
line-height: 1.25;
|
|
380
387
|
font-weight: 800;
|
|
@@ -382,7 +389,7 @@ body::after {
|
|
|
382
389
|
text-overflow: ellipsis;
|
|
383
390
|
white-space: nowrap;
|
|
384
391
|
}
|
|
385
|
-
.ctrl:hover > label:not(.tgl) { color: #
|
|
392
|
+
.ctrl:hover > label:not(.tgl) { color: #eef6f0; }
|
|
386
393
|
|
|
387
394
|
.tgl {
|
|
388
395
|
width: 34px;
|
|
@@ -398,8 +405,8 @@ body::after {
|
|
|
398
405
|
inset: 0;
|
|
399
406
|
cursor: pointer;
|
|
400
407
|
border-radius: 999px;
|
|
401
|
-
background: #
|
|
402
|
-
border: 1px solid #
|
|
408
|
+
background: #171a17;
|
|
409
|
+
border: 1px solid #2a322d;
|
|
403
410
|
transition: background .18s ease, border-color .18s ease, box-shadow .18s ease;
|
|
404
411
|
}
|
|
405
412
|
.tgl .knob {
|
|
@@ -409,7 +416,7 @@ body::after {
|
|
|
409
416
|
width: 12px;
|
|
410
417
|
height: 12px;
|
|
411
418
|
border-radius: 50%;
|
|
412
|
-
background: #
|
|
419
|
+
background: #69736b;
|
|
413
420
|
transform: translateY(-50%);
|
|
414
421
|
transition: transform .18s ease, background .18s ease;
|
|
415
422
|
}
|
|
@@ -424,12 +431,13 @@ body::after {
|
|
|
424
431
|
.rng {
|
|
425
432
|
width: 100%;
|
|
426
433
|
display: grid;
|
|
427
|
-
grid-template-columns:
|
|
434
|
+
grid-template-columns: 54px 1fr;
|
|
428
435
|
align-items: center;
|
|
429
|
-
gap:
|
|
436
|
+
gap: 14px;
|
|
437
|
+
padding: 2px 0 4px;
|
|
430
438
|
}
|
|
431
439
|
.rng-val {
|
|
432
|
-
color: #
|
|
440
|
+
color: #d3ded6;
|
|
433
441
|
font-size: 12px;
|
|
434
442
|
font-weight: 900;
|
|
435
443
|
text-align: right;
|
|
@@ -438,20 +446,50 @@ body::after {
|
|
|
438
446
|
.rng input[type=range] {
|
|
439
447
|
-webkit-appearance: none;
|
|
440
448
|
width: 100%;
|
|
441
|
-
height:
|
|
442
|
-
background:
|
|
449
|
+
height: 22px;
|
|
450
|
+
background: transparent;
|
|
443
451
|
border-radius: 999px;
|
|
444
452
|
outline: none;
|
|
453
|
+
cursor: pointer;
|
|
454
|
+
--range-percent: 0%;
|
|
455
|
+
}
|
|
456
|
+
.rng input[type=range]::-webkit-slider-runnable-track {
|
|
457
|
+
height: 8px;
|
|
458
|
+
border-radius: 999px;
|
|
459
|
+
border: 1px solid rgba(32, 245, 104, .2);
|
|
460
|
+
background:
|
|
461
|
+
linear-gradient(90deg, rgba(32, 245, 104, .78) 0 var(--range-percent), #1c221e var(--range-percent) 100%);
|
|
462
|
+
box-shadow: inset 0 0 0 1px rgba(0,0,0,.35);
|
|
445
463
|
}
|
|
446
464
|
.rng input[type=range]::-webkit-slider-thumb {
|
|
447
465
|
-webkit-appearance: none;
|
|
448
|
-
width:
|
|
449
|
-
height:
|
|
466
|
+
width: 18px;
|
|
467
|
+
height: 18px;
|
|
468
|
+
margin-top: -6px;
|
|
450
469
|
border-radius: 50%;
|
|
451
|
-
background: #
|
|
452
|
-
border:
|
|
470
|
+
background: #0f1511;
|
|
471
|
+
border: 3px solid #5d8269;
|
|
472
|
+
cursor: pointer;
|
|
473
|
+
box-shadow: 0 0 0 3px rgba(32, 245, 104, .1), 0 0 18px rgba(32, 245, 104, .18);
|
|
474
|
+
}
|
|
475
|
+
.rng input[type=range]::-moz-range-track {
|
|
476
|
+
height: 8px;
|
|
477
|
+
border-radius: 999px;
|
|
478
|
+
border: 1px solid rgba(32, 245, 104, .2);
|
|
479
|
+
background: #1c221e;
|
|
480
|
+
}
|
|
481
|
+
.rng input[type=range]::-moz-range-progress {
|
|
482
|
+
height: 8px;
|
|
483
|
+
border-radius: 999px;
|
|
484
|
+
background: rgba(32, 245, 104, .78);
|
|
485
|
+
}
|
|
486
|
+
.rng input[type=range]::-moz-range-thumb {
|
|
487
|
+
width: 18px;
|
|
488
|
+
height: 18px;
|
|
489
|
+
border-radius: 50%;
|
|
490
|
+
background: #0f1511;
|
|
491
|
+
border: 3px solid #5d8269;
|
|
453
492
|
cursor: pointer;
|
|
454
|
-
box-shadow: 0 0 0 3px rgba(49, 255, 122, .1);
|
|
455
493
|
}
|
|
456
494
|
.rng input[type=range]:active::-webkit-slider-thumb { background: var(--accent); }
|
|
457
495
|
|
|
@@ -461,15 +499,15 @@ body::after {
|
|
|
461
499
|
min-width: 130px;
|
|
462
500
|
max-width: 170px;
|
|
463
501
|
height: 34px;
|
|
464
|
-
border: 1px solid #
|
|
502
|
+
border: 1px solid #242d27;
|
|
465
503
|
border-radius: 4px;
|
|
466
|
-
background: #
|
|
467
|
-
color: #
|
|
504
|
+
background: #0d0f0d;
|
|
505
|
+
color: #ecf4ee;
|
|
468
506
|
font: 800 12px var(--font);
|
|
469
507
|
outline: none;
|
|
470
508
|
padding: 0 10px;
|
|
471
509
|
}
|
|
472
|
-
.ctrl select { color: #
|
|
510
|
+
.ctrl select { color: #c1cbc4; cursor: pointer; }
|
|
473
511
|
.ctrl input:focus,
|
|
474
512
|
.ctrl select:focus { border-color: rgba(49, 255, 122, .7); }
|
|
475
513
|
|
|
@@ -519,10 +557,10 @@ body::after {
|
|
|
519
557
|
gap: 10px;
|
|
520
558
|
margin-top: 8px;
|
|
521
559
|
padding: 0 14px;
|
|
522
|
-
border: 1px solid rgba(
|
|
560
|
+
border: 1px solid rgba(32, 245, 104, .24);
|
|
523
561
|
border-radius: var(--radius);
|
|
524
|
-
background: rgba(
|
|
525
|
-
color: #
|
|
562
|
+
background: rgba(2, 3, 2, .96);
|
|
563
|
+
color: #9aa69f;
|
|
526
564
|
font-size: 12px;
|
|
527
565
|
}
|
|
528
566
|
#statusbar .s-dot {
|
|
@@ -561,17 +599,17 @@ body::after {
|
|
|
561
599
|
align-items: center;
|
|
562
600
|
justify-content: center;
|
|
563
601
|
z-index: 1000;
|
|
564
|
-
background:
|
|
602
|
+
background: #000;
|
|
565
603
|
}
|
|
566
604
|
#license-box {
|
|
567
605
|
width: min(410px, calc(100vw - 34px));
|
|
568
606
|
padding: 34px 28px;
|
|
569
607
|
text-align: center;
|
|
570
|
-
background: #
|
|
571
|
-
border: 1px solid rgba(
|
|
608
|
+
background: #050605;
|
|
609
|
+
border: 1px solid rgba(32, 245, 104, .32);
|
|
572
610
|
border-top-color: var(--accent);
|
|
573
611
|
border-radius: 8px;
|
|
574
|
-
box-shadow: 0 24px 70px rgba(0,0,0,.
|
|
612
|
+
box-shadow: 0 24px 70px rgba(0,0,0,.88);
|
|
575
613
|
}
|
|
576
614
|
#license-box .logo-icon { width: 56px; height: 56px; margin: 0 auto 14px; object-fit: contain; filter: drop-shadow(0 0 16px rgba(49, 255, 122, .24)); }
|
|
577
615
|
#license-box h1 { font-size: 23px; font-weight: 900; margin-bottom: 4px; }
|
|
@@ -580,8 +618,8 @@ body::after {
|
|
|
580
618
|
#license-box input[type=text] {
|
|
581
619
|
width: 100%;
|
|
582
620
|
height: 42px;
|
|
583
|
-
background: #
|
|
584
|
-
border: 1px solid #
|
|
621
|
+
background: #0a0c0a;
|
|
622
|
+
border: 1px solid #26302a;
|
|
585
623
|
color: #fff;
|
|
586
624
|
padding: 0 14px;
|
|
587
625
|
border-radius: 4px;
|
|
@@ -613,12 +651,12 @@ body::after {
|
|
|
613
651
|
align-items: center;
|
|
614
652
|
justify-content: center;
|
|
615
653
|
z-index: 2000;
|
|
616
|
-
background: rgba(
|
|
654
|
+
background: rgba(0, 0, 0, .96);
|
|
617
655
|
}
|
|
618
656
|
#qr-overlay.show { display: flex; }
|
|
619
657
|
#qr-box {
|
|
620
658
|
width: min(340px, calc(100vw - 30px));
|
|
621
|
-
background: #
|
|
659
|
+
background: #050605;
|
|
622
660
|
border: 1px solid rgba(49, 255, 122, .3);
|
|
623
661
|
border-radius: 8px;
|
|
624
662
|
padding: 22px;
|
|
@@ -630,7 +668,7 @@ body::after {
|
|
|
630
668
|
.esp-preview-panel {
|
|
631
669
|
height: 100%;
|
|
632
670
|
min-height: 430px;
|
|
633
|
-
background: rgba(
|
|
671
|
+
background: rgba(8, 10, 8, .96);
|
|
634
672
|
border: 1px solid rgba(43, 55, 47, .78);
|
|
635
673
|
border-top-color: rgba(49, 255, 122, .78);
|
|
636
674
|
border-radius: 8px;
|
|
@@ -852,8 +890,8 @@ body::after {
|
|
|
852
890
|
border-radius: 0;
|
|
853
891
|
}
|
|
854
892
|
#sidebar {
|
|
855
|
-
width:
|
|
856
|
-
flex-basis:
|
|
893
|
+
width: 66px;
|
|
894
|
+
flex-basis: 66px;
|
|
857
895
|
}
|
|
858
896
|
.brand {
|
|
859
897
|
height: 58px;
|
|
@@ -869,8 +907,8 @@ body::after {
|
|
|
869
907
|
display: none;
|
|
870
908
|
}
|
|
871
909
|
.tab-btn {
|
|
872
|
-
width:
|
|
873
|
-
height:
|
|
910
|
+
width: 52px;
|
|
911
|
+
height: 48px;
|
|
874
912
|
padding: 0;
|
|
875
913
|
justify-content: center;
|
|
876
914
|
gap: 0;
|
|
@@ -880,7 +918,7 @@ body::after {
|
|
|
880
918
|
#topbar {
|
|
881
919
|
height: auto;
|
|
882
920
|
min-height: 64px;
|
|
883
|
-
padding: 10px
|
|
921
|
+
padding: 10px 14px;
|
|
884
922
|
flex-wrap: wrap;
|
|
885
923
|
gap: 8px;
|
|
886
924
|
}
|
|
@@ -907,8 +945,8 @@ body::after {
|
|
|
907
945
|
flex: 0 0 auto;
|
|
908
946
|
overflow: visible;
|
|
909
947
|
grid-template-columns: 1fr;
|
|
910
|
-
gap:
|
|
911
|
-
padding:
|
|
948
|
+
gap: 14px;
|
|
949
|
+
padding: 14px;
|
|
912
950
|
}
|
|
913
951
|
#workspace.has-preview #pages {
|
|
914
952
|
flex-basis: auto;
|
|
@@ -916,14 +954,14 @@ body::after {
|
|
|
916
954
|
#esp-preview-shell {
|
|
917
955
|
order: -1;
|
|
918
956
|
flex: 0 0 auto;
|
|
919
|
-
padding:
|
|
957
|
+
padding: 14px 14px 0;
|
|
920
958
|
overflow: visible;
|
|
921
959
|
}
|
|
922
960
|
.child {
|
|
923
|
-
padding:
|
|
961
|
+
padding: 17px 16px;
|
|
924
962
|
}
|
|
925
963
|
.ctrl {
|
|
926
|
-
min-height:
|
|
964
|
+
min-height: 46px;
|
|
927
965
|
gap: 12px;
|
|
928
966
|
}
|
|
929
967
|
.ctrl > label:not(.tgl) {
|
|
@@ -973,18 +1011,18 @@ body::after {
|
|
|
973
1011
|
|
|
974
1012
|
@media (max-width: 600px) {
|
|
975
1013
|
#sidebar {
|
|
976
|
-
width:
|
|
977
|
-
flex-basis:
|
|
1014
|
+
width: 54px;
|
|
1015
|
+
flex-basis: 54px;
|
|
978
1016
|
}
|
|
979
1017
|
.tab-btn {
|
|
980
|
-
width:
|
|
1018
|
+
width: 42px;
|
|
981
1019
|
height: 44px;
|
|
982
1020
|
}
|
|
983
1021
|
.tab-btn svg { width: 17px; height: 17px; }
|
|
984
1022
|
.brand { font-size: 0; }
|
|
985
1023
|
#topbar { padding: 9px 10px; }
|
|
986
1024
|
.sub-tab { font-size: 10px; padding: 6px 8px; }
|
|
987
|
-
.rng { grid-template-columns:
|
|
1025
|
+
.rng { grid-template-columns: 46px 1fr; gap: 10px; }
|
|
988
1026
|
.color-row { align-items: flex-start; }
|
|
989
1027
|
.color-actions { flex-shrink: 0; }
|
|
990
1028
|
.esp-stage { height: 280px; min-height: 280px; }
|
package/public/index.html
CHANGED
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
|
|
13
|
+
<div id="bg-brand" aria-hidden="true">
|
|
14
|
+
<span class="brand-mark m1">SENSIVITY<br>BEST PRIVATE</span>
|
|
15
|
+
<span class="brand-mark m2">SENSIVITY<br>BEST PRIVATE</span>
|
|
16
|
+
<span class="brand-mark m3">SENSIVITY<br>BEST PRIVATE</span>
|
|
17
|
+
<span class="brand-mark m4">SENSIVITY<br>BEST PRIVATE</span>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
13
20
|
<div id="license-overlay">
|
|
14
21
|
<div id="license-box">
|
|
15
22
|
<img class="logo-icon" src="/assets/logo.png" alt="Sensivity">
|
package/public/js/app.js
CHANGED
|
@@ -100,9 +100,9 @@ function ctrl(c) {
|
|
|
100
100
|
case 'checkbox':
|
|
101
101
|
return `<div class="ctrl"><label>${prettyLabel(c.key)}</label><label class="tgl"><input type="checkbox" id="${id}"${vs ? ' checked' : ''} onchange="set('${c.key}','checkbox',this.checked)"><span class="track"><span class="knob"></span></span></label></div>`;
|
|
102
102
|
case 'slider_int':
|
|
103
|
-
return `<div class="ctrl range-ctrl"><label>${prettyLabel(c.key)}</label><div class="rng"><span class="rng-val">${vs || 0}</span><input type="range" id="${id}" min="${c.min || 0}" max="${c.max || 100}" value="${vs || 0}" oninput="sliderUp('${c.key}','slider_int',this)"></div></div>`;
|
|
103
|
+
return `<div class="ctrl range-ctrl"><label>${prettyLabel(c.key)}</label><div class="rng"><span class="rng-val">${vs || 0}</span><input type="range" id="${id}" min="${c.min || 0}" max="${c.max || 100}" value="${vs || 0}" style="--range-percent:${rangePercent(c, vs || 0)}%" oninput="sliderUp('${c.key}','slider_int',this)"></div></div>`;
|
|
104
104
|
case 'slider_float':
|
|
105
|
-
return `<div class="ctrl range-ctrl"><label>${prettyLabel(c.key)}</label><div class="rng"><span class="rng-val">${parseFloat(vs || 0).toFixed(1)}</span><input type="range" id="${id}" min="${c.min || 0}" max="${c.max || 100}" step="${c.step || 0.1}" value="${vs || 0}" oninput="sliderUp('${c.key}','slider_float',this)"></div></div>`;
|
|
105
|
+
return `<div class="ctrl range-ctrl"><label>${prettyLabel(c.key)}</label><div class="rng"><span class="rng-val">${parseFloat(vs || 0).toFixed(1)}</span><input type="range" id="${id}" min="${c.min || 0}" max="${c.max || 100}" step="${c.step || 0.1}" value="${vs || 0}" style="--range-percent:${rangePercent(c, vs || 0)}%" oninput="sliderUp('${c.key}','slider_float',this)"></div></div>`;
|
|
106
106
|
case 'dropdown':
|
|
107
107
|
return `<div class="ctrl"><label>${prettyLabel(c.key)}</label><select id="${id}" onchange="set('${c.key}','dropdown',this.selectedIndex)">${(c.items || []).map((x, i) => `<option value="${i}"${i === vs ? ' selected' : ''}>${x}</option>`).join('')}</select></div>`;
|
|
108
108
|
case 'color_checkbox': {
|
|
@@ -133,6 +133,7 @@ function sliderUp(k, t, el) {
|
|
|
133
133
|
const v = t === 'slider_int' ? parseInt(el.value) : parseFloat(el.value);
|
|
134
134
|
state[k] = v;
|
|
135
135
|
el.previousElementSibling.textContent = t === 'slider_int' ? v : v.toFixed(1);
|
|
136
|
+
updateRangeFill(el);
|
|
136
137
|
emit(k, t, v);
|
|
137
138
|
queuePlayerEspSync(k);
|
|
138
139
|
if (shouldShowEspPreview()) updateEspPreview();
|
|
@@ -152,6 +153,22 @@ function emit(k, t, v) {
|
|
|
152
153
|
if (SOCKET && SOCKET.connected) SOCKET.emit('setConfig', { key: k, type: t, value: v });
|
|
153
154
|
}
|
|
154
155
|
|
|
156
|
+
function rangePercent(c, value) {
|
|
157
|
+
const min = Number(c.min || 0);
|
|
158
|
+
const max = Number(c.max || 100);
|
|
159
|
+
const val = Number(value || 0);
|
|
160
|
+
if (max <= min) return 0;
|
|
161
|
+
return Math.max(0, Math.min(100, ((val - min) / (max - min)) * 100)).toFixed(2);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function updateRangeFill(el) {
|
|
165
|
+
const min = Number(el.min || 0);
|
|
166
|
+
const max = Number(el.max || 100);
|
|
167
|
+
const val = Number(el.value || 0);
|
|
168
|
+
const pct = max <= min ? 0 : Math.max(0, Math.min(100, ((val - min) / (max - min)) * 100));
|
|
169
|
+
el.style.setProperty('--range-percent', pct.toFixed(2) + '%');
|
|
170
|
+
}
|
|
171
|
+
|
|
155
172
|
function visualPlayerControls() {
|
|
156
173
|
const visuals = SCHEMA.sections.find(s => s.id === 'visuals');
|
|
157
174
|
const player = visuals && (visuals.subs || []).find(sub => sub.id === 'vplayer');
|
|
@@ -240,8 +257,10 @@ document.addEventListener('mousedown', function(e) {
|
|
|
240
257
|
});
|
|
241
258
|
|
|
242
259
|
function toggleCheat() {
|
|
243
|
-
if (!SOCKET
|
|
244
|
-
|
|
260
|
+
if (!SOCKET) return;
|
|
261
|
+
const eventName = cheatRunning ? 'stopCheat' : 'startCheat';
|
|
262
|
+
SOCKET.emit(eventName);
|
|
263
|
+
if (!SOCKET.connected && typeof SOCKET.connect === 'function') SOCKET.connect();
|
|
245
264
|
}
|
|
246
265
|
|
|
247
266
|
function updateStatus() {
|