{"version":3,"sources":["../src/index.ts","../src/engine.ts"],"sourcesContent":["export * from './engine';\r\nimport './styles.css'; ","// Emotional CSS Engine (TypeScript)\r\n// Wraps your full demo into a reusable class with an ergonomic API.\r\n\r\nexport type Emotion = 'happy' | 'calm' | 'confused' | 'stressed' | 'focused';\r\n\r\nexport interface EmotionalCssOptions {\r\n  // Required video/canvas for MediaPipe\r\n  video: HTMLVideoElement | string;\r\n  canvas: HTMLCanvasElement | string;\r\n\r\n  // Optional UI controls (wire up only if provided)\r\n  startBtn?: HTMLButtonElement | string;\r\n  stopBtn?: HTMLButtonElement | string;\r\n  showVideoCheckbox?: HTMLInputElement | string;\r\n  stabilityInput?: HTMLInputElement | string; // type=\"range\"\r\n  intervalInput?: HTMLInputElement | string;  // type=\"number\"\r\n  toastEl?: HTMLElement | string;\r\n  emotionLabel?: HTMLElement | string;\r\n  confidenceLabel?: HTMLElement | string;\r\n\r\n  // Optional “demo” elements\r\n  sampleSelect?: HTMLSelectElement | string;\r\n  numberInput?: HTMLInputElement | string; // changes dwell (ms via *10)\r\n  rangeInput?: HTMLInputElement | string;  // changes stability window\r\n\r\n  // Hooks\r\n  onEmotionChange?: (emotion: Emotion, confidence: number) => void;\r\n\r\n  // Initial settings\r\n  initial?: Partial<{\r\n    stabilitySize: number;\r\n    updateInterval: number;\r\n    showVideo: boolean;\r\n  }>;\r\n}\r\n\r\nconst E = Object.freeze({\r\n  HAPPY: 'happy' as Emotion,\r\n  CALM: 'calm' as Emotion,\r\n  CONFUSED: 'confused' as Emotion,\r\n  STRESSED: 'stressed' as Emotion,\r\n  FOCUSED: 'focused' as Emotion\r\n});\r\n\r\nfunction $(elOrSel?: Element | string | null): any {\r\n  if (!elOrSel) return null;\r\n  return typeof elOrSel === 'string' ? document.querySelector(elOrSel) : elOrSel;\r\n}\r\n\r\nconst clamp = (v: number, a: number, b: number) => Math.min(b, Math.max(a, v));\r\nconst dist = (p: {x:number;y:number}, q: {x:number;y:number}) => Math.hypot(p.x - q.x, p.y - q.y);\r\n\r\nfunction ema(prev: number | null, value: number, alpha = 0.3) {\r\n  return prev == null ? value : prev * (1 - alpha) + value * alpha;\r\n}\r\n\r\nexport class EmotionalCss {\r\n  // DOM\r\n  private video!: HTMLVideoElement;\r\n  private canvas!: HTMLCanvasElement;\r\n  private ctx!: CanvasRenderingContext2D | null;\r\n\r\n  private startBtn?: HTMLButtonElement | null;\r\n  private stopBtn?: HTMLButtonElement | null;\r\n  private showVideo?: HTMLInputElement | null;\r\n  private stabilityInput?: HTMLInputElement | null;\r\n  private intervalInput?: HTMLInputElement | null;\r\n  private toastEl?: HTMLElement | null;\r\n  private emotionLabel?: HTMLElement | null;\r\n  private confidenceLabel?: HTMLElement | null;\r\n\r\n  private sampleSelect?: HTMLSelectElement | null;\r\n  private numberInput?: HTMLInputElement | null;\r\n  private rangeInput?: HTMLInputElement | null;\r\n\r\n  // Engine\r\n  private opts: EmotionalCssOptions;\r\n  private timer: any = null;\r\n  private faceMesh: any = null;\r\n  private camera: any = null;\r\n  private frameEmotion: Emotion = E.CALM;\r\n\r\n  // State (ported from your script)\r\n  private state = {\r\n    running: false,\r\n    lastEmotion: 'none',\r\n    stabilityWindow: [] as Emotion[],\r\n    stabilitySize: 20,\r\n    updateInterval: 200,\r\n    conf: 0,\r\n    calibrated: false,\r\n    calibFrames: 0,\r\n    calibTarget: 40, // ~2s @ 20fps\r\n    baseline: { mouthW: 0, mouthOpen: 0, brow: 0, ear: 0 },\r\n    ema: { mouthW: null as number | null, mouthOpen: null as number | null, brow: null as number | null, ear: null as number | null, motion: 0 },\r\n    prevLm: null as any,\r\n    dwell: { current: 'calm' as Emotion, since: 0, minMs: 1200 },\r\n    overrideLocked: false,\r\n    overrideEmotion: 'calm' as Emotion,\r\n    lastSwitchAt: 0,\r\n    cooldownMs: 900,\r\n    reducedMotion: typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches\r\n  };\r\n\r\n  constructor(options: EmotionalCssOptions) {\r\n    this.opts = options;\r\n\r\n    // Resolve DOM\r\n    this.video = $(options.video);\r\n    this.canvas = $(options.canvas);\r\n    this.ctx = this.canvas?.getContext('2d') ?? null;\r\n\r\n    this.startBtn = $(options.startBtn);\r\n    this.stopBtn = $(options.stopBtn);\r\n    this.showVideo = $(options.showVideoCheckbox);\r\n    this.stabilityInput = $(options.stabilityInput);\r\n    this.intervalInput = $(options.intervalInput);\r\n    this.toastEl = $(options.toastEl);\r\n    this.emotionLabel = $(options.emotionLabel);\r\n    this.confidenceLabel = $(options.confidenceLabel);\r\n\r\n    this.sampleSelect = $(options.sampleSelect);\r\n    this.numberInput = $(options.numberInput);\r\n    this.rangeInput = $(options.rangeInput);\r\n\r\n    // Initial settings\r\n    if (options.initial?.stabilitySize) this.state.stabilitySize = options.initial.stabilitySize;\r\n    if (options.initial?.updateInterval) this.state.updateInterval = options.initial.updateInterval;\r\n\r\n    // Persisted settings\r\n    this.loadSettings();\r\n\r\n    // Apply initial show/hide for preview\r\n    this.toggleVideoPreview(this.showVideo ? !!this.showVideo.checked : (options.initial?.showVideo ?? true));\r\n\r\n    this.wireUI();\r\n  }\r\n\r\n  /** ---------- Public API ---------- */\r\n  async start() {\r\n    if (this.state.running) return;\r\n    this.state.running = true;\r\n    this.state.calibrated = false;\r\n    this.state.calibFrames = 0;\r\n    this.state.ema = { mouthW: null, mouthOpen: null, brow: null, ear: null, motion: 0 };\r\n    this.state.prevLm = null;\r\n    this.state.dwell = { current: 'calm', since: 0, minMs: 1200 };\r\n\r\n    this.startBtn && (this.startBtn.disabled = true);\r\n    this.stopBtn && (this.stopBtn.disabled = false);\r\n    this.startBtn && this.startBtn.setAttribute('aria-pressed', 'true');\r\n\r\n    // Expect MediaPipe globals provided by host app (via CDN or npm)\r\n    const FaceMesh = (window as any).FaceMesh;\r\n    const Camera = (window as any).Camera;\r\n\r\n    this.faceMesh = new FaceMesh({ locateFile: (file: string) => `https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh/${file}` });\r\n    this.faceMesh.setOptions({\r\n      selfieMode: true,\r\n      maxNumFaces: 1,\r\n      refineLandmarks: true,\r\n      minDetectionConfidence: 0.6,\r\n      minTrackingConfidence: 0.6\r\n    });\r\n    this.faceMesh.onResults((r: any) => this.onResults(r));\r\n\r\n    this.camera = new Camera(this.video, {\r\n      onFrame: async () => { await this.faceMesh.send({ image: this.video }); },\r\n      width: 640,\r\n      height: 480\r\n    });\r\n    await this.camera.start();\r\n\r\n    this.timer = setInterval(() => this.tick(), this.state.updateInterval);\r\n    this.toast('Camera on. You can press 1–5 to simulate emotions.');\r\n  }\r\n\r\n  stop() {\r\n    if (!this.state.running) return;\r\n    this.state.running = false;\r\n    this.startBtn && (this.startBtn.disabled = false);\r\n    this.stopBtn && (this.stopBtn.disabled = true);\r\n    this.startBtn && this.startBtn.setAttribute('aria-pressed', 'false');\r\n    if (this.timer) { clearInterval(this.timer); this.timer = null; }\r\n    if (this.camera) { this.camera.stop(); this.camera = null; }\r\n    this.ctx?.clearRect(0, 0, this.canvas.width, this.canvas.height);\r\n    if (this.video) this.video.srcObject = null;\r\n    document.documentElement.removeAttribute('data-emotion');\r\n    this.setLabel('none', '0.00');\r\n    this.toast('Camera off.');\r\n  }\r\n\r\n  setEmotion(em: Emotion) { this._setEmotion(em, 1.0); }\r\n  simulate(em: Emotion) { this._setEmotion(em, 1.0); }\r\n  lock(em: Emotion) { this.state.overrideEmotion = em; this.state.overrideLocked = true; this.saveSettings(); this.toast(`Override ON (${em})`); this._setEmotion(em, 1.0); }\r\n  unlock() { this.state.overrideLocked = false; this.saveSettings(); this.toast('Override OFF'); }\r\n\r\n  isLocked() { return this.state.overrideLocked; }\r\n\r\n  /** ---------- Internals (ported from your script) ---------- */\r\n  private wireUI() {\r\n    // Buttons\r\n    this.startBtn?.addEventListener('click', () => this.start());\r\n    this.stopBtn?.addEventListener('click', () => this.stop());\r\n\r\n    // Show video\r\n    this.showVideo?.addEventListener('change', () => {\r\n      this.toggleVideoPreview(!!this.showVideo?.checked);\r\n      this.saveSettings();\r\n    });\r\n\r\n    // Stability slider\r\n    this.stabilityInput?.addEventListener('input', (e: any) => {\r\n      this.state.stabilitySize = parseInt(e.target.value, 10);\r\n      this.saveSettings();\r\n    });\r\n\r\n    // Live update interval\r\n    if (this.intervalInput) {\r\n      const apply = (val: string) => {\r\n        this.state.updateInterval = Math.max(100, parseInt(val, 10) || 200);\r\n        if (this.timer) { clearInterval(this.timer); this.timer = setInterval(() => this.tick(), this.state.updateInterval); }\r\n        this.saveSettings();\r\n      };\r\n      this.intervalInput.addEventListener('input', (e: any) => apply(e.target.value));\r\n      this.intervalInput.addEventListener('change', (e: any) => apply(e.target.value));\r\n    }\r\n\r\n    // Demo knobs\r\n    if (this.numberInput) {\r\n      this.numberInput.addEventListener('input', (e: any) => {\r\n        const n = Math.max(10, parseInt(e.target.value || '0', 10));\r\n        this.state.dwell.minMs = Math.min(3000, Math.max(400, n * 10)); // 400–3000ms\r\n        this.toast(`Dwell: ${this.state.dwell.minMs}ms`);\r\n      });\r\n    }\r\n\r\n    if (this.rangeInput) {\r\n      const applyIntensity = (val: string) => {\r\n        const v = Math.max(0, Math.min(100, parseInt(val || '0', 10)));\r\n        this.state.stabilitySize = 8 + Math.round(v * (40 - 8) / 100);\r\n        if (this.stabilityInput) this.stabilityInput.value = String(this.state.stabilitySize);\r\n      };\r\n      this.rangeInput.addEventListener('input', (e: any) => applyIntensity(e.target.value));\r\n      this.rangeInput.addEventListener('change', (e: any) => applyIntensity(e.target.value));\r\n    }\r\n\r\n    if (this.sampleSelect) {\r\n      const map: Record<string, Emotion> = { 'Default': E.CALM, 'Option A': E.FOCUSED, 'Option B': E.HAPPY };\r\n      this.sampleSelect.addEventListener('change', (e: any) => {\r\n        const em = map[e.target.value] || E.CALM;\r\n        this.simulate(em);\r\n        this.toast(`Demo switched to \"${em}\" via select`);\r\n      });\r\n    }\r\n\r\n    // Keyboard shortcuts (global)\r\n    document.addEventListener('keydown', (e) => {\r\n      const k = e.key.toLowerCase();\r\n      if (k === 's') { this.state.running ? this.stop() : this.start(); }\r\n      const map: Record<string, Emotion> = { '1': E.HAPPY, '2': E.CALM, '3': E.CONFUSED, '4': E.STRESSED, '5': E.FOCUSED };\r\n      if (map[e.key]) this.simulate(map[e.key]);\r\n      if (k === 'o') {\r\n        if (e.shiftKey) {\r\n          const order = [E.CALM, E.HAPPY, E.CONFUSED, E.STRESSED, E.FOCUSED] as Emotion[];\r\n          const idx = order.indexOf(this.state.overrideEmotion);\r\n          this.state.overrideEmotion = order[(idx + 1) % order.length];\r\n          this.toast(`Override target: ${this.state.overrideEmotion}`);\r\n        } else {\r\n          this.state.overrideLocked = !this.state.overrideLocked;\r\n          this.toast(this.state.overrideLocked ? `Manual override ON (${this.state.overrideEmotion})` : 'Manual override OFF');\r\n        }\r\n        this.saveSettings();\r\n      }\r\n    });\r\n  }\r\n\r\n  private toast(msg = '', duration = 2800) {\r\n    if (!this.toastEl) return;\r\n    this.toastEl.textContent = msg;\r\n    (this.toastEl as HTMLElement).style.display = 'block';\r\n    setTimeout(() => ((this.toastEl as HTMLElement).style.display = 'none'), duration);\r\n  }\r\n\r\n  private setLabel(emotionStr: string, confStr: string) {\r\n    if (this.emotionLabel) {\r\n      const prefix = this.state.calibrated ? '' : '(calibrating…) ';\r\n      this.emotionLabel.textContent = `${prefix}${emotionStr}`;\r\n    }\r\n    if (this.confidenceLabel) this.confidenceLabel.textContent = confStr;\r\n  }\r\n\r\n  private toggleVideoPreview(on: boolean) {\r\n    if (!this.video || !this.canvas) return;\r\n    this.video.style.display = on ? 'block' : 'none';\r\n    this.canvas.style.display = on ? 'block' : 'none';\r\n  }\r\n\r\n  private applyEmotionToDOM(emotion: Emotion) {\r\n    const t = performance.now();\r\n    if (t - this.state.lastSwitchAt < this.state.cooldownMs && emotion !== this.state.lastEmotion) return;\r\n\r\n    document.body.classList.remove('mode-stressed', 'mode-confused', 'mode-focused', 'mode-happy', 'mode-calm');\r\n    switch (emotion) {\r\n      case E.HAPPY:\r\n        document.body.classList.add('mode-happy');\r\n        if (!this.state.reducedMotion) this.toast('You look happy — love it!');\r\n        break;\r\n      case E.CALM:\r\n        document.body.classList.add('mode-calm');\r\n        break;\r\n      case E.CONFUSED:\r\n        document.body.classList.add('mode-confused');\r\n        // optional focus nudge handled by app CSS `.pulse-outline`\r\n        if (this.numberInput && document.activeElement === document.body) this.numberInput.focus({ preventScroll: true });\r\n        break;\r\n      case E.STRESSED:\r\n        document.body.classList.add('mode-stressed');\r\n        this.toggleVideoPreview(false);\r\n        this.state.stabilitySize = Math.max(this.state.stabilitySize, 26);\r\n        this.stabilityInput && (this.stabilityInput.value = String(this.state.stabilitySize));\r\n        this.toast('Taking it easy. We’ve softened the UI.');\r\n        break;\r\n      case E.FOCUSED:\r\n        document.body.classList.add('mode-focused');\r\n        this.toggleVideoPreview(false);\r\n        this.state.dwell.minMs = 1400;\r\n        break;\r\n    }\r\n\r\n    // Respect checkbox if user explicitly wants preview ON (except focused/stressed)\r\n    if (this.showVideo?.checked && (emotion === E.HAPPY || emotion === E.CALM || emotion === E.CONFUSED)) {\r\n      this.toggleVideoPreview(true);\r\n    }\r\n\r\n    this.state.lastSwitchAt = t;\r\n  }\r\n\r\n  private setEmotionCore(emotion: Emotion, conf = 0.0) {\r\n    // Manual override\r\n    if (this.state.overrideLocked) { emotion = this.state.overrideEmotion; conf = 1.0; }\r\n\r\n    // Majority vote\r\n    const win = this.state.stabilityWindow;\r\n    win.push(emotion);\r\n    if (win.length > this.state.stabilitySize) win.shift();\r\n\r\n    const counts: Record<string, number> = {};\r\n    win.forEach(e => counts[e] = (counts[e] || 0) + 1);\r\n    const [best, bestCount] = Object.entries(counts).sort((a,b)=>b[1]-a[1])[0];\r\n    const majority = bestCount / win.length;\r\n\r\n    // Dwell\r\n    const t = performance.now();\r\n    if (this.state.dwell.current !== (best as Emotion)) {\r\n      if (this.state.dwell.since === 0) this.state.dwell.since = t;\r\n      const elapsed = t - this.state.dwell.since;\r\n      if (elapsed >= this.state.dwell.minMs) {\r\n        this.state.dwell.current = best as Emotion;\r\n        this.state.dwell.since = 0;\r\n      }\r\n    } else {\r\n      this.state.dwell.since = 0;\r\n    }\r\n\r\n    const chosen = this.state.dwell.current as Emotion;\r\n    document.documentElement.setAttribute('data-emotion', chosen);\r\n    this.state.lastEmotion = chosen;\r\n    this.state.conf = Number((majority).toFixed(2));\r\n\r\n    this.setLabel(chosen, this.state.conf.toFixed(2));\r\n    this.applyEmotionToDOM(chosen);\r\n    this.opts.onEmotionChange?.(chosen, this.state.conf);\r\n  }\r\n\r\n  private onResults(results: any) {\r\n    // Canvas\r\n    this.canvas.width = this.video.videoWidth || 640;\r\n    this.canvas.height = this.video.videoHeight || 480;\r\n    this.ctx?.save();\r\n    this.ctx?.clearRect(0, 0, this.canvas.width, this.canvas.height);\r\n\r\n    if (this.showVideo?.checked && results.multiFaceLandmarks?.length) {\r\n      const lm = results.multiFaceLandmarks[0];\r\n      // drawConnectors/drawLandmarks are global from MediaPipe drawing_utils\r\n      (window as any).drawConnectors?.(this.ctx, lm, (window as any).FACEMESH_TESSELATION);\r\n      (window as any).drawLandmarks?.(this.ctx, lm, { radius: 1 });\r\n    }\r\n    this.ctx?.restore();\r\n\r\n    if (!results.multiFaceLandmarks?.length) {\r\n      this.frameEmotion = E.CALM;\r\n      this.state.prevLm = null;\r\n      return;\r\n    }\r\n\r\n    const lm = results.multiFaceLandmarks[0];\r\n    const W = this.canvas.width, H = this.canvas.height;\r\n    const P = (i: number) => ({ x: lm[i].x * W, y: lm[i].y * H });\r\n\r\n    const IDX = {\r\n      LEFT_MOUTH: 61, RIGHT_MOUTH: 291, TOP_LIP: 13, BOTTOM_LIP: 14,\r\n      LEFT_BROW: 105, RIGHT_BROW: 334, NOSE_TIP: 1, LEFT_CHEEK: 234, RIGHT_CHEEK: 454,\r\n      L_EYE_TOP: 159, L_EYE_BOTTOM: 145, L_EYE_LEFT: 33, L_EYE_RIGHT: 133,\r\n      R_EYE_TOP: 386, R_EYE_BOTTOM: 374, R_EYE_LEFT: 362, R_EYE_RIGHT: 263,\r\n      L_EYE_CENTER: 468, R_EYE_CENTER: 473\r\n    };\r\n\r\n    // Face width (normalize)\r\n    const pLC = P(IDX.LEFT_CHEEK), pRC = P(IDX.RIGHT_CHEEK);\r\n    const faceW = Math.max(1, dist(pLC, pRC));\r\n    if (faceW < 120) { this.frameEmotion = E.CALM; return; }\r\n\r\n    // Roll\r\n    const pLE = lm[IDX.L_EYE_CENTER] ? P(IDX.L_EYE_CENTER) : P(IDX.L_EYE_LEFT);\r\n    const pRE = lm[IDX.R_EYE_CENTER] ? P(IDX.R_EYE_CENTER) : P(IDX.R_EYE_LEFT);\r\n    const roll = Math.atan2(pRE.y - pLE.y, pRE.x - pLE.x) * 57.3;\r\n    if (Math.abs(roll) > 25) { this.frameEmotion = (this.state.lastEmotion as Emotion) || E.CALM; return; }\r\n\r\n    // Features\r\n    const pL = P(IDX.LEFT_MOUTH), pR = P(IDX.RIGHT_MOUTH);\r\n    const pTop = P(IDX.TOP_LIP), pBot = P(IDX.BOTTOM_LIP);\r\n    const pLEb = P(IDX.LEFT_BROW), pREb = P(IDX.RIGHT_BROW);\r\n    const pN = P(IDX.NOSE_TIP);\r\n\r\n    const mouthW = dist(pL, pR) / faceW;\r\n    const mouthOpen = Math.abs(pBot.y - pTop.y) / faceW;\r\n    const brow = ((pN.y - ((pLEb.y + pREb.y) / 2)) / faceW);\r\n\r\n    const lEyeV = dist(P(IDX.L_EYE_TOP), P(IDX.L_EYE_BOTTOM));\r\n    const lEyeH = dist(P(IDX.L_EYE_LEFT), P(IDX.L_EYE_RIGHT));\r\n    const rEyeV = dist(P(IDX.R_EYE_TOP), P(IDX.R_EYE_BOTTOM));\r\n    const rEyeH = dist(P(IDX.R_EYE_LEFT), P(IDX.R_EYE_RIGHT));\r\n    const ear = ((lEyeV / lEyeH) + (rEyeV / rEyeH)) / 2;\r\n\r\n    // Motion\r\n    let motion = 0;\r\n    if (this.state.prevLm) {\r\n      const sampleIdx = [IDX.NOSE_TIP, IDX.LEFT_CHEEK, IDX.RIGHT_CHEEK, IDX.L_EYE_LEFT, IDX.R_EYE_RIGHT];\r\n      for (const i of sampleIdx) {\r\n        const a = P(i), b = { x: this.state.prevLm[i].x * W, y: this.state.prevLm[i].y * H };\r\n        motion += dist(a, b);\r\n      }\r\n      motion = motion / (sampleIdx.length * faceW);\r\n    }\r\n    this.state.prevLm = lm;\r\n\r\n    // EMAs\r\n    this.state.ema.mouthW = ema(this.state.ema.mouthW, mouthW, 0.25);\r\n    this.state.ema.mouthOpen = ema(this.state.ema.mouthOpen, mouthOpen, 0.25);\r\n    this.state.ema.brow = ema(this.state.ema.brow, brow, 0.25);\r\n    this.state.ema.ear = ema(this.state.ema.ear, ear, 0.25);\r\n    this.state.ema.motion = ema(this.state.ema.motion, motion, 0.4)!;\r\n\r\n    // Calibration\r\n    if (!this.state.calibrated) {\r\n      this.state.baseline.mouthW    = ema(this.state.baseline.mouthW,    mouthW,    0.15)!;\r\n      this.state.baseline.mouthOpen = ema(this.state.baseline.mouthOpen, mouthOpen, 0.15)!;\r\n      this.state.baseline.brow      = ema(this.state.baseline.brow,      brow,      0.15)!;\r\n      this.state.baseline.ear       = ema(this.state.baseline.ear,       ear,       0.15)!;\r\n      this.state.calibFrames++;\r\n      if (this.state.calibFrames >= this.state.calibTarget) this.state.calibrated = true;\r\n      this.frameEmotion = E.CALM;\r\n      return;\r\n    }\r\n\r\n    // Deviations\r\n    const dSmile = (this.state.ema.mouthW! - this.state.baseline.mouthW);\r\n    const dOpen  = (this.state.ema.mouthOpen! - this.state.baseline.mouthOpen);\r\n    const dBrow  = (this.state.ema.brow! - this.state.baseline.brow);\r\n    const dEar   = (this.state.ema.ear! - this.state.baseline.ear);\r\n\r\n    // Scores\r\n    const smileScore    = dSmile - dOpen * 0.3 + clamp(dEar, -0.05, 0.08) * 0.2;\r\n    const confusedScore = dOpen * 0.8 + dBrow * 0.6;\r\n    const stressScore   = (-dSmile * 0.4) + (-dEar * 0.8) + (this.state.ema.motion * 0.9) + (-dBrow * 0.4);\r\n    const focusScore    = (-Math.abs(dOpen) * 0.6) + (clamp(dEar, -0.02, 0.02) * -1) + (-this.state.ema.motion * 1.1);\r\n\r\n    // Classification\r\n    let emotion: Emotion = E.CALM;\r\n    if (smileScore > 0.05 && dSmile > 0.02) emotion = E.HAPPY;\r\n    if (confusedScore > 0.06 && dOpen > 0.015) emotion = E.CONFUSED;\r\n    if (stressScore > 0.08 || (dEar < -0.02 && this.state.ema.motion > 0.02)) emotion = E.STRESSED;\r\n\r\n    if (emotion === E.CALM) {\r\n      if (focusScore > -0.04 && this.state.ema.motion < 0.012 && Math.abs(dOpen) < 0.01) {\r\n        emotion = E.FOCUSED;\r\n      } else {\r\n        emotion = E.CALM;\r\n      }\r\n    }\r\n\r\n    this.frameEmotion = emotion;\r\n  }\r\n\r\n  private tick() {\r\n    this._setEmotion(this.frameEmotion, 0.9);\r\n  }\r\n\r\n  private _setEmotion(emotion: Emotion, conf = 0.0) {\r\n    this.setEmotionCore(emotion, conf);\r\n  }\r\n\r\n  private saveSettings() {\r\n    try {\r\n      localStorage.setItem('emcss_settings', JSON.stringify({\r\n        stabilitySize: this.state.stabilitySize,\r\n        updateInterval: this.state.updateInterval,\r\n        showVideo: this.showVideo?.checked ?? true,\r\n        overrideLocked: this.state.overrideLocked,\r\n        overrideEmotion: this.state.overrideEmotion\r\n      }));\r\n    } catch {}\r\n  }\r\n\r\n  private loadSettings() {\r\n    try {\r\n      const raw = localStorage.getItem('emcss_settings');\r\n      if (!raw) return;\r\n      const s = JSON.parse(raw);\r\n      if (typeof s.stabilitySize === 'number') {\r\n        this.state.stabilitySize = s.stabilitySize;\r\n        this.stabilityInput && (this.stabilityInput.value = String(s.stabilitySize));\r\n      }\r\n      if (typeof s.updateInterval === 'number') {\r\n        this.state.updateInterval = s.updateInterval;\r\n        this.intervalInput && (this.intervalInput.value = String(s.updateInterval));\r\n      }\r\n      if (typeof s.showVideo === 'boolean' && this.showVideo) {\r\n        this.showVideo.checked = s.showVideo;\r\n      }\r\n      if (typeof s.overrideLocked === 'boolean') this.state.overrideLocked = s.overrideLocked;\r\n      if (typeof s.overrideEmotion === 'string') this.state.overrideEmotion = s.overrideEmotion as Emotion;\r\n    } catch {}\r\n  }\r\n}\r\n"],"mappings":"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","names":["lm"]}