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.
- package/dist/analysis/anomaly/common.d.ts +53 -0
- package/dist/analysis/anomaly/common.d.ts.map +1 -0
- package/dist/analysis/anomaly/common.js +69 -0
- package/dist/analysis/anomaly/common.js.map +1 -0
- package/dist/analysis/anomaly/diet.d.ts +8 -0
- package/dist/analysis/anomaly/diet.d.ts.map +1 -0
- package/dist/analysis/anomaly/diet.js +95 -0
- package/dist/analysis/anomaly/diet.js.map +1 -0
- package/dist/analysis/anomaly/exercise.d.ts +9 -0
- package/dist/analysis/anomaly/exercise.d.ts.map +1 -0
- package/dist/analysis/anomaly/exercise.js +116 -0
- package/dist/analysis/anomaly/exercise.js.map +1 -0
- package/dist/analysis/anomaly/index.d.ts +19 -0
- package/dist/analysis/anomaly/index.d.ts.map +1 -0
- package/dist/analysis/anomaly/index.js +51 -0
- package/dist/analysis/anomaly/index.js.map +1 -0
- package/dist/analysis/anomaly/overall.d.ts +13 -0
- package/dist/analysis/anomaly/overall.d.ts.map +1 -0
- package/dist/analysis/anomaly/overall.js +128 -0
- package/dist/analysis/anomaly/overall.js.map +1 -0
- package/dist/analysis/anomaly/overall2.d.ts +5 -0
- package/dist/analysis/anomaly/overall2.d.ts.map +1 -0
- package/dist/analysis/anomaly/overall2.js +94 -0
- package/dist/analysis/anomaly/overall2.js.map +1 -0
- package/dist/analysis/anomaly/weight.d.ts +8 -0
- package/dist/analysis/anomaly/weight.d.ts.map +1 -0
- package/dist/analysis/anomaly/weight.js +106 -0
- package/dist/analysis/anomaly/weight.js.map +1 -0
- package/dist/analysis/anomaly/weight2.d.ts +4 -0
- package/dist/analysis/anomaly/weight2.d.ts.map +1 -0
- package/dist/analysis/anomaly/weight2.js +59 -0
- package/dist/analysis/anomaly/weight2.js.map +1 -0
- package/dist/analysis/contraindications.d.ts +63 -0
- package/dist/analysis/contraindications.d.ts.map +1 -0
- package/dist/analysis/contraindications.js +121 -0
- package/dist/analysis/contraindications.js.map +1 -0
- package/dist/analysis/cross.d.ts +75 -0
- package/dist/analysis/cross.d.ts.map +1 -0
- package/dist/analysis/cross.js +283 -0
- package/dist/analysis/cross.js.map +1 -0
- package/dist/analysis/dashboard.d.ts +18 -0
- package/dist/analysis/dashboard.d.ts.map +1 -0
- package/dist/analysis/dashboard.js +48 -0
- package/dist/analysis/dashboard.js.map +1 -0
- package/dist/analysis/deficit.d.ts +44 -0
- package/dist/analysis/deficit.d.ts.map +1 -0
- package/dist/analysis/deficit.js +54 -0
- package/dist/analysis/deficit.js.map +1 -0
- package/dist/analysis/diet.d.ts +76 -0
- package/dist/analysis/diet.d.ts.map +1 -0
- package/dist/analysis/diet.js +164 -0
- package/dist/analysis/diet.js.map +1 -0
- package/dist/analysis/exercise.d.ts +98 -0
- package/dist/analysis/exercise.d.ts.map +1 -0
- package/dist/analysis/exercise.js +298 -0
- package/dist/analysis/exercise.js.map +1 -0
- package/dist/analysis/exerciseReview.d.ts +36 -0
- package/dist/analysis/exerciseReview.d.ts.map +1 -0
- package/dist/analysis/exerciseReview.js +50 -0
- package/dist/analysis/exerciseReview.js.map +1 -0
- package/dist/analysis/precision.d.ts +15 -0
- package/dist/analysis/precision.d.ts.map +1 -0
- package/dist/analysis/precision.js +38 -0
- package/dist/analysis/precision.js.map +1 -0
- package/dist/analysis/result.d.ts +15 -0
- package/dist/analysis/result.d.ts.map +1 -0
- package/dist/analysis/result.js +13 -0
- package/dist/analysis/result.js.map +1 -0
- package/dist/analysis/review.d.ts +118 -0
- package/dist/analysis/review.d.ts.map +1 -0
- package/dist/analysis/review.js +195 -0
- package/dist/analysis/review.js.map +1 -0
- package/dist/analysis/series.d.ts +42 -0
- package/dist/analysis/series.d.ts.map +1 -0
- package/dist/analysis/series.js +127 -0
- package/dist/analysis/series.js.map +1 -0
- package/dist/analysis/simulate.d.ts +43 -0
- package/dist/analysis/simulate.d.ts.map +1 -0
- package/dist/analysis/simulate.js +109 -0
- package/dist/analysis/simulate.js.map +1 -0
- package/dist/analysis/simulate2.d.ts +65 -0
- package/dist/analysis/simulate2.d.ts.map +1 -0
- package/dist/analysis/simulate2.js +173 -0
- package/dist/analysis/simulate2.js.map +1 -0
- package/dist/analysis/trend.d.ts +39 -0
- package/dist/analysis/trend.d.ts.map +1 -0
- package/dist/analysis/trend.js +48 -0
- package/dist/analysis/trend.js.map +1 -0
- package/dist/analysis/utils.d.ts +17 -0
- package/dist/analysis/utils.d.ts.map +1 -0
- package/dist/analysis/utils.js +52 -0
- package/dist/analysis/utils.js.map +1 -0
- package/dist/analysis/volatility.d.ts +43 -0
- package/dist/analysis/volatility.d.ts.map +1 -0
- package/dist/analysis/volatility.js +96 -0
- package/dist/analysis/volatility.js.map +1 -0
- package/dist/analysis/weight.d.ts +86 -0
- package/dist/analysis/weight.d.ts.map +1 -0
- package/dist/analysis/weight.js +219 -0
- package/dist/analysis/weight.js.map +1 -0
- package/dist/analysis/weightCompare.d.ts +63 -0
- package/dist/analysis/weightCompare.d.ts.map +1 -0
- package/dist/analysis/weightCompare.js +212 -0
- package/dist/analysis/weightCompare.js.map +1 -0
- package/dist/analysis/weightCompare2.d.ts +63 -0
- package/dist/analysis/weightCompare2.d.ts.map +1 -0
- package/dist/analysis/weightCompare2.js +211 -0
- package/dist/analysis/weightCompare2.js.map +1 -0
- package/dist/analysis/weightCompare3.d.ts +13 -0
- package/dist/analysis/weightCompare3.d.ts.map +1 -0
- package/dist/analysis/weightCompare3.js +199 -0
- package/dist/analysis/weightCompare3.js.map +1 -0
- package/dist/cli/cmd_read.d.ts +8 -0
- package/dist/cli/cmd_read.d.ts.map +1 -0
- package/dist/cli/cmd_read.js +719 -0
- package/dist/cli/cmd_read.js.map +1 -0
- package/dist/cli/keys.d.ts +333 -0
- package/dist/cli/keys.d.ts.map +1 -0
- package/dist/cli/keys.js +103 -0
- package/dist/cli/keys.js.map +1 -0
- package/dist/cli/write.d.ts +24 -0
- package/dist/cli/write.d.ts.map +1 -0
- package/dist/cli/write.js +832 -0
- package/dist/cli/write.js.map +1 -0
- package/dist/fetch/audit.d.ts +25 -0
- package/dist/fetch/audit.d.ts.map +1 -0
- package/dist/fetch/audit.js +46 -0
- package/dist/fetch/audit.js.map +1 -0
- package/dist/fetch/batch.d.ts +68 -0
- package/dist/fetch/batch.d.ts.map +1 -0
- package/dist/fetch/batch.js +183 -0
- package/dist/fetch/batch.js.map +1 -0
- package/dist/fetch/body.d.ts +89 -0
- package/dist/fetch/body.d.ts.map +1 -0
- package/dist/fetch/body.js +217 -0
- package/dist/fetch/body.js.map +1 -0
- package/dist/fetch/cli.d.ts +3 -0
- package/dist/fetch/cli.d.ts.map +1 -0
- package/dist/fetch/cli.js +195 -0
- package/dist/fetch/cli.js.map +1 -0
- package/dist/fetch/cross-skill.d.ts +29 -0
- package/dist/fetch/cross-skill.d.ts.map +1 -0
- package/dist/fetch/cross-skill.js +42 -0
- package/dist/fetch/cross-skill.js.map +1 -0
- package/dist/fetch/db.d.ts +5 -0
- package/dist/fetch/db.d.ts.map +1 -0
- package/dist/fetch/db.js +4 -0
- package/dist/fetch/db.js.map +1 -0
- package/dist/fetch/diet.d.ts +174 -0
- package/dist/fetch/diet.d.ts.map +1 -0
- package/dist/fetch/diet.js +239 -0
- package/dist/fetch/diet.js.map +1 -0
- package/dist/fetch/errors.d.ts +5 -0
- package/dist/fetch/errors.d.ts.map +1 -0
- package/dist/fetch/errors.js +8 -0
- package/dist/fetch/errors.js.map +1 -0
- package/dist/fetch/exercise.d.ts +72 -0
- package/dist/fetch/exercise.d.ts.map +1 -0
- package/dist/fetch/exercise.js +270 -0
- package/dist/fetch/exercise.js.map +1 -0
- package/dist/fetch/goal.d.ts +48 -0
- package/dist/fetch/goal.d.ts.map +1 -0
- package/dist/fetch/goal.js +73 -0
- package/dist/fetch/goal.js.map +1 -0
- package/dist/fetch/goalHistory.d.ts +24 -0
- package/dist/fetch/goalHistory.d.ts.map +1 -0
- package/dist/fetch/goalHistory.js +51 -0
- package/dist/fetch/goalHistory.js.map +1 -0
- package/dist/fetch/history.d.ts +28 -0
- package/dist/fetch/history.d.ts.map +1 -0
- package/dist/fetch/history.js +29 -0
- package/dist/fetch/history.js.map +1 -0
- package/dist/fetch/index.d.ts +23 -0
- package/dist/fetch/index.d.ts.map +1 -0
- package/dist/fetch/index.js +16 -0
- package/dist/fetch/index.js.map +1 -0
- package/dist/fetch/nutritionGoal.d.ts +115 -0
- package/dist/fetch/nutritionGoal.d.ts.map +1 -0
- package/dist/fetch/nutritionGoal.js +154 -0
- package/dist/fetch/nutritionGoal.js.map +1 -0
- package/dist/fetch/photos.d.ts +76 -0
- package/dist/fetch/photos.d.ts.map +1 -0
- package/dist/fetch/photos.js +193 -0
- package/dist/fetch/photos.js.map +1 -0
- package/dist/fetch/plan.d.ts +145 -0
- package/dist/fetch/plan.d.ts.map +1 -0
- package/dist/fetch/plan.js +258 -0
- package/dist/fetch/plan.js.map +1 -0
- package/dist/fetch/products.d.ts +62 -0
- package/dist/fetch/products.d.ts.map +1 -0
- package/dist/fetch/products.js +73 -0
- package/dist/fetch/products.js.map +1 -0
- package/dist/fetch/profile.d.ts +46 -0
- package/dist/fetch/profile.d.ts.map +1 -0
- package/dist/fetch/profile.js +105 -0
- package/dist/fetch/profile.js.map +1 -0
- package/dist/fetch/shapes.d.ts +41 -0
- package/dist/fetch/shapes.d.ts.map +1 -0
- package/dist/fetch/shapes.js +38 -0
- package/dist/fetch/shapes.js.map +1 -0
- package/dist/fetch/validate.d.ts +11 -0
- package/dist/fetch/validate.d.ts.map +1 -0
- package/dist/fetch/validate.js +64 -0
- package/dist/fetch/validate.js.map +1 -0
- package/dist/fetch/weight.d.ts +109 -0
- package/dist/fetch/weight.d.ts.map +1 -0
- package/dist/fetch/weight.js +210 -0
- package/dist/fetch/weight.js.map +1 -0
- package/dist/fetch/xunji-catalog.d.ts +17 -0
- package/dist/fetch/xunji-catalog.d.ts.map +1 -0
- package/dist/fetch/xunji-catalog.js +57 -0
- package/dist/fetch/xunji-catalog.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/kcal.d.ts +21 -0
- package/dist/kcal.d.ts.map +1 -0
- package/dist/kcal.js +27 -0
- package/dist/kcal.js.map +1 -0
- package/dist/migrate/migrate.d.ts +71 -0
- package/dist/migrate/migrate.d.ts.map +1 -0
- package/dist/migrate/migrate.js +450 -0
- package/dist/migrate/migrate.js.map +1 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +34 -0
- package/dist/paths.js.map +1 -0
- package/dist/render/analysisPlate.d.ts +49 -0
- package/dist/render/analysisPlate.d.ts.map +1 -0
- package/dist/render/analysisPlate.js +149 -0
- package/dist/render/analysisPlate.js.map +1 -0
- package/dist/render/bodyPlate.d.ts +55 -0
- package/dist/render/bodyPlate.d.ts.map +1 -0
- package/dist/render/bodyPlate.js +97 -0
- package/dist/render/bodyPlate.js.map +1 -0
- package/dist/render/diet.d.ts +47 -0
- package/dist/render/diet.d.ts.map +1 -0
- package/dist/render/diet.js +94 -0
- package/dist/render/diet.js.map +1 -0
- package/dist/render/envelope.d.ts +60 -0
- package/dist/render/envelope.d.ts.map +1 -0
- package/dist/render/envelope.js +111 -0
- package/dist/render/envelope.js.map +1 -0
- package/dist/render/errors.d.ts +10 -0
- package/dist/render/errors.d.ts.map +1 -0
- package/dist/render/errors.js +9 -0
- package/dist/render/errors.js.map +1 -0
- package/dist/render/exercise.d.ts +20 -0
- package/dist/render/exercise.d.ts.map +1 -0
- package/dist/render/exercise.js +32 -0
- package/dist/render/exercise.js.map +1 -0
- package/dist/render/goal.d.ts +24 -0
- package/dist/render/goal.d.ts.map +1 -0
- package/dist/render/goal.js +23 -0
- package/dist/render/goal.js.map +1 -0
- package/dist/render/goalExtra.d.ts +45 -0
- package/dist/render/goalExtra.d.ts.map +1 -0
- package/dist/render/goalExtra.js +94 -0
- package/dist/render/goalExtra.js.map +1 -0
- package/dist/render/goalPlate.d.ts +66 -0
- package/dist/render/goalPlate.d.ts.map +1 -0
- package/dist/render/goalPlate.js +110 -0
- package/dist/render/goalPlate.js.map +1 -0
- package/dist/render/health.d.ts +21 -0
- package/dist/render/health.d.ts.map +1 -0
- package/dist/render/health.js +41 -0
- package/dist/render/health.js.map +1 -0
- package/dist/render/help.d.ts +18 -0
- package/dist/render/help.d.ts.map +1 -0
- package/dist/render/help.js +58 -0
- package/dist/render/help.js.map +1 -0
- package/dist/render/home.d.ts +30 -0
- package/dist/render/home.d.ts.map +1 -0
- package/dist/render/home.js +73 -0
- package/dist/render/home.js.map +1 -0
- package/dist/render/html.d.ts +66 -0
- package/dist/render/html.d.ts.map +1 -0
- package/dist/render/html.js +510 -0
- package/dist/render/html.js.map +1 -0
- package/dist/render/index.d.ts +47 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +26 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/insightPlate.d.ts +55 -0
- package/dist/render/insightPlate.d.ts.map +1 -0
- package/dist/render/insightPlate.js +97 -0
- package/dist/render/insightPlate.js.map +1 -0
- package/dist/render/library.d.ts +32 -0
- package/dist/render/library.d.ts.map +1 -0
- package/dist/render/library.js +54 -0
- package/dist/render/library.js.map +1 -0
- package/dist/render/photo.d.ts +101 -0
- package/dist/render/photo.d.ts.map +1 -0
- package/dist/render/photo.js +241 -0
- package/dist/render/photo.js.map +1 -0
- package/dist/render/planPlate.d.ts +40 -0
- package/dist/render/planPlate.d.ts.map +1 -0
- package/dist/render/planPlate.js +72 -0
- package/dist/render/planPlate.js.map +1 -0
- package/dist/render/profilePlate.d.ts +17 -0
- package/dist/render/profilePlate.d.ts.map +1 -0
- package/dist/render/profilePlate.js +18 -0
- package/dist/render/profilePlate.js.map +1 -0
- package/dist/render/ranking.d.ts +22 -0
- package/dist/render/ranking.d.ts.map +1 -0
- package/dist/render/ranking.js +63 -0
- package/dist/render/ranking.js.map +1 -0
- package/dist/render/receipt.d.ts +71 -0
- package/dist/render/receipt.d.ts.map +1 -0
- package/dist/render/receipt.js +65 -0
- package/dist/render/receipt.js.map +1 -0
- package/dist/render/weightPlate.d.ts +54 -0
- package/dist/render/weightPlate.d.ts.map +1 -0
- package/dist/render/weightPlate.js +110 -0
- package/dist/render/weightPlate.js.map +1 -0
- package/dist/schema.d.ts +25 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +281 -0
- package/dist/schema.js.map +1 -0
- package/dist/triggers/help-lookup.d.ts +28 -0
- package/dist/triggers/help-lookup.d.ts.map +1 -0
- package/dist/triggers/help-lookup.js +163 -0
- package/dist/triggers/help-lookup.js.map +1 -0
- package/dist/triggers/index.d.ts +24 -0
- package/dist/triggers/index.d.ts.map +1 -0
- package/dist/triggers/index.js +78 -0
- package/dist/triggers/index.js.map +1 -0
- package/dist/triggers/scene-01-home.d.ts +4 -0
- package/dist/triggers/scene-01-home.d.ts.map +1 -0
- package/dist/triggers/scene-01-home.js +13 -0
- package/dist/triggers/scene-01-home.js.map +1 -0
- package/dist/triggers/scene-02-diet.d.ts +4 -0
- package/dist/triggers/scene-02-diet.d.ts.map +1 -0
- package/dist/triggers/scene-02-diet.js +74 -0
- package/dist/triggers/scene-02-diet.js.map +1 -0
- package/dist/triggers/scene-03-weight.d.ts +4 -0
- package/dist/triggers/scene-03-weight.d.ts.map +1 -0
- package/dist/triggers/scene-03-weight.js +62 -0
- package/dist/triggers/scene-03-weight.js.map +1 -0
- package/dist/triggers/scene-04-exercise.d.ts +4 -0
- package/dist/triggers/scene-04-exercise.d.ts.map +1 -0
- package/dist/triggers/scene-04-exercise.js +43 -0
- package/dist/triggers/scene-04-exercise.js.map +1 -0
- package/dist/triggers/scene-05-workout.d.ts +4 -0
- package/dist/triggers/scene-05-workout.d.ts.map +1 -0
- package/dist/triggers/scene-05-workout.js +36 -0
- package/dist/triggers/scene-05-workout.js.map +1 -0
- package/dist/triggers/scene-06-goal.d.ts +4 -0
- package/dist/triggers/scene-06-goal.d.ts.map +1 -0
- package/dist/triggers/scene-06-goal.js +29 -0
- package/dist/triggers/scene-06-goal.js.map +1 -0
- package/dist/triggers/scene-07-profile.d.ts +4 -0
- package/dist/triggers/scene-07-profile.d.ts.map +1 -0
- package/dist/triggers/scene-07-profile.js +8 -0
- package/dist/triggers/scene-07-profile.js.map +1 -0
- package/dist/triggers/scene-08-body.d.ts +4 -0
- package/dist/triggers/scene-08-body.d.ts.map +1 -0
- package/dist/triggers/scene-08-body.js +17 -0
- package/dist/triggers/scene-08-body.js.map +1 -0
- package/dist/triggers/scene-09-photo.d.ts +4 -0
- package/dist/triggers/scene-09-photo.d.ts.map +1 -0
- package/dist/triggers/scene-09-photo.js +14 -0
- package/dist/triggers/scene-09-photo.js.map +1 -0
- package/dist/triggers/scene-10-analysis.d.ts +4 -0
- package/dist/triggers/scene-10-analysis.d.ts.map +1 -0
- package/dist/triggers/scene-10-analysis.js +180 -0
- package/dist/triggers/scene-10-analysis.js.map +1 -0
- package/dist/triggers/types.d.ts +66 -0
- package/dist/triggers/types.d.ts.map +1 -0
- package/dist/triggers/types.js +3 -0
- package/dist/triggers/types.js.map +1 -0
- 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":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvF,MAAM,UAAU,YAAY,CAAC,EAAgB,EAAE,MAAmB;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAChD,MAAM,IAAI,GAAI,MAAM,CAAC,CAAC,CAA2B,EAAE,WAAW,IAAI,IAAI,CAAC;IACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAK,CAAC,CAAC,QAAmB,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;IAC9H,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC1C,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAChB,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,WAAW,GAAG,IAAI,GAAG,eAAe,GAAG,QAAQ,CAAC,MAAM,GAAG,IAAI;QAChG,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,iCAAiC;KAC1C,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,KAAe,EAAE,GAAG,CAAC,GAAa,EAAE,UAAU,CAAC,CAAC;QAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9F,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC,CAAC;IACrI,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC,CAAC;IAChH,CAAC;IACD,GAAG,CAAC,OAAO,GAAG,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,KAAK,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAC7H,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAmB;IAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,IAAI,GAAI,MAAM,CAAC,CAAC,CAA2B,EAAE,IAAI,IAAI,IAAI,CAAC;IAChE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,GAAG,iBAAiB,EAAE,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAK,CAAC,CAAC,QAAmB,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC;IAC9H,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC1C,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAChB,KAAK,EAAE,WAAW;QAClB,QAAQ,EAAE,SAAS,GAAG,GAAG,GAAG,gBAAgB,GAAG,QAAQ,CAAC,MAAM,GAAG,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI;QACjG,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC,sBAAsB;KAChG,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC7C,IAAI,OAAO,EAAE,CAAC;QACZ,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,4BAA4B,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC,CAAC;IACpJ,CAAC;IACD,GAAG,CAAC,OAAO,GAAG,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,YAAY,GAAG,QAAQ,CAAC,MAAM,GAAG,KAAK,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC9H,OAAO,GAAG,CAAC;IAEX,SAAS,MAAM,CAAC,CAAS,IAAY,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAmB;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;IAC9D,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACzD,MAAM,MAAM,GAA2B;QACrC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;QACxC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;QACxC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;KACzC,CAAC;IACF,MAAM,GAAG,GAAqC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;IACjG,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAqB,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1J,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAChB,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,+BAA+B;QACtH,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,0CAA0C,CAAC,CAAC,CAAC,aAAa;KAC9G,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC;IACvG,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAC7D,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACxI,CAAC;IACD,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC9E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAAgB,EAAE,MAAmB;IACrE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,EAAE,GAAG,CAAC,KAAe,EAAE,GAAG,CAAC,GAAa,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAqC,CAAC;IAChE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAChB,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QACrG,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,GAAG,yBAAyB,CAAC,CAAC,CAAC,iBAAiB;KACnG,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACrB,0GAA0G,CAC3G,CAAC,GAAG,CAAC,GAAG,CAAC,KAAe,EAAE,GAAG,CAAC,GAAa,CAAuC,CAAC;IACpF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAChB,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACtH,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,uCAAuC;KAChD,CAAC,CAAC;IACH,GAAG,CAAC,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC;IAC/I,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -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":"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"}
|
|
@@ -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":"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"}
|
|
@@ -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"}
|