{
  "schema": "leumas.docs.page/1",
  "id": "pkg:@leumas/sing",
  "slug": "packages/sing",
  "kind": "capabilities",
  "bucket": "package",
  "title": "@leumas/sing",
  "name": "@leumas/sing",
  "eyebrow": null,
  "chip": null,
  "summary": "Leumas Sing — the karaoke game (\"Just Dance for karaoke\"). A HEADLESS game engine (src/engine: MPM pitch tracker, score engine, game clock, session state machine, library reader — zero...",
  "keywords": [
    "sing",
    "dance",
    "lms-sing",
    "react-3d-viewer",
    "tracker",
    "leumas sing",
    "karaoke",
    "screens"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "# @leumas/sing\n\n**Leumas Sing** — the karaoke game (\"Just Dance for karaoke\"). Pick a song, sing into the mic over\nthe instrumental, and get scored on timing, steadiness, and (with scoring v2) pitch, while a 3D\ndancer reacts on a cinematic stage. Leaderboards + live rooms make it a micro-community in Leumas\nSocial. Roadmap: `ops/todos/sing-roadmap.md`.\n\n## Layout\n\n- `src/engine/**` — the **headless** game core. No React, no DOM, no three, no CSS.\n  - `pitch/` — the pitch pipeline: `detectPitchMPM` (McLeod Pitch Method over the NSDF),\n    `createPitchTracker` (AnalyserNode + rAF → pitch frames), `createMicSource` (the shared mic with\n    the permission latch), `pitchMath` (freq⇄MIDI⇄note helpers).\n  - `constants.js` — tracker defaults, storage keys.\n- `src/react/**` — React bindings + screens (`MicLab`, `SingProvider`, `useMicPermission`).\n- `src/surfaces/**` — the mountable shell (`SingApp`) + `singRoutes()` for hosts.\n\n## Entries\n\n- `@leumas/sing` — React barrel (grows per phase).\n- `@leumas/sing/engine` — the headless core (usable in tests / a tuner / node).\n- `@leumas/sing/sing.css` — base skin, scoped under `.lms-sing`, tokens only.\n\n## Rules\n\n- `sing → music` only via `@leumas/music/karaoke` (timing utils). Music never imports sing.\n- Exactly one file may import `@leumas/react-3d-viewer` (the lazy 3D dancer), behind a quality gate.\n- Tokens only (`@leumas/theme`); CSS scoped under `.lms-sing`.\n",
  "source": {
    "path": "shared/packages/sing/README.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 1588,
    "hash": "2a0414631f65b2879b7b3aec57168623d143cad8"
  },
  "urls": {
    "html": "/p/packages/sing",
    "json": "/docs/packages/sing.json",
    "md": "/docs/packages/sing.md"
  },
  "links": {
    "composes": [
      "pkg:@leumas/theme",
      "pkg:@leumas/ui"
    ],
    "usedBy": [
      "pkg:@leumas/features",
      "pkg:@leumas/studio"
    ],
    "product": [
      "pkg:@leumas/admin",
      "pkg:@leumas/studio",
      "pkg:@leumas/web"
    ],
    "howTo": [],
    "skills": []
  },
  "exports": {
    "total": 54,
    "component": 26,
    "hook": 3,
    "helper": 25,
    "names": [
      {
        "n": "CalibrationModal",
        "k": "component"
      },
      {
        "n": "Challenges",
        "k": "component"
      },
      {
        "n": "DEFAULT_CALIBRATION_MS",
        "k": "component"
      },
      {
        "n": "GameStage",
        "k": "component"
      },
      {
        "n": "GRADES",
        "k": "component"
      },
      {
        "n": "History",
        "k": "component"
      },
      {
        "n": "Leaderboards",
        "k": "component"
      },
      {
        "n": "LyricLane",
        "k": "component"
      },
      {
        "n": "MIC_CONSTRAINTS",
        "k": "component"
      },
      {
        "n": "MicLab",
        "k": "component"
      },
      {
        "n": "MultiplayerLobby",
        "k": "component"
      },
      {
        "n": "NOTE_NAMES",
        "k": "component"
      },
      {
        "n": "PITCH_DEFAULTS",
        "k": "component"
      },
      {
        "n": "PitchLane",
        "k": "component"
      },
      {
        "n": "ResultsScreen",
        "k": "component"
      },
      {
        "n": "ScoreHud",
        "k": "component"
      },
      {
        "n": "SING_VERSION",
        "k": "component"
      },
      {
        "n": "SingApp",
        "k": "component"
      },
      {
        "n": "SingHome",
        "k": "component"
      },
      {
        "n": "SingPlay",
        "k": "component"
      },
      {
        "n": "SingProvider",
        "k": "component"
      },
      {
        "n": "SongPicker",
        "k": "component"
      },
      {
        "n": "STORAGE_KEYS",
        "k": "component"
      },
      {
        "n": "VerdictPopup",
        "k": "component"
      },
      {
        "n": "WordKaraokeLine",
        "k": "component"
      },
      {
        "n": "XP_FOR_GRADE",
        "k": "component"
      },
      {
        "n": "useMicPermission",
        "k": "hook"
      },
      {
        "n": "useSingContext",
        "k": "hook"
      },
      {
        "n": "useSingGame",
        "k": "hook"
      },
      {
        "n": "accuracyToGrade",
        "k": "helper"
      },
      {
        "n": "centsOff",
        "k": "helper"
      },
      {
        "n": "clamp01",
        "k": "helper"
      },
      {
        "n": "createCalibrator",
        "k": "helper"
      },
      {
        "n": "createGameClock",
        "k": "helper"
      },
      {
        "n": "createGameSession",
        "k": "helper"
      },
      {
        "n": "createLocalSessionDriver",
        "k": "helper"
      },
      {
        "n": "createMicSource",
        "k": "helper"
      },
      {
        "n": "createPitchTracker",
        "k": "helper"
      },
      {
        "n": "createRoomSessionDriver",
        "k": "helper"
      },
      {
        "n": "createScoreEngine",
        "k": "helper"
      },
      {
        "n": "detectPitchMPM",
        "k": "helper"
      },
      {
        "n": "foldToOctave",
        "k": "helper"
      },
      {
        "n": "freqToMidi",
        "k": "helper"
      },
      {
        "n": "getMicState",
        "k": "helper"
      },
      {
        "n": "judgeWord",
        "k": "helper"
      },
      {
        "n": "listSingableTracks",
        "k": "helper"
      },
      {
        "n": "loadChart",
        "k": "helper"
      },
      {
        "n": "medianOfWindow",
        "k": "helper"
      },
      {
        "n": "midiToFreq",
        "k": "helper"
      },
      {
        "n": "multiplierForCombo",
        "k": "helper"
      },
      {
        "n": "noteName",
        "k": "helper"
      },
      {
        "n": "onMicState",
        "k": "helper"
      },
      {
        "n": "retryMic",
        "k": "helper"
      },
      {
        "n": "singRoutes",
        "k": "helper"
      }
    ]
  }
}
