eye-care 1.0.0

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.
Files changed (63) hide show
  1. package/AGENTS.md +48 -0
  2. package/CODE_OF_CONDUCT.md +44 -0
  3. package/CONTRIBUTING.md +67 -0
  4. package/LICENSE +21 -0
  5. package/README.md +178 -0
  6. package/bin/eye-care.js +22 -0
  7. package/build/icon.ico +0 -0
  8. package/build/icon.png +0 -0
  9. package/build/tray.png +0 -0
  10. package/build/tray@2x.png +0 -0
  11. package/out/data/exercises.js +120 -0
  12. package/out/data/exercises.js.map +1 -0
  13. package/out/data/i18n.js +211 -0
  14. package/out/data/i18n.js.map +1 -0
  15. package/out/main/backgrounds.js +180 -0
  16. package/out/main/backgrounds.js.map +1 -0
  17. package/out/main/index.js +258 -0
  18. package/out/main/index.js.map +1 -0
  19. package/out/main/preferences.js +71 -0
  20. package/out/main/preferences.js.map +1 -0
  21. package/out/main/scheduler.js +106 -0
  22. package/out/main/scheduler.js.map +1 -0
  23. package/out/preload/break.js +9 -0
  24. package/out/preload/break.js.map +1 -0
  25. package/out/preload/settings.js +18 -0
  26. package/out/preload/settings.js.map +1 -0
  27. package/out/renderer/backgrounds/forest.svg +13 -0
  28. package/out/renderer/backgrounds/mountains.svg +13 -0
  29. package/out/renderer/backgrounds/sea.svg +13 -0
  30. package/out/renderer/backgrounds/sunny-sky.svg +16 -0
  31. package/out/renderer/backgrounds/sunset.svg +18 -0
  32. package/out/renderer/break.css +265 -0
  33. package/out/renderer/break.html +38 -0
  34. package/out/renderer/break.js +452 -0
  35. package/out/renderer/settings.css +198 -0
  36. package/out/renderer/settings.html +110 -0
  37. package/out/renderer/settings.js +407 -0
  38. package/out/shared/types.js +23 -0
  39. package/out/shared/types.js.map +1 -0
  40. package/package.json +100 -0
  41. package/scripts/copy-static.js +27 -0
  42. package/scripts/make-icon.js +120 -0
  43. package/src/data/exercises.ts +120 -0
  44. package/src/data/i18n.ts +297 -0
  45. package/src/main/backgrounds.ts +144 -0
  46. package/src/main/index.ts +233 -0
  47. package/src/main/preferences.ts +34 -0
  48. package/src/main/scheduler.ts +105 -0
  49. package/src/preload/break.ts +9 -0
  50. package/src/preload/settings.ts +18 -0
  51. package/src/renderer/backgrounds/forest.svg +13 -0
  52. package/src/renderer/backgrounds/mountains.svg +13 -0
  53. package/src/renderer/backgrounds/sea.svg +13 -0
  54. package/src/renderer/backgrounds/sunny-sky.svg +16 -0
  55. package/src/renderer/backgrounds/sunset.svg +18 -0
  56. package/src/renderer/break.css +265 -0
  57. package/src/renderer/break.html +38 -0
  58. package/src/renderer/break.js +452 -0
  59. package/src/renderer/settings.css +198 -0
  60. package/src/renderer/settings.html +110 -0
  61. package/src/renderer/settings.js +407 -0
  62. package/src/shared/types.ts +82 -0
  63. package/tsconfig.json +19 -0
