@harmonia-core/ui 1.2.6 → 1.2.7
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/aggregator-M6X5XUQY.js +475 -0
- package/dist/aggregator-M6X5XUQY.js.map +1 -0
- package/dist/aggregator-TH7FATMR.mjs +473 -0
- package/dist/aggregator-TH7FATMR.mjs.map +1 -0
- package/dist/capacity/index.js +12 -517
- package/dist/capacity/index.js.map +1 -1
- package/dist/capacity/index.mjs +4 -509
- package/dist/capacity/index.mjs.map +1 -1
- package/dist/capacity/provider.d.ts.map +1 -1
- package/dist/capacity/server.js.map +1 -1
- package/dist/capacity/server.mjs.map +1 -1
- package/dist/capacity/utils/typography.d.ts +1 -16
- package/dist/capacity/utils/typography.d.ts.map +1 -1
- package/dist/chunk-E3LOUS7X.mjs +43 -0
- package/dist/chunk-E3LOUS7X.mjs.map +1 -0
- package/dist/chunk-JPRRZPBL.js +47 -0
- package/dist/chunk-JPRRZPBL.js.map +1 -0
- package/package.json +2 -2
package/dist/capacity/index.js
CHANGED
|
@@ -1,49 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
var chunkJPRRZPBL_js = require('../chunk-JPRRZPBL.js');
|
|
4
5
|
var react = require('react');
|
|
5
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
7
|
|
|
7
|
-
var __defProp = Object.defineProperty;
|
|
8
|
-
var __defProps = Object.defineProperties;
|
|
9
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
10
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
11
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
13
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
14
|
-
var __spreadValues = (a, b) => {
|
|
15
|
-
for (var prop in b || (b = {}))
|
|
16
|
-
if (__hasOwnProp.call(b, prop))
|
|
17
|
-
__defNormalProp(a, prop, b[prop]);
|
|
18
|
-
if (__getOwnPropSymbols)
|
|
19
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
20
|
-
if (__propIsEnum.call(b, prop))
|
|
21
|
-
__defNormalProp(a, prop, b[prop]);
|
|
22
|
-
}
|
|
23
|
-
return a;
|
|
24
|
-
};
|
|
25
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
26
|
-
var __async = (__this, __arguments, generator) => {
|
|
27
|
-
return new Promise((resolve, reject) => {
|
|
28
|
-
var fulfilled = (value) => {
|
|
29
|
-
try {
|
|
30
|
-
step(generator.next(value));
|
|
31
|
-
} catch (e) {
|
|
32
|
-
reject(e);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
var rejected = (value) => {
|
|
36
|
-
try {
|
|
37
|
-
step(generator.throw(value));
|
|
38
|
-
} catch (e) {
|
|
39
|
-
reject(e);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
43
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
|
|
47
8
|
// lib/capacity/validation.ts
|
|
48
9
|
function detectConflicts(field) {
|
|
49
10
|
var _a;
|
|
@@ -289,8 +250,8 @@ var FieldManagerClass = class {
|
|
|
289
250
|
* Update user capacity (Phase 1 slider system writes here)
|
|
290
251
|
*/
|
|
291
252
|
updateCapacity(capacity) {
|
|
292
|
-
const newCapacity = __spreadValues(__spreadValues({}, this.context.userCapacity), capacity);
|
|
293
|
-
this.context = __spreadProps(__spreadValues({}, this.context), {
|
|
253
|
+
const newCapacity = chunkJPRRZPBL_js.__spreadValues(chunkJPRRZPBL_js.__spreadValues({}, this.context.userCapacity), capacity);
|
|
254
|
+
this.context = chunkJPRRZPBL_js.__spreadProps(chunkJPRRZPBL_js.__spreadValues({}, this.context), {
|
|
294
255
|
userCapacity: newCapacity,
|
|
295
256
|
energy: createFieldValue(deriveEnergyField(newCapacity), this.context.energy),
|
|
296
257
|
attention: createFieldValue(deriveAttentionField(newCapacity), this.context.attention)
|
|
@@ -301,8 +262,8 @@ var FieldManagerClass = class {
|
|
|
301
262
|
* Update emotional state (Phase 1 slider system writes here)
|
|
302
263
|
*/
|
|
303
264
|
updateEmotionalState(state) {
|
|
304
|
-
const newState = __spreadValues(__spreadValues({}, this.context.emotionalState), state);
|
|
305
|
-
this.context = __spreadProps(__spreadValues({}, this.context), {
|
|
265
|
+
const newState = chunkJPRRZPBL_js.__spreadValues(chunkJPRRZPBL_js.__spreadValues({}, this.context.emotionalState), state);
|
|
266
|
+
this.context = chunkJPRRZPBL_js.__spreadProps(chunkJPRRZPBL_js.__spreadValues({}, this.context), {
|
|
306
267
|
emotionalState: newState,
|
|
307
268
|
emotionalValence: createFieldValue(deriveEmotionalValenceField(newState), this.context.emotionalValence)
|
|
308
269
|
});
|
|
@@ -333,7 +294,7 @@ var FieldManagerClass = class {
|
|
|
333
294
|
* Update field configuration
|
|
334
295
|
*/
|
|
335
296
|
updateConfig(config) {
|
|
336
|
-
this.config = __spreadValues(__spreadValues({}, this.config), config);
|
|
297
|
+
this.config = chunkJPRRZPBL_js.__spreadValues(chunkJPRRZPBL_js.__spreadValues({}, this.config), config);
|
|
337
298
|
}
|
|
338
299
|
/**
|
|
339
300
|
* Get current field configuration
|
|
@@ -396,474 +357,6 @@ function getModeBadgeColor(label) {
|
|
|
396
357
|
return "oklch(0.5 0 0)";
|
|
397
358
|
}
|
|
398
359
|
}
|
|
399
|
-
|
|
400
|
-
// lib/capacity/signals/detectors/time-detector.ts
|
|
401
|
-
var TimeDetector = class {
|
|
402
|
-
constructor() {
|
|
403
|
-
this.name = "TimeDetector";
|
|
404
|
-
this.weight = 0.6;
|
|
405
|
-
}
|
|
406
|
-
// Medium weight — time is significant but a broad generalisation
|
|
407
|
-
/**
|
|
408
|
-
* Detects and returns SignalReadings based on the current time and day.
|
|
409
|
-
* Returns two readings: cognitive (hour-of-day) and temporal (weekday/weekend).
|
|
410
|
-
*/
|
|
411
|
-
detect() {
|
|
412
|
-
const now = /* @__PURE__ */ new Date();
|
|
413
|
-
const hour = now.getHours();
|
|
414
|
-
const dayOfWeek = now.getDay();
|
|
415
|
-
const ts = now.getTime();
|
|
416
|
-
let cognitiveValue;
|
|
417
|
-
if (hour >= 9 && hour < 12) {
|
|
418
|
-
cognitiveValue = 0.8;
|
|
419
|
-
} else if (hour >= 14 && hour < 17) {
|
|
420
|
-
cognitiveValue = 0.6;
|
|
421
|
-
} else if (hour >= 17 && hour < 20) {
|
|
422
|
-
cognitiveValue = 0.5;
|
|
423
|
-
} else if (hour >= 20 || hour < 6) {
|
|
424
|
-
cognitiveValue = 0.3;
|
|
425
|
-
} else {
|
|
426
|
-
cognitiveValue = 0.7;
|
|
427
|
-
}
|
|
428
|
-
const temporalValue = dayOfWeek >= 1 && dayOfWeek <= 5 ? 0.7 : 0.9;
|
|
429
|
-
return [
|
|
430
|
-
{
|
|
431
|
-
dimension: "cognitive",
|
|
432
|
-
value: cognitiveValue,
|
|
433
|
-
confidence: 0.7,
|
|
434
|
-
// Medium — population average, not personalised
|
|
435
|
-
timestamp: ts,
|
|
436
|
-
detectorName: this.name
|
|
437
|
-
},
|
|
438
|
-
{
|
|
439
|
-
dimension: "temporal",
|
|
440
|
-
value: temporalValue,
|
|
441
|
-
confidence: 0.6,
|
|
442
|
-
// Slightly lower — weekday/weekend is a coarser signal
|
|
443
|
-
timestamp: ts,
|
|
444
|
-
detectorName: this.name
|
|
445
|
-
}
|
|
446
|
-
];
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
|
|
450
|
-
// lib/capacity/signals/detectors/session-detector.ts
|
|
451
|
-
var SessionDetector = class {
|
|
452
|
-
constructor() {
|
|
453
|
-
this.name = "SessionDetector";
|
|
454
|
-
this.weight = 0.7;
|
|
455
|
-
this.sessionStartTime = Date.now();
|
|
456
|
-
}
|
|
457
|
-
/**
|
|
458
|
-
* Detects and returns a SignalReading based on the current session duration.
|
|
459
|
-
* It provides insights into the temporal dimension.
|
|
460
|
-
*
|
|
461
|
-
* @returns {SignalReading} A reading indicating the inferred capacity.
|
|
462
|
-
*/
|
|
463
|
-
detect() {
|
|
464
|
-
const now = Date.now();
|
|
465
|
-
const sessionDurationMinutes = (now - this.sessionStartTime) / (1e3 * 60);
|
|
466
|
-
let temporalValue;
|
|
467
|
-
let confidence;
|
|
468
|
-
if (sessionDurationMinutes < 15) {
|
|
469
|
-
temporalValue = 0.9;
|
|
470
|
-
confidence = 0.8;
|
|
471
|
-
} else if (sessionDurationMinutes < 60) {
|
|
472
|
-
temporalValue = 0.7;
|
|
473
|
-
confidence = 0.7;
|
|
474
|
-
} else if (sessionDurationMinutes < 180) {
|
|
475
|
-
temporalValue = 0.5;
|
|
476
|
-
confidence = 0.6;
|
|
477
|
-
} else {
|
|
478
|
-
temporalValue = 0.3;
|
|
479
|
-
confidence = 0.7;
|
|
480
|
-
}
|
|
481
|
-
return [{
|
|
482
|
-
dimension: "temporal",
|
|
483
|
-
value: temporalValue,
|
|
484
|
-
confidence,
|
|
485
|
-
timestamp: now,
|
|
486
|
-
detectorName: this.name
|
|
487
|
-
}];
|
|
488
|
-
}
|
|
489
|
-
};
|
|
490
|
-
|
|
491
|
-
// lib/capacity/signals/detectors/scroll-detector.ts
|
|
492
|
-
var DEBOUNCE_TIME_MS = 100;
|
|
493
|
-
var ScrollDetector = class {
|
|
494
|
-
constructor() {
|
|
495
|
-
this.name = "ScrollDetector";
|
|
496
|
-
this.weight = 0.5;
|
|
497
|
-
// Moderate weight, as scroll velocity can indicate engagement or frustration
|
|
498
|
-
this.lastScrollY = 0;
|
|
499
|
-
this.lastScrollTime = 0;
|
|
500
|
-
this.scrollVelocity = 0;
|
|
501
|
-
this.timeoutId = null;
|
|
502
|
-
/**
|
|
503
|
-
* Handles the scroll event, debouncing it and calculating scroll velocity.
|
|
504
|
-
* @private
|
|
505
|
-
*/
|
|
506
|
-
this.handleScroll = () => {
|
|
507
|
-
if (this.timeoutId) {
|
|
508
|
-
clearTimeout(this.timeoutId);
|
|
509
|
-
}
|
|
510
|
-
this.timeoutId = setTimeout(() => {
|
|
511
|
-
const now = Date.now();
|
|
512
|
-
const scrollY = window.scrollY;
|
|
513
|
-
const distance = Math.abs(scrollY - this.lastScrollY);
|
|
514
|
-
const timeElapsed = now - this.lastScrollTime;
|
|
515
|
-
if (timeElapsed > 0) {
|
|
516
|
-
this.scrollVelocity = distance / timeElapsed * 1e3;
|
|
517
|
-
} else {
|
|
518
|
-
this.scrollVelocity = 0;
|
|
519
|
-
}
|
|
520
|
-
this.lastScrollY = scrollY;
|
|
521
|
-
this.lastScrollTime = now;
|
|
522
|
-
}, DEBOUNCE_TIME_MS);
|
|
523
|
-
};
|
|
524
|
-
if (typeof window !== "undefined") {
|
|
525
|
-
window.addEventListener("scroll", this.handleScroll, { passive: true });
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
/**
|
|
529
|
-
* Detects and returns a SignalReading based on the current scroll velocity.
|
|
530
|
-
* It provides insights into the cognitive dimension.
|
|
531
|
-
*
|
|
532
|
-
* @returns {SignalReading} A reading indicating the inferred capacity.
|
|
533
|
-
*/
|
|
534
|
-
detect() {
|
|
535
|
-
const now = Date.now();
|
|
536
|
-
let cognitiveValue;
|
|
537
|
-
let confidence;
|
|
538
|
-
if (this.scrollVelocity > 1500) {
|
|
539
|
-
cognitiveValue = 0.4;
|
|
540
|
-
confidence = 0.6;
|
|
541
|
-
} else if (this.scrollVelocity > 500) {
|
|
542
|
-
cognitiveValue = 0.7;
|
|
543
|
-
confidence = 0.8;
|
|
544
|
-
} else if (this.scrollVelocity > 50) {
|
|
545
|
-
cognitiveValue = 0.6;
|
|
546
|
-
confidence = 0.7;
|
|
547
|
-
} else {
|
|
548
|
-
cognitiveValue = 0.5;
|
|
549
|
-
confidence = 0.5;
|
|
550
|
-
}
|
|
551
|
-
return [{
|
|
552
|
-
dimension: "cognitive",
|
|
553
|
-
value: cognitiveValue,
|
|
554
|
-
confidence,
|
|
555
|
-
timestamp: now,
|
|
556
|
-
detectorName: this.name
|
|
557
|
-
}];
|
|
558
|
-
}
|
|
559
|
-
/**
|
|
560
|
-
* Cleans up the scroll event listener when the detector is no longer needed.
|
|
561
|
-
*/
|
|
562
|
-
destroy() {
|
|
563
|
-
if (typeof window !== "undefined") {
|
|
564
|
-
window.removeEventListener("scroll", this.handleScroll);
|
|
565
|
-
if (this.timeoutId) {
|
|
566
|
-
clearTimeout(this.timeoutId);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
};
|
|
571
|
-
|
|
572
|
-
// lib/capacity/signals/detectors/interaction-detector.ts
|
|
573
|
-
var IDLE_THRESHOLD_MS = 15e3;
|
|
574
|
-
var CLICK_WINDOW_MS = 6e4;
|
|
575
|
-
var InteractionDetector = class {
|
|
576
|
-
constructor() {
|
|
577
|
-
this.name = "InteractionDetector";
|
|
578
|
-
this.weight = 0.7;
|
|
579
|
-
this.lastMouseMoveTime = 0;
|
|
580
|
-
this.lastClickTime = 0;
|
|
581
|
-
this.lastClickPosition = null;
|
|
582
|
-
this.clickHistory = [];
|
|
583
|
-
// rolling 60-second window
|
|
584
|
-
this.idleTimer = null;
|
|
585
|
-
this.isIdle = false;
|
|
586
|
-
this.resetIdleTimer = () => {
|
|
587
|
-
if (this.idleTimer) clearTimeout(this.idleTimer);
|
|
588
|
-
this.isIdle = false;
|
|
589
|
-
this.idleTimer = setTimeout(() => {
|
|
590
|
-
this.isIdle = true;
|
|
591
|
-
}, IDLE_THRESHOLD_MS);
|
|
592
|
-
};
|
|
593
|
-
this.handleMouseMove = () => {
|
|
594
|
-
this.lastMouseMoveTime = Date.now();
|
|
595
|
-
this.resetIdleTimer();
|
|
596
|
-
};
|
|
597
|
-
this.handleClick = (event) => {
|
|
598
|
-
this.resetIdleTimer();
|
|
599
|
-
const now = Date.now();
|
|
600
|
-
this.lastClickTime = now;
|
|
601
|
-
let distance = 0;
|
|
602
|
-
if (this.lastClickPosition) {
|
|
603
|
-
const dx = event.clientX - this.lastClickPosition.x;
|
|
604
|
-
const dy = event.clientY - this.lastClickPosition.y;
|
|
605
|
-
distance = Math.sqrt(dx * dx + dy * dy);
|
|
606
|
-
}
|
|
607
|
-
this.lastClickPosition = { x: event.clientX, y: event.clientY };
|
|
608
|
-
this.clickHistory.push({ time: now, distance });
|
|
609
|
-
};
|
|
610
|
-
if (typeof window !== "undefined") {
|
|
611
|
-
window.addEventListener("mousemove", this.handleMouseMove, { passive: true });
|
|
612
|
-
window.addEventListener("click", this.handleClick, { passive: true });
|
|
613
|
-
}
|
|
614
|
-
this.resetIdleTimer();
|
|
615
|
-
}
|
|
616
|
-
detect() {
|
|
617
|
-
const now = Date.now();
|
|
618
|
-
const cutoff = now - CLICK_WINDOW_MS;
|
|
619
|
-
this.clickHistory = this.clickHistory.filter((c) => c.time >= cutoff);
|
|
620
|
-
const clickCount = this.clickHistory.length;
|
|
621
|
-
const avgClickDistance = clickCount > 0 ? this.clickHistory.reduce((sum, c) => sum + c.distance, 0) / clickCount : 0;
|
|
622
|
-
const timeSinceLastClick = now - this.lastClickTime;
|
|
623
|
-
let cognitiveValue;
|
|
624
|
-
let confidence;
|
|
625
|
-
if (this.isIdle) {
|
|
626
|
-
cognitiveValue = 0.4;
|
|
627
|
-
confidence = 0.6;
|
|
628
|
-
} else if (timeSinceLastClick < 500 && clickCount > 5 && avgClickDistance < 20) {
|
|
629
|
-
cognitiveValue = 0.9;
|
|
630
|
-
confidence = 0.9;
|
|
631
|
-
} else if (timeSinceLastClick < 1500 && clickCount > 1 && avgClickDistance < 50) {
|
|
632
|
-
cognitiveValue = 0.7;
|
|
633
|
-
confidence = 0.7;
|
|
634
|
-
} else if (avgClickDistance > 100) {
|
|
635
|
-
cognitiveValue = 0.3;
|
|
636
|
-
confidence = 0.6;
|
|
637
|
-
} else {
|
|
638
|
-
cognitiveValue = 0.5;
|
|
639
|
-
confidence = 0.5;
|
|
640
|
-
}
|
|
641
|
-
return [{
|
|
642
|
-
dimension: "cognitive",
|
|
643
|
-
value: cognitiveValue,
|
|
644
|
-
confidence,
|
|
645
|
-
timestamp: now,
|
|
646
|
-
detectorName: this.name
|
|
647
|
-
}];
|
|
648
|
-
}
|
|
649
|
-
destroy() {
|
|
650
|
-
if (typeof window !== "undefined") {
|
|
651
|
-
window.removeEventListener("mousemove", this.handleMouseMove);
|
|
652
|
-
window.removeEventListener("click", this.handleClick);
|
|
653
|
-
}
|
|
654
|
-
if (this.idleTimer) clearTimeout(this.idleTimer);
|
|
655
|
-
}
|
|
656
|
-
};
|
|
657
|
-
|
|
658
|
-
// lib/capacity/signals/detectors/input-detector.ts
|
|
659
|
-
var TYPING_SPEED_SAMPLE_SIZE = 10;
|
|
660
|
-
var ERROR_CHECK_WINDOW = 5e3;
|
|
661
|
-
var InputDetector = class {
|
|
662
|
-
// timestamps of recent Backspace/Delete presses
|
|
663
|
-
constructor() {
|
|
664
|
-
this.name = "InputDetector";
|
|
665
|
-
this.weight = 0.6;
|
|
666
|
-
this.keyPressTimes = [];
|
|
667
|
-
this.errorTimes = [];
|
|
668
|
-
this.handleKeyDown = (event) => {
|
|
669
|
-
const now = Date.now();
|
|
670
|
-
this.keyPressTimes.push(now);
|
|
671
|
-
if (this.keyPressTimes.length > TYPING_SPEED_SAMPLE_SIZE) {
|
|
672
|
-
this.keyPressTimes.shift();
|
|
673
|
-
}
|
|
674
|
-
if (event.key === "Backspace" || event.key === "Delete") {
|
|
675
|
-
this.errorTimes.push(now);
|
|
676
|
-
}
|
|
677
|
-
};
|
|
678
|
-
if (typeof window !== "undefined") {
|
|
679
|
-
window.addEventListener("keydown", this.handleKeyDown, { passive: true });
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
detect() {
|
|
683
|
-
const now = Date.now();
|
|
684
|
-
let typingSpeedCPM = 0;
|
|
685
|
-
if (this.keyPressTimes.length > 1) {
|
|
686
|
-
const elapsed = this.keyPressTimes[this.keyPressTimes.length - 1] - this.keyPressTimes[0];
|
|
687
|
-
if (elapsed > 0) {
|
|
688
|
-
typingSpeedCPM = this.keyPressTimes.length / elapsed * 6e4;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
const cutoff = now - ERROR_CHECK_WINDOW;
|
|
692
|
-
this.errorTimes = this.errorTimes.filter((t) => t >= cutoff);
|
|
693
|
-
const recentErrorCount = this.errorTimes.length;
|
|
694
|
-
let cognitiveValue;
|
|
695
|
-
let confidence;
|
|
696
|
-
if (typingSpeedCPM > 100 && recentErrorCount === 0) {
|
|
697
|
-
cognitiveValue = 0.9;
|
|
698
|
-
confidence = 0.8;
|
|
699
|
-
} else if (typingSpeedCPM > 40 && recentErrorCount <= 1) {
|
|
700
|
-
cognitiveValue = 0.7;
|
|
701
|
-
confidence = 0.7;
|
|
702
|
-
} else if (recentErrorCount > 2 || typingSpeedCPM < 20) {
|
|
703
|
-
cognitiveValue = 0.4;
|
|
704
|
-
confidence = 0.6;
|
|
705
|
-
} else {
|
|
706
|
-
cognitiveValue = 0.6;
|
|
707
|
-
confidence = 0.5;
|
|
708
|
-
}
|
|
709
|
-
return [{
|
|
710
|
-
dimension: "cognitive",
|
|
711
|
-
value: cognitiveValue,
|
|
712
|
-
confidence,
|
|
713
|
-
timestamp: now,
|
|
714
|
-
detectorName: this.name
|
|
715
|
-
}];
|
|
716
|
-
}
|
|
717
|
-
destroy() {
|
|
718
|
-
if (typeof window !== "undefined") {
|
|
719
|
-
window.removeEventListener("keydown", this.handleKeyDown);
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
};
|
|
723
|
-
|
|
724
|
-
// lib/capacity/signals/detectors/environment-detector.ts
|
|
725
|
-
var EnvironmentDetector = class {
|
|
726
|
-
constructor() {
|
|
727
|
-
this.name = "EnvironmentDetector";
|
|
728
|
-
this.weight = 0.8;
|
|
729
|
-
// High weight — these are explicit user preferences
|
|
730
|
-
this.mqlReducedMotion = null;
|
|
731
|
-
this.mqlDarkMode = null;
|
|
732
|
-
this.handleChange = () => {
|
|
733
|
-
};
|
|
734
|
-
if (typeof window !== "undefined") {
|
|
735
|
-
this.mqlReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
736
|
-
this.mqlDarkMode = window.matchMedia("(prefers-color-scheme: dark)");
|
|
737
|
-
this.mqlReducedMotion.addEventListener("change", this.handleChange);
|
|
738
|
-
this.mqlDarkMode.addEventListener("change", this.handleChange);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
/**
|
|
742
|
-
* Returns two readings:
|
|
743
|
-
* - temporal: based on prefers-reduced-motion (low → less time pressure on animations)
|
|
744
|
-
* - emotional: based on prefers-color-scheme (dark → slightly lower emotional load)
|
|
745
|
-
*/
|
|
746
|
-
detect() {
|
|
747
|
-
const now = Date.now();
|
|
748
|
-
const prefersReducedMotion = this.mqlReducedMotion != null ? this.mqlReducedMotion.matches : typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
749
|
-
const prefersDarkMode = this.mqlDarkMode != null ? this.mqlDarkMode.matches : typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
750
|
-
return [
|
|
751
|
-
{
|
|
752
|
-
dimension: "temporal",
|
|
753
|
-
// prefers-reduced-motion → user may have lower tolerance for demanding UIs
|
|
754
|
-
value: prefersReducedMotion ? 0.3 : 0.8,
|
|
755
|
-
confidence: 0.9,
|
|
756
|
-
timestamp: now,
|
|
757
|
-
detectorName: this.name
|
|
758
|
-
},
|
|
759
|
-
{
|
|
760
|
-
dimension: "emotional",
|
|
761
|
-
// Dark mode preference → slightly lower emotional capacity or reduced-stimulation preference
|
|
762
|
-
value: prefersDarkMode ? 0.6 : 0.7,
|
|
763
|
-
confidence: 0.9,
|
|
764
|
-
timestamp: now,
|
|
765
|
-
detectorName: this.name
|
|
766
|
-
}
|
|
767
|
-
];
|
|
768
|
-
}
|
|
769
|
-
/**
|
|
770
|
-
* Removes the event listeners registered in the constructor.
|
|
771
|
-
* Uses the stored refs so the same function reference is unregistered.
|
|
772
|
-
*/
|
|
773
|
-
destroy() {
|
|
774
|
-
var _a, _b;
|
|
775
|
-
(_a = this.mqlReducedMotion) == null ? void 0 : _a.removeEventListener("change", this.handleChange);
|
|
776
|
-
(_b = this.mqlDarkMode) == null ? void 0 : _b.removeEventListener("change", this.handleChange);
|
|
777
|
-
this.mqlReducedMotion = null;
|
|
778
|
-
this.mqlDarkMode = null;
|
|
779
|
-
}
|
|
780
|
-
};
|
|
781
|
-
|
|
782
|
-
// lib/capacity/signals/aggregator.ts
|
|
783
|
-
var _SignalAggregator = class _SignalAggregator {
|
|
784
|
-
constructor() {
|
|
785
|
-
this.detectors = [
|
|
786
|
-
new TimeDetector(),
|
|
787
|
-
new SessionDetector(),
|
|
788
|
-
new ScrollDetector(),
|
|
789
|
-
new InteractionDetector(),
|
|
790
|
-
new InputDetector(),
|
|
791
|
-
new EnvironmentDetector()
|
|
792
|
-
];
|
|
793
|
-
}
|
|
794
|
-
/**
|
|
795
|
-
* Collects signal readings from all detectors and aggregates them into a
|
|
796
|
-
* confidence-weighted CapacityField.
|
|
797
|
-
*/
|
|
798
|
-
aggregateSignals() {
|
|
799
|
-
return __async(this, null, function* () {
|
|
800
|
-
const readings = [];
|
|
801
|
-
for (const detector of this.detectors) {
|
|
802
|
-
const detectorReadings = yield detector.detect();
|
|
803
|
-
readings.push(...detectorReadings);
|
|
804
|
-
}
|
|
805
|
-
const weightedSums = {
|
|
806
|
-
cognitive: 0,
|
|
807
|
-
temporal: 0,
|
|
808
|
-
emotional: 0,
|
|
809
|
-
valence: 0
|
|
810
|
-
};
|
|
811
|
-
const totalWeights = {
|
|
812
|
-
cognitive: 0,
|
|
813
|
-
temporal: 0,
|
|
814
|
-
emotional: 0,
|
|
815
|
-
valence: 0
|
|
816
|
-
};
|
|
817
|
-
for (const reading of readings) {
|
|
818
|
-
const effectiveWeight = reading.confidence * this.getDetectorWeight(reading.dimension, reading.detectorName);
|
|
819
|
-
weightedSums[reading.dimension] += reading.value * effectiveWeight;
|
|
820
|
-
totalWeights[reading.dimension] += effectiveWeight;
|
|
821
|
-
}
|
|
822
|
-
return {
|
|
823
|
-
cognitive: totalWeights.cognitive > 0 ? weightedSums.cognitive / totalWeights.cognitive : 0.5,
|
|
824
|
-
temporal: totalWeights.temporal > 0 ? weightedSums.temporal / totalWeights.temporal : 0.5,
|
|
825
|
-
emotional: totalWeights.emotional > 0 ? weightedSums.emotional / totalWeights.emotional : 0.5,
|
|
826
|
-
valence: totalWeights.valence > 0 ? weightedSums.valence / totalWeights.valence : 0
|
|
827
|
-
};
|
|
828
|
-
});
|
|
829
|
-
}
|
|
830
|
-
/**
|
|
831
|
-
* Returns the effective weight for a detector/dimension pair.
|
|
832
|
-
* Checks DIMENSION_WEIGHTS first; falls back to detector.weight.
|
|
833
|
-
*/
|
|
834
|
-
getDetectorWeight(dimension, detectorName) {
|
|
835
|
-
var _a, _b, _c;
|
|
836
|
-
const override = (_a = _SignalAggregator.DIMENSION_WEIGHTS[detectorName]) == null ? void 0 : _a[dimension];
|
|
837
|
-
if (override !== void 0) return override;
|
|
838
|
-
return (_c = (_b = this.detectors.find((d) => d.name === detectorName)) == null ? void 0 : _b.weight) != null ? _c : 0;
|
|
839
|
-
}
|
|
840
|
-
/** Cleans up all detector resources (event listeners, timers). */
|
|
841
|
-
destroy() {
|
|
842
|
-
var _a;
|
|
843
|
-
for (const detector of this.detectors) {
|
|
844
|
-
(_a = detector.destroy) == null ? void 0 : _a.call(detector);
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
};
|
|
848
|
-
/**
|
|
849
|
-
* Per-detector, per-dimension weight overrides.
|
|
850
|
-
* Falls back to detector.weight for any unlisted combination.
|
|
851
|
-
*
|
|
852
|
-
* Rationale for asymmetries:
|
|
853
|
-
* - TimeDetector: cognitive signal is stronger (diurnal pattern) than temporal
|
|
854
|
-
* (weekday/weekend is coarser)
|
|
855
|
-
* - EnvironmentDetector: emotional signal (color scheme) is a stronger explicit
|
|
856
|
-
* preference than temporal (reduced-motion)
|
|
857
|
-
*/
|
|
858
|
-
_SignalAggregator.DIMENSION_WEIGHTS = {
|
|
859
|
-
TimeDetector: { cognitive: 0.6, temporal: 0.5 },
|
|
860
|
-
EnvironmentDetector: { emotional: 0.8, temporal: 0.7 },
|
|
861
|
-
InteractionDetector: { cognitive: 0.7 },
|
|
862
|
-
InputDetector: { cognitive: 0.6 },
|
|
863
|
-
SessionDetector: { temporal: 0.7 },
|
|
864
|
-
ScrollDetector: { cognitive: 0.5 }
|
|
865
|
-
};
|
|
866
|
-
var SignalAggregator = _SignalAggregator;
|
|
867
360
|
var CapacityContext = react.createContext(null);
|
|
868
361
|
var AUTO_EMA_ALPHA = 0.2;
|
|
869
362
|
function applyEMA(prev, next, alpha) {
|
|
@@ -883,7 +376,9 @@ function CapacityProvider({ children }) {
|
|
|
883
376
|
const smoothedFieldRef = react.useRef(null);
|
|
884
377
|
const aggregatorRef = react.useRef(null);
|
|
885
378
|
react.useEffect(() => {
|
|
886
|
-
|
|
379
|
+
import('../aggregator-M6X5XUQY.js').then(({ SignalAggregator }) => {
|
|
380
|
+
aggregatorRef.current = new SignalAggregator();
|
|
381
|
+
});
|
|
887
382
|
const unsubscribe = FieldManager.subscribe((newContext) => {
|
|
888
383
|
setContext(newContext);
|
|
889
384
|
});
|
|
@@ -899,7 +394,7 @@ function CapacityProvider({ children }) {
|
|
|
899
394
|
if (isAutoMode && aggregatorRef.current) {
|
|
900
395
|
isFirstAggregationComplete.current = false;
|
|
901
396
|
smoothedFieldRef.current = null;
|
|
902
|
-
intervalId = setInterval(() => __async(null, null, function* () {
|
|
397
|
+
intervalId = setInterval(() => chunkJPRRZPBL_js.__async(null, null, function* () {
|
|
903
398
|
var _a;
|
|
904
399
|
try {
|
|
905
400
|
const suggestedField = yield aggregatorRef.current.aggregateSignals();
|
|
@@ -1072,7 +567,7 @@ function usePacedMotionTokens() {
|
|
|
1072
567
|
return {
|
|
1073
568
|
mode: effectiveMotion,
|
|
1074
569
|
pace: effectivePace,
|
|
1075
|
-
tokens: __spreadProps(__spreadValues({}, baseTokens), {
|
|
570
|
+
tokens: chunkJPRRZPBL_js.__spreadProps(chunkJPRRZPBL_js.__spreadValues({}, baseTokens), {
|
|
1076
571
|
durationFast: Math.round(baseTokens.durationFast * multiplier),
|
|
1077
572
|
durationBase: Math.round(baseTokens.durationBase * multiplier),
|
|
1078
573
|
durationSlow: Math.round(baseTokens.durationSlow * multiplier)
|
|
@@ -1283,7 +778,7 @@ var SignalBusClass = class {
|
|
|
1283
778
|
* Process signal queue
|
|
1284
779
|
*/
|
|
1285
780
|
processQueue() {
|
|
1286
|
-
return __async(this, null, function* () {
|
|
781
|
+
return chunkJPRRZPBL_js.__async(this, null, function* () {
|
|
1287
782
|
if (this.processing || this.signalQueue.length === 0) {
|
|
1288
783
|
return;
|
|
1289
784
|
}
|