# 단어를 맞춰라 · Find-Word v0.1.1 소음 속에 숨은 한국어 단어를 듣고 찾는 반응형 웹 게임입니다. **Designed by OZ at Heat-T Medical Inc.** Canonical repository: [OZ-Group/Find-Word](https://source.ibit.kr/OZ-Group/Find-Word). 프로젝트 자체는 **private / all-rights-reserved**이며 `package.json`의 `license`는 `UNLICENSED`입니다. [LICENSE](LICENSE)를 참고하세요. 런타임 의존성 React, ReactDOM, scheduler의 MIT 전문은 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)에 보존하며, `public/THIRD_PARTY_NOTICES.md`가 빌드 시 `dist/THIRD_PARTY_NOTICES.md`로 복사됩니다. 빌드 검증기는 설치된 의존성의 라이선스 전문·버전과 세 사본을 대조합니다. React + TypeScript strict + Vite로 만든 정적 SPA입니다. 로그인, 개인정보 저장, 분석 도구, 외부 CDN, 런타임 TTS/API 요청이 없습니다. 청각적 주의·식별 게임이며 의료적 진단·치료나 효과를 주장하지 않습니다. ## 실행 Node.js 최소 버전은 **22.22.2** (`>=22.22.2`)입니다. 잠긴 jsdom 계열 의존성이 요구하는 지원 범위는 22.x의 22.22.2 이상, 24.x의 24.15.0 이상 또는 26.0.0 이상입니다. 이 중 지원되는 LTS 버전을 사용하세요. `package-lock.json`을 포함하므로 새 환경에서는 `npm ci`를 사용합니다. 이번 검증 환경은 Node 26.7.0입니다. ```bash npm ci npm run dev ``` 표시되는 `http://127.0.0.1:5173`에서 사용합니다. 소리는 사용자가 **게임 시작 · 소리 듣기**를 누른 뒤에만 재생합니다. 낮은 음량부터 조절하고 헤드폰이나 스피커를 사용할 수 있습니다. ## 플레이 - 골고루 풀기, 보기에서 선택, 직접 입력 중 선택합니다. - 8개 환경을 순환하거나 하나를 지정합니다. - 에스의 안내가 배경에 묻힌 뒤 목표 문장이 나옵니다. 재생 후 질문에 답합니다. - 10문제 동안 2문제마다 난이도가 올라갑니다: **SNR +6, +3, 0, −3, −6 dB**. 양수는 음성이 배경보다 크고, 0은 같고, 음수는 더 작다는 뜻입니다. - 다시 듣기는 감점하지 않습니다. 정답은 `단계 × 100점`, 연속 정답은 최대 40점의 보너스를 받습니다. - 결과에서 점수·정답률·최고 연속 정답·단계별 결과를 확인하고 다시 시작할 수 있습니다. - 새로고침하면 기록이 사라집니다. 결과를 브라우저나 서버에 저장하지 않습니다. 10개 유형 × 10개 단어의 100개 목표 문장을 저장했습니다. 각 세션은 유형과 단어를 섞어 출제하며 정답 위치도 섞습니다. 사전 표제어와 변형 규칙은 [WORDS.md](docs/WORDS.md)에 설명했습니다. 청취 과제는 직접 목표 식별, 연습 암호와 진짜 암호 구별, 앞 단어를 잊고 다음 단어 기억, 첫째·마지막·가운데 선택, 반복 찾기, 정정 반영, 신호 조건 적용, 오른쪽 표지 선택의 10가지입니다. 문장에 실제 보기의 오답도 포함됩니다. ## 검증과 정적 빌드 ```bash npm run lint npm test npm run build npm run preview ``` `lint`는 ESLint와 TypeScript 검사, `test`는 unit/component/자산/빌드 검증기 테스트를 실행합니다. `build`는 `dist/`를 만들고 음성 101개가 원본 해시 그대로 포함되었는지 확인합니다. 빌드에는 음성 합성 도구가 필요하지 않습니다. 런타임 MIT notice가 `dist/`에 전문 그대로 포함되는지도 검증합니다. 실제 오디오·360px/1280px 화면·키보드·접근성·오류 재시도 검증: ```bash # Chromium이 없는 개발 환경에서 한 번만 실행합니다. npx playwright install chromium npm run test:browser # 이미 설치된 Chrome을 사용할 때의 대안입니다. CHROME_PATH=/usr/bin/google-chrome npm run test:browser ``` Chromium sandbox는 기본으로 켭니다. sandbox를 지원하지 않는 격리된 개발 환경에서만 `PLAYWRIGHT_NO_SANDBOX=1`을 명시해 끌 수 있습니다. `0`, `false`, 빈 값이나 미설정은 sandbox를 유지합니다. `CHROME_PATH` 지정은 sandbox를 끄지 않습니다. 브라우저 테스트는 기존 `dist/`를 사용하므로 소스 변경 후 먼저 빌드하세요. 실제 음성 재생이 끝나기를 기다려 약 2–3분이 걸립니다. 로컬 4173 포트를 테스트 중에만 열고 종료합니다. 스크린샷과 101개 WAV의 query URL·해시·디코드 결과는 `test-results/`에 저장합니다. 인수 기록은 실행별 새 evidence 경로에 복사하여 `.agent/evidence-v0.1.1/`의 과거 결과를 보존합니다. ## 음성과 문서 한국어 WAV 101개는 직접 쓴 문장을 Microsoft Edge online TTS의 `ko-KR-HyunsuMultilingualNeural`로 새로 생성했습니다. edge-tts **7.3.1**, rate `-6%`, pitch `-4Hz`이며 FFmpeg로 **24kHz mono PCM16**으로 변환합니다. 생성 시 네트워크가 필요하며 앱은 저장된 WAV만 재생합니다. 환경음은 브라우저에서 고정 seed로 합성합니다. 생성 음성의 독점 권리를 주장하지 않습니다. intro와 목표 WAV는 모두 `/audio/파일명.wav?v=0.1.1`로 요청합니다. `src/audio/assets.ts`의 자산 버전 한 곳을 사용하며, 같은 파일명으로 음성을 교체할 때 이 값을 갱신해 기존 7일 캐시와 구분합니다. 제품 버전은 0.1.1입니다. Linux에서 Python 3.11 이상과 FFmpeg를 준비한 뒤 다음 명령을 사용합니다. 클라이언트 버전을 고정해도 원격 모델 변경으로 동일 바이트 재생성은 보장하지 않습니다. ```bash python3 -m venv .venv-audio .venv-audio/bin/python -m pip install -r requirements-audio.txt .venv-audio/bin/python -m pip check npm run audio:generate ``` 고정 venv의 Python이 101개 모두 임시 생성·검증하고 디렉터리를 원자 교체합니다. 요청별 60초 제한과 최대 3회 시도를 적용하며, 실패 시 기존 자산을 보존합니다. 청취 샘플: [안내](public/audio/intro.wav), [행운의 사과](public/audio/luck-apple.wav). 생성 방법, 도구 라이선스, 합성 음질의 한계는 [AUDIO_PROVENANCE.md](docs/AUDIO_PROVENANCE.md)를 참고하세요. 실제 음량은 출력 장치에 따라 달라지며 표기 dB는 디지털 상대값입니다. - [설계와 상태 전이](docs/ARCHITECTURE.md) - [Neo를 위한 정적 배포 안내](docs/DEPLOYMENT.md) - [v0.1.1 RED/GREEN 및 실제 검증 결과](.agent/RESULT-v0.1.1.md) - [v0.1 역사 기록](.agent/RESULT.md) 이번 작업에서는 서버 배포와 Git commit/push를 실행하지 않습니다.