package/AGENTS.md ADDED
@@ -0,0 +1,48 @@
1
+ # AGENTS.md - guide for AI assistants working on eye-care
2
+
3
+ ## Project
4
+
5
+ PC eye-exercise reminder app. Electron + TypeScript. Open source (MIT).
6
+
7
+ ## Stack
8
+
9
+ - Runtime: Electron 33+, Node 18+
10
+ - Language: TypeScript (strict mode, no `any` without justification)
11
+ - Module system: CommonJS (Electron main); renderer uses ES modules via preload bridge
12
+ - No bundler yet — plain `tsc` to `out/`. HTML/CSS/TS loaded directly by Electron.
13
+
14
+ ## Commands
15
+
16
+ - `npm run dev` — typecheck-watch + launch Electron
17
+ - `npm run build` — compile TS to `out/`
18
+ - `npm run start` — build then launch
19
+ - `npm run typecheck` — typecheck only, no emit
20
+ - `npm run clean` — remove `out/` and `dist/`
21
+
22
+ ## Layout
23
+
24
+ ```
25
+ src/
26
+ main/ Electron main process
27
+ preload/ Preload bridges (context isolation, no nodeIntegration)
28
+ renderer/ UI for break & settings windows
29
+ data/ Eye-exercise routines (ophthalmology-sourced)
30
+ shared/ Types shared between main and renderer
31
+ out/ Compiled JS (gitignored)
32
+ ```
33
+
34
+ ## Conventions
35
+
36
+ - Commits: conventional-commit prefixes (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`)
37
+ - No emoji in code or commits unless explicitly requested
38
+ - No comments in code unless requested or non-obvious safety reason
39
+ - Every exercise in `src/data/` MUST cite a reputable ophthalmology source
40
+ - Never claim "vision restoration" / "myopia cure" — not medically supported
41
+ - Context isolation ON, nodeIntegration OFF, preload bridges for IPC
42
+ - Run `npm run typecheck` before considering work done
43
+
44
+ ## Medical safety
45
+
46
+ This app is for eye-fatigue relief only. Do not add features implying medical
47
+ treatment, diagnosis, or vision correction. When in doubt, cite the American
48
+ Academy of Ophthalmology (AAO) or similar body and frame as "rest/fatigue relief".
@@ -0,0 +1,44 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, religion, or sexual identity
10
+ and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment:
18
+
19
+ * Demonstrating empathy and kindness toward other people
20
+ * Being respectful of differing opinions, viewpoints, and experiences
21
+ * Giving and gracefully accepting constructive feedback
22
+ * Accepting responsibility and apologizing to those affected by our mistakes
23
+ * Focusing on what is best for the overall community
24
+
25
+ Examples of unacceptable behavior:
26
+
27
+ * The use of sexualized language or imagery, and sexual attention or advances
28
+ * Trolling, insulting or derogatory comments, and personal or political attacks
29
+ * Public or private harassment
30
+ * Publishing others' private information without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate
32
+
33
+ ## Enforcement
34
+
35
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
36
+ reported to the maintainers at https://github.com/rudylee/eye-care/issues.
37
+
38
+ All complaints will be reviewed and investigated promptly and fairly.
39
+
40
+ ## Attribution
41
+
42
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
43
+ version 2.1, available at
44
+ https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
@@ -0,0 +1,67 @@
1
+ # Contributing to eye-care
2
+
3
+ Thanks for your interest in contributing! This is a community-driven open-source health tool, so quality, safety, and transparency matter more than speed.
4
+
5
+ ## Project setup
6
+
7
+ Requirements:
8
+ - Node.js >= 18 (developed on Node 20/22)
9
+ - npm >= 9
10
+
11
+ ```bash
12
+ git clone https://github.com/uptodatelabs/eye-care.git
13
+ cd eye-care
14
+ npm install
15
+ npm run dev
16
+ ```
17
+
18
+ ## Project layout
19
+
20
+ ```
21
+ src/
22
+ main/ Electron main process (window, tray, scheduler)
23
+ preload/ Preload bridges (context-isolated)
24
+ renderer/ UI HTML/CSS/TS for break & settings windows
25
+ data/ Eye-exercise routines (ophthalmology-sourced)
26
+ shared/ Types shared between main/renderer
27
+ out/ Compiled JS (gitignored)
28
+ ```
29
+
30
+ ## How to contribute
31
+
32
+ ### Good first issues
33
+ - Translating exercise instructions (i18n)
34
+ - Adding new exercises backed by ophthalmology sources
35
+ - OS-specific testing (Windows/macOS/Linux)
36
+ - Accessibility improvements (screen readers, high-contrast)
37
+
38
+ ### Adding an eye exercise
39
+
40
+ Every exercise in `src/data/` MUST include:
41
+
42
+ 1. A citation to a reputable ophthalmology source (AAO, NEI, NHS, peer-reviewed paper, etc.)
43
+ 2. A clear `durationSeconds`
44
+ 3. Step-by-step instructions safe for the general public
45
+
46
+ **Do not** add exercises that promise "vision correction" or "myopia cure" — these lack medical consensus and can mislead users.
47
+
48
+ ### Commit style
49
+
50
+ - Use clear, conventional-commit-style messages: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`
51
+ - Keep commits focused; one logical change per commit
52
+ - Reference issues when relevant: `fix: tray menu crash on Windows (#12)`
53
+
54
+ ### Before opening a PR
55
+
56
+ 1. `npm run typecheck` passes
57
+ 2. `npm run build` succeeds
58
+ 3. No new TypeScript `any` types without justification
59
+ 4. README updated if user-facing behavior changed
60
+
61
+ ## Code of conduct
62
+
63
+ See [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md). Be kind, assume good intent.
64
+
65
+ ## License
66
+
67
+ By contributing you agree your contributions are licensed under the project's MIT license.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 eye-care contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # eye-care
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
4
+ [![Version](https://img.shields.io/badge/version-1.0.0-green.svg)](#)
5
+
6
+ A PC eye-exercise reminder app for monitor-heavy users. Built with Electron + TypeScript. Open source (MIT).
7
+
8
+ > **Medical disclaimer:** This software is for eye-fatigue relief and rest reminders only. It is NOT a medical device, does not diagnose or treat any condition, and is not a substitute for professional ophthalmologic care. Claims about "vision restoration" or "curing myopia" are not supported by modern ophthalmology; this app intentionally avoids them.
9
+
10
+ ---
11
+
12
+ ## English
13
+
14
+ ### Why
15
+
16
+ Mobile apps for eye exercises are common, but well-made PC apps that **guide actual eye exercises** (not just "take a break" reminders) are rare. `eye-care` periodically overlays a guided exercise on your screen based on ophthalmologist-recommended practices.
17
+
18
+ ### Features
19
+
20
+ - **Guided eye exercises** with animated SVG visual guides — not just text reminders
21
+ - **6 evidence-based exercises** sourced from the American Academy of Ophthalmology (AAO) and American Optometric Association (AOA):
22
+ - **20-20-20 rule** — every 20 min, look 20 ft (6 m) away for 20 s
23
+ - **Conscious blinking** — counter the ~66% reduction in blink rate during screen work
24
+ - **Near-far focus shift** — alternate focus between near and distant targets
25
+ - **Figure-8 tracing** — slow eye movement to relieve fatigue
26
+ - **Palming** — cover eyes with warm palms to relax
27
+ - **Horizontal eye rolls** — slow horizontal sweeping
28
+ - **Two break types** with configurable intervals:
29
+ - Mini break (default: every 20 min, 20 s)
30
+ - Long break (default: every 50 min, 5 min)
31
+ - **Audio cues** — chimes on exercise start, step end, and break complete (helps during eyes-closed exercises like palming)
32
+ - **Background images** — 5 built-in nature scenes (sunny sky, forest, sea, mountains, sunset) or upload your own. Adjustable blur strength.
33
+ - **Languages** — English and Korean
34
+ - **System tray** integration — lives in your tray, breaks appear as fullscreen overlay
35
+ - **Cross-platform** — Windows, macOS, Linux
36
+
37
+ ### Install
38
+
39
+ #### Option 1: Desktop installer (recommended for general users)
40
+
41
+ Download the latest installer from [GitHub Releases](https://github.com/uptodatelabs/eye-care/releases):
42
+
43
+ - **Windows**: `eye-care Setup 1.0.0.exe` — auto-creates desktop and start menu shortcuts
44
+ - **macOS**: `eye-care-1.0.0.dmg`
45
+ - **Linux**: `eye-care-1.0.0.AppImage` or `.deb`
46
+
47
+ #### Option 2: npm (for developers)
48
+
49
+ ```bash
50
+ npm install -g eye-care
51
+ eye-care
52
+ ```
53
+
54
+ ### Build from source
55
+
56
+ Requirements: Node.js >= 18, npm >= 9.
57
+
58
+ ```bash
59
+ git clone https://github.com/uptodatelabs/eye-care.git
60
+ cd eye-care
61
+ npm install
62
+ npm start
63
+ ```
64
+
65
+ ### Usage
66
+
67
+ 1. Launch eye-care — it lives in your system tray.
68
+ 2. Right-click the tray icon to:
69
+ - Take a mini / long break now
70
+ - Pause breaks for 1 hour
71
+ - Open settings
72
+ - Quit
73
+ 3. When a break starts, a fullscreen overlay appears with a guided exercise. Follow the animated guide and on-screen instructions.
74
+ 4. Click "Skip break" or press the tray menu to dismiss early.
75
+
76
+ ### Settings
77
+
78
+ - **Language** — English / 한국어
79
+ - **Background** — None / Built-in / User images / Random, with adjustable blur
80
+ - **Mini break** — enable, interval, duration
81
+ - **Long break** — enable, interval, duration
82
+ - **Sound notifications** — on/off
83
+ - **Strict mode** — disable skipping
84
+
85
+ ### Screenshots
86
+
87
+ _Screenshots coming soon._
88
+
89
+ ### Contributing
90
+
91
+ See [CONTRIBUTING.md](CONTRIBUTING.md). We welcome translations, new exercises (with ophthalmology citations), OS testing, and accessibility improvements.
92
+
93
+ ### License
94
+
95
+ MIT — see [LICENSE](LICENSE).
96
+
97
+ ---
98
+
99
+ ## 한국어
100
+
101
+ ### 왜 만들었나요
102
+
103
+ 모바일용 눈운동 앱은 많지만, PC에서 **실제 운동을 가이드**해주는 앱 (단순 휴식 알림이 아닌)은 드뭅니다. `eye-care`는 안과 의사가 권장하는 방법에 따라 주기적으로 화면에 가이드 운동을 띄워줍니다.
104
+
105
+ ### 기능
106
+
107
+ - **애니메이션 SVG 가이드**가 포함된 안내식 눈 운동 — 글자만 보여주는 알림이 아닙니다
108
+ - **안과학회(AAO)와 검안사협회(AOA) 근거의 6가지 운동:**
109
+ - **20-20-20 규칙** — 20분마다 20피트(6m) 너머를 20초간 응시
110
+ - **의식적 깜빡임** — 모니터 작업 시 1/3로 줄어드는 깜빡임 보충
111
+ - **원근 촛점 교대** — 가까운 곳과 먼 곳을 번갈아 응시
112
+ - **8자 추적** — 느린 눈 운동으로 피로 완화
113
+ - **파밍** — 따뜻한 손바닥으로 감은 눈을 덮어 휴식
114
+ - **좌우 눈 운동** — 느린 좌우 스윕
115
+ - **두 가지 휴식 (설정 가능):**
116
+ - 미니 휴식 (기본: 20분 간격, 20초)
117
+ - 긴 휴식 (기본: 50분 간격, 5분)
118
+ - **효과음** — 운동 시작, 단계 종료, 휴식 완료 시 차임 (파밍처럼 눈 감는 운동에서 유용)
119
+ - **배경화면** — 5가지 기본 자연 풍경(맑은 하늘, 숲, 바다, 산, 노을) 또는 사용자 이미지 업로드. 흐림 정도 조절 가능.
120
+ - **언어** — 영어 / 한국어
121
+ - **시스템 트레이** — 트레이에 상주, 휴식 시 전체화면 오버레이
122
+ - **크로스플랫폼** — Windows, macOS, Linux
123
+
124
+ ### 설치
125
+
126
+ #### 방법 1: 데스크톱 설치 파일 (일반 사용자 권장)
127
+
128
+ [GitHub Releases](https://github.com/uptodatelabs/eye-care/releases)에서 최신 설치 파일을 다운로드:
129
+
130
+ - **Windows**: `eye-care Setup 1.0.0.exe` — 바탕화면 및 시작 메뉴 바로가기 자동 생성
131
+ - **macOS**: `eye-care-1.0.0.dmg`
132
+ - **Linux**: `eye-care-1.0.0.AppImage` 또는 `.deb`
133
+
134
+ #### 방법 2: npm (개발자용)
135
+
136
+ ```bash
137
+ npm install -g eye-care
138
+ eye-care
139
+ ```
140
+
141
+ ### 소스에서 빌드
142
+
143
+ 요구사항: Node.js 18 이상, npm 9 이상.
144
+
145
+ ```bash
146
+ git clone https://github.com/uptodatelabs/eye-care.git
147
+ cd eye-care
148
+ npm install
149
+ npm start
150
+ ```
151
+
152
+ ### 사용법
153
+
154
+ 1. eye-care를 실행하면 시스템 트레이에 상주합니다.
155
+ 2. 트레이 아이콘 우클릭:
156
+ - 지금 미니 / 긴 휴식하기
157
+ - 1시간 동안 휴식 일시정지
158
+ - 설정 열기
159
+ - 종료
160
+ 3. 휴식이 시작되면 전체화면 오버레이로 가이드 운동이 나타납니다. 애니메이션과 지시문을 따라 하세요.
161
+ 4. "휴식 건너뛰기" 버튼이나 트레이 메뉴로 일찍 종료할 수 있습니다.
162
+
163
+ ### 설정
164
+
165
+ - **언어** — English / 한국어
166
+ - **배경화면** — 없음 / 기본 제공 / 사용자 이미지 / 랜덤, 흐림 정도 조절
167
+ - **미니 휴식** — 사용 여부, 간격, 시간
168
+ - **긴 휴식** — 사용 여부, 간격, 시간
169
+ - **소리 알림** — 켜기/끄기
170
+ - **엄격 모드** — 건너뛰기 금지
171
+
172
+ ### 기여
173
+
174
+ [CONTRIBUTING.md](CONTRIBUTING.md)를 참고하세요. 번역, 새 운동 추가 (안과 출처 필수), OS별 테스트, 접근성 개선을 환영합니다.
175
+
176
+ ### 라이선스
177
+
178
+ MIT — [LICENSE](LICENSE) 참고.
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require("child_process");
4
+ const path = require("path");
5
+ const fs = require("fs");
6
+
7
+ const electronPath = require("electron");
8
+ const appRoot = path.resolve(__dirname, "..");
9
+
10
+ if (!fs.existsSync(path.join(appRoot, "out", "main", "index.js"))) {
11
+ console.error("eye-care: build output not found. Run `npm run build` first.");
12
+ process.exit(1);
13
+ }
14
+
15
+ const child = spawn(electronPath, [appRoot], {
16
+ stdio: "inherit",
17
+ windowsHide: false,
18
+ });
19
+
20
+ child.on("close", (code) => {
21
+ process.exit(code);
22
+ });
package/build/icon.ico ADDED
Binary file
package/build/icon.png ADDED
Binary file
package/build/tray.png ADDED
Binary file
Binary file
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EXERCISES = void 0;
4
+ exports.exercisesForBreak = exercisesForBreak;
5
+ exports.EXERCISES = [
6
+ {
7
+ id: "20-20-20",
8
+ name: "20-20-20 Rule",
9
+ shortDescription: "Look at something 20 feet away for 20 seconds.",
10
+ steps: [
11
+ {
12
+ text: "Look at an object at least 20 feet (6 m) away — out a window or across the room.",
13
+ durationSeconds: 20,
14
+ },
15
+ ],
16
+ source: "American Academy of Ophthalmology",
17
+ sourceUrl: "https://www.aao.org/eye-health/tips-prevention/computer-vision-syndrome",
18
+ forBreakTypes: ["mini", "long"],
19
+ },
20
+ {
21
+ id: "conscious-blink",
22
+ name: "Conscious Blinking",
23
+ shortDescription: "Blink slowly to remoisten your eyes.",
24
+ steps: [
25
+ { text: "Close your eyes gently and softly for 2 seconds.", durationSeconds: 2 },
26
+ { text: "Open slowly. Repeat the slow blink at a relaxed pace.", durationSeconds: 18 },
27
+ ],
28
+ source: "American Academy of Ophthalmology — Computer Vision Syndrome",
29
+ sourceUrl: "https://www.aao.org/eye-health/tips-prevention/computer-vision-syndrome",
30
+ forBreakTypes: ["mini", "long"],
31
+ },
32
+ {
33
+ id: "near-far-focus",
34
+ name: "Near-Far Focus Shift",
35
+ shortDescription: "Alternate focus between a near and distant target.",
36
+ steps: [
37
+ { text: "Hold your finger 10-15 inches (25-38 cm) from your eyes and focus on it.", durationSeconds: 5 },
38
+ { text: "Shift focus to an object 20 feet (6 m) or farther away.", durationSeconds: 5 },
39
+ { text: "Back to your finger.", durationSeconds: 5 },
40
+ { text: "Back to the distant object. Repeat smoothly.", durationSeconds: 5 },
41
+ ],
42
+ source: "American Optometric Association — Computer Vision Initiative",
43
+ sourceUrl: "https://www.aoa.org/healthy-eyes/caring-for-your-eyes/protecting-your-eyes/computer-vision-syndrome",
44
+ forBreakTypes: ["long"],
45
+ },
46
+ {
47
+ id: "figure-eight",
48
+ name: "Figure-8 Tracing",
49
+ shortDescription: "Trace an imaginary figure-8 with your eyes to relax eye muscles.",
50
+ steps: [
51
+ { text: "Imagine a large figure-8 on the wall about 10 feet (3 m) away.", durationSeconds: 5 },
52
+ { text: "Slowly trace it one way with your eyes only (head still).", durationSeconds: 10 },
53
+ { text: "Reverse direction and trace it back.", durationSeconds: 10 },
54
+ ],
55
+ source: "American Academy of Ophthalmology — Eye Exercises",
56
+ sourceUrl: "https://www.aao.org/eye-health/tips-prevention/eye-exercises",
57
+ forBreakTypes: ["long"],
58
+ },
59
+ {
60
+ id: "palming",
61
+ name: "Palming",
62
+ shortDescription: "Cover closed eyes with warm palms to relax.",
63
+ steps: [
64
+ { text: "Rub your palms together until they feel warm.", durationSeconds: 5 },
65
+ { text: "Close your eyes and cup your palms over them without pressing on the eyeballs.", durationSeconds: 30 },
66
+ { text: "Breathe slowly and relax. Keep the position.", durationSeconds: 25 },
67
+ ],
68
+ source: "American Academy of Ophthalmology — Eye Exercises",
69
+ sourceUrl: "https://www.aao.org/eye-health/tips-prevention/eye-exercises",
70
+ forBreakTypes: ["long"],
71
+ },
72
+ {
73
+ id: "horizontal-rolls",
74
+ name: "Horizontal Eye Rolls",
75
+ shortDescription: "Slow horizontal eye movement to relieve fatigue.",
76
+ steps: [
77
+ { text: "Look as far right as comfortable (head still).", durationSeconds: 4 },
78
+ { text: "Slowly move your gaze to the far left.", durationSeconds: 4 },
79
+ { text: "Back to center.", durationSeconds: 2 },
80
+ { text: "Repeat the slow sweep a few more times.", durationSeconds: 10 },
81
+ ],
82
+ source: "American Academy of Ophthalmology — Eye Exercises",
83
+ sourceUrl: "https://www.aao.org/eye-health/tips-prevention/eye-exercises",
84
+ forBreakTypes: ["mini", "long"],
85
+ },
86
+ ];
87
+ function exercisesForBreak(type, durationSeconds) {
88
+ const pool = exports.EXERCISES.filter((e) => e.forBreakTypes.includes(type));
89
+ if (pool.length === 0)
90
+ return [];
91
+ const selected = [];
92
+ let used = 0;
93
+ let i = 0;
94
+ while (used < durationSeconds) {
95
+ const ex = pool[i % pool.length];
96
+ const exTotal = ex.steps.reduce((s, st) => s + st.durationSeconds, 0);
97
+ const remaining = durationSeconds - used;
98
+ if (exTotal <= remaining) {
99
+ selected.push({ ...ex, id: ex.id + "-" + i });
100
+ used += exTotal;
101
+ }
102
+ else {
103
+ const scaled = {
104
+ ...ex,
105
+ id: ex.id + "-" + i,
106
+ steps: ex.steps.map((st) => ({
107
+ text: st.text,
108
+ durationSeconds: Math.max(3, Math.round((st.durationSeconds / exTotal) * remaining)),
109
+ })),
110
+ };
111
+ const scaledTotal = scaled.steps.reduce((s, st) => s + st.durationSeconds, 0);
112
+ selected.push(scaled);
113
+ used += scaledTotal;
114
+ break;
115
+ }
116
+ i += 1;
117
+ }
118
+ return selected;
119
+ }
120
+ //# sourceMappingURL=exercises.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exercises.js","sourceRoot":"","sources":["../../src/data/exercises.ts"],"names":[],"mappings":"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"}