File size: 6,765 Bytes
d0b8e8f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
import gleam/list
import gleam/float
import gleam/int

import gleam/option.{type Option, None, Some}

// --- 🌌 BIOMETRIC DATA ARCHITECTURE ---

pub type HeadPosture {
  Upright
  TiltedLeft
  TiltedRight
  SlumpedForward
  LookingAway
  RecedingFromCamera
}

pub type BiometricData {
  BiometricData(
    timestamp: Int,
    eye_gaze_x: Float,
    eye_gaze_y: Float,
    head_posture: HeadPosture,
    blink_rate: Float,
    pupil_size: Float,
    attention_score: Float,
    is_user_present: Bool,
  )
}

pub type AlertLevel {
  Green
  Yellow
  Orange
  Red
  Critical
}

pub type FocusMetrics {
  FocusMetrics(
    current_focus_score: Float,
    average_focus: Float,
    focus_trend: String,
    recommendations: List(String),
    alert_level: AlertLevel,
    session_fatigue: Float,
  )
}

pub type BiometricSession {
  BiometricSession(
    session_id: String,
    data_points: List(BiometricData),
    start_time: Int,
    end_time: Int,
    total_duration: Int,
    peak_focus: Float,
    average_blink_rate: Float,
  )
}

// --- 🛠️ PERMISSION & SYSTEM INITIALIZATION ---

pub fn request_biometric_permission() -> String {
  "IDENTITY SYNC: Camera access required for Neural Focus Tracking. 
   Encryption: AES-256. Purpose: Real-time Ocular Fatigue Analysis."
}

// --- 🧠 ADVANCED ANALYTICS ENGINE ---

pub fn calculate_focus_score(data: BiometricData) -> Float {
  let eye_score = {
    case data.eye_gaze_x, data.eye_gaze_y {
      x, y if x >. 200.0 && x <. 800.0 && y >. 200.0 && y <. 800.0 -> 100.0
      _, _ -> 40.0
    }
  }

  let posture_score = {
    case data.head_posture {
      Upright -> 100.0
      TiltedLeft | TiltedRight -> 75.0
      SlumpedForward -> 30.0
      LookingAway -> 10.0
      RecedingFromCamera -> 5.0
    }
  }

  let blink_score = {
    case data.blink_rate {
      b if b >. 12.0 && b <. 20.0 -> 100.0
      b if b >=. 20.0 && b <. 30.0 -> 70.0
      _ -> 40.0
    }
  }

  // FIXED: Using braces for math grouping per Gleam syntax
  {eye_score +. posture_score +. blink_score} /. 3.0
}

pub fn monitor_focus_stream(
  current: BiometricData,
  previous: Option(BiometricData),
) -> FocusMetrics {
  let current_score = calculate_focus_score(current)

  // FIXED: Using braces {} for math expression grouping
  let average_score = {
    case previous {
      Some(p) -> {current_score +. calculate_focus_score(p)} /. 2.0
      None -> current_score
    }
  }

  let trend = {
    case previous {
      Some(p) -> {
        let prev_score = calculate_focus_score(p)
        case current_score >. prev_score {
          True -> "🚀 ASCENDING"
          False -> "📉 DECAYING"
        }
      }
      None -> "→ SYNCHRONIZING"
    }
  }

  let alert = {
    case current_score {
      s if s >. 85.0 -> Green
      s if s >. 70.0 -> Yellow
      s if s >. 50.0 -> Orange
      s if s >. 30.0 -> Red
      _ -> Critical
    }
  }

  let recommendations = generate_dynamic_recommendations(alert, current.blink_rate)

  FocusMetrics(
    current_focus_score: current_score,
    average_focus: average_score,
    focus_trend: trend,
    recommendations: recommendations,
    alert_level: alert,
    session_fatigue: calculate_fatigue_index(current),
  )
}

// --- 📋 RECOMMENDATION ENGINE ---

