skill-calorie 0.1.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 (373) hide show
  1. package/dist/analysis/anomaly/common.d.ts +53 -0
  2. package/dist/analysis/anomaly/common.d.ts.map +1 -0
  3. package/dist/analysis/anomaly/common.js +69 -0
  4. package/dist/analysis/anomaly/common.js.map +1 -0
  5. package/dist/analysis/anomaly/diet.d.ts +8 -0
  6. package/dist/analysis/anomaly/diet.d.ts.map +1 -0
  7. package/dist/analysis/anomaly/diet.js +95 -0
  8. package/dist/analysis/anomaly/diet.js.map +1 -0
  9. package/dist/analysis/anomaly/exercise.d.ts +9 -0
  10. package/dist/analysis/anomaly/exercise.d.ts.map +1 -0
  11. package/dist/analysis/anomaly/exercise.js +116 -0
  12. package/dist/analysis/anomaly/exercise.js.map +1 -0
  13. package/dist/analysis/anomaly/index.d.ts +19 -0
  14. package/dist/analysis/anomaly/index.d.ts.map +1 -0
  15. package/dist/analysis/anomaly/index.js +51 -0
  16. package/dist/analysis/anomaly/index.js.map +1 -0
  17. package/dist/analysis/anomaly/overall.d.ts +13 -0
  18. package/dist/analysis/anomaly/overall.d.ts.map +1 -0
  19. package/dist/analysis/anomaly/overall.js +128 -0
  20. package/dist/analysis/anomaly/overall.js.map +1 -0
  21. package/dist/analysis/anomaly/overall2.d.ts +5 -0
  22. package/dist/analysis/anomaly/overall2.d.ts.map +1 -0
  23. package/dist/analysis/anomaly/overall2.js +94 -0
  24. package/dist/analysis/anomaly/overall2.js.map +1 -0
  25. package/dist/analysis/anomaly/weight.d.ts +8 -0
  26. package/dist/analysis/anomaly/weight.d.ts.map +1 -0
  27. package/dist/analysis/anomaly/weight.js +106 -0
  28. package/dist/analysis/anomaly/weight.js.map +1 -0
  29. package/dist/analysis/anomaly/weight2.d.ts +4 -0
  30. package/dist/analysis/anomaly/weight2.d.ts.map +1 -0
  31. package/dist/analysis/anomaly/weight2.js +59 -0
  32. package/dist/analysis/anomaly/weight2.js.map +1 -0
  33. package/dist/analysis/contraindications.d.ts +63 -0
  34. package/dist/analysis/contraindications.d.ts.map +1 -0
  35. package/dist/analysis/contraindications.js +121 -0
  36. package/dist/analysis/contraindications.js.map +1 -0
  37. package/dist/analysis/cross.d.ts +75 -0
  38. package/dist/analysis/cross.d.ts.map +1 -0
  39. package/dist/analysis/cross.js +283 -0
  40. package/dist/analysis/cross.js.map +1 -0
  41. package/dist/analysis/dashboard.d.ts +18 -0
  42. package/dist/analysis/dashboard.d.ts.map +1 -0
  43. package/dist/analysis/dashboard.js +48 -0
  44. package/dist/analysis/dashboard.js.map +1 -0
  45. package/dist/analysis/deficit.d.ts +44 -0
  46. package/dist/analysis/deficit.d.ts.map +1 -0
  47. package/dist/analysis/deficit.js +54 -0
  48. package/dist/analysis/deficit.js.map +1 -0
  49. package/dist/analysis/diet.d.ts +76 -0
  50. package/dist/analysis/diet.d.ts.map +1 -0
  51. package/dist/analysis/diet.js +164 -0
  52. package/dist/analysis/diet.js.map +1 -0
  53. package/dist/analysis/exercise.d.ts +98 -0
  54. package/dist/analysis/exercise.d.ts.map +1 -0
  55. package/dist/analysis/exercise.js +298 -0
  56. package/dist/analysis/exercise.js.map +1 -0
  57. package/dist/analysis/exerciseReview.d.ts +36 -0
  58. package/dist/analysis/exerciseReview.d.ts.map +1 -0
  59. package/dist/analysis/exerciseReview.js +50 -0
  60. package/dist/analysis/exerciseReview.js.map +1 -0
  61. package/dist/analysis/precision.d.ts +15 -0
  62. package/dist/analysis/precision.d.ts.map +1 -0
  63. package/dist/analysis/precision.js +38 -0
  64. package/dist/analysis/precision.js.map +1 -0
  65. package/dist/analysis/result.d.ts +15 -0
  66. package/dist/analysis/result.d.ts.map +1 -0
  67. package/dist/analysis/result.js +13 -0
  68. package/dist/analysis/result.js.map +1 -0
  69. package/dist/analysis/review.d.ts +118 -0
  70. package/dist/analysis/review.d.ts.map +1 -0
  71. package/dist/analysis/review.js +195 -0
  72. package/dist/analysis/review.js.map +1 -0
  73. package/dist/analysis/series.d.ts +42 -0
  74. package/dist/analysis/series.d.ts.map +1 -0
  75. package/dist/analysis/series.js +127 -0
  76. package/dist/analysis/series.js.map +1 -0
  77. package/dist/analysis/simulate.d.ts +43 -0
  78. package/dist/analysis/simulate.d.ts.map +1 -0
  79. package/dist/analysis/simulate.js +109 -0
  80. package/dist/analysis/simulate.js.map +1 -0
  81. package/dist/analysis/simulate2.d.ts +65 -0
  82. package/dist/analysis/simulate2.d.ts.map +1 -0
  83. package/dist/analysis/simulate2.js +173 -0
  84. package/dist/analysis/simulate2.js.map +1 -0
  85. package/dist/analysis/trend.d.ts +39 -0
  86. package/dist/analysis/trend.d.ts.map +1 -0
  87. package/dist/analysis/trend.js +48 -0
  88. package/dist/analysis/trend.js.map +1 -0
  89. package/dist/analysis/utils.d.ts +17 -0
  90. package/dist/analysis/utils.d.ts.map +1 -0
  91. package/dist/analysis/utils.js +52 -0
  92. package/dist/analysis/utils.js.map +1 -0
  93. package/dist/analysis/volatility.d.ts +43 -0
  94. package/dist/analysis/volatility.d.ts.map +1 -0
  95. package/dist/analysis/volatility.js +96 -0
  96. package/dist/analysis/volatility.js.map +1 -0
  97. package/dist/analysis/weight.d.ts +86 -0
  98. package/dist/analysis/weight.d.ts.map +1 -0
  99. package/dist/analysis/weight.js +219 -0
  100. package/dist/analysis/weight.js.map +1 -0
  101. package/dist/analysis/weightCompare.d.ts +63 -0
  102. package/dist/analysis/weightCompare.d.ts.map +1 -0
  103. package/dist/analysis/weightCompare.js +212 -0
  104. package/dist/analysis/weightCompare.js.map +1 -0
  105. package/dist/analysis/weightCompare2.d.ts +63 -0
  106. package/dist/analysis/weightCompare2.d.ts.map +1 -0
  107. package/dist/analysis/weightCompare2.js +211 -0
  108. package/dist/analysis/weightCompare2.js.map +1 -0
  109. package/dist/analysis/weightCompare3.d.ts +13 -0
  110. package/dist/analysis/weightCompare3.d.ts.map +1 -0
  111. package/dist/analysis/weightCompare3.js +199 -0
  112. package/dist/analysis/weightCompare3.js.map +1 -0
  113. package/dist/cli/cmd_read.d.ts +8 -0
  114. package/dist/cli/cmd_read.d.ts.map +1 -0
  115. package/dist/cli/cmd_read.js +719 -0
  116. package/dist/cli/cmd_read.js.map +1 -0
  117. package/dist/cli/keys.d.ts +333 -0
  118. package/dist/cli/keys.d.ts.map +1 -0
  119. package/dist/cli/keys.js +103 -0
  120. package/dist/cli/keys.js.map +1 -0
  121. package/dist/cli/write.d.ts +24 -0
  122. package/dist/cli/write.d.ts.map +1 -0
  123. package/dist/cli/write.js +832 -0
  124. package/dist/cli/write.js.map +1 -0
  125. package/dist/fetch/audit.d.ts +25 -0
  126. package/dist/fetch/audit.d.ts.map +1 -0
  127. package/dist/fetch/audit.js +46 -0
  128. package/dist/fetch/audit.js.map +1 -0
  129. package/dist/fetch/batch.d.ts +68 -0
  130. package/dist/fetch/batch.d.ts.map +1 -0
  131. package/dist/fetch/batch.js +183 -0
  132. package/dist/fetch/batch.js.map +1 -0
  133. package/dist/fetch/body.d.ts +89 -0
  134. package/dist/fetch/body.d.ts.map +1 -0
  135. package/dist/fetch/body.js +217 -0
  136. package/dist/fetch/body.js.map +1 -0
  137. package/dist/fetch/cli.d.ts +3 -0
  138. package/dist/fetch/cli.d.ts.map +1 -0
  139. package/dist/fetch/cli.js +195 -0
  140. package/dist/fetch/cli.js.map +1 -0
  141. package/dist/fetch/cross-skill.d.ts +29 -0
  142. package/dist/fetch/cross-skill.d.ts.map +1 -0
  143. package/dist/fetch/cross-skill.js +42 -0
  144. package/dist/fetch/cross-skill.js.map +1 -0
  145. package/dist/fetch/db.d.ts +5 -0
  146. package/dist/fetch/db.d.ts.map +1 -0
  147. package/dist/fetch/db.js +4 -0
  148. package/dist/fetch/db.js.map +1 -0
  149. package/dist/fetch/diet.d.ts +174 -0
  150. package/dist/fetch/diet.d.ts.map +1 -0
  151. package/dist/fetch/diet.js +239 -0
  152. package/dist/fetch/diet.js.map +1 -0
  153. package/dist/fetch/errors.d.ts +5 -0
  154. package/dist/fetch/errors.d.ts.map +1 -0
  155. package/dist/fetch/errors.js +8 -0
  156. package/dist/fetch/errors.js.map +1 -0
  157. package/dist/fetch/exercise.d.ts +72 -0
  158. package/dist/fetch/exercise.d.ts.map +1 -0
  159. package/dist/fetch/exercise.js +270 -0
  160. package/dist/fetch/exercise.js.map +1 -0
  161. package/dist/fetch/goal.d.ts +48 -0
  162. package/dist/fetch/goal.d.ts.map +1 -0
  163. package/dist/fetch/goal.js +73 -0
  164. package/dist/fetch/goal.js.map +1 -0
  165. package/dist/fetch/goalHistory.d.ts +24 -0
  166. package/dist/fetch/goalHistory.d.ts.map +1 -0
  167. package/dist/fetch/goalHistory.js +51 -0
  168. package/dist/fetch/goalHistory.js.map +1 -0
  169. package/dist/fetch/history.d.ts +28 -0
  170. package/dist/fetch/history.d.ts.map +1 -0
  171. package/dist/fetch/history.js +29 -0
  172. package/dist/fetch/history.js.map +1 -0
  173. package/dist/fetch/index.d.ts +23 -0
  174. package/dist/fetch/index.d.ts.map +1 -0
  175. package/dist/fetch/index.js +16 -0
  176. package/dist/fetch/index.js.map +1 -0
  177. package/dist/fetch/nutritionGoal.d.ts +115 -0
  178. package/dist/fetch/nutritionGoal.d.ts.map +1 -0
  179. package/dist/fetch/nutritionGoal.js +154 -0
  180. package/dist/fetch/nutritionGoal.js.map +1 -0
  181. package/dist/fetch/photos.d.ts +76 -0
  182. package/dist/fetch/photos.d.ts.map +1 -0
  183. package/dist/fetch/photos.js +193 -0
  184. package/dist/fetch/photos.js.map +1 -0
  185. package/dist/fetch/plan.d.ts +145 -0
  186. package/dist/fetch/plan.d.ts.map +1 -0
  187. package/dist/fetch/plan.js +258 -0
  188. package/dist/fetch/plan.js.map +1 -0
  189. package/dist/fetch/products.d.ts +62 -0
  190. package/dist/fetch/products.d.ts.map +1 -0
  191. package/dist/fetch/products.js +73 -0
  192. package/dist/fetch/products.js.map +1 -0
  193. package/dist/fetch/profile.d.ts +46 -0
  194. package/dist/fetch/profile.d.ts.map +1 -0
  195. package/dist/fetch/profile.js +105 -0
  196. package/dist/fetch/profile.js.map +1 -0
  197. package/dist/fetch/shapes.d.ts +41 -0
  198. package/dist/fetch/shapes.d.ts.map +1 -0
  199. package/dist/fetch/shapes.js +38 -0
  200. package/dist/fetch/shapes.js.map +1 -0
  201. package/dist/fetch/validate.d.ts +11 -0
  202. package/dist/fetch/validate.d.ts.map +1 -0
  203. package/dist/fetch/validate.js +64 -0
  204. package/dist/fetch/validate.js.map +1 -0
  205. package/dist/fetch/weight.d.ts +109 -0
  206. package/dist/fetch/weight.d.ts.map +1 -0
  207. package/dist/fetch/weight.js +210 -0
  208. package/dist/fetch/weight.js.map +1 -0
  209. package/dist/fetch/xunji-catalog.d.ts +17 -0
  210. package/dist/fetch/xunji-catalog.d.ts.map +1 -0
  211. package/dist/fetch/xunji-catalog.js +57 -0
  212. package/dist/fetch/xunji-catalog.js.map +1 -0
  213. package/dist/index.d.ts +17 -0
  214. package/dist/index.d.ts.map +1 -0
  215. package/dist/index.js +12 -0
  216. package/dist/index.js.map +1 -0
  217. package/dist/kcal.d.ts +21 -0
  218. package/dist/kcal.d.ts.map +1 -0
  219. package/dist/kcal.js +27 -0
  220. package/dist/kcal.js.map +1 -0
  221. package/dist/migrate/migrate.d.ts +71 -0
  222. package/dist/migrate/migrate.d.ts.map +1 -0
  223. package/dist/migrate/migrate.js +450 -0
  224. package/dist/migrate/migrate.js.map +1 -0
  225. package/dist/paths.d.ts +6 -0
  226. package/dist/paths.d.ts.map +1 -0
  227. package/dist/paths.js +34 -0
  228. package/dist/paths.js.map +1 -0
  229. package/dist/render/analysisPlate.d.ts +49 -0
  230. package/dist/render/analysisPlate.d.ts.map +1 -0
  231. package/dist/render/analysisPlate.js +149 -0
  232. package/dist/render/analysisPlate.js.map +1 -0
  233. package/dist/render/bodyPlate.d.ts +55 -0
  234. package/dist/render/bodyPlate.d.ts.map +1 -0
  235. package/dist/render/bodyPlate.js +97 -0
  236. package/dist/render/bodyPlate.js.map +1 -0
  237. package/dist/render/diet.d.ts +47 -0
  238. package/dist/render/diet.d.ts.map +1 -0
  239. package/dist/render/diet.js +94 -0
  240. package/dist/render/diet.js.map +1 -0
  241. package/dist/render/envelope.d.ts +60 -0
  242. package/dist/render/envelope.d.ts.map +1 -0
  243. package/dist/render/envelope.js +111 -0
  244. package/dist/render/envelope.js.map +1 -0
  245. package/dist/render/errors.d.ts +10 -0
  246. package/dist/render/errors.d.ts.map +1 -0
  247. package/dist/render/errors.js +9 -0
  248. package/dist/render/errors.js.map +1 -0
  249. package/dist/render/exercise.d.ts +20 -0
  250. package/dist/render/exercise.d.ts.map +1 -0
  251. package/dist/render/exercise.js +32 -0
  252. package/dist/render/exercise.js.map +1 -0
  253. package/dist/render/goal.d.ts +24 -0
  254. package/dist/render/goal.d.ts.map +1 -0
  255. package/dist/render/goal.js +23 -0
  256. package/dist/render/goal.js.map +1 -0
  257. package/dist/render/goalExtra.d.ts +45 -0
  258. package/dist/render/goalExtra.d.ts.map +1 -0
  259. package/dist/render/goalExtra.js +94 -0
  260. package/dist/render/goalExtra.js.map +1 -0
  261. package/dist/render/goalPlate.d.ts +66 -0
  262. package/dist/render/goalPlate.d.ts.map +1 -0
  263. package/dist/render/goalPlate.js +110 -0
  264. package/dist/render/goalPlate.js.map +1 -0
  265. package/dist/render/health.d.ts +21 -0
  266. package/dist/render/health.d.ts.map +1 -0
  267. package/dist/render/health.js +41 -0
  268. package/dist/render/health.js.map +1 -0
  269. package/dist/render/help.d.ts +18 -0
  270. package/dist/render/help.d.ts.map +1 -0
  271. package/dist/render/help.js +58 -0
  272. package/dist/render/help.js.map +1 -0
  273. package/dist/render/home.d.ts +30 -0
  274. package/dist/render/home.d.ts.map +1 -0
  275. package/dist/render/home.js +73 -0
  276. package/dist/render/home.js.map +1 -0
  277. package/dist/render/html.d.ts +66 -0
  278. package/dist/render/html.d.ts.map +1 -0
  279. package/dist/render/html.js +510 -0
  280. package/dist/render/html.js.map +1 -0
  281. package/dist/render/index.d.ts +47 -0
  282. package/dist/render/index.d.ts.map +1 -0
  283. package/dist/render/index.js +26 -0
  284. package/dist/render/index.js.map +1 -0
  285. package/dist/render/insightPlate.d.ts +55 -0
  286. package/dist/render/insightPlate.d.ts.map +1 -0
  287. package/dist/render/insightPlate.js +97 -0
  288. package/dist/render/insightPlate.js.map +1 -0
  289. package/dist/render/library.d.ts +32 -0
  290. package/dist/render/library.d.ts.map +1 -0
  291. package/dist/render/library.js +54 -0
  292. package/dist/render/library.js.map +1 -0
  293. package/dist/render/photo.d.ts +101 -0
  294. package/dist/render/photo.d.ts.map +1 -0
  295. package/dist/render/photo.js +241 -0
  296. package/dist/render/photo.js.map +1 -0
  297. package/dist/render/planPlate.d.ts +40 -0
  298. package/dist/render/planPlate.d.ts.map +1 -0
  299. package/dist/render/planPlate.js +72 -0
  300. package/dist/render/planPlate.js.map +1 -0
  301. package/dist/render/profilePlate.d.ts +17 -0
  302. package/dist/render/profilePlate.d.ts.map +1 -0
  303. package/dist/render/profilePlate.js +18 -0
  304. package/dist/render/profilePlate.js.map +1 -0
  305. package/dist/render/ranking.d.ts +22 -0
  306. package/dist/render/ranking.d.ts.map +1 -0
  307. package/dist/render/ranking.js +63 -0
  308. package/dist/render/ranking.js.map +1 -0
  309. package/dist/render/receipt.d.ts +71 -0
  310. package/dist/render/receipt.d.ts.map +1 -0
  311. package/dist/render/receipt.js +65 -0
  312. package/dist/render/receipt.js.map +1 -0
  313. package/dist/render/weightPlate.d.ts +54 -0
  314. package/dist/render/weightPlate.d.ts.map +1 -0
  315. package/dist/render/weightPlate.js +110 -0
  316. package/dist/render/weightPlate.js.map +1 -0
  317. package/dist/schema.d.ts +25 -0
  318. package/dist/schema.d.ts.map +1 -0
  319. package/dist/schema.js +281 -0
  320. package/dist/schema.js.map +1 -0
  321. package/dist/triggers/help-lookup.d.ts +28 -0
  322. package/dist/triggers/help-lookup.d.ts.map +1 -0
  323. package/dist/triggers/help-lookup.js +163 -0
  324. package/dist/triggers/help-lookup.js.map +1 -0
  325. package/dist/triggers/index.d.ts +24 -0
  326. package/dist/triggers/index.d.ts.map +1 -0
  327. package/dist/triggers/index.js +78 -0
  328. package/dist/triggers/index.js.map +1 -0
  329. package/dist/triggers/scene-01-home.d.ts +4 -0
  330. package/dist/triggers/scene-01-home.d.ts.map +1 -0
  331. package/dist/triggers/scene-01-home.js +13 -0
  332. package/dist/triggers/scene-01-home.js.map +1 -0
  333. package/dist/triggers/scene-02-diet.d.ts +4 -0
  334. package/dist/triggers/scene-02-diet.d.ts.map +1 -0
  335. package/dist/triggers/scene-02-diet.js +74 -0
  336. package/dist/triggers/scene-02-diet.js.map +1 -0
  337. package/dist/triggers/scene-03-weight.d.ts +4 -0
  338. package/dist/triggers/scene-03-weight.d.ts.map +1 -0
  339. package/dist/triggers/scene-03-weight.js +62 -0
  340. package/dist/triggers/scene-03-weight.js.map +1 -0
  341. package/dist/triggers/scene-04-exercise.d.ts +4 -0
  342. package/dist/triggers/scene-04-exercise.d.ts.map +1 -0
  343. package/dist/triggers/scene-04-exercise.js +43 -0
  344. package/dist/triggers/scene-04-exercise.js.map +1 -0
  345. package/dist/triggers/scene-05-workout.d.ts +4 -0
  346. package/dist/triggers/scene-05-workout.d.ts.map +1 -0
  347. package/dist/triggers/scene-05-workout.js +36 -0
  348. package/dist/triggers/scene-05-workout.js.map +1 -0
  349. package/dist/triggers/scene-06-goal.d.ts +4 -0
  350. package/dist/triggers/scene-06-goal.d.ts.map +1 -0
  351. package/dist/triggers/scene-06-goal.js +29 -0
  352. package/dist/triggers/scene-06-goal.js.map +1 -0
  353. package/dist/triggers/scene-07-profile.d.ts +4 -0
  354. package/dist/triggers/scene-07-profile.d.ts.map +1 -0
  355. package/dist/triggers/scene-07-profile.js +8 -0
  356. package/dist/triggers/scene-07-profile.js.map +1 -0
  357. package/dist/triggers/scene-08-body.d.ts +4 -0
  358. package/dist/triggers/scene-08-body.d.ts.map +1 -0
  359. package/dist/triggers/scene-08-body.js +17 -0
  360. package/dist/triggers/scene-08-body.js.map +1 -0
  361. package/dist/triggers/scene-09-photo.d.ts +4 -0
  362. package/dist/triggers/scene-09-photo.d.ts.map +1 -0
  363. package/dist/triggers/scene-09-photo.js +14 -0
  364. package/dist/triggers/scene-09-photo.js.map +1 -0
  365. package/dist/triggers/scene-10-analysis.d.ts +4 -0
  366. package/dist/triggers/scene-10-analysis.d.ts.map +1 -0
  367. package/dist/triggers/scene-10-analysis.js +180 -0
  368. package/dist/triggers/scene-10-analysis.js.map +1 -0
  369. package/dist/triggers/types.d.ts +66 -0
  370. package/dist/triggers/types.d.ts.map +1 -0
  371. package/dist/triggers/types.js +3 -0
  372. package/dist/triggers/types.js.map +1 -0
  373. package/package.json +35 -0
