targets.ts (9105B)
1 /* 2 * Contains types and helper functions for calculator target sets 3 */ 4 5 import { DistanceUnits, convertDistance, formatDistance, formatDuration } from '@/core/units'; 6 import type { Distance } from '@/core/units'; 7 8 /* 9 * The two basic types of targets: those defined by distance and those defined by time 10 */ 11 export enum TargetTypes { 12 Distance = 'distance', 13 Time = 'time', 14 }; 15 16 /* 17 * The types for basic standard targets and target sets used by the pace and race calculators 18 */ 19 interface DistanceTarget { 20 type: TargetTypes.Distance, 21 distanceValue: number, 22 distanceUnit: DistanceUnits, 23 }; 24 interface TimeTarget { 25 type: TargetTypes.Time, 26 time: number, 27 }; 28 export type StandardTarget = DistanceTarget | TimeTarget; 29 export interface StandardTargetSet { 30 name: string, 31 targets: Array<StandardTarget>, 32 }; 33 export interface StandardTargetSets { 34 [key: string]: StandardTargetSet, 35 }; 36 37 /* 38 * The types for split calculator targets and target sets 39 */ 40 export type SplitTarget = DistanceTarget & { 41 splitTime?: number 42 }; 43 export interface SplitTargetSet { 44 name: string, 45 targets: Array<SplitTarget>, 46 }; 47 export interface SplitTargetSets { 48 [key: string]: SplitTargetSet, 49 }; 50 51 /* 52 * The types for workout calculator targets and target sets 53 */ 54 export type WorkoutTarget = StandardTarget & { 55 splitValue: number, 56 splitUnit: DistanceUnits, 57 customName?: string, 58 }; 59 export interface WorkoutTargetSet { 60 name: string, 61 targets: Array<WorkoutTarget>, 62 }; 63 export interface WorkoutTargetSets { 64 [key: string]: WorkoutTargetSet, 65 }; 66 67 /* 68 * The types for generic targets and target sets 69 */ 70 export type Target = StandardTarget | SplitTarget | WorkoutTarget; 71 export type TargetSet = StandardTargetSet | SplitTargetSet | WorkoutTargetSet; 72 export type TargetSets = StandardTargetSets | SplitTargetSets | WorkoutTargetSets; 73 74 /** 75 * Sort an array of targets 76 * @param {Array<Target>} targets The array of targets 77 * @returns {Array<Target>} The sorted targets 78 */ 79 export function sort(targets: Array<Target>): Array<Target> { 80 return [ 81 ...targets.filter((item) => item.type === TargetTypes.Distance) 82 .sort((a, b) => convertDistance(a.distanceValue, a.distanceUnit, DistanceUnits.Meters) 83 - convertDistance(b.distanceValue, b.distanceUnit, DistanceUnits.Meters)), 84 85 ...targets.filter((item) => item.type === TargetTypes.Time) 86 .sort((a, b) => a.time - b.time), 87 ]; 88 } 89 90 /** 91 * Generate a string description of a workout target 92 * @param {WorkoutTarget} target The workout target 93 * @return {string} The string description 94 */ 95 export function workoutTargetToString(target: WorkoutTarget): string { 96 let result = formatDistance({ distanceValue: target.splitValue, distanceUnit: target.splitUnit }, 97 false); 98 99 if (target.type === TargetTypes.Time) { 100 result += ' @ ' + formatDuration(target.time, 3, 2, false); 101 } else if (target.distanceValue != target.splitValue || target.distanceUnit != target.splitUnit) { 102 result += ' @ ' + formatDistance(target as Distance, false); 103 } 104 return result; 105 } 106 107 /* 108 * The default target sets for each calculator 109 */ 110 export const defaultTargetSets: { [key: string]: TargetSet } = { 111 '_pace_targets': { 112 name: 'Common Pace Targets', 113 targets: sort([ 114 { type: TargetTypes.Distance, distanceValue: 100, distanceUnit: DistanceUnits.Meters }, 115 { type: TargetTypes.Distance, distanceValue: 200, distanceUnit: DistanceUnits.Meters }, 116 { type: TargetTypes.Distance, distanceValue: 300, distanceUnit: DistanceUnits.Meters }, 117 { type: TargetTypes.Distance, distanceValue: 400, distanceUnit: DistanceUnits.Meters }, 118 { type: TargetTypes.Distance, distanceValue: 600, distanceUnit: DistanceUnits.Meters }, 119 { type: TargetTypes.Distance, distanceValue: 800, distanceUnit: DistanceUnits.Meters }, 120 { type: TargetTypes.Distance, distanceValue: 1000, distanceUnit: DistanceUnits.Meters }, 121 { type: TargetTypes.Distance, distanceValue: 1200, distanceUnit: DistanceUnits.Meters }, 122 { type: TargetTypes.Distance, distanceValue: 1500, distanceUnit: DistanceUnits.Meters }, 123 { type: TargetTypes.Distance, distanceValue: 1600, distanceUnit: DistanceUnits.Meters }, 124 { type: TargetTypes.Distance, distanceValue: 3200, distanceUnit: DistanceUnits.Meters }, 125 126 { type: TargetTypes.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Kilometers }, 127 { type: TargetTypes.Distance, distanceValue: 3, distanceUnit: DistanceUnits.Kilometers }, 128 { type: TargetTypes.Distance, distanceValue: 4, distanceUnit: DistanceUnits.Kilometers }, 129 { type: TargetTypes.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers }, 130 { type: TargetTypes.Distance, distanceValue: 6, distanceUnit: DistanceUnits.Kilometers }, 131 { type: TargetTypes.Distance, distanceValue: 8, distanceUnit: DistanceUnits.Kilometers }, 132 { type: TargetTypes.Distance, distanceValue: 10, distanceUnit: DistanceUnits.Kilometers }, 133 134 { type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles }, 135 { type: TargetTypes.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Miles }, 136 { type: TargetTypes.Distance, distanceValue: 3, distanceUnit: DistanceUnits.Miles }, 137 { type: TargetTypes.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Miles }, 138 { type: TargetTypes.Distance, distanceValue: 6, distanceUnit: DistanceUnits.Miles }, 139 { type: TargetTypes.Distance, distanceValue: 8, distanceUnit: DistanceUnits.Miles }, 140 { type: TargetTypes.Distance, distanceValue: 10, distanceUnit: DistanceUnits.Miles }, 141 142 { type: TargetTypes.Distance, distanceValue: 0.5, distanceUnit: DistanceUnits.Marathons }, 143 { type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Marathons }, 144 145 { type: TargetTypes.Time, time: 600 }, 146 { type: TargetTypes.Time, time: 1800 }, 147 { type: TargetTypes.Time, time: 3600 }, 148 ]), 149 }, '_race_targets': { 150 name: 'Common Race Targets', 151 targets: sort([ 152 { type: TargetTypes.Distance, distanceValue: 400, distanceUnit: DistanceUnits.Meters }, 153 { type: TargetTypes.Distance, distanceValue: 800, distanceUnit: DistanceUnits.Meters }, 154 { type: TargetTypes.Distance, distanceValue: 1500, distanceUnit: DistanceUnits.Meters }, 155 { type: TargetTypes.Distance, distanceValue: 1600, distanceUnit: DistanceUnits.Meters }, 156 { type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles }, 157 { type: TargetTypes.Distance, distanceValue: 3000, distanceUnit: DistanceUnits.Meters }, 158 { type: TargetTypes.Distance, distanceValue: 3200, distanceUnit: DistanceUnits.Meters }, 159 { type: TargetTypes.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Miles }, 160 161 { type: TargetTypes.Distance, distanceValue: 3, distanceUnit: DistanceUnits.Miles }, 162 { type: TargetTypes.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers }, 163 { type: TargetTypes.Distance, distanceValue: 6, distanceUnit: DistanceUnits.Kilometers }, 164 { type: TargetTypes.Distance, distanceValue: 8, distanceUnit: DistanceUnits.Kilometers }, 165 { type: TargetTypes.Distance, distanceValue: 10, distanceUnit: DistanceUnits.Kilometers }, 166 { type: TargetTypes.Distance, distanceValue: 15, distanceUnit: DistanceUnits.Kilometers }, 167 168 { type: TargetTypes.Distance, distanceValue: 0.5, distanceUnit: DistanceUnits.Marathons }, 169 { type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Marathons }, 170 ]), 171 }, '_split_targets': { 172 name: '5K Mile Splits', 173 targets: [ 174 { type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles }, 175 { type: TargetTypes.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Miles }, 176 { type: TargetTypes.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers }, 177 ], 178 }, '_workout_targets': { 179 name: 'Common Workout Targets', 180 targets: [ 181 { 182 splitValue: 400, splitUnit: DistanceUnits.Meters, 183 type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles, 184 }, 185 { 186 splitValue: 800, splitUnit: DistanceUnits.Meters, 187 type: TargetTypes.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers, 188 }, 189 { 190 splitValue: 1600, splitUnit: DistanceUnits.Meters, 191 type: TargetTypes.Time, time: 3600, 192 }, 193 { 194 splitValue: 1, splitUnit: DistanceUnits.Miles, 195 type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Marathons, 196 }, 197 ], 198 }, 199 }; 200 export const defaultPaceTargetSets: StandardTargetSets = { 201 '_pace_targets': defaultTargetSets._pace_targets, 202 }; 203 export const defaultRaceTargetSets: StandardTargetSets = { 204 '_race_targets': defaultTargetSets._race_targets, 205 }; 206 export const defaultSplitTargetSets: SplitTargetSets = { 207 '_split_targets': defaultTargetSets._split_targets as SplitTargetSet, 208 }; 209 export const defaultWorkoutTargetSets: WorkoutTargetSets = { 210 '_workout_targets': defaultTargetSets._workout_targets as WorkoutTargetSet, 211 };