easter-egg-quest 1.0.20 → 1.0.22

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.
@@ -142,7 +142,7 @@ function resolveConfig(raw = {}) {
142
142
  stageDurations: {
143
143
  stillnessMs: clampDuration((_i = raw.stageDurations) == null ? void 0 : _i.stillnessMs, 2e4),
144
144
  motionMs: clampDuration((_j = raw.stageDurations) == null ? void 0 : _j.motionMs, 2e4),
145
- rhythmCycles: clampInt((_k = raw.stageDurations) == null ? void 0 : _k.rhythmCycles, 6, 1, 50)
145
+ rhythmCycles: clampInt((_k = raw.stageDurations) == null ? void 0 : _k.rhythmCycles, 3, 1, 50)
146
146
  },
147
147
  renderer: raw.renderer ?? "auto",
148
148
  scoring: {
@@ -3665,7 +3665,7 @@ const _ResultsRenderer = class _ResultsRenderer {
3665
3665
  display: "flex",
3666
3666
  alignItems: "center",
3667
3667
  justifyContent: "center",
3668
- pointerEvents: "none"
3668
+ pointerEvents: "auto"
3669
3669
  });
3670
3670
  document.body.appendChild(this.host);
3671
3671
  this.shadow = this.host.attachShadow({ mode: "closed" });
@@ -4791,6 +4791,7 @@ class RhythmStage {
4791
4791
  this._lastPhaseCount = 0;
4792
4792
  this._bestAccuracy = 0;
4793
4793
  this._lastGuideTime = 0;
4794
+ this._lastGoodCycleAt = 0;
4794
4795
  this.IDEAL_MOVE_MIN = 900;
4795
4796
  this.IDEAL_MOVE_MAX = 4200;
4796
4797
  this.IDEAL_PAUSE_MIN = 600;
@@ -4839,6 +4840,7 @@ class RhythmStage {
4839
4840
  this._totalCycles++;
4840
4841
  if (isGood) {
4841
4842
  this._goodCycles++;
4843
+ this._lastGoodCycleAt = Date.now();
4842
4844
  } else {
4843
4845
  this._goodCycles = Math.max(0, this._goodCycles - 0.5);
4844
4846
  this._showReaction();
@@ -4851,13 +4853,20 @@ class RhythmStage {
4851
4853
  const accuracy = this._totalCycles > 0 ? this._goodCycles / this._totalCycles : 0;
4852
4854
  if (accuracy > this._bestAccuracy) this._bestAccuracy = accuracy;
4853
4855
  const progress = Math.min(1, this._goodCycles / requiredCycles);
4856
+ const targetPhase = this._getTargetPhase();
4857
+ const phaseMatch = this.input.snapshot.isMoving === (targetPhase === "move");
4858
+ const cycleSignal = this._lastGoodCycleAt > 0 ? Math.max(0, 1 - (Date.now() - this._lastGoodCycleAt) / 2200) : 0;
4854
4859
  this.bus.emit("stage:progress", progress);
4855
4860
  this.bus.emit("rhythm:breathe", {
4856
4861
  accuracy,
4857
4862
  isMoving: this.input.snapshot.isMoving,
4858
4863
  progress,
4859
4864
  moveDuration: this.input.moveDuration,
4860
- stillDuration: this.input.stillDuration
4865
+ stillDuration: this.input.stillDuration,
4866
+ liveConfidence: this._getLiveConfidence(),
4867
+ targetPhase,
4868
+ phaseMatch,
4869
+ cycleSignal
4861
4870
  });
4862
4871
  if (accuracy === 0 && Date.now() - this._lastGuideTime > 12e3) {
4863
4872
  this._lastGuideTime = Date.now();
@@ -4890,6 +4899,27 @@ class RhythmStage {
4890
4899
  const stillOk = stillPhase.duration >= this.IDEAL_PAUSE_MIN && stillPhase.duration <= this.IDEAL_PAUSE_MAX;
4891
4900
  return moveOk && stillOk;
4892
4901
  }
4902
+ _getLiveConfidence() {
4903
+ if (this.input.snapshot.isMoving) {
4904
+ return this._scoreDuration(this.input.moveDuration, this.IDEAL_MOVE_MIN, this.IDEAL_MOVE_MAX);
4905
+ }
4906
+ return this._scoreDuration(this.input.stillDuration, this.IDEAL_PAUSE_MIN, this.IDEAL_PAUSE_MAX);
4907
+ }
4908
+ _getTargetPhase() {
4909
+ if (this.input.snapshot.isMoving) {
4910
+ return this.input.moveDuration >= this.IDEAL_MOVE_MIN ? "still" : "move";
4911
+ }
4912
+ return this.input.stillDuration >= this.IDEAL_PAUSE_MIN ? "move" : "still";
4913
+ }
4914
+ _scoreDuration(duration, idealMin, idealMax) {
4915
+ if (duration <= 0) return 0;
4916
+ if (duration >= idealMin && duration <= idealMax) return 1;
4917
+ const tolerance = Math.max(300, Math.round((idealMax - idealMin) * 0.35));
4918
+ if (duration < idealMin) {
4919
+ return Math.max(0, 1 - (idealMin - duration) / tolerance);
4920
+ }
4921
+ return Math.max(0, 1 - (duration - idealMax) / tolerance);
4922
+ }
4893
4923
  _showReaction() {
4894
4924
  const now = Date.now();
4895
4925
  if (now - this._lastNarrativeTime > 12e3) {
@@ -5013,24 +5043,25 @@ class PageBreather {
5013
5043
  this._isUserMoving = false;
5014
5044
  this._inSync = false;
5015
5045
  this._accuracy = 0;
5016
- this.CYCLE_MS = 6e3;
5046
+ this._targetPhase = "move";
5047
+ this._phaseMatch = false;
5048
+ this._signal = 0;
5017
5049
  this._tick = () => {
5018
5050
  if (!this._active || !this._overlay) return;
5019
5051
  this._rafId = requestAnimationFrame(this._tick);
5020
5052
  this._intensity += (this._targetIntensity - this._intensity) * 0.06;
5021
5053
  const elapsed = Date.now() - this._startTime;
5022
- const phase = elapsed % this.CYCLE_MS / this.CYCLE_MS;
5023
- const wave = (Math.sin(phase * Math.PI * 2 - Math.PI / 2) + 1) * 0.5;
5024
- const shouldMove = phase < 0.5;
5025
- this._inSync = this._accuracy > 0 && shouldMove === this._isUserMoving;
5026
- const baseOpacity = wave * 0.85;
5027
- const syncBonus = this._inSync ? 0.22 : 0;
5028
- const opacity = this._intensity * (0.18 + baseOpacity + (1 - wave) * 0.12 + syncBonus);
5054
+ const wave = (Math.sin(elapsed * 4e-3) + 1) * 0.5;
5055
+ const shouldMove = this._targetPhase === "move";
5056
+ this._inSync = this._phaseMatch && this._signal > 0.15;
5057
+ const baseOpacity = shouldMove ? 0.12 + wave * 0.08 : 0.32 + wave * 0.18;
5058
+ const syncBonus = this._inSync ? 0.12 + this._signal * 0.18 : 0;
5059
+ const opacity = this._intensity * (baseOpacity + syncBonus);
5029
5060
  this._overlay.style.opacity = String(Math.min(0.9, opacity));
5030
- this._overlay.style.transform = `scale(${1 + wave * 0.015})`;
5061
+ this._overlay.style.transform = `scale(${1 + wave * (shouldMove ? 0.01 : 0.02)})`;
5031
5062
  if (this._label) {
5032
5063
  this._label.textContent = shouldMove ? "In" : "Out";
5033
- this._label.style.opacity = shouldMove === this._isUserMoving ? "0.98" : "0.82";
5064
+ this._label.style.opacity = this._phaseMatch ? "0.98" : "0.78";
5034
5065
  this._label.style.boxShadow = this._inSync ? "0 0 28px rgba(212,165,80,0.4)" : "0 0 20px rgba(255,255,255,0.08)";
5035
5066
  this._label.style.borderColor = this._inSync ? "rgba(212,165,80,0.55)" : "rgba(255,255,255,0.12)";
5036
5067
  }
@@ -5080,12 +5111,15 @@ class PageBreather {
5080
5111
  this._label = label;
5081
5112
  this._tick();
5082
5113
  }
5083
- update(accuracy, isMoving) {
5114
+ update(accuracy, isMoving, targetPhase, phaseMatch, signal) {
5084
5115
  if (!this._active) return;
5085
5116
  this._isUserMoving = isMoving;
5086
5117
  this._accuracy = accuracy;
5087
- const raw = Math.max(0, Math.min(1, (accuracy - 0.02) / 0.45));
5088
- this._targetIntensity = 0.68 + raw * 0.32;
5118
+ this._targetPhase = targetPhase;
5119
+ this._phaseMatch = phaseMatch;
5120
+ this._signal = signal;
5121
+ const raw = Math.max(0, Math.min(1, Math.max(accuracy, signal) / 0.8));
5122
+ this._targetIntensity = 0.38 + raw * 0.62;
5089
5123
  }
5090
5124
  /** Whether the user is currently in sync with the breathing rhythm. */
5091
5125
  isInSync() {
@@ -5104,6 +5138,9 @@ class PageBreather {
5104
5138
  this._targetIntensity = 0;
5105
5139
  this._inSync = false;
5106
5140
  this._accuracy = 0;
5141
+ this._targetPhase = "move";
5142
+ this._phaseMatch = false;
5143
+ this._signal = 0;
5107
5144
  }
5108
5145
  destroy() {
5109
5146
  this.stop();
@@ -5204,12 +5241,15 @@ class GameController {
5204
5241
  this.bus.on("rhythm:breathe", (data) => {
5205
5242
  var _a3, _b3;
5206
5243
  (_a3 = this.eggRenderer) == null ? void 0 : _a3.setBreathIntensity(data.accuracy);
5207
- (_b3 = this.pageBreather) == null ? void 0 : _b3.update(data.accuracy, data.isMoving);
5208
- const rhythmSignal = Math.max(data.accuracy, data.progress * 0.75);
5209
- const hasLiveCycleSignal = data.moveDuration > 700 || data.stillDuration > 700;
5210
- if ((rhythmSignal > 0.08 || hasLiveCycleSignal) && this.threeRenderer) {
5211
- const liveSignal = hasLiveCycleSignal ? 0.2 : 0;
5212
- this.threeRenderer.showProgressParticles(Math.max(0.35, 0.45 + Math.max(rhythmSignal, liveSignal) * 0.55), "rhythm");
5244
+ (_b3 = this.pageBreather) == null ? void 0 : _b3.update(
5245
+ data.accuracy,
5246
+ data.isMoving,
5247
+ data.targetPhase,
5248
+ data.phaseMatch,
5249
+ Math.max(data.liveConfidence * 0.55, data.cycleSignal)
5250
+ );
5251
+ if (data.cycleSignal > 0.12 && this.threeRenderer) {
5252
+ this.threeRenderer.showProgressParticles(0.35 + Math.max(data.progress, data.cycleSignal) * 0.65, "rhythm");
5213
5253
  } else if (this.threeRenderer) {
5214
5254
  this.threeRenderer.fadeOutAmbientParticles();
5215
5255
  }