@@ -0,0 +1,44 @@
1
+ /** T7 #26 · 赤字口径层(对照老家 scripts/render_calorie_deficit.py 数据段 + ADR-0013)。
2
+ *
3
+ * 薄壳:唯一数据源 = T5 buildSeries,不自算缺口(老家 v2 T5 薄壳化后同样)。
4
+ * 热量缺口 = 消耗 − 摄入,正=缺口;消耗 = TDEE + 当日运动;摄入 = 当日食物(不含水)。
5
+ * KCAL_PER_KG = 7700(脂肪);weekly_deficit_per_day: 300 沿老家 target 段。
6
+ */
7
+ import type { DatabaseSync } from 'node:sqlite';
8
+ export declare const KCAL_PER_KG = 7700;
9
+ export declare const WEEKDAY_NAMES: string[];
10
+ export declare function weekdayName(isoDate: string): string;
11
+ export interface DeficitDay {
12
+ date: string;
13
+ intake: number;
14
+ burn: number;
15
+ deficit: number;
16
+ weekday: string;
17
+ }
18
+ export interface DeficitSummary {
19
+ avgIntake: number;
20
+ avgBurn: number;
21
+ avgExerciseBurn: number;
22
+ avgDeficit: number;
23
+ weeklyDeficit: number;
24
+ predictedLossKg: number;
25
+ trend: 'loss' | 'gain' | 'flat';
26
+ }
27
+ export interface DeficitData {
28
+ summary: DeficitSummary;
29
+ target: {
30
+ intake: number;
31
+ tdee: number;
32
+ weeklyDeficitPerDay: number;
33
+ };
34
+ series: DeficitDay[];
35
+ meta: {
36
+ start: string;
37
+ end: string;
38
+ days: number;
39
+ weekdayCount: number;
40
+ weekendCount: number;
41
+ };
42
+ }
43
+ export declare function buildDeficitData(db: DatabaseSync, start: string, end: string): DeficitData;
44
+ //# sourceMappingURL=deficit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deficit.d.ts","sourceRoot":"","sources":["../../src/analysis/deficit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,eAAO,MAAM,WAAW,OAAO,CAAC;AAChC,eAAO,MAAM,aAAa,UAA6C,CAAC;AAExE,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;CAC9E;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAChF,aAAa,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CACjF;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CAChG;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAwC1F"}
@@ -0,0 +1,54 @@
1
+ import { FetchError } from '../fetch/errors.js';
2
+ import { round2 } from '../kcal.js';
3
+ import { buildSeries } from './series.js';
4
+ export const KCAL_PER_KG = 7700;
5
+ export const WEEKDAY_NAMES = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
6
+ export function weekdayName(isoDate) {
7
+ const t = Date.parse(isoDate + 'T12:00:00Z');
8
+ if (Number.isNaN(t))
9
+ throw new FetchError('日期非法: ' + isoDate);
10
+ return WEEKDAY_NAMES[(new Date(t).getUTCDay() + 6) % 7];
11
+ }
12
+ export function buildDeficitData(db, start, end) {
13
+ const s = buildSeries(db, start, end);
14
+ if (!s.length)
15
+ throw new FetchError(`无数据:${start} ~ ${end}`);
16
+ const first = s[0];
17
+ const targetIntake = first.calorieGoal || 1800;
18
+ const tdee = first.tdee || 1800;
19
+ const series = s.map((day) => {
20
+ const intake = day.calories ?? 0;
21
+ const exerciseBurn = day.exerciseKcal ?? 0;
22
+ return {
23
+ date: day.date,
24
+ intake,
25
+ burn: (day.tdee || 0) + exerciseBurn,
26
+ deficit: day.deficit ?? 0,
27
+ weekday: weekdayName(day.date),
28
+ };
29
+ });
30
+ const n = series.length;
31
+ const sum = (f) => series.reduce((a, d) => a + f(d), 0);
32
+ const totalD = sum((d) => d.deficit);
33
+ const avgD = Math.round(totalD / n);
34
+ const totalEx = s.reduce((a, d) => a + (d.exerciseKcal ?? 0), 0);
35
+ return {
36
+ summary: {
37
+ avgIntake: Math.round(sum((d) => d.intake) / n),
38
+ avgBurn: Math.round(sum((d) => d.burn) / n),
39
+ avgExerciseBurn: Math.round(totalEx / n),
40
+ avgDeficit: avgD,
41
+ weeklyDeficit: totalD,
42
+ predictedLossKg: round2(totalD / KCAL_PER_KG),
43
+ trend: avgD > 0 ? 'loss' : avgD < 0 ? 'gain' : 'flat',
44
+ },
45
+ target: { intake: targetIntake, tdee, weeklyDeficitPerDay: 300 },
46
+ series,
47
+ meta: {
48
+ start, end, days: n,
49
+ weekdayCount: series.filter((d) => ['周一', '周二', '周三', '周四', '周五'].includes(d.weekday)).length,
50
+ weekendCount: series.filter((d) => d.weekday === '周六' || d.weekday === '周日').length,
51
+ },
52
+ };
53
+ }
54
+ //# sourceMappingURL=deficit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deficit.js","sourceRoot":"","sources":["../../src/analysis/deficit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /** T5 #24 · 饮食分析口径(对照老家 scripts/analysis/diet.py)。
2
+ *
3
+ * dietCalorieTrend / dietMacroRatio / dietFoodRanking / dietDeficitAnalysis。
4
+ * 只取 as_dict=True 结构化形状;print 分支归 T11。空数据回 rejection(明确阻断)。
5
+ * 注意:trend/ranking 查询不过滤饮水行(老家原样);low_calorie/frequent 榜
6
+ * 排除含 water/💧水(B-205)。deficit 用 体重×24×系数 BMR(老家口径,非 Mifflin)。
7
+ */
8
+ import type { DatabaseSync } from 'node:sqlite';
9
+ import type { AnalysisResult } from './result.js';
10
+ export interface TrendDay {
11
+ date: string;
12
+ totalCal: number;
13
+ totalProtein: number;
14
+ totalCarbs: number;
15
+ totalFat: number;
16
+ }
17
+ export interface CalorieTrend {
18
+ daysCount: number;
19
+ totalCal: number;
20
+ avgCal: number;
21
+ calGoal: number | null;
22
+ complianceDays: number;
23
+ weekdayAvg: number;
24
+ weekendAvg: number;
25
+ daily: TrendDay[];
26
+ }
27
+ export declare function dietCalorieTrend(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<CalorieTrend>;
28
+ export type MacroStatus = 'high' | 'low' | 'ok';
29
+ export interface MacroEval {
30
+ pct: number;
31
+ targetPct: number;
32
+ diff: number;
33
+ status: MacroStatus;
34
+ }
35
+ export interface MacroRatio {
36
+ protein: MacroEval | null;
37
+ carb: MacroEval | null;
38
+ fat: MacroEval | null;
39
+ }
40
+ export declare function dietMacroRatio(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<MacroRatio>;
41
+ export type FoodRankCategory = 'high_calorie' | 'low_calorie' | 'frequent' | 'high_carb' | 'high_protein';
42
+ export interface RankItem {
43
+ rank: number;
44
+ foodName: string;
45
+ totalCal: number;
46
+ totalGrams: number;
47
+ totalProtein: number;
48
+ totalCarbs: number;
49
+ totalFat: number;
50
+ cnt: number;
51
+ avgCalPerMeal: number;
52
+ }
53
+ export interface FoodRanking {
54
+ category: string;
55
+ title: string;
56
+ start: string;
57
+ end: string;
58
+ topN: number;
59
+ items: RankItem[];
60
+ }
61
+ export declare function dietFoodRanking(db: DatabaseSync, startDate: string, endDate?: string | null, category?: string, topN?: number): AnalysisResult<FoodRanking>;
62
+ export interface DeficitAnalysis {
63
+ daysCount: number;
64
+ avgIntake: number;
65
+ bmr: number;
66
+ currentWeight: number;
67
+ avgExerciseBurn: number;
68
+ avgDeficit: number;
69
+ totalDeficit: number;
70
+ kgEquivalent: number;
71
+ sizeLabel: string;
72
+ dietContribPct: number;
73
+ exerciseContribPct: number;
74
+ }
75
+ export declare function dietDeficitAnalysis(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<DeficitAnalysis>;
76
+ //# sourceMappingURL=diet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diet.d.ts","sourceRoot":"","sources":["../../src/analysis/diet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,164 @@
1
+ import { FetchError } from '../fetch/errors.js';
2
+ import { getActivityFactor, parseDate } from './utils.js';
3
+ import { ok, rejection } from './result.js';
4
+ const round = (n) => Math.round(n);
5
+ const round1 = (n) => Math.round(n * 10) / 10;
6
+ const round2 = (n) => Math.round(n * 100) / 100;
7
+ function rangeOf(start, end) {
8
+ const s = parseDate(start);
9
+ if (!s)
10
+ throw new FetchError('起始日期非法: ' + String(start));
11
+ return [s, parseDate(end ?? undefined) ?? s];
12
+ }
13
+ function latestWeightKg(db) {
14
+ const row = db.prepare('SELECT weight_kg FROM weight_log ORDER BY date DESC LIMIT 1').get();
15
+ return row?.weight_kg ?? 70;
16
+ }
17
+ function profileActivityLevel(db) {
18
+ const row = db.prepare('SELECT activity_level FROM user_profile WHERE id = 1').get();
19
+ return row?.activity_level ?? 'moderate';
20
+ }
21
+ export function dietCalorieTrend(db, startDate, endDate) {
22
+ const [start, end] = rangeOf(startDate, endDate);
23
+ const raw = db.prepare('SELECT date, SUM(calories) AS c, SUM(protein) AS p, SUM(carbs) AS cb, SUM(fat) AS f FROM food_log WHERE date >= ? AND date <= ? GROUP BY date ORDER BY date ASC').all(start, end);
24
+ const rows = raw.map((r) => [r.date, r.c, r.p, r.cb, r.f]);
25
+ if (rows.length === 0)
26
+ return rejection('无饮食记录(' + start + ' ~ ' + end + ')');
27
+ const totalCal = rows.reduce((a, r) => a + (r[1] ?? 0), 0);
28
+ const avgCal = totalCal / rows.length;
29
+ const goal = db.prepare('SELECT calorie_goal FROM daily_goal WHERE id = 1').get();
30
+ const calGoal = goal?.calorie_goal ?? null;
31
+ const onTarget = calGoal ? rows.filter((r) => Math.abs((r[1] ?? 0) - calGoal) <= calGoal * 0.1).length : 0;
32
+ let weekdayCal = 0;
33
+ let weekendCal = 0;
34
+ let wdCount = 0;
35
+ let weCount = 0;
36
+ for (const r of rows) {
37
+ const wd = new Date(r[0] + 'T12:00:00Z').getUTCDay();
38
+ if (wd >= 1 && wd <= 5) {
39
+ weekdayCal += r[1] ?? 0;
40
+ wdCount += 1;
41
+ }
42
+ else {
43
+ weekendCal += r[1] ?? 0;
44
+ weCount += 1;
45
+ }
46
+ }
47
+ const wdAvg = wdCount > 0 ? weekdayCal / wdCount : 0;
48
+ const weAvg = weCount > 0 ? weekendCal / weCount : 0;
49
+ const daily = rows.map((r) => ({ date: r[0], totalCal: r[1] ?? 0, totalProtein: r[2] ?? 0, totalCarbs: r[3] ?? 0, totalFat: r[4] ?? 0 }));
50
+ return ok({ daysCount: rows.length, totalCal: round(totalCal), avgCal: round(avgCal), calGoal, complianceDays: onTarget, weekdayAvg: round(wdAvg), weekendAvg: round(weAvg), daily }, '热量趋势 ' + rows.length + ' 天,日均 ' + round(avgCal) + ' 卡');
51
+ }
52
+ function evalMacro(pct, macro, goal) {
53
+ if (!goal)
54
+ return null;
55
+ const calGoal = goal.calorie_goal ?? 1800;
56
+ const target = macro === 'protein'
57
+ ? ((goal.protein_goal ?? 150) * 4) / calGoal * 100
58
+ : macro === 'carb' ? ((goal.carbs_goal ?? 200) * 4) / calGoal * 100 : ((goal.fat_goal ?? 60) * 9) / calGoal * 100;
59
+ const diff = pct - target;
60
+ return { pct: round(pct), targetPct: round(target), diff: round1(diff), status: diff > 3 ? 'high' : diff < -3 ? 'low' : 'ok' };
61
+ }
62
+ export function dietMacroRatio(db, startDate, endDate) {
63
+ const [start, end] = rangeOf(startDate, endDate);
64
+ const row = db.prepare('SELECT SUM(protein)*4 AS p, SUM(carbs)*4 AS c, SUM(fat)*9 AS f FROM food_log WHERE date >= ? AND date <= ?').get(start, end);
65
+ const parts = [row?.p ?? 0, row?.c ?? 0, row?.f ?? 0];
66
+ if (!row || parts[0] + parts[1] + parts[2] === 0)
67
+ return rejection('无饮食记录(' + start + ' ~ ' + end + ')');
68
+ const total = parts[0] + parts[1] + parts[2];
69
+ const denom = total === 0 ? 1 : total;
70
+ const pctPro = (parts[0] / denom) * 100;
71
+ const pctCarb = (parts[1] / denom) * 100;
72
+ const pctFat = (parts[2] / denom) * 100;
73
+ const goal = db.prepare('SELECT calorie_goal, protein_goal, carbs_goal, fat_goal FROM daily_goal WHERE id = 1').get();
74
+ const g = goal ?? undefined;
75
+ return ok({ protein: evalMacro(pctPro, 'protein', g), carb: evalMacro(pctCarb, 'carb', g), fat: evalMacro(pctFat, 'fat', g) }, '营养配比 蛋白/碳水/脂肪 = ' + round(pctPro) + '/' + round(pctCarb) + '/' + round(pctFat));
76
+ }
77
+ const RANK_TITLES = {
78
+ high_calorie: '🔥 热量炸弹榜',
79
+ low_calorie: '🥬 低热量健康榜',
80
+ frequent: '📅 频繁吃榜',
81
+ high_carb: '🍚 高碳水榜',
82
+ high_protein: '💪 高蛋白榜',
83
+ };
84
+ function isWaterFood(name) {
85
+ return name.toLowerCase().includes('water') || name === '💧水';
86
+ }
87
+ export function dietFoodRanking(db, startDate, endDate, category = 'high_calorie', topN = 5) {
88
+ const [start, end] = rangeOf(startDate, endDate);
89
+ if (!Number.isInteger(topN) || topN < 1)
90
+ throw new FetchError('topN 须为正整数');
91
+ const raw = db.prepare('SELECT food_name AS n, SUM(calories) AS c, SUM(grams) AS g, SUM(protein) AS p, SUM(carbs) AS cb, SUM(fat) AS f, COUNT(*) AS cnt FROM food_log WHERE date >= ? AND date <= ? GROUP BY food_name').all(start, end);
92
+ const rows = raw.map((r) => [r.n, r.c, r.g, r.p, r.cb, r.f, r.cnt]);
93
+ if (rows.length === 0)
94
+ return rejection('无饮食记录(' + start + ' ~ ' + end + ')');
95
+ const filtered = category === 'low_calorie' || category === 'frequent' ? rows.filter((r) => !isWaterFood(r[0])) : rows;
96
+ if (filtered.length === 0)
97
+ return rejection('过滤后无记录(' + category + ')');
98
+ const byCal = (x) => x[1] ?? 0;
99
+ const sorted = [...filtered].sort((a, b) => {
100
+ if (category === 'low_calorie') {
101
+ const avA = byCal(a) / Math.max(a[6], 1);
102
+ const avB = byCal(b) / Math.max(b[6], 1);
103
+ return avA - avB;
104
+ }
105
+ if (category === 'frequent')
106
+ return b[6] - a[6];
107
+ if (category === 'high_carb')
108
+ return (b[4] ?? 0) - (a[4] ?? 0);
109
+ if (category === 'high_protein')
110
+ return (b[3] ?? 0) - (a[3] ?? 0);
111
+ return byCal(b) - byCal(a);
112
+ }).slice(0, topN);
113
+ const title = (RANK_TITLES[category] ?? '📋 食物榜') + '(' + start + ' ~ ' + end + ')';
114
+ const items = sorted.map((r, i) => ({
115
+ rank: i + 1,
116
+ foodName: r[0],
117
+ totalCal: r[1] ?? 0,
118
+ totalGrams: r[2] ?? 0,
119
+ totalProtein: r[3] ?? 0,
120
+ totalCarbs: r[4] ?? 0,
121
+ totalFat: r[5] ?? 0,
122
+ cnt: r[6],
123
+ avgCalPerMeal: Math.floor((r[1] ?? 0) / Math.max(r[6], 1)),
124
+ }));
125
+ return ok({ category, title, start, end, topN: items.length, items }, category + ' 榜单 TOP ' + items.length);
126
+ }
127
+ export function dietDeficitAnalysis(db, startDate, endDate) {
128
+ const [start, end] = rangeOf(startDate, endDate);
129
+ const dietRaw = db.prepare('SELECT date, SUM(calories) AS v FROM food_log WHERE date >= ? AND date <= ? GROUP BY date ORDER BY date ASC').all(start, end);
130
+ const dietRows = dietRaw.map((r) => [r.date, r.v]);
131
+ const exRaw = db.prepare('SELECT date, SUM(calories_burned) AS v FROM exercise_log WHERE date >= ? AND date <= ? GROUP BY date ORDER BY date ASC').all(start, end);
132
+ const exRows = exRaw.map((r) => [r.date, r.v]);
133
+ if (dietRows.length === 0)
134
+ return rejection('无记录(' + start + ' ~ ' + end + ')');
135
+ const dietMap = new Map(dietRows.map((r) => [r[0], r[1] ?? 0]));
136
+ const exMap = new Map(exRows.map((r) => [r[0], r[1] ?? 0]));
137
+ const days = dietMap.size;
138
+ const totalIntake = [...dietMap.values()].reduce((a, b) => a + b, 0);
139
+ const totalEx = [...exMap.values()].reduce((a, b) => a + b, 0);
140
+ const avgIntake = totalIntake / days;
141
+ const avgEx = totalEx / days;
142
+ const currentWeight = latestWeightKg(db);
143
+ const bmr = currentWeight * 24 * getActivityFactor(profileActivityLevel(db));
144
+ const avgDeficit = bmr + avgEx - avgIntake;
145
+ const totalDeficit = avgDeficit * days;
146
+ const kgEquivalent = totalDeficit / 7700;
147
+ const dietContrib = totalDeficit !== 0 ? (Math.abs(totalDeficit - totalEx * days) / Math.abs(totalDeficit)) * 100 : 0;
148
+ const exContrib = totalDeficit !== 0 ? (totalEx / Math.abs(totalDeficit)) * 100 : 0;
149
+ const sizeLabel = avgDeficit > 0 && avgDeficit < 300 ? '偏小' : avgDeficit > 700 ? '过大' : '正常';
150
+ return ok({
151
+ daysCount: days,
152
+ avgIntake: round(avgIntake),
153
+ bmr: round(bmr),
154
+ currentWeight: round1(currentWeight),
155
+ avgExerciseBurn: round(avgEx),
156
+ avgDeficit: round(avgDeficit),
157
+ totalDeficit: round(totalDeficit),
158
+ kgEquivalent: round2(kgEquivalent),
159
+ sizeLabel,
160
+ dietContribPct: round(dietContrib),
161
+ exerciseContribPct: round(exContrib),
162
+ }, '日均缺口 ' + round(avgDeficit) + ' 卡(' + sizeLabel + ')');
163
+ }
164
+ //# sourceMappingURL=diet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diet.js","sourceRoot":"","sources":["../../src/analysis/diet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /** T5 #24 · 运动分析口径(对照老家 scripts/analysis/exercise.py)。
2
+ *
3
+ * exerciseTrend / exerciseTypeBreakdown / exerciseDeficitContribution /
4
+ * exerciseReview(计划 vs 实绩:完成率=实做组数/计划组数,B-305;容量聚合
5
+ * #257:plan 仅 unit 缺省或 kg 且 weight>0,actual 仅 load_kg>0;TOP4 按
6
+ * 计划+实绩合计;by_severity 计数)。只取结构化形状,不 print。
7
+ * BMR 口径:体重×24×系数(老家原样)。
8
+ */
9
+ import type { DatabaseSync } from 'node:sqlite';
10
+ import type { AnalysisResult } from './result.js';
11
+ export interface ExerciseTrend {
12
+ daysWithExercise: number;
13
+ totalDays: number;
14
+ coveragePct: number;
15
+ totalCalories: number;
16
+ totalMinutes: number;
17
+ avgCaloriesPerDay: number;
18
+ avgMinutesPerDay: number | null;
19
+ longestStreakDays: number;
20
+ longestRestDays: number;
21
+ alert: string | null;
22
+ durationMissing: boolean;
23
+ }
24
+ export declare function exerciseTrend(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<ExerciseTrend>;
25
+ export interface ExerciseTypeStat {
26
+ type: string;
27
+ calories: number;
28
+ count: number;
29
+ minutes: number;
30
+ calPct: number;
31
+ countPct: number;
32
+ minutesPct: number;
33
+ }
34
+ export interface ExerciseBreakdown {
35
+ totalCalories: number;
36
+ totalCount: number;
37
+ totalMinutes: number;
38
+ types: ExerciseTypeStat[];
39
+ }
40
+ export declare function exerciseTypeBreakdown(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<ExerciseBreakdown>;
41
+ export interface DeficitContribution {
42
+ dietDeficit: number;
43
+ dietContribPct: number;
44
+ exerciseDeficit: number;
45
+ exerciseContribPct: number;
46
+ evaluation: string;
47
+ bmr: number;
48
+ currentWeight: number;
49
+ }
50
+ export declare function exerciseDeficitContribution(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<DeficitContribution>;
51
+ export interface ReviewAnomaly {
52
+ type: 'low_completion' | 'over_completion' | 'no_actual' | 'rest_but_done';
53
+ msg: string;
54
+ }
55
+ export interface ReviewDay {
56
+ date: string;
57
+ planWeek: number | null;
58
+ sessions: string[];
59
+ planTotalSets: number;
60
+ actualTotalSets: number;
61
+ caloriesBurned: number;
62
+ completionRate: number | null;
63
+ anomalies: ReviewAnomaly[];
64
+ note: string | null;
65
+ isRestDay: boolean;
66
+ }
67
+ export interface ReviewMeta {
68
+ bySeverityCount: Record<string, number>;
69
+ totalDays: number;
70
+ trainDays: number;
71
+ restDays: number;
72
+ totalCalories: number;
73
+ volume: {
74
+ weeks: Array<{
75
+ week: string;
76
+ label: string;
77
+ plan: number;
78
+ actual: number;
79
+ actualSets: number;
80
+ }>;
81
+ movements: Array<{
82
+ name: string;
83
+ planTotal: number;
84
+ actualTotal: number;
85
+ weeks: Array<{
86
+ week: string;
87
+ label: string;
88
+ plan: number;
89
+ actual: number;
90
+ }>;
91
+ }>;
92
+ totalPlan: number;
93
+ totalActual: number;
94
+ hasActual: boolean;
95
+ };
96
+ }
97
+ export declare function exerciseReview(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<Record<string, ReviewDay>>;
98
+ //# sourceMappingURL=exercise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exercise.d.ts","sourceRoot":"","sources":["../../src/analysis/exercise.ts"],"names":[],"mappings":"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"}