@sports-alliance/sports-lib 7.0.12 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/check-metrics.js +30 -0
- package/find-values.js +33 -0
- package/inspect-devices.js +21 -0
- package/inspect-session.js +27 -0
- package/lib/cjs/activities/devices/device.d.ts +1 -0
- package/lib/cjs/activities/devices/device.interface.d.ts +1 -0
- package/lib/cjs/activities/devices/device.js +1 -0
- package/lib/cjs/activities/devices/device.json.interface.d.ts +1 -0
- package/lib/cjs/data/data.age.d.ts +6 -0
- package/lib/cjs/data/data.age.js +12 -0
- package/lib/cjs/data/data.avg-flow.d.ts +5 -0
- package/lib/cjs/data/data.avg-flow.js +9 -0
- package/lib/cjs/data/data.avg-grit.d.ts +5 -0
- package/lib/cjs/data/data.avg-grit.js +9 -0
- package/lib/cjs/data/data.avg-respiration-rate.d.ts +5 -0
- package/lib/cjs/data/data.avg-respiration-rate.js +9 -0
- package/lib/cjs/data/data.avg-vam.d.ts +5 -0
- package/lib/cjs/data/data.avg-vam.js +9 -0
- package/lib/cjs/data/data.est-sweat-loss.d.ts +6 -0
- package/lib/cjs/data/data.est-sweat-loss.js +12 -0
- package/lib/cjs/data/data.flow.d.ts +5 -0
- package/lib/cjs/data/data.flow.js +9 -0
- package/lib/cjs/data/data.gender.d.ts +4 -0
- package/lib/cjs/data/data.gender.js +8 -0
- package/lib/cjs/data/data.grit.d.ts +5 -0
- package/lib/cjs/data/data.grit.js +9 -0
- package/lib/cjs/data/data.height.d.ts +6 -0
- package/lib/cjs/data/data.height.js +12 -0
- package/lib/cjs/data/data.jump-count.d.ts +6 -0
- package/lib/cjs/data/data.jump-count.js +12 -0
- package/lib/cjs/data/data.jump-event.d.ts +12 -0
- package/lib/cjs/data/data.jump-event.js +16 -0
- package/lib/cjs/data/data.left-pedal-smoothness.d.ts +6 -0
- package/lib/cjs/data/data.left-pedal-smoothness.js +12 -0
- package/lib/cjs/data/data.left-torque-effectiveness.d.ts +6 -0
- package/lib/cjs/data/data.left-torque-effectiveness.js +12 -0
- package/lib/cjs/data/data.max-respiration-rate.d.ts +5 -0
- package/lib/cjs/data/data.max-respiration-rate.js +9 -0
- package/lib/cjs/data/data.min-respiration-rate.d.ts +5 -0
- package/lib/cjs/data/data.min-respiration-rate.js +9 -0
- package/lib/cjs/data/data.primary-benefit.d.ts +6 -0
- package/lib/cjs/data/data.primary-benefit.js +12 -0
- package/lib/cjs/data/data.resting-calories.d.ts +5 -0
- package/lib/cjs/data/data.resting-calories.js +9 -0
- package/lib/cjs/data/data.right-pedal-smoothness.d.ts +6 -0
- package/lib/cjs/data/data.right-pedal-smoothness.js +12 -0
- package/lib/cjs/data/data.right-torque-effectiveness.d.ts +6 -0
- package/lib/cjs/data/data.right-torque-effectiveness.js +12 -0
- package/lib/cjs/data/data.store.js +54 -2
- package/lib/cjs/data/data.total-flow.d.ts +5 -0
- package/lib/cjs/data/data.total-flow.js +9 -0
- package/lib/cjs/data/data.total-grit.d.ts +5 -0
- package/lib/cjs/data/data.total-grit.js +9 -0
- package/lib/cjs/data/data.training-load-peak.d.ts +5 -0
- package/lib/cjs/data/data.training-load-peak.js +9 -0
- package/lib/cjs/data/data.weight.d.ts +6 -0
- package/lib/cjs/data/data.weight.js +12 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.d.ts +3 -1
- package/lib/cjs/events/adapters/importers/fit/importer.fit.js +209 -1
- package/lib/cjs/events/adapters/importers/fit/importer.fit.mapper.js +42 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.mtb.spec.d.ts +1 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.mtb.spec.js +217 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.road.spec.d.ts +1 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.road.spec.js +103 -0
- package/lib/cjs/geodesy/adapters/geolib.adapter.js +4 -9
- package/lib/cjs/index.d.ts +4 -0
- package/lib/cjs/index.js +4 -0
- package/lib/esm/activities/devices/device.d.ts +1 -0
- package/lib/esm/activities/devices/device.interface.d.ts +1 -0
- package/lib/esm/activities/devices/device.json.interface.d.ts +1 -0
- package/lib/esm/data/data.age.d.ts +6 -0
- package/lib/esm/data/data.avg-flow.d.ts +5 -0
- package/lib/esm/data/data.avg-grit.d.ts +5 -0
- package/lib/esm/data/data.avg-respiration-rate.d.ts +5 -0
- package/lib/esm/data/data.avg-vam.d.ts +5 -0
- package/lib/esm/data/data.est-sweat-loss.d.ts +6 -0
- package/lib/esm/data/data.flow.d.ts +5 -0
- package/lib/esm/data/data.gender.d.ts +4 -0
- package/lib/esm/data/data.grit.d.ts +5 -0
- package/lib/esm/data/data.height.d.ts +6 -0
- package/lib/esm/data/data.jump-count.d.ts +6 -0
- package/lib/esm/data/data.jump-event.d.ts +12 -0
- package/lib/esm/data/data.left-pedal-smoothness.d.ts +6 -0
- package/lib/esm/data/data.left-torque-effectiveness.d.ts +6 -0
- package/lib/esm/data/data.max-respiration-rate.d.ts +5 -0
- package/lib/esm/data/data.min-respiration-rate.d.ts +5 -0
- package/lib/esm/data/data.primary-benefit.d.ts +6 -0
- package/lib/esm/data/data.resting-calories.d.ts +5 -0
- package/lib/esm/data/data.right-pedal-smoothness.d.ts +6 -0
- package/lib/esm/data/data.right-torque-effectiveness.d.ts +6 -0
- package/lib/esm/data/data.total-flow.d.ts +5 -0
- package/lib/esm/data/data.total-grit.d.ts +5 -0
- package/lib/esm/data/data.training-load-peak.d.ts +5 -0
- package/lib/esm/data/data.weight.d.ts +6 -0
- package/lib/esm/events/adapters/importers/fit/importer.fit.d.ts +3 -1
- package/lib/esm/events/adapters/importers/fit/importer.fit.mtb.spec.d.ts +1 -0
- package/lib/esm/events/adapters/importers/fit/importer.fit.road.spec.d.ts +1 -0
- package/lib/esm/index.d.ts +4 -0
- package/lib/esm/index.js +515 -6
- package/package.json +2 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataTotalFlow = void 0;
|
|
4
|
+
const data_number_1 = require("./data.number");
|
|
5
|
+
class DataTotalFlow extends data_number_1.DataNumber {
|
|
6
|
+
}
|
|
7
|
+
exports.DataTotalFlow = DataTotalFlow;
|
|
8
|
+
DataTotalFlow.type = 'Total Flow';
|
|
9
|
+
DataTotalFlow.unit = '';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataTotalGrit = void 0;
|
|
4
|
+
const data_number_1 = require("./data.number");
|
|
5
|
+
class DataTotalGrit extends data_number_1.DataNumber {
|
|
6
|
+
}
|
|
7
|
+
exports.DataTotalGrit = DataTotalGrit;
|
|
8
|
+
DataTotalGrit.type = 'Total Grit';
|
|
9
|
+
DataTotalGrit.unit = '';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataTrainingLoadPeak = void 0;
|
|
4
|
+
const data_number_1 = require("./data.number");
|
|
5
|
+
class DataTrainingLoadPeak extends data_number_1.DataNumber {
|
|
6
|
+
}
|
|
7
|
+
exports.DataTrainingLoadPeak = DataTrainingLoadPeak;
|
|
8
|
+
DataTrainingLoadPeak.type = 'Training Load Peak';
|
|
9
|
+
DataTrainingLoadPeak.unit = '';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataWeight = void 0;
|
|
4
|
+
const data_number_1 = require("./data.number");
|
|
5
|
+
class DataWeight extends data_number_1.DataNumber {
|
|
6
|
+
getDisplayValue() {
|
|
7
|
+
return this.getValue().toFixed(1);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.DataWeight = DataWeight;
|
|
11
|
+
DataWeight.type = 'Weight';
|
|
12
|
+
DataWeight.unit = 'kg';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { EventInterface } from '../../../event.interface';
|
|
2
2
|
import { CreatorInterface } from '../../../../creators/creator.interface';
|
|
3
|
+
import { ActivityInterface } from '../../../../activities/activity.interface';
|
|
4
|
+
import { DataInterface } from '../../../../data/data.interface';
|
|
3
5
|
import { ActivityParsingOptions } from '../../../../activities/activity-parsing-options';
|
|
4
6
|
import { Buffer } from 'buffer';
|
|
5
7
|
export declare class EventImporterFIT {
|
|
@@ -27,7 +29,7 @@ export declare class EventImporterFIT {
|
|
|
27
29
|
*/
|
|
28
30
|
private static swapTimesIfRequired;
|
|
29
31
|
private static getActivityTypeFromSessionObject;
|
|
30
|
-
|
|
32
|
+
static getStatsFromObject(object: any, activity: ActivityInterface, isLap: boolean): DataInterface[];
|
|
31
33
|
static getCreatorFromFitDataObject(fitDataObject: any): CreatorInterface;
|
|
32
34
|
}
|
|
33
35
|
export interface FITFileActivityEvent {
|
|
@@ -107,6 +107,20 @@ const data_anaerobic_training_effect_1 = require("../../../../data/data-anaerobi
|
|
|
107
107
|
const importer_fit_wahoo_device_names_1 = require("./importer.fit.wahoo.device.names");
|
|
108
108
|
const importer_fit_coros_device_names_1 = require("./importer.fit.coros.device.names");
|
|
109
109
|
const importer_fit_srm_device_names_1 = require("./importer.fit.srm.device.names");
|
|
110
|
+
const data_avg_respiration_rate_1 = require("../../../../data/data.avg-respiration-rate");
|
|
111
|
+
const data_max_respiration_rate_1 = require("../../../../data/data.max-respiration-rate");
|
|
112
|
+
const data_min_respiration_rate_1 = require("../../../../data/data.min-respiration-rate");
|
|
113
|
+
const data_jump_count_1 = require("../../../../data/data.jump-count");
|
|
114
|
+
const data_total_grit_1 = require("../../../../data/data.total-grit");
|
|
115
|
+
const data_avg_flow_1 = require("../../../../data/data.avg-flow");
|
|
116
|
+
const data_est_sweat_loss_1 = require("../../../../data/data.est-sweat-loss");
|
|
117
|
+
const data_primary_benefit_1 = require("../../../../data/data.primary-benefit");
|
|
118
|
+
const data_sport_profile_name_1 = require("../../../../data/data.sport-profile-name");
|
|
119
|
+
const data_resting_calories_1 = require("../../../../data/data.resting-calories");
|
|
120
|
+
const data_training_load_peak_1 = require("../../../../data/data.training-load-peak");
|
|
121
|
+
const data_avg_vam_1 = require("../../../../data/data.avg-vam");
|
|
122
|
+
const data_end_position_1 = require("../../../../data/data.end-position");
|
|
123
|
+
const data_start_position_1 = require("../../../../data/data.start-position");
|
|
110
124
|
const activity_parsing_options_1 = require("../../../../activities/activity-parsing-options");
|
|
111
125
|
const importer_fit_hammerhead_device_names_1 = require("./importer.fit.hammerhead.device.names");
|
|
112
126
|
const importer_fit_lezyne_device_names_1 = require("./importer.fit.lezyne.device.names");
|
|
@@ -116,6 +130,12 @@ const parsing_event_lib_error_1 = require("../../../../errors/parsing-event-lib.
|
|
|
116
130
|
const data_power_down_1 = require("../../../../data/data.power-down");
|
|
117
131
|
const data_power_up_1 = require("../../../../data/data.power-up");
|
|
118
132
|
const importer_fit_development_device_names_1 = require("./importer.fit.development.device.names");
|
|
133
|
+
const data_weight_1 = require("../../../../data/data.weight");
|
|
134
|
+
const data_height_1 = require("../../../../data/data.height");
|
|
135
|
+
const data_age_1 = require("../../../../data/data.age");
|
|
136
|
+
const data_gender_1 = require("../../../../data/data.gender");
|
|
137
|
+
const data_avg_grit_1 = require("../../../../data/data.avg-grit");
|
|
138
|
+
const data_jump_event_1 = require("../../../../data/data.jump-event");
|
|
119
139
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
120
140
|
// @ts-ignore
|
|
121
141
|
const fit_file_parser_1 = __importDefault(require("fit-file-parser"));
|
|
@@ -288,6 +308,23 @@ class EventImporterFIT {
|
|
|
288
308
|
}
|
|
289
309
|
}
|
|
290
310
|
});
|
|
311
|
+
// Add jumps
|
|
312
|
+
if (fitDataObject.jumps && fitDataObject.jumps.length) {
|
|
313
|
+
fitDataObject.jumps
|
|
314
|
+
.filter((jump) => {
|
|
315
|
+
const timestamp = new Date(jump.timestamp);
|
|
316
|
+
// Relaxed check for jumps as they might be recorded slightly outside session stats or have timezone offsets
|
|
317
|
+
const margin = 24 * 60 * 60 * 1000; // 24 hours
|
|
318
|
+
return timestamp.getTime() >= activity.startDate.getTime() - margin && timestamp.getTime() <= activity.endDate.getTime() + margin;
|
|
319
|
+
})
|
|
320
|
+
.forEach((jump) => {
|
|
321
|
+
activity.addEvent(new data_jump_event_1.DataJumpEvent(activity.getDateIndex(jump.timestamp), {
|
|
322
|
+
distance: jump.distance,
|
|
323
|
+
height: jump.height,
|
|
324
|
+
score: jump.score
|
|
325
|
+
}));
|
|
326
|
+
});
|
|
327
|
+
}
|
|
291
328
|
// Get the samples..
|
|
292
329
|
// Test if activity is lengths based
|
|
293
330
|
// Indeed when based on lengths, an activity do not provides samples under records object (e.g. Pool swimming activities)
|
|
@@ -442,6 +479,9 @@ class EventImporterFIT {
|
|
|
442
479
|
device.antTransmissionType = deviceInfo.ant_transmission_type;
|
|
443
480
|
device.antNetwork = deviceInfo.ant_network;
|
|
444
481
|
device.sourceType = deviceInfo.source_type;
|
|
482
|
+
if (deviceInfo.ant_id) {
|
|
483
|
+
device.antId = deviceInfo.ant_id;
|
|
484
|
+
}
|
|
445
485
|
device.cumOperatingTime = deviceInfo.cum_operating_time;
|
|
446
486
|
return device;
|
|
447
487
|
});
|
|
@@ -556,6 +596,100 @@ class EventImporterFIT {
|
|
|
556
596
|
const activity = new activity_1.Activity(startDate, endDate, this.getActivityTypeFromSessionObject(sessionObject), this.getCreatorFromFitDataObject(fitDataObject), options);
|
|
557
597
|
// Set the activity stats
|
|
558
598
|
this.getStatsFromObject(sessionObject, activity, false).forEach(stat => activity.addStat(stat));
|
|
599
|
+
// Check for VO2 Max in jumps
|
|
600
|
+
if (fitDataObject.jumps && fitDataObject.jumps.length) {
|
|
601
|
+
const jumpWithMets = fitDataObject.jumps.find((j) => j.enhanced_mets);
|
|
602
|
+
if (jumpWithMets) {
|
|
603
|
+
activity.addStat(new data_vo2_max_1.DataVO2Max(jumpWithMets.enhanced_mets * 3.5));
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
// Check for User Profile
|
|
607
|
+
if (fitDataObject.user_profile) {
|
|
608
|
+
const userProfile = fitDataObject.user_profile;
|
|
609
|
+
if ((0, helpers_1.isNumberOrString)(userProfile.weight)) {
|
|
610
|
+
activity.addStat(new data_weight_1.DataWeight(userProfile.weight));
|
|
611
|
+
}
|
|
612
|
+
if ((0, helpers_1.isNumberOrString)(userProfile.height)) {
|
|
613
|
+
activity.addStat(new data_height_1.DataHeight(userProfile.height));
|
|
614
|
+
}
|
|
615
|
+
if ((0, helpers_1.isNumberOrString)(userProfile.age)) {
|
|
616
|
+
activity.addStat(new data_age_1.DataAge(userProfile.age));
|
|
617
|
+
}
|
|
618
|
+
if (userProfile.gender) {
|
|
619
|
+
activity.addStat(new data_gender_1.DataGender(userProfile.gender));
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
// Check for HR zone durations from time_in_zone messages
|
|
623
|
+
// This is an alternative source when sessionObject.time_in_hr_zone is not available
|
|
624
|
+
if (fitDataObject.time_in_zone && fitDataObject.time_in_zone.length) {
|
|
625
|
+
// Find session-level time_in_zone message (reference_mesg = 18 for session, reference_index = 0 for first session)
|
|
626
|
+
const sessionTimeInZone = fitDataObject.time_in_zone.find((z) => z.reference_mesg === 18 && (z.reference_index === 0 || z.reference_index === undefined));
|
|
627
|
+
if (sessionTimeInZone && sessionTimeInZone.time_in_hr_zone && Array.isArray(sessionTimeInZone.time_in_hr_zone)) {
|
|
628
|
+
const hrZones = sessionTimeInZone.time_in_hr_zone;
|
|
629
|
+
const hrZoneBoundaries = sessionTimeInZone.hr_zone_high_boundary;
|
|
630
|
+
// Only add zone duration stats if not already set from sessionObject.time_in_hr_zone
|
|
631
|
+
if (!activity.getStat(data_heart_rate_zone_one_duration_1.DataHeartRateZoneOneDuration.type)) {
|
|
632
|
+
if (hrZones[0] !== undefined && hrZones[0] !== null) {
|
|
633
|
+
activity.addStat(new data_heart_rate_zone_one_duration_1.DataHeartRateZoneOneDuration(hrZones[0]));
|
|
634
|
+
}
|
|
635
|
+
if (hrZones[1] !== undefined && hrZones[1] !== null) {
|
|
636
|
+
activity.addStat(new data_heart_rate_zone_two_duration_1.DataHeartRateZoneTwoDuration(hrZones[1]));
|
|
637
|
+
}
|
|
638
|
+
if (hrZones[2] !== undefined && hrZones[2] !== null) {
|
|
639
|
+
activity.addStat(new data_heart_rate_zone_three_duration_1.DataHeartRateZoneThreeDuration(hrZones[2]));
|
|
640
|
+
}
|
|
641
|
+
if (hrZones[3] !== undefined && hrZones[3] !== null) {
|
|
642
|
+
activity.addStat(new data_heart_rate_zone_four_duration_1.DataHeartRateZoneFourDuration(hrZones[3]));
|
|
643
|
+
}
|
|
644
|
+
if (hrZones[4] !== undefined && hrZones[4] !== null) {
|
|
645
|
+
activity.addStat(new data_heart_rate_zone_five_duration_1.DataHeartRateZoneFiveDuration(hrZones[4]));
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
// Check if IntensityZones for HR is already set, if not create one with boundaries
|
|
649
|
+
const existingHrZones = activity.intensityZones.find(iz => iz.type === data_heart_rate_1.DataHeartRate.type);
|
|
650
|
+
if (!existingHrZones && Array.isArray(hrZoneBoundaries) && hrZoneBoundaries.length > 0) {
|
|
651
|
+
// Create IntensityZones with boundaries
|
|
652
|
+
const hrIntensityZones = new intensity_zones_1.IntensityZones(data_heart_rate_1.DataHeartRate.type);
|
|
653
|
+
hrIntensityZones.zone1Duration = hrZones[0] || 0;
|
|
654
|
+
hrIntensityZones.zone2Duration = hrZones[1] || 0;
|
|
655
|
+
hrIntensityZones.zone3Duration = hrZones[2] || 0;
|
|
656
|
+
hrIntensityZones.zone4Duration = hrZones[3] || 0;
|
|
657
|
+
hrIntensityZones.zone5Duration = hrZones[4] || 0;
|
|
658
|
+
// hr_zone_high_boundary[n] is the upper limit of zone n+1
|
|
659
|
+
// Zone 2 lower limit = Zone 1 high boundary = hrZoneBoundaries[0]
|
|
660
|
+
// Zone 3 lower limit = Zone 2 high boundary = hrZoneBoundaries[1]
|
|
661
|
+
// etc.
|
|
662
|
+
if ((0, helpers_1.isNumber)(hrZoneBoundaries[0]) && hrZoneBoundaries[0] !== 255) {
|
|
663
|
+
hrIntensityZones.zone2LowerLimit = hrZoneBoundaries[0];
|
|
664
|
+
}
|
|
665
|
+
if ((0, helpers_1.isNumber)(hrZoneBoundaries[1]) && hrZoneBoundaries[1] !== 255) {
|
|
666
|
+
hrIntensityZones.zone3LowerLimit = hrZoneBoundaries[1];
|
|
667
|
+
}
|
|
668
|
+
if ((0, helpers_1.isNumber)(hrZoneBoundaries[2]) && hrZoneBoundaries[2] !== 255) {
|
|
669
|
+
hrIntensityZones.zone4LowerLimit = hrZoneBoundaries[2];
|
|
670
|
+
}
|
|
671
|
+
if ((0, helpers_1.isNumber)(hrZoneBoundaries[3]) && hrZoneBoundaries[3] !== 255) {
|
|
672
|
+
hrIntensityZones.zone5LowerLimit = hrZoneBoundaries[3];
|
|
673
|
+
}
|
|
674
|
+
activity.intensityZones.push(hrIntensityZones);
|
|
675
|
+
}
|
|
676
|
+
else if (existingHrZones && Array.isArray(hrZoneBoundaries) && hrZoneBoundaries.length > 0) {
|
|
677
|
+
// Update existing IntensityZones with boundary data if not set
|
|
678
|
+
if (!existingHrZones.zone2LowerLimit && (0, helpers_1.isNumber)(hrZoneBoundaries[0]) && hrZoneBoundaries[0] !== 255) {
|
|
679
|
+
existingHrZones.zone2LowerLimit = hrZoneBoundaries[0];
|
|
680
|
+
}
|
|
681
|
+
if (!existingHrZones.zone3LowerLimit && (0, helpers_1.isNumber)(hrZoneBoundaries[1]) && hrZoneBoundaries[1] !== 255) {
|
|
682
|
+
existingHrZones.zone3LowerLimit = hrZoneBoundaries[1];
|
|
683
|
+
}
|
|
684
|
+
if (!existingHrZones.zone4LowerLimit && (0, helpers_1.isNumber)(hrZoneBoundaries[2]) && hrZoneBoundaries[2] !== 255) {
|
|
685
|
+
existingHrZones.zone4LowerLimit = hrZoneBoundaries[2];
|
|
686
|
+
}
|
|
687
|
+
if (!existingHrZones.zone5LowerLimit && (0, helpers_1.isNumber)(hrZoneBoundaries[3]) && hrZoneBoundaries[3] !== 255) {
|
|
688
|
+
existingHrZones.zone5LowerLimit = hrZoneBoundaries[3];
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
559
693
|
return activity;
|
|
560
694
|
}
|
|
561
695
|
}
|
|
@@ -686,6 +820,9 @@ class EventImporterFIT {
|
|
|
686
820
|
stats.push(new data_heart_rate_max_1.DataHeartRateMax(object.max_heart_rate));
|
|
687
821
|
}
|
|
688
822
|
// Cadence
|
|
823
|
+
if (object.vo2_max_cycling && object.vo2_max_cycling > 10) {
|
|
824
|
+
stats.push(new data_vo2_max_1.DataVO2Max(object.vo2_max_cycling));
|
|
825
|
+
}
|
|
689
826
|
if ((0, helpers_1.isNumberOrString)(object.avg_cadence)) {
|
|
690
827
|
stats.push(new data_cadence_avg_1.DataCadenceAvg(object.avg_cadence));
|
|
691
828
|
}
|
|
@@ -699,6 +836,15 @@ class EventImporterFIT {
|
|
|
699
836
|
if ((0, helpers_1.isNumberOrString)(object.avg_power)) {
|
|
700
837
|
stats.push(new data_power_avg_1.DataPowerAvg(object.avg_power));
|
|
701
838
|
}
|
|
839
|
+
// Grit & Flow
|
|
840
|
+
if ((0, helpers_1.isNumberOrString)(object.total_flow)) {
|
|
841
|
+
}
|
|
842
|
+
if ((0, helpers_1.isNumberOrString)(object.avg_grit)) {
|
|
843
|
+
stats.push(new data_avg_grit_1.DataAvgGrit(object.avg_grit));
|
|
844
|
+
}
|
|
845
|
+
if ((0, helpers_1.isNumberOrString)(object.avg_flow)) {
|
|
846
|
+
stats.push(new data_avg_flow_1.DataAvgFlow(object.avg_flow));
|
|
847
|
+
}
|
|
702
848
|
if ((0, helpers_1.isNumberOrString)(object.min_power)) {
|
|
703
849
|
stats.push(new data_power_min_1.DataPowerMin(object.min_power));
|
|
704
850
|
}
|
|
@@ -770,7 +916,10 @@ class EventImporterFIT {
|
|
|
770
916
|
stats.push(new data_aerobic_training_effect_1.DataAerobicTrainingEffect(object.total_training_effect));
|
|
771
917
|
}
|
|
772
918
|
// Total training anaerobic effect
|
|
773
|
-
if ((0, helpers_1.isNumberOrString)(object.
|
|
919
|
+
if ((0, helpers_1.isNumberOrString)(object.total_anaerobic_training_effect)) {
|
|
920
|
+
stats.push(new data_anaerobic_training_effect_1.DataAnaerobicTrainingEffect(object.total_anaerobic_training_effect));
|
|
921
|
+
}
|
|
922
|
+
else if ((0, helpers_1.isNumberOrString)(object.total_anaerobic_effect)) {
|
|
774
923
|
stats.push(new data_anaerobic_training_effect_1.DataAnaerobicTrainingEffect(object.total_anaerobic_effect));
|
|
775
924
|
}
|
|
776
925
|
// Vo2Max
|
|
@@ -843,6 +992,65 @@ class EventImporterFIT {
|
|
|
843
992
|
const avgStrideLengthMeters = object.avg_step_length / 1000;
|
|
844
993
|
stats.push(new data_avg_stride_length_1.DataAvgStrideLength(Math.round(avgStrideLengthMeters * 100) / 100));
|
|
845
994
|
}
|
|
995
|
+
// Respiration Rate
|
|
996
|
+
if ((0, helpers_1.isNumberOrString)(object.avg_respiration_rate) || (0, helpers_1.isNumberOrString)(object.enhanced_avg_respiration_rate)) {
|
|
997
|
+
stats.push(new data_avg_respiration_rate_1.DataAvgRespirationRate(object.enhanced_avg_respiration_rate || object.avg_respiration_rate));
|
|
998
|
+
}
|
|
999
|
+
if ((0, helpers_1.isNumberOrString)(object.max_respiration_rate) || (0, helpers_1.isNumberOrString)(object.enhanced_max_respiration_rate)) {
|
|
1000
|
+
stats.push(new data_max_respiration_rate_1.DataMaxRespirationRate(object.enhanced_max_respiration_rate || object.max_respiration_rate));
|
|
1001
|
+
}
|
|
1002
|
+
if ((0, helpers_1.isNumberOrString)(object.min_respiration_rate) || (0, helpers_1.isNumberOrString)(object.enhanced_min_respiration_rate)) {
|
|
1003
|
+
stats.push(new data_min_respiration_rate_1.DataMinRespirationRate(object.enhanced_min_respiration_rate || object.min_respiration_rate));
|
|
1004
|
+
}
|
|
1005
|
+
// Total Grit
|
|
1006
|
+
if ((0, helpers_1.isNumberOrString)(object.total_grit)) {
|
|
1007
|
+
stats.push(new data_total_grit_1.DataTotalGrit(object.total_grit));
|
|
1008
|
+
}
|
|
1009
|
+
// Avg Flow
|
|
1010
|
+
if ((0, helpers_1.isNumberOrString)(object.avg_flow)) {
|
|
1011
|
+
stats.push(new data_avg_flow_1.DataAvgFlow(object.avg_flow));
|
|
1012
|
+
}
|
|
1013
|
+
// Est Sweat Loss
|
|
1014
|
+
if ((0, helpers_1.isNumberOrString)(object.est_sweat_loss)) {
|
|
1015
|
+
stats.push(new data_est_sweat_loss_1.DataEstSweatLoss(object.est_sweat_loss));
|
|
1016
|
+
}
|
|
1017
|
+
// Primary Benefit
|
|
1018
|
+
if ((0, helpers_1.isNumberOrString)(object.primary_benefit)) {
|
|
1019
|
+
stats.push(new data_primary_benefit_1.DataPrimaryBenefit(object.primary_benefit));
|
|
1020
|
+
}
|
|
1021
|
+
// Sport Profile Name
|
|
1022
|
+
if (object.sport_profile_name) {
|
|
1023
|
+
stats.push(new data_sport_profile_name_1.DataSportProfileName(object.sport_profile_name));
|
|
1024
|
+
}
|
|
1025
|
+
// Jump Count
|
|
1026
|
+
if ((0, helpers_1.isNumberOrString)(object.jump_count)) {
|
|
1027
|
+
stats.push(new data_jump_count_1.DataJumpCount(object.jump_count));
|
|
1028
|
+
}
|
|
1029
|
+
// Training Load Peak
|
|
1030
|
+
if ((0, helpers_1.isNumberOrString)(object.training_load_peak)) {
|
|
1031
|
+
stats.push(new data_training_load_peak_1.DataTrainingLoadPeak(object.training_load_peak));
|
|
1032
|
+
}
|
|
1033
|
+
// Positions
|
|
1034
|
+
if ((0, helpers_1.isNumber)(object.start_position_lat) && (0, helpers_1.isNumber)(object.start_position_long)) {
|
|
1035
|
+
stats.push(new data_start_position_1.DataStartPosition({
|
|
1036
|
+
latitudeDegrees: object.start_position_lat,
|
|
1037
|
+
longitudeDegrees: object.start_position_long,
|
|
1038
|
+
}));
|
|
1039
|
+
}
|
|
1040
|
+
if ((0, helpers_1.isNumber)(object.end_position_lat) && (0, helpers_1.isNumber)(object.end_position_long)) {
|
|
1041
|
+
stats.push(new data_end_position_1.DataEndPosition({
|
|
1042
|
+
latitudeDegrees: object.end_position_lat,
|
|
1043
|
+
longitudeDegrees: object.end_position_long,
|
|
1044
|
+
}));
|
|
1045
|
+
}
|
|
1046
|
+
// Resting Calories
|
|
1047
|
+
if ((0, helpers_1.isNumberOrString)(object.resting_calories)) {
|
|
1048
|
+
stats.push(new data_resting_calories_1.DataRestingCalories(object.resting_calories));
|
|
1049
|
+
}
|
|
1050
|
+
// Avg VAM
|
|
1051
|
+
if ((0, helpers_1.isNumberOrString)(object.avg_vam)) {
|
|
1052
|
+
stats.push(new data_avg_vam_1.DataAvgVAM(object.avg_vam));
|
|
1053
|
+
}
|
|
846
1054
|
return stats;
|
|
847
1055
|
}
|
|
848
1056
|
static getCreatorFromFitDataObject(fitDataObject) {
|
|
@@ -27,6 +27,12 @@ const data_step_length_1 = require("../../../../data/data.step-length");
|
|
|
27
27
|
const data_vertical_ratio_1 = require("../../../../data/data.vertical-ratio");
|
|
28
28
|
const data_ground_time_1 = require("../../../../data/data.ground-time");
|
|
29
29
|
const data_air_power_1 = require("../../../../data/data.air-power");
|
|
30
|
+
const data_grit_1 = require("../../../../data/data.grit");
|
|
31
|
+
const data_flow_1 = require("../../../../data/data.flow");
|
|
32
|
+
const data_left_torque_effectiveness_1 = require("../../../../data/data.left-torque-effectiveness");
|
|
33
|
+
const data_right_torque_effectiveness_1 = require("../../../../data/data.right-torque-effectiveness");
|
|
34
|
+
const data_left_pedal_smoothness_1 = require("../../../../data/data.left-pedal-smoothness");
|
|
35
|
+
const data_right_pedal_smoothness_1 = require("../../../../data/data.right-pedal-smoothness");
|
|
30
36
|
const constants_1 = require("../../../../constants/constants");
|
|
31
37
|
exports.FITSampleMapper = [
|
|
32
38
|
{
|
|
@@ -230,5 +236,41 @@ exports.FITSampleMapper = [
|
|
|
230
236
|
getSampleValue: (sample) => {
|
|
231
237
|
return sample.vertical_ratio;
|
|
232
238
|
}
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
dataType: data_grit_1.DataGrit.type,
|
|
242
|
+
getSampleValue: (sample) => {
|
|
243
|
+
return sample.grit;
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
dataType: data_flow_1.DataFlow.type,
|
|
248
|
+
getSampleValue: (sample) => {
|
|
249
|
+
return sample.flow;
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
dataType: data_left_torque_effectiveness_1.DataLeftTorqueEffectiveness.type,
|
|
254
|
+
getSampleValue: (sample) => {
|
|
255
|
+
return sample.left_torque_effectiveness;
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
dataType: data_right_torque_effectiveness_1.DataRightTorqueEffectiveness.type,
|
|
260
|
+
getSampleValue: (sample) => {
|
|
261
|
+
return sample.right_torque_effectiveness;
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
dataType: data_left_pedal_smoothness_1.DataLeftPedalSmoothness.type,
|
|
266
|
+
getSampleValue: (sample) => {
|
|
267
|
+
return sample.left_pedal_smoothness;
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
dataType: data_right_pedal_smoothness_1.DataRightPedalSmoothness.type,
|
|
272
|
+
getSampleValue: (sample) => {
|
|
273
|
+
return sample.right_pedal_smoothness;
|
|
274
|
+
}
|
|
233
275
|
}
|
|
234
276
|
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const importer_fit_1 = require("./importer.fit");
|
|
48
|
+
const data_aerobic_training_effect_1 = require("../../../../data/data-aerobic-training-effect");
|
|
49
|
+
const data_anaerobic_training_effect_1 = require("../../../../data/data-anaerobic-training-effect");
|
|
50
|
+
const data_vo2_max_1 = require("../../../../data/data.vo2-max");
|
|
51
|
+
const data_recovery_time_1 = require("../../../../data/data.recovery-time");
|
|
52
|
+
const data_avg_respiration_rate_1 = require("../../../../data/data.avg-respiration-rate");
|
|
53
|
+
const data_heart_rate_zone_five_duration_1 = require("../../../../data/data.heart-rate-zone-five-duration");
|
|
54
|
+
const data_heart_rate_zone_four_duration_1 = require("../../../../data/data.heart-rate-zone-four-duration");
|
|
55
|
+
const data_heart_rate_zone_one_duration_1 = require("../../../../data/data.heart-rate-zone-one-duration");
|
|
56
|
+
const data_heart_rate_zone_three_duration_1 = require("../../../../data/data.heart-rate-zone-three-duration");
|
|
57
|
+
const data_heart_rate_zone_two_duration_1 = require("../../../../data/data.heart-rate-zone-two-duration");
|
|
58
|
+
const data_jump_count_1 = require("../../../../data/data.jump-count");
|
|
59
|
+
const data_max_respiration_rate_1 = require("../../../../data/data.max-respiration-rate");
|
|
60
|
+
const data_min_respiration_rate_1 = require("../../../../data/data.min-respiration-rate");
|
|
61
|
+
const data_weight_1 = require("../../../../data/data.weight");
|
|
62
|
+
const data_training_load_peak_1 = require("../../../../data/data.training-load-peak");
|
|
63
|
+
const data_resting_calories_1 = require("../../../../data/data.resting-calories");
|
|
64
|
+
const data_est_sweat_loss_1 = require("../../../../data/data.est-sweat-loss");
|
|
65
|
+
const data_primary_benefit_1 = require("../../../../data/data.primary-benefit");
|
|
66
|
+
const data_sport_profile_name_1 = require("../../../../data/data.sport-profile-name");
|
|
67
|
+
const data_total_grit_1 = require("../../../../data/data.total-grit");
|
|
68
|
+
const data_avg_flow_1 = require("../../../../data/data.avg-flow");
|
|
69
|
+
const data_jump_event_1 = require("../../../../data/data.jump-event");
|
|
70
|
+
const data_avg_vam_1 = require("../../../../data/data.avg-vam");
|
|
71
|
+
const data_temperature_max_1 = require("../../../../data/data.temperature-max");
|
|
72
|
+
const data_temperature_min_1 = require("../../../../data/data.temperature-min");
|
|
73
|
+
const data_start_position_1 = require("../../../../data/data.start-position");
|
|
74
|
+
const data_end_position_1 = require("../../../../data/data.end-position");
|
|
75
|
+
const data_energy_1 = require("../../../../data/data.energy");
|
|
76
|
+
const helpers_1 = require("../../../../events/utilities/helpers");
|
|
77
|
+
describe('EventImporterFIT MTB Jumps', () => {
|
|
78
|
+
const samplesDir = path.resolve(__dirname, '../../../../../samples/fit');
|
|
79
|
+
const fitFile = 'jumps-mtb.fit';
|
|
80
|
+
it('should parse jumps-mtb.fit and extract grit, flow and jumps', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
81
|
+
const filePath = path.join(samplesDir, fitFile);
|
|
82
|
+
if (!fs.existsSync(filePath)) {
|
|
83
|
+
console.warn(`Sample file ${fitFile} not found. Skipping test.`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
87
|
+
const arrayBuffer = fileBuffer.buffer.slice(fileBuffer.byteOffset, fileBuffer.byteOffset + fileBuffer.byteLength);
|
|
88
|
+
const event = yield importer_fit_1.EventImporterFIT.getFromArrayBuffer(arrayBuffer, undefined, fitFile);
|
|
89
|
+
expect(event).toBeDefined();
|
|
90
|
+
const activities = event.getActivities();
|
|
91
|
+
console.log(`Parsed ${activities.length} activities.`);
|
|
92
|
+
activities.forEach((a, i) => {
|
|
93
|
+
console.log(`Activity ${i}: ${a.startDate.toISOString()} - ${a.endDate.toISOString()}`);
|
|
94
|
+
});
|
|
95
|
+
const activity = activities[0];
|
|
96
|
+
expect(activity).toBeDefined();
|
|
97
|
+
// Check Stats
|
|
98
|
+
const totalGrit = activity.getStat(data_total_grit_1.DataTotalGrit.type);
|
|
99
|
+
expect(totalGrit).toBeDefined();
|
|
100
|
+
expect(totalGrit.getValue()).toBeCloseTo(38.4, 1);
|
|
101
|
+
const avgFlow = activity.getStat(data_avg_flow_1.DataAvgFlow.type);
|
|
102
|
+
expect(avgFlow).toBeDefined();
|
|
103
|
+
expect(avgFlow.getValue()).toBeCloseTo(6.13, 2);
|
|
104
|
+
// Verify Respiration Rate
|
|
105
|
+
const avgResp = activity.getStat(data_avg_respiration_rate_1.DataAvgRespirationRate.type);
|
|
106
|
+
expect(avgResp).toBeDefined();
|
|
107
|
+
expect(avgResp.getValue()).toBeCloseTo(27.56, 1);
|
|
108
|
+
const maxResp = activity.getStat(data_max_respiration_rate_1.DataMaxRespirationRate.type);
|
|
109
|
+
expect(maxResp).toBeDefined();
|
|
110
|
+
expect(maxResp.getValue()).toBeCloseTo(41.43, 2);
|
|
111
|
+
const minResp = activity.getStat(data_min_respiration_rate_1.DataMinRespirationRate.type);
|
|
112
|
+
expect(minResp).toBeDefined();
|
|
113
|
+
expect(minResp.getValue()).toBeCloseTo(15.77, 2);
|
|
114
|
+
// Verify Avg VAM
|
|
115
|
+
const avgVam = activity.getStat(data_avg_vam_1.DataAvgVAM.type);
|
|
116
|
+
expect(avgVam).toBeDefined();
|
|
117
|
+
expect(avgVam.getValue()).toBeCloseTo(100, 1);
|
|
118
|
+
// Verify Jump Count
|
|
119
|
+
const jumpCount = activity.getStat(data_jump_count_1.DataJumpCount.type);
|
|
120
|
+
expect(jumpCount).toBeDefined();
|
|
121
|
+
expect(jumpCount.getValue()).toBe(11);
|
|
122
|
+
// Verify Training Load Peak
|
|
123
|
+
const trainingLoadPeak = activity.getStat(data_training_load_peak_1.DataTrainingLoadPeak.type);
|
|
124
|
+
expect(trainingLoadPeak).toBeDefined();
|
|
125
|
+
expect(trainingLoadPeak.getValue()).toBe(6079174);
|
|
126
|
+
// Verify Resting Calories
|
|
127
|
+
const restingCalories = activity.getStat(data_resting_calories_1.DataRestingCalories.type);
|
|
128
|
+
expect(restingCalories).toBeDefined();
|
|
129
|
+
expect(restingCalories.getValue()).toBe(159);
|
|
130
|
+
// Verify Est Sweat Loss
|
|
131
|
+
const sweatLoss = activity.getStat(data_est_sweat_loss_1.DataEstSweatLoss.type);
|
|
132
|
+
expect(sweatLoss).toBeDefined();
|
|
133
|
+
expect(sweatLoss.getValue()).toBe(790);
|
|
134
|
+
// Verify Primary Benefit
|
|
135
|
+
const primaryBenefit = activity.getStat(data_primary_benefit_1.DataPrimaryBenefit.type);
|
|
136
|
+
expect(primaryBenefit).toBeDefined();
|
|
137
|
+
expect(primaryBenefit.getValue()).toBe(2);
|
|
138
|
+
// Verify Sport Profile Name
|
|
139
|
+
const sportProfileName = activity.getStat(data_sport_profile_name_1.DataSportProfileName.type);
|
|
140
|
+
expect(sportProfileName).toBeDefined();
|
|
141
|
+
expect(sportProfileName.getValue()).toBe('MOUNTAIN');
|
|
142
|
+
// Verify Physiological Metrics
|
|
143
|
+
const aerobic = activity.getStat(data_aerobic_training_effect_1.DataAerobicTrainingEffect.type);
|
|
144
|
+
expect(aerobic).toBeDefined();
|
|
145
|
+
expect(aerobic.getValue()).toBe(3);
|
|
146
|
+
const anaerobic = activity.getStat(data_anaerobic_training_effect_1.DataAnaerobicTrainingEffect.type);
|
|
147
|
+
expect(anaerobic).toBeDefined();
|
|
148
|
+
expect(anaerobic.getValue()).toBe(2);
|
|
149
|
+
// VO2 Max
|
|
150
|
+
const vo2Max = activity.getStat(data_vo2_max_1.DataVO2Max.type);
|
|
151
|
+
expect(vo2Max).toBeDefined();
|
|
152
|
+
expect(vo2Max.getValue()).toBeCloseTo(57.0633, 4);
|
|
153
|
+
expect(activity.getStat(data_temperature_max_1.DataTemperatureMax.type).getValue()).toBe(19);
|
|
154
|
+
expect(activity.getStat(data_temperature_min_1.DataTemperatureMin.type).getValue()).toBe(7);
|
|
155
|
+
// Positions
|
|
156
|
+
const startPos = activity.getStat(data_start_position_1.DataStartPosition.type).getValue();
|
|
157
|
+
expect(startPos.latitudeDegrees).toBeCloseTo(39.664968, 5);
|
|
158
|
+
expect(startPos.longitudeDegrees).toBeCloseTo(20.849827, 5);
|
|
159
|
+
const endPos = activity.getStat(data_end_position_1.DataEndPosition.type).getValue();
|
|
160
|
+
expect(endPos.latitudeDegrees).toBeCloseTo(39.664946, 5);
|
|
161
|
+
expect(endPos.longitudeDegrees).toBeCloseTo(20.849807, 5);
|
|
162
|
+
expect(activity.getStat(data_recovery_time_1.DataRecoveryTime.type)).toBeUndefined();
|
|
163
|
+
// User Profile
|
|
164
|
+
const weight = activity.getStat(data_weight_1.DataWeight.type);
|
|
165
|
+
expect(weight).toBeDefined();
|
|
166
|
+
// Resting Calories
|
|
167
|
+
expect(activity.getStat(data_resting_calories_1.DataRestingCalories.type).getValue()).toBe(159);
|
|
168
|
+
expect(activity.getStat(data_aerobic_training_effect_1.DataAerobicTrainingEffect.type).getValue()).toBe(3);
|
|
169
|
+
expect(activity.getStat(data_anaerobic_training_effect_1.DataAnaerobicTrainingEffect.type).getValue()).toBe(2);
|
|
170
|
+
expect(activity.getStat(data_energy_1.DataEnergy.type).getValue()).toBe(853);
|
|
171
|
+
// HR Zone Durations from time_in_zone (session-level message 216)
|
|
172
|
+
const zone1 = activity.getStat(data_heart_rate_zone_one_duration_1.DataHeartRateZoneOneDuration.type);
|
|
173
|
+
expect(zone1).toBeDefined();
|
|
174
|
+
expect(zone1.getValue()).toBeCloseTo(346.004, 0); // ~346 seconds in zone 1
|
|
175
|
+
const zone2 = activity.getStat(data_heart_rate_zone_two_duration_1.DataHeartRateZoneTwoDuration.type);
|
|
176
|
+
expect(zone2).toBeDefined();
|
|
177
|
+
expect(zone2.getValue()).toBeCloseTo(1831.986, 0); // ~1832 seconds in zone 2
|
|
178
|
+
const zone3 = activity.getStat(data_heart_rate_zone_three_duration_1.DataHeartRateZoneThreeDuration.type);
|
|
179
|
+
expect(zone3).toBeDefined();
|
|
180
|
+
expect(zone3.getValue()).toBeCloseTo(2412.306, 0); // ~2412 seconds in zone 3
|
|
181
|
+
const zone4 = activity.getStat(data_heart_rate_zone_four_duration_1.DataHeartRateZoneFourDuration.type);
|
|
182
|
+
expect(zone4).toBeDefined();
|
|
183
|
+
expect(zone4.getValue()).toBeCloseTo(2160.994, 0); // ~2161 seconds in zone 4
|
|
184
|
+
const zone5 = activity.getStat(data_heart_rate_zone_five_duration_1.DataHeartRateZoneFiveDuration.type);
|
|
185
|
+
expect(zone5).toBeDefined();
|
|
186
|
+
expect(zone5.getValue()).toBeCloseTo(450.999, 0); // ~451 seconds in zone 5
|
|
187
|
+
// Check IntensityZones with boundaries
|
|
188
|
+
const hrIntensityZones = activity.intensityZones.find(iz => iz.type === 'Heart Rate');
|
|
189
|
+
expect(hrIntensityZones).toBeDefined();
|
|
190
|
+
if (hrIntensityZones) {
|
|
191
|
+
expect(hrIntensityZones.zone1Duration).toBeCloseTo(346.004, 0);
|
|
192
|
+
expect(hrIntensityZones.zone2Duration).toBeCloseTo(1831.986, 0);
|
|
193
|
+
// Zone boundaries: hr_zone_high_boundary = [93, 111, 130, 148, 167, 185] (from image)
|
|
194
|
+
// zone2LowerLimit = 93, zone3LowerLimit = 111, zone4LowerLimit = 130, zone5LowerLimit = 148
|
|
195
|
+
expect(hrIntensityZones.zone2LowerLimit).toBe(93);
|
|
196
|
+
expect(hrIntensityZones.zone3LowerLimit).toBe(111);
|
|
197
|
+
expect(hrIntensityZones.zone4LowerLimit).toBe(130);
|
|
198
|
+
expect(hrIntensityZones.zone5LowerLimit).toBe(148);
|
|
199
|
+
}
|
|
200
|
+
// Check Jumps
|
|
201
|
+
const jumpEvents = activity.getAllEvents().filter((e) => e.getType() === data_jump_event_1.DataJumpEvent.type);
|
|
202
|
+
expect(jumpEvents.length).toBeGreaterThan(0);
|
|
203
|
+
const jump = jumpEvents[0];
|
|
204
|
+
expect(jump.jumpData).toBeDefined();
|
|
205
|
+
expect((0, helpers_1.isNumber)(jump.jumpData.distance)).toBeTruthy();
|
|
206
|
+
expect((0, helpers_1.isNumber)(jump.jumpData.height)).toBeTruthy();
|
|
207
|
+
expect((0, helpers_1.isNumber)(jump.jumpData.score)).toBeTruthy();
|
|
208
|
+
console.log(`Found ${jumpEvents.length} jumps.`);
|
|
209
|
+
console.log('First jump:', jump.jumpData);
|
|
210
|
+
// We can check if we can find a sample with Grit.
|
|
211
|
+
// In sports-lib, samples are often accessed via activity.getStream(type) or similar, BUT
|
|
212
|
+
// importer creates `DataPoint`s? Or `DataSample`s?
|
|
213
|
+
// Let's assume we just check if parsing succeeded without error for now for samples,
|
|
214
|
+
// as verifying exact sample values requires knowing the file content deep structure.
|
|
215
|
+
// However, we added mapping for DataGrit/Flow, so they SHOULD be in the data set.
|
|
216
|
+
}));
|
|
217
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|