@titan-design/react-ui 0.2.7 → 0.4.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/bodymap-BhG55xHM.d.mts +318 -0
- package/dist/bodymap-BhG55xHM.d.ts +318 -0
- package/dist/bodymap.d.mts +3 -0
- package/dist/bodymap.d.ts +3 -0
- package/dist/bodymap.js +3014 -0
- package/dist/bodymap.js.map +1 -0
- package/dist/bodymap.mjs +1088 -0
- package/dist/bodymap.mjs.map +1 -0
- package/dist/chunk-2SISKTWM.mjs +1027 -0
- package/dist/chunk-2SISKTWM.mjs.map +1 -0
- package/dist/{chunk-5SSKGS6E.mjs → chunk-7XPB4NAO.mjs} +124 -4
- package/dist/chunk-7XPB4NAO.mjs.map +1 -0
- package/dist/{chunk-3VLOBS6O.mjs → chunk-SNVKL5WZ.mjs} +42 -5
- package/dist/chunk-SNVKL5WZ.mjs.map +1 -0
- package/dist/index.d.mts +416 -250
- package/dist/index.d.ts +416 -250
- package/dist/index.js +1567 -1123
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1491 -2201
- package/dist/index.mjs.map +1 -1
- package/dist/theme/index.d.mts +288 -2
- package/dist/theme/index.d.ts +288 -2
- package/dist/theme/index.js +159 -2
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +2 -2
- package/dist/theme/tokens-css.d.mts +5 -3
- package/dist/theme/tokens-css.d.ts +5 -3
- package/dist/theme/tokens-css.js +318 -9
- package/dist/theme/tokens-css.js.map +1 -1
- package/dist/theme/tokens-css.mjs +1 -1
- package/dist/theme/tokens-css.mjs.map +1 -1
- package/package.json +10 -1
- package/src/bodymap.ts +37 -0
- package/src/components/custom/Table/Table.test.tsx +27 -0
- package/src/components/custom/Table/Table.tsx +33 -17
- package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +118 -0
- package/src/components/custom/Workout/ActiveWorkoutPage.test.tsx +171 -0
- package/src/components/custom/Workout/ActiveWorkoutPage.tsx +442 -0
- package/src/components/custom/Workout/BodyMap.tsx +7 -9
- package/src/components/custom/Workout/BodyMapDetailPanel.tsx +25 -29
- package/src/components/custom/Workout/CapacityBandChart.tsx +2 -3
- package/src/components/custom/Workout/ExerciseCard.test.tsx +24 -0
- package/src/components/custom/Workout/ExerciseCard.tsx +24 -26
- package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +225 -0
- package/src/components/custom/Workout/ExerciseDetailPage.test.tsx +128 -0
- package/src/components/custom/Workout/ExerciseDetailPage.tsx +624 -0
- package/src/components/custom/Workout/InputBar.tsx +10 -12
- package/src/components/custom/Workout/MesoCard.tsx +2 -4
- package/src/components/custom/Workout/MesoProgressBar.test.tsx +12 -0
- package/src/components/custom/Workout/MesoProgressBar.tsx +5 -1
- package/src/components/custom/Workout/MesoStatusCard.tsx +17 -15
- package/src/components/custom/Workout/MuscleGroupChip.tsx +2 -4
- package/src/components/custom/Workout/PlaceholderStrip.tsx +2 -4
- package/src/components/custom/Workout/PrHistoryModal.tsx +12 -14
- package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +257 -0
- package/src/components/custom/Workout/ProgramPlanningPage.test.tsx +142 -0
- package/src/components/custom/Workout/ProgramPlanningPage.tsx +418 -0
- package/src/components/custom/Workout/ReadinessCheck.tsx +13 -12
- package/src/components/custom/Workout/RestTimer.test.tsx +10 -0
- package/src/components/custom/Workout/RestTimer.tsx +12 -9
- package/src/components/custom/Workout/SetRow.tsx +16 -19
- package/src/components/custom/Workout/StatusDot.tsx +1 -0
- package/src/components/custom/Workout/StrengthTrendChart.tsx +15 -17
- package/src/components/custom/Workout/TempoBar.stories.tsx +95 -0
- package/src/components/custom/Workout/TempoBar.test.tsx +103 -0
- package/src/components/custom/Workout/TempoBar.tsx +215 -0
- package/src/components/custom/Workout/TempoDisplay.tsx +3 -1
- package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +212 -0
- package/src/components/custom/Workout/TrainingStatusPage.test.tsx +131 -0
- package/src/components/custom/Workout/TrainingStatusPage.tsx +312 -0
- package/src/components/custom/Workout/VelocityStrip.test.tsx +10 -0
- package/src/components/custom/Workout/VelocityStrip.tsx +19 -16
- package/src/components/custom/Workout/WeekRow.tsx +2 -1
- package/src/components/custom/Workout/WorkoutCard.tsx +3 -6
- package/src/components/custom/Workout/index.ts +80 -32
- package/src/test/nativewind-stub.ts +13 -0
- package/src/theme/ThemeProvider.test.tsx +24 -0
- package/src/theme/ThemeProvider.tsx +50 -0
- package/src/theme/config.completeness.test.ts +77 -0
- package/src/theme/config.ts +151 -0
- package/src/theme/index.ts +2 -0
- package/src/theme/manifest/design-freeze.test.ts +155 -0
- package/src/theme/manifest/extract-css-properties.fixture.html +29 -0
- package/src/theme/manifest/extract-css-properties.test.ts +112 -0
- package/src/theme/resolve-color.ts +19 -0
- package/src/theme/tokens-css.ts +5 -3
- package/src/theme/workout-tokens.ts +12 -14
- package/src/utils/index.ts +10 -0
- package/src/utils/workout-format.test.ts +81 -0
- package/src/utils/workout-format.ts +83 -0
- package/dist/chunk-3VLOBS6O.mjs.map +0 -1
- package/dist/chunk-5SSKGS6E.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -5,13 +5,12 @@ var clsx = require('clsx');
|
|
|
5
5
|
var tailwindMerge = require('tailwind-merge');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
var React24 = require('react');
|
|
8
|
+
var nativewind = require('nativewind');
|
|
8
9
|
var lucideReact = require('lucide-react');
|
|
9
|
-
var BodyHighlighter = require('react-native-body-highlighter');
|
|
10
10
|
|
|
11
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
12
|
|
|
13
13
|
var React24__default = /*#__PURE__*/_interopDefault(React24);
|
|
14
|
-
var BodyHighlighter__default = /*#__PURE__*/_interopDefault(BodyHighlighter);
|
|
15
14
|
|
|
16
15
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
17
16
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
@@ -1211,6 +1210,28 @@ var PasswordInput = React24.forwardRef(function PasswordInput2({ showIcon, hideI
|
|
|
1211
1210
|
});
|
|
1212
1211
|
|
|
1213
1212
|
// src/theme/config.ts
|
|
1213
|
+
var themeIndependentCSSVars = {
|
|
1214
|
+
// RGB decomposed values for glow shadows
|
|
1215
|
+
"--color-brand-primary-rgb": "255, 121, 0",
|
|
1216
|
+
"--color-brand-secondary-rgb": "64, 109, 135",
|
|
1217
|
+
"--color-status-success-rgb": "20, 184, 166",
|
|
1218
|
+
"--color-status-error-rgb": "209, 67, 67",
|
|
1219
|
+
"--color-status-warning-rgb": "255, 176, 32",
|
|
1220
|
+
"--color-status-info-rgb": "33, 150, 243",
|
|
1221
|
+
"--color-background-base-rgb": "16, 16, 16",
|
|
1222
|
+
// Font families
|
|
1223
|
+
"--font-family-sans": "'Inter'",
|
|
1224
|
+
"--font-family-body": "'Nunito Sans'",
|
|
1225
|
+
"--font-family-heading": "'Space Grotesk'",
|
|
1226
|
+
"--font-family-mono": "'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace",
|
|
1227
|
+
// Animation tokens
|
|
1228
|
+
"--ease-out": "cubic-bezier(0.22, 1, 0.36, 1)",
|
|
1229
|
+
"--ease-in-out": "cubic-bezier(0.65, 0, 0.35, 1)",
|
|
1230
|
+
"--ease-spring": "cubic-bezier(0.34, 1.56, 0.64, 1)",
|
|
1231
|
+
"--duration-fast": "150ms",
|
|
1232
|
+
"--duration-normal": "250ms",
|
|
1233
|
+
"--duration-slow": "400ms"
|
|
1234
|
+
};
|
|
1214
1235
|
var lightThemeCSSVars = {
|
|
1215
1236
|
"--color-brand-primary": semanticColorsLight["brand-primary"],
|
|
1216
1237
|
"--color-brand-primary-light": semanticColorsLight["brand-primary-light"],
|
|
@@ -1251,7 +1272,56 @@ var lightThemeCSSVars = {
|
|
|
1251
1272
|
"--color-interactive-active": semanticColorsLight["interactive-active"],
|
|
1252
1273
|
"--color-interactive-selected": semanticColorsLight["interactive-selected"],
|
|
1253
1274
|
"--color-interactive-disabled": semanticColorsLight["interactive-disabled"],
|
|
1254
|
-
"--color-divider": semanticColorsLight["divider"]
|
|
1275
|
+
"--color-divider": semanticColorsLight["divider"],
|
|
1276
|
+
"--color-brand-primary-hover": semanticColorsLight["brand-primary-hover"],
|
|
1277
|
+
"--color-brand-primary-active": semanticColorsLight["brand-primary-active"],
|
|
1278
|
+
"--color-brand-secondary-hover": semanticColorsLight["brand-secondary-hover"],
|
|
1279
|
+
"--color-brand-secondary-active": semanticColorsLight["brand-secondary-active"],
|
|
1280
|
+
"--color-status-success-light": semanticColorsLight["status-success-light"],
|
|
1281
|
+
"--color-status-success-dark": semanticColorsLight["status-success-dark"],
|
|
1282
|
+
"--color-status-error-light": semanticColorsLight["status-error-light"],
|
|
1283
|
+
"--color-status-error-dark": semanticColorsLight["status-error-dark"],
|
|
1284
|
+
"--color-status-warning-light": semanticColorsLight["status-warning-light"],
|
|
1285
|
+
"--color-status-warning-dark": semanticColorsLight["status-warning-dark"],
|
|
1286
|
+
"--color-status-info-light": semanticColorsLight["status-info-light"],
|
|
1287
|
+
"--color-status-info-dark": semanticColorsLight["status-info-dark"],
|
|
1288
|
+
"--color-on-status-success": semanticColorsLight["on-status-success"],
|
|
1289
|
+
"--color-on-status-error": semanticColorsLight["on-status-error"],
|
|
1290
|
+
"--color-on-status-warning": semanticColorsLight["on-status-warning"],
|
|
1291
|
+
"--color-on-status-info": semanticColorsLight["on-status-info"],
|
|
1292
|
+
"--color-result-improve": semanticColorsLight["result-improve"],
|
|
1293
|
+
"--color-result-improve-light": semanticColorsLight["result-improve-light"],
|
|
1294
|
+
"--color-result-improve-dark": semanticColorsLight["result-improve-dark"],
|
|
1295
|
+
"--color-result-degrade": semanticColorsLight["result-degrade"],
|
|
1296
|
+
"--color-result-degrade-light": semanticColorsLight["result-degrade-light"],
|
|
1297
|
+
"--color-result-degrade-dark": semanticColorsLight["result-degrade-dark"],
|
|
1298
|
+
"--color-result-inconclusive": semanticColorsLight["result-inconclusive"],
|
|
1299
|
+
"--color-result-inconclusive-light": semanticColorsLight["result-inconclusive-light"],
|
|
1300
|
+
"--color-result-neutral": semanticColorsLight["result-neutral"],
|
|
1301
|
+
"--color-on-result-improve": semanticColorsLight["on-result-improve"],
|
|
1302
|
+
"--color-on-result-degrade": semanticColorsLight["on-result-degrade"],
|
|
1303
|
+
"--color-on-result-inconclusive": semanticColorsLight["on-result-inconclusive"],
|
|
1304
|
+
"--color-data-1": semanticColorsLight["data-1"],
|
|
1305
|
+
"--color-data-2": semanticColorsLight["data-2"],
|
|
1306
|
+
"--color-data-3": semanticColorsLight["data-3"],
|
|
1307
|
+
"--color-data-4": semanticColorsLight["data-4"],
|
|
1308
|
+
"--color-data-5": semanticColorsLight["data-5"],
|
|
1309
|
+
"--color-data-6": semanticColorsLight["data-6"],
|
|
1310
|
+
"--color-data-7": semanticColorsLight["data-7"],
|
|
1311
|
+
"--color-data-8": semanticColorsLight["data-8"],
|
|
1312
|
+
"--color-data-9": semanticColorsLight["data-9"],
|
|
1313
|
+
"--color-data-10": semanticColorsLight["data-10"],
|
|
1314
|
+
"--color-text-link-hover": semanticColorsLight["text-link-hover"],
|
|
1315
|
+
"--color-surface-overlay": semanticColorsLight["surface-overlay"],
|
|
1316
|
+
"--color-surface-input": semanticColorsLight["surface-input"],
|
|
1317
|
+
"--color-border-input": semanticColorsLight["border-input"],
|
|
1318
|
+
"--color-border-input-hover": semanticColorsLight["border-input-hover"],
|
|
1319
|
+
"--color-border-input-focus": semanticColorsLight["border-input-focus"],
|
|
1320
|
+
"--color-border-input-error": semanticColorsLight["border-input-error"],
|
|
1321
|
+
"--color-interactive-disabled-text": semanticColorsLight["interactive-disabled-text"],
|
|
1322
|
+
"--color-avatar-background": semanticColorsLight["avatar-background"],
|
|
1323
|
+
"--color-avatar-text": semanticColorsLight["avatar-text"],
|
|
1324
|
+
...themeIndependentCSSVars
|
|
1255
1325
|
};
|
|
1256
1326
|
var darkThemeCSSVars = {
|
|
1257
1327
|
"--color-brand-primary": semanticColorsDark["brand-primary"],
|
|
@@ -1293,7 +1363,56 @@ var darkThemeCSSVars = {
|
|
|
1293
1363
|
"--color-interactive-active": semanticColorsDark["interactive-active"],
|
|
1294
1364
|
"--color-interactive-selected": semanticColorsDark["interactive-selected"],
|
|
1295
1365
|
"--color-interactive-disabled": semanticColorsDark["interactive-disabled"],
|
|
1296
|
-
"--color-divider": semanticColorsDark["divider"]
|
|
1366
|
+
"--color-divider": semanticColorsDark["divider"],
|
|
1367
|
+
"--color-brand-primary-hover": semanticColorsDark["brand-primary-hover"],
|
|
1368
|
+
"--color-brand-primary-active": semanticColorsDark["brand-primary-active"],
|
|
1369
|
+
"--color-brand-secondary-hover": semanticColorsDark["brand-secondary-hover"],
|
|
1370
|
+
"--color-brand-secondary-active": semanticColorsDark["brand-secondary-active"],
|
|
1371
|
+
"--color-status-success-light": semanticColorsDark["status-success-light"],
|
|
1372
|
+
"--color-status-success-dark": semanticColorsDark["status-success-dark"],
|
|
1373
|
+
"--color-status-error-light": semanticColorsDark["status-error-light"],
|
|
1374
|
+
"--color-status-error-dark": semanticColorsDark["status-error-dark"],
|
|
1375
|
+
"--color-status-warning-light": semanticColorsDark["status-warning-light"],
|
|
1376
|
+
"--color-status-warning-dark": semanticColorsDark["status-warning-dark"],
|
|
1377
|
+
"--color-status-info-light": semanticColorsDark["status-info-light"],
|
|
1378
|
+
"--color-status-info-dark": semanticColorsDark["status-info-dark"],
|
|
1379
|
+
"--color-on-status-success": semanticColorsDark["on-status-success"],
|
|
1380
|
+
"--color-on-status-error": semanticColorsDark["on-status-error"],
|
|
1381
|
+
"--color-on-status-warning": semanticColorsDark["on-status-warning"],
|
|
1382
|
+
"--color-on-status-info": semanticColorsDark["on-status-info"],
|
|
1383
|
+
"--color-result-improve": semanticColorsDark["result-improve"],
|
|
1384
|
+
"--color-result-improve-light": semanticColorsDark["result-improve-light"],
|
|
1385
|
+
"--color-result-improve-dark": semanticColorsDark["result-improve-dark"],
|
|
1386
|
+
"--color-result-degrade": semanticColorsDark["result-degrade"],
|
|
1387
|
+
"--color-result-degrade-light": semanticColorsDark["result-degrade-light"],
|
|
1388
|
+
"--color-result-degrade-dark": semanticColorsDark["result-degrade-dark"],
|
|
1389
|
+
"--color-result-inconclusive": semanticColorsDark["result-inconclusive"],
|
|
1390
|
+
"--color-result-inconclusive-light": semanticColorsDark["result-inconclusive-light"],
|
|
1391
|
+
"--color-result-neutral": semanticColorsDark["result-neutral"],
|
|
1392
|
+
"--color-on-result-improve": semanticColorsDark["on-result-improve"],
|
|
1393
|
+
"--color-on-result-degrade": semanticColorsDark["on-result-degrade"],
|
|
1394
|
+
"--color-on-result-inconclusive": semanticColorsDark["on-result-inconclusive"],
|
|
1395
|
+
"--color-data-1": semanticColorsDark["data-1"],
|
|
1396
|
+
"--color-data-2": semanticColorsDark["data-2"],
|
|
1397
|
+
"--color-data-3": semanticColorsDark["data-3"],
|
|
1398
|
+
"--color-data-4": semanticColorsDark["data-4"],
|
|
1399
|
+
"--color-data-5": semanticColorsDark["data-5"],
|
|
1400
|
+
"--color-data-6": semanticColorsDark["data-6"],
|
|
1401
|
+
"--color-data-7": semanticColorsDark["data-7"],
|
|
1402
|
+
"--color-data-8": semanticColorsDark["data-8"],
|
|
1403
|
+
"--color-data-9": semanticColorsDark["data-9"],
|
|
1404
|
+
"--color-data-10": semanticColorsDark["data-10"],
|
|
1405
|
+
"--color-text-link-hover": semanticColorsDark["text-link-hover"],
|
|
1406
|
+
"--color-surface-overlay": semanticColorsDark["surface-overlay"],
|
|
1407
|
+
"--color-surface-input": semanticColorsDark["surface-input"],
|
|
1408
|
+
"--color-border-input": semanticColorsDark["border-input"],
|
|
1409
|
+
"--color-border-input-hover": semanticColorsDark["border-input-hover"],
|
|
1410
|
+
"--color-border-input-focus": semanticColorsDark["border-input-focus"],
|
|
1411
|
+
"--color-border-input-error": semanticColorsDark["border-input-error"],
|
|
1412
|
+
"--color-interactive-disabled-text": semanticColorsDark["interactive-disabled-text"],
|
|
1413
|
+
"--color-avatar-background": semanticColorsDark["avatar-background"],
|
|
1414
|
+
"--color-avatar-text": semanticColorsDark["avatar-text"],
|
|
1415
|
+
...themeIndependentCSSVars
|
|
1297
1416
|
};
|
|
1298
1417
|
function getThemeCSSVars(mode) {
|
|
1299
1418
|
return mode === "dark" ? darkThemeCSSVars : lightThemeCSSVars;
|
|
@@ -2042,6 +2161,21 @@ function validateCssPropertyManifest(candidate) {
|
|
|
2042
2161
|
function isCssPropertyManifest(candidate) {
|
|
2043
2162
|
return validateCssPropertyManifest(candidate).valid;
|
|
2044
2163
|
}
|
|
2164
|
+
var MODE_VARS = {
|
|
2165
|
+
dark: nativewind.vars(darkThemeCSSVars),
|
|
2166
|
+
light: nativewind.vars(lightThemeCSSVars)
|
|
2167
|
+
};
|
|
2168
|
+
function ThemeProvider({
|
|
2169
|
+
mode = "dark",
|
|
2170
|
+
style,
|
|
2171
|
+
children,
|
|
2172
|
+
...props
|
|
2173
|
+
}) {
|
|
2174
|
+
return /* @__PURE__ */ jsx(reactNative.View, { style: [MODE_VARS[mode], { flex: 1 }, style], ...props, children });
|
|
2175
|
+
}
|
|
2176
|
+
function resolveColor(token, mode = "dark") {
|
|
2177
|
+
return reactNative.Platform.OS === "web" ? `var(--color-${token})` : getSemanticColors(mode)[token];
|
|
2178
|
+
}
|
|
2045
2179
|
|
|
2046
2180
|
// src/theme/presets/apply.ts
|
|
2047
2181
|
function colorKeyToVar(key) {
|
|
@@ -4867,7 +5001,7 @@ function ToastProvider({
|
|
|
4867
5001
|
return id;
|
|
4868
5002
|
}, [defaultDuration, maxToasts]);
|
|
4869
5003
|
const removeToast = React24.useCallback((id) => {
|
|
4870
|
-
setToasts((prev) => prev.filter((
|
|
5004
|
+
setToasts((prev) => prev.filter((t2) => t2.id !== id));
|
|
4871
5005
|
}, []);
|
|
4872
5006
|
const removeAllToasts = React24.useCallback(() => {
|
|
4873
5007
|
setToasts([]);
|
|
@@ -5982,7 +6116,7 @@ function Table({
|
|
|
5982
6116
|
selectable,
|
|
5983
6117
|
allRowIds: rowIds
|
|
5984
6118
|
},
|
|
5985
|
-
children: /* @__PURE__ */ jsx(reactNative.View, { className: cn("w-full", className), ...props, children: /* @__PURE__ */ jsx(reactNative.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: /* @__PURE__ */ jsx(reactNative.View, { className: "w-full min-w-full", children: isLoading ? /* @__PURE__ */ jsx(TableLoadingSkeleton, { rowCount: loadingRowCount }) : children }) }) })
|
|
6119
|
+
children: /* @__PURE__ */ jsx(reactNative.View, { className: cn("w-full", className), ...props, children: /* @__PURE__ */ jsx(reactNative.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: /* @__PURE__ */ jsx(reactNative.View, { role: "table", className: "w-full min-w-full", children: isLoading ? /* @__PURE__ */ jsx(TableLoadingSkeleton, { rowCount: loadingRowCount }) : children }) }) })
|
|
5986
6120
|
}
|
|
5987
6121
|
);
|
|
5988
6122
|
}
|
|
@@ -5990,14 +6124,14 @@ function TableHeader({ children, className }) {
|
|
|
5990
6124
|
return /* @__PURE__ */ jsx(
|
|
5991
6125
|
reactNative.View,
|
|
5992
6126
|
{
|
|
5993
|
-
|
|
6127
|
+
role: "rowgroup",
|
|
5994
6128
|
className: cn("bg-background-subtle rounded-t-lg", className),
|
|
5995
6129
|
children
|
|
5996
6130
|
}
|
|
5997
6131
|
);
|
|
5998
6132
|
}
|
|
5999
6133
|
function TableBody({ children, className }) {
|
|
6000
|
-
return /* @__PURE__ */ jsx(reactNative.View, {
|
|
6134
|
+
return /* @__PURE__ */ jsx(reactNative.View, { role: "rowgroup", className, children });
|
|
6001
6135
|
}
|
|
6002
6136
|
function TableRow({
|
|
6003
6137
|
isSelected = false,
|
|
@@ -6009,7 +6143,7 @@ function TableRow({
|
|
|
6009
6143
|
return /* @__PURE__ */ jsx(
|
|
6010
6144
|
reactNative.View,
|
|
6011
6145
|
{
|
|
6012
|
-
|
|
6146
|
+
role: "row",
|
|
6013
6147
|
className: cn(
|
|
6014
6148
|
"flex-row border-b border-divider",
|
|
6015
6149
|
isHoverable && "web:hover:bg-interactive-hover",
|
|
@@ -6033,6 +6167,7 @@ function TableHeaderCell({
|
|
|
6033
6167
|
const { sortColumn, sortDirection, onSort } = React24.useContext(TableContext);
|
|
6034
6168
|
const isSorted = sortKey && sortColumn === sortKey;
|
|
6035
6169
|
const isSortable = !!sortKey && !!onSort;
|
|
6170
|
+
const ariaSort = isSorted ? sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : "none" : "none";
|
|
6036
6171
|
const handlePress = (e) => {
|
|
6037
6172
|
if (isSortable && sortKey) {
|
|
6038
6173
|
onSort(sortKey);
|
|
@@ -6059,26 +6194,34 @@ function TableHeaderCell({
|
|
|
6059
6194
|
] });
|
|
6060
6195
|
if (isSortable) {
|
|
6061
6196
|
return /* @__PURE__ */ jsx(
|
|
6062
|
-
reactNative.
|
|
6197
|
+
reactNative.View,
|
|
6063
6198
|
{
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
onPress: handlePress,
|
|
6199
|
+
role: "columnheader",
|
|
6200
|
+
"aria-sort": ariaSort,
|
|
6067
6201
|
style: width ? { width } : { flex: 1 },
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6202
|
+
children: /* @__PURE__ */ jsx(
|
|
6203
|
+
reactNative.Pressable,
|
|
6204
|
+
{
|
|
6205
|
+
accessibilityRole: "button",
|
|
6206
|
+
accessibilityLabel: `Sort by ${children}`,
|
|
6207
|
+
onPress: handlePress,
|
|
6208
|
+
className: cn(
|
|
6209
|
+
"flex-row items-center px-4 py-3",
|
|
6210
|
+
alignStyles3[align],
|
|
6211
|
+
"web:hover:bg-interactive-hover active:bg-interactive-active",
|
|
6212
|
+
className
|
|
6213
|
+
),
|
|
6214
|
+
...props,
|
|
6215
|
+
children: content
|
|
6216
|
+
}
|
|
6217
|
+
)
|
|
6076
6218
|
}
|
|
6077
6219
|
);
|
|
6078
6220
|
}
|
|
6079
6221
|
return /* @__PURE__ */ jsx(
|
|
6080
6222
|
reactNative.View,
|
|
6081
6223
|
{
|
|
6224
|
+
role: "columnheader",
|
|
6082
6225
|
style: width ? { width } : { flex: 1 },
|
|
6083
6226
|
className: cn(
|
|
6084
6227
|
"flex-row items-center px-4 py-3",
|
|
@@ -6104,6 +6247,7 @@ function TableCell({
|
|
|
6104
6247
|
return /* @__PURE__ */ jsx(
|
|
6105
6248
|
reactNative.View,
|
|
6106
6249
|
{
|
|
6250
|
+
role: "cell",
|
|
6107
6251
|
style: width ? { width } : { flex: 1 },
|
|
6108
6252
|
className: cn(
|
|
6109
6253
|
"justify-center px-4 py-3.5",
|
|
@@ -6985,36 +7129,6 @@ function StatusDot({
|
|
|
6985
7129
|
}
|
|
6986
7130
|
return /* @__PURE__ */ jsx(reactNative.View, { className, ...props, children: dot });
|
|
6987
7131
|
}
|
|
6988
|
-
|
|
6989
|
-
// src/theme/workout-tokens.ts
|
|
6990
|
-
var WORKOUT_TOKENS = {
|
|
6991
|
-
// BodyMap volume heatmap scale (drive dynamic SVG fills, so inline values).
|
|
6992
|
-
// Maps weekly-volume status against MEV/MAV/MRV landmarks to a fill color.
|
|
6993
|
-
heatmap: {
|
|
6994
|
-
none: "#E0E0E0",
|
|
6995
|
-
// gray — no training data
|
|
6996
|
-
under: "#4A90D9",
|
|
6997
|
-
// cool blue — below MEV
|
|
6998
|
-
maintenance: "#F5C842",
|
|
6999
|
-
// warm yellow — MEV to MAV
|
|
7000
|
-
productive: "#4CAF50",
|
|
7001
|
-
// green — MAV to MRV
|
|
7002
|
-
approaching: "#FFA502",
|
|
7003
|
-
// orange — near MRV
|
|
7004
|
-
over: "#FF6B35"
|
|
7005
|
-
// red-orange — over MRV
|
|
7006
|
-
},
|
|
7007
|
-
// Border colors (use inline to avoid 'border' class pitfall)
|
|
7008
|
-
border: {
|
|
7009
|
-
default: "#1F1F1F",
|
|
7010
|
-
strong: "#2C2C2C"},
|
|
7011
|
-
// Surface colors for inline use
|
|
7012
|
-
surface: {
|
|
7013
|
-
raised: "#1C1C1C",
|
|
7014
|
-
elevated: "#191919"
|
|
7015
|
-
}};
|
|
7016
|
-
|
|
7017
|
-
// src/components/custom/Workout/PlaceholderStrip.tsx
|
|
7018
7132
|
function SingleStrip({
|
|
7019
7133
|
width,
|
|
7020
7134
|
className,
|
|
@@ -7023,14 +7137,13 @@ function SingleStrip({
|
|
|
7023
7137
|
return /* @__PURE__ */ jsx(
|
|
7024
7138
|
reactNative.View,
|
|
7025
7139
|
{
|
|
7026
|
-
className: cn(className),
|
|
7140
|
+
className: cn("border-border-strong", className),
|
|
7027
7141
|
style: [
|
|
7028
7142
|
{
|
|
7029
7143
|
height: 3,
|
|
7030
7144
|
backgroundColor: "transparent",
|
|
7031
7145
|
borderWidth: 1,
|
|
7032
7146
|
borderStyle: "dashed",
|
|
7033
|
-
borderColor: WORKOUT_TOKENS.border.strong,
|
|
7034
7147
|
borderRadius: 1,
|
|
7035
7148
|
opacity: 0.5
|
|
7036
7149
|
},
|
|
@@ -7064,13 +7177,13 @@ function SegmentedStrip({
|
|
|
7064
7177
|
children: Array.from({ length: segments }, (_, i) => /* @__PURE__ */ jsx(
|
|
7065
7178
|
reactNative.View,
|
|
7066
7179
|
{
|
|
7180
|
+
className: "border-border-strong",
|
|
7067
7181
|
style: {
|
|
7068
7182
|
flex: 1,
|
|
7069
7183
|
height: 3,
|
|
7070
7184
|
backgroundColor: "transparent",
|
|
7071
7185
|
borderWidth: 1,
|
|
7072
7186
|
borderStyle: "dashed",
|
|
7073
|
-
borderColor: WORKOUT_TOKENS.border.strong,
|
|
7074
7187
|
borderRadius: 1,
|
|
7075
7188
|
minWidth: 4
|
|
7076
7189
|
},
|
|
@@ -7092,6 +7205,63 @@ function PlaceholderStrip({
|
|
|
7092
7205
|
}
|
|
7093
7206
|
return /* @__PURE__ */ jsx(SingleStrip, { ...props });
|
|
7094
7207
|
}
|
|
7208
|
+
|
|
7209
|
+
// src/theme/workout-tokens.ts
|
|
7210
|
+
var WORKOUT_TOKENS = {
|
|
7211
|
+
// Canonical 4-band performance scale — the single source for BOTH the
|
|
7212
|
+
// VelocityStrip zone bars and the SetRow RPE color (TD-03.43). The direction
|
|
7213
|
+
// is intentionally inverted between the two consumers: for velocity, green =
|
|
7214
|
+
// fastest/best; for RPE, green = easiest. Each component maps its own
|
|
7215
|
+
// thresholds onto these four colors. Kept as vivid data-viz values (distinct
|
|
7216
|
+
// from the muted status tokens) and theme-independent, so — like the heatmap
|
|
7217
|
+
// scale below — they are consumed inline as a JS import rather than CSS vars.
|
|
7218
|
+
// A JS import also resolves on native RN, unlike var(--…) strings.
|
|
7219
|
+
scale: {
|
|
7220
|
+
green: "#2ed573",
|
|
7221
|
+
yellow: "#ffd43b",
|
|
7222
|
+
orange: "#ffa502",
|
|
7223
|
+
red: "#ff4757"
|
|
7224
|
+
}};
|
|
7225
|
+
|
|
7226
|
+
// src/utils/workout-format.ts
|
|
7227
|
+
function roundRpe(rpe) {
|
|
7228
|
+
return Math.round(rpe * 2) / 2;
|
|
7229
|
+
}
|
|
7230
|
+
function rpeColor(rpe) {
|
|
7231
|
+
if (rpe >= 9.5) return WORKOUT_TOKENS.scale.red;
|
|
7232
|
+
if (rpe >= 8.5) return WORKOUT_TOKENS.scale.orange;
|
|
7233
|
+
if (rpe >= 7) return WORKOUT_TOKENS.scale.yellow;
|
|
7234
|
+
return WORKOUT_TOKENS.scale.green;
|
|
7235
|
+
}
|
|
7236
|
+
function roundWeight(weight) {
|
|
7237
|
+
return Math.round(weight);
|
|
7238
|
+
}
|
|
7239
|
+
function formatVelocity(velocity) {
|
|
7240
|
+
return velocity.toFixed(2);
|
|
7241
|
+
}
|
|
7242
|
+
function roundTempo(tempo) {
|
|
7243
|
+
return tempo.map((v) => Math.round(v * 10) / 10);
|
|
7244
|
+
}
|
|
7245
|
+
function formatSignedPct(ratio) {
|
|
7246
|
+
const pct = Math.round(ratio * 100);
|
|
7247
|
+
return `${pct > 0 ? "+" : ""}${pct}%`;
|
|
7248
|
+
}
|
|
7249
|
+
function formatPrescription(p) {
|
|
7250
|
+
if (p == null) return null;
|
|
7251
|
+
let reps = null;
|
|
7252
|
+
if (p.repsLow != null && p.repsHigh != null) {
|
|
7253
|
+
reps = p.repsLow === p.repsHigh ? `${p.repsLow}` : `${p.repsLow}\u2013${p.repsHigh}`;
|
|
7254
|
+
} else if (p.repsLow != null) {
|
|
7255
|
+
reps = `${p.repsLow}`;
|
|
7256
|
+
}
|
|
7257
|
+
const weight = p.weightLbs != null ? `${p.weightLbs} lb` : null;
|
|
7258
|
+
const head = [reps, weight].filter((s) => s != null).join(" @ ");
|
|
7259
|
+
const rpe = p.rpe != null ? `RPE ${p.rpe}` : null;
|
|
7260
|
+
const full = [head.length > 0 ? head : null, rpe].filter((s) => s != null).join(" \xB7 ");
|
|
7261
|
+
return full.length > 0 ? full : null;
|
|
7262
|
+
}
|
|
7263
|
+
|
|
7264
|
+
// src/components/custom/Workout/TempoDisplay.tsx
|
|
7095
7265
|
var INTER = "Inter, sans-serif";
|
|
7096
7266
|
var TEXT_TERTIARY = "#6B7280";
|
|
7097
7267
|
var phaseColors = {
|
|
@@ -7147,7 +7317,7 @@ function TempoDisplay({
|
|
|
7147
7317
|
...props
|
|
7148
7318
|
}) {
|
|
7149
7319
|
const [showTooltip, setShowTooltip] = React24.useState(false);
|
|
7150
|
-
const [eccentric, pauseBottom, concentric, pauseTop] = tempo;
|
|
7320
|
+
const [eccentric, pauseBottom, concentric, pauseTop] = roundTempo(tempo);
|
|
7151
7321
|
const isSm = size === "sm";
|
|
7152
7322
|
const fontSize = isSm ? 9 : 11;
|
|
7153
7323
|
const monoColor = TEXT_TERTIARY;
|
|
@@ -7300,6 +7470,198 @@ function TempoDisplay({
|
|
|
7300
7470
|
}
|
|
7301
7471
|
);
|
|
7302
7472
|
}
|
|
7473
|
+
|
|
7474
|
+
// src/utils/colors.ts
|
|
7475
|
+
function getStatusColor(status) {
|
|
7476
|
+
return `var(--color-status-${status})`;
|
|
7477
|
+
}
|
|
7478
|
+
function getResultColor(result) {
|
|
7479
|
+
return `var(--color-result-${result})`;
|
|
7480
|
+
}
|
|
7481
|
+
function alpha(color, opacity) {
|
|
7482
|
+
const clampedOpacity = Math.max(0, Math.min(1, opacity));
|
|
7483
|
+
if (color.startsWith("#")) {
|
|
7484
|
+
const hex = color.slice(1);
|
|
7485
|
+
let r, g, b;
|
|
7486
|
+
if (hex.length === 3) {
|
|
7487
|
+
r = parseInt(hex[0] + hex[0], 16);
|
|
7488
|
+
g = parseInt(hex[1] + hex[1], 16);
|
|
7489
|
+
b = parseInt(hex[2] + hex[2], 16);
|
|
7490
|
+
} else if (hex.length === 6) {
|
|
7491
|
+
r = parseInt(hex.slice(0, 2), 16);
|
|
7492
|
+
g = parseInt(hex.slice(2, 4), 16);
|
|
7493
|
+
b = parseInt(hex.slice(4, 6), 16);
|
|
7494
|
+
} else {
|
|
7495
|
+
return color;
|
|
7496
|
+
}
|
|
7497
|
+
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
7498
|
+
}
|
|
7499
|
+
const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
7500
|
+
if (rgbMatch) {
|
|
7501
|
+
const [, r, g, b] = rgbMatch;
|
|
7502
|
+
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
7503
|
+
}
|
|
7504
|
+
const rgbaMatch = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/);
|
|
7505
|
+
if (rgbaMatch) {
|
|
7506
|
+
const [, r, g, b] = rgbaMatch;
|
|
7507
|
+
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
7508
|
+
}
|
|
7509
|
+
return color;
|
|
7510
|
+
}
|
|
7511
|
+
function getLuminance(color) {
|
|
7512
|
+
if (!color.startsWith("#")) return "dark";
|
|
7513
|
+
const hex = color.slice(1);
|
|
7514
|
+
let r, g, b;
|
|
7515
|
+
if (hex.length === 3) {
|
|
7516
|
+
r = parseInt(hex[0] + hex[0], 16);
|
|
7517
|
+
g = parseInt(hex[1] + hex[1], 16);
|
|
7518
|
+
b = parseInt(hex[2] + hex[2], 16);
|
|
7519
|
+
} else if (hex.length === 6) {
|
|
7520
|
+
r = parseInt(hex.slice(0, 2), 16);
|
|
7521
|
+
g = parseInt(hex.slice(2, 4), 16);
|
|
7522
|
+
b = parseInt(hex.slice(4, 6), 16);
|
|
7523
|
+
} else {
|
|
7524
|
+
return "dark";
|
|
7525
|
+
}
|
|
7526
|
+
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
7527
|
+
return luminance > 0.5 ? "light" : "dark";
|
|
7528
|
+
}
|
|
7529
|
+
function getContrastText(backgroundColor) {
|
|
7530
|
+
return getLuminance(backgroundColor) === "light" ? "#000000" : "#FFFFFF";
|
|
7531
|
+
}
|
|
7532
|
+
|
|
7533
|
+
// src/components/custom/Workout/TempoBar.tsx
|
|
7534
|
+
var t = getSemanticColors("dark");
|
|
7535
|
+
var TEMPO_PACING = {
|
|
7536
|
+
behindThresholdPct: 0.15,
|
|
7537
|
+
minPhaseDurationMs: 500
|
|
7538
|
+
};
|
|
7539
|
+
function getTempoPacingState(elapsedMs, targetMs) {
|
|
7540
|
+
if (!targetMs || targetMs < TEMPO_PACING.minPhaseDurationMs) return "none";
|
|
7541
|
+
const ratio = elapsedMs / targetMs;
|
|
7542
|
+
if (ratio > 1 + TEMPO_PACING.behindThresholdPct) return "behind";
|
|
7543
|
+
return "on-pace";
|
|
7544
|
+
}
|
|
7545
|
+
function getTempoFillPct(elapsedMs, targetMs) {
|
|
7546
|
+
if (!targetMs) return 100;
|
|
7547
|
+
return Math.min(100, elapsedMs / targetMs * 100);
|
|
7548
|
+
}
|
|
7549
|
+
var PHASE_ORDER = ["concentric", "hold", "eccentric"];
|
|
7550
|
+
var PHASE_CONFIG = {
|
|
7551
|
+
concentric: { label: "Con", color: t["status-success"], flex: 2 },
|
|
7552
|
+
hold: { label: "Hold", color: t["brand-primary"], flex: 1 },
|
|
7553
|
+
eccentric: { label: "Ecc", color: t["status-warning"], flex: 3 }
|
|
7554
|
+
};
|
|
7555
|
+
function TempoBar({
|
|
7556
|
+
activePhase,
|
|
7557
|
+
phaseElapsedMs,
|
|
7558
|
+
completed,
|
|
7559
|
+
target,
|
|
7560
|
+
className,
|
|
7561
|
+
...props
|
|
7562
|
+
}) {
|
|
7563
|
+
return /* @__PURE__ */ jsxs(reactNative.View, { className, testID: "tempo-bar", ...props, children: [
|
|
7564
|
+
/* @__PURE__ */ jsx(reactNative.View, { style: { flexDirection: "row", marginBottom: 4 }, children: PHASE_ORDER.map((phase) => {
|
|
7565
|
+
const config = PHASE_CONFIG[phase];
|
|
7566
|
+
return /* @__PURE__ */ jsx(reactNative.View, { style: { flex: config.flex, alignItems: "center" }, children: /* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 10, color: t["text-disabled"] }, children: config.label }) }, phase);
|
|
7567
|
+
}) }),
|
|
7568
|
+
/* @__PURE__ */ jsx(reactNative.View, { style: { flexDirection: "row", gap: 2, height: 20 }, children: PHASE_ORDER.map((phase) => {
|
|
7569
|
+
const config = PHASE_CONFIG[phase];
|
|
7570
|
+
const isActive = activePhase === phase;
|
|
7571
|
+
const completedMs = completed?.[phase];
|
|
7572
|
+
const targetSec = target?.[phase];
|
|
7573
|
+
const targetMs = targetSec != null ? targetSec * 1e3 : null;
|
|
7574
|
+
return /* @__PURE__ */ jsx(
|
|
7575
|
+
reactNative.View,
|
|
7576
|
+
{
|
|
7577
|
+
style: {
|
|
7578
|
+
flex: config.flex,
|
|
7579
|
+
backgroundColor: alpha("#ffffff", 0.06),
|
|
7580
|
+
borderRadius: 4,
|
|
7581
|
+
overflow: "hidden"
|
|
7582
|
+
},
|
|
7583
|
+
children: isActive ? /* @__PURE__ */ jsx(
|
|
7584
|
+
ActiveSegment,
|
|
7585
|
+
{
|
|
7586
|
+
config,
|
|
7587
|
+
phaseElapsedMs,
|
|
7588
|
+
targetMs
|
|
7589
|
+
}
|
|
7590
|
+
) : completedMs != null ? /* @__PURE__ */ jsx(CompletedSegment, { config, completedMs, targetMs }) : null
|
|
7591
|
+
},
|
|
7592
|
+
phase
|
|
7593
|
+
);
|
|
7594
|
+
}) })
|
|
7595
|
+
] });
|
|
7596
|
+
}
|
|
7597
|
+
function ActiveSegment({
|
|
7598
|
+
config,
|
|
7599
|
+
phaseElapsedMs,
|
|
7600
|
+
targetMs
|
|
7601
|
+
}) {
|
|
7602
|
+
const pacing = getTempoPacingState(phaseElapsedMs, targetMs);
|
|
7603
|
+
const barColor = pacing === "behind" ? t["status-error"] : config.color;
|
|
7604
|
+
const fillPct = getTempoFillPct(phaseElapsedMs, targetMs);
|
|
7605
|
+
const label = targetMs ? `${formatDuration(phaseElapsedMs)} / ${formatDuration(targetMs)}` : formatDuration(phaseElapsedMs);
|
|
7606
|
+
return /* @__PURE__ */ jsxs(reactNative.View, { style: { height: "100%", position: "relative" }, testID: `tempo-segment-active-${config.label}`, children: [
|
|
7607
|
+
/* @__PURE__ */ jsx(
|
|
7608
|
+
reactNative.View,
|
|
7609
|
+
{
|
|
7610
|
+
style: {
|
|
7611
|
+
position: "absolute",
|
|
7612
|
+
left: 0,
|
|
7613
|
+
top: 0,
|
|
7614
|
+
bottom: 0,
|
|
7615
|
+
width: `${fillPct}%`,
|
|
7616
|
+
backgroundColor: alpha(barColor, 0.3),
|
|
7617
|
+
borderRadius: 4
|
|
7618
|
+
}
|
|
7619
|
+
}
|
|
7620
|
+
),
|
|
7621
|
+
/* @__PURE__ */ jsx(
|
|
7622
|
+
reactNative.View,
|
|
7623
|
+
{
|
|
7624
|
+
style: {
|
|
7625
|
+
height: "100%",
|
|
7626
|
+
flexDirection: "row",
|
|
7627
|
+
alignItems: "center",
|
|
7628
|
+
justifyContent: "center"
|
|
7629
|
+
},
|
|
7630
|
+
children: /* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 12, fontWeight: "700", color: barColor }, children: label })
|
|
7631
|
+
}
|
|
7632
|
+
)
|
|
7633
|
+
] });
|
|
7634
|
+
}
|
|
7635
|
+
function CompletedSegment({
|
|
7636
|
+
config,
|
|
7637
|
+
completedMs,
|
|
7638
|
+
targetMs
|
|
7639
|
+
}) {
|
|
7640
|
+
const pacing = getTempoPacingState(completedMs, targetMs);
|
|
7641
|
+
const hitTarget = pacing !== "behind";
|
|
7642
|
+
const indicator = targetMs && targetMs >= TEMPO_PACING.minPhaseDurationMs ? hitTarget ? " \u2713" : " \u2717" : "";
|
|
7643
|
+
return /* @__PURE__ */ jsx(
|
|
7644
|
+
reactNative.View,
|
|
7645
|
+
{
|
|
7646
|
+
style: {
|
|
7647
|
+
height: "100%",
|
|
7648
|
+
flexDirection: "row",
|
|
7649
|
+
alignItems: "center",
|
|
7650
|
+
justifyContent: "center",
|
|
7651
|
+
backgroundColor: alpha(config.color, 0.15)
|
|
7652
|
+
},
|
|
7653
|
+
testID: `tempo-segment-completed-${config.label}`,
|
|
7654
|
+
children: /* @__PURE__ */ jsxs(reactNative.Text, { style: { fontSize: 12, fontWeight: "500", color: alpha(config.color, 0.7) }, children: [
|
|
7655
|
+
formatDuration(completedMs),
|
|
7656
|
+
indicator
|
|
7657
|
+
] })
|
|
7658
|
+
}
|
|
7659
|
+
);
|
|
7660
|
+
}
|
|
7661
|
+
function formatDuration(ms) {
|
|
7662
|
+
const s = ms / 1e3;
|
|
7663
|
+
return s < 10 ? s.toFixed(1) : Math.round(s).toString();
|
|
7664
|
+
}
|
|
7303
7665
|
function getDotColor(deviation) {
|
|
7304
7666
|
const abs = Math.abs(deviation);
|
|
7305
7667
|
if (deviation < -0.3) return "#14B8A6";
|
|
@@ -7655,12 +8017,7 @@ function WorkoutPill({
|
|
|
7655
8017
|
}
|
|
7656
8018
|
return pill;
|
|
7657
8019
|
}
|
|
7658
|
-
var VEL_COLORS =
|
|
7659
|
-
green: "#2ed573",
|
|
7660
|
-
yellow: "#ffd43b",
|
|
7661
|
-
orange: "#ffa502",
|
|
7662
|
-
red: "#ff4757"
|
|
7663
|
-
};
|
|
8020
|
+
var VEL_COLORS = WORKOUT_TOKENS.scale;
|
|
7664
8021
|
function getVelocityZoneColor(velocity) {
|
|
7665
8022
|
if (velocity >= 1) return "vel-green";
|
|
7666
8023
|
if (velocity >= 0.75) return "vel-yellow";
|
|
@@ -7787,7 +8144,7 @@ function VelocityStrip({
|
|
|
7787
8144
|
const stripContent = /* @__PURE__ */ jsxs(
|
|
7788
8145
|
reactNative.Animated.View,
|
|
7789
8146
|
{
|
|
7790
|
-
className,
|
|
8147
|
+
className: [className, expanded ? "bg-surface-raised" : "bg-transparent"].filter(Boolean).join(" "),
|
|
7791
8148
|
style: [
|
|
7792
8149
|
{
|
|
7793
8150
|
height: heightAnim,
|
|
@@ -7798,7 +8155,6 @@ function VelocityStrip({
|
|
|
7798
8155
|
paddingBottom: expanded ? 24 : 0,
|
|
7799
8156
|
paddingHorizontal: expanded ? 6 : 0,
|
|
7800
8157
|
paddingVertical: expanded ? void 0 : 8,
|
|
7801
|
-
backgroundColor: expanded ? "#1C1C1C" : "transparent",
|
|
7802
8158
|
overflow: expanded ? "visible" : "hidden"
|
|
7803
8159
|
}
|
|
7804
8160
|
],
|
|
@@ -7813,7 +8169,7 @@ function VelocityStrip({
|
|
|
7813
8169
|
style: { flexDirection: "row", flex: 1, gap: 2, alignItems: "flex-end" },
|
|
7814
8170
|
children: velocities.map((v, i) => {
|
|
7815
8171
|
const zone = getVelocityZoneColor(v);
|
|
7816
|
-
const barHeightPct = Math.round(v / (maxVelocity * 1.15) * 100);
|
|
8172
|
+
const barHeightPct = maxVelocity > 0 ? Math.round(v / (maxVelocity * 1.15) * 100) : 0;
|
|
7817
8173
|
const bar = /* @__PURE__ */ jsxs(
|
|
7818
8174
|
reactNative.View,
|
|
7819
8175
|
{
|
|
@@ -7822,9 +8178,10 @@ function VelocityStrip({
|
|
|
7822
8178
|
expanded && /* @__PURE__ */ jsx(reactNative.Animated.View, { style: { opacity: labelOpacity, alignItems: "center", position: "absolute", top: -13, left: 0, right: 0 }, accessibilityElementsHidden: true, children: /* @__PURE__ */ jsx(
|
|
7823
8179
|
reactNative.Text,
|
|
7824
8180
|
{
|
|
7825
|
-
|
|
8181
|
+
className: "text-text-secondary",
|
|
8182
|
+
style: { fontSize: 8, fontWeight: "600" },
|
|
7826
8183
|
testID: `velocity-label-${i}`,
|
|
7827
|
-
children: v
|
|
8184
|
+
children: formatVelocity(v)
|
|
7828
8185
|
}
|
|
7829
8186
|
) }),
|
|
7830
8187
|
/* @__PURE__ */ jsx(
|
|
@@ -7840,7 +8197,7 @@ function VelocityStrip({
|
|
|
7840
8197
|
},
|
|
7841
8198
|
testID: `velocity-bar-${i}`,
|
|
7842
8199
|
accessibilityRole: "image",
|
|
7843
|
-
accessibilityLabel: `Rep ${i + 1}: ${v
|
|
8200
|
+
accessibilityLabel: `Rep ${i + 1}: ${formatVelocity(v)} meters per second`
|
|
7844
8201
|
}
|
|
7845
8202
|
)
|
|
7846
8203
|
]
|
|
@@ -7854,7 +8211,7 @@ function VelocityStrip({
|
|
|
7854
8211
|
style: { flex: 1, height: "100%" },
|
|
7855
8212
|
onPress: () => onRepPress(i, v),
|
|
7856
8213
|
accessibilityRole: "button",
|
|
7857
|
-
accessibilityLabel: `Rep ${i + 1}: ${v
|
|
8214
|
+
accessibilityLabel: `Rep ${i + 1}: ${formatVelocity(v)} meters per second, tap for details`,
|
|
7858
8215
|
testID: `velocity-bar-pressable-${i}`,
|
|
7859
8216
|
children: bar
|
|
7860
8217
|
},
|
|
@@ -7882,9 +8239,9 @@ function VelocityStrip({
|
|
|
7882
8239
|
/* @__PURE__ */ jsxs(
|
|
7883
8240
|
reactNative.Text,
|
|
7884
8241
|
{
|
|
8242
|
+
className: "text-text-secondary",
|
|
7885
8243
|
style: {
|
|
7886
8244
|
fontSize: 10,
|
|
7887
|
-
color: "#9CA3AF",
|
|
7888
8245
|
fontFamily: "Inter, sans-serif"
|
|
7889
8246
|
},
|
|
7890
8247
|
children: [
|
|
@@ -7892,7 +8249,7 @@ function VelocityStrip({
|
|
|
7892
8249
|
" ",
|
|
7893
8250
|
"\xB7",
|
|
7894
8251
|
" ",
|
|
7895
|
-
meanVelocity
|
|
8252
|
+
formatVelocity(meanVelocity),
|
|
7896
8253
|
" m/s"
|
|
7897
8254
|
]
|
|
7898
8255
|
}
|
|
@@ -7900,9 +8257,9 @@ function VelocityStrip({
|
|
|
7900
8257
|
/* @__PURE__ */ jsxs(
|
|
7901
8258
|
reactNative.Text,
|
|
7902
8259
|
{
|
|
8260
|
+
className: "text-text-secondary",
|
|
7903
8261
|
style: {
|
|
7904
8262
|
fontSize: 10,
|
|
7905
|
-
color: "#9CA3AF",
|
|
7906
8263
|
fontFamily: "Inter, sans-serif",
|
|
7907
8264
|
...getLossStyle(loss)
|
|
7908
8265
|
},
|
|
@@ -7952,16 +8309,14 @@ function MuscleGroupChip({
|
|
|
7952
8309
|
const content = /* @__PURE__ */ jsxs(
|
|
7953
8310
|
reactNative.View,
|
|
7954
8311
|
{
|
|
7955
|
-
className,
|
|
8312
|
+
className: ["bg-surface-raised border-border", className].filter(Boolean).join(" "),
|
|
7956
8313
|
style: {
|
|
7957
8314
|
flexDirection: "row",
|
|
7958
8315
|
alignItems: "center",
|
|
7959
8316
|
borderRadius: 9999,
|
|
7960
8317
|
paddingHorizontal: 9,
|
|
7961
8318
|
paddingVertical: 3,
|
|
7962
|
-
|
|
7963
|
-
borderWidth: 1,
|
|
7964
|
-
borderColor: "var(--color-border-default)"
|
|
8319
|
+
borderWidth: 1
|
|
7965
8320
|
},
|
|
7966
8321
|
accessibilityLabel: onPress ? void 0 : `${name}, volume status: ${statusLabel}`,
|
|
7967
8322
|
testID: "muscle-group-chip",
|
|
@@ -7985,11 +8340,11 @@ function MuscleGroupChip({
|
|
|
7985
8340
|
/* @__PURE__ */ jsx(
|
|
7986
8341
|
reactNative.Text,
|
|
7987
8342
|
{
|
|
8343
|
+
className: "text-text-secondary",
|
|
7988
8344
|
style: {
|
|
7989
8345
|
fontFamily: "Inter, sans-serif",
|
|
7990
8346
|
fontWeight: "500",
|
|
7991
|
-
fontSize: 11
|
|
7992
|
-
color: "var(--color-text-secondary)"
|
|
8347
|
+
fontSize: 11
|
|
7993
8348
|
},
|
|
7994
8349
|
accessibilityElementsHidden: true,
|
|
7995
8350
|
children: name
|
|
@@ -8163,15 +8518,9 @@ function Sparkline({
|
|
|
8163
8518
|
}
|
|
8164
8519
|
);
|
|
8165
8520
|
}
|
|
8166
|
-
function getRPEColor(rpe) {
|
|
8167
|
-
if (rpe >= 9.5) return "#ff4757";
|
|
8168
|
-
if (rpe >= 8.5) return "#ffa502";
|
|
8169
|
-
if (rpe >= 7) return "#ffd43b";
|
|
8170
|
-
return "#2ed573";
|
|
8171
|
-
}
|
|
8172
8521
|
function formatAccessibilityLabel(setNumber, reps, weight, unit) {
|
|
8173
8522
|
const repsText = reps != null ? `${reps} reps` : "no reps";
|
|
8174
|
-
const weightText = weight != null ? `at ${weight} ${unit}` : "";
|
|
8523
|
+
const weightText = weight != null ? `at ${roundWeight(weight)} ${unit}` : "";
|
|
8175
8524
|
return `Set ${setNumber}: ${repsText}${weightText ? ` ${weightText}` : ""}`;
|
|
8176
8525
|
}
|
|
8177
8526
|
function SetRow({
|
|
@@ -8245,11 +8594,11 @@ function SetRow({
|
|
|
8245
8594
|
) : /* @__PURE__ */ jsx(
|
|
8246
8595
|
reactNative.Text,
|
|
8247
8596
|
{
|
|
8597
|
+
className: "text-text-secondary",
|
|
8248
8598
|
style: {
|
|
8249
8599
|
fontSize: 13,
|
|
8250
8600
|
fontWeight: "600",
|
|
8251
|
-
fontFamily: "Inter, sans-serif"
|
|
8252
|
-
color: "#9CA3AF"
|
|
8601
|
+
fontFamily: "Inter, sans-serif"
|
|
8253
8602
|
},
|
|
8254
8603
|
children: setNumber
|
|
8255
8604
|
}
|
|
@@ -8264,12 +8613,12 @@ function SetRow({
|
|
|
8264
8613
|
children: /* @__PURE__ */ jsx(
|
|
8265
8614
|
reactNative.Text,
|
|
8266
8615
|
{
|
|
8616
|
+
className: "text-text-secondary",
|
|
8267
8617
|
style: {
|
|
8268
8618
|
fontSize: 12,
|
|
8269
|
-
fontFamily: "Inter, sans-serif"
|
|
8270
|
-
color: "#9CA3AF"
|
|
8619
|
+
fontFamily: "Inter, sans-serif"
|
|
8271
8620
|
},
|
|
8272
|
-
children: previous ? `${previous.reps} x ${previous.weight}` : "\u2014"
|
|
8621
|
+
children: previous ? `${previous.reps} x ${roundWeight(previous.weight)}` : "\u2014"
|
|
8273
8622
|
}
|
|
8274
8623
|
)
|
|
8275
8624
|
}
|
|
@@ -8282,11 +8631,11 @@ function SetRow({
|
|
|
8282
8631
|
children: isActive && reps == null && targets ? /* @__PURE__ */ jsx(
|
|
8283
8632
|
reactNative.Text,
|
|
8284
8633
|
{
|
|
8634
|
+
className: "text-text-tertiary",
|
|
8285
8635
|
style: {
|
|
8286
8636
|
fontSize: 13,
|
|
8287
8637
|
fontStyle: "italic",
|
|
8288
|
-
fontFamily: "Inter, sans-serif"
|
|
8289
|
-
color: "#6B7280"
|
|
8638
|
+
fontFamily: "Inter, sans-serif"
|
|
8290
8639
|
},
|
|
8291
8640
|
testID: "set-row-target-reps",
|
|
8292
8641
|
children: targets.reps
|
|
@@ -8294,11 +8643,11 @@ function SetRow({
|
|
|
8294
8643
|
) : /* @__PURE__ */ jsx(
|
|
8295
8644
|
reactNative.Text,
|
|
8296
8645
|
{
|
|
8646
|
+
className: reps != null ? "text-text-primary" : "text-text-tertiary",
|
|
8297
8647
|
style: {
|
|
8298
8648
|
fontSize: 14,
|
|
8299
8649
|
fontWeight: "600",
|
|
8300
|
-
fontFamily: "Inter, sans-serif"
|
|
8301
|
-
color: reps != null ? "#F3F4F6" : "#6B7280"
|
|
8650
|
+
fontFamily: "Inter, sans-serif"
|
|
8302
8651
|
},
|
|
8303
8652
|
children: reps != null ? reps : "\u2014"
|
|
8304
8653
|
}
|
|
@@ -8313,25 +8662,25 @@ function SetRow({
|
|
|
8313
8662
|
children: isActive && weight == null && targets ? /* @__PURE__ */ jsx(
|
|
8314
8663
|
reactNative.Text,
|
|
8315
8664
|
{
|
|
8665
|
+
className: "text-text-tertiary",
|
|
8316
8666
|
style: {
|
|
8317
8667
|
fontSize: 13,
|
|
8318
8668
|
fontStyle: "italic",
|
|
8319
|
-
fontFamily: "Inter, sans-serif"
|
|
8320
|
-
color: "#6B7280"
|
|
8669
|
+
fontFamily: "Inter, sans-serif"
|
|
8321
8670
|
},
|
|
8322
8671
|
testID: "set-row-target-weight",
|
|
8323
|
-
children: targets.weight
|
|
8672
|
+
children: roundWeight(targets.weight)
|
|
8324
8673
|
}
|
|
8325
8674
|
) : /* @__PURE__ */ jsx(
|
|
8326
8675
|
reactNative.Text,
|
|
8327
8676
|
{
|
|
8677
|
+
className: weight != null ? "text-text-primary" : "text-text-tertiary",
|
|
8328
8678
|
style: {
|
|
8329
8679
|
fontSize: 14,
|
|
8330
8680
|
fontWeight: "600",
|
|
8331
|
-
fontFamily: "Inter, sans-serif"
|
|
8332
|
-
color: weight != null ? "#F3F4F6" : "#6B7280"
|
|
8681
|
+
fontFamily: "Inter, sans-serif"
|
|
8333
8682
|
},
|
|
8334
|
-
children: weight != null ? weight : "\u2014"
|
|
8683
|
+
children: weight != null ? roundWeight(weight) : "\u2014"
|
|
8335
8684
|
}
|
|
8336
8685
|
)
|
|
8337
8686
|
}
|
|
@@ -8344,13 +8693,16 @@ function SetRow({
|
|
|
8344
8693
|
children: /* @__PURE__ */ jsx(
|
|
8345
8694
|
reactNative.Text,
|
|
8346
8695
|
{
|
|
8696
|
+
className: rpe != null ? void 0 : "text-text-tertiary",
|
|
8347
8697
|
style: {
|
|
8348
8698
|
fontSize: 13,
|
|
8349
8699
|
fontWeight: "600",
|
|
8350
8700
|
fontFamily: "Inter, sans-serif",
|
|
8351
|
-
|
|
8701
|
+
// rpeColor returns a concrete hex (native-safe); only the tertiary
|
|
8702
|
+
// fallback needs the className token.
|
|
8703
|
+
color: rpe != null ? rpeColor(rpe) : void 0
|
|
8352
8704
|
},
|
|
8353
|
-
children: rpe != null ? rpe : "\u2014"
|
|
8705
|
+
children: rpe != null ? roundRpe(rpe) : "\u2014"
|
|
8354
8706
|
}
|
|
8355
8707
|
)
|
|
8356
8708
|
}
|
|
@@ -8394,18 +8746,14 @@ function SetRow({
|
|
|
8394
8746
|
);
|
|
8395
8747
|
}
|
|
8396
8748
|
var BRAND_PRIMARY2 = "#FF7900";
|
|
8397
|
-
var
|
|
8398
|
-
var TEXT_TERTIARY2 = "#6B7280";
|
|
8749
|
+
var INPUT_CLASSNAME = "bg-surface-raised border-border-strong text-text-primary";
|
|
8399
8750
|
var inputStyle = {
|
|
8400
8751
|
fontSize: 14,
|
|
8401
8752
|
fontWeight: "600",
|
|
8402
8753
|
fontFamily: "Inter, sans-serif",
|
|
8403
|
-
backgroundColor: WORKOUT_TOKENS.surface.raised,
|
|
8404
8754
|
borderWidth: 1,
|
|
8405
|
-
borderColor: WORKOUT_TOKENS.border.strong,
|
|
8406
8755
|
borderRadius: 6,
|
|
8407
8756
|
textAlign: "center",
|
|
8408
|
-
color: TEXT_PRIMARY,
|
|
8409
8757
|
paddingVertical: 5,
|
|
8410
8758
|
paddingHorizontal: 2
|
|
8411
8759
|
};
|
|
@@ -8427,11 +8775,11 @@ function InputBar({
|
|
|
8427
8775
|
return /* @__PURE__ */ jsxs(
|
|
8428
8776
|
reactNative.View,
|
|
8429
8777
|
{
|
|
8778
|
+
className: "bg-surface-elevated",
|
|
8430
8779
|
style: {
|
|
8431
8780
|
width: "100%",
|
|
8432
|
-
backgroundColor: WORKOUT_TOKENS.surface.elevated,
|
|
8433
8781
|
borderTopWidth: 1,
|
|
8434
|
-
borderTopColor:
|
|
8782
|
+
borderTopColor: resolveColor("border-default"),
|
|
8435
8783
|
paddingTop: 10,
|
|
8436
8784
|
paddingHorizontal: 16,
|
|
8437
8785
|
paddingBottom: 12,
|
|
@@ -8446,11 +8794,11 @@ function InputBar({
|
|
|
8446
8794
|
/* @__PURE__ */ jsx(
|
|
8447
8795
|
reactNative.Text,
|
|
8448
8796
|
{
|
|
8797
|
+
className: "text-text-primary",
|
|
8449
8798
|
style: {
|
|
8450
8799
|
fontSize: 12,
|
|
8451
8800
|
fontWeight: "700",
|
|
8452
|
-
fontFamily: '"Space Grotesk", sans-serif'
|
|
8453
|
-
color: TEXT_PRIMARY
|
|
8801
|
+
fontFamily: '"Space Grotesk", sans-serif'
|
|
8454
8802
|
},
|
|
8455
8803
|
testID: "input-bar-exercise-name",
|
|
8456
8804
|
numberOfLines: 1,
|
|
@@ -8460,10 +8808,10 @@ function InputBar({
|
|
|
8460
8808
|
/* @__PURE__ */ jsx(
|
|
8461
8809
|
reactNative.Text,
|
|
8462
8810
|
{
|
|
8811
|
+
className: "text-text-tertiary",
|
|
8463
8812
|
style: {
|
|
8464
8813
|
fontSize: 10,
|
|
8465
|
-
fontFamily: "Inter, sans-serif"
|
|
8466
|
-
color: TEXT_TERTIARY2
|
|
8814
|
+
fontFamily: "Inter, sans-serif"
|
|
8467
8815
|
},
|
|
8468
8816
|
testID: "input-bar-set-info",
|
|
8469
8817
|
children: setLabel
|
|
@@ -8476,6 +8824,7 @@ function InputBar({
|
|
|
8476
8824
|
{
|
|
8477
8825
|
value: reps,
|
|
8478
8826
|
onChangeText: onRepsChange,
|
|
8827
|
+
className: INPUT_CLASSNAME,
|
|
8479
8828
|
style: { ...inputStyle, width: 36 },
|
|
8480
8829
|
accessibilityLabel: "Reps",
|
|
8481
8830
|
testID: "input-bar-reps",
|
|
@@ -8485,10 +8834,10 @@ function InputBar({
|
|
|
8485
8834
|
/* @__PURE__ */ jsx(
|
|
8486
8835
|
reactNative.Text,
|
|
8487
8836
|
{
|
|
8837
|
+
className: "text-text-tertiary",
|
|
8488
8838
|
style: {
|
|
8489
8839
|
fontSize: 12,
|
|
8490
|
-
fontFamily: "Inter, sans-serif"
|
|
8491
|
-
color: TEXT_TERTIARY2
|
|
8840
|
+
fontFamily: "Inter, sans-serif"
|
|
8492
8841
|
},
|
|
8493
8842
|
children: "\xD7"
|
|
8494
8843
|
}
|
|
@@ -8498,6 +8847,7 @@ function InputBar({
|
|
|
8498
8847
|
{
|
|
8499
8848
|
value: weight,
|
|
8500
8849
|
onChangeText: onWeightChange,
|
|
8850
|
+
className: INPUT_CLASSNAME,
|
|
8501
8851
|
style: { ...inputStyle, width: 52 },
|
|
8502
8852
|
accessibilityLabel: `Weight in ${unit}`,
|
|
8503
8853
|
testID: "input-bar-weight",
|
|
@@ -8507,11 +8857,11 @@ function InputBar({
|
|
|
8507
8857
|
/* @__PURE__ */ jsx(
|
|
8508
8858
|
reactNative.Text,
|
|
8509
8859
|
{
|
|
8860
|
+
className: "text-text-tertiary",
|
|
8510
8861
|
style: {
|
|
8511
8862
|
fontSize: 12,
|
|
8512
8863
|
fontWeight: "500",
|
|
8513
|
-
fontFamily: "Inter, sans-serif"
|
|
8514
|
-
color: TEXT_TERTIARY2
|
|
8864
|
+
fontFamily: "Inter, sans-serif"
|
|
8515
8865
|
},
|
|
8516
8866
|
testID: "input-bar-unit",
|
|
8517
8867
|
children: unit
|
|
@@ -8566,15 +8916,16 @@ function RestTimer({
|
|
|
8566
8916
|
const minutes = Math.floor(remainingSec / 60);
|
|
8567
8917
|
const seconds = remainingSec % 60;
|
|
8568
8918
|
const timeDisplay = `${minutes}:${String(seconds).padStart(2, "0")}`;
|
|
8569
|
-
const
|
|
8919
|
+
const totalMs = totalSeconds * 1e3;
|
|
8920
|
+
const progressPct = totalMs > 0 ? Math.min(100, elapsedMs / totalMs * 100) : 100;
|
|
8570
8921
|
return /* @__PURE__ */ jsxs(
|
|
8571
8922
|
reactNative.View,
|
|
8572
8923
|
{
|
|
8924
|
+
className: "bg-surface-raised",
|
|
8573
8925
|
style: {
|
|
8574
8926
|
width: "100%",
|
|
8575
|
-
backgroundColor: WORKOUT_TOKENS.surface.raised,
|
|
8576
8927
|
borderTopWidth: 1,
|
|
8577
|
-
borderTopColor:
|
|
8928
|
+
borderTopColor: resolveColor("border-default"),
|
|
8578
8929
|
paddingVertical: 12,
|
|
8579
8930
|
paddingHorizontal: 16
|
|
8580
8931
|
},
|
|
@@ -8596,13 +8947,13 @@ function RestTimer({
|
|
|
8596
8947
|
/* @__PURE__ */ jsx(
|
|
8597
8948
|
reactNative.Text,
|
|
8598
8949
|
{
|
|
8950
|
+
className: "text-text-secondary",
|
|
8599
8951
|
style: {
|
|
8600
8952
|
fontSize: 11,
|
|
8601
8953
|
fontFamily: "Inter, sans-serif",
|
|
8602
8954
|
fontWeight: "600",
|
|
8603
8955
|
textTransform: "uppercase",
|
|
8604
|
-
letterSpacing: 1
|
|
8605
|
-
color: "#9CA3AF"
|
|
8956
|
+
letterSpacing: 1
|
|
8606
8957
|
},
|
|
8607
8958
|
testID: "rest-timer-label",
|
|
8608
8959
|
children: "REST"
|
|
@@ -8611,10 +8962,10 @@ function RestTimer({
|
|
|
8611
8962
|
nextSetInfo != null && /* @__PURE__ */ jsx(
|
|
8612
8963
|
reactNative.Text,
|
|
8613
8964
|
{
|
|
8965
|
+
className: "text-text-tertiary",
|
|
8614
8966
|
style: {
|
|
8615
8967
|
fontSize: 11,
|
|
8616
8968
|
fontFamily: "Inter, sans-serif",
|
|
8617
|
-
color: "#6B7280",
|
|
8618
8969
|
marginTop: 2
|
|
8619
8970
|
},
|
|
8620
8971
|
testID: "rest-timer-next-set",
|
|
@@ -8625,11 +8976,11 @@ function RestTimer({
|
|
|
8625
8976
|
/* @__PURE__ */ jsx(
|
|
8626
8977
|
reactNative.Text,
|
|
8627
8978
|
{
|
|
8979
|
+
className: "text-text-primary",
|
|
8628
8980
|
style: {
|
|
8629
8981
|
fontSize: 28,
|
|
8630
8982
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
8631
8983
|
fontWeight: "700",
|
|
8632
|
-
color: "#F3F4F6",
|
|
8633
8984
|
fontVariant: ["tabular-nums"],
|
|
8634
8985
|
letterSpacing: -0.5
|
|
8635
8986
|
},
|
|
@@ -8643,9 +8994,9 @@ function RestTimer({
|
|
|
8643
8994
|
/* @__PURE__ */ jsx(
|
|
8644
8995
|
reactNative.View,
|
|
8645
8996
|
{
|
|
8997
|
+
className: "bg-border",
|
|
8646
8998
|
style: {
|
|
8647
8999
|
height: 3,
|
|
8648
|
-
backgroundColor: WORKOUT_TOKENS.border.default,
|
|
8649
9000
|
borderRadius: 2,
|
|
8650
9001
|
marginBottom: 12
|
|
8651
9002
|
},
|
|
@@ -8681,11 +9032,11 @@ function RestTimer({
|
|
|
8681
9032
|
children: /* @__PURE__ */ jsx(
|
|
8682
9033
|
reactNative.Text,
|
|
8683
9034
|
{
|
|
9035
|
+
className: "text-text-secondary",
|
|
8684
9036
|
style: {
|
|
8685
9037
|
fontSize: 11,
|
|
8686
9038
|
fontFamily: "Inter, sans-serif",
|
|
8687
|
-
fontWeight: "600"
|
|
8688
|
-
color: "#9CA3AF"
|
|
9039
|
+
fontWeight: "600"
|
|
8689
9040
|
},
|
|
8690
9041
|
children: "+30s"
|
|
8691
9042
|
}
|
|
@@ -8724,11 +9075,9 @@ function RestTimer({
|
|
|
8724
9075
|
}
|
|
8725
9076
|
);
|
|
8726
9077
|
}
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
textTertiary: "#6B7280"};
|
|
8731
|
-
var COLUMN_HEADERS = ["SET", "PREV", "REPS", "LBS", "RPE"];
|
|
9078
|
+
function buildColumnHeaders(unit) {
|
|
9079
|
+
return ["SET", "PREV", "REPS", unit.toUpperCase(), "RPE"];
|
|
9080
|
+
}
|
|
8732
9081
|
function getSupersetBorderRadius(position) {
|
|
8733
9082
|
switch (position) {
|
|
8734
9083
|
case "first":
|
|
@@ -8769,7 +9118,7 @@ function getSupersetMargin(position) {
|
|
|
8769
9118
|
}
|
|
8770
9119
|
function formatSummary(summary) {
|
|
8771
9120
|
if (!summary) return "";
|
|
8772
|
-
return `${summary.sets}\xD7${summary.reps} @ ${summary.weight} ${summary.unit}`;
|
|
9121
|
+
return `${summary.sets}\xD7${summary.reps} @ ${roundWeight(summary.weight)} ${summary.unit}`;
|
|
8773
9122
|
}
|
|
8774
9123
|
function formatAccessibilityLabel2(name, summary, prescription) {
|
|
8775
9124
|
if (summary) return `${name}, ${formatSummary(summary)}`;
|
|
@@ -8803,11 +9152,11 @@ function CollapsedCard({
|
|
|
8803
9152
|
children: /* @__PURE__ */ jsxs(
|
|
8804
9153
|
reactNative.View,
|
|
8805
9154
|
{
|
|
9155
|
+
className: pressed ? "bg-surface-raised" : void 0,
|
|
8806
9156
|
style: {
|
|
8807
9157
|
padding: 12,
|
|
8808
9158
|
paddingHorizontal: 14,
|
|
8809
9159
|
cursor: "pointer",
|
|
8810
|
-
backgroundColor: pressed ? WORKOUT_TOKENS.surface.raised : "transparent",
|
|
8811
9160
|
...borderRadius,
|
|
8812
9161
|
...supersetMargin
|
|
8813
9162
|
},
|
|
@@ -8821,11 +9170,11 @@ function CollapsedCard({
|
|
|
8821
9170
|
/* @__PURE__ */ jsx(
|
|
8822
9171
|
reactNative.Text,
|
|
8823
9172
|
{
|
|
9173
|
+
className: "text-text-primary",
|
|
8824
9174
|
style: {
|
|
8825
9175
|
fontSize: 14,
|
|
8826
9176
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
8827
|
-
fontWeight: "700"
|
|
8828
|
-
color: COLORS.textPrimary
|
|
9177
|
+
fontWeight: "700"
|
|
8829
9178
|
},
|
|
8830
9179
|
testID: "exercise-card-name",
|
|
8831
9180
|
children: name
|
|
@@ -8835,10 +9184,10 @@ function CollapsedCard({
|
|
|
8835
9184
|
summary && /* @__PURE__ */ jsx(
|
|
8836
9185
|
reactNative.Text,
|
|
8837
9186
|
{
|
|
9187
|
+
className: "text-text-secondary",
|
|
8838
9188
|
style: {
|
|
8839
9189
|
fontSize: 12,
|
|
8840
9190
|
fontFamily: "Inter, sans-serif",
|
|
8841
|
-
color: COLORS.textSecondary,
|
|
8842
9191
|
marginRight: 8
|
|
8843
9192
|
},
|
|
8844
9193
|
testID: "exercise-card-summary",
|
|
@@ -8848,7 +9197,7 @@ function CollapsedCard({
|
|
|
8848
9197
|
e1rm && /* @__PURE__ */ jsx(
|
|
8849
9198
|
WeightBadge,
|
|
8850
9199
|
{
|
|
8851
|
-
value: e1rm.value,
|
|
9200
|
+
value: roundWeight(e1rm.value),
|
|
8852
9201
|
unit: e1rm.unit,
|
|
8853
9202
|
size: "sm",
|
|
8854
9203
|
showIcon: false,
|
|
@@ -8903,13 +9252,14 @@ function ExpandedCard({
|
|
|
8903
9252
|
}) {
|
|
8904
9253
|
const borderRadius = getSupersetBorderRadius(supersetPosition);
|
|
8905
9254
|
const supersetMargin = getSupersetMargin(supersetPosition);
|
|
9255
|
+
const unit = summary?.unit ?? sets?.[0]?.unit ?? "lbs";
|
|
9256
|
+
const columnHeaders = buildColumnHeaders(unit);
|
|
8906
9257
|
return /* @__PURE__ */ jsxs(
|
|
8907
9258
|
reactNative.View,
|
|
8908
9259
|
{
|
|
9260
|
+
className: "bg-surface-elevated border-border",
|
|
8909
9261
|
style: {
|
|
8910
|
-
backgroundColor: WORKOUT_TOKENS.surface.elevated,
|
|
8911
9262
|
borderWidth: 1,
|
|
8912
|
-
borderColor: WORKOUT_TOKENS.border.default,
|
|
8913
9263
|
...borderRadius,
|
|
8914
9264
|
...supersetMargin
|
|
8915
9265
|
},
|
|
@@ -8932,17 +9282,17 @@ function ExpandedCard({
|
|
|
8932
9282
|
paddingHorizontal: 14,
|
|
8933
9283
|
paddingBottom: 10,
|
|
8934
9284
|
borderBottomWidth: 1,
|
|
8935
|
-
borderBottomColor:
|
|
9285
|
+
borderBottomColor: resolveColor("border-default")
|
|
8936
9286
|
},
|
|
8937
9287
|
children: [
|
|
8938
9288
|
/* @__PURE__ */ jsx(
|
|
8939
9289
|
reactNative.Text,
|
|
8940
9290
|
{
|
|
9291
|
+
className: "text-text-primary",
|
|
8941
9292
|
style: {
|
|
8942
9293
|
fontSize: 14,
|
|
8943
9294
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
8944
|
-
fontWeight: "700"
|
|
8945
|
-
color: COLORS.textPrimary
|
|
9295
|
+
fontWeight: "700"
|
|
8946
9296
|
},
|
|
8947
9297
|
testID: "exercise-card-name",
|
|
8948
9298
|
children: name
|
|
@@ -8952,10 +9302,10 @@ function ExpandedCard({
|
|
|
8952
9302
|
summary && /* @__PURE__ */ jsx(
|
|
8953
9303
|
reactNative.Text,
|
|
8954
9304
|
{
|
|
9305
|
+
className: "text-text-secondary",
|
|
8955
9306
|
style: {
|
|
8956
9307
|
fontSize: 12,
|
|
8957
9308
|
fontFamily: "Inter, sans-serif",
|
|
8958
|
-
color: COLORS.textSecondary,
|
|
8959
9309
|
marginRight: 8
|
|
8960
9310
|
},
|
|
8961
9311
|
testID: "exercise-card-summary",
|
|
@@ -8965,7 +9315,7 @@ function ExpandedCard({
|
|
|
8965
9315
|
e1rm && /* @__PURE__ */ jsx(
|
|
8966
9316
|
WeightBadge,
|
|
8967
9317
|
{
|
|
8968
|
-
value: e1rm.value,
|
|
9318
|
+
value: roundWeight(e1rm.value),
|
|
8969
9319
|
unit: e1rm.unit,
|
|
8970
9320
|
size: "sm",
|
|
8971
9321
|
showIcon: false,
|
|
@@ -8989,7 +9339,7 @@ function ExpandedCard({
|
|
|
8989
9339
|
paddingBottom: 4
|
|
8990
9340
|
},
|
|
8991
9341
|
testID: "exercise-card-column-headers",
|
|
8992
|
-
children:
|
|
9342
|
+
children: columnHeaders.map((header, i) => {
|
|
8993
9343
|
const widths = [36, void 0, 44, 56, 36];
|
|
8994
9344
|
const width = widths[i];
|
|
8995
9345
|
const isFlex = width === void 0;
|
|
@@ -9006,13 +9356,13 @@ function ExpandedCard({
|
|
|
9006
9356
|
children: /* @__PURE__ */ jsx(
|
|
9007
9357
|
reactNative.Text,
|
|
9008
9358
|
{
|
|
9359
|
+
className: "text-text-tertiary",
|
|
9009
9360
|
style: {
|
|
9010
9361
|
fontSize: 10,
|
|
9011
9362
|
fontWeight: "600",
|
|
9012
9363
|
fontFamily: "Inter, sans-serif",
|
|
9013
9364
|
textTransform: "uppercase",
|
|
9014
|
-
letterSpacing: 0.8
|
|
9015
|
-
color: COLORS.textTertiary
|
|
9365
|
+
letterSpacing: 0.8
|
|
9016
9366
|
},
|
|
9017
9367
|
children: header
|
|
9018
9368
|
}
|
|
@@ -9052,11 +9402,11 @@ function UpcomingCard({
|
|
|
9052
9402
|
/* @__PURE__ */ jsx(
|
|
9053
9403
|
reactNative.Text,
|
|
9054
9404
|
{
|
|
9405
|
+
className: "text-text-primary",
|
|
9055
9406
|
style: {
|
|
9056
9407
|
fontSize: 14,
|
|
9057
9408
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
9058
|
-
fontWeight: "700"
|
|
9059
|
-
color: COLORS.textPrimary
|
|
9409
|
+
fontWeight: "700"
|
|
9060
9410
|
},
|
|
9061
9411
|
testID: "exercise-card-name",
|
|
9062
9412
|
children: name
|
|
@@ -9065,10 +9415,10 @@ function UpcomingCard({
|
|
|
9065
9415
|
prescription && /* @__PURE__ */ jsx(
|
|
9066
9416
|
reactNative.Text,
|
|
9067
9417
|
{
|
|
9418
|
+
className: "text-text-secondary",
|
|
9068
9419
|
style: {
|
|
9069
9420
|
fontSize: 12,
|
|
9070
9421
|
fontFamily: "Inter, sans-serif",
|
|
9071
|
-
color: COLORS.textSecondary,
|
|
9072
9422
|
marginLeft: 8
|
|
9073
9423
|
},
|
|
9074
9424
|
testID: "exercise-card-prescription",
|
|
@@ -9079,10 +9429,10 @@ function UpcomingCard({
|
|
|
9079
9429
|
previousBest && /* @__PURE__ */ jsx(
|
|
9080
9430
|
reactNative.Text,
|
|
9081
9431
|
{
|
|
9432
|
+
className: "text-text-tertiary",
|
|
9082
9433
|
style: {
|
|
9083
9434
|
fontSize: 11,
|
|
9084
|
-
fontFamily: "Inter, sans-serif"
|
|
9085
|
-
color: COLORS.textTertiary
|
|
9435
|
+
fontFamily: "Inter, sans-serif"
|
|
9086
9436
|
},
|
|
9087
9437
|
testID: "exercise-card-previous-best",
|
|
9088
9438
|
children: previousBest
|
|
@@ -9183,10 +9533,11 @@ function MesoSegment({ meso, isActive, onPress }) {
|
|
|
9183
9533
|
}).start();
|
|
9184
9534
|
};
|
|
9185
9535
|
const progress = meso.status === "current" ? clampProgress(meso.currentWeek, meso.weekCount) : 0;
|
|
9536
|
+
const segmentFlex = Math.max(1, meso.weekCount);
|
|
9186
9537
|
return /* @__PURE__ */ jsx(
|
|
9187
9538
|
reactNative.Pressable,
|
|
9188
9539
|
{
|
|
9189
|
-
style: { flex:
|
|
9540
|
+
style: { flex: segmentFlex },
|
|
9190
9541
|
onPress: () => onPress(meso.id),
|
|
9191
9542
|
onPressIn: handlePressIn,
|
|
9192
9543
|
onPressOut: handlePressOut,
|
|
@@ -9319,11 +9670,12 @@ function WeekRow({
|
|
|
9319
9670
|
/* @__PURE__ */ jsx(
|
|
9320
9671
|
reactNative.Text,
|
|
9321
9672
|
{
|
|
9673
|
+
className: isCurrent ? void 0 : "text-text-primary",
|
|
9322
9674
|
style: {
|
|
9323
9675
|
fontSize: 13,
|
|
9324
9676
|
fontWeight: "700",
|
|
9325
9677
|
fontFamily: "Inter, sans-serif",
|
|
9326
|
-
color: isCurrent ? BRAND_PRIMARY5 :
|
|
9678
|
+
color: isCurrent ? BRAND_PRIMARY5 : void 0
|
|
9327
9679
|
},
|
|
9328
9680
|
accessibilityElementsHidden: true,
|
|
9329
9681
|
children: `W${weekNumber}`
|
|
@@ -9362,19 +9714,16 @@ function WeekRow({
|
|
|
9362
9714
|
}
|
|
9363
9715
|
);
|
|
9364
9716
|
}
|
|
9365
|
-
var
|
|
9366
|
-
textPrimary: "#F3F4F6",
|
|
9367
|
-
textSecondary: "#9CA3AF",
|
|
9368
|
-
textTertiary: "#6B7280",
|
|
9717
|
+
var COLORS = {
|
|
9369
9718
|
statusSuccess: "#14B8A6",
|
|
9370
9719
|
brandPrimary: "#FF7900",
|
|
9371
9720
|
borderDefault: "#1F1F1F",
|
|
9372
9721
|
brandPrimarySubtle: "rgba(255,121,0,0.06)"
|
|
9373
9722
|
};
|
|
9374
9723
|
var statusBorderColors = {
|
|
9375
|
-
completed:
|
|
9376
|
-
today:
|
|
9377
|
-
upcoming:
|
|
9724
|
+
completed: COLORS.statusSuccess,
|
|
9725
|
+
today: COLORS.brandPrimary,
|
|
9726
|
+
upcoming: COLORS.borderDefault
|
|
9378
9727
|
};
|
|
9379
9728
|
var volumeStatusMap = {
|
|
9380
9729
|
under: "behind",
|
|
@@ -9411,11 +9760,11 @@ function WorkoutCard({
|
|
|
9411
9760
|
/* @__PURE__ */ jsx(
|
|
9412
9761
|
reactNative.Text,
|
|
9413
9762
|
{
|
|
9763
|
+
className: "text-text-primary",
|
|
9414
9764
|
style: {
|
|
9415
9765
|
fontSize: 15,
|
|
9416
9766
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
9417
|
-
fontWeight: "700"
|
|
9418
|
-
color: COLORS2.textPrimary
|
|
9767
|
+
fontWeight: "700"
|
|
9419
9768
|
},
|
|
9420
9769
|
testID: "workout-card-name",
|
|
9421
9770
|
children: name
|
|
@@ -9425,10 +9774,10 @@ function WorkoutCard({
|
|
|
9425
9774
|
/* @__PURE__ */ jsx(
|
|
9426
9775
|
reactNative.Text,
|
|
9427
9776
|
{
|
|
9777
|
+
className: "text-text-tertiary",
|
|
9428
9778
|
style: {
|
|
9429
9779
|
fontSize: 11,
|
|
9430
|
-
fontFamily: "Inter, sans-serif"
|
|
9431
|
-
color: COLORS2.textTertiary
|
|
9780
|
+
fontFamily: "Inter, sans-serif"
|
|
9432
9781
|
},
|
|
9433
9782
|
testID: "workout-card-date",
|
|
9434
9783
|
children: date
|
|
@@ -9438,11 +9787,11 @@ function WorkoutCard({
|
|
|
9438
9787
|
/* @__PURE__ */ jsx(
|
|
9439
9788
|
reactNative.Text,
|
|
9440
9789
|
{
|
|
9790
|
+
className: "text-text-secondary",
|
|
9441
9791
|
style: {
|
|
9442
9792
|
marginTop: 4,
|
|
9443
9793
|
fontSize: 12,
|
|
9444
|
-
fontFamily: "Inter, sans-serif"
|
|
9445
|
-
color: COLORS2.textSecondary
|
|
9794
|
+
fontFamily: "Inter, sans-serif"
|
|
9446
9795
|
},
|
|
9447
9796
|
testID: "workout-card-stats",
|
|
9448
9797
|
children: formatStats(totalSets, totalVolume, unit, duration)
|
|
@@ -9473,7 +9822,7 @@ function WorkoutCard({
|
|
|
9473
9822
|
variant: "accent",
|
|
9474
9823
|
elevation: 1,
|
|
9475
9824
|
accentColor: statusBorderColors[status],
|
|
9476
|
-
bgColor: isToday ?
|
|
9825
|
+
bgColor: isToday ? COLORS.brandPrimarySubtle : void 0,
|
|
9477
9826
|
className,
|
|
9478
9827
|
style: isUpcoming ? { opacity: 0.6 } : void 0,
|
|
9479
9828
|
testID: "workout-card",
|
|
@@ -9513,8 +9862,6 @@ var BRAND_PRIMARY6 = "#FF7900";
|
|
|
9513
9862
|
var BRAND_PRIMARY_DARK = "#C45E00";
|
|
9514
9863
|
var BRAND_PRIMARY_LIGHT = "#FFB066";
|
|
9515
9864
|
var BORDER_DEFAULT = "#1F1F1F";
|
|
9516
|
-
var TEXT_PRIMARY2 = "#F3F4F6";
|
|
9517
|
-
var TEXT_SECONDARY = "#9CA3AF";
|
|
9518
9865
|
var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY6, BRAND_PRIMARY_LIGHT];
|
|
9519
9866
|
function heatmapColor(percentage) {
|
|
9520
9867
|
const clamped = Math.max(0, Math.min(100, percentage));
|
|
@@ -9557,11 +9904,11 @@ function MesoCard({
|
|
|
9557
9904
|
/* @__PURE__ */ jsx(
|
|
9558
9905
|
reactNative.Text,
|
|
9559
9906
|
{
|
|
9907
|
+
className: "text-text-primary",
|
|
9560
9908
|
style: {
|
|
9561
9909
|
fontSize: 15,
|
|
9562
9910
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
9563
|
-
fontWeight: "700"
|
|
9564
|
-
color: TEXT_PRIMARY2
|
|
9911
|
+
fontWeight: "700"
|
|
9565
9912
|
},
|
|
9566
9913
|
testID: "meso-card-name",
|
|
9567
9914
|
children: name
|
|
@@ -9572,11 +9919,11 @@ function MesoCard({
|
|
|
9572
9919
|
/* @__PURE__ */ jsx(
|
|
9573
9920
|
reactNative.Text,
|
|
9574
9921
|
{
|
|
9922
|
+
className: "text-text-secondary",
|
|
9575
9923
|
style: {
|
|
9576
9924
|
marginTop: 4,
|
|
9577
9925
|
fontSize: 12,
|
|
9578
|
-
fontFamily: "Inter, sans-serif"
|
|
9579
|
-
color: TEXT_SECONDARY
|
|
9926
|
+
fontFamily: "Inter, sans-serif"
|
|
9580
9927
|
},
|
|
9581
9928
|
testID: "meso-card-subheader",
|
|
9582
9929
|
children: `${split} \xB7 ${weekRange}`
|
|
@@ -9670,11 +10017,7 @@ function MesoCard({
|
|
|
9670
10017
|
var BRAND_PRIMARY7 = "#FF7900";
|
|
9671
10018
|
var RECENT_BORDER = "rgba(255,176,32,0.3)";
|
|
9672
10019
|
var RECENT_GLOW = "0 0 12px rgba(255,176,32,0.06)";
|
|
9673
|
-
var
|
|
9674
|
-
var BORDER_DEFAULT2 = "#1F1F1F";
|
|
9675
|
-
var TEXT_PRIMARY3 = "#F3F4F6";
|
|
9676
|
-
var TEXT_SECONDARY2 = "#9CA3AF";
|
|
9677
|
-
var TEXT_TERTIARY3 = "#6B7280";
|
|
10020
|
+
var BORDER_DEFAULT2 = resolveColor("border-default");
|
|
9678
10021
|
var TYPE_LABELS = {
|
|
9679
10022
|
e1rm: "e1RM",
|
|
9680
10023
|
weight: "Weight",
|
|
@@ -9700,14 +10043,13 @@ function PrRecordRow({ record, index }) {
|
|
|
9700
10043
|
{
|
|
9701
10044
|
accessibilityRole: "text",
|
|
9702
10045
|
accessibilityLabel: a11yLabel,
|
|
9703
|
-
className: "flex-row items-center",
|
|
10046
|
+
className: "flex-row items-center bg-surface-raised",
|
|
9704
10047
|
style: {
|
|
9705
10048
|
gap: 10,
|
|
9706
10049
|
paddingVertical: 10,
|
|
9707
10050
|
paddingHorizontal: 12,
|
|
9708
10051
|
marginBottom: 8,
|
|
9709
10052
|
borderRadius: 8,
|
|
9710
|
-
backgroundColor: SURFACE_RAISED,
|
|
9711
10053
|
borderWidth: 1,
|
|
9712
10054
|
borderColor: record.isRecent ? RECENT_BORDER : BORDER_DEFAULT2,
|
|
9713
10055
|
...record.isRecent ? { boxShadow: RECENT_GLOW } : {}
|
|
@@ -9718,12 +10060,12 @@ function PrRecordRow({ record, index }) {
|
|
|
9718
10060
|
/* @__PURE__ */ jsx(
|
|
9719
10061
|
reactNative.Text,
|
|
9720
10062
|
{
|
|
10063
|
+
className: "text-text-secondary",
|
|
9721
10064
|
style: {
|
|
9722
10065
|
flex: 1,
|
|
9723
10066
|
fontSize: 13,
|
|
9724
10067
|
fontFamily: "Inter, sans-serif",
|
|
9725
|
-
fontWeight: "600"
|
|
9726
|
-
color: TEXT_SECONDARY2
|
|
10068
|
+
fontWeight: "600"
|
|
9727
10069
|
},
|
|
9728
10070
|
testID: `pr-history-modal-record-${index}-type`,
|
|
9729
10071
|
children: label
|
|
@@ -9732,11 +10074,11 @@ function PrRecordRow({ record, index }) {
|
|
|
9732
10074
|
/* @__PURE__ */ jsx(
|
|
9733
10075
|
reactNative.Text,
|
|
9734
10076
|
{
|
|
10077
|
+
className: "text-text-primary",
|
|
9735
10078
|
style: {
|
|
9736
10079
|
fontSize: 14,
|
|
9737
10080
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
9738
|
-
fontWeight: "700"
|
|
9739
|
-
color: TEXT_PRIMARY3
|
|
10081
|
+
fontWeight: "700"
|
|
9740
10082
|
},
|
|
9741
10083
|
testID: `pr-history-modal-record-${index}-value`,
|
|
9742
10084
|
children: valueText
|
|
@@ -9745,12 +10087,12 @@ function PrRecordRow({ record, index }) {
|
|
|
9745
10087
|
/* @__PURE__ */ jsx(
|
|
9746
10088
|
reactNative.Text,
|
|
9747
10089
|
{
|
|
10090
|
+
className: "text-text-tertiary",
|
|
9748
10091
|
style: {
|
|
9749
10092
|
minWidth: 64,
|
|
9750
10093
|
textAlign: "right",
|
|
9751
10094
|
fontSize: 11,
|
|
9752
|
-
fontFamily: "Inter, sans-serif"
|
|
9753
|
-
color: TEXT_TERTIARY3
|
|
10095
|
+
fontFamily: "Inter, sans-serif"
|
|
9754
10096
|
},
|
|
9755
10097
|
testID: `pr-history-modal-record-${index}-date`,
|
|
9756
10098
|
children: record.date
|
|
@@ -9788,13 +10130,13 @@ function PrHistoryModal({
|
|
|
9788
10130
|
reactNative.View,
|
|
9789
10131
|
{
|
|
9790
10132
|
accessibilityElementsHidden: true,
|
|
10133
|
+
className: "bg-border",
|
|
9791
10134
|
style: {
|
|
9792
10135
|
alignSelf: "center",
|
|
9793
10136
|
width: 40,
|
|
9794
10137
|
height: 4,
|
|
9795
10138
|
borderRadius: 2,
|
|
9796
|
-
marginTop: 8
|
|
9797
|
-
backgroundColor: BORDER_DEFAULT2
|
|
10139
|
+
marginTop: 8
|
|
9798
10140
|
},
|
|
9799
10141
|
testID: "pr-history-modal-handle"
|
|
9800
10142
|
}
|
|
@@ -9810,11 +10152,11 @@ function PrHistoryModal({
|
|
|
9810
10152
|
reactNative.Text,
|
|
9811
10153
|
{
|
|
9812
10154
|
accessibilityRole: "header",
|
|
10155
|
+
className: "text-text-primary",
|
|
9813
10156
|
style: {
|
|
9814
10157
|
fontSize: 16,
|
|
9815
10158
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
9816
|
-
fontWeight: "700"
|
|
9817
|
-
color: TEXT_PRIMARY3
|
|
10159
|
+
fontWeight: "700"
|
|
9818
10160
|
},
|
|
9819
10161
|
testID: "pr-history-modal-title",
|
|
9820
10162
|
children: dialogLabel
|
|
@@ -9829,7 +10171,7 @@ function PrHistoryModal({
|
|
|
9829
10171
|
hitSlop: 8,
|
|
9830
10172
|
style: { padding: 4, margin: -4 },
|
|
9831
10173
|
testID: "pr-history-modal-close",
|
|
9832
|
-
children: /* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 22, lineHeight: 22
|
|
10174
|
+
children: /* @__PURE__ */ jsx(reactNative.Text, { className: "text-text-secondary", style: { fontSize: 22, lineHeight: 22 }, children: "\xD7" })
|
|
9833
10175
|
}
|
|
9834
10176
|
)
|
|
9835
10177
|
]
|
|
@@ -9838,11 +10180,11 @@ function PrHistoryModal({
|
|
|
9838
10180
|
/* @__PURE__ */ jsx(DrawerBody, { className: "px-4 pt-0 pb-4", children: records.length === 0 ? /* @__PURE__ */ jsx(reactNative.View, { style: { paddingVertical: 24 }, testID: "pr-history-modal-empty", children: /* @__PURE__ */ jsx(
|
|
9839
10181
|
reactNative.Text,
|
|
9840
10182
|
{
|
|
10183
|
+
className: "text-text-tertiary",
|
|
9841
10184
|
style: {
|
|
9842
10185
|
textAlign: "center",
|
|
9843
10186
|
fontSize: 13,
|
|
9844
|
-
fontFamily: "Inter, sans-serif"
|
|
9845
|
-
color: TEXT_TERTIARY3
|
|
10187
|
+
fontFamily: "Inter, sans-serif"
|
|
9846
10188
|
},
|
|
9847
10189
|
children: "No personal records yet"
|
|
9848
10190
|
}
|
|
@@ -9863,8 +10205,6 @@ var BRAND_PRIMARY_SUBTLE = "rgba(255,121,0,0.12)";
|
|
|
9863
10205
|
var STATUS_SUCCESS = "#14B8A6";
|
|
9864
10206
|
var STATUS_WARNING = "#FFB020";
|
|
9865
10207
|
var STATUS_ERROR = "#D14343";
|
|
9866
|
-
var TEXT_PRIMARY4 = "#F3F4F6";
|
|
9867
|
-
var TEXT_SECONDARY3 = "#9CA3AF";
|
|
9868
10208
|
var EMOJI_SETS = {
|
|
9869
10209
|
sleep: ["\u{1F634}", "\u{1F610}", "\u{1F642}", "\u{1F60A}", "\u{1F929}"],
|
|
9870
10210
|
soreness: ["\u{1F635}", "\u{1F623}", "\u{1F610}", "\u{1F642}", "\u{1F4AA}"],
|
|
@@ -9896,7 +10236,8 @@ function EmojiSlider({ factor }) {
|
|
|
9896
10236
|
/* @__PURE__ */ jsx(
|
|
9897
10237
|
reactNative.Text,
|
|
9898
10238
|
{
|
|
9899
|
-
|
|
10239
|
+
className: "text-text-secondary",
|
|
10240
|
+
style: { fontSize: 12, fontWeight: "500", fontFamily: "Inter, sans-serif" },
|
|
9900
10241
|
testID: "readiness-check-factor-label",
|
|
9901
10242
|
children: factor.label
|
|
9902
10243
|
}
|
|
@@ -9920,14 +10261,15 @@ function EmojiSlider({ factor }) {
|
|
|
9920
10261
|
accessibilityLabel: `${factor.label} level ${level} of 5`,
|
|
9921
10262
|
"aria-checked": selected,
|
|
9922
10263
|
testID: "readiness-check-emoji",
|
|
10264
|
+
className: selected ? void 0 : "border-border bg-surface-raised",
|
|
9923
10265
|
style: ({ pressed }) => ({
|
|
9924
10266
|
flex: 1,
|
|
9925
10267
|
alignItems: "center",
|
|
9926
10268
|
paddingVertical: 8,
|
|
9927
10269
|
borderRadius: 8,
|
|
9928
10270
|
borderWidth: 1,
|
|
9929
|
-
borderColor: selected ? BRAND_PRIMARY8 :
|
|
9930
|
-
backgroundColor: selected ? BRAND_PRIMARY_SUBTLE :
|
|
10271
|
+
borderColor: selected ? BRAND_PRIMARY8 : void 0,
|
|
10272
|
+
backgroundColor: selected ? BRAND_PRIMARY_SUBTLE : void 0,
|
|
9931
10273
|
opacity: selected ? 1 : pressed ? 0.8 : 0.55,
|
|
9932
10274
|
transform: [{ scale: selected ? 1.06 : 1 }]
|
|
9933
10275
|
}),
|
|
@@ -9948,13 +10290,13 @@ function ScoreGauge({ score }) {
|
|
|
9948
10290
|
accessibilityRole: "image",
|
|
9949
10291
|
accessibilityLabel: `Readiness score: ${score} out of 100`,
|
|
9950
10292
|
testID: "readiness-check-score",
|
|
10293
|
+
className: "bg-surface-raised",
|
|
9951
10294
|
style: {
|
|
9952
10295
|
width: 60,
|
|
9953
10296
|
height: 60,
|
|
9954
10297
|
borderRadius: 30,
|
|
9955
10298
|
borderWidth: 4,
|
|
9956
10299
|
borderColor: color,
|
|
9957
|
-
backgroundColor: WORKOUT_TOKENS.surface.raised,
|
|
9958
10300
|
alignItems: "center",
|
|
9959
10301
|
justifyContent: "center"
|
|
9960
10302
|
},
|
|
@@ -9974,13 +10316,12 @@ function WarmUpCard({ validation }) {
|
|
|
9974
10316
|
return /* @__PURE__ */ jsxs(
|
|
9975
10317
|
reactNative.View,
|
|
9976
10318
|
{
|
|
10319
|
+
className: "border-border bg-surface-raised",
|
|
9977
10320
|
style: {
|
|
9978
10321
|
marginTop: 16,
|
|
9979
10322
|
padding: 12,
|
|
9980
10323
|
borderRadius: 8,
|
|
9981
|
-
borderWidth: 1
|
|
9982
|
-
borderColor: WORKOUT_TOKENS.border.default,
|
|
9983
|
-
backgroundColor: WORKOUT_TOKENS.surface.raised
|
|
10324
|
+
borderWidth: 1
|
|
9984
10325
|
},
|
|
9985
10326
|
testID: "readiness-check-warmup",
|
|
9986
10327
|
children: [
|
|
@@ -9988,7 +10329,8 @@ function WarmUpCard({ validation }) {
|
|
|
9988
10329
|
/* @__PURE__ */ jsx(
|
|
9989
10330
|
reactNative.Text,
|
|
9990
10331
|
{
|
|
9991
|
-
|
|
10332
|
+
className: "text-text-secondary",
|
|
10333
|
+
style: { fontSize: 12, fontWeight: "600", fontFamily: "Inter, sans-serif" },
|
|
9992
10334
|
testID: "readiness-check-warmup-deficit",
|
|
9993
10335
|
children: velocityDeficitText(validation.velocityDeficit)
|
|
9994
10336
|
}
|
|
@@ -9998,7 +10340,8 @@ function WarmUpCard({ validation }) {
|
|
|
9998
10340
|
/* @__PURE__ */ jsx(
|
|
9999
10341
|
reactNative.Text,
|
|
10000
10342
|
{
|
|
10001
|
-
|
|
10343
|
+
className: "text-text-primary",
|
|
10344
|
+
style: { marginTop: 6, fontSize: 13, fontFamily: "Inter, sans-serif" },
|
|
10002
10345
|
testID: "readiness-check-warmup-recommendation",
|
|
10003
10346
|
children: validation.recommendation
|
|
10004
10347
|
}
|
|
@@ -10020,7 +10363,8 @@ function ReadinessCheck({
|
|
|
10020
10363
|
/* @__PURE__ */ jsx(
|
|
10021
10364
|
reactNative.Text,
|
|
10022
10365
|
{
|
|
10023
|
-
|
|
10366
|
+
className: "text-text-primary",
|
|
10367
|
+
style: { fontSize: 18, fontWeight: "700", fontFamily: '"Space Grotesk", sans-serif' },
|
|
10024
10368
|
testID: "readiness-check-title",
|
|
10025
10369
|
children: "How are you feeling?"
|
|
10026
10370
|
}
|
|
@@ -10053,14 +10397,11 @@ function ReadinessCheck({
|
|
|
10053
10397
|
var BRAND_PRIMARY9 = "#FF7900";
|
|
10054
10398
|
var BRAND_PRIMARY_DARK2 = "#C45E00";
|
|
10055
10399
|
var BRAND_PRIMARY_LIGHT2 = "#FFB066";
|
|
10056
|
-
var TEXT_PRIMARY5 = "#F3F4F6";
|
|
10057
|
-
var TEXT_SECONDARY4 = "#9CA3AF";
|
|
10058
|
-
var TEXT_TERTIARY4 = "#6B7280";
|
|
10059
10400
|
var SUCCESS = "#14B8A6";
|
|
10060
10401
|
var WARNING = "#FFB020";
|
|
10061
10402
|
var ERROR = "#D14343";
|
|
10062
10403
|
var ACCENT_STOPS2 = [BRAND_PRIMARY_DARK2, BRAND_PRIMARY9, BRAND_PRIMARY_LIGHT2];
|
|
10063
|
-
var CARD_GRADIENT =
|
|
10404
|
+
var CARD_GRADIENT = `linear-gradient(135deg, ${resolveColor("surface-elevated")} 0%, ${resolveColor("surface-raised")} 100%)`;
|
|
10064
10405
|
var GAUGE_GRADIENT = "linear-gradient(90deg, rgba(20,184,166,0.25) 0%, rgba(255,176,32,0.25) 50%, rgba(209,67,67,0.25) 100%)";
|
|
10065
10406
|
var STATUS_VARIANTS = {
|
|
10066
10407
|
success: { bg: "rgba(20,184,166,0.15)", border: "rgba(20,184,166,0.3)", text: SUCCESS },
|
|
@@ -10087,7 +10428,8 @@ function renderCoachingText(text, highlights) {
|
|
|
10087
10428
|
(part, index) => highlights.includes(part) ? /* @__PURE__ */ jsx(
|
|
10088
10429
|
reactNative.Text,
|
|
10089
10430
|
{
|
|
10090
|
-
|
|
10431
|
+
className: "text-text-primary",
|
|
10432
|
+
style: { fontWeight: "700" },
|
|
10091
10433
|
children: part
|
|
10092
10434
|
},
|
|
10093
10435
|
`${part}-${index}`
|
|
@@ -10134,13 +10476,13 @@ function MetricCell({ metric }) {
|
|
|
10134
10476
|
/* @__PURE__ */ jsx(
|
|
10135
10477
|
reactNative.Text,
|
|
10136
10478
|
{
|
|
10479
|
+
className: "text-text-tertiary",
|
|
10137
10480
|
style: {
|
|
10138
10481
|
fontSize: 10,
|
|
10139
10482
|
fontFamily: "Inter, sans-serif",
|
|
10140
10483
|
fontWeight: "600",
|
|
10141
10484
|
letterSpacing: 0.5,
|
|
10142
|
-
textTransform: "uppercase"
|
|
10143
|
-
color: TEXT_TERTIARY4
|
|
10485
|
+
textTransform: "uppercase"
|
|
10144
10486
|
},
|
|
10145
10487
|
children: metric.label
|
|
10146
10488
|
}
|
|
@@ -10148,12 +10490,12 @@ function MetricCell({ metric }) {
|
|
|
10148
10490
|
/* @__PURE__ */ jsx(
|
|
10149
10491
|
reactNative.Text,
|
|
10150
10492
|
{
|
|
10493
|
+
className: "text-text-primary",
|
|
10151
10494
|
style: {
|
|
10152
10495
|
marginTop: 2,
|
|
10153
10496
|
fontSize: 13,
|
|
10154
10497
|
fontFamily: "Inter, sans-serif",
|
|
10155
|
-
fontWeight: "600"
|
|
10156
|
-
color: TEXT_PRIMARY5
|
|
10498
|
+
fontWeight: "600"
|
|
10157
10499
|
},
|
|
10158
10500
|
children: metric.value
|
|
10159
10501
|
}
|
|
@@ -10185,13 +10527,13 @@ function Gauge({ gauge }) {
|
|
|
10185
10527
|
/* @__PURE__ */ jsx(
|
|
10186
10528
|
reactNative.Text,
|
|
10187
10529
|
{
|
|
10530
|
+
className: "text-text-secondary",
|
|
10188
10531
|
style: {
|
|
10189
10532
|
fontSize: 10,
|
|
10190
10533
|
fontFamily: "Inter, sans-serif",
|
|
10191
10534
|
fontWeight: "500",
|
|
10192
10535
|
letterSpacing: 0.5,
|
|
10193
|
-
textTransform: "uppercase"
|
|
10194
|
-
color: TEXT_SECONDARY4
|
|
10536
|
+
textTransform: "uppercase"
|
|
10195
10537
|
},
|
|
10196
10538
|
children: gauge.label
|
|
10197
10539
|
}
|
|
@@ -10199,11 +10541,11 @@ function Gauge({ gauge }) {
|
|
|
10199
10541
|
gauge.sublabel != null && /* @__PURE__ */ jsx(
|
|
10200
10542
|
reactNative.Text,
|
|
10201
10543
|
{
|
|
10544
|
+
className: "text-text-tertiary",
|
|
10202
10545
|
style: {
|
|
10203
10546
|
fontSize: 10,
|
|
10204
10547
|
fontFamily: "Inter, sans-serif",
|
|
10205
|
-
fontWeight: "500"
|
|
10206
|
-
color: TEXT_TERTIARY4
|
|
10548
|
+
fontWeight: "500"
|
|
10207
10549
|
},
|
|
10208
10550
|
children: gauge.sublabel
|
|
10209
10551
|
}
|
|
@@ -10240,6 +10582,7 @@ function Gauge({ gauge }) {
|
|
|
10240
10582
|
/* @__PURE__ */ jsx(
|
|
10241
10583
|
reactNative.View,
|
|
10242
10584
|
{
|
|
10585
|
+
className: "border-text-primary",
|
|
10243
10586
|
style: {
|
|
10244
10587
|
position: "absolute",
|
|
10245
10588
|
left: `${percentage}%`,
|
|
@@ -10249,7 +10592,6 @@ function Gauge({ gauge }) {
|
|
|
10249
10592
|
height: 14,
|
|
10250
10593
|
borderRadius: 9999,
|
|
10251
10594
|
borderWidth: 2,
|
|
10252
|
-
borderColor: TEXT_PRIMARY5,
|
|
10253
10595
|
backgroundColor: markerColor,
|
|
10254
10596
|
boxShadow: "0 0 4px rgba(0,0,0,0.5)"
|
|
10255
10597
|
},
|
|
@@ -10312,12 +10654,12 @@ function MesoStatusCard({
|
|
|
10312
10654
|
/* @__PURE__ */ jsx(
|
|
10313
10655
|
reactNative.Text,
|
|
10314
10656
|
{
|
|
10657
|
+
className: "text-text-primary",
|
|
10315
10658
|
style: {
|
|
10316
10659
|
flexShrink: 1,
|
|
10317
10660
|
fontSize: 15,
|
|
10318
10661
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
10319
|
-
fontWeight: "700"
|
|
10320
|
-
color: TEXT_PRIMARY5
|
|
10662
|
+
fontWeight: "700"
|
|
10321
10663
|
},
|
|
10322
10664
|
testID: "meso-status-card-name",
|
|
10323
10665
|
children: mesoName
|
|
@@ -10330,11 +10672,11 @@ function MesoStatusCard({
|
|
|
10330
10672
|
/* @__PURE__ */ jsx(
|
|
10331
10673
|
reactNative.Text,
|
|
10332
10674
|
{
|
|
10675
|
+
className: "text-text-secondary",
|
|
10333
10676
|
style: {
|
|
10334
10677
|
marginTop: 4,
|
|
10335
10678
|
fontSize: 12,
|
|
10336
|
-
fontFamily: "Inter, sans-serif"
|
|
10337
|
-
color: TEXT_SECONDARY4
|
|
10679
|
+
fontFamily: "Inter, sans-serif"
|
|
10338
10680
|
},
|
|
10339
10681
|
testID: "meso-status-card-subtitle",
|
|
10340
10682
|
children: mesoSubtitle
|
|
@@ -10366,11 +10708,11 @@ function MesoStatusCard({
|
|
|
10366
10708
|
children: /* @__PURE__ */ jsx(
|
|
10367
10709
|
reactNative.Text,
|
|
10368
10710
|
{
|
|
10711
|
+
className: "text-text-secondary",
|
|
10369
10712
|
style: {
|
|
10370
10713
|
fontSize: 12,
|
|
10371
10714
|
lineHeight: 17,
|
|
10372
|
-
fontFamily: "Inter, sans-serif"
|
|
10373
|
-
color: TEXT_SECONDARY4
|
|
10715
|
+
fontFamily: "Inter, sans-serif"
|
|
10374
10716
|
},
|
|
10375
10717
|
children: renderCoachingText(coaching.text, coaching.highlights)
|
|
10376
10718
|
}
|
|
@@ -10415,15 +10757,11 @@ function MesoStatusCard({
|
|
|
10415
10757
|
);
|
|
10416
10758
|
}
|
|
10417
10759
|
var BRAND_PRIMARY10 = "#FF7900";
|
|
10418
|
-
var
|
|
10419
|
-
var TEXT_SECONDARY5 = "#9CA3AF";
|
|
10420
|
-
var TEXT_TERTIARY5 = "#6B7280";
|
|
10421
|
-
var BORDER_STRONG = "#2C2C2C";
|
|
10760
|
+
var PROJECTION_LINE_COLOR = resolveColor("text-tertiary");
|
|
10422
10761
|
var STATUS_SUCCESS2 = "#14B8A6";
|
|
10423
10762
|
var STATUS_ERROR2 = "#D14343";
|
|
10424
10763
|
var STATUS_WARNING2 = "#FFB020";
|
|
10425
10764
|
var GRID_LINE = "rgba(255,255,255,0.06)";
|
|
10426
|
-
var TOOLTIP_BG = "rgba(28,28,28,0.95)";
|
|
10427
10765
|
var SUCCESS_PILL_BG = "rgba(20,184,166,0.10)";
|
|
10428
10766
|
var SUCCESS_PILL_BORDER = "rgba(20,184,166,0.20)";
|
|
10429
10767
|
var ERROR_PILL_BG = "rgba(209,67,67,0.10)";
|
|
@@ -10431,8 +10769,8 @@ var ERROR_PILL_BORDER = "rgba(209,67,67,0.20)";
|
|
|
10431
10769
|
var PLOT_LEFT = 26;
|
|
10432
10770
|
var TOOLTIP_WIDTH = 124;
|
|
10433
10771
|
function timeOf(dateStr) {
|
|
10434
|
-
const
|
|
10435
|
-
return Number.isNaN(
|
|
10772
|
+
const t2 = Date.parse(dateStr);
|
|
10773
|
+
return Number.isNaN(t2) ? 0 : t2;
|
|
10436
10774
|
}
|
|
10437
10775
|
function formatValue(value) {
|
|
10438
10776
|
return `${Math.round(value)}`;
|
|
@@ -10604,7 +10942,7 @@ function StrengthTrendChart({
|
|
|
10604
10942
|
alignItems: "center",
|
|
10605
10943
|
justifyContent: "center"
|
|
10606
10944
|
},
|
|
10607
|
-
children: /* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 12, fontFamily: "Inter, sans-serif"
|
|
10945
|
+
children: /* @__PURE__ */ jsx(reactNative.Text, { className: "text-text-tertiary", style: { fontSize: 12, fontFamily: "Inter, sans-serif" }, children: "No strength data yet" })
|
|
10608
10946
|
}
|
|
10609
10947
|
)
|
|
10610
10948
|
}
|
|
@@ -10648,6 +10986,7 @@ function StrengthTrendChart({
|
|
|
10648
10986
|
children: /* @__PURE__ */ jsx(
|
|
10649
10987
|
reactNative.Text,
|
|
10650
10988
|
{
|
|
10989
|
+
className: "text-text-tertiary",
|
|
10651
10990
|
style: {
|
|
10652
10991
|
position: "absolute",
|
|
10653
10992
|
left: -PLOT_LEFT,
|
|
@@ -10655,8 +10994,7 @@ function StrengthTrendChart({
|
|
|
10655
10994
|
width: PLOT_LEFT - 4,
|
|
10656
10995
|
textAlign: "right",
|
|
10657
10996
|
fontSize: 9,
|
|
10658
|
-
fontFamily: "Inter, sans-serif"
|
|
10659
|
-
color: TEXT_TERTIARY5
|
|
10997
|
+
fontFamily: "Inter, sans-serif"
|
|
10660
10998
|
},
|
|
10661
10999
|
children: line.label
|
|
10662
11000
|
}
|
|
@@ -10699,7 +11037,7 @@ function StrengthTrendChart({
|
|
|
10699
11037
|
ChartLine,
|
|
10700
11038
|
{
|
|
10701
11039
|
coords: geometry.projection,
|
|
10702
|
-
color:
|
|
11040
|
+
color: PROJECTION_LINE_COLOR,
|
|
10703
11041
|
strokeWidth: 2,
|
|
10704
11042
|
dashed: true,
|
|
10705
11043
|
testID: "strength-trend-chart-projection-segment"
|
|
@@ -10775,6 +11113,7 @@ function StrengthTrendChart({
|
|
|
10775
11113
|
{
|
|
10776
11114
|
testID: "strength-trend-chart-tooltip",
|
|
10777
11115
|
accessibilityElementsHidden: true,
|
|
11116
|
+
className: "bg-surface-elevated border-border-strong",
|
|
10778
11117
|
style: {
|
|
10779
11118
|
position: "absolute",
|
|
10780
11119
|
left: Math.max(
|
|
@@ -10783,9 +11122,7 @@ function StrengthTrendChart({
|
|
|
10783
11122
|
),
|
|
10784
11123
|
top: Math.max(0, selectedCoord.y - 52),
|
|
10785
11124
|
maxWidth: TOOLTIP_WIDTH,
|
|
10786
|
-
backgroundColor: TOOLTIP_BG,
|
|
10787
11125
|
borderWidth: 1,
|
|
10788
|
-
borderColor: BORDER_STRONG,
|
|
10789
11126
|
borderRadius: 8,
|
|
10790
11127
|
paddingVertical: 8,
|
|
10791
11128
|
paddingHorizontal: 10
|
|
@@ -10794,10 +11131,10 @@ function StrengthTrendChart({
|
|
|
10794
11131
|
/* @__PURE__ */ jsx(
|
|
10795
11132
|
reactNative.Text,
|
|
10796
11133
|
{
|
|
11134
|
+
className: "text-text-tertiary",
|
|
10797
11135
|
style: {
|
|
10798
11136
|
fontSize: 10,
|
|
10799
|
-
fontFamily: "Inter, sans-serif"
|
|
10800
|
-
color: TEXT_TERTIARY5
|
|
11137
|
+
fontFamily: "Inter, sans-serif"
|
|
10801
11138
|
},
|
|
10802
11139
|
children: selectedCoord.point.sessionLabel ?? selectedCoord.point.date
|
|
10803
11140
|
}
|
|
@@ -10805,12 +11142,12 @@ function StrengthTrendChart({
|
|
|
10805
11142
|
/* @__PURE__ */ jsx(
|
|
10806
11143
|
reactNative.Text,
|
|
10807
11144
|
{
|
|
11145
|
+
className: "text-text-primary",
|
|
10808
11146
|
style: {
|
|
10809
11147
|
marginTop: 2,
|
|
10810
11148
|
fontSize: 13,
|
|
10811
11149
|
fontFamily: "Inter, sans-serif",
|
|
10812
|
-
fontWeight: "700"
|
|
10813
|
-
color: TEXT_PRIMARY6
|
|
11150
|
+
fontWeight: "700"
|
|
10814
11151
|
},
|
|
10815
11152
|
children: `${formatValue(selectedCoord.point.e1rm)} ${unit}`
|
|
10816
11153
|
}
|
|
@@ -10843,14 +11180,14 @@ function StrengthTrendChart({
|
|
|
10843
11180
|
reactNative.Text,
|
|
10844
11181
|
{
|
|
10845
11182
|
testID: "strength-trend-chart-axis-label",
|
|
11183
|
+
className: "text-text-tertiary",
|
|
10846
11184
|
style: {
|
|
10847
11185
|
position: "absolute",
|
|
10848
11186
|
left: boundary.x - 24,
|
|
10849
11187
|
width: 48,
|
|
10850
11188
|
textAlign: "center",
|
|
10851
11189
|
fontSize: 10,
|
|
10852
|
-
fontFamily: "Inter, sans-serif"
|
|
10853
|
-
color: TEXT_TERTIARY5
|
|
11190
|
+
fontFamily: "Inter, sans-serif"
|
|
10854
11191
|
},
|
|
10855
11192
|
children: boundary.label
|
|
10856
11193
|
},
|
|
@@ -10894,7 +11231,7 @@ function StrengthTrendChart({
|
|
|
10894
11231
|
children: [
|
|
10895
11232
|
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { gap: 5 }, children: [
|
|
10896
11233
|
/* @__PURE__ */ jsx(reactNative.View, { style: { width: 14, height: 2.5, borderRadius: 1.5, backgroundColor: BRAND_PRIMARY10 } }),
|
|
10897
|
-
/* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 10, fontFamily: "Inter, sans-serif"
|
|
11234
|
+
/* @__PURE__ */ jsx(reactNative.Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "Actual" })
|
|
10898
11235
|
] }),
|
|
10899
11236
|
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { gap: 5 }, children: [
|
|
10900
11237
|
/* @__PURE__ */ jsx(
|
|
@@ -10905,15 +11242,15 @@ function StrengthTrendChart({
|
|
|
10905
11242
|
height: 0,
|
|
10906
11243
|
borderTopWidth: 2,
|
|
10907
11244
|
borderStyle: "dashed",
|
|
10908
|
-
borderTopColor:
|
|
11245
|
+
borderTopColor: PROJECTION_LINE_COLOR
|
|
10909
11246
|
}
|
|
10910
11247
|
}
|
|
10911
11248
|
),
|
|
10912
|
-
/* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 10, fontFamily: "Inter, sans-serif"
|
|
11249
|
+
/* @__PURE__ */ jsx(reactNative.Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "Projected" })
|
|
10913
11250
|
] }),
|
|
10914
11251
|
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { gap: 5 }, children: [
|
|
10915
11252
|
/* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 12, color: STATUS_WARNING2 }, children: "\u2605" }),
|
|
10916
|
-
/* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 10, fontFamily: "Inter, sans-serif"
|
|
11253
|
+
/* @__PURE__ */ jsx(reactNative.Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "PR" })
|
|
10917
11254
|
] })
|
|
10918
11255
|
]
|
|
10919
11256
|
}
|
|
@@ -10926,7 +11263,6 @@ var STATUS_SUCCESS3 = "#14B8A6";
|
|
|
10926
11263
|
var STATUS_WARNING3 = "#FFB020";
|
|
10927
11264
|
var STATUS_INFO = "#2196F3";
|
|
10928
11265
|
var DOT_BORDER = "#F3F4F6";
|
|
10929
|
-
var TEXT_TERTIARY6 = "#6B7280";
|
|
10930
11266
|
var BAND_FILL = "rgba(20,184,166,0.1)";
|
|
10931
11267
|
var BAND_EDGE = "rgba(20,184,166,0.45)";
|
|
10932
11268
|
var PROJECTION_FILL = "rgba(20,184,166,0.05)";
|
|
@@ -10968,8 +11304,8 @@ function interpEdge(pixels, x, key) {
|
|
|
10968
11304
|
const a = pixels[i];
|
|
10969
11305
|
const b = pixels[i + 1];
|
|
10970
11306
|
if (x >= a.x && x <= b.x) {
|
|
10971
|
-
const
|
|
10972
|
-
return a[key] +
|
|
11307
|
+
const t2 = b.x === a.x ? 0 : (x - a.x) / (b.x - a.x);
|
|
11308
|
+
return a[key] + t2 * (b[key] - a[key]);
|
|
10973
11309
|
}
|
|
10974
11310
|
}
|
|
10975
11311
|
return pixels[pixels.length - 1][key];
|
|
@@ -11207,6 +11543,7 @@ function CapacityBandChart({
|
|
|
11207
11543
|
/* @__PURE__ */ jsx(
|
|
11208
11544
|
reactNative.Text,
|
|
11209
11545
|
{
|
|
11546
|
+
className: "text-text-tertiary",
|
|
11210
11547
|
style: {
|
|
11211
11548
|
position: "absolute",
|
|
11212
11549
|
left: PADDING_LEFT / 2 - 14,
|
|
@@ -11215,7 +11552,6 @@ function CapacityBandChart({
|
|
|
11215
11552
|
textAlign: "center",
|
|
11216
11553
|
fontSize: 9,
|
|
11217
11554
|
fontFamily: "Inter, sans-serif",
|
|
11218
|
-
color: TEXT_TERTIARY6,
|
|
11219
11555
|
transform: [{ rotate: "-90deg" }]
|
|
11220
11556
|
},
|
|
11221
11557
|
accessibilityElementsHidden: true,
|
|
@@ -11229,6 +11565,7 @@ function CapacityBandChart({
|
|
|
11229
11565
|
return /* @__PURE__ */ jsx(
|
|
11230
11566
|
reactNative.Text,
|
|
11231
11567
|
{
|
|
11568
|
+
className: "text-text-tertiary",
|
|
11232
11569
|
style: {
|
|
11233
11570
|
position: "absolute",
|
|
11234
11571
|
left: toX(point.date) - 14,
|
|
@@ -11236,8 +11573,7 @@ function CapacityBandChart({
|
|
|
11236
11573
|
width: 28,
|
|
11237
11574
|
textAlign: "center",
|
|
11238
11575
|
fontSize: 10,
|
|
11239
|
-
fontFamily: "Inter, sans-serif"
|
|
11240
|
-
color: TEXT_TERTIARY6
|
|
11576
|
+
fontFamily: "Inter, sans-serif"
|
|
11241
11577
|
},
|
|
11242
11578
|
accessibilityElementsHidden: true,
|
|
11243
11579
|
importantForAccessibility: "no-hide-descendants",
|
|
@@ -11299,854 +11635,1002 @@ function CapacityBandChart({
|
|
|
11299
11635
|
}
|
|
11300
11636
|
);
|
|
11301
11637
|
}
|
|
11302
|
-
|
|
11303
|
-
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
return MuscleGroup4;
|
|
11321
|
-
})(MuscleGroup || {});
|
|
11322
|
-
var SimpleMuscleGroup = /* @__PURE__ */ ((SimpleMuscleGroup3) => {
|
|
11323
|
-
SimpleMuscleGroup3["CHEST"] = "chest";
|
|
11324
|
-
SimpleMuscleGroup3["BACK"] = "back";
|
|
11325
|
-
SimpleMuscleGroup3["SHOULDERS"] = "shoulders";
|
|
11326
|
-
SimpleMuscleGroup3["BICEPS"] = "biceps";
|
|
11327
|
-
SimpleMuscleGroup3["TRICEPS"] = "triceps";
|
|
11328
|
-
SimpleMuscleGroup3["LEGS"] = "legs";
|
|
11329
|
-
SimpleMuscleGroup3["CORE"] = "core";
|
|
11330
|
-
SimpleMuscleGroup3["FOREARMS"] = "forearms";
|
|
11331
|
-
return SimpleMuscleGroup3;
|
|
11332
|
-
})(SimpleMuscleGroup || {});
|
|
11333
|
-
var SIMPLE_TO_DETAILED = {
|
|
11334
|
-
["chest" /* CHEST */]: ["chest" /* CHEST */],
|
|
11335
|
-
["back" /* BACK */]: ["lats" /* LATS */, "upper_back" /* UPPER_BACK */],
|
|
11336
|
-
["shoulders" /* SHOULDERS */]: [
|
|
11337
|
-
"front_delts" /* FRONT_DELTS */,
|
|
11338
|
-
"side_delts" /* SIDE_DELTS */,
|
|
11339
|
-
"rear_delts" /* REAR_DELTS */
|
|
11340
|
-
],
|
|
11341
|
-
["biceps" /* BICEPS */]: ["biceps" /* BICEPS */],
|
|
11342
|
-
["triceps" /* TRICEPS */]: ["triceps" /* TRICEPS */],
|
|
11343
|
-
["legs" /* LEGS */]: [
|
|
11344
|
-
"quads" /* QUADS */,
|
|
11345
|
-
"hamstrings" /* HAMSTRINGS */,
|
|
11346
|
-
"glutes" /* GLUTES */,
|
|
11347
|
-
"calves" /* CALVES */
|
|
11348
|
-
],
|
|
11349
|
-
["core" /* CORE */]: ["abs" /* ABS */, "obliques" /* OBLIQUES */],
|
|
11350
|
-
["forearms" /* FOREARMS */]: ["forearms" /* FOREARMS */]
|
|
11351
|
-
};
|
|
11352
|
-
var DETAILED_TO_SIMPLE = Object.entries(
|
|
11353
|
-
SIMPLE_TO_DETAILED
|
|
11354
|
-
).reduce(
|
|
11355
|
-
(acc, [simple, groups]) => {
|
|
11356
|
-
for (const group of groups) {
|
|
11357
|
-
acc[group] = simple;
|
|
11358
|
-
}
|
|
11359
|
-
return acc;
|
|
11360
|
-
},
|
|
11361
|
-
{}
|
|
11362
|
-
);
|
|
11363
|
-
var MUSCLE_TO_CATEGORY = {
|
|
11364
|
-
["chest" /* CHEST */]: "push",
|
|
11365
|
-
["front_delts" /* FRONT_DELTS */]: "push",
|
|
11366
|
-
["side_delts" /* SIDE_DELTS */]: "push",
|
|
11367
|
-
["triceps" /* TRICEPS */]: "push",
|
|
11368
|
-
["lats" /* LATS */]: "pull",
|
|
11369
|
-
["upper_back" /* UPPER_BACK */]: "pull",
|
|
11370
|
-
["rear_delts" /* REAR_DELTS */]: "pull",
|
|
11371
|
-
["biceps" /* BICEPS */]: "pull",
|
|
11372
|
-
["forearms" /* FOREARMS */]: "pull",
|
|
11373
|
-
["quads" /* QUADS */]: "legs",
|
|
11374
|
-
["hamstrings" /* HAMSTRINGS */]: "legs",
|
|
11375
|
-
["glutes" /* GLUTES */]: "legs",
|
|
11376
|
-
["calves" /* CALVES */]: "legs",
|
|
11377
|
-
["abs" /* ABS */]: "core",
|
|
11378
|
-
["obliques" /* OBLIQUES */]: "core"
|
|
11379
|
-
};
|
|
11380
|
-
var MUSCLE_TO_SVG_SLUGS = {
|
|
11381
|
-
["chest" /* CHEST */]: ["chest"],
|
|
11382
|
-
["front_delts" /* FRONT_DELTS */]: ["deltoids"],
|
|
11383
|
-
["side_delts" /* SIDE_DELTS */]: ["deltoids"],
|
|
11384
|
-
["rear_delts" /* REAR_DELTS */]: ["deltoids"],
|
|
11385
|
-
["triceps" /* TRICEPS */]: ["triceps"],
|
|
11386
|
-
["lats" /* LATS */]: ["upper-back"],
|
|
11387
|
-
["upper_back" /* UPPER_BACK */]: ["upper-back", "trapezius"],
|
|
11388
|
-
["biceps" /* BICEPS */]: ["biceps"],
|
|
11389
|
-
["forearms" /* FOREARMS */]: ["forearm"],
|
|
11390
|
-
["quads" /* QUADS */]: ["quadriceps"],
|
|
11391
|
-
["hamstrings" /* HAMSTRINGS */]: ["hamstring"],
|
|
11392
|
-
["glutes" /* GLUTES */]: ["gluteal"],
|
|
11393
|
-
["calves" /* CALVES */]: ["calves"],
|
|
11394
|
-
["abs" /* ABS */]: ["abs"],
|
|
11395
|
-
["obliques" /* OBLIQUES */]: ["obliques"]
|
|
11396
|
-
};
|
|
11397
|
-
var MUSCLE_DISPLAY_NAMES = {
|
|
11398
|
-
["chest" /* CHEST */]: "Chest",
|
|
11399
|
-
["front_delts" /* FRONT_DELTS */]: "Front Delts",
|
|
11400
|
-
["side_delts" /* SIDE_DELTS */]: "Side Delts",
|
|
11401
|
-
["rear_delts" /* REAR_DELTS */]: "Rear Delts",
|
|
11402
|
-
["triceps" /* TRICEPS */]: "Triceps",
|
|
11403
|
-
["lats" /* LATS */]: "Lats",
|
|
11404
|
-
["upper_back" /* UPPER_BACK */]: "Upper Back",
|
|
11405
|
-
["biceps" /* BICEPS */]: "Biceps",
|
|
11406
|
-
["forearms" /* FOREARMS */]: "Forearms",
|
|
11407
|
-
["quads" /* QUADS */]: "Quads",
|
|
11408
|
-
["hamstrings" /* HAMSTRINGS */]: "Hamstrings",
|
|
11409
|
-
["glutes" /* GLUTES */]: "Glutes",
|
|
11410
|
-
["calves" /* CALVES */]: "Calves",
|
|
11411
|
-
["abs" /* ABS */]: "Abs",
|
|
11412
|
-
["obliques" /* OBLIQUES */]: "Obliques"
|
|
11413
|
-
};
|
|
11414
|
-
var SIMPLE_DISPLAY_NAMES = {
|
|
11415
|
-
["chest" /* CHEST */]: "Chest",
|
|
11416
|
-
["back" /* BACK */]: "Back",
|
|
11417
|
-
["shoulders" /* SHOULDERS */]: "Shoulders",
|
|
11418
|
-
["biceps" /* BICEPS */]: "Biceps",
|
|
11419
|
-
["triceps" /* TRICEPS */]: "Triceps",
|
|
11420
|
-
["legs" /* LEGS */]: "Legs",
|
|
11421
|
-
["core" /* CORE */]: "Core",
|
|
11422
|
-
["forearms" /* FOREARMS */]: "Forearms"
|
|
11423
|
-
};
|
|
11424
|
-
var DEFAULT_VOLUME_LANDMARKS = {
|
|
11425
|
-
["chest" /* CHEST */]: { mev: 8, mav: 14, mrv: 20 },
|
|
11426
|
-
["lats" /* LATS */]: { mev: 8, mav: 14, mrv: 20 },
|
|
11427
|
-
["upper_back" /* UPPER_BACK */]: { mev: 6, mav: 12, mrv: 18 },
|
|
11428
|
-
["front_delts" /* FRONT_DELTS */]: { mev: 2, mav: 6, mrv: 10 },
|
|
11429
|
-
["side_delts" /* SIDE_DELTS */]: { mev: 6, mav: 14, mrv: 22 },
|
|
11430
|
-
["rear_delts" /* REAR_DELTS */]: { mev: 6, mav: 12, mrv: 18 },
|
|
11431
|
-
["biceps" /* BICEPS */]: { mev: 4, mav: 10, mrv: 18 },
|
|
11432
|
-
["triceps" /* TRICEPS */]: { mev: 4, mav: 8, mrv: 14 },
|
|
11433
|
-
["forearms" /* FOREARMS */]: { mev: 2, mav: 6, mrv: 12 },
|
|
11434
|
-
["quads" /* QUADS */]: { mev: 6, mav: 12, mrv: 18 },
|
|
11435
|
-
["hamstrings" /* HAMSTRINGS */]: { mev: 4, mav: 10, mrv: 16 },
|
|
11436
|
-
["glutes" /* GLUTES */]: { mev: 4, mav: 10, mrv: 16 },
|
|
11437
|
-
["calves" /* CALVES */]: { mev: 6, mav: 10, mrv: 16 },
|
|
11438
|
-
["abs" /* ABS */]: { mev: 0, mav: 8, mrv: 16 },
|
|
11439
|
-
["obliques" /* OBLIQUES */]: { mev: 0, mav: 6, mrv: 12 }
|
|
11440
|
-
};
|
|
11441
|
-
var VOLUME_STATUS_LABELS = {
|
|
11442
|
-
under: "under-trained",
|
|
11443
|
-
maintenance: "maintenance",
|
|
11444
|
-
productive: "productive",
|
|
11445
|
-
over: "over-reaching"
|
|
11446
|
-
};
|
|
11447
|
-
var STATUS_SEVERITY = {
|
|
11448
|
-
under: 1,
|
|
11449
|
-
maintenance: 2,
|
|
11450
|
-
productive: 3,
|
|
11451
|
-
over: 4
|
|
11452
|
-
};
|
|
11453
|
-
function getHeatmapColor(status, intensity = 0) {
|
|
11454
|
-
const heatmap = WORKOUT_TOKENS.heatmap;
|
|
11455
|
-
switch (status) {
|
|
11456
|
-
case "under":
|
|
11457
|
-
return heatmap.under;
|
|
11458
|
-
case "maintenance":
|
|
11459
|
-
return heatmap.maintenance;
|
|
11460
|
-
case "productive":
|
|
11461
|
-
return intensity >= 0.85 ? heatmap.approaching : heatmap.productive;
|
|
11462
|
-
case "over":
|
|
11463
|
-
return heatmap.over;
|
|
11464
|
-
default:
|
|
11465
|
-
return heatmap.none;
|
|
11466
|
-
}
|
|
11467
|
-
}
|
|
11468
|
-
function isMoreSevere(a, b) {
|
|
11469
|
-
return STATUS_SEVERITY[a] >= STATUS_SEVERITY[b];
|
|
11470
|
-
}
|
|
11471
|
-
var SLUG_TO_PRIMARY_MUSCLE = {
|
|
11472
|
-
chest: "chest" /* CHEST */,
|
|
11473
|
-
deltoids: "side_delts" /* SIDE_DELTS */,
|
|
11474
|
-
triceps: "triceps" /* TRICEPS */,
|
|
11475
|
-
"upper-back": "lats" /* LATS */,
|
|
11476
|
-
trapezius: "upper_back" /* UPPER_BACK */,
|
|
11477
|
-
biceps: "biceps" /* BICEPS */,
|
|
11478
|
-
forearm: "forearms" /* FOREARMS */,
|
|
11479
|
-
quadriceps: "quads" /* QUADS */,
|
|
11480
|
-
hamstring: "hamstrings" /* HAMSTRINGS */,
|
|
11481
|
-
gluteal: "glutes" /* GLUTES */,
|
|
11482
|
-
calves: "calves" /* CALVES */,
|
|
11483
|
-
abs: "abs" /* ABS */,
|
|
11484
|
-
obliques: "obliques" /* OBLIQUES */
|
|
11485
|
-
};
|
|
11486
|
-
|
|
11487
|
-
// src/components/custom/Workout/BodyMap.tsx
|
|
11488
|
-
var Body = BodyHighlighter__default.default.default ?? BodyHighlighter__default.default;
|
|
11489
|
-
var OUTLINE_FILL = "rgba(255,255,255,0.08)";
|
|
11490
|
-
var OUTLINE_BORDER = "rgba(255,255,255,0.12)";
|
|
11491
|
-
var BODY_SCALE = 0.8;
|
|
11492
|
-
var TEXT_PRIMARY7 = "#F3F4F6";
|
|
11493
|
-
var TEXT_SECONDARY6 = "#9CA3AF";
|
|
11494
|
-
function buildSlugParts(data) {
|
|
11495
|
-
const bySlug = /* @__PURE__ */ new Map();
|
|
11496
|
-
for (const d of data) {
|
|
11497
|
-
for (const slug of MUSCLE_TO_SVG_SLUGS[d.muscleGroup] ?? []) {
|
|
11498
|
-
const existing = bySlug.get(slug);
|
|
11499
|
-
if (!existing || isMoreSevere(d.volumeStatus, existing.status)) {
|
|
11500
|
-
bySlug.set(slug, { status: d.volumeStatus, intensity: d.intensity });
|
|
11501
|
-
}
|
|
11502
|
-
}
|
|
11503
|
-
}
|
|
11504
|
-
return Array.from(bySlug.entries()).map(([slug, v]) => ({
|
|
11505
|
-
slug,
|
|
11506
|
-
color: getHeatmapColor(v.status, v.intensity)
|
|
11638
|
+
var BRAND_PRIMARY11 = "#FF7900";
|
|
11639
|
+
var WORKOUT_PILL_STATUS = {
|
|
11640
|
+
completed: "completed",
|
|
11641
|
+
today: "current",
|
|
11642
|
+
upcoming: "upcoming"
|
|
11643
|
+
};
|
|
11644
|
+
function deriveNavLevel(selection) {
|
|
11645
|
+
if (selection.workoutId != null) return "workout";
|
|
11646
|
+
if (selection.weekNumber != null) return "week";
|
|
11647
|
+
return "meso";
|
|
11648
|
+
}
|
|
11649
|
+
function toProgressBarMesos(mesos) {
|
|
11650
|
+
return mesos.map(({ id, name, weekCount, status, currentWeek }) => ({
|
|
11651
|
+
id,
|
|
11652
|
+
name,
|
|
11653
|
+
weekCount,
|
|
11654
|
+
status,
|
|
11655
|
+
currentWeek
|
|
11507
11656
|
}));
|
|
11508
11657
|
}
|
|
11509
|
-
function
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
|
-
|
|
11513
|
-
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
|
|
11524
|
-
}
|
|
11525
|
-
existing.sets += d.weeklySets;
|
|
11526
|
-
existing.intensity = Math.max(existing.intensity, d.intensity);
|
|
11527
|
-
if (isMoreSevere(d.volumeStatus, existing.status)) {
|
|
11528
|
-
existing.status = d.volumeStatus;
|
|
11529
|
-
existing.muscle = d.muscleGroup;
|
|
11530
|
-
}
|
|
11658
|
+
function findMeso(mesos, id) {
|
|
11659
|
+
if (id == null) return null;
|
|
11660
|
+
return mesos.find((meso) => meso.id === id) ?? null;
|
|
11661
|
+
}
|
|
11662
|
+
function findWeek(meso, weekNumber) {
|
|
11663
|
+
if (meso == null || weekNumber == null) return null;
|
|
11664
|
+
return meso.weeks.find((week) => week.weekNumber === weekNumber) ?? null;
|
|
11665
|
+
}
|
|
11666
|
+
function findWorkout(week, workoutId) {
|
|
11667
|
+
if (week == null || workoutId == null) return null;
|
|
11668
|
+
return week.workouts.find((workout) => workout.id === workoutId) ?? null;
|
|
11669
|
+
}
|
|
11670
|
+
function buildBreadcrumbs(meso, weekNumber, workout) {
|
|
11671
|
+
const crumbs = [{ key: "meso", label: meso.name, level: "meso" }];
|
|
11672
|
+
if (weekNumber != null) {
|
|
11673
|
+
crumbs.push({ key: "week", label: `Week ${weekNumber}`, level: "week" });
|
|
11531
11674
|
}
|
|
11532
|
-
|
|
11675
|
+
if (workout != null) {
|
|
11676
|
+
crumbs.push({ key: "workout", label: workout.name, level: "workout" });
|
|
11677
|
+
}
|
|
11678
|
+
return crumbs;
|
|
11679
|
+
}
|
|
11680
|
+
function Breadcrumbs2({ crumbs, onNavigate }) {
|
|
11681
|
+
return /* @__PURE__ */ jsx(
|
|
11682
|
+
reactNative.View,
|
|
11683
|
+
{
|
|
11684
|
+
className: "flex-row items-center flex-wrap",
|
|
11685
|
+
style: { gap: 4 },
|
|
11686
|
+
testID: "program-planning-page-breadcrumbs",
|
|
11687
|
+
children: crumbs.map((crumb, index) => {
|
|
11688
|
+
const isLast = index === crumbs.length - 1;
|
|
11689
|
+
return /* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { gap: 4 }, children: [
|
|
11690
|
+
index > 0 && /* @__PURE__ */ jsx(reactNative.Text, { className: "text-text-tertiary", style: { fontSize: 12 }, children: "\u203A" }),
|
|
11691
|
+
/* @__PURE__ */ jsx(
|
|
11692
|
+
reactNative.Pressable,
|
|
11693
|
+
{
|
|
11694
|
+
onPress: () => onNavigate(crumb.level),
|
|
11695
|
+
disabled: isLast,
|
|
11696
|
+
accessibilityRole: "button",
|
|
11697
|
+
testID: `program-planning-page-crumb-${crumb.key}`,
|
|
11698
|
+
children: /* @__PURE__ */ jsx(
|
|
11699
|
+
reactNative.Text,
|
|
11700
|
+
{
|
|
11701
|
+
className: isLast ? "text-text-primary" : void 0,
|
|
11702
|
+
style: {
|
|
11703
|
+
fontSize: 12,
|
|
11704
|
+
fontFamily: "Inter, sans-serif",
|
|
11705
|
+
fontWeight: isLast ? "700" : "500",
|
|
11706
|
+
color: isLast ? void 0 : BRAND_PRIMARY11
|
|
11707
|
+
},
|
|
11708
|
+
children: crumb.label
|
|
11709
|
+
}
|
|
11710
|
+
)
|
|
11711
|
+
}
|
|
11712
|
+
)
|
|
11713
|
+
] }, crumb.key);
|
|
11714
|
+
})
|
|
11715
|
+
}
|
|
11716
|
+
);
|
|
11533
11717
|
}
|
|
11534
|
-
function
|
|
11535
|
-
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
intensity: d.intensity,
|
|
11540
|
-
sets: d.weeklySets,
|
|
11541
|
-
muscle: d.muscleGroup
|
|
11718
|
+
function toWeekRow(week, meso, onSelectWeek) {
|
|
11719
|
+
const workouts = week.workouts.map((workout) => ({
|
|
11720
|
+
name: workout.name,
|
|
11721
|
+
status: WORKOUT_PILL_STATUS[workout.status],
|
|
11722
|
+
onPress: () => onSelectWeek(week.weekNumber)
|
|
11542
11723
|
}));
|
|
11724
|
+
return {
|
|
11725
|
+
weekNumber: week.weekNumber,
|
|
11726
|
+
totalWeeks: meso.weekCount,
|
|
11727
|
+
workouts,
|
|
11728
|
+
intensityLevel: week.intensityLevel,
|
|
11729
|
+
intensityThreshold: week.intensityThreshold,
|
|
11730
|
+
isCurrent: week.isCurrent ?? week.weekNumber === meso.currentWeek,
|
|
11731
|
+
isDeload: week.isDeload
|
|
11732
|
+
};
|
|
11543
11733
|
}
|
|
11544
|
-
function
|
|
11545
|
-
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
|
|
11549
|
-
|
|
11550
|
-
|
|
11551
|
-
|
|
11552
|
-
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
|
|
11563
|
-
duration: 250,
|
|
11564
|
-
easing: reactNative.Easing.out(reactNative.Easing.ease),
|
|
11565
|
-
useNativeDriver: false
|
|
11566
|
-
});
|
|
11567
|
-
animation.start();
|
|
11568
|
-
return () => animation.stop();
|
|
11569
|
-
}, [highlightedMuscle, highlight]);
|
|
11570
|
-
const scale = highlight.interpolate({ inputRange: [0, 1], outputRange: [1, 1.02] });
|
|
11571
|
-
const glowColor = highlightedMuscle ? getHeatmapColor(
|
|
11572
|
-
data.find((d) => d.muscleGroup === highlightedMuscle)?.volumeStatus,
|
|
11573
|
-
data.find((d) => d.muscleGroup === highlightedMuscle)?.intensity ?? 0
|
|
11574
|
-
) : null;
|
|
11575
|
-
const handleBodyPress = (part) => {
|
|
11576
|
-
if (!onMusclePress || !part.slug) return;
|
|
11577
|
-
const fromData = data.find(
|
|
11578
|
-
(d) => (MUSCLE_TO_SVG_SLUGS[d.muscleGroup] ?? []).includes(part.slug)
|
|
11734
|
+
function MesoLevel({ mesos, activeMesoId, onSelectMeso, onSelectWeek }) {
|
|
11735
|
+
return /* @__PURE__ */ jsx(reactNative.View, { style: { gap: 12 }, testID: "program-planning-page-meso-level", children: mesos.map((meso) => {
|
|
11736
|
+
const expanded = meso.id === activeMesoId;
|
|
11737
|
+
return /* @__PURE__ */ jsx(
|
|
11738
|
+
MesoCard,
|
|
11739
|
+
{
|
|
11740
|
+
name: meso.name,
|
|
11741
|
+
goal: meso.goal,
|
|
11742
|
+
split: meso.split,
|
|
11743
|
+
weekRange: meso.weekRange,
|
|
11744
|
+
currentWeek: meso.currentWeek,
|
|
11745
|
+
totalWeeks: meso.weekCount,
|
|
11746
|
+
weeks: expanded ? meso.weeks.map((week) => toWeekRow(week, meso, onSelectWeek)) : [],
|
|
11747
|
+
volumeHeatmap: meso.volumeHeatmap,
|
|
11748
|
+
expanded,
|
|
11749
|
+
onToggle: () => onSelectMeso(meso.id),
|
|
11750
|
+
highlighted: expanded
|
|
11751
|
+
},
|
|
11752
|
+
meso.id
|
|
11579
11753
|
);
|
|
11580
|
-
|
|
11581
|
-
|
|
11754
|
+
}) });
|
|
11755
|
+
}
|
|
11756
|
+
function WeekLevel({ week, onSelectWorkout }) {
|
|
11757
|
+
return /* @__PURE__ */ jsx(reactNative.View, { style: { gap: 10 }, testID: "program-planning-page-week-level", children: week.workouts.map((workout) => /* @__PURE__ */ jsx(
|
|
11758
|
+
WorkoutCard,
|
|
11759
|
+
{
|
|
11760
|
+
name: workout.name,
|
|
11761
|
+
date: workout.date,
|
|
11762
|
+
duration: workout.duration,
|
|
11763
|
+
status: workout.status,
|
|
11764
|
+
muscleGroups: workout.muscleGroups,
|
|
11765
|
+
totalSets: workout.totalSets,
|
|
11766
|
+
totalVolume: workout.totalVolume,
|
|
11767
|
+
unit: workout.unit,
|
|
11768
|
+
exercises: workout.exercises,
|
|
11769
|
+
expanded: false,
|
|
11770
|
+
onToggle: () => onSelectWorkout(workout.id)
|
|
11771
|
+
},
|
|
11772
|
+
workout.id
|
|
11773
|
+
)) });
|
|
11774
|
+
}
|
|
11775
|
+
function WorkoutLevel({ workout, expandedExercise, onToggleExercise }) {
|
|
11776
|
+
const exercises = workout.exercises.map((exercise, index) => ({
|
|
11777
|
+
...exercise,
|
|
11778
|
+
state: exercise.state === "upcoming" ? exercise.state : index === expandedExercise ? "expanded" : "collapsed",
|
|
11779
|
+
onToggle: () => onToggleExercise(index)
|
|
11780
|
+
}));
|
|
11781
|
+
return /* @__PURE__ */ jsx(reactNative.View, { testID: "program-planning-page-workout-level", children: /* @__PURE__ */ jsx(
|
|
11782
|
+
WorkoutCard,
|
|
11783
|
+
{
|
|
11784
|
+
name: workout.name,
|
|
11785
|
+
date: workout.date,
|
|
11786
|
+
duration: workout.duration,
|
|
11787
|
+
status: workout.status,
|
|
11788
|
+
muscleGroups: workout.muscleGroups,
|
|
11789
|
+
totalSets: workout.totalSets,
|
|
11790
|
+
totalVolume: workout.totalVolume,
|
|
11791
|
+
unit: workout.unit,
|
|
11792
|
+
exercises,
|
|
11793
|
+
expanded: true,
|
|
11794
|
+
onToggle: () => void 0
|
|
11795
|
+
}
|
|
11796
|
+
) });
|
|
11797
|
+
}
|
|
11798
|
+
function ProgramPlanningPage({
|
|
11799
|
+
title = "Program Plan",
|
|
11800
|
+
mesos,
|
|
11801
|
+
className,
|
|
11802
|
+
...props
|
|
11803
|
+
}) {
|
|
11804
|
+
const [activeMesoId, setActiveMesoId] = React24.useState(mesos[0]?.id ?? null);
|
|
11805
|
+
const [selectedWeek, setSelectedWeek] = React24.useState(null);
|
|
11806
|
+
const [selectedWorkoutId, setSelectedWorkoutId] = React24.useState(null);
|
|
11807
|
+
const [expandedExercise, setExpandedExercise] = React24.useState(null);
|
|
11808
|
+
const progressMesos = React24.useMemo(() => toProgressBarMesos(mesos), [mesos]);
|
|
11809
|
+
const activeMeso = findMeso(mesos, activeMesoId);
|
|
11810
|
+
const level = deriveNavLevel({ weekNumber: selectedWeek, workoutId: selectedWorkoutId });
|
|
11811
|
+
const activeWeek = findWeek(activeMeso, selectedWeek);
|
|
11812
|
+
const activeWorkout = findWorkout(activeWeek, selectedWorkoutId);
|
|
11813
|
+
const selectMeso = (id) => {
|
|
11814
|
+
setActiveMesoId(id);
|
|
11815
|
+
setSelectedWeek(null);
|
|
11816
|
+
setSelectedWorkoutId(null);
|
|
11582
11817
|
};
|
|
11583
|
-
|
|
11584
|
-
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
|
|
11588
|
-
|
|
11818
|
+
const selectWeek = (weekNumber) => {
|
|
11819
|
+
setSelectedWeek(weekNumber);
|
|
11820
|
+
setSelectedWorkoutId(null);
|
|
11821
|
+
setExpandedExercise(null);
|
|
11822
|
+
};
|
|
11823
|
+
const selectWorkout = (id) => {
|
|
11824
|
+
setSelectedWorkoutId(id);
|
|
11825
|
+
setExpandedExercise(null);
|
|
11826
|
+
};
|
|
11827
|
+
const toggleExercise = (index) => setExpandedExercise((current) => current === index ? null : index);
|
|
11828
|
+
const navigateTo = (target) => {
|
|
11829
|
+
if (target === "meso") selectMeso(activeMesoId ?? mesos[0]?.id);
|
|
11830
|
+
else if (target === "week" && selectedWeek != null) selectWeek(selectedWeek);
|
|
11831
|
+
};
|
|
11832
|
+
return /* @__PURE__ */ jsx(
|
|
11833
|
+
reactNative.View,
|
|
11834
|
+
{
|
|
11835
|
+
className: cn(className, "bg-background-base"),
|
|
11836
|
+
style: { width: 390 },
|
|
11837
|
+
accessibilityRole: "main",
|
|
11838
|
+
"aria-label": title,
|
|
11839
|
+
testID: "program-planning-page",
|
|
11840
|
+
...props,
|
|
11841
|
+
children: /* @__PURE__ */ jsxs(reactNative.View, { style: { padding: 16, gap: 14 }, testID: "program-planning-page-content", children: [
|
|
11842
|
+
/* @__PURE__ */ jsx(
|
|
11843
|
+
reactNative.Text,
|
|
11589
11844
|
{
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
|
|
11598
|
-
|
|
11599
|
-
|
|
11600
|
-
|
|
11601
|
-
|
|
11845
|
+
accessibilityRole: "header",
|
|
11846
|
+
className: "text-text-primary",
|
|
11847
|
+
style: {
|
|
11848
|
+
fontSize: 20,
|
|
11849
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
11850
|
+
fontWeight: "700"
|
|
11851
|
+
},
|
|
11852
|
+
testID: "program-planning-page-title",
|
|
11853
|
+
children: title
|
|
11854
|
+
}
|
|
11855
|
+
),
|
|
11856
|
+
/* @__PURE__ */ jsx(reactNative.View, { style: { marginHorizontal: -16 }, children: /* @__PURE__ */ jsx(
|
|
11857
|
+
MesoProgressBar,
|
|
11602
11858
|
{
|
|
11603
|
-
|
|
11604
|
-
|
|
11605
|
-
|
|
11606
|
-
gender: "male",
|
|
11607
|
-
defaultFill: OUTLINE_FILL,
|
|
11608
|
-
border: OUTLINE_BORDER,
|
|
11609
|
-
onBodyPartPress: handleBodyPress
|
|
11859
|
+
mesos: progressMesos,
|
|
11860
|
+
activeMesoId,
|
|
11861
|
+
onMesoPress: selectMeso
|
|
11610
11862
|
}
|
|
11611
|
-
)
|
|
11612
|
-
|
|
11613
|
-
|
|
11614
|
-
legend.length === 0 ? /* @__PURE__ */ jsx(
|
|
11615
|
-
reactNative.Text,
|
|
11616
|
-
{
|
|
11617
|
-
style: {
|
|
11618
|
-
marginTop: 8,
|
|
11619
|
-
fontSize: 12,
|
|
11620
|
-
color: TEXT_SECONDARY6,
|
|
11621
|
-
textAlign: "center",
|
|
11622
|
-
fontFamily: "Inter, sans-serif"
|
|
11623
|
-
},
|
|
11624
|
-
testID: "body-map-empty",
|
|
11625
|
-
children: "No training data"
|
|
11626
|
-
}
|
|
11627
|
-
) : /* @__PURE__ */ jsx(
|
|
11628
|
-
reactNative.View,
|
|
11629
|
-
{
|
|
11630
|
-
className: "flex-row flex-wrap",
|
|
11631
|
-
style: { marginTop: 10, gap: 6, justifyContent: "center" },
|
|
11632
|
-
testID: "body-map-legend",
|
|
11633
|
-
children: legend.map((entry) => /* @__PURE__ */ jsx(
|
|
11634
|
-
MuscleButton,
|
|
11863
|
+
) }),
|
|
11864
|
+
activeMeso != null && /* @__PURE__ */ jsx(
|
|
11865
|
+
Breadcrumbs2,
|
|
11635
11866
|
{
|
|
11636
|
-
|
|
11637
|
-
|
|
11638
|
-
|
|
11639
|
-
|
|
11640
|
-
|
|
11641
|
-
|
|
11642
|
-
|
|
11643
|
-
|
|
11644
|
-
|
|
11867
|
+
crumbs: buildBreadcrumbs(activeMeso, selectedWeek, activeWorkout),
|
|
11868
|
+
onNavigate: navigateTo
|
|
11869
|
+
}
|
|
11870
|
+
),
|
|
11871
|
+
/* @__PURE__ */ jsxs(
|
|
11872
|
+
reactNative.View,
|
|
11873
|
+
{
|
|
11874
|
+
className: "bg-surface-elevated border-border",
|
|
11875
|
+
style: {
|
|
11876
|
+
borderWidth: 1,
|
|
11877
|
+
borderRadius: 12,
|
|
11878
|
+
padding: 12
|
|
11879
|
+
},
|
|
11880
|
+
testID: "program-planning-page-body",
|
|
11881
|
+
children: [
|
|
11882
|
+
level === "meso" && /* @__PURE__ */ jsx(
|
|
11883
|
+
MesoLevel,
|
|
11884
|
+
{
|
|
11885
|
+
mesos,
|
|
11886
|
+
activeMesoId,
|
|
11887
|
+
onSelectMeso: selectMeso,
|
|
11888
|
+
onSelectWeek: selectWeek
|
|
11889
|
+
}
|
|
11890
|
+
),
|
|
11891
|
+
level === "week" && activeWeek != null && /* @__PURE__ */ jsx(WeekLevel, { week: activeWeek, onSelectWorkout: selectWorkout }),
|
|
11892
|
+
level === "workout" && activeWorkout != null && /* @__PURE__ */ jsx(
|
|
11893
|
+
WorkoutLevel,
|
|
11894
|
+
{
|
|
11895
|
+
workout: activeWorkout,
|
|
11896
|
+
expandedExercise,
|
|
11897
|
+
onToggleExercise: toggleExercise
|
|
11898
|
+
}
|
|
11899
|
+
)
|
|
11900
|
+
]
|
|
11901
|
+
}
|
|
11902
|
+
)
|
|
11903
|
+
] })
|
|
11904
|
+
}
|
|
11905
|
+
);
|
|
11645
11906
|
}
|
|
11646
|
-
|
|
11907
|
+
var BRAND_PRIMARY12 = "#FF7900";
|
|
11908
|
+
var CHART_WIDTH = 326;
|
|
11909
|
+
var CHART_HEIGHT = 150;
|
|
11910
|
+
var EXERCISE_DETAIL_TABS = [
|
|
11911
|
+
{ key: "progress", label: "Progress" },
|
|
11912
|
+
{ key: "history", label: "History" },
|
|
11913
|
+
{ key: "advanced", label: "Advanced" }
|
|
11914
|
+
];
|
|
11915
|
+
function deriveExerciseStats(entries) {
|
|
11916
|
+
let bestE1rm = null;
|
|
11917
|
+
let prCount = 0;
|
|
11918
|
+
for (const entry of entries) {
|
|
11919
|
+
if (entry.e1rm != null && (bestE1rm == null || entry.e1rm.value > bestE1rm)) {
|
|
11920
|
+
bestE1rm = entry.e1rm.value;
|
|
11921
|
+
}
|
|
11922
|
+
if (entry.isPR) prCount += 1;
|
|
11923
|
+
}
|
|
11924
|
+
return { sessions: entries.length, bestE1rm, prCount };
|
|
11925
|
+
}
|
|
11926
|
+
function toExerciseCardProps(entry, expanded, onToggle) {
|
|
11927
|
+
return {
|
|
11928
|
+
name: entry.title,
|
|
11929
|
+
state: expanded ? "expanded" : "collapsed",
|
|
11930
|
+
onToggle,
|
|
11931
|
+
summary: entry.summary,
|
|
11932
|
+
e1rm: entry.e1rm,
|
|
11933
|
+
isPR: entry.isPR,
|
|
11934
|
+
tempo: entry.tempo,
|
|
11935
|
+
sets: expanded ? entry.sets : void 0
|
|
11936
|
+
};
|
|
11937
|
+
}
|
|
11938
|
+
function summarizeVbt(sets) {
|
|
11939
|
+
const allReps = sets.flatMap((set) => set.velocities);
|
|
11940
|
+
const meanVelocity = calculateMeanVelocity(allReps);
|
|
11941
|
+
let velocityLoss = 0;
|
|
11942
|
+
for (const set of sets) {
|
|
11943
|
+
velocityLoss = Math.max(velocityLoss, calculateVelocityLoss(set.velocities));
|
|
11944
|
+
}
|
|
11945
|
+
return { meanVelocity, velocityLoss };
|
|
11946
|
+
}
|
|
11947
|
+
function TabBar({ active, onSelect }) {
|
|
11647
11948
|
return /* @__PURE__ */ jsx(
|
|
11648
11949
|
reactNative.View,
|
|
11649
11950
|
{
|
|
11650
|
-
className: "flex-row
|
|
11651
|
-
style: {
|
|
11652
|
-
|
|
11653
|
-
|
|
11654
|
-
|
|
11951
|
+
className: "flex-row",
|
|
11952
|
+
style: {
|
|
11953
|
+
borderBottomWidth: 1,
|
|
11954
|
+
borderBottomColor: resolveColor("border-default")
|
|
11955
|
+
},
|
|
11956
|
+
accessibilityRole: "tablist",
|
|
11957
|
+
testID: "exercise-detail-page-tabs",
|
|
11958
|
+
children: EXERCISE_DETAIL_TABS.map(({ key, label }) => {
|
|
11959
|
+
const isActive = key === active;
|
|
11655
11960
|
return /* @__PURE__ */ jsx(
|
|
11656
11961
|
reactNative.Pressable,
|
|
11657
11962
|
{
|
|
11658
|
-
onPress: () =>
|
|
11659
|
-
accessibilityRole: "
|
|
11660
|
-
|
|
11661
|
-
"aria-pressed": active,
|
|
11662
|
-
disabled: !onViewChange,
|
|
11963
|
+
onPress: () => onSelect(key),
|
|
11964
|
+
accessibilityRole: "tab",
|
|
11965
|
+
accessibilityState: { selected: isActive },
|
|
11663
11966
|
style: {
|
|
11664
|
-
|
|
11665
|
-
|
|
11666
|
-
|
|
11667
|
-
|
|
11668
|
-
|
|
11669
|
-
borderColor: active ? "#FF7900" : WORKOUT_TOKENS.border.strong
|
|
11967
|
+
flex: 1,
|
|
11968
|
+
alignItems: "center",
|
|
11969
|
+
paddingVertical: 10,
|
|
11970
|
+
borderBottomWidth: 2,
|
|
11971
|
+
borderBottomColor: isActive ? BRAND_PRIMARY12 : "transparent"
|
|
11670
11972
|
},
|
|
11671
|
-
testID: `
|
|
11973
|
+
testID: `exercise-detail-page-tab-${key}`,
|
|
11672
11974
|
children: /* @__PURE__ */ jsx(
|
|
11673
11975
|
reactNative.Text,
|
|
11674
11976
|
{
|
|
11977
|
+
className: isActive ? "text-text-primary" : "text-text-tertiary",
|
|
11675
11978
|
style: {
|
|
11676
|
-
fontSize:
|
|
11979
|
+
fontSize: 13,
|
|
11677
11980
|
fontFamily: "Inter, sans-serif",
|
|
11678
|
-
fontWeight:
|
|
11679
|
-
color: active ? "#FF7900" : TEXT_SECONDARY6,
|
|
11680
|
-
textTransform: "capitalize"
|
|
11981
|
+
fontWeight: isActive ? "700" : "500"
|
|
11681
11982
|
},
|
|
11682
|
-
children:
|
|
11983
|
+
children: label
|
|
11683
11984
|
}
|
|
11684
11985
|
)
|
|
11685
11986
|
},
|
|
11686
|
-
|
|
11987
|
+
key
|
|
11687
11988
|
);
|
|
11688
11989
|
})
|
|
11689
11990
|
}
|
|
11690
11991
|
);
|
|
11691
11992
|
}
|
|
11692
|
-
|
|
11693
|
-
|
|
11694
|
-
|
|
11993
|
+
var STAT_CARDS = [
|
|
11994
|
+
{ key: "sessions", label: "Sessions" },
|
|
11995
|
+
{ key: "bestE1rm", label: "Best e1RM" },
|
|
11996
|
+
{ key: "prCount", label: "PRs" }
|
|
11997
|
+
];
|
|
11998
|
+
function StatStrip({ stats, unit }) {
|
|
11999
|
+
return /* @__PURE__ */ jsx(reactNative.View, { className: "flex-row", style: { gap: 8 }, testID: "exercise-detail-page-stats", children: STAT_CARDS.map(({ key, label }) => {
|
|
12000
|
+
const raw = stats[key];
|
|
12001
|
+
const value = key === "bestE1rm" ? raw == null ? "\u2014" : `${raw} ${unit}` : `${raw}`;
|
|
12002
|
+
return /* @__PURE__ */ jsxs(
|
|
12003
|
+
reactNative.View,
|
|
12004
|
+
{
|
|
12005
|
+
className: "bg-surface-elevated border-border",
|
|
12006
|
+
style: {
|
|
12007
|
+
flex: 1,
|
|
12008
|
+
padding: 12,
|
|
12009
|
+
borderRadius: 10,
|
|
12010
|
+
borderWidth: 1
|
|
12011
|
+
},
|
|
12012
|
+
testID: `exercise-detail-page-stat-${key}`,
|
|
12013
|
+
children: [
|
|
12014
|
+
/* @__PURE__ */ jsx(
|
|
12015
|
+
reactNative.Text,
|
|
12016
|
+
{
|
|
12017
|
+
className: "text-text-primary",
|
|
12018
|
+
style: {
|
|
12019
|
+
fontSize: 18,
|
|
12020
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
12021
|
+
fontWeight: "700"
|
|
12022
|
+
},
|
|
12023
|
+
children: value
|
|
12024
|
+
}
|
|
12025
|
+
),
|
|
12026
|
+
/* @__PURE__ */ jsx(
|
|
12027
|
+
reactNative.Text,
|
|
12028
|
+
{
|
|
12029
|
+
className: "text-text-tertiary",
|
|
12030
|
+
style: {
|
|
12031
|
+
marginTop: 2,
|
|
12032
|
+
fontSize: 10,
|
|
12033
|
+
fontFamily: "Inter, sans-serif",
|
|
12034
|
+
fontWeight: "600",
|
|
12035
|
+
letterSpacing: 0.4,
|
|
12036
|
+
textTransform: "uppercase"
|
|
12037
|
+
},
|
|
12038
|
+
children: label
|
|
12039
|
+
}
|
|
12040
|
+
)
|
|
12041
|
+
]
|
|
12042
|
+
},
|
|
12043
|
+
key
|
|
12044
|
+
);
|
|
12045
|
+
}) });
|
|
12046
|
+
}
|
|
12047
|
+
function SectionCard({
|
|
12048
|
+
title,
|
|
12049
|
+
children,
|
|
12050
|
+
testID
|
|
12051
|
+
}) {
|
|
11695
12052
|
return /* @__PURE__ */ jsxs(
|
|
11696
|
-
reactNative.
|
|
12053
|
+
reactNative.View,
|
|
11697
12054
|
{
|
|
11698
|
-
|
|
11699
|
-
accessibilityRole: "button",
|
|
11700
|
-
accessibilityLabel: label,
|
|
11701
|
-
"aria-pressed": highlighted,
|
|
12055
|
+
className: "bg-surface-elevated border-border",
|
|
11702
12056
|
style: {
|
|
11703
|
-
flexDirection: "row",
|
|
11704
|
-
alignItems: "center",
|
|
11705
|
-
gap: 5,
|
|
11706
|
-
paddingHorizontal: 8,
|
|
11707
|
-
paddingVertical: 3,
|
|
11708
|
-
borderRadius: 9999,
|
|
11709
12057
|
borderWidth: 1,
|
|
11710
|
-
|
|
11711
|
-
|
|
12058
|
+
borderRadius: 12,
|
|
12059
|
+
padding: 12,
|
|
12060
|
+
gap: 10
|
|
11712
12061
|
},
|
|
11713
|
-
testID
|
|
12062
|
+
testID,
|
|
11714
12063
|
children: [
|
|
11715
12064
|
/* @__PURE__ */ jsx(
|
|
11716
|
-
reactNative.
|
|
12065
|
+
reactNative.Text,
|
|
12066
|
+
{
|
|
12067
|
+
className: "text-text-tertiary",
|
|
12068
|
+
style: {
|
|
12069
|
+
fontSize: 11,
|
|
12070
|
+
fontFamily: "Inter, sans-serif",
|
|
12071
|
+
fontWeight: "600",
|
|
12072
|
+
letterSpacing: 0.6,
|
|
12073
|
+
textTransform: "uppercase"
|
|
12074
|
+
},
|
|
12075
|
+
children: title
|
|
12076
|
+
}
|
|
12077
|
+
),
|
|
12078
|
+
children
|
|
12079
|
+
]
|
|
12080
|
+
}
|
|
12081
|
+
);
|
|
12082
|
+
}
|
|
12083
|
+
function EntryList({ entries, expandedId, onToggle, emptyLabel, testID }) {
|
|
12084
|
+
if (entries.length === 0) {
|
|
12085
|
+
return /* @__PURE__ */ jsx(
|
|
12086
|
+
reactNative.Text,
|
|
12087
|
+
{
|
|
12088
|
+
className: "text-text-tertiary",
|
|
12089
|
+
style: { fontSize: 12, fontFamily: "Inter, sans-serif" },
|
|
12090
|
+
testID: `${testID}-empty`,
|
|
12091
|
+
children: emptyLabel
|
|
12092
|
+
}
|
|
12093
|
+
);
|
|
12094
|
+
}
|
|
12095
|
+
return /* @__PURE__ */ jsx(reactNative.View, { style: { gap: 8 }, testID, children: entries.map((entry) => /* @__PURE__ */ jsx(
|
|
12096
|
+
ExerciseCard,
|
|
12097
|
+
{
|
|
12098
|
+
...toExerciseCardProps(entry, entry.id === expandedId, () => onToggle(entry.id))
|
|
12099
|
+
},
|
|
12100
|
+
entry.id
|
|
12101
|
+
)) });
|
|
12102
|
+
}
|
|
12103
|
+
function VbtBreakdown({ sets }) {
|
|
12104
|
+
return /* @__PURE__ */ jsx(reactNative.View, { style: { gap: 10 }, testID: "exercise-detail-page-vbt-breakdown", children: sets.map((set) => {
|
|
12105
|
+
const mean = calculateMeanVelocity(set.velocities);
|
|
12106
|
+
const loss = calculateVelocityLoss(set.velocities);
|
|
12107
|
+
return /* @__PURE__ */ jsxs(
|
|
12108
|
+
reactNative.View,
|
|
12109
|
+
{
|
|
12110
|
+
className: "flex-row items-center",
|
|
12111
|
+
style: { gap: 10 },
|
|
12112
|
+
testID: "exercise-detail-page-vbt-set",
|
|
12113
|
+
children: [
|
|
12114
|
+
/* @__PURE__ */ jsx(
|
|
12115
|
+
reactNative.Text,
|
|
12116
|
+
{
|
|
12117
|
+
className: "text-text-secondary",
|
|
12118
|
+
style: {
|
|
12119
|
+
width: 44,
|
|
12120
|
+
fontSize: 11,
|
|
12121
|
+
fontFamily: "Inter, sans-serif",
|
|
12122
|
+
fontWeight: "600"
|
|
12123
|
+
},
|
|
12124
|
+
children: set.label
|
|
12125
|
+
}
|
|
12126
|
+
),
|
|
12127
|
+
/* @__PURE__ */ jsx(reactNative.View, { className: "flex-1", style: { height: 8, justifyContent: "center" }, children: /* @__PURE__ */ jsx(VelocityStrip, { velocities: set.velocities, variant: "mini" }) }),
|
|
12128
|
+
/* @__PURE__ */ jsx(
|
|
12129
|
+
reactNative.Text,
|
|
12130
|
+
{
|
|
12131
|
+
className: "text-text-tertiary",
|
|
12132
|
+
style: {
|
|
12133
|
+
fontSize: 11,
|
|
12134
|
+
fontFamily: "Inter, sans-serif",
|
|
12135
|
+
fontVariant: ["tabular-nums"]
|
|
12136
|
+
},
|
|
12137
|
+
children: `${mean.toFixed(2)} \xB7 -${loss}%`
|
|
12138
|
+
}
|
|
12139
|
+
)
|
|
12140
|
+
]
|
|
12141
|
+
},
|
|
12142
|
+
set.label
|
|
12143
|
+
);
|
|
12144
|
+
}) });
|
|
12145
|
+
}
|
|
12146
|
+
function VbtSummaryRow({ summary }) {
|
|
12147
|
+
const cells = [
|
|
12148
|
+
{ label: "Mean Velocity", value: `${summary.meanVelocity.toFixed(2)} m/s` },
|
|
12149
|
+
{ label: "Peak Vel. Loss", value: `-${summary.velocityLoss}%` }
|
|
12150
|
+
];
|
|
12151
|
+
return /* @__PURE__ */ jsx(reactNative.View, { className: "flex-row", style: { gap: 8 }, testID: "exercise-detail-page-vbt-summary", children: cells.map((cell) => /* @__PURE__ */ jsxs(
|
|
12152
|
+
reactNative.View,
|
|
12153
|
+
{
|
|
12154
|
+
className: "bg-surface-elevated border-border",
|
|
12155
|
+
style: {
|
|
12156
|
+
flex: 1,
|
|
12157
|
+
padding: 12,
|
|
12158
|
+
borderRadius: 10,
|
|
12159
|
+
borderWidth: 1
|
|
12160
|
+
},
|
|
12161
|
+
children: [
|
|
12162
|
+
/* @__PURE__ */ jsx(
|
|
12163
|
+
reactNative.Text,
|
|
12164
|
+
{
|
|
12165
|
+
className: "text-text-primary",
|
|
12166
|
+
style: {
|
|
12167
|
+
fontSize: 16,
|
|
12168
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
12169
|
+
fontWeight: "700"
|
|
12170
|
+
},
|
|
12171
|
+
children: cell.value
|
|
12172
|
+
}
|
|
12173
|
+
),
|
|
12174
|
+
/* @__PURE__ */ jsx(
|
|
12175
|
+
reactNative.Text,
|
|
12176
|
+
{
|
|
12177
|
+
className: "text-text-tertiary",
|
|
12178
|
+
style: {
|
|
12179
|
+
marginTop: 2,
|
|
12180
|
+
fontSize: 10,
|
|
12181
|
+
fontFamily: "Inter, sans-serif",
|
|
12182
|
+
fontWeight: "600",
|
|
12183
|
+
letterSpacing: 0.4,
|
|
12184
|
+
textTransform: "uppercase"
|
|
12185
|
+
},
|
|
12186
|
+
children: cell.label
|
|
12187
|
+
}
|
|
12188
|
+
)
|
|
12189
|
+
]
|
|
12190
|
+
},
|
|
12191
|
+
cell.label
|
|
12192
|
+
)) });
|
|
12193
|
+
}
|
|
12194
|
+
function ExerciseDetailPage({
|
|
12195
|
+
exercise,
|
|
12196
|
+
meso,
|
|
12197
|
+
trend,
|
|
12198
|
+
progression,
|
|
12199
|
+
history,
|
|
12200
|
+
vbt,
|
|
12201
|
+
className,
|
|
12202
|
+
...props
|
|
12203
|
+
}) {
|
|
12204
|
+
const [tab, setTab] = React24.useState("progress");
|
|
12205
|
+
const [expandedProgressId, setExpandedProgressId] = React24.useState(null);
|
|
12206
|
+
const [expandedHistoryId, setExpandedHistoryId] = React24.useState(null);
|
|
12207
|
+
const stats = React24.useMemo(() => deriveExerciseStats(history), [history]);
|
|
12208
|
+
const vbtSummary = React24.useMemo(() => summarizeVbt(vbt.sets), [vbt.sets]);
|
|
12209
|
+
const toggle = (setId) => (id) => setId((current) => current === id ? null : id);
|
|
12210
|
+
return /* @__PURE__ */ jsx(
|
|
12211
|
+
reactNative.View,
|
|
12212
|
+
{
|
|
12213
|
+
className: cn("bg-background-base", className),
|
|
12214
|
+
style: { width: 390 },
|
|
12215
|
+
accessibilityRole: "main",
|
|
12216
|
+
"aria-label": exercise.name,
|
|
12217
|
+
testID: "exercise-detail-page",
|
|
12218
|
+
...props,
|
|
12219
|
+
children: /* @__PURE__ */ jsxs(reactNative.View, { style: { padding: 16, gap: 14 }, testID: "exercise-detail-page-content", children: [
|
|
12220
|
+
/* @__PURE__ */ jsxs(
|
|
12221
|
+
reactNative.View,
|
|
12222
|
+
{
|
|
12223
|
+
className: "flex-row items-start justify-between",
|
|
12224
|
+
style: { gap: 8 },
|
|
12225
|
+
testID: "exercise-detail-page-header",
|
|
12226
|
+
children: [
|
|
12227
|
+
/* @__PURE__ */ jsxs(reactNative.View, { style: { flexShrink: 1 }, children: [
|
|
12228
|
+
/* @__PURE__ */ jsx(
|
|
12229
|
+
reactNative.Text,
|
|
12230
|
+
{
|
|
12231
|
+
accessibilityRole: "header",
|
|
12232
|
+
className: "text-text-primary",
|
|
12233
|
+
style: {
|
|
12234
|
+
fontSize: 20,
|
|
12235
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
12236
|
+
fontWeight: "700"
|
|
12237
|
+
},
|
|
12238
|
+
testID: "exercise-detail-page-title",
|
|
12239
|
+
children: exercise.name
|
|
12240
|
+
}
|
|
12241
|
+
),
|
|
12242
|
+
/* @__PURE__ */ jsx(
|
|
12243
|
+
reactNative.Text,
|
|
12244
|
+
{
|
|
12245
|
+
className: "text-text-secondary",
|
|
12246
|
+
style: {
|
|
12247
|
+
marginTop: 2,
|
|
12248
|
+
fontSize: 12,
|
|
12249
|
+
fontFamily: "Inter, sans-serif"
|
|
12250
|
+
},
|
|
12251
|
+
testID: "exercise-detail-page-subtitle",
|
|
12252
|
+
children: exercise.subtitle
|
|
12253
|
+
}
|
|
12254
|
+
)
|
|
12255
|
+
] }),
|
|
12256
|
+
exercise.currentE1rm != null && /* @__PURE__ */ jsxs(
|
|
12257
|
+
reactNative.View,
|
|
12258
|
+
{
|
|
12259
|
+
style: {
|
|
12260
|
+
paddingVertical: 4,
|
|
12261
|
+
paddingHorizontal: 10,
|
|
12262
|
+
borderRadius: 6,
|
|
12263
|
+
backgroundColor: "rgba(255,121,0,0.10)",
|
|
12264
|
+
borderWidth: 1,
|
|
12265
|
+
borderColor: "rgba(255,121,0,0.25)"
|
|
12266
|
+
},
|
|
12267
|
+
testID: "exercise-detail-page-e1rm",
|
|
12268
|
+
children: [
|
|
12269
|
+
/* @__PURE__ */ jsx(
|
|
12270
|
+
reactNative.Text,
|
|
12271
|
+
{
|
|
12272
|
+
className: "text-text-tertiary",
|
|
12273
|
+
style: {
|
|
12274
|
+
fontSize: 9,
|
|
12275
|
+
fontFamily: "Inter, sans-serif",
|
|
12276
|
+
fontWeight: "600",
|
|
12277
|
+
letterSpacing: 0.4,
|
|
12278
|
+
textTransform: "uppercase"
|
|
12279
|
+
},
|
|
12280
|
+
children: "e1RM"
|
|
12281
|
+
}
|
|
12282
|
+
),
|
|
12283
|
+
/* @__PURE__ */ jsx(
|
|
12284
|
+
reactNative.Text,
|
|
12285
|
+
{
|
|
12286
|
+
style: {
|
|
12287
|
+
fontSize: 15,
|
|
12288
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
12289
|
+
fontWeight: "700",
|
|
12290
|
+
color: BRAND_PRIMARY12
|
|
12291
|
+
},
|
|
12292
|
+
children: `${exercise.currentE1rm} ${exercise.unit}`
|
|
12293
|
+
}
|
|
12294
|
+
)
|
|
12295
|
+
]
|
|
12296
|
+
}
|
|
12297
|
+
)
|
|
12298
|
+
]
|
|
12299
|
+
}
|
|
12300
|
+
),
|
|
12301
|
+
/* @__PURE__ */ jsx(TabBar, { active: tab, onSelect: setTab }),
|
|
12302
|
+
tab === "progress" && /* @__PURE__ */ jsxs(reactNative.View, { style: { gap: 14 }, testID: "exercise-detail-page-panel-progress", children: [
|
|
12303
|
+
/* @__PURE__ */ jsx(MesoStatusCard, { ...meso }),
|
|
12304
|
+
/* @__PURE__ */ jsx(StatStrip, { stats, unit: exercise.unit }),
|
|
12305
|
+
/* @__PURE__ */ jsx(SectionCard, { title: "Strength Trend", testID: "exercise-detail-page-trend", children: /* @__PURE__ */ jsx(
|
|
12306
|
+
StrengthTrendChart,
|
|
12307
|
+
{
|
|
12308
|
+
data: trend.data,
|
|
12309
|
+
projection: trend.projection,
|
|
12310
|
+
mesoBoundaries: trend.mesoBoundaries,
|
|
12311
|
+
width: CHART_WIDTH,
|
|
12312
|
+
height: CHART_HEIGHT,
|
|
12313
|
+
unit: exercise.unit,
|
|
12314
|
+
animateOnMount: false
|
|
12315
|
+
}
|
|
12316
|
+
) }),
|
|
12317
|
+
/* @__PURE__ */ jsx(SectionCard, { title: "Week-by-Week", testID: "exercise-detail-page-progression", children: /* @__PURE__ */ jsx(
|
|
12318
|
+
EntryList,
|
|
12319
|
+
{
|
|
12320
|
+
entries: progression,
|
|
12321
|
+
expandedId: expandedProgressId,
|
|
12322
|
+
onToggle: toggle(setExpandedProgressId),
|
|
12323
|
+
emptyLabel: "No progression logged yet",
|
|
12324
|
+
testID: "exercise-detail-page-progression-list"
|
|
12325
|
+
}
|
|
12326
|
+
) })
|
|
12327
|
+
] }),
|
|
12328
|
+
tab === "history" && /* @__PURE__ */ jsx(reactNative.View, { style: { gap: 14 }, testID: "exercise-detail-page-panel-history", children: /* @__PURE__ */ jsx(SectionCard, { title: "All Sessions", testID: "exercise-detail-page-history", children: /* @__PURE__ */ jsx(
|
|
12329
|
+
EntryList,
|
|
12330
|
+
{
|
|
12331
|
+
entries: history,
|
|
12332
|
+
expandedId: expandedHistoryId,
|
|
12333
|
+
onToggle: toggle(setExpandedHistoryId),
|
|
12334
|
+
emptyLabel: "No sessions logged yet",
|
|
12335
|
+
testID: "exercise-detail-page-history-list"
|
|
12336
|
+
}
|
|
12337
|
+
) }) }),
|
|
12338
|
+
tab === "advanced" && /* @__PURE__ */ jsxs(reactNative.View, { style: { gap: 14 }, testID: "exercise-detail-page-panel-advanced", children: [
|
|
12339
|
+
/* @__PURE__ */ jsx(SectionCard, { title: "Capacity Band", testID: "exercise-detail-page-capacity", children: /* @__PURE__ */ jsx(
|
|
12340
|
+
CapacityBandChart,
|
|
12341
|
+
{
|
|
12342
|
+
band: vbt.band,
|
|
12343
|
+
workouts: vbt.workouts,
|
|
12344
|
+
projection: vbt.projection,
|
|
12345
|
+
width: CHART_WIDTH,
|
|
12346
|
+
height: CHART_HEIGHT
|
|
12347
|
+
}
|
|
12348
|
+
) }),
|
|
12349
|
+
/* @__PURE__ */ jsx(VbtSummaryRow, { summary: vbtSummary }),
|
|
12350
|
+
/* @__PURE__ */ jsx(SectionCard, { title: "Velocity Breakdown", testID: "exercise-detail-page-velocity", children: /* @__PURE__ */ jsx(VbtBreakdown, { sets: vbt.sets }) })
|
|
12351
|
+
] })
|
|
12352
|
+
] })
|
|
12353
|
+
}
|
|
12354
|
+
);
|
|
12355
|
+
}
|
|
12356
|
+
var BRAND_PRIMARY13 = "#FF7900";
|
|
12357
|
+
function countCompletedSets(exercise) {
|
|
12358
|
+
if (exercise.setVelocities != null) return exercise.setVelocities.length;
|
|
12359
|
+
if (exercise.status === "completed") return exercise.totalPlannedSets;
|
|
12360
|
+
return 0;
|
|
12361
|
+
}
|
|
12362
|
+
function deriveWorkoutProgress(exercises) {
|
|
12363
|
+
let completedExercises = 0;
|
|
12364
|
+
let completedSets = 0;
|
|
12365
|
+
let totalSets = 0;
|
|
12366
|
+
for (const exercise of exercises) {
|
|
12367
|
+
if (exercise.status === "completed") completedExercises += 1;
|
|
12368
|
+
completedSets += countCompletedSets(exercise);
|
|
12369
|
+
totalSets += exercise.totalPlannedSets;
|
|
12370
|
+
}
|
|
12371
|
+
return {
|
|
12372
|
+
completedExercises,
|
|
12373
|
+
totalExercises: exercises.length,
|
|
12374
|
+
completedSets,
|
|
12375
|
+
totalSets,
|
|
12376
|
+
fraction: totalSets === 0 ? 0 : completedSets / totalSets
|
|
12377
|
+
};
|
|
12378
|
+
}
|
|
12379
|
+
function findActiveExercise(exercises) {
|
|
12380
|
+
return exercises.find((exercise) => exercise.status === "active") ?? null;
|
|
12381
|
+
}
|
|
12382
|
+
function statusToCardState(status, focused) {
|
|
12383
|
+
if (status === "upcoming") return "upcoming";
|
|
12384
|
+
return focused ? "expanded" : "collapsed";
|
|
12385
|
+
}
|
|
12386
|
+
function toActiveCardProps(exercise, focused, onToggle, supersetPosition = null, supersetColor) {
|
|
12387
|
+
const state = statusToCardState(exercise.status, focused);
|
|
12388
|
+
return {
|
|
12389
|
+
name: exercise.name,
|
|
12390
|
+
state,
|
|
12391
|
+
onToggle,
|
|
12392
|
+
summary: exercise.summary,
|
|
12393
|
+
e1rm: exercise.e1rm,
|
|
12394
|
+
isPR: exercise.isPR,
|
|
12395
|
+
tempo: exercise.tempo,
|
|
12396
|
+
setVelocities: exercise.setVelocities,
|
|
12397
|
+
totalPlannedSets: exercise.totalPlannedSets,
|
|
12398
|
+
sets: state === "expanded" ? exercise.sets : void 0,
|
|
12399
|
+
prescription: exercise.prescription,
|
|
12400
|
+
previousBest: exercise.previousBest,
|
|
12401
|
+
supersetPosition,
|
|
12402
|
+
supersetColor
|
|
12403
|
+
};
|
|
12404
|
+
}
|
|
12405
|
+
function groupExercises(exercises, supersets) {
|
|
12406
|
+
const byId = new Map(supersets.map((superset) => [superset.id, superset]));
|
|
12407
|
+
const groups = [];
|
|
12408
|
+
for (const exercise of exercises) {
|
|
12409
|
+
const superset = exercise.supersetId != null ? byId.get(exercise.supersetId) : void 0;
|
|
12410
|
+
const last = groups[groups.length - 1];
|
|
12411
|
+
if (superset != null && last?.type === "superset" && last.superset.id === superset.id) {
|
|
12412
|
+
last.exercises.push(exercise);
|
|
12413
|
+
} else if (superset != null) {
|
|
12414
|
+
groups.push({ type: "superset", superset, exercises: [exercise] });
|
|
12415
|
+
} else {
|
|
12416
|
+
groups.push({ type: "single", exercise });
|
|
12417
|
+
}
|
|
12418
|
+
}
|
|
12419
|
+
return groups;
|
|
12420
|
+
}
|
|
12421
|
+
function supersetPositionAt(index, length) {
|
|
12422
|
+
if (length === 1) return null;
|
|
12423
|
+
if (index === 0) return "first";
|
|
12424
|
+
if (index === length - 1) return "last";
|
|
12425
|
+
return "middle";
|
|
12426
|
+
}
|
|
12427
|
+
function WorkoutHeader({
|
|
12428
|
+
title,
|
|
12429
|
+
subtitle,
|
|
12430
|
+
progress
|
|
12431
|
+
}) {
|
|
12432
|
+
return /* @__PURE__ */ jsxs(reactNative.View, { style: { gap: 10 }, testID: "active-workout-page-header", children: [
|
|
12433
|
+
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-start justify-between", style: { gap: 8 }, children: [
|
|
12434
|
+
/* @__PURE__ */ jsxs(reactNative.View, { style: { flexShrink: 1 }, children: [
|
|
12435
|
+
/* @__PURE__ */ jsx(
|
|
12436
|
+
reactNative.Text,
|
|
12437
|
+
{
|
|
12438
|
+
accessibilityRole: "header",
|
|
12439
|
+
className: "text-text-primary",
|
|
12440
|
+
style: {
|
|
12441
|
+
fontSize: 20,
|
|
12442
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
12443
|
+
fontWeight: "700"
|
|
12444
|
+
},
|
|
12445
|
+
testID: "active-workout-page-title",
|
|
12446
|
+
children: title
|
|
12447
|
+
}
|
|
12448
|
+
),
|
|
12449
|
+
subtitle != null && /* @__PURE__ */ jsx(
|
|
12450
|
+
reactNative.Text,
|
|
12451
|
+
{
|
|
12452
|
+
className: "text-text-secondary",
|
|
12453
|
+
style: {
|
|
12454
|
+
marginTop: 2,
|
|
12455
|
+
fontSize: 12,
|
|
12456
|
+
fontFamily: "Inter, sans-serif"
|
|
12457
|
+
},
|
|
12458
|
+
testID: "active-workout-page-subtitle",
|
|
12459
|
+
children: subtitle
|
|
12460
|
+
}
|
|
12461
|
+
)
|
|
12462
|
+
] }),
|
|
12463
|
+
/* @__PURE__ */ jsxs(reactNative.View, { style: { alignItems: "flex-end" }, testID: "active-workout-page-progress-count", children: [
|
|
12464
|
+
/* @__PURE__ */ jsx(
|
|
12465
|
+
reactNative.Text,
|
|
11717
12466
|
{
|
|
11718
|
-
style: {
|
|
11719
|
-
|
|
11720
|
-
|
|
12467
|
+
style: {
|
|
12468
|
+
fontSize: 15,
|
|
12469
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
12470
|
+
fontWeight: "700",
|
|
12471
|
+
color: BRAND_PRIMARY13,
|
|
12472
|
+
fontVariant: ["tabular-nums"]
|
|
12473
|
+
},
|
|
12474
|
+
children: `${progress.completedExercises}/${progress.totalExercises}`
|
|
11721
12475
|
}
|
|
11722
12476
|
),
|
|
11723
12477
|
/* @__PURE__ */ jsx(
|
|
11724
12478
|
reactNative.Text,
|
|
11725
12479
|
{
|
|
12480
|
+
className: "text-text-tertiary",
|
|
11726
12481
|
style: {
|
|
11727
|
-
fontSize:
|
|
12482
|
+
fontSize: 10,
|
|
11728
12483
|
fontFamily: "Inter, sans-serif",
|
|
11729
|
-
fontWeight: "
|
|
11730
|
-
|
|
12484
|
+
fontWeight: "600",
|
|
12485
|
+
letterSpacing: 0.4,
|
|
12486
|
+
textTransform: "uppercase"
|
|
11731
12487
|
},
|
|
11732
|
-
|
|
11733
|
-
children: entry.name
|
|
12488
|
+
children: `${progress.completedSets}/${progress.totalSets} sets`
|
|
11734
12489
|
}
|
|
11735
12490
|
)
|
|
11736
|
-
]
|
|
11737
|
-
}
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
|
|
11742
|
-
|
|
11743
|
-
|
|
11744
|
-
|
|
11745
|
-
|
|
11746
|
-
|
|
11747
|
-
|
|
11748
|
-
|
|
11749
|
-
|
|
11750
|
-
|
|
11751
|
-
|
|
11752
|
-
|
|
11753
|
-
|
|
11754
|
-
|
|
11755
|
-
|
|
11756
|
-
}
|
|
11757
|
-
|
|
11758
|
-
|
|
11759
|
-
if (value > 1) return 1;
|
|
11760
|
-
return value;
|
|
12491
|
+
] })
|
|
12492
|
+
] }),
|
|
12493
|
+
/* @__PURE__ */ jsx(
|
|
12494
|
+
reactNative.View,
|
|
12495
|
+
{
|
|
12496
|
+
className: "bg-border",
|
|
12497
|
+
style: { height: 4, borderRadius: 2 },
|
|
12498
|
+
testID: "active-workout-page-progress-track",
|
|
12499
|
+
children: /* @__PURE__ */ jsx(
|
|
12500
|
+
reactNative.View,
|
|
12501
|
+
{
|
|
12502
|
+
style: {
|
|
12503
|
+
height: "100%",
|
|
12504
|
+
width: `${Math.round(progress.fraction * 100)}%`,
|
|
12505
|
+
backgroundColor: BRAND_PRIMARY13,
|
|
12506
|
+
borderRadius: 2
|
|
12507
|
+
},
|
|
12508
|
+
testID: "active-workout-page-progress-fill"
|
|
12509
|
+
}
|
|
12510
|
+
)
|
|
12511
|
+
}
|
|
12512
|
+
)
|
|
12513
|
+
] });
|
|
11761
12514
|
}
|
|
11762
|
-
function
|
|
11763
|
-
|
|
11764
|
-
|
|
11765
|
-
|
|
12515
|
+
function ExerciseList({ groups, focusedId, onToggle }) {
|
|
12516
|
+
return /* @__PURE__ */ jsx(reactNative.View, { style: { gap: 10 }, testID: "active-workout-page-exercises", children: groups.map((group) => {
|
|
12517
|
+
if (group.type === "single") {
|
|
12518
|
+
return /* @__PURE__ */ jsx(
|
|
12519
|
+
reactNative.View,
|
|
12520
|
+
{
|
|
12521
|
+
className: "bg-surface-elevated border-border",
|
|
12522
|
+
style: {
|
|
12523
|
+
borderWidth: 1,
|
|
12524
|
+
borderRadius: 12
|
|
12525
|
+
},
|
|
12526
|
+
children: /* @__PURE__ */ jsx(
|
|
12527
|
+
ExerciseCard,
|
|
12528
|
+
{
|
|
12529
|
+
...toActiveCardProps(
|
|
12530
|
+
group.exercise,
|
|
12531
|
+
group.exercise.id === focusedId,
|
|
12532
|
+
() => onToggle(group.exercise.id)
|
|
12533
|
+
)
|
|
12534
|
+
}
|
|
12535
|
+
)
|
|
12536
|
+
},
|
|
12537
|
+
group.exercise.id
|
|
12538
|
+
);
|
|
12539
|
+
}
|
|
12540
|
+
return /* @__PURE__ */ jsx(
|
|
12541
|
+
SupersetWrapper,
|
|
12542
|
+
{
|
|
12543
|
+
label: group.superset.label,
|
|
12544
|
+
color: group.superset.color,
|
|
12545
|
+
children: group.exercises.map((exercise, index) => /* @__PURE__ */ jsx(
|
|
12546
|
+
ExerciseCard,
|
|
12547
|
+
{
|
|
12548
|
+
...toActiveCardProps(
|
|
12549
|
+
exercise,
|
|
12550
|
+
exercise.id === focusedId,
|
|
12551
|
+
() => onToggle(exercise.id),
|
|
12552
|
+
supersetPositionAt(index, group.exercises.length),
|
|
12553
|
+
group.superset.color
|
|
12554
|
+
)
|
|
12555
|
+
},
|
|
12556
|
+
exercise.id
|
|
12557
|
+
))
|
|
12558
|
+
},
|
|
12559
|
+
group.superset.id
|
|
12560
|
+
);
|
|
12561
|
+
}) });
|
|
11766
12562
|
}
|
|
11767
|
-
function
|
|
11768
|
-
|
|
11769
|
-
|
|
11770
|
-
|
|
11771
|
-
|
|
11772
|
-
|
|
11773
|
-
|
|
11774
|
-
|
|
11775
|
-
|
|
11776
|
-
upcomingExercises,
|
|
11777
|
-
isOpen,
|
|
11778
|
-
visible,
|
|
11779
|
-
onClose,
|
|
11780
|
-
onViewExercises,
|
|
12563
|
+
function ActiveWorkoutPage({
|
|
12564
|
+
title = "Active Workout",
|
|
12565
|
+
subtitle,
|
|
12566
|
+
exercises,
|
|
12567
|
+
supersets = [],
|
|
12568
|
+
input,
|
|
12569
|
+
rest,
|
|
12570
|
+
initialResting = false,
|
|
12571
|
+
className,
|
|
11781
12572
|
...props
|
|
11782
12573
|
}) {
|
|
11783
|
-
const
|
|
11784
|
-
const [
|
|
11785
|
-
const [
|
|
11786
|
-
React24.
|
|
11787
|
-
|
|
11788
|
-
|
|
11789
|
-
|
|
11790
|
-
|
|
11791
|
-
|
|
11792
|
-
|
|
11793
|
-
|
|
11794
|
-
|
|
11795
|
-
reactNative.Animated.timing(backdrop, {
|
|
11796
|
-
toValue: BACKDROP_OPACITY,
|
|
11797
|
-
duration: 300,
|
|
11798
|
-
easing: reactNative.Easing.out(reactNative.Easing.ease),
|
|
11799
|
-
useNativeDriver: false
|
|
11800
|
-
})
|
|
11801
|
-
]);
|
|
11802
|
-
animation.start();
|
|
11803
|
-
return () => animation.stop();
|
|
11804
|
-
}, [open, translateY, backdrop]);
|
|
11805
|
-
if (!open) return null;
|
|
11806
|
-
const dialogLabel = `${displayName} volume details`;
|
|
11807
|
-
const markerLeft = markerFraction(weeklySets, landmarks) * 100;
|
|
11808
|
-
const hasContributing = (contributingExercises?.length ?? 0) > 0;
|
|
11809
|
-
const hasUpcoming = (upcomingExercises?.length ?? 0) > 0;
|
|
12574
|
+
const active = findActiveExercise(exercises);
|
|
12575
|
+
const [focusedId, setFocusedId] = React24.useState(active?.id ?? null);
|
|
12576
|
+
const [resting, setResting] = React24.useState(initialResting);
|
|
12577
|
+
const [reps, setReps] = React24.useState(input?.reps ?? "");
|
|
12578
|
+
const [weight, setWeight] = React24.useState(input?.weight ?? "");
|
|
12579
|
+
const progress = React24.useMemo(() => deriveWorkoutProgress(exercises), [exercises]);
|
|
12580
|
+
const groups = React24.useMemo(() => groupExercises(exercises, supersets), [exercises, supersets]);
|
|
12581
|
+
const toggleFocus = (id) => setFocusedId((current) => current === id ? null : id);
|
|
12582
|
+
const nextSetNumber = active != null ? countCompletedSets(active) + 1 : 1;
|
|
12583
|
+
const canRecord = reps.trim() !== "" && weight.trim() !== "";
|
|
12584
|
+
const showRest = resting && rest != null;
|
|
12585
|
+
const showInput = !showRest && active != null;
|
|
11810
12586
|
return /* @__PURE__ */ jsxs(
|
|
11811
12587
|
reactNative.View,
|
|
11812
12588
|
{
|
|
11813
|
-
|
|
11814
|
-
|
|
12589
|
+
className: ["bg-background-base", className].filter(Boolean).join(" "),
|
|
12590
|
+
style: { position: "relative", width: 390 },
|
|
12591
|
+
accessibilityRole: "main",
|
|
12592
|
+
"aria-label": title,
|
|
12593
|
+
testID: "active-workout-page",
|
|
12594
|
+
...props,
|
|
11815
12595
|
children: [
|
|
11816
|
-
/* @__PURE__ */
|
|
11817
|
-
|
|
12596
|
+
/* @__PURE__ */ jsxs(reactNative.View, { style: { padding: 16, gap: 14 }, testID: "active-workout-page-content", children: [
|
|
12597
|
+
/* @__PURE__ */ jsx(WorkoutHeader, { title, subtitle, progress }),
|
|
12598
|
+
/* @__PURE__ */ jsx(ExerciseList, { groups, focusedId, onToggle: toggleFocus })
|
|
12599
|
+
] }),
|
|
12600
|
+
(showRest || showInput) && /* @__PURE__ */ jsx(
|
|
12601
|
+
reactNative.View,
|
|
11818
12602
|
{
|
|
11819
|
-
style: {
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
right: 0,
|
|
11824
|
-
bottom: 0,
|
|
11825
|
-
backgroundColor: "#000000",
|
|
11826
|
-
opacity: backdrop
|
|
11827
|
-
},
|
|
11828
|
-
testID: "body-map-detail-panel-backdrop-anim",
|
|
11829
|
-
children: /* @__PURE__ */ jsx(
|
|
11830
|
-
reactNative.Pressable,
|
|
12603
|
+
style: { borderTopWidth: 1, borderTopColor: resolveColor("border-default") },
|
|
12604
|
+
testID: "active-workout-page-bottom-bar",
|
|
12605
|
+
children: showRest && rest != null ? /* @__PURE__ */ jsx(
|
|
12606
|
+
RestTimer,
|
|
11831
12607
|
{
|
|
11832
|
-
|
|
11833
|
-
|
|
11834
|
-
|
|
11835
|
-
|
|
11836
|
-
|
|
12608
|
+
totalSeconds: rest.totalSeconds,
|
|
12609
|
+
elapsedMs: rest.elapsedMs,
|
|
12610
|
+
nextSetInfo: rest.nextSetInfo,
|
|
12611
|
+
onSkip: () => setResting(false),
|
|
12612
|
+
onAddTime: () => void 0,
|
|
12613
|
+
visible: true
|
|
12614
|
+
}
|
|
12615
|
+
) : active != null && /* @__PURE__ */ jsx(
|
|
12616
|
+
InputBar,
|
|
12617
|
+
{
|
|
12618
|
+
exerciseName: active.name,
|
|
12619
|
+
setNumber: nextSetNumber,
|
|
12620
|
+
totalSets: active.totalPlannedSets,
|
|
12621
|
+
reps,
|
|
12622
|
+
weight,
|
|
12623
|
+
unit: active.unit,
|
|
12624
|
+
onRepsChange: setReps,
|
|
12625
|
+
onWeightChange: setWeight,
|
|
12626
|
+
onRecord: () => {
|
|
12627
|
+
if (rest != null) setResting(true);
|
|
12628
|
+
},
|
|
12629
|
+
canRecord,
|
|
12630
|
+
visible: true
|
|
11837
12631
|
}
|
|
11838
12632
|
)
|
|
11839
12633
|
}
|
|
11840
|
-
),
|
|
11841
|
-
/* @__PURE__ */ jsxs(
|
|
11842
|
-
reactNative.Animated.View,
|
|
11843
|
-
{
|
|
11844
|
-
accessibilityRole: "dialog",
|
|
11845
|
-
accessibilityLabel: dialogLabel,
|
|
11846
|
-
"aria-label": dialogLabel,
|
|
11847
|
-
style: {
|
|
11848
|
-
backgroundColor: SURFACE_ELEVATED,
|
|
11849
|
-
borderTopLeftRadius: 16,
|
|
11850
|
-
borderTopRightRadius: 16,
|
|
11851
|
-
maxHeight: "88%",
|
|
11852
|
-
transform: [{ translateY }]
|
|
11853
|
-
},
|
|
11854
|
-
testID: "body-map-detail-panel",
|
|
11855
|
-
...props,
|
|
11856
|
-
children: [
|
|
11857
|
-
/* @__PURE__ */ jsx(
|
|
11858
|
-
reactNative.Pressable,
|
|
11859
|
-
{
|
|
11860
|
-
onPress: onClose,
|
|
11861
|
-
accessibilityRole: "button",
|
|
11862
|
-
accessibilityLabel: `Close ${displayName} details`,
|
|
11863
|
-
hitSlop: 12,
|
|
11864
|
-
style: { alignSelf: "center", paddingVertical: 8 },
|
|
11865
|
-
testID: "body-map-detail-panel-handle",
|
|
11866
|
-
children: /* @__PURE__ */ jsx(
|
|
11867
|
-
reactNative.View,
|
|
11868
|
-
{
|
|
11869
|
-
style: { width: 40, height: 4, borderRadius: 2, backgroundColor: BORDER_STRONG2 },
|
|
11870
|
-
accessibilityElementsHidden: true
|
|
11871
|
-
}
|
|
11872
|
-
)
|
|
11873
|
-
}
|
|
11874
|
-
),
|
|
11875
|
-
/* @__PURE__ */ jsxs(
|
|
11876
|
-
reactNative.ScrollView,
|
|
11877
|
-
{
|
|
11878
|
-
style: { paddingHorizontal: 16 },
|
|
11879
|
-
contentContainerStyle: { paddingBottom: 20 },
|
|
11880
|
-
testID: "body-map-detail-panel-scroll",
|
|
11881
|
-
children: [
|
|
11882
|
-
/* @__PURE__ */ jsxs(
|
|
11883
|
-
reactNative.View,
|
|
11884
|
-
{
|
|
11885
|
-
className: "flex-row items-center justify-between",
|
|
11886
|
-
style: { gap: 8, paddingTop: 4, paddingBottom: 4 },
|
|
11887
|
-
testID: "body-map-detail-panel-header",
|
|
11888
|
-
children: [
|
|
11889
|
-
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { gap: 8, flexShrink: 1 }, children: [
|
|
11890
|
-
/* @__PURE__ */ jsx(
|
|
11891
|
-
reactNative.Text,
|
|
11892
|
-
{
|
|
11893
|
-
accessibilityRole: "header",
|
|
11894
|
-
style: {
|
|
11895
|
-
fontSize: 16,
|
|
11896
|
-
fontFamily: '"Space Grotesk", sans-serif',
|
|
11897
|
-
fontWeight: "700",
|
|
11898
|
-
color: TEXT_PRIMARY8
|
|
11899
|
-
},
|
|
11900
|
-
testID: "body-map-detail-panel-title",
|
|
11901
|
-
children: displayName
|
|
11902
|
-
}
|
|
11903
|
-
),
|
|
11904
|
-
/* @__PURE__ */ jsx(
|
|
11905
|
-
Badge,
|
|
11906
|
-
{
|
|
11907
|
-
variant: "subtle",
|
|
11908
|
-
color: STATUS_BADGE_COLOR[volumeStatus],
|
|
11909
|
-
size: "sm",
|
|
11910
|
-
testID: "body-map-detail-panel-status-badge",
|
|
11911
|
-
children: VOLUME_STATUS_LABELS[volumeStatus]
|
|
11912
|
-
}
|
|
11913
|
-
)
|
|
11914
|
-
] }),
|
|
11915
|
-
/* @__PURE__ */ jsx(
|
|
11916
|
-
reactNative.Pressable,
|
|
11917
|
-
{
|
|
11918
|
-
onPress: onClose,
|
|
11919
|
-
accessibilityRole: "button",
|
|
11920
|
-
accessibilityLabel: `Close ${displayName} details`,
|
|
11921
|
-
hitSlop: 8,
|
|
11922
|
-
style: { padding: 4, margin: -4 },
|
|
11923
|
-
testID: "body-map-detail-panel-close",
|
|
11924
|
-
children: /* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 22, lineHeight: 22, color: TEXT_SECONDARY7 }, children: "\xD7" })
|
|
11925
|
-
}
|
|
11926
|
-
)
|
|
11927
|
-
]
|
|
11928
|
-
}
|
|
11929
|
-
),
|
|
11930
|
-
lastTrained != null && /* @__PURE__ */ jsx(
|
|
11931
|
-
reactNative.Text,
|
|
11932
|
-
{
|
|
11933
|
-
style: { fontSize: 12, fontFamily: "Inter, sans-serif", color: TEXT_SECONDARY7 },
|
|
11934
|
-
testID: "body-map-detail-panel-last-trained",
|
|
11935
|
-
children: `Last trained ${lastTrained}`
|
|
11936
|
-
}
|
|
11937
|
-
),
|
|
11938
|
-
/* @__PURE__ */ jsxs(reactNative.View, { style: { marginTop: 16 }, testID: "body-map-detail-panel-volume", children: [
|
|
11939
|
-
/* @__PURE__ */ jsxs(
|
|
11940
|
-
reactNative.View,
|
|
11941
|
-
{
|
|
11942
|
-
className: "flex-row items-center justify-between",
|
|
11943
|
-
style: { marginBottom: 6 },
|
|
11944
|
-
accessibilityElementsHidden: true,
|
|
11945
|
-
children: [
|
|
11946
|
-
/* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 10, fontFamily: "Inter, sans-serif", fontWeight: "600", color: TEXT_TERTIARY7 }, children: `MEV ${landmarks.mev}` }),
|
|
11947
|
-
/* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 10, fontFamily: "Inter, sans-serif", fontWeight: "600", color: TEXT_TERTIARY7 }, children: `MRV ${landmarks.mrv}` })
|
|
11948
|
-
]
|
|
11949
|
-
}
|
|
11950
|
-
),
|
|
11951
|
-
/* @__PURE__ */ jsxs(
|
|
11952
|
-
reactNative.View,
|
|
11953
|
-
{
|
|
11954
|
-
style: { height: 14, justifyContent: "center" },
|
|
11955
|
-
accessibilityRole: "progressbar",
|
|
11956
|
-
accessibilityValue: { min: landmarks.mev, max: landmarks.mrv, now: weeklySets },
|
|
11957
|
-
accessibilityLabel: `${weeklySets} weekly sets, between MEV ${landmarks.mev} and MRV ${landmarks.mrv}`,
|
|
11958
|
-
"aria-valuenow": weeklySets,
|
|
11959
|
-
"aria-valuemin": landmarks.mev,
|
|
11960
|
-
"aria-valuemax": landmarks.mrv,
|
|
11961
|
-
testID: "body-map-detail-panel-volume-bar",
|
|
11962
|
-
children: [
|
|
11963
|
-
/* @__PURE__ */ jsx(
|
|
11964
|
-
reactNative.View,
|
|
11965
|
-
{
|
|
11966
|
-
style: { height: 8, borderRadius: 4, backgroundImage: VOLUME_GRADIENT },
|
|
11967
|
-
accessibilityElementsHidden: true
|
|
11968
|
-
}
|
|
11969
|
-
),
|
|
11970
|
-
/* @__PURE__ */ jsx(
|
|
11971
|
-
reactNative.View,
|
|
11972
|
-
{
|
|
11973
|
-
style: {
|
|
11974
|
-
position: "absolute",
|
|
11975
|
-
left: `${markerLeft}%`,
|
|
11976
|
-
marginLeft: -7,
|
|
11977
|
-
width: 14,
|
|
11978
|
-
height: 14,
|
|
11979
|
-
borderRadius: 7,
|
|
11980
|
-
borderWidth: 2,
|
|
11981
|
-
borderColor: TEXT_PRIMARY8,
|
|
11982
|
-
backgroundColor: SURFACE_ELEVATED,
|
|
11983
|
-
boxShadow: "0 0 4px rgba(0,0,0,0.5)"
|
|
11984
|
-
},
|
|
11985
|
-
accessibilityElementsHidden: true,
|
|
11986
|
-
testID: "body-map-detail-panel-volume-marker"
|
|
11987
|
-
}
|
|
11988
|
-
)
|
|
11989
|
-
]
|
|
11990
|
-
}
|
|
11991
|
-
)
|
|
11992
|
-
] }),
|
|
11993
|
-
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-baseline", style: { marginTop: 14, gap: 4 }, children: [
|
|
11994
|
-
/* @__PURE__ */ jsx(
|
|
11995
|
-
reactNative.Text,
|
|
11996
|
-
{
|
|
11997
|
-
style: {
|
|
11998
|
-
fontSize: 24,
|
|
11999
|
-
fontFamily: '"Space Grotesk", sans-serif',
|
|
12000
|
-
fontWeight: "700",
|
|
12001
|
-
color: TEXT_PRIMARY8
|
|
12002
|
-
},
|
|
12003
|
-
testID: "body-map-detail-panel-set-count",
|
|
12004
|
-
children: weeklySets
|
|
12005
|
-
}
|
|
12006
|
-
),
|
|
12007
|
-
/* @__PURE__ */ jsx(
|
|
12008
|
-
reactNative.Text,
|
|
12009
|
-
{
|
|
12010
|
-
style: { fontSize: 12, fontFamily: "Inter, sans-serif", color: TEXT_SECONDARY7 },
|
|
12011
|
-
testID: "body-map-detail-panel-mrv-suffix",
|
|
12012
|
-
children: `/ ${landmarks.mrv} MRV`
|
|
12013
|
-
}
|
|
12014
|
-
)
|
|
12015
|
-
] }),
|
|
12016
|
-
weeklyHistory != null && weeklyHistory.length > 0 && /* @__PURE__ */ jsxs(reactNative.View, { style: { marginTop: 14 }, testID: "body-map-detail-panel-sparkline", children: [
|
|
12017
|
-
/* @__PURE__ */ jsx(
|
|
12018
|
-
reactNative.Text,
|
|
12019
|
-
{
|
|
12020
|
-
style: {
|
|
12021
|
-
fontSize: 10,
|
|
12022
|
-
fontFamily: "Inter, sans-serif",
|
|
12023
|
-
fontWeight: "600",
|
|
12024
|
-
color: TEXT_TERTIARY7,
|
|
12025
|
-
marginBottom: 6
|
|
12026
|
-
},
|
|
12027
|
-
accessibilityElementsHidden: true,
|
|
12028
|
-
children: "VOLUME TREND"
|
|
12029
|
-
}
|
|
12030
|
-
),
|
|
12031
|
-
/* @__PURE__ */ jsx(Sparkline, { data: weeklyHistory, width: 80, height: 30, highlightLast: true })
|
|
12032
|
-
] }),
|
|
12033
|
-
hasContributing && /* @__PURE__ */ jsxs(reactNative.View, { style: { marginTop: 16 }, testID: "body-map-detail-panel-contributing", children: [
|
|
12034
|
-
/* @__PURE__ */ jsx(
|
|
12035
|
-
reactNative.Text,
|
|
12036
|
-
{
|
|
12037
|
-
style: {
|
|
12038
|
-
fontSize: 10,
|
|
12039
|
-
fontFamily: "Inter, sans-serif",
|
|
12040
|
-
fontWeight: "600",
|
|
12041
|
-
color: TEXT_TERTIARY7,
|
|
12042
|
-
marginBottom: 8
|
|
12043
|
-
},
|
|
12044
|
-
children: "CONTRIBUTING EXERCISES"
|
|
12045
|
-
}
|
|
12046
|
-
),
|
|
12047
|
-
contributingExercises.map((exercise, index) => /* @__PURE__ */ jsxs(
|
|
12048
|
-
reactNative.View,
|
|
12049
|
-
{
|
|
12050
|
-
className: "flex-row items-center justify-between",
|
|
12051
|
-
style: {
|
|
12052
|
-
gap: 10,
|
|
12053
|
-
paddingVertical: 8,
|
|
12054
|
-
paddingHorizontal: 12,
|
|
12055
|
-
marginBottom: 6,
|
|
12056
|
-
borderRadius: 8,
|
|
12057
|
-
backgroundColor: SURFACE_RAISED2,
|
|
12058
|
-
borderWidth: 1,
|
|
12059
|
-
borderColor: BORDER_DEFAULT3
|
|
12060
|
-
},
|
|
12061
|
-
testID: `body-map-detail-panel-contributing-${index}`,
|
|
12062
|
-
children: [
|
|
12063
|
-
/* @__PURE__ */ jsx(
|
|
12064
|
-
reactNative.Text,
|
|
12065
|
-
{
|
|
12066
|
-
style: { flex: 1, fontSize: 13, fontFamily: "Inter, sans-serif", fontWeight: "600", color: TEXT_PRIMARY8 },
|
|
12067
|
-
testID: `body-map-detail-panel-contributing-${index}-name`,
|
|
12068
|
-
children: exercise.name
|
|
12069
|
-
}
|
|
12070
|
-
),
|
|
12071
|
-
/* @__PURE__ */ jsx(
|
|
12072
|
-
reactNative.Text,
|
|
12073
|
-
{
|
|
12074
|
-
style: { fontSize: 12, fontFamily: "Inter, sans-serif", color: TEXT_SECONDARY7 },
|
|
12075
|
-
testID: `body-map-detail-panel-contributing-${index}-detail`,
|
|
12076
|
-
children: `${exercise.sets} sets \xB7 ${Math.round(exercise.contributionWeight * 100)}%`
|
|
12077
|
-
}
|
|
12078
|
-
)
|
|
12079
|
-
]
|
|
12080
|
-
},
|
|
12081
|
-
`${exercise.name}-${index}`
|
|
12082
|
-
))
|
|
12083
|
-
] }),
|
|
12084
|
-
hasUpcoming && /* @__PURE__ */ jsxs(reactNative.View, { style: { marginTop: 16 }, testID: "body-map-detail-panel-upcoming", children: [
|
|
12085
|
-
/* @__PURE__ */ jsx(
|
|
12086
|
-
reactNative.Text,
|
|
12087
|
-
{
|
|
12088
|
-
style: {
|
|
12089
|
-
fontSize: 10,
|
|
12090
|
-
fontFamily: "Inter, sans-serif",
|
|
12091
|
-
fontWeight: "600",
|
|
12092
|
-
color: TEXT_TERTIARY7,
|
|
12093
|
-
marginBottom: 8
|
|
12094
|
-
},
|
|
12095
|
-
children: "UPCOMING"
|
|
12096
|
-
}
|
|
12097
|
-
),
|
|
12098
|
-
upcomingExercises.map((exercise, index) => /* @__PURE__ */ jsxs(
|
|
12099
|
-
reactNative.View,
|
|
12100
|
-
{
|
|
12101
|
-
className: "flex-row items-center justify-between",
|
|
12102
|
-
style: { gap: 10, paddingVertical: 6 },
|
|
12103
|
-
testID: `body-map-detail-panel-upcoming-${index}`,
|
|
12104
|
-
children: [
|
|
12105
|
-
/* @__PURE__ */ jsx(
|
|
12106
|
-
reactNative.Text,
|
|
12107
|
-
{
|
|
12108
|
-
style: { flex: 1, fontSize: 13, fontFamily: "Inter, sans-serif", fontWeight: "600", color: TEXT_PRIMARY8 },
|
|
12109
|
-
testID: `body-map-detail-panel-upcoming-${index}-name`,
|
|
12110
|
-
children: exercise.name
|
|
12111
|
-
}
|
|
12112
|
-
),
|
|
12113
|
-
/* @__PURE__ */ jsx(
|
|
12114
|
-
reactNative.Text,
|
|
12115
|
-
{
|
|
12116
|
-
style: { fontSize: 12, fontFamily: "Inter, sans-serif", color: TEXT_TERTIARY7 },
|
|
12117
|
-
testID: `body-map-detail-panel-upcoming-${index}-detail`,
|
|
12118
|
-
children: `${exercise.workoutName} \xB7 ${exercise.sets} sets`
|
|
12119
|
-
}
|
|
12120
|
-
)
|
|
12121
|
-
]
|
|
12122
|
-
},
|
|
12123
|
-
`${exercise.name}-${index}`
|
|
12124
|
-
))
|
|
12125
|
-
] }),
|
|
12126
|
-
onViewExercises != null && /* @__PURE__ */ jsx(
|
|
12127
|
-
reactNative.Pressable,
|
|
12128
|
-
{
|
|
12129
|
-
onPress: onViewExercises,
|
|
12130
|
-
accessibilityRole: "button",
|
|
12131
|
-
accessibilityLabel: `View ${displayName} exercises`,
|
|
12132
|
-
style: {
|
|
12133
|
-
marginTop: 16,
|
|
12134
|
-
paddingVertical: 10,
|
|
12135
|
-
borderRadius: 8,
|
|
12136
|
-
alignItems: "center",
|
|
12137
|
-
backgroundColor: "rgba(255,121,0,0.12)",
|
|
12138
|
-
borderWidth: 1,
|
|
12139
|
-
borderColor: "rgba(255,121,0,0.3)"
|
|
12140
|
-
},
|
|
12141
|
-
testID: "body-map-detail-panel-view-exercises",
|
|
12142
|
-
children: /* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 13, fontFamily: "Inter, sans-serif", fontWeight: "700", color: BRAND_PRIMARY11 }, children: "View exercises" })
|
|
12143
|
-
}
|
|
12144
|
-
)
|
|
12145
|
-
]
|
|
12146
|
-
}
|
|
12147
|
-
)
|
|
12148
|
-
]
|
|
12149
|
-
}
|
|
12150
12634
|
)
|
|
12151
12635
|
]
|
|
12152
12636
|
}
|
|
@@ -12376,28 +12860,28 @@ function Scatter({
|
|
|
12376
12860
|
testID: "scatter-canvas",
|
|
12377
12861
|
style: { position: "absolute", top: 0, left: 0, width, height, overflow: "hidden" },
|
|
12378
12862
|
children: [
|
|
12379
|
-
ticksOf(yd, TICK_COUNT).map((
|
|
12380
|
-
const y = toY(
|
|
12863
|
+
ticksOf(yd, TICK_COUNT).map((t2, i) => {
|
|
12864
|
+
const y = toY(t2);
|
|
12381
12865
|
return /* @__PURE__ */ jsx(
|
|
12382
12866
|
reactNative.View,
|
|
12383
12867
|
{
|
|
12384
12868
|
accessibilityElementsHidden: true,
|
|
12385
12869
|
testID: "scatter-gridline-y",
|
|
12386
12870
|
style: { position: "absolute", left: PLOT_LEFT2, width: innerW, top: y, height: 1, backgroundColor: GRID_LINE2 },
|
|
12387
|
-
children: /* @__PURE__ */ jsx(reactNative.Text, { className: "text-[9px] text-text-tertiary", style: { position: "absolute", left: -PLOT_LEFT2, top: -6, width: PLOT_LEFT2 - 6, textAlign: "right" }, children: formatTick(
|
|
12871
|
+
children: /* @__PURE__ */ jsx(reactNative.Text, { className: "text-[9px] text-text-tertiary", style: { position: "absolute", left: -PLOT_LEFT2, top: -6, width: PLOT_LEFT2 - 6, textAlign: "right" }, children: formatTick(t2) })
|
|
12388
12872
|
},
|
|
12389
12873
|
`y-${i}`
|
|
12390
12874
|
);
|
|
12391
12875
|
}),
|
|
12392
|
-
ticksOf(xd, TICK_COUNT).map((
|
|
12393
|
-
const x = toX(
|
|
12876
|
+
ticksOf(xd, TICK_COUNT).map((t2, i) => {
|
|
12877
|
+
const x = toX(t2);
|
|
12394
12878
|
return /* @__PURE__ */ jsx(
|
|
12395
12879
|
reactNative.View,
|
|
12396
12880
|
{
|
|
12397
12881
|
accessibilityElementsHidden: true,
|
|
12398
12882
|
testID: "scatter-gridline-x",
|
|
12399
12883
|
style: { position: "absolute", top: PLOT_TOP, height: innerH, left: x, width: 1, backgroundColor: GRID_LINE2 },
|
|
12400
|
-
children: /* @__PURE__ */ jsx(reactNative.Text, { className: "text-[9px] text-text-tertiary", style: { position: "absolute", top: innerH + 4, left: -16, width: 32, textAlign: "center" }, children: formatTick(
|
|
12884
|
+
children: /* @__PURE__ */ jsx(reactNative.Text, { className: "text-[9px] text-text-tertiary", style: { position: "absolute", top: innerH + 4, left: -16, width: 32, textAlign: "center" }, children: formatTick(t2) })
|
|
12401
12885
|
},
|
|
12402
12886
|
`x-${i}`
|
|
12403
12887
|
);
|
|
@@ -12469,7 +12953,7 @@ var DEFAULT_THRESHOLDS = [
|
|
|
12469
12953
|
var ARC_START = 135;
|
|
12470
12954
|
var ARC_SWEEP = 270;
|
|
12471
12955
|
var SEGMENTS = 40;
|
|
12472
|
-
function
|
|
12956
|
+
function clamp013(n) {
|
|
12473
12957
|
if (Number.isNaN(n)) return 0;
|
|
12474
12958
|
return Math.max(0, Math.min(1, n));
|
|
12475
12959
|
}
|
|
@@ -12514,7 +12998,7 @@ function Gauge2({
|
|
|
12514
12998
|
...props
|
|
12515
12999
|
}) {
|
|
12516
13000
|
const span = max - min || 1;
|
|
12517
|
-
const fill =
|
|
13001
|
+
const fill = clamp013((value - min) / span);
|
|
12518
13002
|
const activeColor = (f) => color ?? bandColor(f, thresholds, min, max);
|
|
12519
13003
|
const ticks = buildTicks(fill, size, activeColor);
|
|
12520
13004
|
const displayColor = color ?? bandColor(fill, thresholds, min, max);
|
|
@@ -12531,23 +13015,23 @@ function Gauge2({
|
|
|
12531
13015
|
testID: "gauge",
|
|
12532
13016
|
...props,
|
|
12533
13017
|
children: [
|
|
12534
|
-
ticks.map((
|
|
13018
|
+
ticks.map((t2) => /* @__PURE__ */ jsx(
|
|
12535
13019
|
reactNative.View,
|
|
12536
13020
|
{
|
|
12537
13021
|
accessibilityElementsHidden: true,
|
|
12538
13022
|
testID: "gauge-segment",
|
|
12539
13023
|
style: {
|
|
12540
13024
|
position: "absolute",
|
|
12541
|
-
left:
|
|
12542
|
-
top:
|
|
13025
|
+
left: t2.left - tickThickness / 2,
|
|
13026
|
+
top: t2.top - tickLength / 2,
|
|
12543
13027
|
width: tickThickness,
|
|
12544
13028
|
height: tickLength,
|
|
12545
13029
|
borderRadius: tickThickness / 2,
|
|
12546
|
-
backgroundColor:
|
|
12547
|
-
transform: [{ rotate:
|
|
13030
|
+
backgroundColor: t2.color,
|
|
13031
|
+
transform: [{ rotate: t2.rotate }]
|
|
12548
13032
|
}
|
|
12549
13033
|
},
|
|
12550
|
-
|
|
13034
|
+
t2.key
|
|
12551
13035
|
)),
|
|
12552
13036
|
/* @__PURE__ */ jsxs(reactNative.View, { style: { position: "absolute", top: 0, left: 0, width: size, height: size }, className: "items-center justify-center", children: [
|
|
12553
13037
|
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-baseline gap-0.5", children: [
|
|
@@ -12561,65 +13045,6 @@ function Gauge2({
|
|
|
12561
13045
|
);
|
|
12562
13046
|
}
|
|
12563
13047
|
|
|
12564
|
-
// src/utils/colors.ts
|
|
12565
|
-
function getStatusColor(status) {
|
|
12566
|
-
return `var(--color-status-${status})`;
|
|
12567
|
-
}
|
|
12568
|
-
function getResultColor(result) {
|
|
12569
|
-
return `var(--color-result-${result})`;
|
|
12570
|
-
}
|
|
12571
|
-
function alpha(color, opacity) {
|
|
12572
|
-
const clampedOpacity = Math.max(0, Math.min(1, opacity));
|
|
12573
|
-
if (color.startsWith("#")) {
|
|
12574
|
-
const hex = color.slice(1);
|
|
12575
|
-
let r, g, b;
|
|
12576
|
-
if (hex.length === 3) {
|
|
12577
|
-
r = parseInt(hex[0] + hex[0], 16);
|
|
12578
|
-
g = parseInt(hex[1] + hex[1], 16);
|
|
12579
|
-
b = parseInt(hex[2] + hex[2], 16);
|
|
12580
|
-
} else if (hex.length === 6) {
|
|
12581
|
-
r = parseInt(hex.slice(0, 2), 16);
|
|
12582
|
-
g = parseInt(hex.slice(2, 4), 16);
|
|
12583
|
-
b = parseInt(hex.slice(4, 6), 16);
|
|
12584
|
-
} else {
|
|
12585
|
-
return color;
|
|
12586
|
-
}
|
|
12587
|
-
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
12588
|
-
}
|
|
12589
|
-
const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
12590
|
-
if (rgbMatch) {
|
|
12591
|
-
const [, r, g, b] = rgbMatch;
|
|
12592
|
-
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
12593
|
-
}
|
|
12594
|
-
const rgbaMatch = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/);
|
|
12595
|
-
if (rgbaMatch) {
|
|
12596
|
-
const [, r, g, b] = rgbaMatch;
|
|
12597
|
-
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
12598
|
-
}
|
|
12599
|
-
return color;
|
|
12600
|
-
}
|
|
12601
|
-
function getLuminance(color) {
|
|
12602
|
-
if (!color.startsWith("#")) return "dark";
|
|
12603
|
-
const hex = color.slice(1);
|
|
12604
|
-
let r, g, b;
|
|
12605
|
-
if (hex.length === 3) {
|
|
12606
|
-
r = parseInt(hex[0] + hex[0], 16);
|
|
12607
|
-
g = parseInt(hex[1] + hex[1], 16);
|
|
12608
|
-
b = parseInt(hex[2] + hex[2], 16);
|
|
12609
|
-
} else if (hex.length === 6) {
|
|
12610
|
-
r = parseInt(hex.slice(0, 2), 16);
|
|
12611
|
-
g = parseInt(hex.slice(2, 4), 16);
|
|
12612
|
-
b = parseInt(hex.slice(4, 6), 16);
|
|
12613
|
-
} else {
|
|
12614
|
-
return "dark";
|
|
12615
|
-
}
|
|
12616
|
-
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
12617
|
-
return luminance > 0.5 ? "light" : "dark";
|
|
12618
|
-
}
|
|
12619
|
-
function getContrastText(backgroundColor) {
|
|
12620
|
-
return getLuminance(backgroundColor) === "light" ? "#000000" : "#FFFFFF";
|
|
12621
|
-
}
|
|
12622
|
-
|
|
12623
13048
|
// src/utils/form.ts
|
|
12624
13049
|
function getFieldValidationProps(state) {
|
|
12625
13050
|
return {
|
|
@@ -12712,6 +13137,7 @@ exports.Accordion = Accordion;
|
|
|
12712
13137
|
exports.AccordionButton = AccordionButton;
|
|
12713
13138
|
exports.AccordionItem = AccordionItem;
|
|
12714
13139
|
exports.AccordionPanel = AccordionPanel;
|
|
13140
|
+
exports.ActiveWorkoutPage = ActiveWorkoutPage;
|
|
12715
13141
|
exports.Alert = Alert;
|
|
12716
13142
|
exports.AlertDescription = AlertDescription;
|
|
12717
13143
|
exports.AlertTitle = AlertTitle;
|
|
@@ -12722,8 +13148,6 @@ exports.AvatarGroup = AvatarGroup;
|
|
|
12722
13148
|
exports.Badge = Badge;
|
|
12723
13149
|
exports.BadgeText = BadgeText;
|
|
12724
13150
|
exports.BaseBadge = BaseBadge;
|
|
12725
|
-
exports.BodyMap = BodyMap;
|
|
12726
|
-
exports.BodyMapDetailPanel = BodyMapDetailPanel;
|
|
12727
13151
|
exports.BreadcrumbItem = BreadcrumbItem;
|
|
12728
13152
|
exports.Breadcrumbs = Breadcrumbs;
|
|
12729
13153
|
exports.Button = Button;
|
|
@@ -12746,8 +13170,6 @@ exports.CircularProgress = CircularProgress;
|
|
|
12746
13170
|
exports.Collapse = Collapse;
|
|
12747
13171
|
exports.CollapseButton = CollapseButton;
|
|
12748
13172
|
exports.CollapseContent = CollapseContent;
|
|
12749
|
-
exports.DEFAULT_VOLUME_LANDMARKS = DEFAULT_VOLUME_LANDMARKS;
|
|
12750
|
-
exports.DETAILED_TO_SIMPLE = DETAILED_TO_SIMPLE;
|
|
12751
13173
|
exports.DataRow = DataRow;
|
|
12752
13174
|
exports.DateTime = DateTime;
|
|
12753
13175
|
exports.DeviationBar = DeviationBar;
|
|
@@ -12756,8 +13178,10 @@ exports.Drawer = Drawer;
|
|
|
12756
13178
|
exports.DrawerBody = DrawerBody;
|
|
12757
13179
|
exports.DrawerFooter = DrawerFooter;
|
|
12758
13180
|
exports.DrawerHeader = DrawerHeader;
|
|
13181
|
+
exports.EXERCISE_DETAIL_TABS = EXERCISE_DETAIL_TABS;
|
|
12759
13182
|
exports.EmptyState = EmptyState;
|
|
12760
13183
|
exports.ExerciseCard = ExerciseCard;
|
|
13184
|
+
exports.ExerciseDetailPage = ExerciseDetailPage;
|
|
12761
13185
|
exports.FormActions = FormActions;
|
|
12762
13186
|
exports.FormField = FormField;
|
|
12763
13187
|
exports.FormRow = FormRow;
|
|
@@ -12780,9 +13204,6 @@ exports.ListItemContent = ListItemContent;
|
|
|
12780
13204
|
exports.ListItemDivider = ListItemDivider;
|
|
12781
13205
|
exports.ListItemIcon = ListItemIcon;
|
|
12782
13206
|
exports.ListItemTrailing = ListItemTrailing;
|
|
12783
|
-
exports.MUSCLE_DISPLAY_NAMES = MUSCLE_DISPLAY_NAMES;
|
|
12784
|
-
exports.MUSCLE_TO_CATEGORY = MUSCLE_TO_CATEGORY;
|
|
12785
|
-
exports.MUSCLE_TO_SVG_SLUGS = MUSCLE_TO_SVG_SLUGS;
|
|
12786
13207
|
exports.Menu = Menu;
|
|
12787
13208
|
exports.MenuDivider = MenuDivider;
|
|
12788
13209
|
exports.MenuGroup = MenuGroup;
|
|
@@ -12801,7 +13222,6 @@ exports.ModalContent = ModalContent;
|
|
|
12801
13222
|
exports.ModalFooter = ModalFooter;
|
|
12802
13223
|
exports.ModalHeader = ModalHeader;
|
|
12803
13224
|
exports.ModalTitle = ModalTitle;
|
|
12804
|
-
exports.MuscleGroup = MuscleGroup;
|
|
12805
13225
|
exports.MuscleGroupChip = MuscleGroupChip;
|
|
12806
13226
|
exports.Overline = Overline;
|
|
12807
13227
|
exports.Paragraph = Paragraph;
|
|
@@ -12814,14 +13234,13 @@ exports.PopoverContent = PopoverContent;
|
|
|
12814
13234
|
exports.PopoverTrigger = PopoverTrigger;
|
|
12815
13235
|
exports.PrBadge = PrBadge;
|
|
12816
13236
|
exports.PrHistoryModal = PrHistoryModal;
|
|
13237
|
+
exports.ProgramPlanningPage = ProgramPlanningPage;
|
|
12817
13238
|
exports.Progress = Progress;
|
|
12818
13239
|
exports.ProgressSteps = ProgressSteps;
|
|
12819
13240
|
exports.Radio = Radio;
|
|
12820
13241
|
exports.RadioGroup = RadioGroup;
|
|
12821
13242
|
exports.ReadinessCheck = ReadinessCheck;
|
|
12822
13243
|
exports.RestTimer = RestTimer;
|
|
12823
|
-
exports.SIMPLE_DISPLAY_NAMES = SIMPLE_DISPLAY_NAMES;
|
|
12824
|
-
exports.SIMPLE_TO_DETAILED = SIMPLE_TO_DETAILED;
|
|
12825
13244
|
exports.Scatter = Scatter;
|
|
12826
13245
|
exports.Section = Section;
|
|
12827
13246
|
exports.SectionContent = SectionContent;
|
|
@@ -12835,7 +13254,6 @@ exports.SidebarFooter = SidebarFooter;
|
|
|
12835
13254
|
exports.SidebarHeader = SidebarHeader;
|
|
12836
13255
|
exports.SidebarItem = SidebarItem;
|
|
12837
13256
|
exports.SidebarSection = SidebarSection;
|
|
12838
|
-
exports.SimpleMuscleGroup = SimpleMuscleGroup;
|
|
12839
13257
|
exports.Skeleton = Skeleton;
|
|
12840
13258
|
exports.SkeletonCard = SkeletonCard;
|
|
12841
13259
|
exports.SkeletonCircle = SkeletonCircle;
|
|
@@ -12854,6 +13272,7 @@ exports.StrengthTrendChart = StrengthTrendChart;
|
|
|
12854
13272
|
exports.SupersetWrapper = SupersetWrapper;
|
|
12855
13273
|
exports.Surface = Surface;
|
|
12856
13274
|
exports.Switch = Switch;
|
|
13275
|
+
exports.TEMPO_PACING = TEMPO_PACING;
|
|
12857
13276
|
exports.Tab = Tab;
|
|
12858
13277
|
exports.TabList = TabList;
|
|
12859
13278
|
exports.TabPanel = TabPanel;
|
|
@@ -12866,7 +13285,9 @@ exports.TableHeaderCell = TableHeaderCell;
|
|
|
12866
13285
|
exports.TablePagination = TablePagination;
|
|
12867
13286
|
exports.TableRow = TableRow;
|
|
12868
13287
|
exports.Tabs = Tabs;
|
|
13288
|
+
exports.TempoBar = TempoBar;
|
|
12869
13289
|
exports.TempoDisplay = TempoDisplay;
|
|
13290
|
+
exports.ThemeProvider = ThemeProvider;
|
|
12870
13291
|
exports.Toast = Toast;
|
|
12871
13292
|
exports.ToastProvider = ToastProvider;
|
|
12872
13293
|
exports.ToolbarButton = ToolbarButton;
|
|
@@ -12874,7 +13295,6 @@ exports.ToolbarButtonGroup = ToolbarButtonGroup;
|
|
|
12874
13295
|
exports.Tooltip = Tooltip;
|
|
12875
13296
|
exports.Treemap = Treemap;
|
|
12876
13297
|
exports.Typography = Typography;
|
|
12877
|
-
exports.VOLUME_STATUS_LABELS = VOLUME_STATUS_LABELS;
|
|
12878
13298
|
exports.VStack = VStack;
|
|
12879
13299
|
exports.VelocityStrip = VelocityStrip;
|
|
12880
13300
|
exports.WeekRow = WeekRow;
|
|
@@ -12884,12 +13304,14 @@ exports.WorkoutPill = WorkoutPill;
|
|
|
12884
13304
|
exports.alpha = alpha;
|
|
12885
13305
|
exports.applyThemePreset = applyThemePreset;
|
|
12886
13306
|
exports.audiobookPreset = audiobookPreset;
|
|
13307
|
+
exports.buildBreadcrumbs = buildBreadcrumbs;
|
|
12887
13308
|
exports.buttonSizes = buttonSizes;
|
|
12888
13309
|
exports.calculateMeanVelocity = calculateMeanVelocity;
|
|
12889
13310
|
exports.calculateVelocityLoss = calculateVelocityLoss;
|
|
12890
13311
|
exports.cn = cn;
|
|
12891
13312
|
exports.componentElevationRanges = componentElevationRanges;
|
|
12892
13313
|
exports.composeValidators = composeValidators;
|
|
13314
|
+
exports.countCompletedSets = countCompletedSets;
|
|
12893
13315
|
exports.createFieldId = createFieldId;
|
|
12894
13316
|
exports.createFlatShadow = createFlatShadow;
|
|
12895
13317
|
exports.createPressedHoverShadow = createPressedHoverShadow;
|
|
@@ -12899,9 +13321,19 @@ exports.createRaisedShadow = createRaisedShadow;
|
|
|
12899
13321
|
exports.darkThemeCSSVars = darkThemeCSSVars;
|
|
12900
13322
|
exports.darken = darken;
|
|
12901
13323
|
exports.defaultPreset = defaultPreset;
|
|
13324
|
+
exports.deriveExerciseStats = deriveExerciseStats;
|
|
13325
|
+
exports.deriveNavLevel = deriveNavLevel;
|
|
13326
|
+
exports.deriveWorkoutProgress = deriveWorkoutProgress;
|
|
12902
13327
|
exports.discreteRainbow = discreteRainbow;
|
|
12903
13328
|
exports.elevationSystem = elevationSystem;
|
|
13329
|
+
exports.findActiveExercise = findActiveExercise;
|
|
13330
|
+
exports.findMeso = findMeso;
|
|
13331
|
+
exports.findWeek = findWeek;
|
|
13332
|
+
exports.findWorkout = findWorkout;
|
|
12904
13333
|
exports.formatDateTime = formatDateTime;
|
|
13334
|
+
exports.formatPrescription = formatPrescription;
|
|
13335
|
+
exports.formatSignedPct = formatSignedPct;
|
|
13336
|
+
exports.formatVelocity = formatVelocity;
|
|
12905
13337
|
exports.getBaseSurfaceColor = getBaseSurfaceColor;
|
|
12906
13338
|
exports.getContrastText = getContrastText;
|
|
12907
13339
|
exports.getDiscreteRainbowColor = getDiscreteRainbowColor;
|
|
@@ -12911,17 +13343,19 @@ exports.getElevationSurface = getElevationSurface;
|
|
|
12911
13343
|
exports.getFieldAriaProps = getFieldAriaProps;
|
|
12912
13344
|
exports.getFieldValidationProps = getFieldValidationProps;
|
|
12913
13345
|
exports.getGlowShadow = getGlowShadow;
|
|
12914
|
-
exports.getHeatmapColor = getHeatmapColor;
|
|
12915
13346
|
exports.getHoverColors = getHoverColors;
|
|
12916
13347
|
exports.getLuminance = getLuminance;
|
|
12917
13348
|
exports.getResultColor = getResultColor;
|
|
12918
13349
|
exports.getSemanticColors = getSemanticColors;
|
|
12919
13350
|
exports.getStatusColor = getStatusColor;
|
|
13351
|
+
exports.getTempoFillPct = getTempoFillPct;
|
|
13352
|
+
exports.getTempoPacingState = getTempoPacingState;
|
|
12920
13353
|
exports.getThemeCSSVars = getThemeCSSVars;
|
|
12921
13354
|
exports.getValidatedElevation = getValidatedElevation;
|
|
12922
13355
|
exports.getVelocityZoneColor = getVelocityZoneColor;
|
|
12923
13356
|
exports.getVelocityZoneName = getVelocityZoneName;
|
|
12924
13357
|
exports.gluestackConfig = gluestackConfig;
|
|
13358
|
+
exports.groupExercises = groupExercises;
|
|
12925
13359
|
exports.hasMaxLength = hasMaxLength;
|
|
12926
13360
|
exports.hasMinLength = hasMinLength;
|
|
12927
13361
|
exports.hexToRgb = hexToRgb;
|
|
@@ -12940,12 +13374,22 @@ exports.primitiveShadows = primitiveShadows;
|
|
|
12940
13374
|
exports.primitiveSpacing = primitiveSpacing;
|
|
12941
13375
|
exports.primitiveTypography = primitiveTypography;
|
|
12942
13376
|
exports.primitiveZIndex = primitiveZIndex;
|
|
13377
|
+
exports.resolveColor = resolveColor;
|
|
12943
13378
|
exports.rgbToHex = rgbToHex;
|
|
12944
13379
|
exports.rgbToHsv = rgbToHsv;
|
|
13380
|
+
exports.roundRpe = roundRpe;
|
|
13381
|
+
exports.roundTempo = roundTempo;
|
|
13382
|
+
exports.roundWeight = roundWeight;
|
|
13383
|
+
exports.rpeColor = rpeColor;
|
|
12945
13384
|
exports.semanticColorsDark = semanticColorsDark;
|
|
12946
13385
|
exports.semanticColorsLight = semanticColorsLight;
|
|
12947
13386
|
exports.semanticTypography = semanticTypography;
|
|
12948
13387
|
exports.shadowColors = shadowColors;
|
|
13388
|
+
exports.statusToCardState = statusToCardState;
|
|
13389
|
+
exports.summarizeVbt = summarizeVbt;
|
|
13390
|
+
exports.toActiveCardProps = toActiveCardProps;
|
|
13391
|
+
exports.toExerciseCardProps = toExerciseCardProps;
|
|
13392
|
+
exports.toProgressBarMesos = toProgressBarMesos;
|
|
12949
13393
|
exports.useTable = useTable;
|
|
12950
13394
|
exports.useToast = useToast;
|
|
12951
13395
|
exports.useToolbarButton = useToolbarButton;
|