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,53 @@
1
+ /** T5 #24 · 诊断公共件(对照老家 anomaly.py 顶部 helpers)。 */
2
+ import type { DatabaseSync } from 'node:sqlite';
3
+ import { seriesAvg, seriesDelta } from '../series.js';
4
+ import type { DaySeries } from '../series.js';
5
+ export declare const MIN_DAYS = 7;
6
+ export declare const PRED_MIN = 14;
7
+ export interface Finding {
8
+ cause: string;
9
+ evidence: string;
10
+ confidence: string;
11
+ action: string;
12
+ }
13
+ export interface Diagnosis {
14
+ kind: string;
15
+ title: string;
16
+ window: string;
17
+ start: string | null;
18
+ end: string | null;
19
+ days: number;
20
+ findings: Finding[];
21
+ degraded: boolean;
22
+ degradeMsg: string;
23
+ insight: string;
24
+ }
25
+ export type DiagnoseKind = 'weight_volatility' | 'weight_plateau' | 'weight_rebound' | 'weight_loss_cause' | 'weight_anomaly' | 'weight_divergence' | 'diet_over' | 'diet_under' | 'diet_unbalanced' | 'diet_structure' | 'exercise_insufficient' | 'exercise_overload' | 'exercise_type_imbalance' | 'exercise_efficiency' | 'exercise_advice' | 'why_not_losing' | 'why_losing_fast' | 'rate_reasonable' | 'strategy_check' | 'gap_to_goal' | 'month_highlights' | 'month_improve' | 'overall';
26
+ export declare const round: (n: number) => number;
27
+ export declare const round1: (n: number) => number;
28
+ export declare const round2: (n: number) => number;
29
+ export { seriesAvg, seriesDelta };
30
+ export type { DaySeries };
31
+ export declare function std(vals: number[]): number;
32
+ export declare function weightVals(series: DaySeries[]): number[];
33
+ export declare function daysBetween(d1: string, d2: string): number;
34
+ export declare function base(series: DaySeries[], kind: string, title: string): Diagnosis;
35
+ export declare function degrade(out: Diagnosis, msg: string): Diagnosis;
36
+ export declare function topFoods(db: DatabaseSync, start: string, end: string, col?: string, limit?: number): Array<{
37
+ food: string;
38
+ total: number;
39
+ times: number;
40
+ }>;
41
+ export declare function mealStructure(db: DatabaseSync, start: string, end: string): Record<string, {
42
+ times: number;
43
+ share: number;
44
+ }>;
45
+ export interface ExRow {
46
+ date: string;
47
+ type: string;
48
+ category: string | null;
49
+ minutes: number | null;
50
+ kcal: number | null;
51
+ }
52
+ export declare function exerciseRows(db: DatabaseSync, start: string, end: string): ExRow[];
53
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/analysis/anomaly/common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import { FetchError } from '../../fetch/errors.js';
2
+ import { seriesAvg, seriesDelta } from '../series.js';
3
+ export const MIN_DAYS = 7;
4
+ export const PRED_MIN = 14;
5
+ export const round = (n) => Math.round(n);
6
+ export const round1 = (n) => Math.round(n * 10) / 10;
7
+ export const round2 = (n) => Math.round(n * 100) / 100;
8
+ export { seriesAvg, seriesDelta };
9
+ export function std(vals) {
10
+ if (vals.length < 2)
11
+ return 0;
12
+ const m = vals.reduce((a, b) => a + b, 0) / vals.length;
13
+ return round2(Math.sqrt(vals.reduce((a, b) => a + (b - m) * (b - m), 0) / (vals.length - 1)));
14
+ }
15
+ export function weightVals(series) {
16
+ return series.map((s) => s.weightKg).filter((v) => v !== null && v !== undefined);
17
+ }
18
+ export function daysBetween(d1, d2) {
19
+ return Math.round((Date.parse(d2 + 'T12:00:00Z') - Date.parse(d1 + 'T12:00:00Z')) / 86400000);
20
+ }
21
+ export function base(series, kind, title) {
22
+ return {
23
+ kind, title, window: '自定义',
24
+ start: series.length > 0 ? series[0].date : null,
25
+ end: series.length > 0 ? series[series.length - 1].date : null,
26
+ days: series.length, findings: [], degraded: false, degradeMsg: '', insight: '',
27
+ };
28
+ }
29
+ export function degrade(out, msg) {
30
+ out.degraded = true;
31
+ out.degradeMsg = msg;
32
+ out.insight = msg;
33
+ return out;
34
+ }
35
+ export function topFoods(db, start, end, col = 'calories', limit = 5) {
36
+ const allowed = ['calories', 'protein', 'carbs', 'fat'];
37
+ if (!allowed.includes(col))
38
+ throw new FetchError('TOP 列非法: ' + col);
39
+ const raw = db.prepare('SELECT food_name AS n, SUM(' + col + ') AS total, COUNT(*) AS times FROM food_log WHERE date BETWEEN ? AND ? AND food_name != ? GROUP BY food_name ORDER BY total DESC LIMIT ?').all(start, end, '💧水', limit);
40
+ return raw.map((r) => ({ food: r.n, total: round1(r.total ?? 0), times: r.times }));
41
+ }
42
+ export function mealStructure(db, start, end) {
43
+ const raw = db.prepare("SELECT time AS t FROM food_log WHERE date BETWEEN ? AND ? AND food_name != '💧水'").all(start, end);
44
+ const rows = raw.map((r) => [r.t]);
45
+ const buckets = { '早餐': 0, '午餐': 0, '晚餐': 0, '加餐/夜宵': 0 };
46
+ for (const r of rows) {
47
+ const h = parseInt(String(r[0] ?? '12:00').split(':')[0], 10);
48
+ if (Number.isNaN(h))
49
+ continue;
50
+ if (h < 10)
51
+ buckets['早餐'] = buckets['早餐'] + 1;
52
+ else if (h < 15)
53
+ buckets['午餐'] = buckets['午餐'] + 1;
54
+ else if (h < 21)
55
+ buckets['晚餐'] = buckets['晚餐'] + 1;
56
+ else
57
+ buckets['加餐/夜宵'] = buckets['加餐/夜宵'] + 1;
58
+ }
59
+ const total = Object.values(buckets).reduce((a, b) => a + b, 0) || 1;
60
+ const out = {};
61
+ for (const [k, v] of Object.entries(buckets))
62
+ out[k] = { times: v, share: round1((v / total) * 100) };
63
+ return out;
64
+ }
65
+ export function exerciseRows(db, start, end) {
66
+ const raw = db.prepare('SELECT date AS d, exercise_type AS t, category AS c, duration_minutes AS dur, calories_burned AS k FROM exercise_log WHERE date BETWEEN ? AND ? ORDER BY date').all(start, end);
67
+ return raw.map((r) => ({ date: r.d, type: r.t, category: r.c, minutes: r.dur, kcal: r.k }));
68
+ }
69
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/analysis/anomaly/common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /** T5 #24 · 饮食诊断 4(对照老家 anomaly.py A4.2)。 */
2
+ import type { DatabaseSync } from 'node:sqlite';
3
+ import type { DaySeries, Diagnosis } from './common.js';
4
+ export declare function diagDietOver(db: DatabaseSync, series: DaySeries[]): Diagnosis;
5
+ export declare function diagDietUnder(series: DaySeries[]): Diagnosis;
6
+ export declare function diagDietUnbalanced(series: DaySeries[]): Diagnosis;
7
+ export declare function diagDietStructure(db: DatabaseSync, series: DaySeries[]): Diagnosis;
8
+ //# sourceMappingURL=diet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diet.d.ts","sourceRoot":"","sources":["../../../src/analysis/anomaly/diet.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExD,wBAAgB,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAoB7E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAoB5D;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CA2BjE;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAsBlF"}
@@ -0,0 +1,95 @@
1
+ import { getActivityFactor } from '../utils.js';
2
+ import { base, degrade, mealStructure, round, seriesAvg, topFoods } from './common.js';
3
+ export function diagDietOver(db, series) {
4
+ const out = base(series, 'diet_over', '诊断饮食超标');
5
+ const goal = series[0]?.calorieGoal ?? 1800;
6
+ const overDays = series.filter((s) => s.calories !== null && s.calories !== undefined && s.calories > goal * 1.1);
7
+ const avg = seriesAvg(series, 'calories');
8
+ out.findings.push({
9
+ cause: '超标日统计',
10
+ evidence: '日均摄入 ' + (avg ?? '—') + ' 卡 vs 目标 ' + goal + ' 卡;超标 >10% 共 ' + overDays.length + ' 天',
11
+ confidence: '高',
12
+ action: '把超标日挑出来看共同的场景(外食/聚餐/零食),针对场景设规则',
13
+ });
14
+ if (overDays.length > 0) {
15
+ const tops = topFoods(db, out.start, out.end, 'calories');
16
+ const topText = tops.slice(0, 3).map((t) => t.food + '(累计' + round(t.total) + '卡)').join('、');
17
+ out.findings.push({ cause: '超标来源食物', evidence: '热量来源 TOP: ' + topText, confidence: '中', action: '对 TOP 食物考虑替换或控量(先记后吃,避免无意识进食)' });
18
+ }
19
+ else {
20
+ out.findings.push({ cause: '超标来源食物', evidence: '窗口内无持续超标日', confidence: '中', action: '维持现状,注意别在疲惫/情绪波动日破功' });
21
+ }
22
+ out.insight = '日均摄入 ' + (avg ?? '—') + ' 卡,超标日 ' + overDays.length + ' 天,' + (overDays.length > 0 ? '注意规律性超标。' : '总体在目标附近。');
23
+ return out;
24
+ }
25
+ export function diagDietUnder(series) {
26
+ const out = base(series, 'diet_under', '诊断饮食不足');
27
+ const tdee = series[0]?.tdee ?? 1800;
28
+ const bmr = round1(tdee / getActivityFactor());
29
+ const underBmr = series.filter((s) => s.calories !== null && s.calories !== undefined && s.calories < bmr * 0.95);
30
+ const avg = seriesAvg(series, 'calories');
31
+ out.findings.push({
32
+ cause: '低于 BMR 天数',
33
+ evidence: '估算 BMR ' + bmr + ' 卡,摄入低于 BMR 共 ' + underBmr.length + ' 天;日均摄入 ' + (avg ?? '—') + ' 卡',
34
+ confidence: '高',
35
+ action: underBmr.length >= 3 ? '⚠️ 摄入长期低于 BMR 会掉代谢+肌肉:把缺口上限控制在 BMR 之上' : '偶尔 1-2 天低摄入可接受,不建议连续',
36
+ });
37
+ const protein = seriesAvg(series, 'protein');
38
+ if (protein) {
39
+ out.findings.push({ cause: '蛋白保障', evidence: '日均蛋白 ' + protein + ' g(目标参考:体重 kg × 1.2-1.6 g)', confidence: '中', action: '低摄入期更要保蛋白,优先保证每餐蛋白到位' });
40
+ }
41
+ out.insight = '日均摄入 ' + (avg ?? '—') + ' 卡,BMR 以下 ' + underBmr.length + ' 天,' + (underBmr.length >= 3 ? '需警惕代谢损伤。' : '风险可控。');
42
+ return out;
43
+ function round1(n) { return Math.round(n * 10) / 10; }
44
+ }
45
+ export function diagDietUnbalanced(series) {
46
+ const out = base(series, 'diet_unbalanced', '诊断营养不均衡(含均衡判断)');
47
+ const p = seriesAvg(series, 'protein') ?? 0;
48
+ const c = seriesAvg(series, 'carbs') ?? 0;
49
+ const f = seriesAvg(series, 'fat') ?? 0;
50
+ const total = p * 4 + c * 4 + f * 9;
51
+ if (total <= 0)
52
+ return degrade(out, '窗口内无营养数据,无法判断均衡度。');
53
+ const shares = {
54
+ '蛋白': round((p * 4) / total * 1000) / 10,
55
+ '碳水': round((c * 4) / total * 1000) / 10,
56
+ '脂肪': round((f * 9) / total * 1000) / 10,
57
+ };
58
+ const ref = { '蛋白': [15, 30], '碳水': [40, 60], '脂肪': [20, 35] };
59
+ const off = Object.keys(shares).filter((k) => { const r = ref[k]; const v = shares[k]; return !(r[0] <= v && v <= r[1]); });
60
+ out.findings.push({
61
+ cause: '三大营养占比',
62
+ evidence: '蛋白 ' + shares['蛋白'] + '% / 碳水 ' + shares['碳水'] + '% / 脂肪 ' + shares['脂肪'] + '%(参考 蛋白15-30 碳水40-60 脂肪20-35)',
63
+ confidence: '中',
64
+ action: off.length > 0 ? '失衡维度:' + off.join('、') + ',针对性调整(蛋白不足→加蛋奶豆肉;碳水过高→减精制碳水;脂肪过高→减油/油炸)' : '三大营养占比在均衡范围',
65
+ });
66
+ const sodium = series.map((s) => s.sodiumMg).filter((v) => v !== null && v !== undefined);
67
+ if (sodium.length > 0) {
68
+ const na = sodium.reduce((a, b) => a + b, 0) / sodium.length;
69
+ out.findings.push({ cause: '钠摄入', evidence: '日均钠 ' + na.toFixed(0) + ' mg(参考 ≤2000 mg)', confidence: '中', action: '超参考值注意减盐;未超则保持' });
70
+ }
71
+ out.insight = off.length === 0 ? '三大营养占比均衡' : '营养占比失衡:' + off.join('、') + '。';
72
+ return out;
73
+ }
74
+ export function diagDietStructure(db, series) {
75
+ const out = base(series, 'diet_structure', '诊断饮食结构问题');
76
+ const meals = mealStructure(db, out.start, out.end);
77
+ const late = meals['加餐/夜宵'];
78
+ out.findings.push({
79
+ cause: '餐次结构',
80
+ evidence: Object.entries(meals).map(([k, v]) => k + ' ' + v.times + ' 次(' + v.share + '%)').join('、'),
81
+ confidence: '中',
82
+ action: late.share >= 20 ? '夜宵/加餐占比 ' + late.share + '%:夜宵最容易累积盈余,尝试睡前 3h 不进食' : '餐次分布较合理,注意早餐别跳过',
83
+ });
84
+ const rows = db.prepare("SELECT date, COUNT(*) AS n FROM food_log WHERE date BETWEEN ? AND ? AND food_name != '💧水' GROUP BY date").all(out.start, out.end);
85
+ const sparse = rows.filter((r) => r[1] <= 1).map((r) => r[0]);
86
+ out.findings.push({
87
+ cause: '进食频率',
88
+ evidence: '单日仅 1 餐的记录 ' + sparse.length + ' 天' + (sparse.length > 0 ? '(如 ' + sparse.slice(0, 5).join('、') + ')' : ''),
89
+ confidence: '中',
90
+ action: '单日 1 餐容易导致后续暴食,保持 3 餐 + 必要时 1-2 次健康加餐',
91
+ });
92
+ out.insight = '夜宵/加餐占 ' + late.share + '%,单日一餐 ' + sparse.length + ' 天,结构' + (late.share < 20 && sparse.length === 0 ? '基本合理' : '有改善空间') + '。';
93
+ return out;
94
+ }
95
+ //# sourceMappingURL=diet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diet.js","sourceRoot":"","sources":["../../../src/analysis/anomaly/diet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** T5 #24 · 运动诊断 5(对照老家 anomaly.py A4.3)。 */
2
+ import type { DatabaseSync } from 'node:sqlite';
3
+ import type { DaySeries, Diagnosis } from './common.js';
4
+ export declare function diagExerciseInsufficient(series: DaySeries[]): Diagnosis;
5
+ export declare function diagExerciseOverload(db: DatabaseSync, series: DaySeries[]): Diagnosis;
6
+ export declare function diagExerciseTypeImbalance(db: DatabaseSync, series: DaySeries[]): Diagnosis;
7
+ export declare function diagExerciseEfficiency(db: DatabaseSync, series: DaySeries[]): Diagnosis;
8
+ export declare function diagExerciseAdvice(db: DatabaseSync, series: DaySeries[]): Diagnosis;
9
+ //# sourceMappingURL=exercise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exercise.d.ts","sourceRoot":"","sources":["../../../src/analysis/anomaly/exercise.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAS,MAAM,aAAa,CAAC;AAE/D,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAWvE;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAqBrF;AAkBD,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAc1F;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAyBvF;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAkBnF"}
@@ -0,0 +1,116 @@
1
+ import { base, degrade, exerciseRows, round, seriesAvg } from './common.js';
2
+ export function diagExerciseInsufficient(series) {
3
+ const out = base(series, 'exercise_insufficient', '诊断运动不足');
4
+ const days = series.length;
5
+ const weeks = Math.max(days / 7, 1);
6
+ const exDays = series.filter((s) => (s.exerciseKcal ?? 0) > 0).length;
7
+ const freq = round((exDays / weeks) * 10) / 10;
8
+ const avgKcal = seriesAvg(series, 'exerciseKcal') ?? 0;
9
+ out.findings.push({ cause: '运动频率', evidence: '窗口 ' + days + ' 天运动 ' + exDays + ' 天,折合 ' + freq + '/周(建议 3-5 次/周)', confidence: '高', action: '频率不足时先从 2-3 次/周快走/骑行开始,固定时间比强度重要' });
10
+ out.findings.push({ cause: '运动消耗', evidence: '日均运动消耗 ' + avgKcal + ' 卡', confidence: '中', action: '每周目标 150 分钟中等强度,或日均消耗 150-250 卡' });
11
+ out.insight = '运动 ' + freq + '/周,' + (freq < 3 ? '不达标,建议提到 3 次以上。' : '频率达标,保持。');
12
+ return out;
13
+ }
14
+ export function diagExerciseOverload(db, series) {
15
+ const out = base(series, 'exercise_overload', '诊断运动过量');
16
+ const rows = exerciseRows(db, out.start, out.end);
17
+ if (rows.length === 0)
18
+ return degrade(out, '窗口内无运动记录,无需诊断过量。');
19
+ const dates = [...new Set(rows.map((r) => r.date))].sort();
20
+ let streak = 1;
21
+ let maxStreak = 1;
22
+ for (let i = 1; i < dates.length; i++) {
23
+ const d = Math.round((Date.parse(dates[i] + 'T12:00:00Z') - Date.parse(dates[i - 1] + 'T12:00:00Z')) / 86400000);
24
+ streak = d <= 1 ? streak + 1 : 1;
25
+ maxStreak = Math.max(maxStreak, streak);
26
+ }
27
+ const over = maxStreak >= 7;
28
+ out.findings.push({
29
+ cause: '连续训练检测',
30
+ evidence: '最长连续运动 ' + maxStreak + ' 天(建议每周至少 1 个休息日)',
31
+ confidence: '高',
32
+ action: over ? '⚠️ 连续 ' + maxStreak + ' 天训练:插入 1-2 个主动恢复日(拉伸/散步),防止过度训练' : '训练节奏有休息日,合理',
33
+ });
34
+ out.insight = '最长连续运动 ' + maxStreak + ' 天,' + (over ? '存在过量风险。' : '节奏合理。');
35
+ return out;
36
+ }
37
+ function shareOf(rows) {
38
+ const byCat = new Map();
39
+ for (const r of rows) {
40
+ const cat = r.category ?? '有氧';
41
+ const d = byCat.get(cat) ?? { times: 0, kcal: 0, minutes: 0 };
42
+ d.times += 1;
43
+ d.kcal += r.kcal ?? 0;
44
+ d.minutes += r.minutes ?? 0;
45
+ byCat.set(cat, d);
46
+ }
47
+ const totalTimes = [...byCat.values()].reduce((a, v) => a + v.times, 0);
48
+ const dist = {};
49
+ for (const [k, v] of byCat)
50
+ dist[k] = { times: v.times, share: round((v.times / (totalTimes || 1)) * 1000) / 10, kcal: v.kcal };
51
+ return { dist, totalTimes };
52
+ }
53
+ export function diagExerciseTypeImbalance(db, series) {
54
+ const out = base(series, 'exercise_type_imbalance', '诊断运动类型失衡');
55
+ const rows = exerciseRows(db, out.start, out.end);
56
+ if (rows.length === 0)
57
+ return degrade(out, '窗口内无运动记录,无法分析类型分布。');
58
+ const { dist } = shareOf(rows);
59
+ const strengthShare = dist['力量']?.share ?? 0;
60
+ out.findings.push({
61
+ cause: '类型占比',
62
+ evidence: Object.entries(dist).map(([k, v]) => k + ' ' + v.share + '%(' + v.times + '次)').join('、'),
63
+ confidence: '中',
64
+ action: strengthShare < 30 ? '力量训练占比 ' + strengthShare + '%:增肌/保肌建议力量占 40-50%,有氧 30-40%,柔韧 10-20%' : '力量与有氧搭配较均衡',
65
+ });
66
+ out.insight = '力量 ' + strengthShare + '%,' + (strengthShare < 30 ? '有氧为主,建议补力量训练。' : '搭配均衡。');
67
+ return out;
68
+ }
69
+ export function diagExerciseEfficiency(db, series) {
70
+ const out = base(series, 'exercise_efficiency', '诊断运动效率(含有效判断)');
71
+ const rows = exerciseRows(db, out.start, out.end);
72
+ if (rows.length === 0)
73
+ return degrade(out, '窗口内无运动记录,无法评估效率。');
74
+ const totalKcal = rows.reduce((a, r) => a + (r.kcal ?? 0), 0);
75
+ const totalMin = rows.reduce((a, r) => a + (r.minutes ?? 0), 0);
76
+ const eff = totalMin ? round((totalKcal / totalMin) * 10) / 10 : null;
77
+ const byCat = new Map();
78
+ for (const r of rows) {
79
+ const k = r.category ?? '有氧';
80
+ if (!byCat.has(k))
81
+ byCat.set(k, []);
82
+ byCat.get(k).push(r);
83
+ }
84
+ const catEff = {};
85
+ for (const [k, v] of byCat) {
86
+ catEff[k] = round((v.reduce((a, r) => a + (r.kcal ?? 0), 0) / (v.reduce((a, r) => a + (r.minutes ?? 0), 0) || 1)) * 10) / 10;
87
+ }
88
+ out.findings.push({
89
+ cause: '单位时长消耗',
90
+ evidence: '平均 ' + (eff ?? '—') + ' 卡/分钟(有氧常见 7-11 卡/分;力量按组算偏低属正常)' + (Object.keys(catEff).length > 0 ? ';分类: ' + JSON.stringify(catEff) : ''),
91
+ confidence: '中',
92
+ action: '偏低时优先看强度(是否只是散步)与时长记录是否完整',
93
+ });
94
+ out.insight = '单位消耗 ' + (eff ?? '—') + ' 卡/分,' + (eff !== null && eff >= 6 ? '效率正常。' : '效率偏低,建议提高强度或确认时长。');
95
+ return out;
96
+ }
97
+ export function diagExerciseAdvice(db, series) {
98
+ const out = base(series, 'exercise_advice', '诊断运动建议(含类型推荐)');
99
+ const rows = exerciseRows(db, out.start, out.end);
100
+ const byCat = new Map();
101
+ for (const r of rows) {
102
+ const k = r.category ?? '有氧';
103
+ byCat.set(k, (byCat.get(k) ?? 0) + 1);
104
+ }
105
+ const total = [...byCat.values()].reduce((a, b) => a + b, 0) || 1;
106
+ const strengthShare = (byCat.get('力量') ?? 0) / total;
107
+ out.findings.push({
108
+ cause: '类型推荐',
109
+ evidence: strengthShare < 0.3 ? '当前力量占比 ' + round(strengthShare * 100) + '%,有氧为主' : '力量与有氧已有搭配',
110
+ confidence: '中',
111
+ action: strengthShare < 0.3 ? '推荐每周 2 次力量(深蹲/卧推/划船 3 大项)+ 2 次有氧(快走/单车 30-40 分钟),力量优先补上' : '维持现有搭配,尝试每周加 1 次高强度间歇(20 分钟)',
112
+ });
113
+ out.insight = strengthShare < 0.3 ? '建议补力量训练' : '建议加入高强度间歇突破平台。';
114
+ return out;
115
+ }
116
+ //# sourceMappingURL=exercise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exercise.js","sourceRoot":"","sources":["../../../src/analysis/anomaly/exercise.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG5E,MAAM,UAAU,wBAAwB,CAAC,MAAmB;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,uBAAuB,EAAE,QAAQ,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IACtE,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;IACvD,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,gBAAgB,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAC,CAAC;IAClL,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC,CAAC;IACvI,GAAG,CAAC,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACjF,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,EAAgB,EAAE,MAAmB;IACxE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,KAAe,EAAE,GAAG,CAAC,GAAa,CAAC,CAAC;IACtE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3D,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAE,KAAK,CAAC,CAAC,CAAY,GAAG,YAAY,CAAC,GAAG,IAAI,CAAC,KAAK,CAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAY,GAAG,YAAY,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;QACzI,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,IAAI,CAAC,CAAC;IAC5B,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAChB,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE,SAAS,GAAG,SAAS,GAAG,mBAAmB;QACrD,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,GAAG,SAAS,GAAG,kCAAkC,CAAC,CAAC,CAAC,aAAa;KACzF,CAAC,CAAC;IACH,GAAG,CAAC,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC3E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,IAAa;IAC5B,MAAM,KAAK,GAAG,IAAI,GAAG,EAA4D,CAAC;IAClF,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;QAC/B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QAC9D,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACb,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;QACtB,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC;QAC5B,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,MAAM,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACxE,MAAM,IAAI,GAAmE,EAAE,CAAC;IAChF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK;QAAE,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChI,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,EAAgB,EAAE,MAAmB;IAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,yBAAyB,EAAE,UAAU,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,KAAe,EAAE,GAAG,CAAC,GAAa,CAAC,CAAC;IACtE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;IACjE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IAC7C,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAChB,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QACnG,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,aAAa,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,aAAa,GAAG,yCAAyC,CAAC,CAAC,CAAC,YAAY;KAClH,CAAC,CAAC;IACH,GAAG,CAAC,OAAO,GAAG,KAAK,GAAG,aAAa,GAAG,IAAI,GAAG,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC9F,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,EAAgB,EAAE,MAAmB;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,qBAAqB,EAAE,eAAe,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,KAAe,EAAE,GAAG,CAAC,GAAa,CAAC,CAAC;IACtE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAChE,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACtE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;QAC3B,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;IAC/H,CAAC;IACD,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAChB,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,iCAAiC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7I,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,2BAA2B;KACpC,CAAC,CAAC;IACH,GAAG,CAAC,OAAO,GAAG,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC5G,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAgB,EAAE,MAAmB;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,KAAe,EAAE,GAAG,CAAC,GAAa,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;QAC7B,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;IACrD,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAChB,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,WAAW;QAC/F,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,yDAAyD,CAAC,CAAC,CAAC,8BAA8B;KACzH,CAAC,CAAC;IACH,GAAG,CAAC,OAAO,GAAG,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC;IACjE,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,19 @@
1
+ /** T5 #24 · 诊断分发器(对照老家 anomaly.py DIAGNOSTICS/diagnose)。
2
+ *
3
+ * kind 非法即抛 FetchError(明确 rejection,可选表列入 message)。
4
+ * 需 DB 取证的场景(diet_over/top、diet_structure、exercise_*、gap_to_goal)
5
+ * 传 db;纯 series 场景可省。L6 开放式诊断不在此表,留 AI。
6
+ */
7
+ import type { DatabaseSync } from 'node:sqlite';
8
+ import type { DaySeries, DiagnoseKind, Diagnosis } from './common.js';
9
+ import { diagWeightVolatility, diagWeightPlateau, diagWeightRebound, diagWeightLossCause } from './weight.js';
10
+ import { diagWeightAnomaly, diagWeightDivergence } from './weight2.js';
11
+ import { diagDietOver, diagDietUnder, diagDietUnbalanced, diagDietStructure } from './diet.js';
12
+ import { diagExerciseInsufficient, diagExerciseOverload, diagExerciseTypeImbalance, diagExerciseEfficiency, diagExerciseAdvice } from './exercise.js';
13
+ import { diagWhyNotLosing, diagWhyLosingFast, diagRateReasonable, diagStrategyCheck, diagGapToGoal } from './overall.js';
14
+ import { diagMonthHighlights, diagMonthImprove, diagOverall } from './overall2.js';
15
+ export declare const DIAGNOSE_KINDS: DiagnoseKind[];
16
+ export type { DaySeries, DiagnoseKind, Diagnosis };
17
+ export { diagWeightVolatility, diagWeightPlateau, diagWeightRebound, diagWeightLossCause, diagWeightAnomaly, diagWeightDivergence, diagDietOver, diagDietUnder, diagDietUnbalanced, diagDietStructure, diagExerciseInsufficient, diagExerciseOverload, diagExerciseTypeImbalance, diagExerciseEfficiency, diagExerciseAdvice, diagWhyNotLosing, diagWhyLosingFast, diagRateReasonable, diagStrategyCheck, diagGapToGoal, diagMonthHighlights, diagMonthImprove, diagOverall, };
18
+ export declare function diagnose(kind: string, series: DaySeries[], db?: DatabaseSync): Diagnosis;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analysis/anomaly/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC9G,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC/F,OAAO,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACtJ,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACzH,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEnF,eAAO,MAAM,cAAc,EAAE,YAAY,EAMxC,CAAC;AAEF,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AACnD,OAAO,EACL,oBAAoB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EACxH,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,EAClE,wBAAwB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,kBAAkB,EACrH,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EACzF,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,GACnD,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,EAAE,YAAY,GAAG,SAAS,CAiCxF"}
@@ -0,0 +1,51 @@
1
+ import { FetchError } from '../../fetch/errors.js';
2
+ import { diagWeightVolatility, diagWeightPlateau, diagWeightRebound, diagWeightLossCause } from './weight.js';
3
+ import { diagWeightAnomaly, diagWeightDivergence } from './weight2.js';
4
+ import { diagDietOver, diagDietUnder, diagDietUnbalanced, diagDietStructure } from './diet.js';
5
+ import { diagExerciseInsufficient, diagExerciseOverload, diagExerciseTypeImbalance, diagExerciseEfficiency, diagExerciseAdvice } from './exercise.js';
6
+ import { diagWhyNotLosing, diagWhyLosingFast, diagRateReasonable, diagStrategyCheck, diagGapToGoal } from './overall.js';
7
+ import { diagMonthHighlights, diagMonthImprove, diagOverall } from './overall2.js';
8
+ export const DIAGNOSE_KINDS = [
9
+ 'weight_volatility', 'weight_plateau', 'weight_rebound', 'weight_loss_cause', 'weight_anomaly', 'weight_divergence',
10
+ 'diet_over', 'diet_under', 'diet_unbalanced', 'diet_structure',
11
+ 'exercise_insufficient', 'exercise_overload', 'exercise_type_imbalance', 'exercise_efficiency', 'exercise_advice',
12
+ 'why_not_losing', 'why_losing_fast', 'rate_reasonable', 'strategy_check', 'gap_to_goal',
13
+ 'month_highlights', 'month_improve', 'overall',
14
+ ];
15
+ export { diagWeightVolatility, diagWeightPlateau, diagWeightRebound, diagWeightLossCause, diagWeightAnomaly, diagWeightDivergence, diagDietOver, diagDietUnder, diagDietUnbalanced, diagDietStructure, diagExerciseInsufficient, diagExerciseOverload, diagExerciseTypeImbalance, diagExerciseEfficiency, diagExerciseAdvice, diagWhyNotLosing, diagWhyLosingFast, diagRateReasonable, diagStrategyCheck, diagGapToGoal, diagMonthHighlights, diagMonthImprove, diagOverall, };
16
+ export function diagnose(kind, series, db) {
17
+ if (!DIAGNOSE_KINDS.includes(kind)) {
18
+ throw new FetchError('未知诊断 ' + kind + ',可选: ' + DIAGNOSE_KINDS.join(', '));
19
+ }
20
+ const needDb = (k) => {
21
+ if (!db)
22
+ throw new FetchError('诊断 ' + k + ' 需 DB 取证');
23
+ return db;
24
+ };
25
+ switch (kind) {
26
+ case 'weight_volatility': return diagWeightVolatility(series);
27
+ case 'weight_plateau': return diagWeightPlateau(series);
28
+ case 'weight_rebound': return diagWeightRebound(series);
29
+ case 'weight_loss_cause': return diagWeightLossCause(series);
30
+ case 'weight_anomaly': return diagWeightAnomaly(series);
31
+ case 'weight_divergence': return diagWeightDivergence(series);
32
+ case 'diet_over': return diagDietOver(needDb(kind), series);
33
+ case 'diet_under': return diagDietUnder(series);
34
+ case 'diet_unbalanced': return diagDietUnbalanced(series);
35
+ case 'diet_structure': return diagDietStructure(needDb(kind), series);
36
+ case 'exercise_insufficient': return diagExerciseInsufficient(series);
37
+ case 'exercise_overload': return diagExerciseOverload(needDb(kind), series);
38
+ case 'exercise_type_imbalance': return diagExerciseTypeImbalance(needDb(kind), series);
39
+ case 'exercise_efficiency': return diagExerciseEfficiency(needDb(kind), series);
40
+ case 'exercise_advice': return diagExerciseAdvice(needDb(kind), series);
41
+ case 'why_not_losing': return diagWhyNotLosing(series);
42
+ case 'why_losing_fast': return diagWhyLosingFast(series);
43
+ case 'rate_reasonable': return diagRateReasonable(series);
44
+ case 'strategy_check': return diagStrategyCheck(series);
45
+ case 'gap_to_goal': return diagGapToGoal(needDb(kind), series);
46
+ case 'month_highlights': return diagMonthHighlights(series);
47
+ case 'month_improve': return diagMonthImprove(series);
48
+ case 'overall': return diagOverall(series);
49
+ }
50
+ }
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analysis/anomaly/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC9G,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC/F,OAAO,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACtJ,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACzH,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEnF,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC5C,mBAAmB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,mBAAmB;IACnH,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB;IAC9D,uBAAuB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,iBAAiB;IACjH,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa;IACvF,kBAAkB,EAAE,eAAe,EAAE,SAAS;CAC/C,CAAC;AAGF,OAAO,EACL,oBAAoB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EACxH,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,EAClE,wBAAwB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,kBAAkB,EACrH,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EACzF,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,GACnD,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,MAAmB,EAAE,EAAiB;IAC3E,IAAI,CAAE,cAA2B,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,UAAU,CAAC,OAAO,GAAG,IAAI,GAAG,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,CAAS,EAAgB,EAAE;QACzC,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC;QACtD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IACF,QAAQ,IAAoB,EAAE,CAAC;QAC7B,KAAK,mBAAmB,CAAC,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC9D,KAAK,gBAAgB,CAAC,CAAC,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACxD,KAAK,gBAAgB,CAAC,CAAC,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACxD,KAAK,mBAAmB,CAAC,CAAC,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC7D,KAAK,gBAAgB,CAAC,CAAC,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACxD,KAAK,mBAAmB,CAAC,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC9D,KAAK,WAAW,CAAC,CAAC,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5D,KAAK,YAAY,CAAC,CAAC,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAChD,KAAK,iBAAiB,CAAC,CAAC,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC1D,KAAK,gBAAgB,CAAC,CAAC,OAAO,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACtE,KAAK,uBAAuB,CAAC,CAAC,OAAO,wBAAwB,CAAC,MAAM,CAAC,CAAC;QACtE,KAAK,mBAAmB,CAAC,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5E,KAAK,yBAAyB,CAAC,CAAC,OAAO,yBAAyB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACvF,KAAK,qBAAqB,CAAC,CAAC,OAAO,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAChF,KAAK,iBAAiB,CAAC,CAAC,OAAO,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACxE,KAAK,gBAAgB,CAAC,CAAC,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACvD,KAAK,iBAAiB,CAAC,CAAC,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACzD,KAAK,iBAAiB,CAAC,CAAC,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC1D,KAAK,gBAAgB,CAAC,CAAC,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACxD,KAAK,aAAa,CAAC,CAAC,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC/D,KAAK,kBAAkB,CAAC,CAAC,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC5D,KAAK,eAAe,CAAC,CAAC,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACtD,KAAK,SAAS,CAAC,CAAC,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** T5 #24 · 综合诊断 8(对照老家 anomaly.py A4.4)。
2
+ *
3
+ * 有意偏离老家(与 loss_cause 同因,待口径裁决 T7):减重速率比较按 -rate
4
+ * 落健康区间(老家未取负恒判偏慢/正常)。insight 速率符号原样透出。
5
+ */
6
+ import type { DatabaseSync } from 'node:sqlite';
7
+ import type { DaySeries, Diagnosis } from './common.js';
8
+ export declare function diagWhyNotLosing(series: DaySeries[]): Diagnosis;
9
+ export declare function diagWhyLosingFast(series: DaySeries[]): Diagnosis;
10
+ export declare function diagRateReasonable(series: DaySeries[]): Diagnosis;
11
+ export declare function diagStrategyCheck(series: DaySeries[]): Diagnosis;
12
+ export declare function diagGapToGoal(db: DatabaseSync, series: DaySeries[]): Diagnosis;
13
+ //# sourceMappingURL=overall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overall.d.ts","sourceRoot":"","sources":["../../../src/analysis/anomaly/overall.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AA8BxD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAY/D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAmBhE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAWjE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAkBhE;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAyB9E"}