fn generate_dynamic_recommendations(alert: AlertLevel, blink: Float) -> List(String) {
  let base = case alert {
    Green -> ["Neural link stable. Maintain current flow state."]
    Yellow -> ["Minor posture drift detected. Re-align spine."]
    Orange -> ["Synaptic fatigue detected. Perform 20-20-20 rule."]
    Red -> ["CRITICAL: Focus collapse imminent. Stand up."]
    Critical -> ["PROTOCOL INITIATED: System lockout recommended for rest."]
  }

  case blink >. 35.0 {
    True -> list.append(base, ["Ocular dryness detected. Increase blink frequency."])
    False -> base
  }
}

// --- 🧪 FATIGUE & THERMAL MODELS ---

fn calculate_fatigue_index(data: BiometricData) -> Float {
  let p_size = data.pupil_size
  let blink = data.blink_rate
  // Heuristic formula for neural fatigue
  {p_size *. 1.5 +. blink *. 0.8} /. 2.0
}

pub fn detect_posture_threats(data: BiometricData) -> Option(String) {
  case data.head_posture {
    SlumpedForward -> Some("BIO-ALERT: Slumping detected. Spinal health at risk.")
    LookingAway -> Some("BIO-ALERT: Sustained gaze deviation.")
    _ -> None
  }
}

// --- 🎵 ADAPTIVE AUDIO ENGINE ---

pub fn get_neural_audio_instruction(metrics: FocusMetrics) -> String {
  case metrics.alert_level {
    Green -> "SET_BPM_140_NEURAL_FLOW"
    Yellow -> "SET_BPM_120_LOFI_STEADY"
    Orange -> "SET_BPM_90_AMBIENT_RECOVERY"
    Red -> "SET_BPM_60_THETA_WAVES"
    Critical -> "AUDIO_MUTE_MANDATORY_BREAK"
  }
}

// --- 📊 REPORT GENERATION & EXPORT ---

pub fn generate_biometric_report(session: BiometricSession) -> String {
  let n = list.length(session.data_points)
  let total_focus = list.fold(session.data_points, 0.0, fn(acc, dp) {
    acc +. calculate_focus_score(dp)
  })
  
  let avg = case n {
    0 -> 0.0
    _ -> total_focus /. int.to_float(n)
  }

  "<div class='neural-report-box'>
    <h2 class='glitch-text'>Neural Performance Analytics</h2>
    <div class='stat-row'>
      <div class='stat'><h4>Mastery</h4><p>" <> float.to_string(avg) <> "%</p></div>
      <div class='stat'><h4>Stability</h4><p>" <> float.to_string(session.peak_focus) <> "%</p></div>
      <div class='stat'><h4>Duration</h4><p>" <> int.to_string(session.total_duration) <> "m</p></div>
    </div>
    <div class='report-footer'>System: FlashSync Zenith v4.0</div>
  </div>"
}

pub fn export_to_json(session: BiometricSession) -> String {
  // Manual JSON construction for high performance
  "{ \"session_id\": \"" <> session.session_id <> "\", \"avg_focus\": " <> 
  float.to_string(session.peak_focus) <> " }"
}

// --- 🎨 SURREAL UI ELEMENTS ---

pub fn render_focus_orb(score: Float) -> String {
  let size = {score *. 2.0}
  let color = case score {
    s if s >. 80.0 -> "#00f2ff"
    s if s >. 50.0 -> "#bc13fe"
    _ -> "#ff006e"
  }
  
  "<div class='focus-orb' style='width:" <> float.to_string(size) <> "px; background:" <> color <> "; box-shadow: 0 0 50px " <> color <> ";'></div>"
}

// --- 🛠️ SESSION UTILITIES ---

pub fn create_new_session(user_id: String) -> BiometricSession {
  BiometricSession(
    session_id: "SYNC-" <> user_id <> "-" <> int.to_string(101),
    data_points: [],
    start_time: 0,
    end_time: 0,
    total_duration: 0,
    peak_focus: 0.0,
    average_blink_rate: 0.0,
  )
}

pub fn check_microbreak_eligibility(active_minutes: Int) -> Bool {
  active_minutes % 25 == 0 && active_minutes > 0
}

pub fn finalize_session_data(session: BiometricSession) -> String {
  "ARCHIVING_NEURAL_LOG_" <> session.session_id <> "... SUCCESS."
}